83 lines
3.0 KiB
TypeScript
83 lines
3.0 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import { generateKeyPairSync, sign } from 'node:crypto';
|
|
import test from 'node:test';
|
|
|
|
import { canonicalJson } from '../../shared/license/canonicalJson';
|
|
import { joinSignedLicenseToken } from '../../shared/license/tokenFormat';
|
|
|
|
import { verifyLicenseToken } from './verifyLicenseToken';
|
|
|
|
void test('verifyLicenseToken: валидная подпись и срок', () => {
|
|
const { publicKey, privateKey } = generateKeyPairSync('ed25519');
|
|
const pubB64 = publicKey.export({ type: 'spki', format: 'der' }).toString('base64');
|
|
const licensePayload = {
|
|
v: 1 as const,
|
|
sub: 'lic_test_1',
|
|
pid: 'dnd_player',
|
|
iat: 100,
|
|
exp: 2_000_000_000,
|
|
did: null as string | null,
|
|
};
|
|
const body = canonicalJson(licensePayload);
|
|
const sig = sign(null, Buffer.from(body, 'utf8'), privateKey);
|
|
const token = joinSignedLicenseToken(body, new Uint8Array(sig.buffer, sig.byteOffset, sig.byteLength));
|
|
|
|
const ok = verifyLicenseToken(token, {
|
|
nowSec: 1_700_000_000,
|
|
deviceId: 'any',
|
|
publicKeyOverrideSpkiDerB64: pubB64,
|
|
});
|
|
if (!ok.ok) assert.fail('expected ok');
|
|
assert.equal(ok.payload.sub, 'lic_test_1');
|
|
});
|
|
|
|
void test('verifyLicenseToken: неверное устройство', () => {
|
|
const { publicKey, privateKey } = generateKeyPairSync('ed25519');
|
|
const pubB64 = publicKey.export({ type: 'spki', format: 'der' }).toString('base64');
|
|
const payload = {
|
|
v: 1 as const,
|
|
sub: 'lic_test_2',
|
|
pid: 'dnd_player',
|
|
iat: 100,
|
|
exp: 2_000_000_000,
|
|
did: 'device-a',
|
|
};
|
|
const body = canonicalJson(payload);
|
|
const sig = sign(null, Buffer.from(body, 'utf8'), privateKey);
|
|
const token = joinSignedLicenseToken(body, new Uint8Array(sig.buffer, sig.byteOffset, sig.byteLength));
|
|
|
|
const bad = verifyLicenseToken(token, {
|
|
nowSec: 1_700_000_000,
|
|
deviceId: 'device-b',
|
|
publicKeyOverrideSpkiDerB64: pubB64,
|
|
});
|
|
if (bad.ok) assert.fail('expected failure');
|
|
assert.equal(bad.reason, 'wrong_device');
|
|
});
|
|
|
|
void test('verifyLicenseToken: токен с переносами строк после копирования', () => {
|
|
const { publicKey, privateKey } = generateKeyPairSync('ed25519');
|
|
const pubB64 = publicKey.export({ type: 'spki', format: 'der' }).toString('base64');
|
|
const licensePayload = {
|
|
v: 1 as const,
|
|
sub: 'lic_wrap',
|
|
pid: 'dnd_player',
|
|
iat: 100,
|
|
exp: 2_000_000_000,
|
|
did: null as string | null,
|
|
};
|
|
const body = canonicalJson(licensePayload);
|
|
const sig = sign(null, Buffer.from(body, 'utf8'), privateKey);
|
|
const token = joinSignedLicenseToken(body, new Uint8Array(sig.buffer, sig.byteOffset, sig.byteLength));
|
|
const mid = Math.max(1, Math.floor(token.length / 2));
|
|
const messy = `${token.slice(0, mid)}\n${token.slice(mid, mid + 3)} \r\n ${token.slice(mid + 3)}`;
|
|
|
|
const ok = verifyLicenseToken(messy, {
|
|
nowSec: 1_700_000_000,
|
|
deviceId: 'any',
|
|
publicKeyOverrideSpkiDerB64: pubB64,
|
|
});
|
|
if (!ok.ok) assert.fail(`expected ok, got ${ok.reason}`);
|
|
assert.equal(ok.payload.sub, 'lic_wrap');
|
|
});
|