@prism-d1/cli 1.6.0 → 1.7.0

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.
Files changed (43) hide show
  1. package/dist/src/aws/connect.d.ts +1 -1
  2. package/dist/src/aws/connect.d.ts.map +1 -1
  3. package/dist/src/aws/connect.js.map +1 -1
  4. package/dist/src/commands/_top/dashboard.d.ts.map +1 -1
  5. package/dist/src/commands/_top/dashboard.js +22 -3
  6. package/dist/src/commands/_top/dashboard.js.map +1 -1
  7. package/dist/src/dashboard/actions.d.ts +112 -0
  8. package/dist/src/dashboard/actions.d.ts.map +1 -0
  9. package/dist/src/dashboard/actions.js +242 -0
  10. package/dist/src/dashboard/actions.js.map +1 -0
  11. package/dist/src/dashboard/aws-identity.d.ts +115 -0
  12. package/dist/src/dashboard/aws-identity.d.ts.map +1 -0
  13. package/dist/src/dashboard/aws-identity.js +240 -0
  14. package/dist/src/dashboard/aws-identity.js.map +1 -0
  15. package/dist/src/dashboard/page.d.ts +1 -1
  16. package/dist/src/dashboard/page.d.ts.map +1 -1
  17. package/dist/src/dashboard/page.js +23 -7
  18. package/dist/src/dashboard/page.js.map +1 -1
  19. package/dist/src/dashboard/server.d.ts +27 -6
  20. package/dist/src/dashboard/server.d.ts.map +1 -1
  21. package/dist/src/dashboard/server.js +75 -10
  22. package/dist/src/dashboard/server.js.map +1 -1
  23. package/dist/src/dashboard/setup-api.d.ts +63 -0
  24. package/dist/src/dashboard/setup-api.d.ts.map +1 -0
  25. package/dist/src/dashboard/setup-api.js +66 -0
  26. package/dist/src/dashboard/setup-api.js.map +1 -0
  27. package/dist/src/dashboard/setup-page.d.ts +16 -0
  28. package/dist/src/dashboard/setup-page.d.ts.map +1 -0
  29. package/dist/src/dashboard/setup-page.js +347 -0
  30. package/dist/src/dashboard/setup-page.js.map +1 -0
  31. package/dist/src/dashboard/setup.d.ts +2 -0
  32. package/dist/src/dashboard/setup.d.ts.map +1 -1
  33. package/dist/src/dashboard/setup.js +1 -1
  34. package/dist/src/dashboard/setup.js.map +1 -1
  35. package/dist/src/utils/aws.d.ts +2 -0
  36. package/dist/src/utils/aws.d.ts.map +1 -1
  37. package/dist/src/utils/aws.js +1 -1
  38. package/dist/src/utils/aws.js.map +1 -1
  39. package/dist/src/utils/exec.d.ts +1 -1
  40. package/dist/src/utils/exec.d.ts.map +1 -1
  41. package/dist/src/utils/exec.js +3 -1
  42. package/dist/src/utils/exec.js.map +1 -1
  43. package/package.json +1 -1
@@ -0,0 +1,115 @@
1
+ import { aws } from '../utils/aws.js';
2
+ import { writeConnectionFile, type SavedConnection } from '../aws/connection.js';
3
+ /** Section name -> its key names (lower case), plus the region value: the only value kept. */
4
+ export type IniKeys = Map<string, {
5
+ keys: Set<string>;
6
+ region?: string;
7
+ }>;
8
+ /**
9
+ * Key names per section. Values are discarded line by line; `region` is kept
10
+ * only when it looks like a region name. Indented lines are nested settings
11
+ * (e.g. s3 = ...) and are skipped.
12
+ */
13
+ export declare function iniKeys(text: string, kind: 'config' | 'credentials'): IniKeys;
14
+ export type CredentialType = 'credential_process' | 'sso' | 'static-credentials-file' | 'static-config-file' | 'assume-role' | 'web-identity' | 'env' | 'container' | 'none';
15
+ export declare const CREDENTIAL_TYPE_LABEL: Record<CredentialType, string>;
16
+ /**
17
+ * The type the AWS CLI would use for `profile`, in its provider order within a
18
+ * profile: role_arn, web identity, SSO, keys in the credentials file,
19
+ * credential_process, keys in the config file. `shadowed` lists the types that
20
+ * are configured but lose.
21
+ */
22
+ export declare function classifyProfile(profile: string, config: IniKeys, creds: IniKeys): {
23
+ type: CredentialType;
24
+ shadowed: CredentialType[];
25
+ };
26
+ export interface ResolutionStep {
27
+ id: 'flags' | 'env' | 'repo' | 'user' | 'default';
28
+ label: string;
29
+ /** used: this step chose the credentials. skipped: set, but an earlier step won. */
30
+ state: 'used' | 'skipped' | 'not-set' | 'n/a';
31
+ detail: string;
32
+ }
33
+ export interface AwsIdentityView {
34
+ /** Profile name the AWS CLI is given, or null (env keys, container, or nothing). */
35
+ profile: string | null;
36
+ /** Why: "AWS_PROFILE", "aws connect, repo", "default chain", ... */
37
+ source: string;
38
+ credentialType: CredentialType;
39
+ credentialLabel: string;
40
+ region: {
41
+ value: string;
42
+ source: string;
43
+ } | null;
44
+ steps: ResolutionStep[];
45
+ /** The saved aws connect connection (the repo file, else the user file), whether or not it is in use. */
46
+ saved: null | {
47
+ scope: 'repo' | 'user';
48
+ path: string;
49
+ profile: string;
50
+ region: string;
51
+ account: string;
52
+ alias: string | null;
53
+ verifiedAt: string;
54
+ inUse: boolean;
55
+ };
56
+ warnings: string[];
57
+ files: {
58
+ config: string;
59
+ credentials: string;
60
+ configFound: boolean;
61
+ credentialsFound: boolean;
62
+ };
63
+ }
64
+ export interface IdentityDeps {
65
+ env: NodeJS.ProcessEnv;
66
+ home: string;
67
+ /** The repo the dashboard runs in (for .prism/aws.local.json), or null. */
68
+ repoRoot: string | null;
69
+ /** File reader; null when the file is missing or unreadable. */
70
+ readText?: (path: string) => string | null;
71
+ }
72
+ export declare const STATIC_DEFAULT_WARNING = "The default profile has static keys in ~/.aws/credentials. Static keys win over a credential_process or SSO setting for the same profile, and they often expire. If you sign in with credential_process or SSO, remove the keys from [default] in ~/.aws/credentials.";
73
+ export declare const NO_CREDENTIALS_WARNING = "No AWS credentials found: no AWS env var, no saved aws connect profile, and no default profile in ~/.aws/config or ~/.aws/credentials. Set one up with aws configure sso (or aws configure), then run prism-cli aws connect.";
74
+ /** What prism-cli would use, from local files and env only. No AWS call, no aws CLI call. */
75
+ export declare function resolveAwsIdentity(d: IdentityDeps): AwsIdentityView;
76
+ export type CheckNowResult = {
77
+ ok: true;
78
+ account: string;
79
+ arn: string;
80
+ region: string | null;
81
+ profile: string | null;
82
+ savedAccount: string | null;
83
+ matches: boolean | null;
84
+ updated: boolean;
85
+ note: string;
86
+ } | {
87
+ ok: false;
88
+ expired: boolean;
89
+ error: string;
90
+ profile: string | null;
91
+ region: string | null;
92
+ fixes: string[];
93
+ };
94
+ export interface CheckNowDeps {
95
+ identity: AwsIdentityView;
96
+ /** The saved connection behind identity.saved (with its real path), or null. */
97
+ saved: SavedConnection | null;
98
+ /** Same shape as aws connect's deps.aws: one read-only `aws <args>` call. */
99
+ aws(args: string[], profile: string, region: string): ReturnType<typeof aws>;
100
+ now(): Date;
101
+ write?: typeof writeConnectionFile;
102
+ redact(s: string): string;
103
+ }
104
+ /** The fixes to suggest for a failed check, by credential type. */
105
+ export declare function checkFixes(v: AwsIdentityView): string[];
106
+ /** The default `aws` call for Check now: aws connect's call, with the region optional and a timeout. */
107
+ export declare const CHECK_NOW_TIMEOUT_MS = 30000;
108
+ export declare function checkNowAws(args: string[], profile: string, region: string): import("../utils/aws.js").AwsResult;
109
+ /**
110
+ * One read-only `sts get-caller-identity`, through aws connect's callerIdentity.
111
+ * On a match with the saved connection (same profile and region), the saved
112
+ * file's verifiedAt is refreshed; nothing else is written.
113
+ */
114
+ export declare function checkNow(d: CheckNowDeps): CheckNowResult;
115
+ //# sourceMappingURL=aws-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-identity.d.ts","sourceRoot":"","sources":["../../../src/dashboard/aws-identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,240 @@
1
+ /**
2
+ * The Setup page's AWS section: which credentials prism-cli would use and why,
3
+ * with no AWS call, and the one read-only "Check now" call.
4
+ *
5
+ * Resolution follows the order every AWS command uses (aws/connection.ts):
6
+ * flags (none here), env credentials, .prism/aws.local.json, ~/.prism/aws.json,
7
+ * then the default chain. The credential TYPE comes from the KEY NAMES in
8
+ * ~/.aws/config and ~/.aws/credentials. The parser drops every value as it
9
+ * reads a line, except `region`, so no secret is kept, returned or shown.
10
+ */
11
+ import { readFileSync } from 'node:fs';
12
+ import { join } from 'node:path';
13
+ import { aws } from '../utils/aws.js';
14
+ import { callerIdentity } from '../aws/connect.js';
15
+ import { applyConnection, connectionLabel, loadConnection, REGION_RE, writeConnectionFile } from '../aws/connection.js';
16
+ import { resolveRegion } from '../security/setup.js';
17
+ import { tildeHome } from './payload.js';
18
+ /**
19
+ * Key names per section. Values are discarded line by line; `region` is kept
20
+ * only when it looks like a region name. Indented lines are nested settings
21
+ * (e.g. s3 = ...) and are skipped.
22
+ */
23
+ export function iniKeys(text, kind) {
24
+ const out = new Map();
25
+ let cur = null;
26
+ for (const raw of text.split(/\r?\n/)) {
27
+ if (/^\s/.test(raw))
28
+ continue;
29
+ const line = raw.trim();
30
+ if (!line || line.startsWith('#') || line.startsWith(';'))
31
+ continue;
32
+ const sec = /^\[\s*([^\]]+?)\s*\]$/.exec(line);
33
+ if (sec) {
34
+ // config: [default] and [profile name]; [sso-session x] and others are not profiles.
35
+ const name = kind === 'credentials' ? sec[1] : sec[1] === 'default' ? 'default' : /^profile\s+(.+)$/.exec(sec[1])?.[1]?.trim();
36
+ cur = name ? (out.get(name) ?? { keys: new Set() }) : null;
37
+ if (name && cur)
38
+ out.set(name, cur);
39
+ continue;
40
+ }
41
+ const eq = line.indexOf('=');
42
+ if (!cur || eq <= 0)
43
+ continue;
44
+ const key = line.slice(0, eq).trim().toLowerCase();
45
+ cur.keys.add(key);
46
+ if (key === 'region') {
47
+ const v = line.slice(eq + 1).trim();
48
+ if (REGION_RE.test(v))
49
+ cur.region = v;
50
+ }
51
+ }
52
+ return out;
53
+ }
54
+ export const CREDENTIAL_TYPE_LABEL = {
55
+ credential_process: 'credential_process',
56
+ sso: 'IAM Identity Center (SSO)',
57
+ 'static-credentials-file': 'static keys in ~/.aws/credentials',
58
+ 'static-config-file': 'static keys in ~/.aws/config',
59
+ 'assume-role': 'assume role (role_arn)',
60
+ 'web-identity': 'web identity token',
61
+ env: 'environment variables',
62
+ container: 'container credentials',
63
+ none: 'none found',
64
+ };
65
+ /**
66
+ * The type the AWS CLI would use for `profile`, in its provider order within a
67
+ * profile: role_arn, web identity, SSO, keys in the credentials file,
68
+ * credential_process, keys in the config file. `shadowed` lists the types that
69
+ * are configured but lose.
70
+ */
71
+ export function classifyProfile(profile, config, creds) {
72
+ const c = config.get(profile)?.keys ?? new Set();
73
+ const k = creds.get(profile)?.keys ?? new Set();
74
+ const present = [];
75
+ if (c.has('role_arn') && (c.has('web_identity_token_file')))
76
+ present.push('web-identity');
77
+ else if (c.has('role_arn') || k.has('role_arn'))
78
+ present.push('assume-role');
79
+ if (c.has('sso_session') || c.has('sso_start_url') || c.has('sso_account_id'))
80
+ present.push('sso');
81
+ if (k.has('aws_access_key_id'))
82
+ present.push('static-credentials-file');
83
+ if (c.has('credential_process') || k.has('credential_process'))
84
+ present.push('credential_process');
85
+ if (c.has('aws_access_key_id'))
86
+ present.push('static-config-file');
87
+ if (!present.length)
88
+ return { type: 'none', shadowed: [] };
89
+ return { type: present[0], shadowed: present.slice(1) };
90
+ }
91
+ const readTextFile = (p) => { try {
92
+ return readFileSync(p, 'utf8');
93
+ }
94
+ catch {
95
+ return null;
96
+ } };
97
+ export const STATIC_DEFAULT_WARNING = 'The default profile has static keys in ~/.aws/credentials. Static keys win over a credential_process or SSO setting for the same profile, and they often expire. If you sign in with credential_process or SSO, remove the keys from [default] in ~/.aws/credentials.';
98
+ export const NO_CREDENTIALS_WARNING = 'No AWS credentials found: no AWS env var, no saved aws connect profile, and no default profile in ~/.aws/config or ~/.aws/credentials. Set one up with aws configure sso (or aws configure), then run prism-cli aws connect.';
99
+ /** What prism-cli would use, from local files and env only. No AWS call, no aws CLI call. */
100
+ export function resolveAwsIdentity(d) {
101
+ const read = d.readText ?? readTextFile;
102
+ const env = d.env;
103
+ const configPath = env.AWS_CONFIG_FILE || join(d.home, '.aws', 'config');
104
+ const credsPath = env.AWS_SHARED_CREDENTIALS_FILE || join(d.home, '.aws', 'credentials');
105
+ const configText = read(configPath), credsText = read(credsPath);
106
+ const config = iniKeys(configText ?? '', 'config');
107
+ const creds = iniKeys(credsText ?? '', 'credentials');
108
+ const saved = loadConnection(d.home, d.repoRoot);
109
+ const applied = applyConnection({}, saved, env);
110
+ const warnings = [];
111
+ let profile = null, source, type, shadowed = [];
112
+ let envDetail = 'no AWS credential env var set';
113
+ let decided;
114
+ if (env.AWS_ACCESS_KEY_ID) {
115
+ type = 'env';
116
+ source = 'AWS_ACCESS_KEY_ID';
117
+ decided = 'env';
118
+ envDetail = `AWS_ACCESS_KEY_ID is set${env.AWS_PROFILE ? ' (it wins over AWS_PROFILE)' : ''}`;
119
+ }
120
+ else if (env.AWS_PROFILE) {
121
+ profile = env.AWS_PROFILE;
122
+ source = 'AWS_PROFILE';
123
+ decided = 'env';
124
+ ({ type, shadowed } = classifyProfile(profile, config, creds));
125
+ envDetail = `AWS_PROFILE=${profile}`;
126
+ }
127
+ else if (env.AWS_WEB_IDENTITY_TOKEN_FILE) {
128
+ type = 'web-identity';
129
+ source = 'AWS_WEB_IDENTITY_TOKEN_FILE';
130
+ decided = 'env';
131
+ envDetail = 'AWS_WEB_IDENTITY_TOKEN_FILE is set';
132
+ }
133
+ else if (env.AWS_CONTAINER_CREDENTIALS_FULL_URI || env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {
134
+ type = 'container';
135
+ source = 'container credentials env var';
136
+ decided = 'env';
137
+ envDetail = 'a container credentials env var is set';
138
+ }
139
+ else if (saved && applied.profileSource) {
140
+ profile = saved.profile;
141
+ source = connectionLabel(saved);
142
+ decided = saved.scope;
143
+ ({ type, shadowed } = classifyProfile(profile, config, creds));
144
+ }
145
+ else {
146
+ profile = 'default';
147
+ source = 'default chain';
148
+ decided = 'default';
149
+ ({ type, shadowed } = classifyProfile(profile, config, creds));
150
+ }
151
+ const repoFile = d.repoRoot ? join(d.repoRoot, '.prism', 'aws.local.json') : null;
152
+ const savedStep = (scope) => decided === scope ? 'used' : saved?.scope === scope ? 'skipped' : 'not-set';
153
+ const steps = [
154
+ { id: 'flags', label: '--profile / --region', state: 'n/a', detail: 'not used by the dashboard' },
155
+ { id: 'env', label: 'Environment', state: decided === 'env' ? 'used' : 'not-set', detail: envDetail },
156
+ { id: 'repo', label: 'Repo: .prism/aws.local.json', state: savedStep('repo'),
157
+ detail: !repoFile ? 'the dashboard is not running in a git repo' : saved?.scope === 'repo' ? `profile ${saved.profile}` : 'not set' },
158
+ { id: 'user', label: 'User: ~/.prism/aws.json', state: savedStep('user'),
159
+ detail: saved?.scope === 'user' ? `profile ${saved.profile}` : saved?.scope === 'repo' ? 'the repo file wins' : 'not set' },
160
+ { id: 'default', label: 'Default chain', state: decided === 'default' ? 'used' : 'not-set', detail: 'the [default] profile' },
161
+ ];
162
+ const configRegion = (p) => config.get(p ?? env.AWS_PROFILE ?? 'default')?.region ?? null;
163
+ const region = resolveRegion({ profile: profile && profile !== 'default' ? profile : undefined, connection: applied.connection }, { env, configRegion });
164
+ if (creds.get('default')?.keys.has('aws_access_key_id'))
165
+ warnings.push(STATIC_DEFAULT_WARNING);
166
+ if (profile && profile !== 'default' && type === 'static-credentials-file' && shadowed.length) {
167
+ warnings.push(`Profile ${profile} has static keys in ~/.aws/credentials, and they win over its ${shadowed.map((t) => CREDENTIAL_TYPE_LABEL[t]).join(' and ')}. Remove the keys if they are stale.`);
168
+ }
169
+ if (type === 'none') {
170
+ warnings.push(profile && profile !== 'default'
171
+ ? `Profile ${profile} (${source}) is not configured in ~/.aws/config or ~/.aws/credentials. Create it with aws configure sso --profile ${profile}, or re-run prism-cli aws connect.`
172
+ : NO_CREDENTIALS_WARNING);
173
+ }
174
+ if (saved && !applied.profileSource)
175
+ warnings.push(`The saved aws connect profile ${saved.profile} is not used: ${source} is set in the dashboard's environment and wins.`);
176
+ return {
177
+ profile, source, credentialType: type, credentialLabel: CREDENTIAL_TYPE_LABEL[type],
178
+ region: region ? { value: region.region, source: region.source } : null,
179
+ steps,
180
+ saved: saved ? {
181
+ scope: saved.scope, path: tildeHome(saved.path, d.home), profile: saved.profile, region: saved.region, account: saved.account,
182
+ alias: saved.alias, verifiedAt: saved.verifiedAt, inUse: !!applied.profileSource,
183
+ } : null,
184
+ warnings,
185
+ files: { config: tildeHome(configPath, d.home), credentials: tildeHome(credsPath, d.home), configFound: configText !== null, credentialsFound: credsText !== null },
186
+ };
187
+ }
188
+ const EXPIRED_RE = /expired|ExpiredToken|InvalidClientTokenId|UnrecognizedClient|RequestExpired|SignatureDoesNotMatch|AuthFailure|Unable to locate credentials|NoCredentialProviders|refresh|sso|credential_process|custom-process/i;
189
+ /** The fixes to suggest for a failed check, by credential type. */
190
+ export function checkFixes(v) {
191
+ const p = v.profile && v.profile !== 'default' ? ` --profile ${v.profile}` : '';
192
+ const out = [];
193
+ if (v.credentialType === 'credential_process')
194
+ out.push('Sign in again with the tool your credential_process runs, then Check now again');
195
+ if (v.credentialType === 'sso')
196
+ out.push(`aws sso login${p}`);
197
+ if (v.credentialType === 'static-credentials-file' || v.warnings.includes(STATIC_DEFAULT_WARNING))
198
+ out.push('Remove or rotate the stale static keys in ~/.aws/credentials');
199
+ if (v.credentialType === 'none')
200
+ out.push(`aws configure sso${p}`);
201
+ out.push('prism-cli aws connect');
202
+ return out;
203
+ }
204
+ /** The default `aws` call for Check now: aws connect's call, with the region optional and a timeout. */
205
+ export const CHECK_NOW_TIMEOUT_MS = 30_000;
206
+ export function checkNowAws(args, profile, region) {
207
+ return aws(region ? [...args, '--region', region] : args, { profile: profile || undefined, env: { AWS_PAGER: '' }, timeoutMs: CHECK_NOW_TIMEOUT_MS });
208
+ }
209
+ /**
210
+ * One read-only `sts get-caller-identity`, through aws connect's callerIdentity.
211
+ * On a match with the saved connection (same profile and region), the saved
212
+ * file's verifiedAt is refreshed; nothing else is written.
213
+ */
214
+ export function checkNow(d) {
215
+ const v = d.identity;
216
+ // --profile only for a saved aws connect profile; env and the default chain are left to the AWS CLI, as every AWS command does.
217
+ const profile = d.saved && v.saved?.inUse ? d.saved.profile : '';
218
+ const region = v.region?.value ?? '';
219
+ const id = callerIdentity({ aws: d.aws }, profile, region);
220
+ if ('error' in id) {
221
+ const error = d.redact(id.error);
222
+ return { ok: false, expired: EXPIRED_RE.test(error), error, profile: v.profile, region: region || null, fixes: checkFixes(v) };
223
+ }
224
+ const s = d.saved;
225
+ const matches = s ? s.account === id.account : null;
226
+ let updated = false, note;
227
+ if (!s)
228
+ note = 'No saved aws connect connection; nothing was written. Save one with prism-cli aws connect.';
229
+ else if (!matches)
230
+ note = `Does not match the saved account ${s.account}. The saved file was not changed; check the profile, then re-run prism-cli aws connect${s.scope === 'repo' ? ' --repo' : ''}.`;
231
+ else if (s.profile !== v.profile || s.region !== region)
232
+ note = `Matches the saved account, but the check used ${v.profile ? `profile ${v.profile}` : v.source} in ${region || 'no region'}, not the saved pair; the saved file was not changed.`;
233
+ else {
234
+ (d.write ?? writeConnectionFile)(s.path, { profile: s.profile, region: s.region, account: s.account, alias: s.alias, verifiedAt: d.now().toISOString() });
235
+ updated = true;
236
+ note = `Matches the saved account; updated the verified time in ${v.saved?.path ?? s.path}.`;
237
+ }
238
+ return { ok: true, account: id.account, arn: id.arn, region: region || null, profile: v.profile, savedAccount: s?.account ?? null, matches, updated, note };
239
+ }
240
+ //# sourceMappingURL=aws-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-identity.js","sourceRoot":"","sources":["../../../src/dashboard/aws-identity.ts"],"names":[],"mappings":"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"}
@@ -6,5 +6,5 @@
6
6
  * Every value from the payload is placed with textContent or a DOM attribute;
7
7
  * innerHTML is never used for data.
8
8
  */
9
- export declare function renderPage(nonce: string): string;
9
+ export declare function renderPage(nonce: string, csrf?: string): string;
10
10
  //# sourceMappingURL=page.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/dashboard/page.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA6nBH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQhD"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../src/dashboard/page.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAsoBH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM,CAgB3D"}
@@ -6,11 +6,14 @@
6
6
  * Every value from the payload is placed with textContent or a DOM attribute;
7
7
  * innerHTML is never used for data.
8
8
  */
9
+ import { SETUP_SCRIPT, SETUP_STYLE, THEME_BOOT, THEME_SCRIPT } from './setup-page.js';
10
+ /** Colour tokens; the dark set applies by system preference unless the toggle picks Light, and always with Dark. */
11
+ const LIGHT_VARS = '--bg:#f7f7f8; --card:#fff; --text:#1d1d1f; --muted:#6b6b73; --line:#e3e3e8; --ok:#1a7f37; --warn:#9a6700; --bad:#cf222e; --high:#cf222e; --medium:#bf8700; --low:#3d6fa8; --accent:#0969da; --raised:var(--bg);';
12
+ const DARK_VARS = '--bg:#0d1117; --card:#161b22; --text:#e6edf3; --muted:#8b949e; --line:#30363d; --ok:#3fb950; --warn:#d29922; --bad:#f85149; --high:#f85149; --medium:#d29922; --low:#a5d6ff; --accent:#58a6ff; --raised:#21262d;';
9
13
  const STYLE = `
10
- :root { color-scheme: light dark; --bg:#f7f7f8; --card:#fff; --text:#1d1d1f; --muted:#6b6b73; --line:#e3e3e8;
11
- --ok:#1a7f37; --warn:#9a6700; --bad:#cf222e; --high:#cf222e; --medium:#bf8700; --low:#3d6fa8; --accent:#0969da; --raised:var(--bg); }
12
- @media (prefers-color-scheme: dark) { :root { --bg:#0d1117; --card:#161b22; --text:#e6edf3; --muted:#8b949e; --line:#30363d;
13
- --ok:#3fb950; --warn:#d29922; --bad:#f85149; --high:#f85149; --medium:#d29922; --low:#a5d6ff; --accent:#58a6ff; --raised:#21262d; } }
14
+ :root { color-scheme: light; ${LIGHT_VARS} }
15
+ @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { color-scheme: dark; ${DARK_VARS} } }
16
+ :root[data-theme="dark"] { color-scheme: dark; ${DARK_VARS} }
14
17
  * { box-sizing: border-box; }
15
18
  body { margin:0; font:14px/1.45 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif; background:var(--bg); color:var(--text); }
16
19
  header { display:flex; flex-wrap:wrap; align-items:center; gap:8px 12px; padding:14px 20px; border-bottom:1px solid var(--line); background:var(--card); }
@@ -61,6 +64,7 @@ svg.trend line { stroke:var(--line); }
61
64
  .changed { outline:2px solid var(--accent); outline-offset:1px; border-radius:4px; }
62
65
  @keyframes prism-flash { from { background-color:color-mix(in srgb, var(--accent) 35%, transparent); } to { background-color:transparent; } }
63
66
  @media (prefers-reduced-motion: no-preference) { .changed { animation:prism-flash 2.5s ease-out 1; } }
67
+ ${SETUP_STYLE}
64
68
  `;
65
69
  const SCRIPT = `
66
70
  'use strict';
@@ -633,19 +637,31 @@ async function render() {
633
637
  const c = data.overview.counts;
634
638
  meta.textContent = c.repos + ' repos under ' + txt(data.scope.root_display) + ' · ' + c.codewatch + ' with codewatch' + (data.scope.truncated ? ' (scan capped)' : '')
635
639
  + ' · updated ' + when(data.generated_at) + (changed.size ? ' · ' + changed.size + ' value' + (changed.size === 1 ? '' : 's') + ' changed (outlined)' : '') + ' · refreshes every minute while visible';
640
+ await renderSetup(data);
636
641
  }
642
+ ${SETUP_SCRIPT}
643
+ ${THEME_SCRIPT}
637
644
  document.getElementById('refresh').addEventListener('click', load);
638
645
  setInterval(() => { if (document.visibilityState === 'visible' && Date.now() - lastLoad >= AUTO_REFRESH_MS - 1000) load(); }, AUTO_REFRESH_MS / 4);
639
646
  document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible' && Date.now() - lastLoad >= AUTO_REFRESH_MS) load(); });
640
647
  load();
641
648
  `;
642
- export function renderPage(nonce) {
643
- // The nonce is base64 generated server-side; nothing user-derived is interpolated here.
649
+ export function renderPage(nonce, csrf = '') {
650
+ // The nonce and the CSRF token are base64/base64url generated server-side; nothing user-derived is interpolated here.
651
+ if (!/^[A-Za-z0-9_-]*$/.test(csrf))
652
+ throw new Error('bad CSRF token');
644
653
  return `<!DOCTYPE html>
645
654
  <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
655
+ <meta name="prism-csrf" content="${csrf}">
656
+ <script nonce="${nonce}">${THEME_BOOT}</script>
646
657
  <title>PRISM dashboard</title><style nonce="${nonce}">${STYLE}</style></head>
647
- <body><header><h1>PRISM dashboard</h1><button id="refresh" type="button">Refresh</button><span class="meta" id="meta"></span></header>
658
+ <body><header><h1>PRISM dashboard</h1>
659
+ <nav class="tabs" aria-label="Views"><a href="#" data-view="dashboard">Dashboard</a><a href="#setup" data-view="setup">Setup</a></nav>
660
+ <button id="refresh" type="button">Refresh</button>
661
+ <div class="theme" role="group" aria-label="Theme"><button type="button" data-theme-set="light">Light</button><button type="button" data-theme-set="dark">Dark</button><button type="button" data-theme-set="system">System</button></div>
662
+ <span class="meta" id="meta"></span></header>
648
663
  <main id="main"></main>
664
+ <main id="setup" hidden></main>
649
665
  <script nonce="${nonce}">${SCRIPT}</script></body></html>`;
650
666
  }
651
667
  //# sourceMappingURL=page.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"page.js","sourceRoot":"","sources":["../../../src/dashboard/page.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuDb,CAAC;AAEF,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgkBd,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,wFAAwF;IACxF,OAAO;;8CAEqC,KAAK,KAAK,KAAK;;;iBAG5C,KAAK,KAAK,MAAM,yBAAyB,CAAC;AAC3D,CAAC"}
1
+ {"version":3,"file":"page.js","sourceRoot":"","sources":["../../../src/dashboard/page.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEtF,oHAAoH;AACpH,MAAM,UAAU,GAAG,iNAAiN,CAAC;AACrO,MAAM,SAAS,GAAG,kNAAkN,CAAC;AAErO,MAAM,KAAK,GAAG;+BACiB,UAAU;8FACqD,SAAS;iDACtD,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDxD,WAAW;CACZ,CAAC;AAEF,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6jBb,YAAY;EACZ,YAAY;;;;;CAKb,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,IAAI,GAAG,EAAE;IACjD,sHAAsH;IACtH,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtE,OAAO;;mCAE0B,IAAI;iBACtB,KAAK,KAAK,UAAU;8CACS,KAAK,KAAK,KAAK;;;;;;;;iBAQ5C,KAAK,KAAK,MAAM,yBAAyB,CAAC;AAC3D,CAAC"}
@@ -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 only, read-only routes, no CORS headers, strict CSP.
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. */
41
+ getApi?: Record<string, () => 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
- /** Starts the server on 127.0.0.1. `port` 0 (default) picks a free port. */
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
- }): Promise<RunningServer>;
50
- /** Memoises the payload for `ttlMs` and shares one in-flight build between requests. */
51
- export declare function cachedPayload(build: () => Promise<unknown>, ttlMs?: number): () => Promise<unknown>;
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;;;;;;;;;;;;;;;;;GAiBG;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,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;CACxD;AAKD,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,IAClC,KAAK,eAAe,EAAE,KAAK,cAAc,KAAG,OAAO,CAAC,IAAI,CAAC,CAwDxE;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAoBvL;AAED,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAWnG"}
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,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAChD,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"}