подготовка к билду

This commit is contained in:
Ivan Fontosh
2026-04-19 23:22:05 +08:00
parent 2fa20da94d
commit 726c89e104
13 changed files with 180 additions and 13 deletions
+41 -2
View File
@@ -6,6 +6,8 @@ import { ipcChannels } from '../../shared/ipc/contracts';
import { EULA_CURRENT_VERSION } from '../../shared/license/eulaVersion';
import type { LicenseSnapshot } from '../../shared/license/licenseSnapshot';
import type { LicensePayloadV1 } from '../../shared/license/payloadV1';
import { isDndProductKey } from '../../shared/license/productKey';
import { normalizeLicenseTokenInput } from '../../shared/license/tokenFormat';
import { getOrCreateDeviceId } from './deviceId';
import { licenseEncryptedPath, preferencesPath } from './paths';
@@ -77,6 +79,40 @@ export class LicenseService {
}
}
/** База для `POST /v1/activate` (и при желании совпадает с сервером отзыва). */
private resolveLicenseActivateBaseUrl(): string {
const raw = process.env.DND_LICENSE_STATUS_URL?.trim();
if (raw) return raw.endsWith('/') ? raw : `${raw}/`;
return 'https://license.mailib.ru/';
}
private async activateWithProductKey(productKey: string): Promise<string> {
const base = this.resolveLicenseActivateBaseUrl();
const url = new URL('v1/activate', base);
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify({ productKey: productKey.trim(), deviceId: this.deviceId }),
signal: AbortSignal.timeout(20_000),
});
const text = await res.text();
let parsed: unknown;
try {
parsed = JSON.parse(text) as unknown;
} catch {
throw new Error(`LICENSE_ACTIVATE_FAILED:${text.slice(0, 200)}`);
}
const obj = parsed as { token?: string; error?: string; message?: string };
if (!res.ok) {
throw new Error(`LICENSE_ACTIVATE_FAILED:${obj.error ?? obj.message ?? String(res.status)}`);
}
const token = obj.token;
if (!token || typeof token !== 'string') {
throw new Error('LICENSE_ACTIVATE_FAILED:token_missing');
}
return normalizeLicenseTokenInput(token);
}
private async maybeRefreshRemoteRevocation(payload: LicensePayloadV1): Promise<void> {
const base = process.env.DND_LICENSE_STATUS_URL?.trim();
if (!base) return;
@@ -191,11 +227,14 @@ export class LicenseService {
return this.getStatusSync();
}
setToken(token: string): LicenseSnapshot {
async setToken(token: string): Promise<LicenseSnapshot> {
if (this.isSkipLicense()) {
return this.getStatusSync();
}
const trimmed = token.trim();
let trimmed = normalizeLicenseTokenInput(token);
if (isDndProductKey(trimmed)) {
trimmed = await this.activateWithProductKey(trimmed);
}
const nowSec = Math.floor(Date.now() / 1000);
const v = verifyLicenseToken(trimmed, { nowSec, deviceId: this.deviceId });
if (!v.ok) {