@actuate-media/cms-core 0.36.0 → 0.38.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 (48) hide show
  1. package/dist/__tests__/api/security-routes.test.d.ts +2 -0
  2. package/dist/__tests__/api/security-routes.test.d.ts.map +1 -0
  3. package/dist/__tests__/api/security-routes.test.js +212 -0
  4. package/dist/__tests__/api/security-routes.test.js.map +1 -0
  5. package/dist/__tests__/api/totp-login.test.d.ts +2 -0
  6. package/dist/__tests__/api/totp-login.test.d.ts.map +1 -0
  7. package/dist/__tests__/api/totp-login.test.js +115 -0
  8. package/dist/__tests__/api/totp-login.test.js.map +1 -0
  9. package/dist/__tests__/auth/totp.test.d.ts +2 -0
  10. package/dist/__tests__/auth/totp.test.d.ts.map +1 -0
  11. package/dist/__tests__/auth/totp.test.js +52 -0
  12. package/dist/__tests__/auth/totp.test.js.map +1 -0
  13. package/dist/__tests__/security/center.test.d.ts +2 -0
  14. package/dist/__tests__/security/center.test.d.ts.map +1 -0
  15. package/dist/__tests__/security/center.test.js +226 -0
  16. package/dist/__tests__/security/center.test.js.map +1 -0
  17. package/dist/api/handlers.d.ts.map +1 -1
  18. package/dist/api/handlers.js +240 -8
  19. package/dist/api/handlers.js.map +1 -1
  20. package/dist/auth/totp.d.ts +12 -0
  21. package/dist/auth/totp.d.ts.map +1 -1
  22. package/dist/auth/totp.js +24 -0
  23. package/dist/auth/totp.js.map +1 -1
  24. package/dist/security/center/gather.d.ts +12 -0
  25. package/dist/security/center/gather.d.ts.map +1 -0
  26. package/dist/security/center/gather.js +185 -0
  27. package/dist/security/center/gather.js.map +1 -0
  28. package/dist/security/center/index.d.ts +13 -0
  29. package/dist/security/center/index.d.ts.map +1 -0
  30. package/dist/security/center/index.js +4 -0
  31. package/dist/security/center/index.js.map +1 -0
  32. package/dist/security/center/settings.d.ts +38 -0
  33. package/dist/security/center/settings.d.ts.map +1 -0
  34. package/dist/security/center/settings.js +121 -0
  35. package/dist/security/center/settings.js.map +1 -0
  36. package/dist/security/center/status.d.ts +10 -0
  37. package/dist/security/center/status.d.ts.map +1 -0
  38. package/dist/security/center/status.js +249 -0
  39. package/dist/security/center/status.js.map +1 -0
  40. package/dist/security/center/summaries.d.ts +21 -0
  41. package/dist/security/center/summaries.d.ts.map +1 -0
  42. package/dist/security/center/summaries.js +65 -0
  43. package/dist/security/center/summaries.js.map +1 -0
  44. package/dist/security/center/types.d.ts +127 -0
  45. package/dist/security/center/types.d.ts.map +1 -0
  46. package/dist/security/center/types.js +12 -0
  47. package/dist/security/center/types.js.map +1 -0
  48. package/package.json +6 -1
@@ -1,5 +1,17 @@
1
1
  export declare function generateTOTPSecret(): string;
2
2
  export declare function generateTOTPUri(secret: string, email: string, issuer?: string): string;
3
3
  export declare function verifyTOTP(token: string, secret: string, window?: number): boolean;
4
+ /**
5
+ * Normalize a user-entered backup code: strip whitespace/dashes and lowercase
6
+ * so "ABCD-1234" and "abcd 1234" both match the stored "abcd1234".
7
+ */
8
+ export declare function normalizeBackupCode(input: string): string;
9
+ /**
10
+ * Find the index of the stored backup code matching the submitted value, or -1.
11
+ * Compares against every stored code in constant time so timing can't reveal
12
+ * which/whether a code matched. Callers must treat a match as single-use and
13
+ * remove the code from storage.
14
+ */
15
+ export declare function findBackupCodeMatch(codes: string[], submitted: string): number;
4
16
  export declare function generateBackupCodes(count?: number): string[];
5
17
  //# sourceMappingURL=totp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"totp.d.ts","sourceRoot":"","sources":["../../src/auth/totp.ts"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,SAAgB,GAAG,MAAM,CAE7F;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,OAAO,CAQ7E;AAkED,wBAAgB,mBAAmB,CAAC,KAAK,SAAI,GAAG,MAAM,EAAE,CAavD"}
1
+ {"version":3,"file":"totp.d.ts","sourceRoot":"","sources":["../../src/auth/totp.ts"],"names":[],"mappings":"AAKA,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,SAAgB,GAAG,MAAM,CAE7F;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,OAAO,CAQ7E;AAkED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAQ9E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,SAAI,GAAG,MAAM,EAAE,CAavD"}
package/dist/auth/totp.js CHANGED
@@ -77,6 +77,30 @@ function base32Decode(encoded) {
77
77
  }
78
78
  return Buffer.from(output);
79
79
  }
80
+ /**
81
+ * Normalize a user-entered backup code: strip whitespace/dashes and lowercase
82
+ * so "ABCD-1234" and "abcd 1234" both match the stored "abcd1234".
83
+ */
84
+ export function normalizeBackupCode(input) {
85
+ return input.replace(/[\s-]/g, '').toLowerCase();
86
+ }
87
+ /**
88
+ * Find the index of the stored backup code matching the submitted value, or -1.
89
+ * Compares against every stored code in constant time so timing can't reveal
90
+ * which/whether a code matched. Callers must treat a match as single-use and
91
+ * remove the code from storage.
92
+ */
93
+ export function findBackupCodeMatch(codes, submitted) {
94
+ const normalized = normalizeBackupCode(submitted);
95
+ if (!normalized)
96
+ return -1;
97
+ let matchIdx = -1;
98
+ for (let i = 0; i < codes.length; i++) {
99
+ if (timingSafeEqual(codes[i].toLowerCase(), normalized))
100
+ matchIdx = i;
101
+ }
102
+ return matchIdx;
103
+ }
80
104
  export function generateBackupCodes(count = 8) {
81
105
  const codes = [];
82
106
  for (let i = 0; i < count; i++) {
@@ -1 +1 @@
1
- {"version":3,"file":"totp.js","sourceRoot":"","sources":["../../src/auth/totp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"totp.js","sourceRoot":"","sources":["../../src/auth/totp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { SecuritySettings, SecurityCenterData } from './types.js';
2
+ /** Read the persisted, enforced security policy from the `settings` global. */
3
+ export declare function getStoredSecuritySettings(db: unknown): Promise<SecuritySettings>;
4
+ export interface GatherOptions {
5
+ db: unknown;
6
+ /** Acting admin's user id (for the lockout-safe MFA enable check). */
7
+ userId?: string;
8
+ /** Resolved client IP of the request (for the allowlist indicator). */
9
+ currentIp?: string | null;
10
+ }
11
+ export declare function getSecurityCenterData(opts: GatherOptions): Promise<SecurityCenterData>;
12
+ //# sourceMappingURL=gather.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gather.d.ts","sourceRoot":"","sources":["../../../src/security/center/gather.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAGV,gBAAgB,EAChB,kBAAkB,EAEnB,MAAM,YAAY,CAAA;AAmCnB,+EAA+E;AAC/E,wBAAsB,yBAAyB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAYtF;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAA;IACX,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1B;AAED,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsJ5F"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Security Center data gathering (async, DB + env I/O).
3
+ *
4
+ * Reads real auth/session/secret/audit state and composes the
5
+ * {@link SecurityCenterData} the admin tab renders. Never returns secret
6
+ * values — only configured/missing verdicts.
7
+ */
8
+ import { getActuateConfig } from '../../config/runtime.js';
9
+ import { validateEnvShape } from '../../diagnostics/env.js';
10
+ import { isIpAllowed } from '../ip-allowlist.js';
11
+ import { parseSecuritySettings } from './settings.js';
12
+ import { computeSecurityStatus } from './status.js';
13
+ import { summarizeApiKeys, summarizeUsers } from './summaries.js';
14
+ function hasModel(db, model) {
15
+ return Boolean(db && typeof db === 'object' && db[model]);
16
+ }
17
+ function isProductionEnv() {
18
+ return (process.env.VERCEL_ENV ?? process.env.NODE_ENV) === 'production';
19
+ }
20
+ function envSeverityToCheck(s) {
21
+ switch (s) {
22
+ case 'ok':
23
+ return 'pass';
24
+ case 'warn':
25
+ return 'warning';
26
+ case 'error':
27
+ case 'missing':
28
+ return 'fail';
29
+ default:
30
+ return 'unknown';
31
+ }
32
+ }
33
+ /** Read the persisted, enforced security policy from the `settings` global. */
34
+ export async function getStoredSecuritySettings(db) {
35
+ const d = db;
36
+ if (!hasModel(d, 'document'))
37
+ return parseSecuritySettings({});
38
+ try {
39
+ const row = await d.document.findFirst({
40
+ where: { collection: 'settings', deletedAt: null },
41
+ select: { data: true },
42
+ });
43
+ return parseSecuritySettings(row?.data ?? {});
44
+ }
45
+ catch {
46
+ return parseSecuritySettings({});
47
+ }
48
+ }
49
+ export async function getSecurityCenterData(opts) {
50
+ const d = opts.db;
51
+ const isProduction = isProductionEnv();
52
+ const now = Date.now();
53
+ const settings = await getStoredSecuritySettings(opts.db);
54
+ const userRows = hasModel(d, 'user')
55
+ ? await d
56
+ .user.findMany({ select: { role: true, isActive: true, totpEnabled: true } })
57
+ .catch(() => [])
58
+ : [];
59
+ const users = summarizeUsers(userRows);
60
+ let viewerHasMfa = false;
61
+ if (opts.userId && hasModel(d, 'user')) {
62
+ const viewer = await d
63
+ .user.findUnique({
64
+ where: { id: opts.userId },
65
+ select: { totpEnabled: true },
66
+ })
67
+ .catch(() => null);
68
+ viewerHasMfa = Boolean(viewer?.totpEnabled);
69
+ }
70
+ const activeSessions = hasModel(d, 'session')
71
+ ? await d
72
+ .session.count({ where: { revokedAt: null, expiresAt: { gt: new Date() } } })
73
+ .catch(() => 0)
74
+ : 0;
75
+ const apiKeyRows = hasModel(d, 'apiKey')
76
+ ? await d
77
+ .apiKey.findMany({
78
+ select: { scopes: true, expiresAt: true, lastUsedAt: true, revokedAt: true },
79
+ })
80
+ .catch(() => [])
81
+ : [];
82
+ const apiKeys = summarizeApiKeys(apiKeyRows, now);
83
+ const since = new Date(now - 24 * 60 * 60 * 1000);
84
+ const failedLogins24h = hasModel(d, 'auditLog')
85
+ ? await d
86
+ .auditLog.count({ where: { event: 'login_failed', timestamp: { gte: since } } })
87
+ .catch(() => 0)
88
+ : 0;
89
+ // ── Secrets / encryption (verdicts only, never values) ───────────────────────
90
+ const env = validateEnvShape();
91
+ const byName = new Map(env.checks.map((c) => [c.name, c]));
92
+ const config = getActuateConfig();
93
+ const configSecret = typeof config?.secret === 'string' && config.secret.length >= 32;
94
+ let cmsSecret = envSeverityToCheck(byName.get('CMS_SECRET')?.status ?? 'missing');
95
+ if (cmsSecret === 'fail' && configSecret)
96
+ cmsSecret = 'pass';
97
+ const encRaw = byName.get('CMS_ENCRYPTION_KEY')?.status ?? 'warn';
98
+ // A *missing* key is only a hard failure in production; elsewhere it's a warning.
99
+ let encryptionKey = envSeverityToCheck(encRaw);
100
+ if (encRaw === 'warn' && isProduction)
101
+ encryptionKey = 'fail';
102
+ const upstash = byName.get('UPSTASH_REDIS_REST_URL')?.status;
103
+ const rateLimitBackend = upstash === 'ok' ? 'distributed' : 'in_memory';
104
+ const secrets = {
105
+ cmsSecret,
106
+ encryptionKey,
107
+ rateLimitBackend,
108
+ apiKeysHashed: true,
109
+ webhookSecretsEncrypted: encryptionKey === 'pass',
110
+ };
111
+ // ── IP allowlist (config-driven; middleware enforces) ────────────────────────
112
+ const ranges = Array.isArray(config?.admin?.ipAllowlist)
113
+ ? config.admin.ipAllowlist
114
+ : [];
115
+ const currentIp = opts.currentIp ?? null;
116
+ const ipAllowlist = {
117
+ enabled: ranges.length > 0,
118
+ source: (ranges.length > 0 ? 'config' : 'none'),
119
+ ranges,
120
+ currentIp,
121
+ currentIpAllowed: ranges.length > 0 && currentIp ? isIpAllowed(currentIp, ranges) : null,
122
+ };
123
+ const sessionMaxAgeHours = 24 * 7; // login issues a fixed 7-day session today
124
+ const status = computeSecurityStatus({
125
+ isProduction,
126
+ settings,
127
+ users,
128
+ apiKeys,
129
+ secrets,
130
+ ipAllowlist,
131
+ failedLogins24h,
132
+ activeSessions,
133
+ csrfEnabled: true,
134
+ uploadValidation: true,
135
+ auditEnabled: true,
136
+ });
137
+ const editable = { source: 'database', editable: true };
138
+ const sources = {
139
+ mfaRequired: editable,
140
+ mfaGracePeriodDays: editable,
141
+ maxConcurrentSessions: editable,
142
+ sessionMaxAgeHours: {
143
+ source: 'computed',
144
+ editable: false,
145
+ reason: 'Sessions are issued with a fixed 7-day lifetime.',
146
+ },
147
+ ipAllowlist: {
148
+ source: 'config',
149
+ editable: false,
150
+ reason: 'Set admin.ipAllowlist in actuate.config.ts; enforced in middleware.',
151
+ },
152
+ csrf: { source: 'computed', editable: false, reason: 'Always enabled for mutating requests.' },
153
+ rateLimiting: {
154
+ source: 'environment',
155
+ editable: false,
156
+ reason: 'Backend is selected from UPSTASH_REDIS_REST_URL / KV_REST_API_URL.',
157
+ },
158
+ uploadValidation: {
159
+ source: 'computed',
160
+ editable: false,
161
+ reason: 'Always enforced server-side.',
162
+ },
163
+ cmsSecret: { source: 'environment', editable: false },
164
+ encryptionKey: { source: 'environment', editable: false },
165
+ audit: { source: 'computed', editable: false, reason: 'Always enabled.' },
166
+ };
167
+ return {
168
+ settings,
169
+ status,
170
+ users,
171
+ apiKeys,
172
+ secrets,
173
+ ipAllowlist,
174
+ failedLogins24h,
175
+ activeSessions,
176
+ csrfEnabled: true,
177
+ uploadValidation: true,
178
+ auditEnabled: true,
179
+ sessionMaxAgeHours,
180
+ viewerHasMfa,
181
+ environment: process.env.VERCEL_ENV ?? process.env.NODE_ENV ?? 'development',
182
+ sources,
183
+ };
184
+ }
185
+ //# sourceMappingURL=gather.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gather.js","sourceRoot":"","sources":["../../../src/security/center/gather.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,gBAAgB,EAAyB,MAAM,0BAA0B,CAAA;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAgC,MAAM,gBAAgB,CAAA;AAoB/F,SAAS,QAAQ,CAAyB,EAAU,EAAE,KAAQ;IAC5D,OAAO,OAAO,CAAC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;AAC3D,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,YAAY,CAAA;AAC1E,CAAC;AAED,SAAS,kBAAkB,CAAC,CAAmB;IAC7C,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,IAAI;YACP,OAAO,MAAM,CAAA;QACf,KAAK,MAAM;YACT,OAAO,SAAS,CAAA;QAClB,KAAK,OAAO,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,MAAM,CAAA;QACf;YACE,OAAO,SAAS,CAAA;IACpB,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,EAAW;IACzD,MAAM,CAAC,GAAG,EAAY,CAAA;IACtB,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC;QAAE,OAAO,qBAAqB,CAAC,EAAE,CAAC,CAAA;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,QAAS,CAAC,SAAS,CAAC;YACtC,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE;YAClD,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;SACvB,CAAC,CAAA;QACF,OAAO,qBAAqB,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,qBAAqB,CAAC,EAAE,CAAC,CAAA;IAClC,CAAC;AACH,CAAC;AAUD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAmB;IAC7D,MAAM,CAAC,GAAG,IAAI,CAAC,EAAY,CAAA;IAC3B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAA;IACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAEtB,MAAM,QAAQ,GAAG,MAAM,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEzD,MAAM,QAAQ,GAAc,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAC7C,CAAC,CAAC,MAAM,CAAC;aACJ,IAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC;aAC7E,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;QACpB,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IAEtC,IAAI,YAAY,GAAG,KAAK,CAAA;IACxB,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,CAAC;aACnB,IAAK,CAAC,UAAU,CAAC;YAChB,KAAK,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE;YAC1B,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;SAC9B,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QACpB,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAC7C,CAAC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC;QAC3C,CAAC,CAAC,MAAM,CAAC;aACJ,OAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC;aAC7E,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC,CAAA;IAEL,MAAM,UAAU,GAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC;QACnD,CAAC,CAAC,MAAM,CAAC;aACJ,MAAO,CAAC,QAAQ,CAAC;YAChB,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE;SAC7E,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC;QACpB,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,OAAO,GAAG,gBAAgB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAA;IAEjD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IACjD,MAAM,eAAe,GAAG,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC;QAC7C,CAAC,CAAC,MAAM,CAAC;aACJ,QAAS,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;aAChF,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACnB,CAAC,CAAC,CAAC,CAAA;IAEL,gFAAgF;IAChF,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAA;IAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1D,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAA;IACjC,MAAM,YAAY,GAAG,OAAO,MAAM,EAAE,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA;IAErF,IAAI,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,MAAM,IAAI,SAAS,CAAC,CAAA;IACjF,IAAI,SAAS,KAAK,MAAM,IAAI,YAAY;QAAE,SAAS,GAAG,MAAM,CAAA;IAE5D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,MAAM,IAAI,MAAM,CAAA;IACjE,kFAAkF;IAClF,IAAI,aAAa,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAC9C,IAAI,MAAM,KAAK,MAAM,IAAI,YAAY;QAAE,aAAa,GAAG,MAAM,CAAA;IAE7D,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAA;IAC5D,MAAM,gBAAgB,GACpB,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAA;IAEhD,MAAM,OAAO,GAAkB;QAC7B,SAAS;QACT,aAAa;QACb,gBAAgB;QAChB,aAAa,EAAE,IAAI;QACnB,uBAAuB,EAAE,aAAa,KAAK,MAAM;KAClD,CAAA;IAED,gFAAgF;IAChF,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC;QACtD,CAAC,CAAE,MAAO,CAAC,KAAM,CAAC,WAAwB;QAC1C,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAA;IACxC,MAAM,WAAW,GAAG;QAClB,OAAO,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;QAC1B,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAsB;QACpE,MAAM;QACN,SAAS;QACT,gBAAgB,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;KACzF,CAAA;IAED,MAAM,kBAAkB,GAAG,EAAE,GAAG,CAAC,CAAA,CAAC,2CAA2C;IAE7E,MAAM,MAAM,GAAG,qBAAqB,CAAC;QACnC,YAAY;QACZ,QAAQ;QACR,KAAK;QACL,OAAO;QACP,OAAO;QACP,WAAW;QACX,eAAe;QACf,cAAc;QACd,WAAW,EAAE,IAAI;QACjB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAA;IAEF,MAAM,QAAQ,GAA2B,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC/E,MAAM,OAAO,GAA2C;QACtD,WAAW,EAAE,QAAQ;QACrB,kBAAkB,EAAE,QAAQ;QAC5B,qBAAqB,EAAE,QAAQ;QAC/B,kBAAkB,EAAE;YAClB,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,kDAAkD;SAC3D;QACD,WAAW,EAAE;YACX,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,qEAAqE;SAC9E;QACD,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,uCAAuC,EAAE;QAC9F,YAAY,EAAE;YACZ,MAAM,EAAE,aAAa;YACrB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,oEAAoE;SAC7E;QACD,gBAAgB,EAAE;YAChB,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,8BAA8B;SACvC;QACD,SAAS,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE;QACrD,aAAa,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE;QACzD,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE;KAC1E,CAAA;IAED,OAAO;QACL,QAAQ;QACR,MAAM;QACN,KAAK;QACL,OAAO;QACP,OAAO;QACP,WAAW;QACX,eAAe;QACf,cAAc;QACd,WAAW,EAAE,IAAI;QACjB,gBAAgB,EAAE,IAAI;QACtB,YAAY,EAAE,IAAI;QAClB,kBAAkB;QAClB,YAAY;QACZ,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa;QAC5E,OAAO;KACR,CAAA;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Security Center — public barrel.
3
+ *
4
+ * Exports the PURE pieces only (types, settings parse/validate, IP validation,
5
+ * status computation, cross-module summaries) so the admin client can import
6
+ * them without pulling in server-side DB/env code. The async gatherer
7
+ * (`gather.ts`) is imported directly by the API handlers, not re-exported here.
8
+ */
9
+ export type { ApiKeysSecuritySummary, CheckStatus, IpAllowlistStatus, MfaSettings, SecretsStatus, SecurityCenterData, SecurityCheck, SecuritySettings, SecuritySourceMetadata, SecurityStatus, SecurityStatusInput, SecurityStatusLevel, SecurityWarning, SecurityWarningCategory, SessionSettings, UsersSecuritySummary, } from './types.js';
10
+ export { DEFAULT_SECURITY_SETTINGS, MAX_CONCURRENT_SESSION_OPTIONS, MFA_GRACE_PERIOD_OPTIONS, mfaEnableLockoutError, parseSecuritySettings, validateIpRange, validateSecuritySettings, type SecurityValidationIssue, } from './settings.js';
11
+ export { computeSecurityStatus } from './status.js';
12
+ export { summarizeApiKeys, summarizeUsers, type ApiKeyRow, type UserRow } from './summaries.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/security/center/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,YAAY,EACV,sBAAsB,EACtB,WAAW,EACX,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,uBAAuB,EACvB,eAAe,EACf,oBAAoB,GACrB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,yBAAyB,EACzB,8BAA8B,EAC9B,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,wBAAwB,EACxB,KAAK,uBAAuB,GAC7B,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { DEFAULT_SECURITY_SETTINGS, MAX_CONCURRENT_SESSION_OPTIONS, MFA_GRACE_PERIOD_OPTIONS, mfaEnableLockoutError, parseSecuritySettings, validateIpRange, validateSecuritySettings, } from './settings.js';
2
+ export { computeSecurityStatus } from './status.js';
3
+ export { summarizeApiKeys, summarizeUsers } from './summaries.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/security/center/index.ts"],"names":[],"mappings":"AA2BA,OAAO,EACL,yBAAyB,EACzB,8BAA8B,EAC9B,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,wBAAwB,GAEzB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAgC,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Security settings parsing + validation (pure).
3
+ *
4
+ * The persisted, enforced policy lives under the `security` key of the
5
+ * `settings` global. Only fields the runtime actually enforces are stored
6
+ * here (MFA requirement + grace, concurrent-session cap) so the UI never
7
+ * presents a control that does nothing.
8
+ */
9
+ import type { SecuritySettings } from './types.js';
10
+ export declare const DEFAULT_SECURITY_SETTINGS: SecuritySettings;
11
+ export declare const MFA_GRACE_PERIOD_OPTIONS: readonly [0, 1, 7, 14, 30];
12
+ export declare const MAX_CONCURRENT_SESSION_OPTIONS: readonly [0, 3, 5, 10];
13
+ export interface SecurityValidationIssue {
14
+ field: string;
15
+ message: string;
16
+ severity: 'error' | 'warning';
17
+ }
18
+ /** Read the `security` blob off a settings document, coercing to a safe shape. */
19
+ export declare function parseSecuritySettings(blob: unknown): SecuritySettings;
20
+ /** Validate an incoming settings payload. Pure — no DB / lockout checks here. */
21
+ export declare function validateSecuritySettings(settings: SecuritySettings): SecurityValidationIssue[];
22
+ /**
23
+ * Lockout-safe MFA enable check. Enabling org-wide MFA while the acting admin
24
+ * has no TOTP configured would lock them (and possibly everyone) out. Callers
25
+ * MUST run this server-side before persisting `mfa.required = true`.
26
+ */
27
+ export declare function mfaEnableLockoutError(input: {
28
+ enabling: boolean;
29
+ viewerHasMfa: boolean;
30
+ totalAdmins: number;
31
+ }): string | null;
32
+ /**
33
+ * Validate a single allowlist entry: an IPv4/IPv6 literal or a CIDR range.
34
+ * Standalone (does not import the matcher's private helpers) so it can run in
35
+ * the client bundle for inline form validation.
36
+ */
37
+ export declare function validateIpRange(entry: string): boolean;
38
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/security/center/settings.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,eAAO,MAAM,yBAAyB,EAAE,gBAGvC,CAAA;AAED,eAAO,MAAM,wBAAwB,4BAA6B,CAAA;AAClE,eAAO,MAAM,8BAA8B,wBAAyB,CAAA;AAEpE,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;CAC9B;AAOD,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,gBAAgB,CAiCrE;AAcD,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,uBAAuB,EAAE,CAmB9F;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,MAAM,GAAG,IAAI,CAMhB;AAKD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAatD"}
@@ -0,0 +1,121 @@
1
+ export const DEFAULT_SECURITY_SETTINGS = {
2
+ mfa: { required: false, gracePeriodDays: 7 },
3
+ session: { maxConcurrentSessions: 5 },
4
+ };
5
+ export const MFA_GRACE_PERIOD_OPTIONS = [0, 1, 7, 14, 30];
6
+ export const MAX_CONCURRENT_SESSION_OPTIONS = [0, 3, 5, 10];
7
+ function toInt(value, fallback) {
8
+ const n = typeof value === 'number' ? value : Number(value);
9
+ return Number.isFinite(n) ? Math.trunc(n) : fallback;
10
+ }
11
+ /** Read the `security` blob off a settings document, coercing to a safe shape. */
12
+ export function parseSecuritySettings(blob) {
13
+ const root = (blob && typeof blob === 'object' ? blob : {}) ?? {};
14
+ const sec = (root.security && typeof root.security === 'object'
15
+ ? root.security
16
+ : {});
17
+ const mfa = (sec.mfa && typeof sec.mfa === 'object' ? sec.mfa : {});
18
+ const session = (sec.session && typeof sec.session === 'object' ? sec.session : {});
19
+ return {
20
+ mfa: {
21
+ required: Boolean(mfa.required),
22
+ gracePeriodDays: clampGrace(toInt(mfa.gracePeriodDays, DEFAULT_SECURITY_SETTINGS.mfa.gracePeriodDays)),
23
+ requiredAt: typeof mfa.requiredAt === 'string' ? mfa.requiredAt : undefined,
24
+ },
25
+ session: {
26
+ maxConcurrentSessions: clampSessions(toInt(session.maxConcurrentSessions, DEFAULT_SECURITY_SETTINGS.session.maxConcurrentSessions)),
27
+ },
28
+ updatedAt: typeof sec.updatedAt === 'string' ? sec.updatedAt : undefined,
29
+ updatedBy: typeof sec.updatedBy === 'string' ? sec.updatedBy : undefined,
30
+ };
31
+ }
32
+ function clampGrace(n) {
33
+ if (n < 0)
34
+ return 0;
35
+ if (n > 365)
36
+ return 365;
37
+ return n;
38
+ }
39
+ function clampSessions(n) {
40
+ if (n < 0)
41
+ return 0;
42
+ if (n > 100)
43
+ return 100;
44
+ return n;
45
+ }
46
+ /** Validate an incoming settings payload. Pure — no DB / lockout checks here. */
47
+ export function validateSecuritySettings(settings) {
48
+ const issues = [];
49
+ const grace = settings.mfa.gracePeriodDays;
50
+ if (!Number.isInteger(grace) || grace < 0 || grace > 365) {
51
+ issues.push({
52
+ field: 'mfaGracePeriodDays',
53
+ message: 'MFA grace period must be a whole number of days between 0 and 365.',
54
+ severity: 'error',
55
+ });
56
+ }
57
+ const max = settings.session.maxConcurrentSessions;
58
+ if (!Number.isInteger(max) || max < 0 || max > 100) {
59
+ issues.push({
60
+ field: 'maxConcurrentSessions',
61
+ message: 'Maximum concurrent sessions must be a whole number between 0 (unlimited) and 100.',
62
+ severity: 'error',
63
+ });
64
+ }
65
+ return issues;
66
+ }
67
+ /**
68
+ * Lockout-safe MFA enable check. Enabling org-wide MFA while the acting admin
69
+ * has no TOTP configured would lock them (and possibly everyone) out. Callers
70
+ * MUST run this server-side before persisting `mfa.required = true`.
71
+ */
72
+ export function mfaEnableLockoutError(input) {
73
+ if (!input.enabling)
74
+ return null;
75
+ if (!input.viewerHasMfa) {
76
+ return 'Set up MFA for your own account before requiring it for everyone — otherwise you would lock yourself out.';
77
+ }
78
+ return null;
79
+ }
80
+ const IPV4_OCTET = '(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)';
81
+ const IPV4_RE = new RegExp(`^${IPV4_OCTET}(\\.${IPV4_OCTET}){3}$`);
82
+ /**
83
+ * Validate a single allowlist entry: an IPv4/IPv6 literal or a CIDR range.
84
+ * Standalone (does not import the matcher's private helpers) so it can run in
85
+ * the client bundle for inline form validation.
86
+ */
87
+ export function validateIpRange(entry) {
88
+ const value = entry.trim();
89
+ if (!value)
90
+ return false;
91
+ const [addr, maskStr, ...rest] = value.split('/');
92
+ if (rest.length > 0 || addr === undefined)
93
+ return false;
94
+ const isV6 = addr.includes(':');
95
+ if (maskStr !== undefined) {
96
+ if (!/^\d{1,3}$/.test(maskStr))
97
+ return false;
98
+ const mask = Number(maskStr);
99
+ if (isV6 ? mask > 128 : mask > 32)
100
+ return false;
101
+ }
102
+ return isV6 ? isValidIpv6(addr) : IPV4_RE.test(addr);
103
+ }
104
+ function isValidIpv6(addr) {
105
+ // Reject IPv4-mapped + multiple `::`; otherwise validate 1–8 hextet groups.
106
+ if (addr.includes('.'))
107
+ return false;
108
+ const halves = addr.split('::');
109
+ if (halves.length > 2)
110
+ return false;
111
+ const groups = addr
112
+ .replace('::', ':')
113
+ .split(':')
114
+ .filter((g) => g.length > 0);
115
+ if (groups.length === 0 && halves.length !== 2)
116
+ return false;
117
+ if (groups.length > 8)
118
+ return false;
119
+ return groups.every((g) => /^[0-9a-fA-F]{1,4}$/.test(g));
120
+ }
121
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/security/center/settings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Pure security-posture computation.
3
+ *
4
+ * Turns gathered signals ({@link SecurityStatusInput}) into checks, warnings,
5
+ * an overall level, and an advisory score. No I/O — fully unit-tested so the
6
+ * "is this safe for production?" verdict is deterministic and reviewable.
7
+ */
8
+ import type { SecurityStatus, SecurityStatusInput } from './types.js';
9
+ export declare function computeSecurityStatus(input: SecurityStatusInput): SecurityStatus;
10
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/security/center/status.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAEV,cAAc,EACd,mBAAmB,EAGpB,MAAM,YAAY,CAAA;AA2BnB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,cAAc,CAuNhF"}