@prism-d1/cli 1.6.0 → 1.7.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/src/aws/connect.d.ts +1 -1
- package/dist/src/aws/connect.d.ts.map +1 -1
- package/dist/src/aws/connect.js.map +1 -1
- package/dist/src/commands/_top/dashboard.d.ts +4 -0
- package/dist/src/commands/_top/dashboard.d.ts.map +1 -1
- package/dist/src/commands/_top/dashboard.js +57 -5
- package/dist/src/commands/_top/dashboard.js.map +1 -1
- package/dist/src/dashboard/actions.d.ts +112 -0
- package/dist/src/dashboard/actions.d.ts.map +1 -0
- package/dist/src/dashboard/actions.js +242 -0
- package/dist/src/dashboard/actions.js.map +1 -0
- package/dist/src/dashboard/aws-identity.d.ts +115 -0
- package/dist/src/dashboard/aws-identity.d.ts.map +1 -0
- package/dist/src/dashboard/aws-identity.js +240 -0
- package/dist/src/dashboard/aws-identity.js.map +1 -0
- package/dist/src/dashboard/page.d.ts +2 -2
- package/dist/src/dashboard/page.d.ts.map +1 -1
- package/dist/src/dashboard/page.js +68 -21
- package/dist/src/dashboard/page.js.map +1 -1
- package/dist/src/dashboard/payload.d.ts +28 -1
- package/dist/src/dashboard/payload.d.ts.map +1 -1
- package/dist/src/dashboard/payload.js +34 -7
- package/dist/src/dashboard/payload.js.map +1 -1
- package/dist/src/dashboard/server.d.ts +27 -6
- package/dist/src/dashboard/server.d.ts.map +1 -1
- package/dist/src/dashboard/server.js +75 -10
- package/dist/src/dashboard/server.js.map +1 -1
- package/dist/src/dashboard/setup-api.d.ts +63 -0
- package/dist/src/dashboard/setup-api.d.ts.map +1 -0
- package/dist/src/dashboard/setup-api.js +66 -0
- package/dist/src/dashboard/setup-api.js.map +1 -0
- package/dist/src/dashboard/setup-page.d.ts +16 -0
- package/dist/src/dashboard/setup-page.d.ts.map +1 -0
- package/dist/src/dashboard/setup-page.js +347 -0
- package/dist/src/dashboard/setup-page.js.map +1 -0
- package/dist/src/dashboard/setup.d.ts +53 -1
- package/dist/src/dashboard/setup.d.ts.map +1 -1
- package/dist/src/dashboard/setup.js +126 -16
- package/dist/src/dashboard/setup.js.map +1 -1
- package/dist/src/dashboard/summary.d.ts +2 -0
- package/dist/src/dashboard/summary.d.ts.map +1 -1
- package/dist/src/dashboard/summary.js +1 -1
- package/dist/src/dashboard/summary.js.map +1 -1
- package/dist/src/dashboard/usage-cache.d.ts +44 -0
- package/dist/src/dashboard/usage-cache.d.ts.map +1 -0
- package/dist/src/dashboard/usage-cache.js +90 -0
- package/dist/src/dashboard/usage-cache.js.map +1 -0
- package/dist/src/dashboard/usage.d.ts +14 -1
- package/dist/src/dashboard/usage.d.ts.map +1 -1
- package/dist/src/dashboard/usage.js +45 -12
- package/dist/src/dashboard/usage.js.map +1 -1
- package/dist/src/utils/aws.d.ts +2 -0
- package/dist/src/utils/aws.d.ts.map +1 -1
- package/dist/src/utils/aws.js +1 -1
- package/dist/src/utils/aws.js.map +1 -1
- package/dist/src/utils/exec.d.ts +1 -1
- package/dist/src/utils/exec.d.ts.map +1 -1
- package/dist/src/utils/exec.js +3 -1
- package/dist/src/utils/exec.js.map +1 -1
- package/dist/src/utils/private-json.d.ts +5 -0
- package/dist/src/utils/private-json.d.ts.map +1 -0
- package/dist/src/utils/private-json.js +29 -0
- package/dist/src/utils/private-json.js.map +1 -0
- package/dist/src/utils/tool-check.d.ts +9 -0
- package/dist/src/utils/tool-check.d.ts.map +1 -1
- package/dist/src/utils/tool-check.js +37 -2
- package/dist/src/utils/tool-check.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../src/dashboard/payload.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAA2C,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,
|
|
1
|
+
{"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../../src/dashboard/payload.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ export function tildeHome(p, home) {
|
|
|
19
19
|
return p.startsWith(home + sep) ? '~' + p.slice(home.length) : p;
|
|
20
20
|
}
|
|
21
21
|
import { collectUsage, spendByRepo } from './usage.js';
|
|
22
|
+
import { versionCachePath } from './usage-cache.js';
|
|
22
23
|
import { collectSecurity } from './security.js';
|
|
23
24
|
import { collectAws } from './aws.js';
|
|
24
25
|
export const PAYLOAD_SCHEMA = 'prism.dashboard.v2';
|
|
@@ -38,6 +39,19 @@ export function globalSuggestion(g, missing) {
|
|
|
38
39
|
reason: `${missing} repos don't have codewatch. Cover all of them at once.`,
|
|
39
40
|
};
|
|
40
41
|
}
|
|
42
|
+
/** At most this many repos are checked at once (each check is one git process). */
|
|
43
|
+
export const GIT_CONCURRENCY = 8;
|
|
44
|
+
/** fn over items, at most `limit` running at a time; results keep the input order. */
|
|
45
|
+
export async function mapLimit(items, limit, fn) {
|
|
46
|
+
const out = new Array(items.length);
|
|
47
|
+
let next = 0;
|
|
48
|
+
const worker = async () => { while (next < items.length) {
|
|
49
|
+
const i = next++;
|
|
50
|
+
out[i] = await fn(items[i]);
|
|
51
|
+
} };
|
|
52
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
|
|
53
|
+
return out;
|
|
54
|
+
}
|
|
41
55
|
const byName = (a, b) => a.name.localeCompare(b.name) || a.path.localeCompare(b.path);
|
|
42
56
|
const STATUS_ORDER = { ok: 0, warn: 1, missing: 2, 'opted-out': 3 };
|
|
43
57
|
/** The current repo first, then repos with activity, then installed, bypassed (warn), missing and opted-out repos, each by name. */
|
|
@@ -49,16 +63,29 @@ export function sortCodewatchRows(rows) {
|
|
|
49
63
|
return [...rows].sort((a, b) => Number(b.active) - Number(a.active) || b.high - a.high || b.medium - a.medium || b.low - a.low || byName(a, b));
|
|
50
64
|
}
|
|
51
65
|
export async function buildPayload(opts) {
|
|
66
|
+
const t0 = Date.now();
|
|
52
67
|
const d = discoverRepos(opts);
|
|
53
|
-
const
|
|
54
|
-
|
|
68
|
+
const tScan = Date.now();
|
|
69
|
+
// Usage (codeburn) and the git checks are child processes: start both, then do the in-process work while they run.
|
|
70
|
+
let usageMs = 0;
|
|
71
|
+
const usageP = (opts.usage || (async () => ({ usage: await collectUsage({ exporter: opts.exporter, pathEnv: opts.pathEnv }), cacheHit: false })))()
|
|
72
|
+
.finally(() => { usageMs = Date.now() - tScan; });
|
|
55
73
|
const g = globalStatus(opts.home || homedir());
|
|
74
|
+
const setupsP = mapLimit(d.repos, GIT_CONCURRENCY, (r) => codewatchSetup(r.path, { pathEnv: opts.pathEnv, global: g, git: opts.git }));
|
|
75
|
+
// One turn of the event loop: a cache hit settles here, so its timing is not the sync work below.
|
|
76
|
+
await new Promise((r) => setImmediate(r));
|
|
77
|
+
const gitleaksAvailable = findOnPath('gitleaks', opts.pathEnv) !== null;
|
|
78
|
+
const machineSetup = machineChecks({ pathEnv: opts.pathEnv, global: g, versionCache: versionCachePath(opts.machineDeps?.home || opts.home || homedir()), ...opts.machineDeps });
|
|
56
79
|
const labels = repoLabels(d.repos.map((r) => r.path));
|
|
57
|
-
const spend = spendByRepo(usage.projects, d.repos.map((r) => r.path));
|
|
58
80
|
// Read each repo's results once; the Security panel below reuses them.
|
|
59
81
|
const results = new Map(d.repos.map((r) => [r.path, readResults(r.path)]));
|
|
60
|
-
const
|
|
61
|
-
|
|
82
|
+
const codewatchByRepo = new Map(d.repos.map((r) => [r.path, collectCodewatch(r.path, opts.trendRuns, gitleaksAvailable)]));
|
|
83
|
+
const setups = await setupsP;
|
|
84
|
+
const setupMs = Date.now() - tScan;
|
|
85
|
+
const { usage, cacheHit } = await usageP;
|
|
86
|
+
const spend = spendByRepo(usage.projects, d.repos.map((r) => r.path));
|
|
87
|
+
const repos = d.repos.map((r, i) => {
|
|
88
|
+
const codewatch = codewatchByRepo.get(r.path);
|
|
62
89
|
const repoResults = results.get(r.path) || [];
|
|
63
90
|
const s = spend.get(r.path) || null;
|
|
64
91
|
const securityResults = repoResults.some((x) => SECURITY_RESULT_KINDS.some(([k]) => k === x.kind));
|
|
@@ -71,7 +98,7 @@ export async function buildPayload(opts) {
|
|
|
71
98
|
current: r.current,
|
|
72
99
|
hasPrism: r.hasPrism,
|
|
73
100
|
codewatch,
|
|
74
|
-
setup:
|
|
101
|
+
setup: setups[i],
|
|
75
102
|
security: securitySetup(r.path, repoResults),
|
|
76
103
|
};
|
|
77
104
|
});
|
|
@@ -94,7 +121,6 @@ export async function buildPayload(opts) {
|
|
|
94
121
|
unscannedCommits: r.codewatch.secretScanning.unscannedCommits,
|
|
95
122
|
gitleaksWarning: r.codewatch.secretScanning.unscannedCommits > 0,
|
|
96
123
|
})));
|
|
97
|
-
const machineSetup = machineChecks({ pathEnv: opts.pathEnv, global: g, ...opts.machineDeps });
|
|
98
124
|
return {
|
|
99
125
|
schema: PAYLOAD_SCHEMA,
|
|
100
126
|
generated_at: new Date().toISOString(),
|
|
@@ -112,6 +138,7 @@ export async function buildPayload(opts) {
|
|
|
112
138
|
security: collectSecurity(repos, (p) => results.get(p) ?? readResults(p)),
|
|
113
139
|
aws: collectAws([...repos.map((r) => r.path), opts.home || homedir()]),
|
|
114
140
|
summary: buildSummary(repos, usage, machineSetup),
|
|
141
|
+
timing: { scan: tScan - t0, setup: setupMs, usage: usageMs, total: Date.now() - t0, cacheHit },
|
|
115
142
|
};
|
|
116
143
|
}
|
|
117
144
|
//# sourceMappingURL=payload.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/dashboard/payload.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAA4C,MAAM,gBAAgB,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAwB,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"payload.js","sourceRoot":"","sources":["../../../src/dashboard/payload.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
* cookie on every request (compared in constant time);
|
|
9
9
|
* - the Host header must be 127.0.0.1:<port> or localhost:<port>, which
|
|
10
10
|
* defeats DNS rebinding (a rebound name arrives with its own Host);
|
|
11
|
-
* - GET
|
|
11
|
+
* - GET for every read route; no CORS headers; strict CSP.
|
|
12
|
+
* - POST only for the Setup page's action routes (postApi), and each POST
|
|
13
|
+
* also needs: an Origin (or, without one, a Referer) of this server; the
|
|
14
|
+
* per-run anti-CSRF token embedded in the page, in the X-Prism-CSRF header;
|
|
15
|
+
* and Content-Type application/json with a body of at most 16 KB.
|
|
12
16
|
*
|
|
13
17
|
* Why a minted token and not a platform auth mechanism: the server is
|
|
14
18
|
* reachable only from this machine, the audience is the developer running it,
|
|
@@ -23,6 +27,8 @@ export declare function newToken(): string;
|
|
|
23
27
|
export declare function cookieName(port: number): string;
|
|
24
28
|
export interface HandlerOptions {
|
|
25
29
|
token: string;
|
|
30
|
+
/** Per-run anti-CSRF token, embedded in the page and required on every POST. */
|
|
31
|
+
csrf?: string;
|
|
26
32
|
/** Read at request time: the real port is known only after listen(). */
|
|
27
33
|
getPort: () => number;
|
|
28
34
|
getPayload: () => Promise<unknown>;
|
|
@@ -31,22 +37,37 @@ export interface HandlerOptions {
|
|
|
31
37
|
* matched against directory listings only; it is never turned into a path.
|
|
32
38
|
*/
|
|
33
39
|
getReport?: (id: string) => Promise<ScanReport | null>;
|
|
40
|
+
/** Extra read-only JSON routes (GET), by exact path; receive the request URL (for its query). */
|
|
41
|
+
getApi?: Record<string, (url: URL) => Promise<unknown>>;
|
|
42
|
+
/** Action routes (POST only), by exact path; receive the parsed JSON body. */
|
|
43
|
+
postApi?: Record<string, (body: unknown) => Promise<{
|
|
44
|
+
status: number;
|
|
45
|
+
json: unknown;
|
|
46
|
+
}>>;
|
|
34
47
|
}
|
|
48
|
+
export declare const CSRF_HEADER = "x-prism-csrf";
|
|
49
|
+
export declare const MAX_BODY: number;
|
|
35
50
|
export declare function createHandler(opts: HandlerOptions): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
36
51
|
export interface RunningServer {
|
|
37
52
|
server: Server;
|
|
38
53
|
port: number;
|
|
39
54
|
token: string;
|
|
55
|
+
csrf: string;
|
|
40
56
|
url: string;
|
|
41
57
|
close: () => Promise<void>;
|
|
42
58
|
}
|
|
43
|
-
|
|
44
|
-
export declare function startServer(opts: {
|
|
59
|
+
export interface StartOptions {
|
|
45
60
|
port?: number;
|
|
46
61
|
token?: string;
|
|
47
62
|
getPayload: () => Promise<unknown>;
|
|
48
63
|
getReport?: (id: string) => Promise<ScanReport | null>;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
getApi?: HandlerOptions['getApi'];
|
|
65
|
+
postApi?: HandlerOptions['postApi'];
|
|
66
|
+
}
|
|
67
|
+
/** Starts the server on 127.0.0.1. `port` 0 (default) picks a free port. */
|
|
68
|
+
export declare function startServer(opts: StartOptions): Promise<RunningServer>;
|
|
69
|
+
/** Memoises the payload for `ttlMs` and shares one in-flight build between requests. `invalidate()` forces the next build. */
|
|
70
|
+
export declare function cachedPayload(build: () => Promise<unknown>, ttlMs?: number): (() => Promise<unknown>) & {
|
|
71
|
+
invalidate(): void;
|
|
72
|
+
};
|
|
52
73
|
//# sourceMappingURL=server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAGjG,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtF,eAAO,MAAM,SAAS,cAAc,CAAC;AAErC,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAqCD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACvD,iGAAiG;IACjG,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAC;CACzF;AAKD,eAAO,MAAM,WAAW,iBAAiB,CAAC;AAC1C,eAAO,MAAM,QAAQ,QAAY,CAAC;AAiClC,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,IAClC,KAAK,eAAe,EAAE,KAAK,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC,CAyExE;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IAClC,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;CACrC;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAqBtE;AAED,8HAA8H;AAC9H,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,GAAG,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG;IAAE,UAAU,IAAI,IAAI,CAAA;CAAE,CAY9H"}
|
|
@@ -8,7 +8,11 @@
|
|
|
8
8
|
* cookie on every request (compared in constant time);
|
|
9
9
|
* - the Host header must be 127.0.0.1:<port> or localhost:<port>, which
|
|
10
10
|
* defeats DNS rebinding (a rebound name arrives with its own Host);
|
|
11
|
-
* - GET
|
|
11
|
+
* - GET for every read route; no CORS headers; strict CSP.
|
|
12
|
+
* - POST only for the Setup page's action routes (postApi), and each POST
|
|
13
|
+
* also needs: an Origin (or, without one, a Referer) of this server; the
|
|
14
|
+
* per-run anti-CSRF token embedded in the page, in the X-Prism-CSRF header;
|
|
15
|
+
* and Content-Type application/json with a body of at most 16 KB.
|
|
12
16
|
*
|
|
13
17
|
* Why a minted token and not a platform auth mechanism: the server is
|
|
14
18
|
* reachable only from this machine, the audience is the developer running it,
|
|
@@ -64,6 +68,39 @@ function send(res, status, type, body, extra = {}, nonce) {
|
|
|
64
68
|
}
|
|
65
69
|
/** /report/<id> or /report/<id>.md; anything else (slashes, dots, %-escapes) does not match. */
|
|
66
70
|
const REPORT_ROUTE = /^\/report\/([A-Za-z0-9_-]{1,120})(\.md)?$/;
|
|
71
|
+
export const CSRF_HEADER = 'x-prism-csrf';
|
|
72
|
+
export const MAX_BODY = 16 * 1024;
|
|
73
|
+
const own = (o, k) => o && Object.prototype.hasOwnProperty.call(o, k) ? o[k] : undefined;
|
|
74
|
+
function readBody(req) {
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
let size = 0;
|
|
77
|
+
const chunks = [];
|
|
78
|
+
const onData = (c) => {
|
|
79
|
+
size += c.length;
|
|
80
|
+
// Too big: stop buffering and answer 413 (sent with Connection: close); the rest is drained, not kept.
|
|
81
|
+
if (size > MAX_BODY) {
|
|
82
|
+
req.off('data', onData);
|
|
83
|
+
req.resume();
|
|
84
|
+
resolve(null);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
chunks.push(c);
|
|
88
|
+
};
|
|
89
|
+
req.on('data', onData);
|
|
90
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
91
|
+
req.on('error', reject);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/** The request's Origin, else its Referer, must be this server (either Host spelling). */
|
|
95
|
+
function sameOrigin(req, port) {
|
|
96
|
+
const allowed = [`http://${BIND_HOST}:${port}`, `http://localhost:${port}`];
|
|
97
|
+
const origin = req.headers.origin;
|
|
98
|
+
if (typeof origin === 'string')
|
|
99
|
+
return allowed.includes(origin);
|
|
100
|
+
const ref = req.headers.referer;
|
|
101
|
+
return typeof ref === 'string' && allowed.some((a) => ref === a || ref.startsWith(a + '/'));
|
|
102
|
+
}
|
|
103
|
+
const json = (res, status, body) => send(res, status, 'application/json; charset=utf-8', JSON.stringify(body));
|
|
67
104
|
export function createHandler(opts) {
|
|
68
105
|
return async (req, res) => {
|
|
69
106
|
try {
|
|
@@ -72,16 +109,17 @@ export function createHandler(opts) {
|
|
|
72
109
|
if (host !== `${BIND_HOST}:${port}` && host !== `localhost:${port}`) {
|
|
73
110
|
return send(res, 403, 'text/plain; charset=utf-8', 'Forbidden: unexpected Host header\n');
|
|
74
111
|
}
|
|
75
|
-
if (req.method !== 'GET') {
|
|
76
|
-
return send(res, 405, 'text/plain; charset=utf-8', 'Method Not Allowed\n', { Allow: 'GET' });
|
|
77
|
-
}
|
|
78
112
|
const url = new URL(req.url || '/', `http://${BIND_HOST}:${port}`);
|
|
113
|
+
const post = own(opts.postApi, url.pathname);
|
|
114
|
+
if (post ? req.method !== 'POST' : req.method !== 'GET') {
|
|
115
|
+
return send(res, 405, 'text/plain; charset=utf-8', 'Method Not Allowed\n', { Allow: post ? 'POST' : 'GET' });
|
|
116
|
+
}
|
|
79
117
|
const name = cookieName(port);
|
|
80
118
|
const cookie = readCookie(req, name);
|
|
81
119
|
const cookieOk = cookie !== null && safeEqual(cookie, opts.token);
|
|
82
120
|
// First load: exchange the URL token for the cookie, then drop it from the URL.
|
|
83
121
|
const qToken = url.searchParams.get('token');
|
|
84
|
-
if (url.pathname === '/' && qToken !== null) {
|
|
122
|
+
if (!post && url.pathname === '/' && qToken !== null) {
|
|
85
123
|
if (!safeEqual(qToken, opts.token))
|
|
86
124
|
return send(res, 401, 'text/plain; charset=utf-8', 'Unauthorized\n');
|
|
87
125
|
return send(res, 303, 'text/plain; charset=utf-8', 'See Other\n', {
|
|
@@ -92,14 +130,39 @@ export function createHandler(opts) {
|
|
|
92
130
|
if (!cookieOk) {
|
|
93
131
|
return send(res, 401, 'text/plain; charset=utf-8', 'Unauthorized: open the URL printed by prism-cli dashboard\n');
|
|
94
132
|
}
|
|
133
|
+
if (post) {
|
|
134
|
+
if (!sameOrigin(req, port))
|
|
135
|
+
return json(res, 403, { error: 'Forbidden: missing or foreign Origin' });
|
|
136
|
+
const csrf = req.headers[CSRF_HEADER];
|
|
137
|
+
if (!opts.csrf || typeof csrf !== 'string' || !safeEqual(csrf, opts.csrf))
|
|
138
|
+
return json(res, 403, { error: 'Forbidden: missing or wrong CSRF token' });
|
|
139
|
+
const type = String(req.headers['content-type'] || '').split(';')[0].trim().toLowerCase();
|
|
140
|
+
if (type !== 'application/json')
|
|
141
|
+
return json(res, 415, { error: 'Content-Type must be application/json' });
|
|
142
|
+
const raw = await readBody(req);
|
|
143
|
+
if (raw === null)
|
|
144
|
+
return send(res, 413, 'application/json; charset=utf-8', JSON.stringify({ error: 'request body too large' }), { Connection: 'close' });
|
|
145
|
+
let body;
|
|
146
|
+
try {
|
|
147
|
+
body = JSON.parse(raw);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return json(res, 400, { error: 'invalid JSON' });
|
|
151
|
+
}
|
|
152
|
+
const r = await post(body);
|
|
153
|
+
return json(res, r.status, r.json);
|
|
154
|
+
}
|
|
95
155
|
if (url.pathname === '/') {
|
|
96
156
|
const nonce = randomBytes(16).toString('base64');
|
|
97
|
-
return send(res, 200, 'text/html; charset=utf-8', renderPage(nonce), {}, nonce);
|
|
157
|
+
return send(res, 200, 'text/html; charset=utf-8', renderPage(nonce, opts.csrf), {}, nonce);
|
|
98
158
|
}
|
|
99
159
|
if (url.pathname === '/api/data') {
|
|
100
160
|
const payload = await opts.getPayload();
|
|
101
161
|
return send(res, 200, 'application/json; charset=utf-8', JSON.stringify(payload));
|
|
102
162
|
}
|
|
163
|
+
const extra = own(opts.getApi, url.pathname);
|
|
164
|
+
if (extra)
|
|
165
|
+
return json(res, 200, await extra(url));
|
|
103
166
|
const m = REPORT_ROUTE.exec(url.pathname);
|
|
104
167
|
if (m && opts.getReport) {
|
|
105
168
|
const report = await opts.getReport(m[1]);
|
|
@@ -127,8 +190,9 @@ export function createHandler(opts) {
|
|
|
127
190
|
/** Starts the server on 127.0.0.1. `port` 0 (default) picks a free port. */
|
|
128
191
|
export function startServer(opts) {
|
|
129
192
|
const token = opts.token || newToken();
|
|
193
|
+
const csrf = newToken();
|
|
130
194
|
let port = 0;
|
|
131
|
-
const server = createServer(createHandler({ token, getPort: () => port, getPayload: opts.getPayload, getReport: opts.getReport }));
|
|
195
|
+
const server = createServer(createHandler({ token, csrf, getPort: () => port, getPayload: opts.getPayload, getReport: opts.getReport, getApi: opts.getApi, postApi: opts.postApi }));
|
|
132
196
|
return new Promise((resolve, reject) => {
|
|
133
197
|
server.once('error', reject);
|
|
134
198
|
server.listen(opts.port ?? 0, BIND_HOST, () => {
|
|
@@ -139,19 +203,19 @@ export function startServer(opts) {
|
|
|
139
203
|
}
|
|
140
204
|
port = addr.port;
|
|
141
205
|
resolve({
|
|
142
|
-
server, port, token,
|
|
206
|
+
server, port, token, csrf,
|
|
143
207
|
url: `http://${BIND_HOST}:${port}/?token=${token}`,
|
|
144
208
|
close: () => new Promise((r) => server.close(() => r())),
|
|
145
209
|
});
|
|
146
210
|
});
|
|
147
211
|
});
|
|
148
212
|
}
|
|
149
|
-
/** Memoises the payload for `ttlMs` and shares one in-flight build between requests. */
|
|
213
|
+
/** Memoises the payload for `ttlMs` and shares one in-flight build between requests. `invalidate()` forces the next build. */
|
|
150
214
|
export function cachedPayload(build, ttlMs = 30_000) {
|
|
151
215
|
let at = 0;
|
|
152
216
|
let pending = null;
|
|
153
217
|
let value;
|
|
154
|
-
|
|
218
|
+
const get = () => {
|
|
155
219
|
if (value !== undefined && Date.now() - at < ttlMs)
|
|
156
220
|
return Promise.resolve(value);
|
|
157
221
|
if (!pending) {
|
|
@@ -159,5 +223,6 @@ export function cachedPayload(build, ttlMs = 30_000) {
|
|
|
159
223
|
}
|
|
160
224
|
return pending;
|
|
161
225
|
};
|
|
226
|
+
return Object.assign(get, { invalidate: () => { at = 0; } });
|
|
162
227
|
}
|
|
163
228
|
//# sourceMappingURL=server.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/dashboard/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { type ActionId, type ActionRunner, type ApiResult } from './actions.js';
|
|
2
|
+
import { type CheckNowDeps, type IdentityDeps } from './aws-identity.js';
|
|
3
|
+
/** Commands the page shows as Copy only: each writes to AWS, needs a terminal, or both. */
|
|
4
|
+
export declare const COPY_ONLY: {
|
|
5
|
+
enableSecurity: string;
|
|
6
|
+
addDeveloper: string;
|
|
7
|
+
codeReview: string;
|
|
8
|
+
threatModel: string;
|
|
9
|
+
pentest: string;
|
|
10
|
+
awsConnect: string;
|
|
11
|
+
};
|
|
12
|
+
export interface SetupApiDeps {
|
|
13
|
+
runner: ActionRunner;
|
|
14
|
+
repoPaths(): Promise<string[]>;
|
|
15
|
+
identity: IdentityDeps;
|
|
16
|
+
/** Where repo-less actions run, for the confirm dialog. */
|
|
17
|
+
cwd: string;
|
|
18
|
+
refresh(): Promise<unknown>;
|
|
19
|
+
checkAws?: CheckNowDeps['aws'];
|
|
20
|
+
now?: () => Date;
|
|
21
|
+
}
|
|
22
|
+
export declare function setupApi(d: SetupApiDeps): {
|
|
23
|
+
getApi: {
|
|
24
|
+
'/api/setup': () => Promise<{
|
|
25
|
+
actions: {
|
|
26
|
+
id: ActionId;
|
|
27
|
+
label: string;
|
|
28
|
+
command: string;
|
|
29
|
+
repo: boolean;
|
|
30
|
+
url: boolean;
|
|
31
|
+
confirm: boolean;
|
|
32
|
+
readOnlyAws: boolean;
|
|
33
|
+
timeoutSec: number;
|
|
34
|
+
available: boolean;
|
|
35
|
+
}[];
|
|
36
|
+
repoIds: {
|
|
37
|
+
[k: string]: string;
|
|
38
|
+
};
|
|
39
|
+
/** `cd <repo>` prefixes for the copy-only per-repo commands. */
|
|
40
|
+
repoCd: {
|
|
41
|
+
[k: string]: string;
|
|
42
|
+
};
|
|
43
|
+
cwd: string;
|
|
44
|
+
copy: {
|
|
45
|
+
gitleaks: string;
|
|
46
|
+
enableSecurity: string;
|
|
47
|
+
addDeveloper: string;
|
|
48
|
+
codeReview: string;
|
|
49
|
+
threatModel: string;
|
|
50
|
+
pentest: string;
|
|
51
|
+
awsConnect: string;
|
|
52
|
+
};
|
|
53
|
+
aws: import("./aws-identity.js").AwsIdentityView;
|
|
54
|
+
}>;
|
|
55
|
+
'/api/action/status': () => Promise<import("./actions.js").ActionStatus>;
|
|
56
|
+
'/api/recheck': () => Promise<unknown>;
|
|
57
|
+
};
|
|
58
|
+
postApi: {
|
|
59
|
+
'/api/action': (body: unknown) => Promise<ApiResult>;
|
|
60
|
+
'/api/check-now': (body: unknown) => Promise<ApiResult>;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=setup-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-api.d.ts","sourceRoot":"","sources":["../../../src/dashboard/setup-api.ts"],"names":[],"mappings":"AAUA,OAAO,EAA2C,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AACzH,OAAO,EAA6C,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIpH,2FAA2F;AAC3F,eAAO,MAAM,SAAS;;;;;;;CAOrB,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/B,QAAQ,EAAE,YAAY,CAAC;IACvB,2DAA2D;IAC3D,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,QAAQ,CAAC,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,YAAY;;;;;;;;;;;;;;;;;YAe9B,gEAAgE;;;;;;;;;;;;;;;;;;;;8BAW9C,OAAO,KAAG,OAAO,CAAC,SAAS,CAAC;iCACzB,OAAO,KAAG,OAAO,CAAC,SAAS,CAAC;;EAc1D"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routes behind the Setup page:
|
|
3
|
+
* GET /api/setup action catalog, repo ids, copy-only commands, AWS identity (no AWS call)
|
|
4
|
+
* GET /api/action/status the current or last action and its redacted output
|
|
5
|
+
* GET /api/recheck rebuilds the dashboard data now (status checks)
|
|
6
|
+
* POST /api/action start an allowlisted action
|
|
7
|
+
* POST /api/check-now one read-only sts get-caller-identity
|
|
8
|
+
* Account ids and ARNs appear only here and in the page, never in `dashboard --json`.
|
|
9
|
+
*/
|
|
10
|
+
import { gitleaksInstallHint, shellPath } from './setup.js';
|
|
11
|
+
import { ACTIONS, displayCommand, redact, repoId } from './actions.js';
|
|
12
|
+
import { checkNow, checkNowAws, resolveAwsIdentity } from './aws-identity.js';
|
|
13
|
+
import { loadConnection } from '../aws/connection.js';
|
|
14
|
+
import { tildeHome } from './payload.js';
|
|
15
|
+
/** Commands the page shows as Copy only: each writes to AWS, needs a terminal, or both. */
|
|
16
|
+
export const COPY_ONLY = {
|
|
17
|
+
enableSecurity: 'prism-cli enable security',
|
|
18
|
+
addDeveloper: 'prism-cli team add-developer <email>',
|
|
19
|
+
codeReview: 'prism-cli security code-review',
|
|
20
|
+
threatModel: 'prism-cli security threat-model',
|
|
21
|
+
pentest: 'prism-cli security pentest',
|
|
22
|
+
awsConnect: 'prism-cli aws connect',
|
|
23
|
+
};
|
|
24
|
+
export function setupApi(d) {
|
|
25
|
+
const catalog = () => Object.keys(ACTIONS).map((id) => {
|
|
26
|
+
const a = ACTIONS[id];
|
|
27
|
+
return {
|
|
28
|
+
id, label: a.label, command: displayCommand(a.args), repo: !!a.repo, url: !!a.url, confirm: !!a.confirm,
|
|
29
|
+
readOnlyAws: !!a.readOnlyAws, timeoutSec: a.timeoutMs / 1000, available: d.runner.available(id),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
return {
|
|
33
|
+
getApi: {
|
|
34
|
+
'/api/setup': async () => {
|
|
35
|
+
const paths = await d.repoPaths();
|
|
36
|
+
return {
|
|
37
|
+
actions: catalog(),
|
|
38
|
+
repoIds: Object.fromEntries(paths.map((p) => [p, repoId(p)])),
|
|
39
|
+
/** `cd <repo>` prefixes for the copy-only per-repo commands. */
|
|
40
|
+
repoCd: Object.fromEntries(paths.map((p) => [p, `cd ${shellPath(p)}`])),
|
|
41
|
+
cwd: tildeHome(d.cwd, d.identity.home),
|
|
42
|
+
copy: { ...COPY_ONLY, gitleaks: gitleaksInstallHint() },
|
|
43
|
+
aws: resolveAwsIdentity(d.identity),
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
'/api/action/status': async () => d.runner.status(),
|
|
47
|
+
'/api/recheck': async () => d.refresh(),
|
|
48
|
+
},
|
|
49
|
+
postApi: {
|
|
50
|
+
'/api/action': (body) => d.runner.start(body),
|
|
51
|
+
'/api/check-now': (body) => {
|
|
52
|
+
if (!body || typeof body !== 'object' || Array.isArray(body) || Object.keys(body).length) {
|
|
53
|
+
return Promise.resolve({ status: 400, json: { error: 'check-now takes an empty JSON object' } });
|
|
54
|
+
}
|
|
55
|
+
return d.runner.exclusive(() => checkNow({
|
|
56
|
+
identity: resolveAwsIdentity(d.identity),
|
|
57
|
+
saved: loadConnection(d.identity.home, d.identity.repoRoot),
|
|
58
|
+
aws: d.checkAws ?? checkNowAws,
|
|
59
|
+
now: d.now ?? (() => new Date()),
|
|
60
|
+
redact,
|
|
61
|
+
}));
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=setup-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-api.js","sourceRoot":"","sources":["../../../src/dashboard/setup-api.ts"],"names":[],"mappings":"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"}
|