1// Node.js Bootstrapper Builder
2// Usage: node build_bootstrapper.js <tenantId> <outputExePath>
3// Reads template, generates JWT, injects values, builds EXE with pkg
5const fs = require('fs');
6const path = require('path');
7const { execFileSync } = require('child_process');
8const jwt = require('jsonwebtoken');
9require('dotenv').config({ path: path.resolve(__dirname, '../.env') });
11const AGENT_SIGN_KEY = process.env.AGENT_SIGN_KEY;
12const TEMPLATE_PATH = path.resolve(__dirname, 'bootstrapper_template.js');
17 * @param outputExePath
19function buildBootstrapper(tenantId, outputExePath) {
20 console.log('[BUILDER] Starting build for tenantId:', tenantId);
21 if (!tenantId) throw new Error('[BUILDER] Missing tenantId');
22 if (!AGENT_SIGN_KEY) throw new Error('[BUILDER] Missing AGENT_SIGN_KEY in .env');
24 // Generate JWT for agent onboarding
25 const token = jwt.sign({ tenantId }, AGENT_SIGN_KEY, { expiresIn: '30d' });
26 console.log('[BUILDER] Generated JWT:', token);
28 // Read template and inject values
29 console.log('[BUILDER] Reading template from:', TEMPLATE_PATH);
30 const template = fs.readFileSync(TEMPLATE_PATH, 'utf8');
31 if (!template.includes('__TENANT__') || !template.includes('__TOKEN__')) {
32 throw new Error('[BUILDER] Template missing placeholders');
34 const jsContent = template.replace(/__TENANT__/g, tenantId).replace(/__TOKEN__/g, token);
35 if (!jsContent.includes(tenantId) || !jsContent.includes(token)) {
36 throw new Error('[BUILDER] Failed to inject tenant/token');
39 // Debug: Log injection success
40 console.log('[BUILDER] Tenant injected:', jsContent.includes(tenantId));
41 console.log('[BUILDER] Token injected:', jsContent.includes(token));
42 console.log('[BUILDER] Sample of injected code:', jsContent.substring(200, 400));
45 const tempJs = path.join(__dirname, `bootstrapper_${tenantId}_${Date.now()}.js`);
46 fs.writeFileSync(tempJs, jsContent);
47 console.log('[BUILDER] Wrote temp JS:', tempJs);
48 console.log('[BUILDER] First 200 chars of JS:', jsContent.slice(0, 200));
50 // Verify the temp file actually has the injected values
51 const tempFileCheck = fs.readFileSync(tempJs, 'utf8');
52 console.log('[BUILDER] Verifying temp file - Has tenant:', tempFileCheck.includes(tenantId));
53 console.log('[BUILDER] Verifying temp file - Has token:', tempFileCheck.includes(token));
56 console.log('[BUILDER] Running pkg to build EXE:', outputExePath);
57 execFileSync('pkg', [tempJs, '--targets', 'node18-win-x64', '--output', outputExePath], { stdio: 'inherit' });
58 console.log('[BUILDER] Built EXE:', outputExePath);
61 fs.unlinkSync(tempJs);
62 console.log('[BUILDER] Cleaned up temp JS');
66if (require.main === module) {
67 const [tenantId, outputExePath] = process.argv.slice(2);
68 if (!tenantId || !outputExePath) {
69 console.error('Usage: node build_bootstrapper.js <tenantId> <outputExePath>');
73 buildBootstrapper(tenantId, outputExePath);
75 console.error('[ERROR]', err.message);