@percher/shared 1.2.0 → 1.3.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.
@@ -33,7 +33,7 @@ export declare const DATA_LIMITS: {
33
33
  /** `GET /api/collections` paging for the schema route. */
34
34
  readonly schemaPerPage: 200;
35
35
  readonly schemaMaxPages: 10;
36
- /** PocketBase's `DefaultSortExprLimit` (v0.40.3 `tools/search/provider.go:25`). */
36
+ /** PocketBase's `DefaultSortExprLimit` (v0.40.5 `tools/search/provider.go:25`). */
37
37
  readonly sortMaxItems: 8;
38
38
  /** `duration` sent to PocketBase's impersonate endpoint. */
39
39
  readonly actAsTokenSeconds: 900;
@@ -33,7 +33,7 @@ export const DATA_LIMITS = {
33
33
  /** `GET /api/collections` paging for the schema route. */
34
34
  schemaPerPage: 200,
35
35
  schemaMaxPages: 10,
36
- /** PocketBase's `DefaultSortExprLimit` (v0.40.3 `tools/search/provider.go:25`). */
36
+ /** PocketBase's `DefaultSortExprLimit` (v0.40.5 `tools/search/provider.go:25`). */
37
37
  sortMaxItems: 8,
38
38
  /** `duration` sent to PocketBase's impersonate endpoint. */
39
39
  actAsTokenSeconds: 900,
@@ -0,0 +1,32 @@
1
+ /** Durable publication decision. Scanner strings are diagnostic data, never instructions. */
2
+ export type SecurityScanFailureCode = "SCANNER_UNAVAILABLE" | "SCANNER_ENGINE_DEGRADED" | "SCANNER_DATABASE_ERROR" | "KEV_CATALOG_STALE" | "IMMUTABLE_SOURCE_UNAVAILABLE" | "IMMUTABLE_SOURCE_CHANGED" | "SCAN_EVIDENCE_UNAVAILABLE" | "SCANNER_EXECUTION_ERROR";
3
+ export type DeploymentSecurityAction = "retry_scan" | "update_dependency" | "wait_for_platform_fix";
4
+ export interface DeploymentSecurityFinding {
5
+ cve: string;
6
+ component: string;
7
+ version: string | null;
8
+ fixedIn: string | null;
9
+ severity: "Critical" | "High" | "Medium" | "Low";
10
+ exploitedKev: boolean;
11
+ responsibility: "user" | "percher";
12
+ }
13
+ export interface DeploymentSecurityBlock {
14
+ version: 1;
15
+ context?: "automatic_rollback";
16
+ reason: "vulnerability" | "scan_unavailable";
17
+ imageId: string | null;
18
+ actions: DeploymentSecurityAction[];
19
+ findings: DeploymentSecurityFinding[];
20
+ totalFindings: number;
21
+ truncated: boolean;
22
+ scanFailureCode?: SecurityScanFailureCode;
23
+ }
24
+ export declare function deploymentSecurityActionText(action: DeploymentSecurityAction, context?: "automatic_rollback"): string;
25
+ /** Fixed authored text only; never interpolate scanner-supplied values here. */
26
+ export declare function deploymentSecuritySummary(block: DeploymentSecurityBlock): string;
27
+ /** Fixed recovery instructions; scanner diagnostics never enter this channel. */
28
+ export declare function deploymentSecurityRecoveryPrompt(block: Pick<DeploymentSecurityBlock, "reason" | "context">): string;
29
+ /** Validate persisted/wire data without turning it into a recovery instruction. */
30
+ export declare function parseDeploymentSecurityBlock(value: unknown): DeploymentSecurityBlock | null;
31
+ export declare function decodeDeploymentSecurityBlock(json: string | null | undefined): DeploymentSecurityBlock | null;
32
+ //# sourceMappingURL=deployment-security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment-security.d.ts","sourceRoot":"","sources":["../src/deployment-security.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,MAAM,MAAM,uBAAuB,GAC/B,qBAAqB,GACrB,yBAAyB,GACzB,wBAAwB,GACxB,mBAAmB,GACnB,8BAA8B,GAC9B,0BAA0B,GAC1B,2BAA2B,GAC3B,yBAAyB,CAAC;AAE9B,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,mBAAmB,GAAG,uBAAuB,CAAC;AAEpG,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,MAAM,EAAE,eAAe,GAAG,kBAAkB,CAAC;IAC7C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,uBAAuB,CAAC;CAC3C;AAaD,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,wBAAwB,EAChC,OAAO,CAAC,EAAE,oBAAoB,GAC7B,MAAM,CAWR;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAUhF;AAED,iFAAiF;AACjF,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,IAAI,CAAC,uBAAuB,EAAE,QAAQ,GAAG,SAAS,CAAC,GACzD,MAAM,CASR;AAYD,mFAAmF;AACnF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,GAAG,IAAI,CAiG3F;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,uBAAuB,GAAG,IAAI,CAOhC"}
@@ -0,0 +1,146 @@
1
+ const FAILURE_TEXT = {
2
+ SCANNER_UNAVAILABLE: "The security scanner is unavailable.",
3
+ SCANNER_ENGINE_DEGRADED: "A security scanner did not complete successfully.",
4
+ SCANNER_DATABASE_ERROR: "The vulnerability databases could not be verified as current.",
5
+ KEV_CATALOG_STALE: "The known-exploited vulnerability catalogue is not current.",
6
+ IMMUTABLE_SOURCE_UNAVAILABLE: "The exact image could not be identified.",
7
+ IMMUTABLE_SOURCE_CHANGED: "The image changed during security verification.",
8
+ SCAN_EVIDENCE_UNAVAILABLE: "The security scan result could not be saved or verified.",
9
+ SCANNER_EXECUTION_ERROR: "The security scan could not complete.",
10
+ };
11
+ export function deploymentSecurityActionText(action, context) {
12
+ switch (action) {
13
+ case "retry_scan":
14
+ if (context === "automatic_rollback")
15
+ return "Retry rollback only when security verification is available, or publish a verified replacement.";
16
+ return "Retry publishing when security verification is available. The new image was not published.";
17
+ case "update_dependency":
18
+ return "Update or replace the affected dependency, then publish again.";
19
+ case "wait_for_platform_fix":
20
+ return "Percher must fix the affected platform component before this image can be published.";
21
+ }
22
+ }
23
+ /** Fixed authored text only; never interpolate scanner-supplied values here. */
24
+ export function deploymentSecuritySummary(block) {
25
+ const explanation = block.reason === "scan_unavailable"
26
+ ? block.scanFailureCode
27
+ ? FAILURE_TEXT[block.scanFailureCode]
28
+ : "The image could not be verified by the security scan."
29
+ : "The image contains a critical or known-exploited vulnerability.";
30
+ return block.context === "automatic_rollback"
31
+ ? `Automatic rollback stopped: ${explanation} The current version was kept running and may still be unhealthy.`
32
+ : `Publication stopped: ${explanation}`;
33
+ }
34
+ /** Fixed recovery instructions; scanner diagnostics never enter this channel. */
35
+ export function deploymentSecurityRecoveryPrompt(block) {
36
+ if (block.context === "automatic_rollback") {
37
+ return block.reason === "vulnerability"
38
+ ? "Automatic rollback was blocked because the previous image has a critical or known-exploited vulnerability. The current version was kept running and may still be unhealthy. Review the findings and publish a fixed replacement, or wait for Percher's platform fix."
39
+ : "Automatic rollback stopped because the previous image could not be verified. The current version was kept running and may still be unhealthy. Retry rollback only when verification is available, or publish a verified replacement.";
40
+ }
41
+ return block.reason === "vulnerability"
42
+ ? "Publication was blocked by security policy. Review the vulnerability details, update affected app dependencies or wait for Percher's platform fix before publishing again."
43
+ : "Publication stopped because security verification was unavailable. Retry publishing when verification is available; the scan has not established whether the image is safe.";
44
+ }
45
+ function text(value, max) {
46
+ return (typeof value === "string" &&
47
+ value.length > 0 &&
48
+ value.length <= max &&
49
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: diagnostic fields cannot forge terminal lines.
50
+ !/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/.test(value));
51
+ }
52
+ /** Validate persisted/wire data without turning it into a recovery instruction. */
53
+ export function parseDeploymentSecurityBlock(value) {
54
+ if (!value || typeof value !== "object" || Array.isArray(value))
55
+ return null;
56
+ const v = value;
57
+ if (v.version !== 1)
58
+ return null;
59
+ if (v.context !== undefined && v.context !== "automatic_rollback")
60
+ return null;
61
+ if (v.reason !== "vulnerability" && v.reason !== "scan_unavailable")
62
+ return null;
63
+ if (v.imageId !== null &&
64
+ (typeof v.imageId !== "string" || !/^sha256:[a-f0-9]{64}$/.test(v.imageId)))
65
+ return null;
66
+ if (!Array.isArray(v.actions) ||
67
+ v.actions.length < 1 ||
68
+ v.actions.length > 3 ||
69
+ !v.actions.every((a) => ["retry_scan", "update_dependency", "wait_for_platform_fix"].includes(a)) ||
70
+ new Set(v.actions).size !== v.actions.length)
71
+ return null;
72
+ if (!Array.isArray(v.findings) ||
73
+ v.findings.length > 100 ||
74
+ !Number.isSafeInteger(v.totalFindings) ||
75
+ v.totalFindings < v.findings.length ||
76
+ typeof v.truncated !== "boolean" ||
77
+ v.truncated !== v.totalFindings > v.findings.length)
78
+ return null;
79
+ if (v.scanFailureCode !== undefined &&
80
+ (v.reason !== "scan_unavailable" ||
81
+ typeof v.scanFailureCode !== "string" ||
82
+ !Object.hasOwn(FAILURE_TEXT, v.scanFailureCode)))
83
+ return null;
84
+ if (v.reason === "scan_unavailable" &&
85
+ (v.totalFindings !== 0 || v.actions.length !== 1 || v.actions[0] !== "retry_scan"))
86
+ return null;
87
+ if (v.reason === "vulnerability" && (v.totalFindings === 0 || v.actions.includes("retry_scan")))
88
+ return null;
89
+ if (v.reason === "vulnerability" && v.imageId === null)
90
+ return null;
91
+ const findings = [];
92
+ for (const item of v.findings) {
93
+ if (!item || typeof item !== "object" || Array.isArray(item))
94
+ return null;
95
+ const f = item;
96
+ if (!text(f.cve, 128) ||
97
+ !text(f.component, 512) ||
98
+ !["Critical", "High", "Medium", "Low"].includes(f.severity) ||
99
+ (f.version !== null && !text(f.version, 512)) ||
100
+ (f.fixedIn !== null && !text(f.fixedIn, 2048)) ||
101
+ typeof f.exploitedKev !== "boolean" ||
102
+ !["user", "percher"].includes(f.responsibility))
103
+ return null;
104
+ findings.push({
105
+ cve: f.cve,
106
+ component: f.component,
107
+ version: f.version,
108
+ fixedIn: f.fixedIn,
109
+ severity: f.severity,
110
+ exploitedKev: f.exploitedKev,
111
+ responsibility: f.responsibility,
112
+ });
113
+ }
114
+ if (v.reason === "vulnerability") {
115
+ if (findings.length === 0 || findings.some((f) => f.severity !== "Critical" && !f.exploitedKev))
116
+ return null;
117
+ const required = new Set(findings.map((f) => f.responsibility === "percher" ? "wait_for_platform_fix" : "update_dependency"));
118
+ if ([...required].some((action) => !v.actions.includes(action)))
119
+ return null;
120
+ if (!v.truncated &&
121
+ v.actions.some((action) => !required.has(action)))
122
+ return null;
123
+ }
124
+ return {
125
+ version: 1,
126
+ ...(v.context === "automatic_rollback" ? { context: "automatic_rollback" } : {}),
127
+ reason: v.reason,
128
+ imageId: v.imageId,
129
+ actions: v.actions,
130
+ findings,
131
+ totalFindings: v.totalFindings,
132
+ truncated: v.truncated,
133
+ ...(v.scanFailureCode ? { scanFailureCode: v.scanFailureCode } : {}),
134
+ };
135
+ }
136
+ export function decodeDeploymentSecurityBlock(json) {
137
+ if (!json || json.length > 400_000)
138
+ return null;
139
+ try {
140
+ return parseDeploymentSecurityBlock(JSON.parse(json));
141
+ }
142
+ catch {
143
+ return null;
144
+ }
145
+ }
146
+ //# sourceMappingURL=deployment-security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployment-security.js","sourceRoot":"","sources":["../src/deployment-security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /** How long a change-email link stays usable after it is sent. */
2
+ export declare const EMAIL_CHANGE_LINK_LIFETIME_SECONDS: number;
3
+ /**
4
+ * Pending account email changes. The dashboard writes a row per attempt and
5
+ * the API claims a row in the same transaction that moves the address, so a
6
+ * link is single-use and only the newest one works. Rows cascade away with the
7
+ * auth identity, which is how account erasure removes the addresses they hold.
8
+ * Dashboard-owned like auth_user; the API creates it only in tests.
9
+ */
10
+ export declare const EMAIL_CHANGE_SCHEMA = "\nCREATE TABLE IF NOT EXISTS account_email_changes (\n id TEXT PRIMARY KEY NOT NULL,\n user_id TEXT NOT NULL,\n from_email TEXT NOT NULL,\n to_email TEXT,\n token_hash TEXT UNIQUE,\n created_at INTEGER NOT NULL,\n completed_at INTEGER,\n FOREIGN KEY (user_id) REFERENCES auth_user(id) ON UPDATE no action ON DELETE cascade\n);\nCREATE INDEX IF NOT EXISTS idx_account_email_changes_user_created\n ON account_email_changes (user_id, created_at);";
11
+ //# sourceMappingURL=email-change.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-change.d.ts","sourceRoot":"","sources":["../src/email-change.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,kCAAkC,QAAe,CAAC;AAE/D;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,ycAYkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** How long a change-email link stays usable after it is sent. */
2
+ export const EMAIL_CHANGE_LINK_LIFETIME_SECONDS = 24 * 60 * 60;
3
+ /**
4
+ * Pending account email changes. The dashboard writes a row per attempt and
5
+ * the API claims a row in the same transaction that moves the address, so a
6
+ * link is single-use and only the newest one works. Rows cascade away with the
7
+ * auth identity, which is how account erasure removes the addresses they hold.
8
+ * Dashboard-owned like auth_user; the API creates it only in tests.
9
+ */
10
+ export const EMAIL_CHANGE_SCHEMA = `
11
+ CREATE TABLE IF NOT EXISTS account_email_changes (
12
+ id TEXT PRIMARY KEY NOT NULL,
13
+ user_id TEXT NOT NULL,
14
+ from_email TEXT NOT NULL,
15
+ to_email TEXT,
16
+ token_hash TEXT UNIQUE,
17
+ created_at INTEGER NOT NULL,
18
+ completed_at INTEGER,
19
+ FOREIGN KEY (user_id) REFERENCES auth_user(id) ON UPDATE no action ON DELETE cascade
20
+ );
21
+ CREATE INDEX IF NOT EXISTS idx_account_email_changes_user_created
22
+ ON account_email_changes (user_id, created_at);`;
23
+ //# sourceMappingURL=email-change.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-change.js","sourceRoot":"","sources":["../src/email-change.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,kCAAkC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;kDAYe,CAAC"}
@@ -0,0 +1,19 @@
1
+ /** Fixed first-party asset; the live wordmark identifies us with images blocked.
2
+ * Only its URL ships in npm. The mark artwork stays in the private package. */
3
+ export declare const EMAIL_BRAND_HEADER: string;
4
+ type EmailFooter = "none" | {
5
+ kind: "notifications";
6
+ dashboardUrl: string;
7
+ };
8
+ /** Use the dashboard origin, not an app/deploy path or its query string. */
9
+ export declare function emailNotificationSettingsUrl(dashboardUrl: string): string;
10
+ /** Callers escape values in bodyHtml and explicitly choose the footer policy.
11
+ * Notification settings apply only to mail with an effective preference gate;
12
+ * security/legal notices and signed waitlist removal links keep their own copy. */
13
+ export declare function renderEmail(input: {
14
+ bodyHtml: string;
15
+ footer: EmailFooter;
16
+ lang?: "en" | "sv";
17
+ }): string;
18
+ export {};
19
+ //# sourceMappingURL=email-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-template.d.ts","sourceRoot":"","sources":["../src/email-template.ts"],"names":[],"mappings":"AAGA;+EAC+E;AAC/E,eAAO,MAAM,kBAAkB,QAGxB,CAAC;AAER,KAAK,WAAW,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E,4EAA4E;AAC5E,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAUzE;AAED;;mFAEmF;AACnF,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACpB,GAAG,MAAM,CA4BT"}
@@ -0,0 +1,53 @@
1
+ import { BRAND } from "./brand.js";
2
+ import { escapeHtml } from "./escape-html.js";
3
+ /** Fixed first-party asset; the live wordmark identifies us with images blocked.
4
+ * Only its URL ships in npm. The mark artwork stays in the private package. */
5
+ export const EMAIL_BRAND_HEADER = `<p style="margin:0 0 20px;line-height:28px;">
6
+ <img src="https://percher.app/email-mark.png" width="28" height="28" alt="" style="display:inline-block;vertical-align:middle;border:0;margin-right:7px;" />
7
+ <span style="font-size:19px;font-weight:700;letter-spacing:-0.01em;color:${BRAND.ink};vertical-align:middle;">Percher</span>
8
+ </p>`;
9
+ /** Use the dashboard origin, not an app/deploy path or its query string. */
10
+ export function emailNotificationSettingsUrl(dashboardUrl) {
11
+ try {
12
+ const url = new URL(dashboardUrl);
13
+ if (url.protocol === "https:" || url.protocol === "http:") {
14
+ return `${url.origin}/login?next=%2Faccount%23notifications`;
15
+ }
16
+ }
17
+ catch {
18
+ // A malformed dashboard link must not turn the footer into an unsafe URL.
19
+ }
20
+ return "https://percher.app/login?next=%2Faccount%23notifications";
21
+ }
22
+ /** Callers escape values in bodyHtml and explicitly choose the footer policy.
23
+ * Notification settings apply only to mail with an effective preference gate;
24
+ * security/legal notices and signed waitlist removal links keep their own copy. */
25
+ export function renderEmail(input) {
26
+ const footer = input.footer === "none"
27
+ ? ""
28
+ : `<p style="margin:24px 0 0;padding-top:16px;border-top:1px solid #e5e5e5;font-size:12px;line-height:1.5;color:#666;"><a href="${escapeHtml(emailNotificationSettingsUrl(input.footer.dashboardUrl))}" style="color:#666;">Manage notifications</a></p>`;
29
+ return `<!doctype html>
30
+ <html lang="${input.lang === "sv" ? "sv" : "en"}">
31
+ <head>
32
+ <meta charset="utf-8" />
33
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
34
+ <style>
35
+ .percher-email-content h1,.percher-email-content h2{margin:0 0 16px;font-size:22px;line-height:1.3;}
36
+ .percher-email-content pre{white-space:pre-wrap;word-break:break-word;}
37
+ @media only screen and (max-width:480px){.percher-email-content{padding:20px!important;}.percher-email-outer{padding:12px 8px!important;}}
38
+ </style>
39
+ </head>
40
+ <body style="margin:0;padding:0;background:#f5f5f5;">
41
+ <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="border-collapse:collapse;background:#f5f5f5;"><tr><td class="percher-email-outer" align="center" style="padding:24px 12px;">
42
+ <!--[if mso]><table role="presentation" width="600" cellpadding="0" cellspacing="0"><tr><td><![endif]-->
43
+ <table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="max-width:600px;margin:0 auto;background:#fff;border:1px solid #e5e5e5;border-radius:8px;table-layout:fixed;"><tr><td class="percher-email-content" style="padding:28px;font-family:Arial,Helvetica,sans-serif;font-size:15px;line-height:1.6;color:${BRAND.ink};overflow-wrap:anywhere;word-break:break-word;">
44
+ ${EMAIL_BRAND_HEADER}
45
+ ${input.bodyHtml.trim()}
46
+ ${footer}
47
+ </td></tr></table>
48
+ <!--[if mso]></td></tr></table><![endif]-->
49
+ </td></tr></table>
50
+ </body>
51
+ </html>`;
52
+ }
53
+ //# sourceMappingURL=email-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-template.js","sourceRoot":"","sources":["../src/email-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;+EAC+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG;;+EAE6C,KAAK,CAAC,GAAG;OACjF,CAAC;AAIR,4EAA4E;AAC5E,MAAM,UAAU,4BAA4B,CAAC,YAAoB;IAC/D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;QAClC,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC1D,OAAO,GAAG,GAAG,CAAC,MAAM,wCAAwC,CAAC;QAC/D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;IAC5E,CAAC;IACD,OAAO,2DAA2D,CAAC;AACrE,CAAC;AAED;;mFAEmF;AACnF,MAAM,UAAU,WAAW,CAAC,KAI3B;IACC,MAAM,MAAM,GACV,KAAK,CAAC,MAAM,KAAK,MAAM;QACrB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,gIAAgI,UAAU,CAAC,4BAA4B,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,oDAAoD,CAAC;IAC9P,OAAO;cACK,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;;;;;;;;;;;;;yUAa0R,KAAK,CAAC,GAAG;QAC1U,kBAAkB;QAClB,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE;QACrB,MAAM;;;;;QAKN,CAAC;AACT,CAAC"}
package/dist/index.d.ts CHANGED
@@ -5,17 +5,21 @@ export { CLIENT_IP_ATTESTATION_MAX_SKEW_MS, CLIENT_IP_ATTESTATION_VERSION, CLIEN
5
5
  export { crashAssistantPrompt } from "./crash-prompt.js";
6
6
  export { type DataExpressionErrorReason, type DataExpressionResult, type DataQueryInvalidExtra, type DataSchemaField, parseDataFields, parseDataFilter, parseDataSort, } from "./data-filter.js";
7
7
  export { DATA_ACCESS_MODES, DATA_ACCESS_SCOPES, DATA_ACCESS_SETTER_ERROR_STATUS, DATA_ACT_AS_UNAVAILABLE_REASONS, DATA_ACTING_AS, DATA_COLLECTION_RE, DATA_IDENTITY_KINDS, DATA_IDENTITY_LABEL_FIELD_TYPES, DATA_IDENTITY_LABELS, DATA_LIMITS, DATA_NOT_RUNNING_REASONS, DATA_RATE_LIMIT_SOURCES, DATA_RECORD_ERROR_STATUS, DATA_RECORD_ID_RE, DATA_RULE_CLASSES, DATA_RULE_DENIED_REASONS, DATA_RULE_OPS, type DataAccess, type DataAccessMode, type DataAccessNoticePayload, type DataAccessScope, type DataAccessSet, type DataAccessSetterErrorCode, type DataAccessUpdate, type DataActAsUnavailableExtra, type DataActAsUnavailableReason, type DataActingAs, type DataCollectionAccess, type DataCollectionSummary, type DataConflictExtra, type DataCreateInput, type DataFieldSummary, type DataIdentity, type DataIdentityCandidatesRequest, type DataIdentityCandidatesResponse, type DataIdentityCollection, type DataIdentityLabelFieldType, type DataNotRunningReason, type DataPaginatedRecords, type DataQueryOptions, type DataRateLimitedExtra, type DataRateLimitSource, type DataRecord, type DataRecordErrorCode, type DataRuleClass, type DataRuleDeniedExtra, type DataRuleDeniedReason, type DataRuleOp, type DataSchemaResponse, type DataTokenAccessNoticePayload, type DataTokenAccessRow, type DataTokenAccessUpdate, type DataUpdateInput, type DataValidationFields, type OAuthGrantsDataTools, } from "./data-records.js";
8
+ export { type DeploymentSecurityAction, type DeploymentSecurityBlock, type DeploymentSecurityFinding, decodeDeploymentSecurityBlock, deploymentSecurityActionText, deploymentSecurityRecoveryPrompt, deploymentSecuritySummary, parseDeploymentSecurityBlock, type SecurityScanFailureCode, } from "./deployment-security.js";
8
9
  export { disposableDomainCount, isDisposableEmailDomain } from "./disposable-email-domains.js";
9
10
  export { DOMAIN_RE } from "./domain-name.js";
10
11
  export { EMAIL_BUDGET_LIMITS, EMAIL_BUDGET_SCHEMA, EmailBudget, type EmailBudgetConnection, type EmailCategory, } from "./email-budget.js";
12
+ export { EMAIL_CHANGE_LINK_LIFETIME_SECONDS, EMAIL_CHANGE_SCHEMA } from "./email-change.js";
13
+ export { EMAIL_BRAND_HEADER, emailNotificationSettingsUrl, renderEmail } from "./email-template.js";
11
14
  export { ENV_MASK, isMaskedEnvValue, maskEnvValue } from "./env-mask.js";
12
15
  export { ENV_NAME_RE } from "./env-name.js";
13
16
  export { escapeHtml } from "./escape-html.js";
14
17
  export { IMAGE_REJECTION_NOTE_MAX, IMAGE_REJECTION_REASONS, type ImageKind, type ImageRejectionCode, imageRejectionLabel, imageRejectionReasons, isImageRejectionCode, } from "./image-rejection.js";
15
18
  export { INTERNAL_SIG_HEADER, INTERNAL_SIG_MAX_SKEW_MS, INTERNAL_SIG_VERSION, INTERNAL_TS_HEADER, type InternalSigParts, internalSigPayload, } from "./internal-sig.js";
19
+ export { ipSubnetKey, parseIpAddress } from "./ip-prefix.js";
16
20
  export { CURRENT_TERMS_VERSION, LEGAL_DOCUMENT_HASHES, LEGAL_DOCUMENT_LAST_UPDATED, LEGAL_DOCUMENT_VERSIONS, type TermsAcceptanceEvidence, } from "./legal.js";
17
21
  export { canonicalLegalChangeJson, compareVersions, declaredVersion, LEGAL_CHANGE_ID_PATTERN, LEGAL_CHANGES, LEGAL_VERSION_PATTERN, type LegalChange, type LegalChangeDocument, type LegalChangeEnforcement, type LegalChangeReason, type LegalDocumentKey, MATERIAL_CHANGE_NOTICE_MS, openMaterialChanges, pendingAcknowledgement, SIGNUP_DISCLOSURE_HEADER, } from "./legal-changes.js";
18
- export { MAX_ANON_TARBALL_BYTES, MAX_INLINE_PUBLISH_BYTES, MAX_OPEN_UPLOAD_SESSIONS_PER_USER, MAX_TARBALL_BYTES, MAX_UPLOAD_CHUNK_BYTES, MAX_UPLOAD_SESSION_FILES, MIN_UPLOAD_CHUNK_BYTES, UPLOAD_SESSION_MAX_LIFETIME_MS, UPLOAD_SESSION_TTL_MS, } from "./limits.js";
22
+ export { MAX_ANON_TARBALL_BYTES, MAX_INLINE_PUBLISH_BYTES, MAX_OPEN_UPLOAD_SESSIONS_PER_USER, MAX_TARBALL_BYTES, MAX_UPLOAD_CHUNK_BYTES, MAX_UPLOAD_SESSION_FILES, MFA_MANAGEMENT_SECONDS, MIN_UPLOAD_CHUNK_BYTES, STAFF_MFA_PROOF_SECONDS, UPLOAD_SESSION_MAX_LIFETIME_MS, UPLOAD_SESSION_TTL_MS, } from "./limits.js";
19
23
  export { MAX_LOG_SEARCH_LENGTH } from "./logs.js";
20
24
  export { MAX_OAUTH_CLIENT_NAME_DISPLAY_CODE_POINTS, normaliseOAuthClientName, } from "./oauth-client-name.js";
21
25
  export { DATA_ACCESS_MODE_LABELS, describeOAuthScope, OAUTH_SCOPE_LABELS, parseOAuthScopes, } from "./oauth-scopes.js";
@@ -27,5 +31,6 @@ export { signupDayWindow } from "./signup-day.js";
27
31
  export { normalizeSignupInviteCode, SIGNUP_INVITE_CODE_ALPHABET, SIGNUP_INVITE_CODE_LENGTH, SIGNUP_INVITE_CODE_PREFIX, SIGNUP_INVITE_HEADER, } from "./signup-invite.js";
28
32
  export { assertValidSwitches, type BooleanSwitch, type EnumSwitch, type PresenceSwitch, reportSwitches, SWITCH_BY_NAME, SWITCHES, type SwitchReader, type SwitchReport, type SwitchSpec, type SwitchState, switchEnabled, switchState, switchValue, } from "./switches.js";
29
33
  export { BUN_MAX_IDLE_TIMEOUT_SECONDS, HTTP_IDLE_TIMEOUT_SECONDS, type HttpIdleTimeoutSurface, TIMEOUTS, type TimeoutKey, } from "./timeouts.js";
34
+ export { chargeVerifiedSignup, initializeVerifiedSignupCutover, type SignupQuotaConnection, VerifiedSignupLimitError, verifiedSignupQuota, } from "./verified-signup.js";
30
35
  export { WAITLIST_THROTTLE_WINDOW_MS } from "./waitlist.js";
31
36
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -5,17 +5,21 @@ export { CLIENT_IP_ATTESTATION_MAX_SKEW_MS, CLIENT_IP_ATTESTATION_VERSION, CLIEN
5
5
  export { crashAssistantPrompt } from "./crash-prompt.js";
6
6
  export { parseDataFields, parseDataFilter, parseDataSort, } from "./data-filter.js";
7
7
  export { DATA_ACCESS_MODES, DATA_ACCESS_SCOPES, DATA_ACCESS_SETTER_ERROR_STATUS, DATA_ACT_AS_UNAVAILABLE_REASONS, DATA_ACTING_AS, DATA_COLLECTION_RE, DATA_IDENTITY_KINDS, DATA_IDENTITY_LABEL_FIELD_TYPES, DATA_IDENTITY_LABELS, DATA_LIMITS, DATA_NOT_RUNNING_REASONS, DATA_RATE_LIMIT_SOURCES, DATA_RECORD_ERROR_STATUS, DATA_RECORD_ID_RE, DATA_RULE_CLASSES, DATA_RULE_DENIED_REASONS, DATA_RULE_OPS, } from "./data-records.js";
8
+ export { decodeDeploymentSecurityBlock, deploymentSecurityActionText, deploymentSecurityRecoveryPrompt, deploymentSecuritySummary, parseDeploymentSecurityBlock, } from "./deployment-security.js";
8
9
  export { disposableDomainCount, isDisposableEmailDomain } from "./disposable-email-domains.js";
9
10
  export { DOMAIN_RE } from "./domain-name.js";
10
11
  export { EMAIL_BUDGET_LIMITS, EMAIL_BUDGET_SCHEMA, EmailBudget, } from "./email-budget.js";
12
+ export { EMAIL_CHANGE_LINK_LIFETIME_SECONDS, EMAIL_CHANGE_SCHEMA } from "./email-change.js";
13
+ export { EMAIL_BRAND_HEADER, emailNotificationSettingsUrl, renderEmail } from "./email-template.js";
11
14
  export { ENV_MASK, isMaskedEnvValue, maskEnvValue } from "./env-mask.js";
12
15
  export { ENV_NAME_RE } from "./env-name.js";
13
16
  export { escapeHtml } from "./escape-html.js";
14
17
  export { IMAGE_REJECTION_NOTE_MAX, IMAGE_REJECTION_REASONS, imageRejectionLabel, imageRejectionReasons, isImageRejectionCode, } from "./image-rejection.js";
15
18
  export { INTERNAL_SIG_HEADER, INTERNAL_SIG_MAX_SKEW_MS, INTERNAL_SIG_VERSION, INTERNAL_TS_HEADER, internalSigPayload, } from "./internal-sig.js";
19
+ export { ipSubnetKey, parseIpAddress } from "./ip-prefix.js";
16
20
  export { CURRENT_TERMS_VERSION, LEGAL_DOCUMENT_HASHES, LEGAL_DOCUMENT_LAST_UPDATED, LEGAL_DOCUMENT_VERSIONS, } from "./legal.js";
17
21
  export { canonicalLegalChangeJson, compareVersions, declaredVersion, LEGAL_CHANGE_ID_PATTERN, LEGAL_CHANGES, LEGAL_VERSION_PATTERN, MATERIAL_CHANGE_NOTICE_MS, openMaterialChanges, pendingAcknowledgement, SIGNUP_DISCLOSURE_HEADER, } from "./legal-changes.js";
18
- export { MAX_ANON_TARBALL_BYTES, MAX_INLINE_PUBLISH_BYTES, MAX_OPEN_UPLOAD_SESSIONS_PER_USER, MAX_TARBALL_BYTES, MAX_UPLOAD_CHUNK_BYTES, MAX_UPLOAD_SESSION_FILES, MIN_UPLOAD_CHUNK_BYTES, UPLOAD_SESSION_MAX_LIFETIME_MS, UPLOAD_SESSION_TTL_MS, } from "./limits.js";
22
+ export { MAX_ANON_TARBALL_BYTES, MAX_INLINE_PUBLISH_BYTES, MAX_OPEN_UPLOAD_SESSIONS_PER_USER, MAX_TARBALL_BYTES, MAX_UPLOAD_CHUNK_BYTES, MAX_UPLOAD_SESSION_FILES, MFA_MANAGEMENT_SECONDS, MIN_UPLOAD_CHUNK_BYTES, STAFF_MFA_PROOF_SECONDS, UPLOAD_SESSION_MAX_LIFETIME_MS, UPLOAD_SESSION_TTL_MS, } from "./limits.js";
19
23
  export { MAX_LOG_SEARCH_LENGTH } from "./logs.js";
20
24
  export { MAX_OAUTH_CLIENT_NAME_DISPLAY_CODE_POINTS, normaliseOAuthClientName, } from "./oauth-client-name.js";
21
25
  export { DATA_ACCESS_MODE_LABELS, describeOAuthScope, OAUTH_SCOPE_LABELS, parseOAuthScopes, } from "./oauth-scopes.js";
@@ -27,5 +31,6 @@ export { signupDayWindow } from "./signup-day.js";
27
31
  export { normalizeSignupInviteCode, SIGNUP_INVITE_CODE_ALPHABET, SIGNUP_INVITE_CODE_LENGTH, SIGNUP_INVITE_CODE_PREFIX, SIGNUP_INVITE_HEADER, } from "./signup-invite.js";
28
32
  export { assertValidSwitches, reportSwitches, SWITCH_BY_NAME, SWITCHES, switchEnabled, switchState, switchValue, } from "./switches.js";
29
33
  export { BUN_MAX_IDLE_TIMEOUT_SECONDS, HTTP_IDLE_TIMEOUT_SECONDS, TIMEOUTS, } from "./timeouts.js";
34
+ export { chargeVerifiedSignup, initializeVerifiedSignupCutover, VerifiedSignupLimitError, verifiedSignupQuota, } from "./verified-signup.js";
30
35
  export { WAITLIST_THROTTLE_WINDOW_MS } from "./waitlist.js";
31
36
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Binary IP parsing and subnet-prefix keying.
3
+ *
4
+ * Any limit keyed on "the network this request came from" needs the address
5
+ * reduced to a prefix, and that reduction has to happen on BYTES. The textual
6
+ * form of an IPv6 address is not positional: "2001:db8::1" and
7
+ * "2001:0db8:0000:0000:0000:0000:0000:0001" are the same address, and
8
+ * "2001::abcd:1" has its hextets in entirely different places than a naive
9
+ * split(":") suggests. Masking by slicing the text therefore puts one address
10
+ * in several buckets and unrelated addresses in one — which is exactly the
11
+ * evasion a subnet key exists to prevent.
12
+ */
13
+ /** A parsed address as raw bytes: 4 for IPv4, 16 for IPv6. */
14
+ export type ParsedIp = {
15
+ family: 4;
16
+ bytes: Uint8Array;
17
+ } | {
18
+ family: 6;
19
+ bytes: Uint8Array;
20
+ };
21
+ /**
22
+ * Parse an address to bytes, or null if it is not one.
23
+ *
24
+ * An IPv6 zone id ("fe80::1%eth0") is dropped — it names a local interface,
25
+ * not a different host. An IPv4-mapped address ("::ffff:203.0.113.7") is
26
+ * returned as the IPv4 it carries, so one client cannot occupy two buckets by
27
+ * choosing a spelling, and so every mapped client does not collapse into one
28
+ * shared bucket.
29
+ *
30
+ * Brackets and zone ids belong to IPv6 alone, so "[1.2.3.4]" and
31
+ * "1.2.3.4%eth0" are rejected rather than quietly read as IPv4 — this decides
32
+ * whether a caller is refused or filed under a real network, and a spelling no
33
+ * address ever has means a caller we cannot key.
34
+ */
35
+ export declare function parseIpAddress(ip: string): ParsedIp | null;
36
+ /**
37
+ * Collapse an address to its subnet key, e.g. "203.0.113.0/24" or
38
+ * "2001:db8:1::/48". Returns null for anything that is not an address, so a
39
+ * caller that must not guess (an admission cap) can refuse, while one with a
40
+ * safe fallback (a rate limiter) can bucket the raw string instead.
41
+ */
42
+ export declare function ipSubnetKey(ip: string, v4Bits: number, v6Bits: number): string | null;
43
+ //# sourceMappingURL=ip-prefix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-prefix.d.ts","sourceRoot":"","sources":["../src/ip-prefix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,8DAA8D;AAC9D,MAAM,MAAM,QAAQ,GAAG;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AA+F3F;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAyB1D;AAmDD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQrF"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Binary IP parsing and subnet-prefix keying.
3
+ *
4
+ * Any limit keyed on "the network this request came from" needs the address
5
+ * reduced to a prefix, and that reduction has to happen on BYTES. The textual
6
+ * form of an IPv6 address is not positional: "2001:db8::1" and
7
+ * "2001:0db8:0000:0000:0000:0000:0000:0001" are the same address, and
8
+ * "2001::abcd:1" has its hextets in entirely different places than a naive
9
+ * split(":") suggests. Masking by slicing the text therefore puts one address
10
+ * in several buckets and unrelated addresses in one — which is exactly the
11
+ * evasion a subnet key exists to prevent.
12
+ */
13
+ const HEXTET_RE = /^[0-9a-fA-F]{1,4}$/;
14
+ const OCTET_RE = /^\d{1,3}$/;
15
+ /** Zone id characters we accept (RFC 4007 scope zones as they are actually
16
+ * written: an interface name or an index). Deliberately narrow — the zone is
17
+ * discarded, so anything unusual here is a spelling no address has — and this
18
+ * module's boundary is that such a caller is refused rather than filed under
19
+ * somebody's network. */
20
+ const ZONE_RE = /^[0-9A-Za-z._~-]+$/;
21
+ function parseIpv4Bytes(text) {
22
+ const parts = text.split(".");
23
+ if (parts.length !== 4)
24
+ return null;
25
+ const bytes = new Uint8Array(4);
26
+ for (let i = 0; i < 4; i++) {
27
+ const part = parts[i];
28
+ // Leading zeros are rejected rather than parsed: "010" is 8 in one
29
+ // reading and 10 in another, and two readings of one address are two
30
+ // buckets. Canonical spellings only, same as node's net.isIP.
31
+ if (!OCTET_RE.test(part) || (part.length > 1 && part.startsWith("0")))
32
+ return null;
33
+ const n = Number(part);
34
+ if (n > 255)
35
+ return null;
36
+ bytes[i] = n;
37
+ }
38
+ return bytes;
39
+ }
40
+ /**
41
+ * Read one side of a "::" split into 16-bit groups, or null if any token is
42
+ * not a legal hextet.
43
+ *
44
+ * `allowEmbeddedIpv4` is only true for the side that ends the whole address:
45
+ * an embedded dotted quad occupies the last 32 bits, so "192.0.2.1::" and
46
+ * "1:192.0.2.1::" are not addresses. Accepting them mapped them onto real
47
+ * prefixes ("192.0.2.1::" landed in c000:201::/56), which is worse than
48
+ * rejecting them — a caller that cannot be keyed must be refused, not filed
49
+ * under somebody else's network.
50
+ */
51
+ function groupsFrom(part, allowEmbeddedIpv4) {
52
+ if (part === "")
53
+ return [];
54
+ const tokens = part.split(":");
55
+ const groups = [];
56
+ for (let i = 0; i < tokens.length; i++) {
57
+ const token = tokens[i];
58
+ if (token.includes(".")) {
59
+ if (!allowEmbeddedIpv4 || i !== tokens.length - 1)
60
+ return null;
61
+ const v4 = parseIpv4Bytes(token);
62
+ if (!v4)
63
+ return null;
64
+ groups.push((v4[0] << 8) | v4[1]);
65
+ groups.push((v4[2] << 8) | v4[3]);
66
+ continue;
67
+ }
68
+ if (!HEXTET_RE.test(token))
69
+ return null;
70
+ groups.push(Number.parseInt(token, 16));
71
+ }
72
+ return groups;
73
+ }
74
+ function parseIpv6Bytes(text) {
75
+ const halves = text.split("::");
76
+ if (halves.length > 2)
77
+ return null;
78
+ // With no "::" the single side ends the address; with one, the tail does —
79
+ // even when the tail is empty, which is what makes "192.0.2.1::" invalid.
80
+ const head = groupsFrom(halves[0], halves.length === 1);
81
+ if (!head)
82
+ return null;
83
+ let groups;
84
+ if (halves.length === 1) {
85
+ if (head.length !== 8)
86
+ return null;
87
+ groups = head;
88
+ }
89
+ else {
90
+ const tail = groupsFrom(halves[1], true);
91
+ if (!tail)
92
+ return null;
93
+ // "::" must stand for at least one zero group, so a full 8 either side
94
+ // of it is not a valid spelling of an address.
95
+ const gap = 8 - head.length - tail.length;
96
+ if (gap < 1)
97
+ return null;
98
+ groups = [...head, ...new Array(gap).fill(0), ...tail];
99
+ }
100
+ const bytes = new Uint8Array(16);
101
+ for (let i = 0; i < 8; i++) {
102
+ const g = groups[i];
103
+ bytes[i * 2] = g >> 8;
104
+ bytes[i * 2 + 1] = g & 0xff;
105
+ }
106
+ return bytes;
107
+ }
108
+ function isIpv4Mapped(bytes) {
109
+ for (let i = 0; i < 10; i++)
110
+ if (bytes[i] !== 0)
111
+ return false;
112
+ return bytes[10] === 0xff && bytes[11] === 0xff;
113
+ }
114
+ /**
115
+ * Parse an address to bytes, or null if it is not one.
116
+ *
117
+ * An IPv6 zone id ("fe80::1%eth0") is dropped — it names a local interface,
118
+ * not a different host. An IPv4-mapped address ("::ffff:203.0.113.7") is
119
+ * returned as the IPv4 it carries, so one client cannot occupy two buckets by
120
+ * choosing a spelling, and so every mapped client does not collapse into one
121
+ * shared bucket.
122
+ *
123
+ * Brackets and zone ids belong to IPv6 alone, so "[1.2.3.4]" and
124
+ * "1.2.3.4%eth0" are rejected rather than quietly read as IPv4 — this decides
125
+ * whether a caller is refused or filed under a real network, and a spelling no
126
+ * address ever has means a caller we cannot key.
127
+ */
128
+ export function parseIpAddress(ip) {
129
+ if (!ip)
130
+ return null;
131
+ let text = ip.trim();
132
+ const bracketed = text.startsWith("[") && text.endsWith("]");
133
+ if (bracketed)
134
+ text = text.slice(1, -1);
135
+ const zone = text.indexOf("%");
136
+ const zoned = zone !== -1;
137
+ if (zoned) {
138
+ // The zone is discarded, so it was previously taken on trust — which let
139
+ // "fe80::1%a%b", "fe80::1%a b" and a zone full of control characters all
140
+ // parse as fe80::1. They reach no wrong bucket, but they are not addresses.
141
+ if (!ZONE_RE.test(text.slice(zone + 1)))
142
+ return null;
143
+ text = text.slice(0, zone);
144
+ }
145
+ if (!text)
146
+ return null;
147
+ if (!text.includes(":")) {
148
+ if (bracketed || zoned)
149
+ return null;
150
+ const v4 = parseIpv4Bytes(text);
151
+ return v4 ? { family: 4, bytes: v4 } : null;
152
+ }
153
+ const v6 = parseIpv6Bytes(text);
154
+ if (!v6)
155
+ return null;
156
+ if (isIpv4Mapped(v6))
157
+ return { family: 4, bytes: v6.slice(12) };
158
+ return { family: 6, bytes: v6 };
159
+ }
160
+ function maskBytes(bytes, bits) {
161
+ const out = new Uint8Array(bytes.length);
162
+ const wholeBytes = bits >> 3;
163
+ out.set(bytes.subarray(0, wholeBytes));
164
+ const remainder = bits & 7;
165
+ if (remainder > 0 && wholeBytes < bytes.length) {
166
+ out[wholeBytes] = bytes[wholeBytes] & (0xff << (8 - remainder));
167
+ }
168
+ return out;
169
+ }
170
+ /** Render IPv6 bytes in the canonical RFC 5952 form: lowercase, no leading
171
+ * zeros, the longest run of zero groups (leftmost on a tie) compressed. */
172
+ function formatIpv6(bytes) {
173
+ const groups = [];
174
+ for (let i = 0; i < 16; i += 2) {
175
+ groups.push((bytes[i] << 8) | bytes[i + 1]);
176
+ }
177
+ let bestStart = -1;
178
+ let bestLen = 0;
179
+ let runStart = -1;
180
+ let runLen = 0;
181
+ for (let i = 0; i < 8; i++) {
182
+ if (groups[i] === 0) {
183
+ if (runStart < 0) {
184
+ runStart = i;
185
+ runLen = 0;
186
+ }
187
+ runLen++;
188
+ if (runLen > bestLen) {
189
+ bestLen = runLen;
190
+ bestStart = runStart;
191
+ }
192
+ }
193
+ else {
194
+ runStart = -1;
195
+ runLen = 0;
196
+ }
197
+ }
198
+ const hex = (g) => g.toString(16);
199
+ // A single zero group is written out; "::" stands for two or more.
200
+ if (bestLen < 2)
201
+ return groups.map(hex).join(":");
202
+ const head = groups.slice(0, bestStart).map(hex).join(":");
203
+ const tail = groups
204
+ .slice(bestStart + bestLen)
205
+ .map(hex)
206
+ .join(":");
207
+ return `${head}::${tail}`;
208
+ }
209
+ /**
210
+ * Collapse an address to its subnet key, e.g. "203.0.113.0/24" or
211
+ * "2001:db8:1::/48". Returns null for anything that is not an address, so a
212
+ * caller that must not guess (an admission cap) can refuse, while one with a
213
+ * safe fallback (a rate limiter) can bucket the raw string instead.
214
+ */
215
+ export function ipSubnetKey(ip, v4Bits, v6Bits) {
216
+ const parsed = parseIpAddress(ip);
217
+ if (!parsed)
218
+ return null;
219
+ if (parsed.family === 4) {
220
+ const masked = maskBytes(parsed.bytes, v4Bits);
221
+ return `${masked.join(".")}/${v4Bits}`;
222
+ }
223
+ return `${formatIpv6(maskBytes(parsed.bytes, v6Bits))}/${v6Bits}`;
224
+ }
225
+ //# sourceMappingURL=ip-prefix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-prefix.js","sourceRoot":"","sources":["../src/ip-prefix.ts"],"names":[],"mappings":"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"}
package/dist/limits.d.ts CHANGED
@@ -60,4 +60,15 @@ export declare const UPLOAD_SESSION_MAX_LIFETIME_MS: number;
60
60
  export declare const MAX_OPEN_UPLOAD_SESSIONS_PER_USER = 2;
61
61
  /** Max files a single upload-session manifest may declare. */
62
62
  export declare const MAX_UPLOAD_SESSION_FILES = 400;
63
+ /**
64
+ * Lifetime of a staff MFA proof (12 h). The dashboard (`lib/mfa.ts`) and the
65
+ * API staff gate (`middleware/staff-mfa.ts`) read this one value.
66
+ */
67
+ export declare const STAFF_MFA_PROOF_SECONDS: number;
68
+ /**
69
+ * How recent a proof must be for a sensitive MFA action (5 min): disabling the
70
+ * factor, new recovery codes, an email change and minting an operator token.
71
+ * The dashboard (`lib/mfa.ts`) and the API operator-token route read this value.
72
+ */
73
+ export declare const MFA_MANAGEMENT_SECONDS: number;
63
74
  //# sourceMappingURL=limits.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,QAAoB,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QAAmB,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,QAAmB,CAAC;AAEzD;;;;;;GAMG;AAEH;;8BAE8B;AAC9B,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD;;;;;iEAKiE;AACjE,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD;;;;qDAIqD;AACrD,eAAO,MAAM,qBAAqB,QAAqB,CAAC;AAExD;;4BAE4B;AAC5B,eAAO,MAAM,8BAA8B,QAAsB,CAAC;AAElE;yEACyE;AACzE,eAAO,MAAM,iCAAiC,IAAI,CAAC;AAEnD,8DAA8D;AAC9D,eAAO,MAAM,wBAAwB,MAAM,CAAC"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,QAAoB,CAAC;AAEnD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QAAmB,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,QAAmB,CAAC;AAEzD;;;;;;GAMG;AAEH;;8BAE8B;AAC9B,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD;;;;;iEAKiE;AACjE,eAAO,MAAM,sBAAsB,QAAY,CAAC;AAEhD;;;;qDAIqD;AACrD,eAAO,MAAM,qBAAqB,QAAqB,CAAC;AAExD;;4BAE4B;AAC5B,eAAO,MAAM,8BAA8B,QAAsB,CAAC;AAElE;yEACyE;AACzE,eAAO,MAAM,iCAAiC,IAAI,CAAC;AAEnD,8DAA8D;AAC9D,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,uBAAuB,QAAe,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,QAAS,CAAC"}
package/dist/limits.js CHANGED
@@ -60,4 +60,15 @@ export const UPLOAD_SESSION_MAX_LIFETIME_MS = 24 * 60 * 60 * 1000;
60
60
  export const MAX_OPEN_UPLOAD_SESSIONS_PER_USER = 2;
61
61
  /** Max files a single upload-session manifest may declare. */
62
62
  export const MAX_UPLOAD_SESSION_FILES = 400;
63
+ /**
64
+ * Lifetime of a staff MFA proof (12 h). The dashboard (`lib/mfa.ts`) and the
65
+ * API staff gate (`middleware/staff-mfa.ts`) read this one value.
66
+ */
67
+ export const STAFF_MFA_PROOF_SECONDS = 12 * 60 * 60;
68
+ /**
69
+ * How recent a proof must be for a sensitive MFA action (5 min): disabling the
70
+ * factor, new recovery codes, an email change and minting an operator token.
71
+ * The dashboard (`lib/mfa.ts`) and the API operator-token route read this value.
72
+ */
73
+ export const MFA_MANAGEMENT_SECONDS = 5 * 60;
63
74
  //# sourceMappingURL=limits.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD;;;;;;GAMG;AAEH;;8BAE8B;AAC9B,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD;;;;;iEAKiE;AACjE,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD;;;;qDAIqD;AACrD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAExD;;4BAE4B;AAC5B,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAElE;yEACyE;AACzE,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC;AAEnD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC"}
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEzD;;;;;;GAMG;AAEH;;8BAE8B;AAC9B,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD;;;;;iEAKiE;AACjE,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhD;;;;qDAIqD;AACrD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAExD;;4BAE4B;AAC5B,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAElE;yEACyE;AACzE,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAAC,CAAC;AAEnD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAE5C;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,CAAC"}
@@ -4,7 +4,7 @@ export const OAUTH_SCOPE_LABELS = {
4
4
  "mcp:account": "View your account",
5
5
  mcp: "Use the hosted Percher MCP tools",
6
6
  };
7
- const DATA_ACCESS_SUFFIX = "records in your apps' databases, including data your app's users entered. Every record the assistant reads is sent to it and may be processed by its provider under the provider's terms. Revoke in Settings → Connections; copies already sent are not recalled.";
7
+ const DATA_ACCESS_SUFFIX = "records in your apps' databases, including data your app's users entered. Every record the assistant reads is sent to it and may be processed by its provider under the provider's terms. Revoke in Account → Connections; copies already sent are not recalled.";
8
8
  /**
9
9
  * A grant's database-tool access, for the Connections editor and the
10
10
  * security email. Not a scope: data access is a grant attribute, so these
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-scopes.js","sourceRoot":"","sources":["../src/oauth-scopes.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,kBAAkB,GAAqC;IAClE,UAAU,EAAE,yDAAyD;IACrE,eAAe,EAAE,iCAAiC;IAClD,aAAa,EAAE,mBAAmB;IAClC,GAAG,EAAE,kCAAkC;CACxC,CAAC;AAEF,MAAM,kBAAkB,GACtB,mQAAmQ,CAAC;AAEtQ;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA6C;IAC/E,SAAS,EAAE,mCAAmC,kBAAkB,EAAE;IAClE,IAAI,EAAE,QAAQ,kBAAkB,EAAE;CACnC,CAAC;AAEF,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,kBAAkB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;AAC5C,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,KAAK;SACT,KAAK,CAAC,KAAK,CAAC;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"oauth-scopes.js","sourceRoot":"","sources":["../src/oauth-scopes.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,kBAAkB,GAAqC;IAClE,UAAU,EAAE,yDAAyD;IACrE,eAAe,EAAE,iCAAiC;IAClD,aAAa,EAAE,mBAAmB;IAClC,GAAG,EAAE,kCAAkC;CACxC,CAAC;AAEF,MAAM,kBAAkB,GACtB,kQAAkQ,CAAC;AAErQ;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA6C;IAC/E,SAAS,EAAE,mCAAmC,kBAAkB,EAAE;IAClE,IAAI,EAAE,QAAQ,kBAAkB,EAAE;CACnC,CAAC;AAEF,gFAAgF;AAChF,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,kBAAkB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;AAC5C,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,gBAAgB,CAAC,KAAa;IAC5C,OAAO,KAAK;SACT,KAAK,CAAC,KAAK,CAAC;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC"}
@@ -6,7 +6,7 @@
6
6
  * without depending on each other.
7
7
  */
8
8
  /** Default PocketBase sidecar image when PERCHER_POCKETBASE_IMAGE is unset. */
9
- export declare const DEFAULT_POCKETBASE_IMAGE = "percher/pocketbase:0.40.3-hardened.1";
9
+ export declare const DEFAULT_POCKETBASE_IMAGE = "percher/pocketbase:0.40.5-hardened.1";
10
10
  /** Default app domain suffix when PERCHER_DOMAIN_SUFFIX is unset. */
11
11
  export declare const DEFAULT_DOMAIN_SUFFIX = "percher.run";
12
12
  /** Default hosted-MCP HTTP port when PERCHER_MCP_HTTP_PORT is unset. */
package/dist/platform.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * without depending on each other.
7
7
  */
8
8
  /** Default PocketBase sidecar image when PERCHER_POCKETBASE_IMAGE is unset. */
9
- export const DEFAULT_POCKETBASE_IMAGE = "percher/pocketbase:0.40.3-hardened.1";
9
+ export const DEFAULT_POCKETBASE_IMAGE = "percher/pocketbase:0.40.5-hardened.1";
10
10
  /** Default app domain suffix when PERCHER_DOMAIN_SUFFIX is unset. */
11
11
  export const DEFAULT_DOMAIN_SUFFIX = "percher.run";
12
12
  /** Default hosted-MCP HTTP port when PERCHER_MCP_HTTP_PORT is unset. */
package/dist/switches.js CHANGED
@@ -82,7 +82,7 @@ export const SWITCHES = [
82
82
  bool("PERCHER_CANARY_EDGE_KEEPS_LIVE", ["api"], "keep a deploy live when the canary failure was Percher's own edge", ONE, "enabled", ["0"]),
83
83
  bool("PERCHER_DRAIN_AT_SETTLEMENT", ["api"], "drain the predecessor at canary settlement instead of on a timer", ONE, "enabled", ["0"]),
84
84
  // Security scanning
85
- bool("SECURITY_BLOCK_DEPLOY", ["api"], "block the swap on red scan findings instead of advising", TRUE),
85
+ bool("SECURITY_BLOCK_DEPLOY", ["api"], "require fresh image verification and block Critical or CISA KEV findings", TRUE),
86
86
  bool("SECURITY_AUTO_HOLD", ["api"], "runtime re-scan places red apps on security hold automatically", TRUE),
87
87
  {
88
88
  kind: "enum",
@@ -1 +1 @@
1
- {"version":3,"file":"switches.js","sourceRoot":"","sources":["../src/switches.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"switches.js","sourceRoot":"","sources":["../src/switches.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAsCH,MAAM,GAAG,GAAG,CAAC,GAAG,CAAU,CAAC;AAC3B,MAAM,IAAI,GAAG,CAAC,MAAM,CAAU,CAAC;AAC/B,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,OAAO,CAAU,CAAC;AAE9C,0EAA0E;AAC1E,6EAA6E;AAC7E,8EAA8E;AAC9E,mCAAmC;AACnC,MAAM,IAAI,GAAG,CACX,IAAY,EACZ,OAAgC,EAChC,OAAe,EACf,OAA0B,EAC1B,GAAG,GAA2B,UAAU,EACxC,QAAQ,GAAsB,aAAa,EAC5B,EAAE,CAAC,CAAC;IACnB,IAAI,EAAE,SAAS;IACf,IAAI;IACJ,OAAO;IACP,OAAO;IACP,OAAO;IACP,QAAQ;IACR,OAAO,EAAE,GAAG;CACb,CAAC,CAAC;AAEH,iFAAiF;AACjF,MAAM,CAAC,MAAM,QAAQ,GAA0B;IAC7C,iBAAiB;IACjB,IAAI,CACF,6BAA6B,EAC7B,CAAC,KAAK,CAAC,EACP,8GAA8G,EAC9G,GAAG,EACH,SAAS,EACT,CAAC,GAAG,CAAC,CACN;IACD,IAAI,CACF,+BAA+B,EAC/B,CAAC,KAAK,CAAC,EACP,4GAA4G,EAC5G,GAAG,EACH,SAAS,EACT,CAAC,GAAG,CAAC,CACN;IACD,IAAI,CACF,0BAA0B,EAC1B,CAAC,KAAK,CAAC,EACP,2DAA2D,EAC3D,GAAG,CACJ;IACD,IAAI,CACF,+BAA+B,EAC/B,CAAC,QAAQ,CAAC,EACV,mHAAmH,EACnH,GAAG,CACJ;IAED,gCAAgC;IAChC,IAAI,CACF,0BAA0B,EAC1B,CAAC,KAAK,EAAE,QAAQ,CAAC,EACjB,+FAA+F,EAC/F,IAAI,CACL;IACD,IAAI,CACF,iCAAiC,EACjC,CAAC,KAAK,CAAC,EACP,uEAAuE,EACvE,GAAG,CACJ;IACD,IAAI,CACF,0BAA0B,EAC1B,CAAC,KAAK,CAAC,EACP,sFAAsF,EACtF,GAAG,CACJ;IACD,IAAI,CACF,mCAAmC,EACnC,CAAC,KAAK,CAAC,EACP,qFAAqF,EACrF,GAAG,CACJ;IACD,IAAI,CAAC,sBAAsB,EAAE,CAAC,KAAK,CAAC,EAAE,kDAAkD,EAAE,GAAG,CAAC;IAC9F,IAAI,CACF,sBAAsB,EACtB,CAAC,KAAK,CAAC,EACP,kEAAkE,EAClE,GAAG,CACJ;IAED,qBAAqB;IACrB,IAAI,CACF,4BAA4B,EAC5B,CAAC,KAAK,CAAC,EACP,mFAAmF,EACnF,GAAG,CACJ;IACD;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,mBAAmB;QACzB,OAAO,EAAE,CAAC,KAAK,CAAC;QAChB,OAAO,EAAE,0EAA0E;QACnF,MAAM,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC;QAC3B,OAAO,EAAE,UAAU;KACpB;IACD,IAAI,CACF,4BAA4B,EAC5B,CAAC,KAAK,CAAC,EACP,qEAAqE,EACrE,IAAI,CACL;IACD,IAAI,CACF,kCAAkC,EAClC,CAAC,KAAK,CAAC,EACP,kEAAkE,EAClE,IAAI,CACL;IAED,+BAA+B;IAC/B,IAAI,CACF,oCAAoC,EACpC,CAAC,KAAK,CAAC,EACP,qDAAqD,EACrD,GAAG,CACJ;IACD,IAAI,CAAC,sBAAsB,EAAE,CAAC,KAAK,CAAC,EAAE,gCAAgC,EAAE,GAAG,CAAC;IAC5E,IAAI,CAAC,yBAAyB,EAAE,CAAC,KAAK,CAAC,EAAE,mCAAmC,EAAE,GAAG,CAAC;IAClF,IAAI,CACF,mCAAmC,EACnC,CAAC,KAAK,CAAC,EACP,qDAAqD,EACrD,GAAG,CACJ;IACD,IAAI,CACF,4BAA4B,EAC5B,CAAC,KAAK,CAAC,EACP,mEAAmE,EACnE,GAAG,CACJ;IACD,IAAI,CACF,+BAA+B,EAC/B,CAAC,KAAK,CAAC,EACP,8DAA8D,EAC9D,GAAG,CACJ;IACD,IAAI,CACF,4BAA4B,EAC5B,CAAC,KAAK,EAAE,QAAQ,CAAC,EACjB,yDAAyD,EACzD,GAAG,CACJ;IACD,IAAI,CACF,+BAA+B,EAC/B,CAAC,KAAK,CAAC,EACP,qEAAqE,EACrE,GAAG,CACJ;IACD;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,gCAAgC;QACtC,OAAO,EAAE,CAAC,KAAK,CAAC;QAChB,OAAO,EAAE,6EAA6E;QACtF,MAAM,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;QAC/B,OAAO,EAAE,UAAU;KACpB;IAED,kBAAkB;IAClB,IAAI,CACF,8BAA8B,EAC9B,CAAC,KAAK,CAAC,EACP,kDAAkD,EAClD,IAAI,EACJ,SAAS,EACT,CAAC,OAAO,CAAC,CACV;IACD,IAAI,CACF,gCAAgC,EAChC,CAAC,KAAK,CAAC,EACP,mEAAmE,EACnE,GAAG,EACH,SAAS,EACT,CAAC,GAAG,CAAC,CACN;IACD,IAAI,CACF,6BAA6B,EAC7B,CAAC,KAAK,CAAC,EACP,kEAAkE,EAClE,GAAG,EACH,SAAS,EACT,CAAC,GAAG,CAAC,CACN;IAED,oBAAoB;IACpB,IAAI,CACF,uBAAuB,EACvB,CAAC,KAAK,CAAC,EACP,0EAA0E,EAC1E,IAAI,CACL;IACD,IAAI,CACF,oBAAoB,EACpB,CAAC,KAAK,CAAC,EACP,gEAAgE,EAChE,IAAI,CACL;IACD;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,2BAA2B;QACjC,OAAO,EAAE,CAAC,KAAK,CAAC;QAChB,OAAO,EAAE,wDAAwD;QACjE,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC;QACjC,OAAO,EAAE,KAAK;KACf;IACD,IAAI,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,EAAE,4CAA4C,EAAE,IAAI,CAAC;IAEnF,YAAY;IACZ;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,CAAC,WAAW,CAAC;QACtB,OAAO,EAAE,sDAAsD;QAC/D,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC;QACpC,OAAO,EAAE,QAAQ;QACjB,SAAS,EAAE,IAAI;KAChB;IACD,IAAI,CACF,yBAAyB,EACzB,CAAC,WAAW,CAAC,EACb,6DAA6D,EAC7D,GAAG,CACJ;IACD;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,CAAC,WAAW,CAAC;QACtB,OAAO,EAAE,uCAAuC;KACjD;IACD,IAAI,CAAC,0BAA0B,EAAE,CAAC,WAAW,CAAC,EAAE,oCAAoC,EAAE,GAAG,CAAC;IAC1F,IAAI,CAAC,iCAAiC,EAAE,CAAC,WAAW,CAAC,EAAE,iCAAiC,EAAE,GAAG,CAAC;IAC9F,IAAI,CACF,gCAAgC,EAChC,CAAC,WAAW,CAAC,EACb,8EAA8E,EAC9E,GAAG,CACJ;IAED,mCAAmC;IACnC,IAAI,CAAC,2BAA2B,EAAE,CAAC,KAAK,CAAC,EAAE,+BAA+B,EAAE,GAAG,CAAC;IAChF;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,CAAC,KAAK,CAAC;QAChB,OAAO,EAAE,gFAAgF;KAC1F;IACD;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,sBAAsB;QAC5B,OAAO,EAAE,CAAC,KAAK,CAAC;QAChB,OAAO,EAAE,kEAAkE;KAC5E;IAED,4BAA4B;IAC5B,IAAI,CAAC,sBAAsB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,sBAAsB,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACnF,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,kDAAkD,EAAE,GAAG,CAAC;IAE7F,0BAA0B;IAC1B;QACE,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,yBAAyB;QAC/B,OAAO,EAAE,CAAC,KAAK,CAAC;QAChB,OAAO,EAAE,4CAA4C;QACrD,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;QAC5B,OAAO,EAAE,UAAU;KACpB;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAoC,IAAI,GAAG,CACpE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CACjC,CAAC;AAEF,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,IAAgB,EAAE,GAAuB;IACnE,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,OAAO,CAAC;IACpD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,SAAS;YACZ,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,UAAU,CAAC;YACnD,OAAO,SAAS,CAAC;QACnB,KAAK,MAAM,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAC9D,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7D,CAAC;QACD,KAAK,UAAU;YACb,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAID,SAAS,UAAU,CACjB,IAAY,EACZ,IAAO;IAEP,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,EAAE,IAAI,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,wBAAwB,IAAI,SAAS,CAAC,CAAC;IACvF,OAAO,IAAwC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,GAAQ;IAClD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC;AACpC,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,GAAQ;IAChD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,IAAI,GAAG,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC;IACnF,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AACzD,CAAC;AAYD;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAuC,EACvC,MAAqB;IAErB,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAAE,SAAS;QACvD,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QACvD,MAAM,QAAQ,GACZ,IAAI,CAAC,IAAI,KAAK,SAAS;YACrB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;YACrC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;gBACpB,CAAC,CAAC,IAAI,CAAC,MAAM;gBACb,CAAC,CAAC,EAAE,CAAC;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QACnE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAuC,EACvC,MAAoB;IAEpB,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,MAAM,IAAI,KAAK,CACb,OAAO;SACJ,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,YAAY,MAAM,wBAAwB,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,0CAA0C;QACnH,aAAa,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QACpE,6BAA6B,CAAC,CAAC,QAAQ,IAAI,CAC9C;SACA,IAAI,CAAC,IAAI,CAAC,CACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ export interface SignupQuotaConnection {
2
+ run(query: string, params?: (string | number | null)[]): void;
3
+ get<T>(query: string, params?: (string | number | null)[]): T | undefined;
4
+ }
5
+ export declare class VerifiedSignupLimitError extends Error {
6
+ readonly code = "DAILY_CAP";
7
+ constructor();
8
+ }
9
+ /** Distinct namespace: historical pending-account totals remain unchanged. */
10
+ export declare function verifiedSignupQuota(db: SignupQuotaConnection, now?: Date): {
11
+ day: string;
12
+ count: number;
13
+ limit: number | null;
14
+ remaining: number | null;
15
+ resetAt: number;
16
+ };
17
+ /** Caller holds an immediate transaction covering this charge and verification. */
18
+ export declare function chargeVerifiedSignup(db: SignupQuotaConnection, now?: Date): void;
19
+ /** One-time upgrade repair. Caller holds the same writer transaction as admission.
20
+ * Snapshot pre-existing identity-bound proof before any new verification write.
21
+ * Absent dashboard schema is not a completed cutover. Invalid schema must fail.
22
+ */
23
+ export declare function initializeVerifiedSignupCutover(db: SignupQuotaConnection, now: Date): void;
24
+ //# sourceMappingURL=verified-signup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verified-signup.d.ts","sourceRoot":"","sources":["../src/verified-signup.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;IAC9D,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;CAC3E;AACD,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,IAAI,eAAe;IAC5B,cAIC;CACF;AACD,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,qBAAqB,EAAE,GAAG,OAAa;;;;;;EAyB9E;AACD,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,qBAAqB,EAAE,GAAG,OAAa,QAY/E;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,EAAE,EAAE,qBAAqB,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAwB1F"}
@@ -0,0 +1,58 @@
1
+ import { signupDayWindow } from "./signup-day.js";
2
+ export class VerifiedSignupLimitError extends Error {
3
+ code = "DAILY_CAP";
4
+ constructor() {
5
+ super("Today's registration quota is full. Try this link again tomorrow; request a new verification email if it has expired.");
6
+ }
7
+ }
8
+ /** Distinct namespace: historical pending-account totals remain unchanged. */
9
+ export function verifiedSignupQuota(db, now = new Date()) {
10
+ const { day, startMs, endMs } = signupDayWindow(now);
11
+ const key = `verified:${day}`;
12
+ const stored = db.get("SELECT count FROM signup_daily_registrations WHERE day = ?", [key]);
13
+ const count = stored?.count ??
14
+ db.get("SELECT COUNT(*) AS count FROM users WHERE email_verified_at >= ? AND email_verified_at < ?", [Math.floor(startMs / 1000), Math.floor(endMs / 1000)])?.count ??
15
+ 0;
16
+ const raw = db.get("SELECT value FROM platform_flags WHERE key = 'signup_daily_cap'")?.value;
17
+ const limit = raw && /^\d{1,9}$/.test(raw) && Number(raw) > 0 ? Number(raw) : null;
18
+ return {
19
+ day,
20
+ count,
21
+ limit,
22
+ remaining: limit === null ? null : Math.max(0, limit - count),
23
+ resetAt: endMs,
24
+ };
25
+ }
26
+ /** Caller holds an immediate transaction covering this charge and verification. */
27
+ export function chargeVerifiedSignup(db, now = new Date()) {
28
+ const quota = verifiedSignupQuota(db, now);
29
+ const key = `verified:${quota.day}`;
30
+ db.run("INSERT INTO signup_daily_registrations(day,count) VALUES(?,?) ON CONFLICT(day) DO NOTHING", [key, quota.count]);
31
+ const charged = db.get("UPDATE signup_daily_registrations SET count=count+1 WHERE day=? AND (? IS NULL OR count < ?) RETURNING day", [key, quota.limit, quota.limit]);
32
+ if (!charged)
33
+ throw new VerifiedSignupLimitError();
34
+ }
35
+ /** One-time upgrade repair. Caller holds the same writer transaction as admission.
36
+ * Snapshot pre-existing identity-bound proof before any new verification write.
37
+ * Absent dashboard schema is not a completed cutover. Invalid schema must fail.
38
+ */
39
+ export function initializeVerifiedSignupCutover(db, now) {
40
+ const marker = "verified_signup_cutover_v1";
41
+ if (db.get("SELECT value FROM platform_flags WHERE key=?", [marker]))
42
+ return;
43
+ if (!db.get("SELECT name FROM sqlite_master WHERE type='table' AND name='auth_user'"))
44
+ return;
45
+ db.get("SELECT id,email,percher_user_id,email_verified FROM auth_user LIMIT 0");
46
+ const quota = verifiedSignupQuota(db, now);
47
+ const key = `verified:${quota.day}`;
48
+ db.run("INSERT INTO signup_daily_registrations(day,count) VALUES(?,?) ON CONFLICT(day) DO NOTHING", [key, quota.count]);
49
+ const predicate = "email_verified_at IS NULL AND status!='deleting' AND EXISTS (SELECT 1 FROM auth_user a WHERE a.percher_user_id=users.id AND lower(a.email)=lower(users.email) AND a.email_verified=1)";
50
+ const repaired = db.get(`SELECT COUNT(*) AS count FROM users WHERE ${predicate}`)?.count ?? 0;
51
+ db.run(`UPDATE users SET email_verified_at=?,status=CASE WHEN status='pending' AND accepted_terms_at IS NOT NULL THEN 'active' ELSE status END WHERE ${predicate}`, [Math.floor(now.getTime() / 1000)]);
52
+ db.run("INSERT INTO platform_flags(key,value,updated_at) VALUES(?,?,?)", [
53
+ marker,
54
+ JSON.stringify({ version: 1, at: now.getTime(), repaired }),
55
+ Math.floor(now.getTime() / 1000),
56
+ ]);
57
+ }
58
+ //# sourceMappingURL=verified-signup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verified-signup.js","sourceRoot":"","sources":["../src/verified-signup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAM/C,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACxC,IAAI,GAAG,WAAW,CAAC;IAC5B;QACE,KAAK,CACH,uHAAuH,CACxH,CAAC;IACJ,CAAC;CACF;AACD,8EAA8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,EAAyB,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE;IAC7E,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,YAAY,GAAG,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,CACnB,4DAA4D,EAC5D,CAAC,GAAG,CAAC,CACN,CAAC;IACF,MAAM,KAAK,GACT,MAAM,EAAE,KAAK;QACb,EAAE,CAAC,GAAG,CACJ,4FAA4F,EAC5F,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CACvD,EAAE,KAAK;QACR,CAAC,CAAC;IACJ,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,CAChB,iEAAiE,CAClE,EAAE,KAAK,CAAC;IACT,MAAM,KAAK,GAAG,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,OAAO;QACL,GAAG;QACH,KAAK;QACL,KAAK;QACL,SAAS,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;QAC7D,OAAO,EAAE,KAAK;KACf,CAAC;AACJ,CAAC;AACD,mFAAmF;AACnF,MAAM,UAAU,oBAAoB,CAAC,EAAyB,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE;IAC9E,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,GAAG,EAAE,CAAC;IACpC,EAAE,CAAC,GAAG,CACJ,2FAA2F,EAC3F,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CACnB,CAAC;IACF,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,CACpB,4GAA4G,EAC5G,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAChC,CAAC;IACF,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,wBAAwB,EAAE,CAAC;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,+BAA+B,CAAC,EAAyB,EAAE,GAAS;IAClF,MAAM,MAAM,GAAG,4BAA4B,CAAC;IAC5C,IAAI,EAAE,CAAC,GAAG,CAAC,8CAA8C,EAAE,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO;IAC7E,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,wEAAwE,CAAC;QAAE,OAAO;IAC9F,EAAE,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,GAAG,EAAE,CAAC;IACpC,EAAE,CAAC,GAAG,CACJ,2FAA2F,EAC3F,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CACnB,CAAC;IACF,MAAM,SAAS,GACb,uLAAuL,CAAC;IAC1L,MAAM,QAAQ,GACZ,EAAE,CAAC,GAAG,CAAoB,6CAA6C,SAAS,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IAClG,EAAE,CAAC,GAAG,CACJ,gJAAgJ,SAAS,EAAE,EAC3J,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,CACnC,CAAC;IACF,EAAE,CAAC,GAAG,CAAC,gEAAgE,EAAE;QACvE,MAAM;QACN,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC;QAC3D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;KACjC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percher/shared",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Shared constants and contracts (timeouts, etc.) used across the Percher CLI, API, MCP, and worker. Internal — values change in lockstep across packages.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",