2fa20da94d
- Main: license service, IPC, router; закрытие окон; yauzl закрытие zip (EMFILE), zipRead тест - Editor: стабильный projectState без мигания, логотип и меню, строки UI, LayoutShell overlay - Control: ластик для всех типов эффектов, затухание/нарастание музыки при смене сцены - Сборка: vite, build/dev scripts, obfuscate-main и build-env скрипты с тестами; package.json Made-with: Cursor
34 lines
1.1 KiB
TypeScript
34 lines
1.1 KiB
TypeScript
/** Полезная нагрузка лицензии v1 (подписывается Ed25519 на сервере). */
|
|
export type LicensePayloadV1 = {
|
|
v: 1;
|
|
/** Стабильный id лицензии (для отзыва и учёта). */
|
|
sub: string;
|
|
/** Идентификатор продукта. */
|
|
pid: string;
|
|
/** Unix-время выдачи (сек). */
|
|
iat: number;
|
|
/** Unix-время окончания (сек). */
|
|
exp: number;
|
|
/** Не раньше этого времени (сек), опционально. */
|
|
nbf?: number;
|
|
/** Привязка к устройству: null — любое устройство. */
|
|
did: string | null;
|
|
};
|
|
|
|
export function isLicensePayloadV1(x: unknown): x is LicensePayloadV1 {
|
|
if (!x || typeof x !== 'object') return false;
|
|
const o = x as Record<string, unknown>;
|
|
return (
|
|
o.v === 1 &&
|
|
typeof o.sub === 'string' &&
|
|
o.sub.length > 0 &&
|
|
typeof o.pid === 'string' &&
|
|
o.pid.length > 0 &&
|
|
typeof o.iat === 'number' &&
|
|
Number.isFinite(o.iat) &&
|
|
typeof o.exp === 'number' &&
|
|
Number.isFinite(o.exp) &&
|
|
(o.did === null || typeof o.did === 'string')
|
|
);
|
|
}
|