theokit 0.11.7 → 0.12.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.
- package/LICENSE +201 -0
- package/dist/actions-virtual-module-SQDY3V5X.js +0 -0
- package/dist/add-W6FNTAFS.js +0 -0
- package/dist/app-typed-client-QG7BVZYW.js +0 -0
- package/dist/aws-lambda-7GSCNLPY.js +0 -0
- package/dist/broadcast-LUMOJIJT.js +0 -0
- package/dist/build-QFRLSEZ4.js +0 -0
- package/dist/build-request-body-preview-QMWD2IXK.js +0 -0
- package/dist/bun-KP2KES6S.js +0 -0
- package/dist/check-PD2FTKMM.js +0 -0
- package/dist/chunk-3LVRAGAZ.js +0 -0
- package/dist/chunk-43D6XNDR.js +0 -0
- package/dist/chunk-45C3WUQ7.js +0 -0
- package/dist/chunk-5ODOE6EF.js +0 -0
- package/dist/chunk-6FYD34NX.js +0 -0
- package/dist/chunk-7YZHAQU7.js +0 -0
- package/dist/{chunk-GEEMNDPH.js → chunk-AD74EAK3.js} +30 -1
- package/dist/chunk-AD74EAK3.js.map +1 -0
- package/dist/chunk-FOZIR3TG.js +0 -0
- package/dist/chunk-GFMQJHXX.js +0 -0
- package/dist/chunk-HGZL5EOI.js +0 -0
- package/dist/chunk-HNBWZKIQ.js +0 -0
- package/dist/chunk-IEES3CHD.js +0 -0
- package/dist/chunk-JAIKGP3Q.js +0 -0
- package/dist/chunk-JQSFBJR5.js +0 -0
- package/dist/chunk-NAZ4E2GT.js +0 -0
- package/dist/chunk-PBEH6NXR.js +0 -0
- package/dist/chunk-YJAUJXZS.js +0 -0
- package/dist/cloudflare-C6E5SPAE.js +0 -0
- package/dist/configure-agent-registry-ZOBVU3MV.js +0 -0
- package/dist/db-3UNAMSFK.js +0 -0
- package/dist/deno-deploy-RFZN56X4.js +0 -0
- package/dist/dev-GBXOTXUP.js +0 -0
- package/dist/dev-emit-FEFEDLZF.js +0 -0
- package/dist/dispatcher-EJHL6JMJ.js +0 -0
- package/dist/docker-LZZB4D5E.js +0 -0
- package/dist/generate-OMKHQ7OM.js +0 -0
- package/dist/info-OUEUZOT7.js +0 -0
- package/dist/netlify-PMLHVPN4.js +0 -0
- package/dist/node-BPJ3Z4DT.js +0 -0
- package/dist/openapi-VR6AFBLJ.js +0 -0
- package/dist/registry-Q2TZQLUH.js +0 -0
- package/dist/router-TLEAOFID.js +0 -0
- package/dist/routes-LRYOIIAI.js +0 -0
- package/dist/scan-7MJC6PYU.js +0 -0
- package/dist/schema-7CAY6IZR.js +0 -0
- package/dist/server/define/index.js +5 -3
- package/dist/server/index.js +4 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server-error-to-envelope-UUXDSLAZ.js +0 -0
- package/dist/server-routes-hmr-VZXOP5YT.js +0 -0
- package/dist/services-json-Y3XODNB5.js +0 -0
- package/dist/services-typed-client-32KMTTXR.js +0 -0
- package/dist/start-3ZHAXSJE.js +0 -0
- package/dist/static-55G3LX2I.js +0 -0
- package/dist/storage-manager-ZSQFLEYT.js +0 -0
- package/dist/theo-cloud-DQRP6S6M.js +0 -0
- package/dist/upgrade-readiness-ACGW44JC.js +0 -0
- package/dist/vercel-J6G7ZHYQ.js +0 -0
- package/dist/vite-plugin-WO72VLYR.js +0 -0
- package/package.json +12 -8
- package/dist/adapters/web-shim.d.ts +0 -67
- package/dist/adapters/ws-shim.d.ts +0 -55
- package/dist/agent-events-DosDXkSV.d.ts +0 -94
- package/dist/audit-log-BQWM5YLG.d.ts +0 -60
- package/dist/boot/index.d.ts +0 -39
- package/dist/chunk-GEEMNDPH.js.map +0 -1
- package/dist/client/index.d.ts +0 -362
- package/dist/csrf-BBrEZSBW.d.ts +0 -107
- package/dist/csrf-readiness-store-CjIoub3U.d.ts +0 -43
- package/dist/define-websocket-CdK94O-D.d.ts +0 -64
- package/dist/devtools/entry.d.ts +0 -5
- package/dist/error-envelope-BsNzzAV5.d.ts +0 -62
- package/dist/health-route-C0hk64_U.d.ts +0 -57
- package/dist/index-B40qUSrQ.d.ts +0 -575
- package/dist/index.d.ts +0 -361
- package/dist/job-backend-CgC8Xf33.d.ts +0 -68
- package/dist/match-CfbEFRG4.d.ts +0 -26
- package/dist/plugin-runner-BGBkzgi0.d.ts +0 -95
- package/dist/plugin-types-DNJGxr4Z.d.ts +0 -79
- package/dist/rate-limit-BdNDZ3vt.d.ts +0 -58
- package/dist/rate-limit-store-BEJnhWdw.d.ts +0 -72
- package/dist/react-query/index.d.ts +0 -33
- package/dist/schema-BpH6ivDY.d.ts +0 -74
- package/dist/server/agent/index.d.ts +0 -229
- package/dist/server/auth/index.d.ts +0 -419
- package/dist/server/cost/index.d.ts +0 -177
- package/dist/server/cron/index.d.ts +0 -208
- package/dist/server/define/index.d.ts +0 -310
- package/dist/server/http/index.d.ts +0 -11
- package/dist/server/index.d.ts +0 -847
- package/dist/server/jobs/index.d.ts +0 -348
- package/dist/server/observability/index.d.ts +0 -324
- package/dist/server/plugins/index.d.ts +0 -17
- package/dist/server/rate-limit/index.d.ts +0 -105
- package/dist/server/realtime/index.d.ts +0 -15
- package/dist/server/scan/index.d.ts +0 -106
- package/dist/server/security/index.d.ts +0 -193
- package/dist/server/storage/index.d.ts +0 -22
- package/dist/server/webhook/index.d.ts +0 -148
- package/dist/storage-manager-C4jsO0Tp.d.ts +0 -89
- package/dist/storage-types-DsDTCPbp.d.ts +0 -96
- package/dist/vite-plugin/index.d.ts +0 -115
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import { R as RateLimitStore } from '../../rate-limit-store-BEJnhWdw.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* T4.1 — Per-request CSP nonce generation.
|
|
6
|
-
*
|
|
7
|
-
* Returns a 22–24 character base64-encoded string carrying 16 bytes of
|
|
8
|
-
* cryptographic entropy. Used by the SSR pipeline to nonce the inline
|
|
9
|
-
* hydration data script so the default CSP can drop `'unsafe-inline'`
|
|
10
|
-
* from `script-src` in 0.3.0.
|
|
11
|
-
*
|
|
12
|
-
* Runtime portability: prefers Web Crypto (`globalThis.crypto`) because
|
|
13
|
-
* it is available on every target runtime (Node 19+, Bun, Deno, Vercel
|
|
14
|
-
* Edge, Cloudflare Workers). Falls back to `node:crypto` for older Node
|
|
15
|
-
* builds where `globalThis.crypto` is absent.
|
|
16
|
-
*
|
|
17
|
-
* NOT a security primitive in the cryptographic sense — the nonce is a
|
|
18
|
-
* one-shot, single-request value that defeats trivial XSS injection by
|
|
19
|
-
* making the attacker guess a 128-bit string per request. It is NOT
|
|
20
|
-
* suitable for signing or session tokens.
|
|
21
|
-
*/
|
|
22
|
-
declare function generateNonce(): string;
|
|
23
|
-
|
|
24
|
-
declare class AuthRequiredError extends Error {
|
|
25
|
-
code: "AUTH_REQUIRED";
|
|
26
|
-
status: number;
|
|
27
|
-
constructor(message?: string);
|
|
28
|
-
}
|
|
29
|
-
declare function requireAuth<T>(session: T | null | undefined): asserts session is T;
|
|
30
|
-
|
|
31
|
-
interface SessionConfig {
|
|
32
|
-
/**
|
|
33
|
-
* Session secret. Either a single string (legacy) or an array of strings
|
|
34
|
-
* where index 0 is the newest. The array form enables dual-key rotation
|
|
35
|
-
* (T3.1 / ADR D5): encrypt always uses `secrets[0]`, decrypt walks the
|
|
36
|
-
* array, transparent re-encrypt on legacy hits (T3.2).
|
|
37
|
-
*
|
|
38
|
-
* EC-1: array length capped at 5 — enforced via throw at construction.
|
|
39
|
-
*/
|
|
40
|
-
secret: string | string[];
|
|
41
|
-
cookieName?: string;
|
|
42
|
-
maxAge?: number;
|
|
43
|
-
}
|
|
44
|
-
interface SessionMeta {
|
|
45
|
-
/** Index of the secret that decrypted the session. 0 = newest; > 0 = legacy. */
|
|
46
|
-
secretIndex: number;
|
|
47
|
-
/** True when the decrypt used a legacy secret and the cookie should be re-encrypted. */
|
|
48
|
-
needsReencrypt: boolean;
|
|
49
|
-
}
|
|
50
|
-
interface SessionManager<TSession> {
|
|
51
|
-
getSession(req: IncomingMessage): Promise<TSession | null>;
|
|
52
|
-
/**
|
|
53
|
-
* T3.2 — Variant of `getSession` that surfaces decrypt metadata.
|
|
54
|
-
* Used by `api-middleware.ts` to wire transparent re-encrypt BEFORE
|
|
55
|
-
* the handler runs (so streaming SSR routes don't miss the Set-Cookie
|
|
56
|
-
* window — EC-4).
|
|
57
|
-
*/
|
|
58
|
-
getSessionWithMeta(req: IncomingMessage): Promise<{
|
|
59
|
-
data: TSession | null;
|
|
60
|
-
meta: SessionMeta;
|
|
61
|
-
}>;
|
|
62
|
-
createSession(res: ServerResponse, data: TSession): Promise<void>;
|
|
63
|
-
destroySession(res: ServerResponse): void;
|
|
64
|
-
/**
|
|
65
|
-
* T3.3 — OWASP A07:2021 session fixation mitigation. Re-encrypts the
|
|
66
|
-
* current session with a fresh IV and refreshed expiry. No-op when no
|
|
67
|
-
* session is present.
|
|
68
|
-
*/
|
|
69
|
-
rotateSession(req: IncomingMessage, res: ServerResponse): Promise<TSession | null>;
|
|
70
|
-
}
|
|
71
|
-
declare function createSessionManager<TSession>(config: SessionConfig): SessionManager<TSession>;
|
|
72
|
-
/**
|
|
73
|
-
* T5a.2 Phase D slice 3/3 — Web-Standards session manager.
|
|
74
|
-
*
|
|
75
|
-
* Mirror of `SessionManager<TSession>` for the Web `Request` + `Headers`
|
|
76
|
-
* shape. Same `SessionConfig`, same encryption (`encrypt`/`decrypt` from
|
|
77
|
-
* `./crypto.js`), same dual-key rotation logic (CR-002 constant-time
|
|
78
|
-
* decrypt fallback walk + transparent re-encrypt), same OWASP A07
|
|
79
|
-
* `rotateSession` invariant.
|
|
80
|
-
*
|
|
81
|
-
* **Signature differences vs `SessionManager`:**
|
|
82
|
-
* - Read methods take `Request` (instead of `IncomingMessage`).
|
|
83
|
-
* - Write methods take a `Headers` instance to mutate (instead of
|
|
84
|
-
* `ServerResponse`) — caller passes the headers they're building
|
|
85
|
-
* for their `Response` constructor.
|
|
86
|
-
*
|
|
87
|
-
* Uses `getCookieFromRequest` / `appendCookieToHeaders` /
|
|
88
|
-
* `appendDeleteCookieToHeaders` from Phase B slice 6/6.
|
|
89
|
-
*/
|
|
90
|
-
interface SessionManagerWeb<TSession> {
|
|
91
|
-
getSession(request: Request): Promise<TSession | null>;
|
|
92
|
-
getSessionWithMeta(request: Request): Promise<{
|
|
93
|
-
data: TSession | null;
|
|
94
|
-
meta: SessionMeta;
|
|
95
|
-
}>;
|
|
96
|
-
createSession(target: Headers, data: TSession): Promise<void>;
|
|
97
|
-
destroySession(target: Headers): void;
|
|
98
|
-
rotateSession(request: Request, target: Headers): Promise<TSession | null>;
|
|
99
|
-
}
|
|
100
|
-
declare function createSessionManagerWeb<TSession>(config: SessionConfig): SessionManagerWeb<TSession>;
|
|
101
|
-
/**
|
|
102
|
-
* T5a.2 Phase D slice 3/3 — Web-Standards transparent re-encrypt helper.
|
|
103
|
-
*
|
|
104
|
-
* Mirror of `rotateIfNeeded(sm, req, res)` for the Web Request + Headers
|
|
105
|
-
* shape. Reads session via `getSessionWithMeta`; if the cookie was
|
|
106
|
-
* decrypted with a legacy secret (index > 0), re-issues the cookie with
|
|
107
|
-
* the newest secret via `createSession(target, data)`.
|
|
108
|
-
*
|
|
109
|
-
* **EC-4 honest framing:** unlike the IncomingMessage path where the
|
|
110
|
-
* timing constraint is "before `res.writeHead` fires", the Web Request
|
|
111
|
-
* path's constraint is "before the `Response` object is constructed and
|
|
112
|
-
* returned to the runtime". Caller MUST invoke `rotateIfNeededWeb`
|
|
113
|
-
* BEFORE building the final `Response(body, { headers: target })` so the
|
|
114
|
-
* re-encrypted Set-Cookie lands on the wire.
|
|
115
|
-
*/
|
|
116
|
-
declare function rotateIfNeededWeb<TSession>(sm: SessionManagerWeb<TSession>, request: Request, target: Headers): Promise<TSession | null>;
|
|
117
|
-
/**
|
|
118
|
-
* T3.2 — Transparent re-encrypt helper (EC-4 timing-safe wrapper).
|
|
119
|
-
*
|
|
120
|
-
* Call this in your `createContext` (before any rendering / streaming
|
|
121
|
-
* starts). It:
|
|
122
|
-
* 1. Reads the session via `getSessionWithMeta`.
|
|
123
|
-
* 2. If the cookie was decrypted with a legacy secret (index > 0), it
|
|
124
|
-
* immediately re-issues the cookie with `secrets[0]` so the next
|
|
125
|
-
* request lands on the newest key.
|
|
126
|
-
* 3. Returns the session data (or null) for use downstream.
|
|
127
|
-
*
|
|
128
|
-
* EC-4: this MUST run before `renderToPipeableStream` / `res.writeHead`
|
|
129
|
-
* fires. Calling it inside an SSR component or handler body that has
|
|
130
|
-
* already streamed bytes makes the re-encrypt a silent no-op (Set-Cookie
|
|
131
|
-
* is locked once headers commit), trapping users on the legacy secret
|
|
132
|
-
* forever once it's removed from the array.
|
|
133
|
-
*/
|
|
134
|
-
declare function rotateIfNeeded<TSession>(sm: SessionManager<TSession>, req: IncomingMessage, res: ServerResponse): Promise<TSession | null>;
|
|
135
|
-
declare function assertProductionSecret(secret: string | string[]): void;
|
|
136
|
-
|
|
137
|
-
declare function encrypt<T>(data: T, secret: string): Promise<string>;
|
|
138
|
-
declare function decrypt<T>(token: string, secret: string): Promise<T | null>;
|
|
139
|
-
/**
|
|
140
|
-
* Reset the derived-key cache. Test helper — never call from production code.
|
|
141
|
-
* Used by Vitest to guarantee isolation between tests that use distinct
|
|
142
|
-
* secrets and want to confirm the derivation path runs.
|
|
143
|
-
*/
|
|
144
|
-
declare function _resetKeyCacheForTests(): void;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* T6.2 — RFC 6238 TOTP primitive.
|
|
148
|
-
*
|
|
149
|
-
* Reference: https://datatracker.ietf.org/doc/html/rfc6238
|
|
150
|
-
* HMAC-based one-time password (HOTP) base: https://datatracker.ietf.org/doc/html/rfc4226
|
|
151
|
-
*
|
|
152
|
-
* Pure-function, dependency-free implementation via Web Crypto. Secrets
|
|
153
|
-
* may be passed as Uint8Array (preferred) or base32 string.
|
|
154
|
-
*
|
|
155
|
-
* SECURITY NOTES (documented per EC-13):
|
|
156
|
-
* - TOTP secrets are equivalent to passwords. Encrypt at rest using a
|
|
157
|
-
* separate KMS key from the session secret. If your DB leaks, ALL
|
|
158
|
-
* 2FA codes are compromised — rotate by forcing all users to re-enroll.
|
|
159
|
-
* - Use `verifyTotp` constant-time (we use crypto.timingSafeEqual internally).
|
|
160
|
-
*/
|
|
161
|
-
/** Supported HMAC algorithms per RFC 6238 §1.2. Default SHA-1. */
|
|
162
|
-
type TotpAlgorithm = 'SHA-1' | 'SHA-256' | 'SHA-512';
|
|
163
|
-
interface TotpOptions {
|
|
164
|
-
/** Shared secret — bytes (preferred) OR base32 string. */
|
|
165
|
-
secret: Uint8Array | string;
|
|
166
|
-
/** Time step in seconds. Default 30 (RFC 6238 §5.2 recommended). */
|
|
167
|
-
step?: number;
|
|
168
|
-
/** Code length: 6, 7, or 8 digits. Default 6. */
|
|
169
|
-
digits?: 6 | 7 | 8;
|
|
170
|
-
/** HMAC algorithm. Default SHA-1 (RFC default). */
|
|
171
|
-
algorithm?: TotpAlgorithm;
|
|
172
|
-
/** Time in ms since epoch. Default Date.now(). */
|
|
173
|
-
time?: number;
|
|
174
|
-
}
|
|
175
|
-
interface VerifyTotpOptions extends TotpOptions {
|
|
176
|
-
/**
|
|
177
|
-
* Drift tolerance in number of steps on each side. Default 1
|
|
178
|
-
* (RFC 6238 §5.2 recommends ±1 step = 90s total window).
|
|
179
|
-
*/
|
|
180
|
-
window?: number;
|
|
181
|
-
}
|
|
182
|
-
/** Generate a TOTP code for a given time. */
|
|
183
|
-
declare function generateTotp(opts: TotpOptions): Promise<string>;
|
|
184
|
-
/**
|
|
185
|
-
* Verify a TOTP code against the current window ± `window` steps.
|
|
186
|
-
*
|
|
187
|
-
* Returns `false` for malformed tokens (non-digit, wrong length) without
|
|
188
|
-
* throwing — defensive against accidental user-input passthrough.
|
|
189
|
-
*/
|
|
190
|
-
declare function verifyTotp(token: string, opts: VerifyTotpOptions): Promise<boolean>;
|
|
191
|
-
/** Generate a cryptographically random TOTP secret. Default 20 bytes (RFC minimum). */
|
|
192
|
-
declare function generateTotpSecret(bytes?: number): Uint8Array;
|
|
193
|
-
/**
|
|
194
|
-
* Build an `otpauth://` URI for QR code enrollment. Format follows the
|
|
195
|
-
* de facto Google Authenticator spec adopted by every major TOTP app.
|
|
196
|
-
* otpauth://totp/<issuer>:<account>?secret=<base32>&issuer=<issuer>&algorithm=<alg>&digits=<n>&period=<sec>
|
|
197
|
-
*/
|
|
198
|
-
interface TotpUriOptions {
|
|
199
|
-
secret: Uint8Array;
|
|
200
|
-
issuer: string;
|
|
201
|
-
account: string;
|
|
202
|
-
algorithm?: TotpAlgorithm;
|
|
203
|
-
digits?: 6 | 7 | 8;
|
|
204
|
-
step?: number;
|
|
205
|
-
}
|
|
206
|
-
declare function totpUri(opts: TotpUriOptions): string;
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* T6.3 — Backup codes for 2FA recovery.
|
|
210
|
-
*
|
|
211
|
-
* generateBackupCodes returns N plaintexts (display once to user) + hashes
|
|
212
|
-
* (store in DB). verifyBackupCode constant-time-walks all hashes and
|
|
213
|
-
* returns the matchedHash so caller can delete the used code from storage
|
|
214
|
-
* — replay protection lives at the caller (we can't see their database).
|
|
215
|
-
*
|
|
216
|
-
* SECURITY NOTES:
|
|
217
|
-
* - Codes have ~40 bits entropy (8 chars × 5 bits per char from a
|
|
218
|
-
* 32-char alphabet excluding I/L/O/0/1). Single-use → argon2id
|
|
219
|
-
* overhead is unnecessary; SHA-256 of the normalized code suffices.
|
|
220
|
-
* - The caller MUST atomically delete the matched hash on successful
|
|
221
|
-
* verify. Without that, the code is replayable. We surface
|
|
222
|
-
* matchedHash explicitly so this step is conspicuous.
|
|
223
|
-
* - Pair this with throttleLoginAttempts (T6.1) on the verify endpoint
|
|
224
|
-
* to prevent online brute-force against the 40-bit space.
|
|
225
|
-
*/
|
|
226
|
-
interface BackupCodeOptions {
|
|
227
|
-
/** How many codes to generate. Default 10. */
|
|
228
|
-
count?: number;
|
|
229
|
-
/** Length in chars (excluding separator). Default 8. */
|
|
230
|
-
length?: number;
|
|
231
|
-
/** Separator inserted at the midpoint. Default '-'; pass null to omit. */
|
|
232
|
-
separator?: '-' | null;
|
|
233
|
-
/** Custom alphabet. Default excludes ambiguous chars (I, L, O, 0, 1). */
|
|
234
|
-
alphabet?: string;
|
|
235
|
-
}
|
|
236
|
-
interface BackupCode {
|
|
237
|
-
plaintext: string;
|
|
238
|
-
hash: string;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Generate cryptographically random backup codes + their SHA-256 hashes.
|
|
242
|
-
*
|
|
243
|
-
* Plaintext is uppercase alphanumeric (default alphabet excludes ambiguous
|
|
244
|
-
* chars). Separator inserted at the midpoint (default `-`).
|
|
245
|
-
*/
|
|
246
|
-
declare function generateBackupCodes(opts?: BackupCodeOptions): Promise<BackupCode[]>;
|
|
247
|
-
/**
|
|
248
|
-
* Verify a code against a list of stored hashes. Walks all hashes
|
|
249
|
-
* constant-time (no early exit). Returns `valid:true` + matchedHash on
|
|
250
|
-
* hit; `valid:false` otherwise.
|
|
251
|
-
*
|
|
252
|
-
* `matchedHash` is the EXACT string the caller stored, ready to be passed
|
|
253
|
-
* to a `DELETE FROM backup_codes WHERE hash = ?` query.
|
|
254
|
-
*/
|
|
255
|
-
declare function verifyBackupCode(code: string, hashes: readonly string[]): Promise<{
|
|
256
|
-
valid: boolean;
|
|
257
|
-
matchedHash?: string;
|
|
258
|
-
}>;
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* T6.1 — Login throttling primitive.
|
|
262
|
-
*
|
|
263
|
-
* Per-credential failure counter backed by any `RateLimitStore`. After
|
|
264
|
-
* `maxAttempts` failures within `windowMs`, the identifier is locked
|
|
265
|
-
* for `lockoutMs`. Successful login resets the counter.
|
|
266
|
-
*
|
|
267
|
-
* Usage in a login handler:
|
|
268
|
-
*
|
|
269
|
-
* const state = await checkThrottle({ store, identifier: hash(email) })
|
|
270
|
-
* if (!state.allowed) return 429
|
|
271
|
-
* const valid = await verifyPassword(creds)
|
|
272
|
-
* await recordAttempt({ store, identifier: hash(email) }, valid)
|
|
273
|
-
* if (!valid) return 401
|
|
274
|
-
*
|
|
275
|
-
* SECURITY:
|
|
276
|
-
* - NEVER pass raw email/username as `identifier`. Hash or normalize
|
|
277
|
-
* first (e.g. SHA-256 of the lowercased email). This prevents PII
|
|
278
|
-
* from landing in the rate-limit store or audit logs.
|
|
279
|
-
* - Combine with the per-route IP rate limit (T2.2) for layered defense:
|
|
280
|
-
* IP-level limits stop scripted floods; credential-level limits stop
|
|
281
|
-
* distributed brute force.
|
|
282
|
-
*/
|
|
283
|
-
interface ThrottleOptions {
|
|
284
|
-
store: RateLimitStore;
|
|
285
|
-
/**
|
|
286
|
-
* Stable identifier per credential. Hash raw emails/usernames before
|
|
287
|
-
* passing in — never leak PII to the rate-limit key space.
|
|
288
|
-
*/
|
|
289
|
-
identifier: string;
|
|
290
|
-
/** Failures before lockout. Default 5. */
|
|
291
|
-
maxAttempts?: number;
|
|
292
|
-
/** Sliding window for counting failures. Default 15 minutes. */
|
|
293
|
-
windowMs?: number;
|
|
294
|
-
/** Lockout duration after maxAttempts hit. Default 1 hour. */
|
|
295
|
-
lockoutMs?: number;
|
|
296
|
-
}
|
|
297
|
-
interface ThrottleState {
|
|
298
|
-
allowed: boolean;
|
|
299
|
-
remainingAttempts: number;
|
|
300
|
-
/** Set when `allowed === false`. Absolute timestamp when the lockout expires. */
|
|
301
|
-
lockedUntil?: Date;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Read the current throttle state for an identifier WITHOUT modifying
|
|
305
|
-
* the counter. Call before validating credentials so locked attempts
|
|
306
|
-
* are rejected fast.
|
|
307
|
-
*/
|
|
308
|
-
declare function checkThrottle(opts: ThrottleOptions): Promise<ThrottleState>;
|
|
309
|
-
/**
|
|
310
|
-
* Record an attempt outcome. On success → reset the counter. On failure
|
|
311
|
-
* → increment within the sliding window. Returns the new throttle state.
|
|
312
|
-
*
|
|
313
|
-
* Storage model: the store entry's TTL is `lockoutMs` (which doubles as
|
|
314
|
-
* the failure-accumulation window). When `lockoutMs` is short — common
|
|
315
|
-
* in tests or for soft lockouts — the entry auto-expires and the next
|
|
316
|
-
* attempt starts fresh.
|
|
317
|
-
*/
|
|
318
|
-
declare function recordAttempt(opts: ThrottleOptions, success: boolean): Promise<ThrottleState>;
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* T7.3 — RFC 7636 PKCE primitive.
|
|
322
|
-
*
|
|
323
|
-
* Reference: https://datatracker.ietf.org/doc/html/rfc7636
|
|
324
|
-
*
|
|
325
|
-
* Pure-function, dependency-free implementation using Web Crypto.
|
|
326
|
-
*
|
|
327
|
-
* Usage in an OAuth authorization-code flow:
|
|
328
|
-
*
|
|
329
|
-
* const { codeVerifier, codeChallenge, codeChallengeMethod } = await generatePkceChallenge()
|
|
330
|
-
* // Store codeVerifier in the user's session
|
|
331
|
-
* // Send codeChallenge + codeChallengeMethod in the /authorize redirect
|
|
332
|
-
* // ... user authenticates with provider ...
|
|
333
|
-
* // On /callback, send codeVerifier with the code → token exchange
|
|
334
|
-
*/
|
|
335
|
-
interface PkceChallenge {
|
|
336
|
-
codeVerifier: string;
|
|
337
|
-
codeChallenge: string;
|
|
338
|
-
codeChallengeMethod: 'S256';
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Compute the code_challenge from a code_verifier per RFC 7636 §4.2.
|
|
342
|
-
* Exported separately to enable RFC 7636 Appendix B vector testing.
|
|
343
|
-
*/
|
|
344
|
-
declare function pkceChallengeFromVerifier(verifier: string): Promise<string>;
|
|
345
|
-
/**
|
|
346
|
-
* Generate a fresh PKCE challenge pair.
|
|
347
|
-
*
|
|
348
|
-
* Verifier: 32 cryptographically random bytes → 43-char base64url string.
|
|
349
|
-
* RFC 7636 §4.1 allows 43–128 chars; we ship the minimum-safe default.
|
|
350
|
-
*
|
|
351
|
-
* Method: 'S256' only — no 'plain' fallback. RFC 7636 §7.2 strongly
|
|
352
|
-
* discourages plain and modern providers reject it.
|
|
353
|
-
*/
|
|
354
|
-
declare function generatePkceChallenge(): Promise<PkceChallenge>;
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* T7.4 — OAuth `state` parameter helpers (RFC 6749 §10.12).
|
|
358
|
-
*
|
|
359
|
-
* `state` is a cryptographically random anti-CSRF token. The client
|
|
360
|
-
* stores it (in session/cookie/db) before redirecting to the
|
|
361
|
-
* authorization endpoint and verifies it on the callback. Without it,
|
|
362
|
-
* an attacker can authorize on the user's account using a captured code.
|
|
363
|
-
*/
|
|
364
|
-
/**
|
|
365
|
-
* Generate a cryptographically random state token. Default 32 bytes
|
|
366
|
-
* (~43 base64url chars). Increase for higher entropy if your provider
|
|
367
|
-
* supports it.
|
|
368
|
-
*/
|
|
369
|
-
declare function generateOAuthState(opts?: {
|
|
370
|
-
bytes?: number;
|
|
371
|
-
}): string;
|
|
372
|
-
/**
|
|
373
|
-
* Verify a state token. Constant-time compare. Empty inputs always fail
|
|
374
|
-
* (defensive — never accept empty as "they match").
|
|
375
|
-
*
|
|
376
|
-
* CR-012 fix: `constantTimeEquals` does not early-exit on length mismatch,
|
|
377
|
-
* so the comparison time is independent of how the input was forged.
|
|
378
|
-
*/
|
|
379
|
-
declare function verifyOAuthState(provided: string, stored: string): boolean;
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* T7.4 — OpenID Connect Discovery 1.0 metadata fetcher.
|
|
383
|
-
*
|
|
384
|
-
* Reference: https://openid.net/specs/openid-connect-discovery-1_0.html
|
|
385
|
-
*
|
|
386
|
-
* Caches metadata in module scope. Cache key is the exact issuer string
|
|
387
|
-
* (trailing-slash sensitive per RFC 8414 §3). Failures are NOT cached —
|
|
388
|
-
* subsequent calls retry the fetch.
|
|
389
|
-
*
|
|
390
|
-
* EC-7 — HTTPS enforced. RFC 8414 §3 requires HTTPS for OIDC issuers.
|
|
391
|
-
* Localhost (loopback) is allowed for development.
|
|
392
|
-
*/
|
|
393
|
-
interface OidcMetadata {
|
|
394
|
-
issuer: string;
|
|
395
|
-
authorization_endpoint: string;
|
|
396
|
-
token_endpoint: string;
|
|
397
|
-
jwks_uri?: string;
|
|
398
|
-
userinfo_endpoint?: string;
|
|
399
|
-
end_session_endpoint?: string;
|
|
400
|
-
scopes_supported?: string[];
|
|
401
|
-
response_types_supported?: string[];
|
|
402
|
-
grant_types_supported?: string[];
|
|
403
|
-
id_token_signing_alg_values_supported?: string[];
|
|
404
|
-
[key: string]: unknown;
|
|
405
|
-
}
|
|
406
|
-
/** Clear the discovery cache. Used by tests. */
|
|
407
|
-
declare function clearOidcCache(): void;
|
|
408
|
-
/**
|
|
409
|
-
* Fetch (or return cached) OIDC provider metadata.
|
|
410
|
-
*
|
|
411
|
-
* Throws when:
|
|
412
|
-
* - Issuer URL is malformed
|
|
413
|
-
* - Issuer is HTTP and not a loopback host (EC-7)
|
|
414
|
-
* - HTTP response is non-OK
|
|
415
|
-
* - Metadata lacks `authorization_endpoint` (sanity check)
|
|
416
|
-
*/
|
|
417
|
-
declare function discoverOidcProvider(issuer: string | URL): Promise<OidcMetadata>;
|
|
418
|
-
|
|
419
|
-
export { AuthRequiredError, type BackupCode, type BackupCodeOptions, type OidcMetadata, type PkceChallenge, type SessionConfig, type SessionManager, type SessionManagerWeb, type SessionMeta, type ThrottleOptions, type ThrottleState, type TotpAlgorithm, type TotpOptions, type TotpUriOptions, type VerifyTotpOptions, _resetKeyCacheForTests, assertProductionSecret, checkThrottle, clearOidcCache, createSessionManager, createSessionManagerWeb, decrypt, discoverOidcProvider, encrypt, generateBackupCodes, generateNonce, generateOAuthState, generatePkceChallenge, generateTotp, generateTotpSecret, pkceChallengeFromVerifier, recordAttempt, requireAuth, rotateIfNeeded, rotateIfNeededWeb, totpUri, verifyBackupCode, verifyOAuthState, verifyTotp };
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import { d as StorageAdapter } from '../../storage-types-DsDTCPbp.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Cost tracking types (R0.5.11).
|
|
5
|
-
*
|
|
6
|
-
* @see docs/adr/0002-job-backend-interface-neutral-contract.md (mirror pattern)
|
|
7
|
-
*
|
|
8
|
-
* Phase 5 — Production-Readiness #4: adds `ToolUsageRecord` for per-tool
|
|
9
|
-
* latency / error tracking via SDK's onToolStart/onToolEnd/onToolError hooks.
|
|
10
|
-
* Same UsageStorageAdapter handles both via discriminated union.
|
|
11
|
-
*
|
|
12
|
-
* EC-9 (SHOULD TEST): backward compat — record() input without `kind` is
|
|
13
|
-
* normalized to 'llm' by the framework so external adapters from older
|
|
14
|
-
* versions keep working.
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
|
-
* Per-LLM-call cost record (existing — gains optional `kind` discriminator).
|
|
18
|
-
*/
|
|
19
|
-
interface UsageRecord {
|
|
20
|
-
/** Discriminator. Optional for backward-compat; defaults to 'llm'. */
|
|
21
|
-
kind?: 'llm';
|
|
22
|
-
/** User identifier (e.g., session userId, tenantId, apiKey hash). */
|
|
23
|
-
userId: string;
|
|
24
|
-
/** Model id (e.g., 'claude-sonnet-4-5-20250929'). */
|
|
25
|
-
model: string;
|
|
26
|
-
/** Token counts per direction. */
|
|
27
|
-
tokens: {
|
|
28
|
-
input: number;
|
|
29
|
-
output: number;
|
|
30
|
-
};
|
|
31
|
-
/** USD cost in fractional dollars. */
|
|
32
|
-
costUsd: number;
|
|
33
|
-
/** When the run happened. */
|
|
34
|
-
timestamp: Date;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Per-tool-invocation record (Phase 5 — Production-Readiness #4).
|
|
38
|
-
*
|
|
39
|
-
* Emitted by `trackAgentTools` on every `onToolEnd` / `onToolError`. The same
|
|
40
|
-
* `UsageStorageAdapter.record` accepts both record kinds via union.
|
|
41
|
-
*/
|
|
42
|
-
interface ToolUsageRecord {
|
|
43
|
-
kind: 'tool';
|
|
44
|
-
userId: string;
|
|
45
|
-
conversationId: string;
|
|
46
|
-
toolName: string;
|
|
47
|
-
/**
|
|
48
|
-
* Unique per invocation; correlates onToolStart with onToolEnd / onToolError.
|
|
49
|
-
* EC-16 (DOCUMENT): callId uniqueness is SDK contract — if SDK ever reuses
|
|
50
|
-
* a callId, `trackAgentTools`'s Map uses last-write-wins (defensive).
|
|
51
|
-
*/
|
|
52
|
-
callId: string;
|
|
53
|
-
/** True when the tool handler returned; false when it threw. */
|
|
54
|
-
success: boolean;
|
|
55
|
-
/** Milliseconds from onToolStart to onToolEnd / onToolError. */
|
|
56
|
-
durationMs: number;
|
|
57
|
-
/** Populated only when success === false. */
|
|
58
|
-
errorMessage?: string;
|
|
59
|
-
timestamp: Date;
|
|
60
|
-
}
|
|
61
|
-
interface UsageQuery {
|
|
62
|
-
userId: string;
|
|
63
|
-
period: {
|
|
64
|
-
from: Date;
|
|
65
|
-
to: Date;
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
interface UsageResult {
|
|
69
|
-
totalTokens: number;
|
|
70
|
-
totalCostUsd: number;
|
|
71
|
-
runs: number;
|
|
72
|
-
}
|
|
73
|
-
interface UsageStorageAdapter {
|
|
74
|
-
readonly name: string;
|
|
75
|
-
/**
|
|
76
|
-
* Record a usage event. Accepts both kinds; framework normalizes input
|
|
77
|
-
* without `kind` to 'llm' before calling adapter (EC-9 backward compat).
|
|
78
|
-
*/
|
|
79
|
-
record(input: UsageRecord | ToolUsageRecord): Promise<void>;
|
|
80
|
-
getUsage(query: UsageQuery): Promise<UsageResult>;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
interface TrackAgentRunInput {
|
|
84
|
-
userId: string;
|
|
85
|
-
model: string;
|
|
86
|
-
tokens: {
|
|
87
|
-
input: number;
|
|
88
|
-
output: number;
|
|
89
|
-
};
|
|
90
|
-
costUsd: number;
|
|
91
|
-
/** Defaults to `new Date()`. */
|
|
92
|
-
timestamp?: Date;
|
|
93
|
-
/** Optional execution status surfaced to devtools (default 'finished'). */
|
|
94
|
-
status?: 'finished' | 'error' | 'aborted';
|
|
95
|
-
}
|
|
96
|
-
interface TrackAgentRunOptions {
|
|
97
|
-
/** Adapter resolved from `theo.config.ts > cost.storage`. */
|
|
98
|
-
storage: UsageStorageAdapter | undefined;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Record a single agent run's usage + cost. Companion to the client-side
|
|
102
|
-
* `<CostMeter>` from `@theokit/ui`.
|
|
103
|
-
*
|
|
104
|
-
* EC-14: this function NEVER bubbles errors back to the caller. Adapter
|
|
105
|
-
* failures (network outage, DB down, etc.) are logged via `console.warn`
|
|
106
|
-
* and swallowed. The agent response MUST NOT fail because cost tracking
|
|
107
|
-
* is degraded.
|
|
108
|
-
*
|
|
109
|
-
* No-op when `storage` is undefined (cost tracking unconfigured).
|
|
110
|
-
*
|
|
111
|
-
* In dev mode (Vite OR tsup-built with NODE_ENV != 'production'), fires a
|
|
112
|
-
* `theokit-evolution-ci-and-dx` Phase 3 dispatcher event so the devtools
|
|
113
|
-
* Agents tab can render the run. Prod tree-shakes the entire dispatcher
|
|
114
|
-
* import via the `__IS_DEV` IIFE guard.
|
|
115
|
-
*
|
|
116
|
-
* @see docs/concepts/cost-tracking.md (when implemented in T6.3)
|
|
117
|
-
*/
|
|
118
|
-
declare function trackAgentRun(input: TrackAgentRunInput, opts: TrackAgentRunOptions): Promise<void>;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* In-memory usage storage for dev/tests. Unbounded — production
|
|
122
|
-
* deployments MUST plug in a durable adapter (Postgres/Redis recipes
|
|
123
|
-
* land with R0.6.7; documented in EC-114).
|
|
124
|
-
*
|
|
125
|
-
* Phase 5 — Production-Readiness #4: accepts both `UsageRecord` (LLM call,
|
|
126
|
-
* kind='llm' or omitted) AND `ToolUsageRecord` (tool call, kind='tool').
|
|
127
|
-
* `getUsage` only sums LLM records (tools have no token/cost dimension).
|
|
128
|
-
*
|
|
129
|
-
* EC-9 (backward compat): input without `kind` is normalized to `kind:'llm'`
|
|
130
|
-
* — adapters from older versions stay working.
|
|
131
|
-
*
|
|
132
|
-
* Concurrency: Node's single-threaded event loop guarantees that
|
|
133
|
-
* `Array.push` is atomic, so concurrent record() calls cannot lose data.
|
|
134
|
-
*/
|
|
135
|
-
declare class InMemoryUsageStorage implements UsageStorageAdapter, StorageAdapter {
|
|
136
|
-
#private;
|
|
137
|
-
readonly name = "memory";
|
|
138
|
-
/**
|
|
139
|
-
* T2.3 — `StorageAdapter` lifecycle hook (ADR-0007 D6). In-memory storage
|
|
140
|
-
* has no real cleanup to perform — this is intentionally a noop so the
|
|
141
|
-
* adapter can be registered with `StorageManager.register()` and
|
|
142
|
-
* participate in graceful shutdown without changing behavior.
|
|
143
|
-
*
|
|
144
|
-
* Does NOT clear stored records (dispose ≠ reset). For test reset use
|
|
145
|
-
* a fresh instance.
|
|
146
|
-
*/
|
|
147
|
-
dispose(): Promise<void>;
|
|
148
|
-
record(input: UsageRecord | ToolUsageRecord): Promise<void>;
|
|
149
|
-
getUsage(query: UsageQuery): Promise<UsageResult>;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
interface TrackAgentToolsOptions {
|
|
153
|
-
storage: UsageStorageAdapter;
|
|
154
|
-
/** Defaults to () => new Date() — overridable for deterministic testing. */
|
|
155
|
-
now?: () => Date;
|
|
156
|
-
/** Identifier for the user — passed through to ToolUsageRecord.userId. */
|
|
157
|
-
userId?: string;
|
|
158
|
-
/** Identifier for the conversation — passed through to ToolUsageRecord.conversationId. */
|
|
159
|
-
conversationId?: string;
|
|
160
|
-
}
|
|
161
|
-
interface ToolHookEvent {
|
|
162
|
-
callId: string;
|
|
163
|
-
name: string;
|
|
164
|
-
[key: string]: unknown;
|
|
165
|
-
}
|
|
166
|
-
interface TrackAgentToolsHooks {
|
|
167
|
-
onToolStart: (event: ToolHookEvent) => void;
|
|
168
|
-
onToolEnd: (event: ToolHookEvent) => void;
|
|
169
|
-
onToolError: (event: ToolHookEvent) => void;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Create the three tool-lifecycle callbacks. Hand the returned object's
|
|
173
|
-
* methods to `Agent.create({ tools, onToolStart, onToolEnd, onToolError })`.
|
|
174
|
-
*/
|
|
175
|
-
declare function trackAgentTools(opts: TrackAgentToolsOptions): TrackAgentToolsHooks;
|
|
176
|
-
|
|
177
|
-
export { InMemoryUsageStorage, type ToolHookEvent, type ToolUsageRecord, type TrackAgentRunInput, type TrackAgentRunOptions, type TrackAgentToolsHooks, type TrackAgentToolsOptions, type UsageQuery, type UsageRecord, type UsageResult, type UsageStorageAdapter, trackAgentRun, trackAgentTools };
|