This guide covers the full loop: activate → store → verify on startup → deactivate. It assumes you already have a workspace and a license key.
1. Activate
license.js
const BASE = 'https://keygate.unionuser.com';
export async function activate(licenseKey, deviceId) {
const res = await fetch(BASE + '/api/v1/license/activate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
license_key: licenseKey,
identifier: deviceId,
identifier_type: 'device',
}),
});
const json = await res.json();
if (!json.success) throw new Error(json.error.code);
return json.data.token;
}
2. Verify offline
verify.js
import { verify, createPublicKey } from 'node:crypto';
const publicKey = createPublicKey({
key: Buffer.concat([
Buffer.from('302a300506032b6570032100', 'hex'),
Buffer.from('bf17435ee7b937b3592808941683c21d37c4e124d95d4e8fdd86fe775dd23b11', 'hex'),
]),
format: 'der',
type: 'spki',
});
export function verifyToken(token, deviceId) {
const [payloadB64, sigB64] = token.split('.');
const ok = verify(
null,
Buffer.from(payloadB64, 'ascii'),
publicKey,
Buffer.from(sigB64, 'base64url'),
);
if (!ok) throw new Error('INVALID_SIGNATURE');
const claims = JSON.parse(
Buffer.from(payloadB64, 'base64url').toString('utf8'),
);
if (claims.did !== deviceId) throw new Error('DEVICE_MISMATCH');
if (claims.exp * 1000 < Date.now()) throw new Error('TOKEN_EXPIRED');
return claims;
}
3. Deactivate
deactivate.js
export async function deactivate(licenseKey, deviceId) {
const res = await fetch(BASE + '/api/v1/license/deactivate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
license_key: licenseKey,
identifier: deviceId,
}),
});
const json = await res.json();
if (!json.success) throw new Error(json.error.code);
}
Electron notes
- Make requests in the main process and call it over IPC so the token never reaches the renderer.
- Store the token under the userData directory, not the install directory.
- Verify on startup before deciding to go online; it behaves better on weak networks.