Files
PaperClipAI/packages/shared/src/validators/claude-setup-token-session.ts
T
3abe9e2134 build(deps): bump zod from 3.25.76 to 4.4.3 (#11719)
Bumps [zod](https://github.com/colinhacks/zod) from 3.25.76 to 4.4.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/colinhacks/zod/releases">zod's
releases</a>.</em></p>
<blockquote>
<h2>v4.4.3</h2>
<h2>Commits:</h2>
<ul>
<li>4c2fa95ce3f3390fbc522324e406b4e9e89b88f9 docs: use Zernio primary
wordmark for gold sponsor logo</li>
<li>2aeec83eb135e3a83756e973ef44845fc5a455d2 docs: prune lapsed gold
sponsors and rebalance logo sizing</li>
<li>7391be88ac1ee5cd02057f5ccc012a1f5df4efd0 docs: prune lapsed
silver/bronze sponsors and add active ones</li>
<li>2c703322a21b4e2b12f33f49ea8430c451a68b4f docs: normalize bronze
sponsor logos to github avatar pattern</li>
<li>9195250cab0e7950efe39c3926d6c203b4b0a170 docs: remove Mintlify from
bronze sponsors (churned)</li>
<li>b8dffe9e62f17e6571e6249d05cc5102b54d94e4 docs: remove Numeric and
Speakeasy (2+ missed monthly cycles)</li>
<li>1cab69383fcdeae2a366d5e2a2fc4d8fc765d168 fix(v4): restore catch
handling for absent object keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5937">#5937</a>)
(<a
href="https://redirect.github.com/colinhacks/zod/issues/5939">#5939</a>)</li>
<li>c2be4f819064eed62c7c350a2d399b5faecd15f8 fix(v4): generalize
optin/fallback to transform; restore preprocess on absent keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5941">#5941</a>)</li>
<li>f3c9ec03ba7a28ae72d25cc295f38674bee0f559 4.4.3</li>
<li>1fb56a5c18c27102dbc92260a4007c7732a0ccca docs: document release
procedure in AGENTS.md</li>
</ul>
<h2>v4.4.2</h2>
<h2>Commits:</h2>
<ul>
<li>0c62df0ea19fd05abdf90473e9eef7eea530fab2 Clean up docs navigation
and stale labels (<a
href="https://redirect.github.com/colinhacks/zod/issues/5901">#5901</a>)</li>
<li>20cc794895cc8604fe0c87d83a5d1c3f89fad0ac chore: add security policy
and refresh tooling deps</li>
<li>6fbe07b0177efdd1bf1c0b05160e70d7a0702337 fix(docs): heading anchor
links now include the hash so it doesnt scoll all the way up, follows
navbar logic (<a
href="https://redirect.github.com/colinhacks/zod/issues/5791">#5791</a>)</li>
<li>4bbed1b1c73eca4ce9e59b1189ed236aa6c8b5bd Tighten discriminated union
option typing</li>
<li>bbac3e567e7fccfaaf7cdc97f1ce30c295e2c908 Update PR guidance for
agents</li>
<li>cf0dc942a32805c292fff59ade20a7ace980735a Merge remote-tracking
branch 'origin/main' into fix-discriminated-union-key-constraint</li>
<li>292c894a5fd2aa42e527900b83d8d7a3009a709c docs: add Zernio gold
sponsor</li>
<li>1fc9f311c28dcf80d0bb5a36b177086cbc3d8eca docs: document codec
inversion</li>
<li>1373c85da9aeff704a9762d27bc58699618aefb7 docs: remove AI disclosure
guidance</li>
<li>e20d02b473c08e3a4e557bc610b1b5fac079b649 chore: ignore triage
notes</li>
<li>e58ea4d91b1dfe8194b73508203213cbc7e9c936 docs: test Zod Mini tab
code heights</li>
<li>905761a5d127e8d5dd2ebb3bc88c75cb0b8149ff docs: document preprocess
input type narrowing</li>
<li>bf64bac850d4dee2b7dde7e64909d5d796d32043 chore: tighten test
guidance in AGENTS.md</li>
<li>8ec4e73f4c4693b6361ad591be40fb41eb8a9f95 chore: update play.ts
scratch</li>
<li>02c2baf7d0d615872fa4528a8020603b71211702 Make z.preprocess defer
optionality to inner schema (<a
href="https://redirect.github.com/colinhacks/zod/issues/5929">#5929</a>)</li>
<li>88015df8e25c44fb5385eb3ef28935119cd5edea fix(docs): drop deprecated
<code>baseUrl</code> from tsconfig</li>
<li>c59d4474e3b4cad1b323462186cf607178ce8267 4.4.2</li>
</ul>
<h2>v4.4.1</h2>
<h2>Commits:</h2>
<ul>
<li>481f7be4238c83ed58183f921b2646f340a91c6a ci: gate release publishing
on full test workflow</li>
<li>95ccab423aec720b2523c3a64cdc7e3204537cc7 test(v3): restore optional
undefined expectations</li>
<li>cede2c63739a5823d6aa5093d291e9a111da943d fix(v4): reject tuple holes
before required defaults (<a
href="https://redirect.github.com/colinhacks/zod/issues/5900">#5900</a>)</li>
<li>edd0bf0f5ada4a8dc581c259407d7bbad0a71ea7 release: 4.4.1</li>
<li>180d83d1dbe6a59260710cc8637a3dea2281ee56 docs: remove Jazz featured
sponsor</li>
</ul>
<h2>v4.4.0</h2>
<h2>4.4.0</h2>
<p>This is a minor release with a wide set of correctness and soundness
fixes. Some fixes intentionally make Zod stricter, so code that depended
on previously accepted invalid or ambiguous inputs may need small
updates.</p>
<h2>Potentially breaking bug fixes</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/colinhacks/zod/commit/1fb56a5c18c27102dbc92260a4007c7732a0ccca"><code>1fb56a5</code></a>
docs: document release procedure in AGENTS.md</li>
<li><a
href="https://github.com/colinhacks/zod/commit/f3c9ec03ba7a28ae72d25cc295f38674bee0f559"><code>f3c9ec0</code></a>
4.4.3</li>
<li><a
href="https://github.com/colinhacks/zod/commit/c2be4f819064eed62c7c350a2d399b5faecd15f8"><code>c2be4f8</code></a>
fix(v4): generalize optin/fallback to transform; restore preprocess on
absent...</li>
<li><a
href="https://github.com/colinhacks/zod/commit/1cab69383fcdeae2a366d5e2a2fc4d8fc765d168"><code>1cab693</code></a>
fix(v4): restore catch handling for absent object keys (<a
href="https://redirect.github.com/colinhacks/zod/issues/5937">#5937</a>)
(<a
href="https://redirect.github.com/colinhacks/zod/issues/5939">#5939</a>)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/b8dffe9e62f17e6571e6249d05cc5102b54d94e4"><code>b8dffe9</code></a>
docs: remove Numeric and Speakeasy (2+ missed monthly cycles)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/9195250cab0e7950efe39c3926d6c203b4b0a170"><code>9195250</code></a>
docs: remove Mintlify from bronze sponsors (churned)</li>
<li><a
href="https://github.com/colinhacks/zod/commit/2c703322a21b4e2b12f33f49ea8430c451a68b4f"><code>2c70332</code></a>
docs: normalize bronze sponsor logos to github avatar pattern</li>
<li><a
href="https://github.com/colinhacks/zod/commit/7391be88ac1ee5cd02057f5ccc012a1f5df4efd0"><code>7391be8</code></a>
docs: prune lapsed silver/bronze sponsors and add active ones</li>
<li><a
href="https://github.com/colinhacks/zod/commit/2aeec83eb135e3a83756e973ef44845fc5a455d2"><code>2aeec83</code></a>
docs: prune lapsed gold sponsors and rebalance logo sizing</li>
<li><a
href="https://github.com/colinhacks/zod/commit/4c2fa95ce3f3390fbc522324e406b4e9e89b88f9"><code>4c2fa95</code></a>
docs: use Zernio primary wordmark for gold sponsor logo</li>
<li>Additional commits viewable in <a
href="https://github.com/colinhacks/zod/compare/v3.25.76...v4.4.3">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for zod since your current version.</p>
</details>
<br />

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Priya Raman <priya@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-21 00:04:14 -07:00

171 lines
8.2 KiB
TypeScript

import { z } from "zod";
import { AGENT_ADAPTER_TYPES } from "../constants.js";
import { ADAPTER_AUTH_PANEL_MODES, SETUP_TOKEN_TRANSPORT_ADVISORY_CODE } from "../types/agent.js";
import {
adapterAuthSessionFailureSchema,
adapterAuthSessionStatusSchema,
} from "./adapter-auth-session.js";
const isoDateTime = z.union([z.date(), z.string().datetime()]);
// The transport advisory schema. A guarded confidential response carries it when
// the login rides a non-confidential transport. The client shows a disclaimer.
export const setupTokenTransportAdvisorySchema = z.object({
code: z.literal(SETUP_TOKEN_TRANSPORT_ADVISORY_CODE),
}).strict();
export type SetupTokenTransportAdvisory = z.infer<typeof setupTokenTransportAdvisorySchema>;
// The confirmed-overwrite capture for a replacement login. The client reads the
// stored value metadata from the status route and passes it back when it starts
// a replacement login. The server maps it to the owner-bound compare-and-set: it
// rotates the value only when the captured version still matches. The server
// still derives the owner and the definition; this body carries no owner. A
// missing capture starts a first-write login instead.
export const claudeSetupTokenOverwriteSchema = z.object({
expectedSecretId: z.string().guid(),
expectedLatestVersion: z.number().int().min(1),
}).strict();
export type ClaudeSetupTokenOverwrite =
z.infer<typeof claudeSetupTokenOverwriteSchema>;
// The start request for a company-and-environment Claude login session. The
// company and the owner user come from the authenticated caller, not from this
// body. The body names the adapter and the environment of the login. It reuses
// the adapter login-session request fields; every field has the same meaning.
//
// The optional `overwrite` capture turns the login into a confirmed replacement.
// The client sends it only after a stored token fails the agent test. The server
// rotates the stored value under the captured version, so a concurrent change
// fails closed with a stale conflict.
//
// `.strict()` rejects an extra field, so an agent id never validates. The scope
// carries no agent id: a hire flow with no agent still starts one session. The
// runtime does not support a caller-supplied session length, so the schema
// exposes no `ttlSeconds` field; a legacy `ttlSeconds` fails the strict parse.
export const startClaudeSetupTokenSessionRequestSchema = z.object({
environmentId: z.string().guid(),
adapterType: z.enum(AGENT_ADAPTER_TYPES),
overwrite: claudeSetupTokenOverwriteSchema.optional(),
}).strict();
export type StartClaudeSetupTokenSessionRequest =
z.infer<typeof startClaudeSetupTokenSessionRequestSchema>;
// The panel-mode schema. It accepts only the two known panel modes.
export const adapterAuthPanelModeSchema = z.enum(ADAPTER_AUTH_PANEL_MODES);
export type AdapterAuthPanelMode = z.infer<typeof adapterAuthPanelModeSchema>;
// The session id is an opaque, cryptographically random string, not a UUID. So
// the schema accepts a bounded opaque string, not a UUID.
const sessionIdSchema = z.string().min(1).max(256);
// The public Claude login-session response schema. `.strict()` rejects an extra
// field, so a prompt, a token, an account identifier, or a provider lease
// identifier never validates.
export const claudeSetupTokenSessionResponseSchema = z.object({
sessionId: sessionIdSchema,
environmentId: z.string().guid(),
status: adapterAuthSessionStatusSchema,
expiresAt: isoDateTime.nullable(),
failure: adapterAuthSessionFailureSchema.nullable(),
transportAdvisory: setupTokenTransportAdvisorySchema.nullable().optional(),
}).strict();
export type ClaudeSetupTokenSessionResponse =
z.infer<typeof claudeSetupTokenSessionResponseSchema>;
// The one-time Claude login prompt schema. It carries the authorization URL the
// user opens. It carries no server-displayed code.
export const claudeSetupTokenSessionPromptSchema = z.object({
authorizationUrl: z.string().min(1),
transportAdvisory: setupTokenTransportAdvisorySchema.nullable().optional(),
}).strict();
export type ClaudeSetupTokenSessionPrompt =
z.infer<typeof claudeSetupTokenSessionPromptSchema>;
// The owner read schema. It adds the panel mode and the one-time prompt to the
// public response.
export const claudeSetupTokenSessionOwnerResponseSchema =
claudeSetupTokenSessionResponseSchema.extend({
panelMode: adapterAuthPanelModeSchema,
prompt: claudeSetupTokenSessionPromptSchema.nullable(),
}).strict();
export type ClaudeSetupTokenSessionOwnerResponse =
z.infer<typeof claudeSetupTokenSessionOwnerResponseSchema>;
// The bounded maximum length of a browser code. The provider code is short. The
// server rejects an oversized code before it reaches the live login process.
export const BROWSER_CODE_MAX_LENGTH = 512;
// The conservative printable grammar for the submitted browser code. It matches
// one character outside the visible ASCII range (0x21-0x7E). The validator
// rejects a code that contains a match, so it rejects a space, a carriage
// return, a line feed, a NUL, and every other control byte. A later
// characterization test narrows this set to the exact provider format.
export const BROWSER_CODE_DISALLOWED_CHAR = /[^\x21-\x7E]/;
/**
* Returns true when the browser code obeys the grammar. The code has one or more
* characters, no character outside the visible ASCII range, and a length at or
* below the bounded maximum.
*/
export function isValidBrowserCode(code: string): boolean {
return (
code.length >= 1 &&
code.length <= BROWSER_CODE_MAX_LENGTH &&
!BROWSER_CODE_DISALLOWED_CHAR.test(code)
);
}
// The printable-ASCII allowlist pattern for the published contract. It is an
// anchored allowlist of the visible ASCII range (0x21-0x7E). The converter reads
// this `.regex()` from the inner `ZodString` and emits it as the OpenAPI
// `pattern`. It is NOT the authoritative guard: JavaScript `$` matches before a
// final line feed, so this pattern accepts a trailing newline. The `.refine()`
// below is the authoritative guard that rejects a trailing newline.
export const BROWSER_CODE_PATTERN = /^[\x21-\x7E]+$/u;
// The browser-code grammar schema. It rejects an empty code, an oversized code,
// and a code with a control byte or any other non-printable character. The
// `.regex()` runs before the `.refine()` so the converter serializes its
// `pattern`; the `.refine()` stays the authoritative guard.
export const browserCodeSchema = z
.string()
.min(1, "A browser code is required.")
.max(BROWSER_CODE_MAX_LENGTH, "The browser code is too long.")
.regex(BROWSER_CODE_PATTERN, "The browser code has an invalid character.")
.refine((code) => !BROWSER_CODE_DISALLOWED_CHAR.test(code), {
message: "The browser code has an invalid character.",
});
export type BrowserCode = z.infer<typeof browserCodeSchema>;
// The submit-browser-code request schema. `.strict()` rejects an extra field.
export const submitBrowserCodeRequestSchema = z.object({
browserCode: browserCodeSchema,
}).strict();
export type SubmitBrowserCodeRequest =
z.infer<typeof submitBrowserCodeRequestSchema>;
// The stored-session claim schema. The `storedSessionId` is the opaque durable
// session id. It is a non-secret claim; it carries no token.
export const storedSessionIdSchema = z.string().min(1).max(256);
// The completion response schema. It carries the non-secret `storedSessionId`
// claim and no token. `.strict()` rejects an extra field, so a token never
// validates.
export const claudeSetupTokenCompletionResponseSchema = z.object({
storedSessionId: storedSessionIdSchema,
}).strict();
export type ClaudeSetupTokenCompletionResponse =
z.infer<typeof claudeSetupTokenCompletionResponseSchema>;
// The stored Claude OAuth token status response schema. It carries only the
// secret id and the latest version of the owner value; it carries no token.
// `.strict()` rejects an extra field, so a token never validates. The status
// route returns a fixed 404 for a missing or a foreign value, so a 200 body
// always describes a present owner value.
export const claudeOAuthTokenStatusResponseSchema = z.object({
secretId: z.string().guid(),
latestVersion: z.number().int().min(1),
}).strict();
export type ClaudeOAuthTokenStatusResponse =
z.infer<typeof claudeOAuthTokenStatusResponseSchema>;