91 lines
2.6 KiB
TypeScript
91 lines
2.6 KiB
TypeScript
jest.mock('../crypto', () => ({
|
|
hashFingerprint: jest.fn(() => 'a'.repeat(64)),
|
|
}));
|
|
|
|
import { enforceDeviceAbusePolicy } from '../abuse-detection';
|
|
import type { HardwareFingerprint } from '../types';
|
|
|
|
function createFingerprint(instanceId = 'instance-1'): HardwareFingerprint {
|
|
return {
|
|
machineId: 'machine-1',
|
|
hostname: 'nas-1',
|
|
macAddress: 'aa:bb:cc:dd:ee:ff',
|
|
instanceId,
|
|
};
|
|
}
|
|
|
|
function createPrismaMock(recentHeartbeats: Array<{ instanceId: string; fingerprintHash: string }>) {
|
|
return {
|
|
heartbeatLog: {
|
|
findMany: jest.fn().mockResolvedValue(recentHeartbeats),
|
|
},
|
|
alert: {
|
|
findFirst: jest.fn().mockResolvedValue(null),
|
|
create: jest.fn().mockResolvedValue({}),
|
|
},
|
|
};
|
|
}
|
|
|
|
describe('abuse-detection', () => {
|
|
it('免费版同许可证出现多个有效指纹时应阻断', async () => {
|
|
const prisma = createPrismaMock([
|
|
{ instanceId: 'instance-2', fingerprintHash: 'b'.repeat(64) },
|
|
]);
|
|
|
|
const result = await enforceDeviceAbusePolicy(prisma as any, {
|
|
licenseId: 'license-1',
|
|
licenseType: 'FREE',
|
|
instanceId: 'instance-1',
|
|
fingerprint: createFingerprint(),
|
|
});
|
|
|
|
expect(result).toMatchObject({ allowed: false, status: 403 });
|
|
expect(prisma.alert.create).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
data: expect.objectContaining({
|
|
alertType: 'free_multi_device_blocked',
|
|
}),
|
|
})
|
|
);
|
|
});
|
|
|
|
it('付费版多个有效指纹应告警但不直接阻断', async () => {
|
|
const prisma = createPrismaMock([
|
|
{ instanceId: 'instance-2', fingerprintHash: 'b'.repeat(64) },
|
|
{ instanceId: 'instance-3', fingerprintHash: 'c'.repeat(64) },
|
|
]);
|
|
|
|
const result = await enforceDeviceAbusePolicy(prisma as any, {
|
|
licenseId: 'license-1',
|
|
licenseType: 'PRO',
|
|
instanceId: 'instance-1',
|
|
fingerprint: createFingerprint(),
|
|
});
|
|
|
|
expect(result).toEqual({ allowed: true });
|
|
expect(prisma.alert.create).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
data: expect.objectContaining({
|
|
alertType: 'paid_multi_device_suspected',
|
|
}),
|
|
})
|
|
);
|
|
});
|
|
|
|
it('旧版本非哈希心跳记录不应导致免费版误判多设备', async () => {
|
|
const prisma = createPrismaMock([
|
|
{ instanceId: 'instance-legacy', fingerprintHash: 'machine-legacy' },
|
|
]);
|
|
|
|
const result = await enforceDeviceAbusePolicy(prisma as any, {
|
|
licenseId: 'license-1',
|
|
licenseType: 'FREE',
|
|
instanceId: 'instance-1',
|
|
fingerprint: createFingerprint(),
|
|
});
|
|
|
|
expect(result).toEqual({ allowed: true });
|
|
expect(prisma.alert.create).not.toHaveBeenCalled();
|
|
});
|
|
});
|