fase(17): licensing module with RSA validation
This commit is contained in:
80
src/scripts/generate-license.ts
Normal file
80
src/scripts/generate-license.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env ts-node
|
||||
/**
|
||||
* ABE License Key Generator (internal tool)
|
||||
* Usage: ts-node src/scripts/generate-license.ts --plan pro --org "Acme Corp" --email admin@acme.com --expires 2027-01-01
|
||||
*/
|
||||
import crypto from 'crypto';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
interface Args {
|
||||
plan: 'free' | 'pro' | 'enterprise';
|
||||
org: string;
|
||||
email: string;
|
||||
expires: string | null;
|
||||
keyFile: string;
|
||||
}
|
||||
|
||||
function parseArgs(): Args {
|
||||
const args = process.argv.slice(2);
|
||||
const get = (flag: string): string | undefined => {
|
||||
const idx = args.indexOf(flag);
|
||||
return idx >= 0 ? args[idx + 1] : undefined;
|
||||
};
|
||||
|
||||
const plan = (get('--plan') ?? 'pro') as Args['plan'];
|
||||
const org = get('--org') ?? 'Unknown Organization';
|
||||
const email = get('--email') ?? '';
|
||||
const expires = get('--expires') ?? null;
|
||||
const keyFile = get('--key') ?? path.join(process.cwd(), 'license-private.pem');
|
||||
|
||||
return { plan, org, email, expires, keyFile };
|
||||
}
|
||||
|
||||
function generateLicense(args: Args): string {
|
||||
if (!fs.existsSync(args.keyFile)) {
|
||||
throw new Error(
|
||||
`Private key not found at ${args.keyFile}.\n` +
|
||||
'Generate with: openssl genrsa -out license-private.pem 2048'
|
||||
);
|
||||
}
|
||||
|
||||
const privateKeyPem = fs.readFileSync(args.keyFile, 'utf-8');
|
||||
const privateKey = crypto.createPrivateKey(privateKeyPem);
|
||||
|
||||
const payload = {
|
||||
plan: args.plan,
|
||||
organizationName: args.org,
|
||||
email: args.email,
|
||||
issuedAt: new Date().toISOString(),
|
||||
expiresAt: args.expires ? new Date(args.expires).toISOString() : null,
|
||||
};
|
||||
|
||||
const payloadJson = JSON.stringify(payload);
|
||||
const payloadB64 = Buffer.from(payloadJson, 'utf-8').toString('base64');
|
||||
|
||||
const signature = crypto.sign('sha256', Buffer.from(payloadJson, 'utf-8'), privateKey);
|
||||
const signatureB64 = signature.toString('base64');
|
||||
|
||||
return `${payloadB64}.${signatureB64}`;
|
||||
}
|
||||
|
||||
function main(): void {
|
||||
const args = parseArgs();
|
||||
try {
|
||||
const licenseKey = generateLicense(args);
|
||||
console.log('\n=== ABE License Key ===');
|
||||
console.log(licenseKey);
|
||||
console.log('\n=== Details ===');
|
||||
console.log(`Plan: ${args.plan}`);
|
||||
console.log(`Organization: ${args.org}`);
|
||||
console.log(`Email: ${args.email}`);
|
||||
console.log(`Expires: ${args.expires ?? 'Never'}`);
|
||||
console.log('===================\n');
|
||||
} catch (err) {
|
||||
console.error('Error generating license:', String(err));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user