@zitadel/sdk-core 0.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ZITADEL
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @zitadel/sdk-core
2
+
3
+ Core public runtime types and mock flow helpers used by the v1 Zitadel setup CLI.
@@ -0,0 +1,22 @@
1
+ export type { NextgenSession, AuthState, UnauthState, AuthResult, NextgenMiddlewareOptions } from "./types.js";
2
+ export { HOP_BY_HOP, INTERNAL_HEADERS, matchesRoutes, filterResponseHeaders } from "./middleware.js";
3
+ export { verifyJwt, decodeJwt, base64UrlDecode, JWKS_TTL_MS } from "./jwt.js";
4
+ export type { JwtPayload, JwtHeader, DecodedJwt, VerifyJwtOptions } from "./jwt.js";
5
+ export type ZitadelEnvironment = "development" | "preview" | "production";
6
+ export type ZitadelRuntime = {
7
+ projectId: string;
8
+ environment: ZitadelEnvironment;
9
+ issuer?: string;
10
+ };
11
+ export type ZitadelRuntimeInput = {
12
+ projectId?: string;
13
+ environment?: ZitadelEnvironment;
14
+ issuer?: string;
15
+ };
16
+ export declare class ZitadelRuntimeError extends Error {
17
+ readonly code: string;
18
+ constructor(code: string, message: string);
19
+ }
20
+ export declare function resolveZitadelRuntimeEnv(env?: Record<string, string | undefined>): ZitadelRuntime;
21
+ export declare function resolveZitadelRuntime(input: ZitadelRuntimeInput): ZitadelRuntime;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAC/G,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACrG,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC9E,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEpF,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;AAE1E,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,kBAAkB,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAIxC;CACF;AAED,wBAAgB,wBAAwB,CACtC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAgB,GACrD,cAAc,CAMhB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,cAAc,CAmBhF"}
package/dist/index.js ADDED
@@ -0,0 +1,36 @@
1
+ import { HOP_BY_HOP as e, INTERNAL_HEADERS as t, filterResponseHeaders as n, matchesRoutes as r } from "./middleware.js";
2
+ import { JWKS_TTL_MS as i, base64UrlDecode as a, decodeJwt as o, verifyJwt as s } from "./jwt.js";
3
+ //#region src/index.ts
4
+ var c = class extends Error {
5
+ code;
6
+ constructor(e, t) {
7
+ super(t), this.name = "ZitadelRuntimeError", this.code = e;
8
+ }
9
+ };
10
+ function l(e = f()) {
11
+ return u({
12
+ projectId: e.NEXT_PUBLIC_ZITADEL_PROJECT_ID ?? e.ZITADEL_PROJECT_ID,
13
+ environment: d(e.NEXT_PUBLIC_ZITADEL_ENVIRONMENT ?? e.ZITADEL_ENVIRONMENT),
14
+ issuer: e.NEXT_PUBLIC_ZITADEL_ISSUER ?? e.ZITADEL_ISSUER
15
+ });
16
+ }
17
+ function u(e) {
18
+ let t = e.environment ?? "development";
19
+ if (!e.projectId) throw new c("E_ZITADEL_CONFIG", "ZITADEL_PROJECT_ID is required for Zitadel runtime.");
20
+ if (t === "production" && !e.issuer) throw new c("E_ZITADEL_CONFIG", "ZITADEL_ISSUER is required in production.");
21
+ return {
22
+ projectId: e.projectId,
23
+ environment: t,
24
+ issuer: e.issuer
25
+ };
26
+ }
27
+ function d(e) {
28
+ if (!e || e === "development") return "development";
29
+ if (e === "preview" || e === "production") return e;
30
+ throw new c("E_ZITADEL_CONFIG", `Unsupported ZITADEL_ENVIRONMENT "${e}".`);
31
+ }
32
+ function f() {
33
+ return globalThis.process?.env ?? {};
34
+ }
35
+ //#endregion
36
+ export { e as HOP_BY_HOP, t as INTERNAL_HEADERS, i as JWKS_TTL_MS, c as ZitadelRuntimeError, a as base64UrlDecode, o as decodeJwt, n as filterResponseHeaders, r as matchesRoutes, u as resolveZitadelRuntime, l as resolveZitadelRuntimeEnv, s as verifyJwt };
package/dist/jwt.d.ts ADDED
@@ -0,0 +1,264 @@
1
+ /**
2
+ * @file lib/jwt.ts
3
+ *
4
+ * # JWT Verification
5
+ *
6
+ * Stateless JWT verification via JWKS, with in-process key caching.
7
+ *
8
+ * ## Anatomy of a JWT
9
+ *
10
+ * A compact JWT (JWS compact serialisation) is three Base64URL-encoded parts
11
+ * joined by dots:
12
+ *
13
+ * ```
14
+ * <header>.<payload>.<signature>
15
+ * ```
16
+ *
17
+ * - **Header** — metadata about the token: signing algorithm, key ID, token type.
18
+ * - **Payload** — the claims: user identity, expiry, issuer, audience, etc.
19
+ * - **Signature** — `SIGN(privateKey, "<header>.<payload>")`. Any party with the
20
+ * matching public key can verify it without contacting the auth server.
21
+ *
22
+ * A valid signature proves two things:
23
+ *
24
+ * 1. **Authenticity** — the token was produced by the holder of the private key.
25
+ * 2. **Integrity** — neither the header nor the payload has been altered since signing.
26
+ *
27
+ * Signature verification alone is not sufficient. The claims inside the payload
28
+ * must also be checked (expiry, issuer, audience, …). Both steps are performed
29
+ * by {@link verifyJwt}.
30
+ *
31
+ * ---
32
+ *
33
+ * ## JWT Header fields
34
+ *
35
+ * The header is a JSON object Base64URL-encoded into the first segment.
36
+ *
37
+ * | Field | Purpose | Verified |
38
+ * |-------|---------|---------|
39
+ * | `alg` | Signing algorithm (`RS256`, `ES256`, …) | Checked against {@link VerifyJwtOptions.allowedAlgorithms} before JWKS is fetched |
40
+ * | `kid` | Key ID — selects the matching public key from the JWKS | Used for key lookup; falls back to the first JWKS key when absent |
41
+ * | `typ` | Token type (`JWT`, `at+JWT`, …) | Checked against {@link VerifyJwtOptions.allowedTokenTypes} (case-insensitive) |
42
+ * | ~~`enc`~~ | ~~Encryption algorithm — present in JWE (encrypted) tokens only~~ | ~~Not applicable — we verify JWS (signed) tokens, not JWE (encrypted)~~ |
43
+ * | ~~`cty`~~ | ~~Content type — describes the secured content media type~~ | ~~Not applicable — not set by standard OIDC/OAuth auth servers~~ |
44
+ *
45
+ * ---
46
+ *
47
+ * ## JWT Payload claims
48
+ *
49
+ * The payload is a JSON object Base64URL-encoded into the second segment.
50
+ *
51
+ * ### Validated claims
52
+ *
53
+ * | Claim | Purpose | How |
54
+ * |-------|---------|-----|
55
+ * | `iss` | Issuer — the URL of the auth server that issued the token | Must be present and must equal {@link VerifyJwtOptions.issuerUrl} |
56
+ * | `exp` | Expiration time — Unix timestamp after which the token is invalid | Must be present and in the future, allowing {@link VerifyJwtOptions.clockSkewMs} tolerance |
57
+ * | `nbf` | Not before — Unix timestamp before which the token must not be accepted | Must be in the past, allowing {@link VerifyJwtOptions.clockSkewMs} tolerance |
58
+ * | `iat` | Issued at — Unix timestamp when the token was created | Must not be in the future beyond {@link VerifyJwtOptions.clockSkewMs} |
59
+ * | `aud` | Audience — the intended recipient(s) of the token | Checked against {@link VerifyJwtOptions.audience} when that option is provided |
60
+ *
61
+ * ### Read-only claims (extracted into the session, not further validated)
62
+ *
63
+ * | Claim | Purpose |
64
+ * |-------|---------|
65
+ * | `sub` | Subject — the user's unique identifier |
66
+ * | `email` | User's email address |
67
+ * | `name` | User's display name |
68
+ *
69
+ * ### Not validated
70
+ *
71
+ * | Claim | Purpose | Why skipped |
72
+ * |-------|---------|-------------|
73
+ * | ~~`jti`~~ | ~~JWT ID — a unique identifier for this specific token instance~~ | ~~Revocation requires a server-side blocklist; not feasible in stateless edge middleware~~ |
74
+ * | ~~`azp`~~ | ~~Authorized party — the OAuth 2.0 client that requested the token~~ | ~~The proxy architecture means the browser never contacts the auth server directly, making cross-origin token replay a non-threat~~ |
75
+ * | ~~`nonce`~~ | ~~OIDC nonce — binds a token to a specific authorisation request~~ | ~~Not applicable in our password/cookie flow (no OIDC redirect round-trip)~~ |
76
+ * | ~~`acr`~~ | ~~Authentication class reference — describes the strength of the authentication~~ | ~~Not validated (future: require MFA for sensitive routes)~~ |
77
+ * | ~~`amr`~~ | ~~Authentication methods reference — list of methods used to authenticate~~ | ~~Not validated~~ |
78
+ * | ~~`scope`~~ | ~~OAuth 2.0 scopes granted to the token~~ | ~~Not validated (future: per-route scope enforcement)~~ |
79
+ *
80
+ * ---
81
+ *
82
+ * ## JWKS caching
83
+ *
84
+ * Public keys are expensive to fetch and import. They are cached in-process,
85
+ * keyed by `"${jwksUri}:${kid}"` (or `"${jwksUri}:__default__"` when `kid` is
86
+ * absent), for {@link JWKS_TTL_MS} milliseconds (default 5 minutes).
87
+ *
88
+ * Including the full JWKS URI in the cache key prevents a key imported for one
89
+ * issuer from being mistakenly served when a different issuer happens to use the
90
+ * same `kid` string — a scenario that can arise in multi-tenant deployments or
91
+ * during key-rotation incidents where two servers briefly share a key identifier.
92
+ *
93
+ * A cache miss — on first use or after TTL expiry — triggers a fresh fetch
94
+ * from `{issuerUrl}/auth/keys`.
95
+ *
96
+ * > **Note (serverless):** the cache is module-level. In serverless environments
97
+ * > each cold start gets a fresh cache; warm instances share it across requests.
98
+ *
99
+ * ---
100
+ *
101
+ * ## Runtime note
102
+ *
103
+ * This file is the **shared implementation** used by both `sdk-next` (Edge
104
+ * runtime) and `sdk-nuxt` (Node.js/Nitro). `base64UrlDecode` uses `atob`,
105
+ * which is available in both environments (Edge natively; Node.js since v16).
106
+ * The previous per-SDK copies (one using `atob`, one using `Buffer`) have
107
+ * been consolidated here.
108
+ */
109
+ /** How long a cached JWKS key is considered fresh before re-fetching. */
110
+ export declare const JWKS_TTL_MS: number;
111
+ /**
112
+ * The subset of standard JWT payload claims this module reads or validates.
113
+ *
114
+ * All fields are `readonly`. Additional custom claims are preserved under
115
+ * the index signature and accessible via `payload["my-claim"]`.
116
+ *
117
+ * Refer to the module-level documentation for the full verification matrix.
118
+ */
119
+ export interface JwtPayload {
120
+ /** Issuer (`iss`) — identifies the auth server that created the token. */
121
+ readonly iss?: string;
122
+ /** Subject (`sub`) — the user's unique identifier. */
123
+ readonly sub?: string;
124
+ /**
125
+ * Audience (`aud`) — the intended recipient(s).
126
+ * A single string or an array of strings per RFC 7519 §4.1.3.
127
+ */
128
+ readonly aud?: string | readonly string[];
129
+ /** Expiration time (`exp`) — seconds since Unix epoch. */
130
+ readonly exp?: number;
131
+ /** Not before (`nbf`) — seconds since Unix epoch. */
132
+ readonly nbf?: number;
133
+ /** Issued at (`iat`) — seconds since Unix epoch. */
134
+ readonly iat?: number;
135
+ /** User's email address (custom claim). */
136
+ readonly email?: string;
137
+ /** User's display name (custom claim). */
138
+ readonly name?: string;
139
+ readonly [key: string]: unknown;
140
+ }
141
+ /**
142
+ * The typed representation of a JWT header.
143
+ *
144
+ * The three fields below are the only ones this library reads. Additional
145
+ * header parameters are preserved under the index signature.
146
+ */
147
+ export interface JwtHeader {
148
+ /** Signing algorithm (`alg`) — e.g. `"RS256"`, `"ES256"`. */
149
+ readonly alg?: string;
150
+ /** Token type (`typ`) — e.g. `"JWT"`, `"at+JWT"`. */
151
+ readonly typ?: string;
152
+ /** Key ID (`kid`) — selects the matching public key from the JWKS. */
153
+ readonly kid?: string;
154
+ readonly [key: string]: unknown;
155
+ }
156
+ /**
157
+ * The decoded, unverified parts of a compact-serialised JWT.
158
+ *
159
+ * **Do not act on these values before signature verification.**
160
+ * This type is returned by {@link decodeJwt} purely to carry the
161
+ * raw data into the next step.
162
+ */
163
+ export interface DecodedJwt {
164
+ readonly header: JwtHeader;
165
+ readonly payload: JwtPayload;
166
+ }
167
+ /**
168
+ * Options for {@link verifyJwt}.
169
+ *
170
+ * All fields are `readonly` — this object is never mutated after construction.
171
+ */
172
+ export interface VerifyJwtOptions {
173
+ /**
174
+ * Base URL of the auth backend.
175
+ *
176
+ * Serves two purposes:
177
+ * 1. Determines the JWKS endpoint: `{issuerUrl}/auth/keys`
178
+ * 2. Is compared against the `iss` claim when present in the token.
179
+ */
180
+ readonly issuerUrl: string;
181
+ /**
182
+ * Restrict accepted `alg` header values. Tokens whose algorithm is not in
183
+ * this list are rejected before the JWKS is fetched.
184
+ * When `undefined`, all algorithms are accepted (the middleware layer
185
+ * defaults to `["RS256", "ES256"]` before passing options here).
186
+ */
187
+ readonly allowedAlgorithms?: readonly string[];
188
+ /**
189
+ * Clock-skew tolerance in milliseconds, applied symmetrically to `exp`,
190
+ * `nbf`, and `iat` checks to accommodate minor differences between clocks.
191
+ */
192
+ readonly clockSkewMs: number;
193
+ /**
194
+ * Expected `aud` claim value(s). When `undefined`, audience is not
195
+ * validated. Provide a string or array when the auth server sets `aud`
196
+ * and you want to ensure the token was issued specifically for your app.
197
+ */
198
+ readonly audience?: string | readonly string[];
199
+ /**
200
+ * Accepted `typ` header values (case-insensitive).
201
+ *
202
+ * Guards against using a refresh token or ID token where an access token
203
+ * is expected. Set to an empty array (`[]`) to disable this check.
204
+ *
205
+ * @default ["JWT", "at+JWT"]
206
+ */
207
+ readonly allowedTokenTypes: readonly string[];
208
+ /**
209
+ * Timeout in milliseconds for JWKS endpoint requests.
210
+ * Requests that do not complete within this window are aborted and the
211
+ * token is rejected (function returns `null`).
212
+ * @default 5000
213
+ */
214
+ readonly jwksTimeoutMs?: number;
215
+ }
216
+ /**
217
+ * Decodes a Base64URL-encoded string into a `Uint8Array`.
218
+ *
219
+ * The Edge runtime has no `Buffer`, so this uses `atob` after translating the
220
+ * Base64URL alphabet (`-` → `+`, `_` → `/`) and padding to a multiple of four.
221
+ *
222
+ * @param input - A Base64URL-encoded string (padding is optional).
223
+ * @returns The decoded bytes.
224
+ */
225
+ export declare function base64UrlDecode(input: string): Uint8Array<ArrayBuffer>;
226
+ /**
227
+ * Decodes a compact-serialised JWT into its header and payload **without**
228
+ * verifying the signature.
229
+ *
230
+ * **Do not trust the result of this function alone.** Use it only as the first
231
+ * step of a full verification pipeline — the signature check in {@link verifyJwt}
232
+ * must follow before any claim can be trusted.
233
+ *
234
+ * @param token - A compact JWT string (`header.payload.signature`).
235
+ * @returns The decoded {@link DecodedJwt}.
236
+ * @throws {TypeError} When `token` has fewer than three dot-separated segments.
237
+ */
238
+ export declare function decodeJwt(token: string): DecodedJwt;
239
+ /**
240
+ * Verifies a compact-serialised JWT and returns its validated payload.
241
+ *
242
+ * ## Verification steps (in order)
243
+ *
244
+ * 1. Split the token — returns `null` immediately when fewer than three
245
+ * dot-separated segments are present.
246
+ * 2. Reject if `alg` is not in {@link VerifyJwtOptions.allowedAlgorithms} (when set).
247
+ * 3. Reject if `typ` is not in {@link VerifyJwtOptions.allowedTokenTypes} (when non-empty).
248
+ * 4. Fetch (or retrieve from cache) the matching public key from the JWKS endpoint.
249
+ * 5. Verify the cryptographic signature over `header.payload`.
250
+ * 6. Reject if `iss` is absent or does not equal {@link VerifyJwtOptions.issuerUrl}.
251
+ * 7. Reject if {@link VerifyJwtOptions.audience} is set and `aud` does not contain it.
252
+ * 8. Reject if `exp` is absent or is in the past (minus clock-skew tolerance).
253
+ * 9. Reject if `nbf` is in the future (plus clock-skew tolerance).
254
+ * 10. Reject if `iat` is in the future (plus clock-skew tolerance).
255
+ *
256
+ * Returns `null` on any failure rather than throwing, so callers can treat a
257
+ * bad token identically to a missing one without try/catch at the call site.
258
+ *
259
+ * @param token - The raw compact-serialised JWT string.
260
+ * @param opts - Verification options; see {@link VerifyJwtOptions}.
261
+ * @returns The verified {@link JwtPayload}, or `null` if verification fails.
262
+ */
263
+ export declare function verifyJwt(token: string, opts: VerifyJwtOptions): Promise<JwtPayload | null>;
264
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../src/jwt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2GG;AAIH,yEAAyE;AACzE,eAAO,MAAM,WAAW,QAAiB,CAAC;AAI1C;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAC1C,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;CAC9B;AAYD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE/C;;;OAGG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAE/C;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;IAE9C;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AA8BD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAQtE;AA0BD;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAYnD;AAsHD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA6G5B"}
package/dist/jwt.js ADDED
@@ -0,0 +1,111 @@
1
+ //#region src/jwt.ts
2
+ var e = 300 * 1e3, t = /* @__PURE__ */ new Map(), n = new TextDecoder(), r = new TextEncoder();
3
+ function i(e) {
4
+ let t = e.replace(/-/g, "+").replace(/_/g, "/"), n = t.padEnd(t.length + (4 - t.length % 4) % 4, "="), r = atob(n);
5
+ return Uint8Array.from(r, (e) => e.charCodeAt(0));
6
+ }
7
+ function a(e) {
8
+ let [t, n, r] = e.split(".");
9
+ return !t || !n || !r ? null : [
10
+ t,
11
+ n,
12
+ r
13
+ ];
14
+ }
15
+ function o(e) {
16
+ let t = a(e);
17
+ if (!t) throw TypeError(`Invalid JWT: expected at least three dot-separated segments, received ${e.split(".").length}.`);
18
+ let [r, o] = t;
19
+ return {
20
+ header: JSON.parse(n.decode(i(r))),
21
+ payload: JSON.parse(n.decode(i(o)))
22
+ };
23
+ }
24
+ var s = {
25
+ RS256: {
26
+ name: "RSASSA-PKCS1-v1_5",
27
+ hash: "SHA-256"
28
+ },
29
+ RS384: {
30
+ name: "RSASSA-PKCS1-v1_5",
31
+ hash: "SHA-384"
32
+ },
33
+ RS512: {
34
+ name: "RSASSA-PKCS1-v1_5",
35
+ hash: "SHA-512"
36
+ },
37
+ ES256: {
38
+ name: "ECDSA",
39
+ namedCurve: "P-256"
40
+ },
41
+ ES384: {
42
+ name: "ECDSA",
43
+ namedCurve: "P-384"
44
+ },
45
+ ES512: {
46
+ name: "ECDSA",
47
+ namedCurve: "P-521"
48
+ }
49
+ }, c = {
50
+ RS256: { name: "RSASSA-PKCS1-v1_5" },
51
+ RS384: { name: "RSASSA-PKCS1-v1_5" },
52
+ RS512: { name: "RSASSA-PKCS1-v1_5" },
53
+ ES256: {
54
+ name: "ECDSA",
55
+ hash: "SHA-256"
56
+ },
57
+ ES384: {
58
+ name: "ECDSA",
59
+ hash: "SHA-384"
60
+ },
61
+ ES512: {
62
+ name: "ECDSA",
63
+ hash: "SHA-512"
64
+ }
65
+ };
66
+ function l(e) {
67
+ if (!Object.hasOwn(s, e)) throw TypeError(`Unsupported JWT algorithm: "${e}". Supported algorithms are ${Object.keys(s).join(", ")}.`);
68
+ }
69
+ function u(e) {
70
+ return l(e), s[e];
71
+ }
72
+ function d(e) {
73
+ return l(e), c[e];
74
+ }
75
+ async function f(e, n, r) {
76
+ let i = `${e}:${n ?? "__default__"}`, a = t.get(i);
77
+ if (a && Date.now() - a.fetchedAt < 3e5) return a.key;
78
+ let o = await fetch(e, { signal: AbortSignal.timeout(r) });
79
+ if (!o.ok) return null;
80
+ let s = await o.json(), c = n ? s.keys.find((e) => e.kid === n) : s.keys[0];
81
+ if (!c) return null;
82
+ let l = c.alg ?? "RS256", d = await crypto.subtle.importKey("jwk", c, u(l), !1, ["verify"]);
83
+ return t.set(i, {
84
+ key: d,
85
+ fetchedAt: Date.now()
86
+ }), d;
87
+ }
88
+ async function p(e, t) {
89
+ try {
90
+ let { issuerUrl: o, allowedAlgorithms: s, clockSkewMs: c, audience: l, allowedTokenTypes: u, jwksTimeoutMs: p = 5e3 } = t, m = a(e);
91
+ if (!m) return null;
92
+ let [h, g, _] = m, v = JSON.parse(n.decode(i(h))), y = JSON.parse(n.decode(i(g))), b = v.alg;
93
+ if (!b || b.toLowerCase() === "none" || s?.length && !s.includes(b)) return null;
94
+ if (u.length > 0) {
95
+ let e = v.typ ?? "";
96
+ if (!u.some((t) => t.toLowerCase() === e.toLowerCase())) return null;
97
+ }
98
+ let x = v.kid, S = await f(`${o}/auth/keys`, x, p);
99
+ if (!S || !await crypto.subtle.verify(d(b), S, i(_), r.encode(`${h}.${g}`)) || y.iss !== o) return null;
100
+ if (l !== void 0) {
101
+ let e = y.aud === void 0 ? [] : [y.aud].flat();
102
+ if (![l].flat().some((t) => e.includes(t))) return null;
103
+ }
104
+ let C = Date.now();
105
+ return y.exp === void 0 || y.exp * 1e3 < C - c || y.nbf !== void 0 && y.nbf * 1e3 > C + c || y.iat !== void 0 && y.iat * 1e3 > C + c ? null : y;
106
+ } catch (e) {
107
+ return console.error("[nextgen] verifyJwt unexpected error:", e), null;
108
+ }
109
+ }
110
+ //#endregion
111
+ export { e as JWKS_TTL_MS, i as base64UrlDecode, o as decodeJwt, p as verifyJwt };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Shared constants and utility functions for the SDK middleware proxy layer.
3
+ *
4
+ * These are consumed by both `sdk-next` and `sdk-nuxt` to avoid duplicating
5
+ * pure, framework-agnostic logic.
6
+ */
7
+ /**
8
+ * Headers that must never be forwarded to an upstream service.
9
+ * These are connection-level headers that are meaningful only between
10
+ * two directly connected peers and become invalid when proxied.
11
+ */
12
+ export declare const HOP_BY_HOP: ReadonlySet<string>;
13
+ /**
14
+ * SDK-internal headers that must never be forwarded to the upstream backend.
15
+ * These headers carry session data between the middleware and server components;
16
+ * forwarding them upstream would expose internal state and allow header injection.
17
+ */
18
+ export declare const INTERNAL_HEADERS: ReadonlySet<string>;
19
+ /**
20
+ * Returns `true` when `pathname` matches at least one entry in `routes`.
21
+ *
22
+ * An entry ending with `*` matches any path that starts with the prefix
23
+ * before the `*`. All other entries require an exact match.
24
+ *
25
+ * @param pathname - The URL pathname to test.
26
+ * @param routes - The list of route patterns to match against.
27
+ * @returns `true` if at least one pattern matches.
28
+ */
29
+ export declare function matchesRoutes(pathname: string, routes: readonly string[]): boolean;
30
+ /**
31
+ * Filters upstream response headers for proxying: strips hop-by-hop headers,
32
+ * `set-cookie` (handled separately via `getSetCookie()`), and `location`
33
+ * (prevents leaking internal upstream URLs).
34
+ *
35
+ * @param upstream - The upstream response headers.
36
+ * @returns A new `Headers` object with filtered headers.
37
+ */
38
+ export declare function filterResponseHeaders(upstream: Headers): Headers;
39
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CAazC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAE/C,CAAC;AAKH;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAUT;AAID;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,CAYhE"}
@@ -0,0 +1,22 @@
1
+ //#region src/middleware.ts
2
+ var e = new Set([
3
+ "connection",
4
+ "host",
5
+ "keep-alive",
6
+ "proxy-authenticate",
7
+ "proxy-authorization",
8
+ "te",
9
+ "trailer",
10
+ "transfer-encoding",
11
+ "upgrade"
12
+ ]), t = new Set(["x-nextgen-auth-token"]);
13
+ function n(e, t) {
14
+ return t.length === 0 ? !1 : t.some((t) => t.endsWith("*") ? e.startsWith(t.slice(0, -1)) : e === t);
15
+ }
16
+ function r(t) {
17
+ let n = new Headers();
18
+ for (let [r, i] of t.entries()) !e.has(r.toLowerCase()) && r.toLowerCase() !== "set-cookie" && r.toLowerCase() !== "location" && n.set(r, i);
19
+ return n;
20
+ }
21
+ //#endregion
22
+ export { e as HOP_BY_HOP, t as INTERNAL_HEADERS, r as filterResponseHeaders, n as matchesRoutes };
@@ -0,0 +1 @@
1
+ {"version":"7.0.0-dev.20260421.2","root":[[60,63]],"fileNames":["lib.es5.d.ts","lib.es2015.d.ts","lib.es2016.d.ts","lib.es2017.d.ts","lib.es2018.d.ts","lib.es2019.d.ts","lib.es2020.d.ts","lib.es2021.d.ts","lib.es2022.d.ts","lib.dom.d.ts","lib.dom.iterable.d.ts","lib.es2015.core.d.ts","lib.es2015.collection.d.ts","lib.es2015.generator.d.ts","lib.es2015.iterable.d.ts","lib.es2015.promise.d.ts","lib.es2015.proxy.d.ts","lib.es2015.reflect.d.ts","lib.es2015.symbol.d.ts","lib.es2015.symbol.wellknown.d.ts","lib.es2016.array.include.d.ts","lib.es2016.intl.d.ts","lib.es2017.arraybuffer.d.ts","lib.es2017.date.d.ts","lib.es2017.object.d.ts","lib.es2017.sharedmemory.d.ts","lib.es2017.string.d.ts","lib.es2017.intl.d.ts","lib.es2017.typedarrays.d.ts","lib.es2018.asyncgenerator.d.ts","lib.es2018.asynciterable.d.ts","lib.es2018.intl.d.ts","lib.es2018.promise.d.ts","lib.es2018.regexp.d.ts","lib.es2019.array.d.ts","lib.es2019.object.d.ts","lib.es2019.string.d.ts","lib.es2019.symbol.d.ts","lib.es2019.intl.d.ts","lib.es2020.bigint.d.ts","lib.es2020.date.d.ts","lib.es2020.promise.d.ts","lib.es2020.sharedmemory.d.ts","lib.es2020.string.d.ts","lib.es2020.symbol.wellknown.d.ts","lib.es2020.intl.d.ts","lib.es2020.number.d.ts","lib.es2021.promise.d.ts","lib.es2021.string.d.ts","lib.es2021.weakref.d.ts","lib.es2021.intl.d.ts","lib.es2022.array.d.ts","lib.es2022.error.d.ts","lib.es2022.intl.d.ts","lib.es2022.object.d.ts","lib.es2022.string.d.ts","lib.es2022.regexp.d.ts","lib.decorators.d.ts","lib.decorators.legacy.d.ts","../src/types.ts","../src/middleware.ts","../src/jwt.ts","../src/index.ts"],"fileInfos":[{"version":"a1aa1a5e065d48ef5c7bb99e38412f96","affectsGlobalScope":true,"impliedNodeFormat":1},"d4306fb2e47f74835e8674ffac07d76f","e437c5c1302869326c3bb93da85bbbcf","e4324975a566567b21d350615f1fc6ac","333b1b9a2a9ac3b8497dba5c63b5ba50","6cffacd662b6eb5fa7a36aa2ea366bfa","b4c34f9c23304dbef2d23698637ed638","e5cb86a5fc491796ecd1d2dd348d208f","feb6c6fb19cdb246a5d8acb36a6901c7",{"version":"aae8996e8b5684814785a42cbbefcd79","affectsGlobalScope":true,"impliedNodeFormat":1},"abad6dd56cc8caf095c165df8124d237",{"version":"01ac052ec4a79e87229f90466a9645f8","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"edba5df642941aa062a62f6328c6df3d","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"6344b55f26a4e81d9608777dbfb877dd","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"3c0ed28e53d3695b363e256ec1c023fd","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4c2761daba7f17141c25baa0821ac5da","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b87656acabd63e69379ff6ffcfe52fc7","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"597469522da047a5af5222cc6989f405","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"bb3a710cbcda0533bb127712927cbe37","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"55d97a8c6fbf34a30450a7b1e5f7a298","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"0ee05eb59426d33e374226d8dcfa708b","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"e347c14030993906efcfbb88915b6a05","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b0231263857c9b6a03641acdc9280ceb","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"3b15c4a83b598cacb4067676e6f0abed","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b417d97b7934cef63b1889abec0bbfbf","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"09a6cf4032ebba60ce22a501e663f881","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"7a42de379b489e8f7b647455bebfc576","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"e22cc07e3f3cc242ba52fa3f8ea1fc58","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"2c45da767a1bfbb220848df1bc4029e4","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b44c3e0fbaf2130cdcf6ac38b120ffa1","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b612fb5cf8e5d964b92063a75207632a","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"02705151a5e1551b9162a9ed8ab763f7","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"41025e398be9215d32e4337335da8f0b","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"52684c2b1f353a5538e4f275182a54cd","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"6dedb6a4f90d1df3a6fbe5693e44886c","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"ca3f36fe3562c07e0f0d71c2bebd3f6d","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"409974d6129befbb8226ddd1c6558568","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4d9cfde2a1ae1b4925f1f9bc10848e5d","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"7e1daecc66dd564144e3bb1a0266b5fd","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"a8e1d9bb35fd0637f2f9fd2b2a54f2ec","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4f168501772a6543182765bfd5f2fbfe","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"a19c80aad1b2162103496f5ba293a732","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"b69afa63cd5d059851c78adb2856ee09","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"ae2fc5d954e9b0f5feee3d481b953c27","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"1cfd3091a071d8b6feec15277643bafe","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"692bcd75364db0f65d428801c7884466","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"a0d87491913d843139e0c993650a3235","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4ef72aa378127e7b7abba915b0110b1e","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"3ec74c6a7d4463f0254db3a74cf75646","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"84c2bdfa470d075526cce6322d81b0b6","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"0b3844c2b8c73e4e1ab91431411cad11","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4fc71cf4a15b8d99675a31df77f26e07","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"d1b49564ddaeca3df5b6dbae925d2242","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"6a25be566d60ccfc2d6e8b7bfdeefa83","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"8a20e27646985dfd58c57ca6566553dd","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"9969f02ad3cdcbf4f709405cda44167f","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"9c9be4792a7a4f42c15ae7360bf28779","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"f64453cbf9671f28158677fa5c43967a","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"33f317af5428801f944a478d2c1e38e5","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"15066bf16fe04ec6d0316cdf19792ac6","signature":"115cce73bdd0821315dbb80c30b72867","impliedNodeFormat":99},{"version":"0ef9f01c1bd1aa2651b01c95d2939eeb","signature":"4395702c4db54aa3eb7c9e41e69dc921","impliedNodeFormat":99},{"version":"f3487fd2342ffcd57a681a7e2830440f","signature":"d7f410111bbbc4f358dcc07db3151877","impliedNodeFormat":99},{"version":"5beb6125d20dbc2c73e35a96973e834a","signature":"0528ac935bfd6a3063a9bfad4cbee925","impliedNodeFormat":99}],"fileIdsList":[[60,61,62]],"options":{"composite":true,"emitDeclarationOnly":true,"declarationMap":true,"importHelpers":true,"module":199,"noFallthroughCasesInSwitch":true,"noImplicitReturns":true,"noUncheckedIndexedAccess":true,"noEmitOnError":true,"noUnusedLocals":true,"noImplicitOverride":true,"outDir":"./","rootDir":"../src","skipLibCheck":true,"strict":true,"target":9,"tsBuildInfoFile":"./tsconfig.lib.tsbuildinfo"},"referencedMap":[[63,1]],"latestChangedDtsFile":"./index.d.ts"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Shared types for the Nextgen SDK middleware layer.
3
+ *
4
+ * These types are consumed by both `sdk-next` and `sdk-nuxt`. Each SDK
5
+ * re-exports them from its own public surface so consumers don't need
6
+ * to add a direct `sdk-core` dependency.
7
+ */
8
+ /**
9
+ * The authenticated session for a signed-in user.
10
+ */
11
+ export type NextgenSession = {
12
+ /** The user's unique identifier (`sub` claim). */
13
+ userId: string;
14
+ /** The user's email address, or `null` if not present in the token. */
15
+ email: string | null;
16
+ /** The user's display name, or `null` if not present in the token. */
17
+ name: string | null;
18
+ /** The raw verified JWT. */
19
+ token: string;
20
+ };
21
+ /** Auth state when the user is signed in. */
22
+ export type AuthState = {
23
+ isAuthenticated: true;
24
+ session: NextgenSession;
25
+ };
26
+ /** Auth state when the user is not signed in. */
27
+ export type UnauthState = {
28
+ isAuthenticated: false;
29
+ session: null;
30
+ };
31
+ /** Union of all possible auth states. */
32
+ export type AuthResult = AuthState | UnauthState;
33
+ /**
34
+ * Options passed to the SDK middleware factory (`nextgenMiddleware` in
35
+ * sdk-next, `createNextgenMiddleware` in sdk-nuxt).
36
+ */
37
+ export type NextgenMiddlewareOptions = {
38
+ /**
39
+ * Full URL of the Zitadel auth backend.
40
+ * @default process.env.ZITADEL_URL ?? "http://localhost:8080"
41
+ */
42
+ url?: string;
43
+ /**
44
+ * URL path prefix that is reverse-proxied to the auth backend.
45
+ * @default "/__nextgen"
46
+ */
47
+ proxyPath?: string;
48
+ /**
49
+ * Pathnames that require a valid session. Requests to these routes without
50
+ * a valid token are redirected to {@link loginPath}.
51
+ * Entries ending with `*` match any sub-path (e.g. `"/admin*"`).
52
+ * @default []
53
+ */
54
+ protectedRoutes?: string[];
55
+ /**
56
+ * Pathnames that are completely skipped by the middleware — no JWT
57
+ * verification, no protection check, no header tunnelling.
58
+ * Useful for webhooks, health-check endpoints, or any route where
59
+ * running auth logic is undesirable.
60
+ * Entries ending with `*` match any sub-path (e.g. `"/public*"`).
61
+ * @default []
62
+ */
63
+ ignoredRoutes?: string[];
64
+ /**
65
+ * Pathname to redirect unauthenticated users to.
66
+ * A `next` query parameter is appended with the originally requested path.
67
+ * @default "/login"
68
+ */
69
+ loginPath?: string;
70
+ /**
71
+ * Reserved for future use. Local PEM public key for offline JWT verification.
72
+ */
73
+ jwtKey?: string;
74
+ /**
75
+ * Restrict accepted JWT `alg` header values. Tokens whose algorithm is not
76
+ * in this list are rejected before JWKS is fetched.
77
+ * @default ["RS256", "ES256"]
78
+ */
79
+ allowedAlgorithms?: string[];
80
+ /**
81
+ * Clock skew tolerance in milliseconds applied to `exp`, `nbf`, and `iat`
82
+ * claim validation.
83
+ * @default 5000
84
+ */
85
+ clockSkewMs?: number;
86
+ /**
87
+ * Expected value(s) of the `aud` claim. When omitted, audience is not
88
+ * validated. Pass a single string or an array when a token may carry
89
+ * multiple audiences.
90
+ */
91
+ audience?: string | string[];
92
+ /**
93
+ * Accepted values for the JWT header `typ` claim (case-insensitive).
94
+ * Tokens whose `typ` is not in this list are rejected.
95
+ * Set to `[]` to disable token-type checking entirely.
96
+ * @default ["JWT", "at+JWT"]
97
+ */
98
+ allowedTokenTypes?: string[];
99
+ /**
100
+ * Timeout in milliseconds for JWKS endpoint requests.
101
+ * Requests that do not complete within this window are aborted and the
102
+ * token is rejected, treating the request as unauthenticated.
103
+ * @default 5000
104
+ */
105
+ jwksTimeoutMs?: number;
106
+ /**
107
+ * Timeout in milliseconds for upstream proxy requests.
108
+ * Requests that do not complete within this window are aborted with a
109
+ * network error. Defaults to 5 000 ms.
110
+ * @default 5000
111
+ */
112
+ proxyTimeoutMs?: number;
113
+ /**
114
+ * Optional hook called when a `POST /sessions/exchange` response is
115
+ * proxied back to the browser. Receives the upstream `Response` after
116
+ * hop-by-hop stripping and cookie upgrading. Return a modified
117
+ * `Response` to add custom headers, extra `Set-Cookie` values, or
118
+ * transform the body.
119
+ *
120
+ * The callback runs on the server — it has access to the full response
121
+ * including `Set-Cookie` headers that are `HttpOnly` and invisible to
122
+ * client-side JavaScript. It fires **after** the upstream has processed
123
+ * the exchange; it cannot prevent the exchange itself (return a 403
124
+ * `Response` to block the browser from receiving it).
125
+ *
126
+ * **Capabilities:**
127
+ *
128
+ * - **Add or modify cookies** — append `Set-Cookie` headers for
129
+ * user-preferences, analytics IDs, or any server-side state.
130
+ * - **Make additional fetch calls** — enrich the session by calling
131
+ * your own backend, a profile service, or any external API. The
132
+ * response body can be read with `response.json()` to extract
133
+ * session details like `user_id`.
134
+ * - **Map or transform response properties** — reshape the JSON body
135
+ * before it reaches the browser (e.g. strip internal fields, add
136
+ * computed properties).
137
+ * - **Logging and auditing** — clone the response, read its body for
138
+ * audit trails, and return the original unchanged.
139
+ *
140
+ * @example Add a cookie
141
+ * ```ts
142
+ * onExchangeResponse: async (response) => {
143
+ * const headers = new Headers(response.headers);
144
+ * headers.append("Set-Cookie", "theme=dark; Path=/; SameSite=Lax");
145
+ * return new Response(response.body, {
146
+ * status: response.status,
147
+ * headers,
148
+ * });
149
+ * },
150
+ * ```
151
+ *
152
+ * @example Fetch additional data and set a cookie from it
153
+ * ```ts
154
+ * onExchangeResponse: async (response) => {
155
+ * const body = await response.json();
156
+ * const profile = await fetch(
157
+ * `https://api.example.com/users/${body.session.user_id}`,
158
+ * );
159
+ * const { locale } = await profile.json();
160
+ * const headers = new Headers(response.headers);
161
+ * headers.append("Set-Cookie", `locale=${locale}; Path=/; SameSite=Lax`);
162
+ * return new Response(JSON.stringify(body), {
163
+ * status: response.status,
164
+ * headers,
165
+ * });
166
+ * },
167
+ * ```
168
+ *
169
+ * @example Log the exchange for auditing (pass-through)
170
+ * ```ts
171
+ * onExchangeResponse: async (response) => {
172
+ * const cloned = response.clone();
173
+ * const body = await cloned.json();
174
+ * await auditLog.record("session_exchange", body.session.session_id);
175
+ * return response;
176
+ * },
177
+ * ```
178
+ *
179
+ * @example Modify existing cookies (e.g. tighten the session cookie path)
180
+ * ```ts
181
+ * onExchangeResponse: async (response) => {
182
+ * const headers = new Headers();
183
+ * for (const [key, value] of response.headers.entries()) {
184
+ * if (key.toLowerCase() !== "set-cookie") headers.set(key, value);
185
+ * }
186
+ * for (const cookie of response.headers.getSetCookie()) {
187
+ * if (cookie.startsWith("__nextgen_session=")) {
188
+ * headers.append("set-cookie", cookie.replace("Path=/", "Path=/app"));
189
+ * } else {
190
+ * headers.append("set-cookie", cookie);
191
+ * }
192
+ * }
193
+ * return new Response(response.body, { status: response.status, headers });
194
+ * },
195
+ * ```
196
+ */
197
+ onExchangeResponse?: (response: Response) => Response | Promise<Response>;
198
+ };
199
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,sEAAsE;IACtE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,6CAA6C;AAC7C,MAAM,MAAM,SAAS,GAAG;IAAE,eAAe,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC;AAE3E,iDAAiD;AACjD,MAAM,MAAM,WAAW,GAAG;IAAE,eAAe,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,IAAI,CAAA;CAAE,CAAC;AAEpE,yCAAyC;AACzC,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE7B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmFG;IACH,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC3E,CAAC"}
package/dist/types.js ADDED
File without changes
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@zitadel/sdk-core",
3
+ "version": "0.0.0",
4
+ "description": "Core types and shared utilities for Zitadel SDKs",
5
+ "homepage": "https://github.com/zitadel/nextgen/tree/main/packages/sdk-core#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/zitadel/nextgen/issues"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/zitadel/nextgen.git",
13
+ "directory": "packages/sdk-core"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "type": "module",
19
+ "exports": {
20
+ ".": {
21
+ "@zitadel/source": "./src/index.ts",
22
+ "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js"
24
+ },
25
+ "./types": {
26
+ "@zitadel/source": "./src/types.ts",
27
+ "types": "./dist/types.d.ts",
28
+ "import": "./dist/types.js"
29
+ },
30
+ "./jwt": {
31
+ "@zitadel/source": "./src/jwt.ts",
32
+ "types": "./dist/jwt.d.ts",
33
+ "import": "./dist/jwt.js"
34
+ },
35
+ "./middleware": {
36
+ "@zitadel/source": "./src/middleware.ts",
37
+ "types": "./dist/middleware.d.ts",
38
+ "import": "./dist/middleware.js"
39
+ }
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ }
44
+ }