- Protocol 1 (docs/hub-protocol.md): public key, register, signed heartbeats - Ed25519 licence tokens (30-day validity, status, expiry, grace, limits) - Dashboard: installs, install detail, customers and licences, alerts, settings and audit log; two-factor login required - Alert checks every 5 minutes, emailed once; heartbeat roll-up after 30 days - Unit tests for encryption, tokens, signatures, TOTP and alert rules Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012mt6TCv85T9VKRq3cV7rXq
31 lines
1.3 KiB
JavaScript
31 lines
1.3 KiB
JavaScript
/**
|
|
* Create the Hub's licence signing key pair (Ed25519).
|
|
*
|
|
* npm run generate-keys → keys/hub-signing-key.pem (refuses to overwrite)
|
|
* npm run generate-keys -- --force → replace it (every install then needs the new public key!)
|
|
*
|
|
* The private key stays on the Hub server only — back it up somewhere safe. The public key it
|
|
* prints goes into Hope Events (backend/src/hub/publicKey.js) so installs can check licences.
|
|
*/
|
|
|
|
const crypto = require('crypto');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const dir = path.join(__dirname, '..', 'keys');
|
|
const file = path.join(dir, 'hub-signing-key.pem');
|
|
|
|
if (fs.existsSync(file) && !process.argv.includes('--force')) {
|
|
console.error(`${file} already exists. Use --force to replace it (installs would need the new public key).`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const { privateKey, publicKey } = crypto.generateKeyPairSync('ed25519');
|
|
fs.mkdirSync(dir, { recursive: true });
|
|
fs.writeFileSync(file, privateKey.export({ type: 'pkcs8', format: 'pem' }), { mode: 0o600 });
|
|
|
|
console.log(`Private key written to ${file} — keep it secret and back it up.`);
|
|
console.log('Set HUB_SIGNING_KEY_FILE to that path in .env.\n');
|
|
console.log('Public key (for Hope Events, backend/src/hub/publicKey.js):\n');
|
|
console.log(publicKey.export({ type: 'spki', format: 'pem' }));
|