@panguard-ai/panguard 1.4.14 → 1.4.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/dist/cli/commands/scan.d.ts.map +1 -1
- package/dist/cli/commands/scan.js +56 -1
- package/dist/cli/commands/scan.js.map +1 -1
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +15 -2
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/up.d.ts.map +1 -1
- package/dist/cli/commands/up.js +180 -24
- package/dist/cli/commands/up.js.map +1 -1
- package/dist/cli/index.js +0 -0
- package/package.json +1 -1
- package/dist/cli/commands/admin.d.ts +0 -9
- package/dist/cli/commands/admin.d.ts.map +0 -1
- package/dist/cli/commands/admin.js +0 -130
- package/dist/cli/commands/admin.js.map +0 -1
- package/dist/cli/commands/manager.d.ts +0 -7
- package/dist/cli/commands/manager.d.ts.map +0 -1
- package/dist/cli/commands/manager.js +0 -113
- package/dist/cli/commands/manager.js.map +0 -1
- package/dist/cli/commands/serve-admin.d.ts +0 -11
- package/dist/cli/commands/serve-admin.d.ts.map +0 -1
- package/dist/cli/commands/serve-admin.js +0 -302
- package/dist/cli/commands/serve-admin.js.map +0 -1
- package/dist/cli/commands/serve-auth.d.ts +0 -11
- package/dist/cli/commands/serve-auth.d.ts.map +0 -1
- package/dist/cli/commands/serve-auth.js +0 -119
- package/dist/cli/commands/serve-auth.js.map +0 -1
- package/dist/cli/commands/serve-core.d.ts +0 -25
- package/dist/cli/commands/serve-core.d.ts.map +0 -1
- package/dist/cli/commands/serve-core.js +0 -215
- package/dist/cli/commands/serve-core.js.map +0 -1
- package/dist/cli/commands/serve-tc.d.ts +0 -12
- package/dist/cli/commands/serve-tc.d.ts.map +0 -1
- package/dist/cli/commands/serve-tc.js +0 -287
- package/dist/cli/commands/serve-tc.js.map +0 -1
- package/dist/cli/commands/serve-types.d.ts +0 -38
- package/dist/cli/commands/serve-types.d.ts.map +0 -1
- package/dist/cli/commands/serve-types.js +0 -108
- package/dist/cli/commands/serve-types.js.map +0 -1
- package/dist/cli/commands/serve.d.ts +0 -14
- package/dist/cli/commands/serve.d.ts.map +0 -1
- package/dist/cli/commands/serve.js +0 -383
- package/dist/cli/commands/serve.js.map +0 -1
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared types, helpers and middleware for serve sub-modules.
|
|
3
|
-
*/
|
|
4
|
-
import { authenticateRequest, requireAdmin } from '@panguard-ai/panguard-auth';
|
|
5
|
-
// ── JSON Response ──────────────────────────────────────────────
|
|
6
|
-
export function sendJson(res, status, data) {
|
|
7
|
-
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
8
|
-
res.end(JSON.stringify(data));
|
|
9
|
-
}
|
|
10
|
-
// ── Request Body Reader ────────────────────────────────────────
|
|
11
|
-
/** Read request body with 1MB size limit */
|
|
12
|
-
export function readRequestBody(req) {
|
|
13
|
-
return new Promise((resolve, reject) => {
|
|
14
|
-
const chunks = [];
|
|
15
|
-
let size = 0;
|
|
16
|
-
const MAX_BODY = 1_048_576; // 1MB
|
|
17
|
-
req.on('data', (chunk) => {
|
|
18
|
-
size += chunk.length;
|
|
19
|
-
if (size > MAX_BODY) {
|
|
20
|
-
req.destroy();
|
|
21
|
-
reject(new Error('Request body too large'));
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
chunks.push(chunk);
|
|
25
|
-
});
|
|
26
|
-
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
|
|
27
|
-
req.on('error', reject);
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
// ── Timing-safe Comparison ─────────────────────────────────────
|
|
31
|
-
/** Timing-safe string comparison to prevent side-channel attacks */
|
|
32
|
-
export function timingSafeCompare(a, b) {
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
34
|
-
const { timingSafeEqual } = require('node:crypto');
|
|
35
|
-
const ab = Buffer.from(a);
|
|
36
|
-
const bb = Buffer.from(b);
|
|
37
|
-
if (ab.length !== bb.length) {
|
|
38
|
-
// Compare against self to maintain constant time
|
|
39
|
-
timingSafeEqual(ab, ab);
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
return timingSafeEqual(ab, bb);
|
|
43
|
-
}
|
|
44
|
-
// ── Threat Cloud Auth Helpers ──────────────────────────────────
|
|
45
|
-
/**
|
|
46
|
-
* Require TC_API_KEY auth for write endpoints.
|
|
47
|
-
* In production: BLOCK if TC_API_KEY not set (refuse unauthenticated writes).
|
|
48
|
-
* In dev: allow passthrough with warning.
|
|
49
|
-
*/
|
|
50
|
-
export function requireTCWriteAuth(req, res) {
|
|
51
|
-
const tcApiKey = process.env['TC_API_KEY'];
|
|
52
|
-
if (!tcApiKey) {
|
|
53
|
-
if (process.env['NODE_ENV'] === 'production') {
|
|
54
|
-
sendJson(res, 503, {
|
|
55
|
-
ok: false,
|
|
56
|
-
error: 'Threat Cloud write API not configured (TC_API_KEY missing)',
|
|
57
|
-
});
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
return true; // dev passthrough
|
|
61
|
-
}
|
|
62
|
-
const authHeader = req.headers.authorization ?? '';
|
|
63
|
-
const token = authHeader.replace('Bearer ', '');
|
|
64
|
-
if (!timingSafeCompare(token, tcApiKey)) {
|
|
65
|
-
sendJson(res, 401, { ok: false, error: 'Invalid API key' });
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Require admin session auth for admin-only GET endpoints.
|
|
72
|
-
* Verifies the Bearer token is a valid session with admin role.
|
|
73
|
-
*/
|
|
74
|
-
export function requireTCAdminAuth(req, res, db) {
|
|
75
|
-
const user = authenticateRequest(req, db);
|
|
76
|
-
if (!user) {
|
|
77
|
-
sendJson(res, 401, { ok: false, error: 'Authentication required' });
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
if (!requireAdmin(user)) {
|
|
81
|
-
sendJson(res, 403, { ok: false, error: 'Admin access required' });
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
/** Validate Content-Type is application/json for POST requests */
|
|
87
|
-
export function requireJsonContentType(req, res) {
|
|
88
|
-
const ct = req.headers['content-type'] ?? '';
|
|
89
|
-
if (!ct.includes('application/json')) {
|
|
90
|
-
sendJson(res, 400, { ok: false, error: 'Content-Type must be application/json' });
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
// ── Rate Limiter ───────────────────────────────────────────────
|
|
96
|
-
/** Per-IP rate limiter for Threat Cloud endpoints (120 req/min) */
|
|
97
|
-
const tcRateLimits = new Map();
|
|
98
|
-
export function checkTCRateLimit(ip) {
|
|
99
|
-
const now = Date.now();
|
|
100
|
-
const entry = tcRateLimits.get(ip);
|
|
101
|
-
if (!entry || now > entry.resetAt) {
|
|
102
|
-
tcRateLimits.set(ip, { count: 1, resetAt: now + 60_000 });
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
entry.count++;
|
|
106
|
-
return entry.count <= 120;
|
|
107
|
-
}
|
|
108
|
-
//# sourceMappingURL=serve-types.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serve-types.js","sourceRoot":"","sources":["../../../src/cli/commands/serve-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* panguard serve - Unified HTTP server gateway
|
|
3
|
-
*
|
|
4
|
-
* Serves auth API, admin API, admin dashboard UI, and health check.
|
|
5
|
-
* Route handling is delegated to focused sub-modules:
|
|
6
|
-
* serve-core.ts -- middleware, health, static files, rule seeding
|
|
7
|
-
* serve-auth.ts -- auth, waitlist, usage routes
|
|
8
|
-
* serve-admin.ts -- admin dashboard + manager proxy routes
|
|
9
|
-
* serve-tc.ts -- Threat Cloud API routes
|
|
10
|
-
* serve-types.ts -- shared types and utilities
|
|
11
|
-
*/
|
|
12
|
-
import { Command } from 'commander';
|
|
13
|
-
export declare function serveCommand(): Command;
|
|
14
|
-
//# sourceMappingURL=serve.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2CpC,wBAAgB,YAAY,IAAI,OAAO,CA+XtC"}
|
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* panguard serve - Unified HTTP server gateway
|
|
3
|
-
*
|
|
4
|
-
* Serves auth API, admin API, admin dashboard UI, and health check.
|
|
5
|
-
* Route handling is delegated to focused sub-modules:
|
|
6
|
-
* serve-core.ts -- middleware, health, static files, rule seeding
|
|
7
|
-
* serve-auth.ts -- auth, waitlist, usage routes
|
|
8
|
-
* serve-admin.ts -- admin dashboard + manager proxy routes
|
|
9
|
-
* serve-tc.ts -- Threat Cloud API routes
|
|
10
|
-
* serve-types.ts -- shared types and utilities
|
|
11
|
-
*/
|
|
12
|
-
import { Command } from 'commander';
|
|
13
|
-
import { createServer } from 'node:http';
|
|
14
|
-
import { join, dirname } from 'node:path';
|
|
15
|
-
import { existsSync } from 'node:fs';
|
|
16
|
-
import { homedir } from 'node:os';
|
|
17
|
-
import { fileURLToPath } from 'node:url';
|
|
18
|
-
import { c, banner } from '@panguard-ai/core';
|
|
19
|
-
import { PANGUARD_VERSION } from '../../index.js';
|
|
20
|
-
import { AuthDB, createAuthHandlers, sendExpirationWarningEmail, initErrorTracking, captureRequestError, ManagerProxy, } from '@panguard-ai/panguard-auth';
|
|
21
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
22
|
-
let ManagerServer = null;
|
|
23
|
-
let DEFAULT_MANAGER_CONFIG = {};
|
|
24
|
-
try {
|
|
25
|
-
const mod = await import('@panguard-ai/manager');
|
|
26
|
-
ManagerServer = mod.ManagerServer;
|
|
27
|
-
DEFAULT_MANAGER_CONFIG = mod.DEFAULT_MANAGER_CONFIG;
|
|
28
|
-
}
|
|
29
|
-
catch {
|
|
30
|
-
// manager is optional — serve command will work without it
|
|
31
|
-
}
|
|
32
|
-
import { sendJson } from './serve-types.js';
|
|
33
|
-
import { applyMiddleware, handleCoreRoutes, seedRulesFromBundled } from './serve-core.js';
|
|
34
|
-
import { handleAuthRoutes } from './serve-auth.js';
|
|
35
|
-
import { handleAdminRoutes } from './serve-admin.js';
|
|
36
|
-
import { handleTCRoutes } from './serve-tc.js';
|
|
37
|
-
export function serveCommand() {
|
|
38
|
-
return new Command('serve')
|
|
39
|
-
.description('Start unified HTTP server / 啟動統一 HTTP 伺服器')
|
|
40
|
-
.option('--port <port>', 'Port number', '3000')
|
|
41
|
-
.option('--host <host>', 'Host to bind', '127.0.0.1')
|
|
42
|
-
.option('--db <path>', 'Database path', join(homedir(), '.panguard', 'auth.db'))
|
|
43
|
-
.option('--manager-port <port>', 'Manager server port / Manager 伺服器埠', '8443')
|
|
44
|
-
.action(async (options) => {
|
|
45
|
-
const port = parseInt(options.port, 10);
|
|
46
|
-
const host = options.host;
|
|
47
|
-
console.log(banner(PANGUARD_VERSION));
|
|
48
|
-
console.log(` ${c.sage('Panguard Serve')} - Unified Server Gateway`);
|
|
49
|
-
console.log('');
|
|
50
|
-
// Startup environment validation
|
|
51
|
-
const isProd = process.env['NODE_ENV'] === 'production';
|
|
52
|
-
const errors = [];
|
|
53
|
-
const warnings = [];
|
|
54
|
-
// Critical in production
|
|
55
|
-
if (isProd && !process.env['PANGUARD_BASE_URL']) {
|
|
56
|
-
errors.push('PANGUARD_BASE_URL not set in production — OAuth and email links will break');
|
|
57
|
-
}
|
|
58
|
-
if (isProd && !process.env['CORS_ALLOWED_ORIGINS']) {
|
|
59
|
-
errors.push('CORS_ALLOWED_ORIGINS not set in production — API will reject cross-origin requests');
|
|
60
|
-
}
|
|
61
|
-
// Warnings (non-fatal)
|
|
62
|
-
if (!process.env['PANGUARD_BASE_URL']) {
|
|
63
|
-
warnings.push('PANGUARD_BASE_URL not set — OAuth callbacks will use localhost');
|
|
64
|
-
}
|
|
65
|
-
if (!process.env['GOOGLE_CLIENT_ID']) {
|
|
66
|
-
warnings.push('GOOGLE_CLIENT_ID not set — Google OAuth login disabled');
|
|
67
|
-
}
|
|
68
|
-
if (!process.env['RESEND_API_KEY'] && !process.env['SMTP_HOST']) {
|
|
69
|
-
warnings.push('No email config (RESEND_API_KEY or SMTP_HOST) — password reset and waitlist emails disabled');
|
|
70
|
-
}
|
|
71
|
-
if (!process.env['SENTRY_DSN']) {
|
|
72
|
-
warnings.push('SENTRY_DSN not set — error tracking disabled');
|
|
73
|
-
}
|
|
74
|
-
if (isProd && !process.env['MANAGER_AUTH_TOKEN']) {
|
|
75
|
-
errors.push('MANAGER_AUTH_TOKEN not set in production — Manager API would allow unauthenticated access');
|
|
76
|
-
}
|
|
77
|
-
if (!isProd && !process.env['MANAGER_AUTH_TOKEN']) {
|
|
78
|
-
warnings.push('MANAGER_AUTH_TOKEN not set — Manager API allows unauthenticated access (OK for dev)');
|
|
79
|
-
}
|
|
80
|
-
if (!process.env['TC_API_KEY']) {
|
|
81
|
-
warnings.push('TC_API_KEY not set — Threat Cloud write API disabled in production, open in dev');
|
|
82
|
-
}
|
|
83
|
-
if (errors.length > 0) {
|
|
84
|
-
console.error(` ${c.critical('FATAL — Missing required environment variables:')}`);
|
|
85
|
-
for (const e of errors) {
|
|
86
|
-
console.error(` ${c.critical('x')} ${e}`);
|
|
87
|
-
}
|
|
88
|
-
console.error('');
|
|
89
|
-
console.error(` Set the variables above and restart. Aborting.`);
|
|
90
|
-
process.exit(1);
|
|
91
|
-
}
|
|
92
|
-
if (warnings.length > 0) {
|
|
93
|
-
console.log(` ${c.caution('Environment warnings:')}`);
|
|
94
|
-
for (const w of warnings) {
|
|
95
|
-
console.log(` ${c.dim('-')} ${w}`);
|
|
96
|
-
}
|
|
97
|
-
console.log('');
|
|
98
|
-
}
|
|
99
|
-
// Initialize error tracking (Sentry if configured, console fallback)
|
|
100
|
-
await initErrorTracking();
|
|
101
|
-
// Initialize database
|
|
102
|
-
const db = new AuthDB(options.db);
|
|
103
|
-
// Initialize Threat Cloud database (optional -- graceful if unavailable)
|
|
104
|
-
let threatDb = null;
|
|
105
|
-
try {
|
|
106
|
-
const tcMod = '@panguard-ai/threat-cloud';
|
|
107
|
-
const tc = await import(/* webpackIgnore: true */ tcMod);
|
|
108
|
-
const threatDbPath = join(dirname(options.db), 'threat-cloud.db');
|
|
109
|
-
threatDb = new tc.ThreatCloudDB(threatDbPath);
|
|
110
|
-
console.log(` ${c.safe('Threat Cloud DB')} initialized at ${c.dim(threatDbPath)}`);
|
|
111
|
-
// Auto-seed rules on first startup if rules table is empty
|
|
112
|
-
const stats = threatDb.getStats();
|
|
113
|
-
if (stats.totalRules === 0) {
|
|
114
|
-
console.log(` ${c.sage('Seeding rules...')} (first startup detected)`);
|
|
115
|
-
const seeded = await seedRulesFromBundled(threatDb);
|
|
116
|
-
console.log(` ${c.safe(`Seeded ${seeded} rules`)} into Threat Cloud DB`);
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
console.log(` ${c.dim(`Threat Cloud: ${stats.totalRules} rules, ${stats.totalThreats} threats`)}`);
|
|
120
|
-
}
|
|
121
|
-
console.log('');
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
125
|
-
console.error(` [ERROR] Threat Cloud initialization failed: ${msg}`);
|
|
126
|
-
if (err instanceof Error && err.stack) {
|
|
127
|
-
console.error(` ${err.stack}`);
|
|
128
|
-
}
|
|
129
|
-
console.log(` ${c.dim('Threat Cloud API routes disabled due to error above')}`);
|
|
130
|
-
console.log('');
|
|
131
|
-
}
|
|
132
|
-
// Initialize LLM Reviewer for ATR proposals (optional -- needs ANTHROPIC_API_KEY)
|
|
133
|
-
let llmReviewer = null;
|
|
134
|
-
if (threatDb && process.env['ANTHROPIC_API_KEY']) {
|
|
135
|
-
try {
|
|
136
|
-
const tcMod = '@panguard-ai/threat-cloud';
|
|
137
|
-
const tc = await import(/* webpackIgnore: true */ tcMod);
|
|
138
|
-
llmReviewer = new tc.LLMReviewer(process.env['ANTHROPIC_API_KEY'], threatDb);
|
|
139
|
-
console.log(` ${c.safe('LLM Reviewer')} enabled for ATR proposal review`);
|
|
140
|
-
}
|
|
141
|
-
catch {
|
|
142
|
-
console.log(` ${c.dim('LLM Reviewer not available')}`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
// Promotion cron: every 15 minutes, promote confirmed + LLM-approved proposals to rules
|
|
146
|
-
let promotionTimer = null;
|
|
147
|
-
if (threatDb) {
|
|
148
|
-
promotionTimer = setInterval(() => {
|
|
149
|
-
try {
|
|
150
|
-
const promoted = threatDb.promoteConfirmedProposals();
|
|
151
|
-
if (promoted > 0) {
|
|
152
|
-
console.log(` [Promotion] ${promoted} proposal(s) promoted to rules`);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
catch (err) {
|
|
156
|
-
console.error(` [Promotion] Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
157
|
-
}
|
|
158
|
-
}, 15 * 60 * 1000);
|
|
159
|
-
}
|
|
160
|
-
// Periodic database backup (every 6 hours)
|
|
161
|
-
let backupTimer = null;
|
|
162
|
-
if (threatDb) {
|
|
163
|
-
try {
|
|
164
|
-
const tcMod2 = '@panguard-ai/threat-cloud';
|
|
165
|
-
const tc2 = await import(/* webpackIgnore: true */ tcMod2);
|
|
166
|
-
const backupDir = join(dirname(options.db), 'backups');
|
|
167
|
-
const threatBackup = new tc2.BackupManager(join(dirname(options.db), 'threat-cloud.db'), backupDir, 7);
|
|
168
|
-
const authBackup = new tc2.BackupManager(options.db, backupDir, 7);
|
|
169
|
-
const runBackups = () => {
|
|
170
|
-
try {
|
|
171
|
-
const r1 = threatBackup.backup();
|
|
172
|
-
const r2 = authBackup.backup();
|
|
173
|
-
console.log(` [Backup] threat-cloud.db (${tc2.BackupManager.formatSize(r1.sizeBytes)}), auth.db (${tc2.BackupManager.formatSize(r2.sizeBytes)})`);
|
|
174
|
-
}
|
|
175
|
-
catch (err) {
|
|
176
|
-
console.error(` [Backup] Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
// Initial backup on startup
|
|
180
|
-
runBackups();
|
|
181
|
-
// Every 6 hours
|
|
182
|
-
backupTimer = setInterval(runBackups, 6 * 60 * 60 * 1000);
|
|
183
|
-
if (backupTimer.unref)
|
|
184
|
-
backupTimer.unref();
|
|
185
|
-
}
|
|
186
|
-
catch {
|
|
187
|
-
console.log(` ${c.dim('Backup manager not available — auto-backups disabled')}`);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
// Build config from environment
|
|
191
|
-
// Prefer Resend API when RESEND_API_KEY is set; fall back to raw SMTP
|
|
192
|
-
const emailConfig = process.env['RESEND_API_KEY']
|
|
193
|
-
? {
|
|
194
|
-
apiKey: process.env['RESEND_API_KEY'],
|
|
195
|
-
from: process.env['RESEND_FROM'] ??
|
|
196
|
-
process.env['SMTP_FROM'] ??
|
|
197
|
-
'Panguard AI <noreply@panguard.ai>',
|
|
198
|
-
}
|
|
199
|
-
: process.env['SMTP_HOST']
|
|
200
|
-
? {
|
|
201
|
-
host: process.env['SMTP_HOST'],
|
|
202
|
-
port: parseInt(process.env['SMTP_PORT'] ?? '587', 10),
|
|
203
|
-
secure: process.env['SMTP_SECURE'] === 'true',
|
|
204
|
-
from: process.env['SMTP_FROM'] ?? 'noreply@panguard.ai',
|
|
205
|
-
auth: {
|
|
206
|
-
user: process.env['SMTP_USER'] ?? '',
|
|
207
|
-
pass: process.env['SMTP_PASS'] ?? '',
|
|
208
|
-
},
|
|
209
|
-
}
|
|
210
|
-
: undefined;
|
|
211
|
-
const google = process.env['GOOGLE_CLIENT_ID']
|
|
212
|
-
? {
|
|
213
|
-
clientId: process.env['GOOGLE_CLIENT_ID'],
|
|
214
|
-
clientSecret: process.env['GOOGLE_CLIENT_SECRET'] ?? '',
|
|
215
|
-
redirectUri: process.env['GOOGLE_REDIRECT_URI'] ??
|
|
216
|
-
`http://${host}:${port}/api/auth/google/callback`,
|
|
217
|
-
}
|
|
218
|
-
: undefined;
|
|
219
|
-
const sheets = process.env['GOOGLE_SHEETS_ID']
|
|
220
|
-
? {
|
|
221
|
-
spreadsheetId: process.env['GOOGLE_SHEETS_ID'],
|
|
222
|
-
serviceAccountEmail: process.env['GOOGLE_SHEETS_SA_EMAIL'] ?? '',
|
|
223
|
-
privateKey: process.env['GOOGLE_SHEETS_PRIVATE_KEY'] ?? '',
|
|
224
|
-
}
|
|
225
|
-
: undefined;
|
|
226
|
-
const baseUrl = process.env['PANGUARD_BASE_URL'] ?? `http://${host}:${port}`;
|
|
227
|
-
const authConfig = {
|
|
228
|
-
db,
|
|
229
|
-
smtp: emailConfig,
|
|
230
|
-
baseUrl,
|
|
231
|
-
google,
|
|
232
|
-
sheets,
|
|
233
|
-
};
|
|
234
|
-
const handlers = createAuthHandlers(authConfig);
|
|
235
|
-
// Initialize Manager proxy for agent/event admin API routes
|
|
236
|
-
const managerProxy = new ManagerProxy(process.env['MANAGER_URL'], process.env['MANAGER_AUTH_TOKEN']);
|
|
237
|
-
// Resolve admin static directory
|
|
238
|
-
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
239
|
-
const adminDirs = [
|
|
240
|
-
join(process.cwd(), 'packages', 'admin'),
|
|
241
|
-
join(thisDir, '..', '..', '..', '..', 'admin'),
|
|
242
|
-
];
|
|
243
|
-
const adminDir = adminDirs.find((d) => existsSync(d));
|
|
244
|
-
// Build shared route context (immutable after creation)
|
|
245
|
-
const routeCtx = {
|
|
246
|
-
handlers,
|
|
247
|
-
db,
|
|
248
|
-
adminDir,
|
|
249
|
-
managerProxy,
|
|
250
|
-
threatDb,
|
|
251
|
-
llmReviewer,
|
|
252
|
-
};
|
|
253
|
-
const server = createServer((req, res) => {
|
|
254
|
-
void handleRequest(req, res, routeCtx);
|
|
255
|
-
});
|
|
256
|
-
// Build Manager config from environment
|
|
257
|
-
const managerPort = parseInt(options.managerPort, 10);
|
|
258
|
-
const managerConfig = {
|
|
259
|
-
...DEFAULT_MANAGER_CONFIG,
|
|
260
|
-
port: managerPort,
|
|
261
|
-
authToken: process.env['MANAGER_AUTH_TOKEN'] ?? '',
|
|
262
|
-
};
|
|
263
|
-
if (!ManagerServer) {
|
|
264
|
-
console.error(' Manager module not installed. Run: npm install @panguard-ai/manager');
|
|
265
|
-
process.exitCode = 1;
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
const managerServer = new ManagerServer(managerConfig);
|
|
269
|
-
server.listen(port, host, () => {
|
|
270
|
-
console.log(` ${c.safe('Server started')} on ${c.bold(`http://${host}:${port}`)}`);
|
|
271
|
-
console.log('');
|
|
272
|
-
console.log(` Routes:`);
|
|
273
|
-
console.log(` ${c.dim('/api/auth/*')} Auth API`);
|
|
274
|
-
console.log(` ${c.dim('/api/admin/*')} Admin API`);
|
|
275
|
-
console.log(` ${c.dim('/api/usage/*')} Usage & Quota API`);
|
|
276
|
-
if (adminDir) {
|
|
277
|
-
console.log(` ${c.dim('/admin')} Admin Dashboard`);
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
console.log(` ${c.dim('/admin')} ${c.caution('Not found')} (packages/admin/ missing)`);
|
|
281
|
-
}
|
|
282
|
-
console.log(` ${c.dim('/docs/api')} API Documentation (Swagger UI)`);
|
|
283
|
-
console.log(` ${c.dim('/openapi.json')} OpenAPI 3.0 Spec`);
|
|
284
|
-
console.log(` ${c.dim('/health')} Health check`);
|
|
285
|
-
console.log(` ${c.dim('/api/manager/*')} Manager API (port ${managerPort})`);
|
|
286
|
-
if (threatDb) {
|
|
287
|
-
console.log(` ${c.dim('/api/threats')} Threat Cloud API (POST)`);
|
|
288
|
-
console.log(` ${c.dim('/api/rules')} Rule Distribution (GET/POST)`);
|
|
289
|
-
console.log(` ${c.dim('/api/stats')} Threat Statistics (GET)`);
|
|
290
|
-
}
|
|
291
|
-
console.log('');
|
|
292
|
-
console.log(` Services:`);
|
|
293
|
-
console.log(` Email: ${emailConfig ? ('apiKey' in emailConfig ? c.safe('Resend API') : c.safe('SMTP')) : c.caution('Not configured')}`);
|
|
294
|
-
console.log(` OAuth: ${google ? c.safe('Google') : c.dim('Not configured')}`);
|
|
295
|
-
console.log(` Sheets: ${sheets ? c.safe('Google Sheets') : c.dim('Not configured')}`);
|
|
296
|
-
console.log(` Manager: ${c.safe(`port ${managerPort}`)}${process.env['MANAGER_AUTH_TOKEN'] ? '' : c.dim(' (no auth)')}`);
|
|
297
|
-
console.log('');
|
|
298
|
-
// Start Manager server after auth server is listening
|
|
299
|
-
managerServer
|
|
300
|
-
.start()
|
|
301
|
-
.then(() => {
|
|
302
|
-
console.log(` ${c.safe('Manager server started')} on ${c.bold(`http://${host}:${managerPort}`)}`);
|
|
303
|
-
console.log('');
|
|
304
|
-
})
|
|
305
|
-
.catch((err) => {
|
|
306
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
307
|
-
console.log(` ${c.caution('Manager server failed to start:')} ${message}`);
|
|
308
|
-
console.log(` ${c.dim('Auth server continues running without Manager')}`);
|
|
309
|
-
console.log('');
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
// Subscription lifecycle: check expired plans hourly
|
|
313
|
-
const runPlanCheck = () => {
|
|
314
|
-
const expired = db.checkExpiredPlans();
|
|
315
|
-
if (expired.length > 0) {
|
|
316
|
-
console.log(` [Plan] Downgraded ${expired.length} expired plan(s) to community tier`);
|
|
317
|
-
}
|
|
318
|
-
// Send warning emails for plans expiring in 3 days
|
|
319
|
-
if (emailConfig) {
|
|
320
|
-
const expiring = db.getExpiringPlans(3);
|
|
321
|
-
for (const user of expiring) {
|
|
322
|
-
sendExpirationWarningEmail(emailConfig, user.email, user.name, user.tier, user.planExpiresAt, baseUrl).catch(() => {
|
|
323
|
-
// Best-effort email delivery
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
if (expiring.length > 0) {
|
|
327
|
-
console.log(` [Plan] Sent ${expiring.length} expiration warning email(s)`);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
// Run immediately on startup, then every hour
|
|
332
|
-
runPlanCheck();
|
|
333
|
-
const planCheckTimer = setInterval(runPlanCheck, 60 * 60 * 1000);
|
|
334
|
-
if (planCheckTimer.unref)
|
|
335
|
-
planCheckTimer.unref();
|
|
336
|
-
// Graceful shutdown
|
|
337
|
-
const shutdown = () => {
|
|
338
|
-
console.log('\n Shutting down...');
|
|
339
|
-
clearInterval(planCheckTimer);
|
|
340
|
-
if (backupTimer)
|
|
341
|
-
clearInterval(backupTimer);
|
|
342
|
-
if (promotionTimer)
|
|
343
|
-
clearInterval(promotionTimer);
|
|
344
|
-
managerServer.stop().catch(() => { });
|
|
345
|
-
server.close(() => {
|
|
346
|
-
db.close();
|
|
347
|
-
if (threatDb)
|
|
348
|
-
threatDb.close();
|
|
349
|
-
process.exit(0);
|
|
350
|
-
});
|
|
351
|
-
};
|
|
352
|
-
process.on('SIGINT', shutdown);
|
|
353
|
-
process.on('SIGTERM', shutdown);
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
// ── Request Router ─────────────────────────────────────────────
|
|
357
|
-
async function handleRequest(req, res, ctx) {
|
|
358
|
-
const url = req.url ?? '/';
|
|
359
|
-
const pathname = url.split('?')[0] ?? '/';
|
|
360
|
-
// Apply security headers and CORS; handle OPTIONS preflight
|
|
361
|
-
if (applyMiddleware(req, res))
|
|
362
|
-
return;
|
|
363
|
-
try {
|
|
364
|
-
// Core routes: health, OpenAPI, static files
|
|
365
|
-
if (handleCoreRoutes(req, res, pathname, ctx.db, ctx.threatDb, ctx.adminDir))
|
|
366
|
-
return;
|
|
367
|
-
// Threat Cloud API routes (rate-limited, auth-gated)
|
|
368
|
-
if (await handleTCRoutes(req, res, url, pathname, ctx))
|
|
369
|
-
return;
|
|
370
|
-
// Auth, waitlist, and usage routes
|
|
371
|
-
if (await handleAuthRoutes(req, res, url, pathname, ctx))
|
|
372
|
-
return;
|
|
373
|
-
// Admin and Manager proxy routes
|
|
374
|
-
if (await handleAdminRoutes(req, res, url, pathname, ctx))
|
|
375
|
-
return;
|
|
376
|
-
sendJson(res, 404, { ok: false, error: 'Not found' });
|
|
377
|
-
}
|
|
378
|
-
catch (err) {
|
|
379
|
-
captureRequestError(err, req.method ?? 'UNKNOWN', pathname);
|
|
380
|
-
sendJson(res, 500, { ok: false, error: 'Internal server error' });
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
//# sourceMappingURL=serve.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"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"}
|