подготовка к билду
This commit is contained in:
@@ -2,4 +2,4 @@
|
||||
* Публичный ключ Ed25519 (SPKI DER, base64). Должен соответствовать приватному ключу на сервере лицензий.
|
||||
* Репозиторий сервера: https://git.mailib.ru/ifontosh/DndGamePlayerLicenseServer.git
|
||||
*/
|
||||
export const LICENSE_ED25519_SPKI_DER_B64 = 'MCowBQYDK2VwAyEAd7zvdjqeYW/fUvG5RX1/L1SCTZL1xzh+kr4rlNLQJbY=';
|
||||
export const LICENSE_ED25519_SPKI_DER_B64 = 'MCowBQYDK2VwAyEA0KNHmwh7cjUtHh0V5XApTav9z/mee9iWLSS4MFbVDq8=';
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { isDndProductKey } from './productKey';
|
||||
|
||||
void test('isDndProductKey: пример пользователя', () => {
|
||||
assert.equal(isDndProductKey('DND-CEBEC1BF-AD0B-4312-BFDD-675AFF5955FD'), true);
|
||||
});
|
||||
|
||||
void test('isDndProductKey: токен с точкой — нет', () => {
|
||||
assert.equal(isDndProductKey('eyJ.xxx'), false);
|
||||
});
|
||||
|
||||
void test('isDndProductKey: пробелы по краям', () => {
|
||||
assert.equal(isDndProductKey(' DND-CEBEC1BF-AD0B-4312-BFDD-675AFF5955FD '), true);
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
/** Продуктовый ключ активации (не путать с лицензионным токеном `base64.base64`). */
|
||||
const DND_PRODUCT_KEY_RE = /^DND-[0-9A-F]{8}-(?:[0-9A-F]{4}-){3}[0-9A-F]{12}$/iu;
|
||||
|
||||
export function isDndProductKey(s: string): boolean {
|
||||
return DND_PRODUCT_KEY_RE.test(s.trim());
|
||||
}
|
||||
@@ -1,5 +1,13 @@
|
||||
/** Убирает переносы/неразрывные пробелы из вставки из почты и мессенджеров (иначе `malformed`). */
|
||||
export function normalizeLicenseTokenInput(token: string): string {
|
||||
return token.replace(/[\s\u00a0\u200b-\u200d\ufeff\u2028\u2029]+/gu, '').trim();
|
||||
}
|
||||
|
||||
const B64URL = {
|
||||
encode(bytes: Uint8Array): string {
|
||||
if (typeof Buffer !== 'undefined') {
|
||||
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64url');
|
||||
}
|
||||
let bin = '';
|
||||
for (const byte of bytes) {
|
||||
bin += String.fromCharCode(byte);
|
||||
@@ -8,6 +16,13 @@ const B64URL = {
|
||||
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/u, '');
|
||||
},
|
||||
decode(s: string): Uint8Array {
|
||||
if (typeof Buffer !== 'undefined') {
|
||||
try {
|
||||
return new Uint8Array(Buffer.from(s, 'base64url'));
|
||||
} catch {
|
||||
/* fall through */
|
||||
}
|
||||
}
|
||||
const pad = s.length % 4 === 0 ? '' : '='.repeat(4 - (s.length % 4));
|
||||
const b64 = s.replace(/-/g, '+').replace(/_/g, '/') + pad;
|
||||
const bin = atob(b64);
|
||||
@@ -19,7 +34,7 @@ const B64URL = {
|
||||
|
||||
/** Тело UTF-8 + подпись Ed25519 (64 байта), разделитель «.». */
|
||||
export function splitSignedLicenseToken(token: string): { bodyUtf8: string; signature: Uint8Array } | null {
|
||||
const t = token.trim();
|
||||
const t = normalizeLicenseTokenInput(token);
|
||||
const dot = t.indexOf('.');
|
||||
if (dot <= 0) return null;
|
||||
const a = t.slice(0, dot);
|
||||
|
||||
Reference in New Issue
Block a user