@panguard-ai/panguard 0.3.7 → 0.4.1
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/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/audit.js +28 -1
- package/dist/cli/commands/audit.js.map +1 -1
- package/dist/cli/commands/serve-admin.d.ts +11 -0
- package/dist/cli/commands/serve-admin.d.ts.map +1 -0
- package/dist/cli/commands/serve-admin.js +302 -0
- package/dist/cli/commands/serve-admin.js.map +1 -0
- package/dist/cli/commands/serve-auth.d.ts +11 -0
- package/dist/cli/commands/serve-auth.d.ts.map +1 -0
- package/dist/cli/commands/serve-auth.js +119 -0
- package/dist/cli/commands/serve-auth.js.map +1 -0
- package/dist/cli/commands/serve-core.d.ts +25 -0
- package/dist/cli/commands/serve-core.d.ts.map +1 -0
- package/dist/cli/commands/serve-core.js +258 -0
- package/dist/cli/commands/serve-core.js.map +1 -0
- package/dist/cli/commands/serve-tc.d.ts +12 -0
- package/dist/cli/commands/serve-tc.d.ts.map +1 -0
- package/dist/cli/commands/serve-tc.js +296 -0
- package/dist/cli/commands/serve-tc.js.map +1 -0
- package/dist/cli/commands/serve-types.d.ts +38 -0
- package/dist/cli/commands/serve-types.d.ts.map +1 -0
- package/dist/cli/commands/serve-types.js +108 -0
- package/dist/cli/commands/serve-types.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +6 -0
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +41 -1144
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/setup.js +2 -2
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/interactive/actions/audit.d.ts +7 -0
- package/dist/cli/interactive/actions/audit.d.ts.map +1 -0
- package/dist/cli/interactive/actions/audit.js +198 -0
- package/dist/cli/interactive/actions/audit.js.map +1 -0
- package/dist/cli/interactive/actions/demo.d.ts +7 -0
- package/dist/cli/interactive/actions/demo.d.ts.map +1 -0
- package/dist/cli/interactive/actions/demo.js +113 -0
- package/dist/cli/interactive/actions/demo.js.map +1 -0
- package/dist/cli/interactive/actions/guard.d.ts +7 -0
- package/dist/cli/interactive/actions/guard.d.ts.map +1 -0
- package/dist/cli/interactive/actions/guard.js +164 -0
- package/dist/cli/interactive/actions/guard.js.map +1 -0
- package/dist/cli/interactive/actions/misc.d.ts +13 -0
- package/dist/cli/interactive/actions/misc.d.ts.map +1 -0
- package/dist/cli/interactive/actions/misc.js +209 -0
- package/dist/cli/interactive/actions/misc.js.map +1 -0
- package/dist/cli/interactive/actions/scan.d.ts +7 -0
- package/dist/cli/interactive/actions/scan.d.ts.map +1 -0
- package/dist/cli/interactive/actions/scan.js +143 -0
- package/dist/cli/interactive/actions/scan.js.map +1 -0
- package/dist/cli/interactive/actions/setup.d.ts +8 -0
- package/dist/cli/interactive/actions/setup.d.ts.map +1 -0
- package/dist/cli/interactive/actions/setup.js +130 -0
- package/dist/cli/interactive/actions/setup.js.map +1 -0
- package/dist/cli/interactive/lang.d.ts +11 -0
- package/dist/cli/interactive/lang.d.ts.map +1 -0
- package/dist/cli/interactive/lang.js +51 -0
- package/dist/cli/interactive/lang.js.map +1 -0
- package/dist/cli/interactive/menu-defs.d.ts +17 -0
- package/dist/cli/interactive/menu-defs.d.ts.map +1 -0
- package/dist/cli/interactive/menu-defs.js +106 -0
- package/dist/cli/interactive/menu-defs.js.map +1 -0
- package/dist/cli/interactive/render.d.ts +16 -0
- package/dist/cli/interactive/render.d.ts.map +1 -0
- package/dist/cli/interactive/render.js +145 -0
- package/dist/cli/interactive/render.js.map +1 -0
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +64 -1322
- package/dist/cli/interactive.js.map +1 -1
- package/package.json +8 -7
|
@@ -0,0 +1,108 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-types.js","sourceRoot":"","sources":["../../../src/cli/commands/serve-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
* panguard serve - Unified HTTP server gateway
|
|
3
3
|
*
|
|
4
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
|
|
5
11
|
*/
|
|
6
12
|
import { Command } from 'commander';
|
|
7
13
|
export declare function serveCommand(): Command;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA
|
|
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;AAgCpC,wBAAgB,YAAY,IAAI,OAAO,CA0XtC"}
|