@cloudflare/workers-oauth-provider 0.6.0 → 0.7.1
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/README.md +41 -0
- package/dist/oauth-provider.d.ts +341 -3
- package/dist/oauth-provider.js +1071 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,6 +117,10 @@ export default new OAuthProvider({
|
|
|
117
117
|
// Defaults to false.
|
|
118
118
|
allowTokenExchangeGrant: false,
|
|
119
119
|
|
|
120
|
+
// Optional: Experimental MCP Enterprise-Managed Authorization support.
|
|
121
|
+
// When enabled, the token endpoint accepts ID-JAG JWTs with the JWT bearer grant.
|
|
122
|
+
enterpriseManagedAuthorization: undefined,
|
|
123
|
+
|
|
120
124
|
// Optional: Explicitly enable Client ID Metadata Document (CIMD) support.
|
|
121
125
|
// When true, URL-formatted client_ids will be fetched as metadata documents.
|
|
122
126
|
// Requires the 'global_fetch_strictly_public' compatibility flag.
|
|
@@ -352,6 +356,42 @@ async function refreshUpstream(props) {
|
|
|
352
356
|
|
|
353
357
|
Only `OAuthError` from this package is converted into a structured `/token` response. Plain errors, plain objects with a `code` field, and app-local error classes continue to surface as 500s so unexpected failures stay visible. Import `OAuthError` from `@cloudflare/workers-oauth-provider` rather than copying or re-implementing it.
|
|
354
358
|
|
|
359
|
+
## Enterprise-Managed Authorization (Experimental)
|
|
360
|
+
|
|
361
|
+
Accepts ID-JAG assertions at `/token` per the [MCP Enterprise-Managed Authorization extension](https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization). The enterprise IdP issues an ID-JAG JWT and the MCP client exchanges it here for an opaque access token.
|
|
362
|
+
|
|
363
|
+
```ts
|
|
364
|
+
new OAuthProvider({
|
|
365
|
+
// ... other options ...
|
|
366
|
+
resourceMetadata: { resource: 'https://mcp.example.com/mcp' },
|
|
367
|
+
enterpriseManagedAuthorization: {
|
|
368
|
+
trustedIssuers: async ({ iss }) =>
|
|
369
|
+
iss === 'https://idp.example.com'
|
|
370
|
+
? { issuer: iss, jwksUri: 'https://idp.example.com/.well-known/jwks.json', algorithms: ['RS256'] }
|
|
371
|
+
: null,
|
|
372
|
+
async mapClaims({ claims, requestedScope }) {
|
|
373
|
+
return {
|
|
374
|
+
// Opaque tokens use ':' as a separator — encode subjects that may contain it.
|
|
375
|
+
userId: `enterprise-${claims.sub}`,
|
|
376
|
+
scope: requestedScope,
|
|
377
|
+
metadata: { enterpriseIssuer: claims.iss, enterpriseSubject: claims.sub },
|
|
378
|
+
props: { enterprise: true, subject: claims.sub, email: claims.email },
|
|
379
|
+
};
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
Setup:
|
|
386
|
+
|
|
387
|
+
1. Configure your IdP as an ID-JAG issuer with this worker's origin as the resource and a public JWKS endpoint.
|
|
388
|
+
2. Set `resourceMetadata.resource` to the MCP endpoint URL (required when EMA is enabled).
|
|
389
|
+
3. Implement `trustedIssuers` as a resolver — for multi-tenant deployments it can read `env` / `clientInfo` to look up per-tenant IdP config without redeploying.
|
|
390
|
+
|
|
391
|
+
The AS enforces `resolved.issuer === iss` (confused-deputy guard) and validates ID-JAG `typ`, signature, audience, client binding, resource, `exp` / `iat` / `nbf`, max lifetime, and `jti` replay. Refresh tokens are not issued for this grant — the ID-JAG itself is the renewable assertion.
|
|
392
|
+
|
|
393
|
+
Experimental — the MCP extension is still a draft.
|
|
394
|
+
|
|
355
395
|
## Custom Error Responses
|
|
356
396
|
|
|
357
397
|
By using the `onError` option, you can emit notifications or take other actions when an error response was to be emitted:
|
|
@@ -434,6 +474,7 @@ This library implements the following OAuth and MCP specifications:
|
|
|
434
474
|
- [OAuth 2.0 Protected Resource Metadata (RFC 9728)](https://datatracker.ietf.org/doc/html/rfc9728) — `/.well-known/oauth-protected-resource` discovery endpoint
|
|
435
475
|
- [OAuth 2.0 Dynamic Client Registration (RFC 7591)](https://datatracker.ietf.org/doc/html/rfc7591) — Dynamic client registration endpoint
|
|
436
476
|
- [OAuth Client ID Metadata Documents (draft-ietf-oauth-client-id-metadata-document)](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document) — HTTPS URLs as client IDs
|
|
477
|
+
- [MCP Enterprise-Managed Authorization extension](https://modelcontextprotocol.io/extensions/auth/enterprise-managed-authorization) — experimental ID-JAG JWT bearer grant support
|
|
437
478
|
|
|
438
479
|
These are the specifications required by the [MCP authorization specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization).
|
|
439
480
|
|
package/dist/oauth-provider.d.ts
CHANGED
|
@@ -1,7 +1,277 @@
|
|
|
1
1
|
import { WorkerEntrypoint } from "cloudflare:workers";
|
|
2
2
|
|
|
3
|
-
//#region src/
|
|
3
|
+
//#region src/ema/result.d.ts
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Tagged union of every validation failure that can occur on the EMA token
|
|
7
|
+
* endpoint path. Extend by adding a new arm; the exhaustive `switch` in
|
|
8
|
+
* `emaErrorToWire` will surface unhandled cases at compile time.
|
|
9
|
+
*/
|
|
10
|
+
type EmaValidationError = {
|
|
11
|
+
reason: 'assertion_missing';
|
|
12
|
+
} | {
|
|
13
|
+
reason: 'assertion_too_large';
|
|
14
|
+
size: number;
|
|
15
|
+
max: number;
|
|
16
|
+
} | {
|
|
17
|
+
reason: 'assertion_malformed';
|
|
18
|
+
} | {
|
|
19
|
+
reason: 'invalid_typ';
|
|
20
|
+
got?: unknown;
|
|
21
|
+
} | {
|
|
22
|
+
reason: 'invalid_alg';
|
|
23
|
+
got?: unknown;
|
|
24
|
+
} | {
|
|
25
|
+
reason: 'issuer_not_trusted';
|
|
26
|
+
iss: string;
|
|
27
|
+
} | {
|
|
28
|
+
reason: 'no_matching_key';
|
|
29
|
+
kid?: string;
|
|
30
|
+
} | {
|
|
31
|
+
reason: 'signature_failed';
|
|
32
|
+
} | {
|
|
33
|
+
reason: 'jwks_fetch_failed';
|
|
34
|
+
status?: number;
|
|
35
|
+
} | {
|
|
36
|
+
reason: 'invalid_claim';
|
|
37
|
+
claim: string;
|
|
38
|
+
} | {
|
|
39
|
+
reason: 'aud_mismatch';
|
|
40
|
+
expected: string;
|
|
41
|
+
got: string | string[];
|
|
42
|
+
} | {
|
|
43
|
+
reason: 'expired';
|
|
44
|
+
exp: number;
|
|
45
|
+
now: number;
|
|
46
|
+
} | {
|
|
47
|
+
reason: 'iat_in_future';
|
|
48
|
+
iat: number;
|
|
49
|
+
now: number;
|
|
50
|
+
skew: number;
|
|
51
|
+
} | {
|
|
52
|
+
reason: 'nbf_in_future';
|
|
53
|
+
nbf: number;
|
|
54
|
+
now: number;
|
|
55
|
+
skew: number;
|
|
56
|
+
} | {
|
|
57
|
+
reason: 'lifetime_too_long';
|
|
58
|
+
lifetime: number;
|
|
59
|
+
max: number;
|
|
60
|
+
} | {
|
|
61
|
+
reason: 'replayed';
|
|
62
|
+
jti: string;
|
|
63
|
+
} | {
|
|
64
|
+
reason: 'client_id_mismatch';
|
|
65
|
+
expected: string;
|
|
66
|
+
got: string;
|
|
67
|
+
} | {
|
|
68
|
+
reason: 'resource_invalid';
|
|
69
|
+
resource: string;
|
|
70
|
+
} | {
|
|
71
|
+
reason: 'resource_mismatch';
|
|
72
|
+
expected: string;
|
|
73
|
+
got: string;
|
|
74
|
+
} | {
|
|
75
|
+
reason: 'invalid_scope_param';
|
|
76
|
+
} | {
|
|
77
|
+
reason: 'invalid_mapped_user';
|
|
78
|
+
} | {
|
|
79
|
+
reason: 'invalid_mapped_scope';
|
|
80
|
+
} | {
|
|
81
|
+
reason: 'invalid_mapped_props';
|
|
82
|
+
} | {
|
|
83
|
+
reason: 'invalid_mapped_ttl';
|
|
84
|
+
} | {
|
|
85
|
+
reason: 'mapper_denied';
|
|
86
|
+
} | {
|
|
87
|
+
reason: 'mapper_threw';
|
|
88
|
+
} | {
|
|
89
|
+
reason: 'assertion_expired_after_processing';
|
|
90
|
+
};
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/ema/types.d.ts
|
|
93
|
+
/**
|
|
94
|
+
* Claims expected in an MCP Enterprise-Managed Authorization ID-JAG assertion.
|
|
95
|
+
* Additional issuer-specific claims (e.g. `email`) are preserved verbatim
|
|
96
|
+
* under the index signature.
|
|
97
|
+
*/
|
|
98
|
+
interface EmaIdJagClaims {
|
|
99
|
+
/** Identity provider issuer URL. */
|
|
100
|
+
iss: string;
|
|
101
|
+
/** Enterprise subject identifier for the resource owner. */
|
|
102
|
+
sub: string;
|
|
103
|
+
/** Authorization server issuer URL or URLs for which this assertion is intended. */
|
|
104
|
+
aud: string | string[];
|
|
105
|
+
/** RFC 9728 resource identifier of the MCP server. */
|
|
106
|
+
resource: string;
|
|
107
|
+
/** OAuth client identifier this assertion was issued to. */
|
|
108
|
+
client_id: string;
|
|
109
|
+
/** Unique assertion identifier used for replay protection. */
|
|
110
|
+
jti: string;
|
|
111
|
+
/** Assertion expiration time as a Unix timestamp in seconds. */
|
|
112
|
+
exp: number;
|
|
113
|
+
/** Assertion issued-at time as a Unix timestamp in seconds. */
|
|
114
|
+
iat: number;
|
|
115
|
+
/** Optional space-separated OAuth scope string. */
|
|
116
|
+
scope?: string;
|
|
117
|
+
/** Optional email claim supplied by the enterprise IdP. */
|
|
118
|
+
email?: string;
|
|
119
|
+
/** Additional enterprise IdP claims. */
|
|
120
|
+
[claim: string]: unknown;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Trusted enterprise IdP configuration for ID-JAG validation.
|
|
124
|
+
*/
|
|
125
|
+
interface EmaTrustedIssuer {
|
|
126
|
+
/** Issuer URL that must exactly match the assertion `iss` claim. */
|
|
127
|
+
issuer: string;
|
|
128
|
+
/** HTTPS JWKS endpoint used to validate assertion signatures. */
|
|
129
|
+
jwksUri: string;
|
|
130
|
+
/** Allowed JWT signing algorithms for this issuer. Defaults to `['RS256']`. */
|
|
131
|
+
algorithms?: string[];
|
|
132
|
+
/** Expected authorization server audience. Defaults to this provider's issuer URL. */
|
|
133
|
+
audience?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Input passed to `enterpriseManagedAuthorization.mapClaims` after ID-JAG validation.
|
|
137
|
+
*/
|
|
138
|
+
interface EmaClaimsMapperInput<Env = Cloudflare.Env> {
|
|
139
|
+
/** Validated ID-JAG claims. */
|
|
140
|
+
claims: EmaIdJagClaims;
|
|
141
|
+
/** Authenticated OAuth client that presented the assertion. */
|
|
142
|
+
clientInfo: ClientInfo;
|
|
143
|
+
/** Validated MCP resource identifier from the assertion. */
|
|
144
|
+
resource: string;
|
|
145
|
+
/** Requested scopes after downscoping to the assertion's scope claim, if present. */
|
|
146
|
+
requestedScope: string[];
|
|
147
|
+
/** The original HTTP token request, e.g. for inspecting Host header in multi-tenant routing. */
|
|
148
|
+
request: Request;
|
|
149
|
+
/** Cloudflare Worker environment variables. */
|
|
150
|
+
env: Env;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Result returned by `enterpriseManagedAuthorization.mapClaims`.
|
|
154
|
+
*/
|
|
155
|
+
interface EmaClaimsMapperResult {
|
|
156
|
+
/**
|
|
157
|
+
* User ID to associate with the issued grant and access token.
|
|
158
|
+
*
|
|
159
|
+
* Must not contain `:` — the opaque access token format issued by this
|
|
160
|
+
* provider uses `:` as an internal separator, so a `userId` containing
|
|
161
|
+
* it will produce tokens that fail to parse on validation. If the IdP
|
|
162
|
+
* subject may contain `:` (e.g. an email), encode or hash it first
|
|
163
|
+
* (e.g. ``userId: `enterprise-${encodeURIComponent(claims.sub)}` ``).
|
|
164
|
+
*/
|
|
165
|
+
userId: string;
|
|
166
|
+
/** Scopes to grant to the issued access token. */
|
|
167
|
+
scope: string[];
|
|
168
|
+
/**
|
|
169
|
+
* Optional grant metadata used for audit and grant listing. This is not
|
|
170
|
+
* encrypted. Stored on the grant in KV alongside the user ID — visible to
|
|
171
|
+
* server-side code via `OAuthHelpers` but never exposed to the MCP client.
|
|
172
|
+
* Use for audit logs, admin UIs, or "list active sessions" features.
|
|
173
|
+
*/
|
|
174
|
+
metadata?: unknown;
|
|
175
|
+
/**
|
|
176
|
+
* Application props encrypted into the issued access token and exposed to
|
|
177
|
+
* API handlers on every authenticated request (via `getMcpAuthContext()`
|
|
178
|
+
* for MCP servers, or `ctx.props` in the underlying OAuth helpers). Use
|
|
179
|
+
* for per-request data the protected resource needs without hitting the
|
|
180
|
+
* IdP again — e.g. `enterprise: true`, subject, email, role claims.
|
|
181
|
+
*/
|
|
182
|
+
props: unknown;
|
|
183
|
+
/**
|
|
184
|
+
* Optional access token TTL override in seconds. Overrides the AS's
|
|
185
|
+
* configured default. Not clamped to the assertion lifetime — the ID-JAG
|
|
186
|
+
* `exp` governs how long the assertion remains a usable grant, not the
|
|
187
|
+
* lifetime of the access token it mints (RFC 7523 §3).
|
|
188
|
+
*/
|
|
189
|
+
accessTokenTTL?: number;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Maps validated enterprise ID-JAG claims to this provider's local user, scopes,
|
|
193
|
+
* metadata, and props. Return `null` to deny token issuance.
|
|
194
|
+
*
|
|
195
|
+
* Always async — mirrors `EmaTrustedIssuerResolver` so the two enterprise
|
|
196
|
+
* callbacks have the same shape and downstream lookups (KV, D1, IdP federation)
|
|
197
|
+
* don't require a later API change to add `Promise<…>` return support.
|
|
198
|
+
*/
|
|
199
|
+
type EmaClaimsMapper<Env = Cloudflare.Env> = (input: EmaClaimsMapperInput<Env>) => Promise<EmaClaimsMapperResult | null>;
|
|
200
|
+
/**
|
|
201
|
+
* Input passed to a dynamic `EmaTrustedIssuerResolver`.
|
|
202
|
+
*
|
|
203
|
+
* The `iss` value comes from the assertion's unverified payload — it is
|
|
204
|
+
* used here only as a routing key to choose which IdP's JWKS to load.
|
|
205
|
+
* The cryptographic trust comes from signature verification later, so
|
|
206
|
+
* the resolver may safely treat `iss` as untrusted input.
|
|
207
|
+
*/
|
|
208
|
+
interface EmaTrustedIssuerResolverInput<Env = Cloudflare.Env> {
|
|
209
|
+
/** Issuer URL from the assertion's `iss` claim (unverified). */
|
|
210
|
+
iss: string;
|
|
211
|
+
/** Cloudflare Worker environment variables (bindings, secrets, KV, D1). */
|
|
212
|
+
env: Env;
|
|
213
|
+
/** The original HTTP request, e.g. for inspecting the Host header in multi-tenant routing. */
|
|
214
|
+
request: Request;
|
|
215
|
+
/** Authenticated OAuth client that presented the assertion. */
|
|
216
|
+
clientInfo: ClientInfo;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Dynamic resolver for `EmaOptions.trustedIssuers`.
|
|
220
|
+
*
|
|
221
|
+
* Returns the trusted issuer configuration for an incoming `iss` claim,
|
|
222
|
+
* or `null` if the issuer is not trusted for this client / tenant. The
|
|
223
|
+
* returned `issuer` field must equal the input `iss` — the AS enforces
|
|
224
|
+
* this to prevent a resolver from being tricked into returning a config
|
|
225
|
+
* for a different IdP than the one the assertion claims to be from.
|
|
226
|
+
*
|
|
227
|
+
* Useful for B2B platforms where new tenants onboard their own IdPs
|
|
228
|
+
* dynamically and the AS cannot ship a static list at deploy time.
|
|
229
|
+
*
|
|
230
|
+
* **SSRF warning**: `jwksUri` is fetched outbound by the AS. If your
|
|
231
|
+
* resolver reads `jwksUri` from tenant-controlled storage (self-service
|
|
232
|
+
* tenant onboarding, etc.), an attacker who controls a tenant config
|
|
233
|
+
* can point the AS at arbitrary HTTPS endpoints — internal services,
|
|
234
|
+
* cloud metadata endpoints, victim hosts for DoS amplification. The
|
|
235
|
+
* library only enforces `https:`; deployers must validate `jwksUri`
|
|
236
|
+
* against their own allowlist (e.g. registered IdP vendor domains)
|
|
237
|
+
* before storing or returning it.
|
|
238
|
+
*/
|
|
239
|
+
type EmaTrustedIssuerResolver<Env = Cloudflare.Env> = (input: EmaTrustedIssuerResolverInput<Env>) => Promise<EmaTrustedIssuer | null>;
|
|
240
|
+
/**
|
|
241
|
+
* MCP Enterprise-Managed Authorization configuration.
|
|
242
|
+
*
|
|
243
|
+
* Presence of this option on `OAuthProviderOptions` enables the EMA grant.
|
|
244
|
+
* There is intentionally no `enabled` flag — forgetting to set it would
|
|
245
|
+
* silently disable the feature despite full configuration.
|
|
246
|
+
*/
|
|
247
|
+
interface EmaOptions<Env = Cloudflare.Env> {
|
|
248
|
+
/**
|
|
249
|
+
* Resolver that returns the trusted issuer configuration for an
|
|
250
|
+
* incoming `iss` claim, or `null` to reject the assertion.
|
|
251
|
+
*
|
|
252
|
+
* Always a function — for a fixed list of IdPs, write a one-line closure:
|
|
253
|
+
*
|
|
254
|
+
* ```ts
|
|
255
|
+
* const issuers = [{ issuer: 'https://idp.example.com', jwksUri: '...' }];
|
|
256
|
+
* trustedIssuers: async ({ iss }) => issuers.find((i) => i.issuer === iss) ?? null,
|
|
257
|
+
* ```
|
|
258
|
+
*
|
|
259
|
+
* For B2B / multi-tenant deployments, the resolver can consult `env`,
|
|
260
|
+
* `request`, or `clientInfo` to look up the issuer dynamically (e.g.
|
|
261
|
+
* a per-tenant config in KV / D1) without redeploying.
|
|
262
|
+
*/
|
|
263
|
+
trustedIssuers: EmaTrustedIssuerResolver<Env>;
|
|
264
|
+
/** Maps validated enterprise claims to local token data. */
|
|
265
|
+
mapClaims: EmaClaimsMapper<Env>;
|
|
266
|
+
/** JWKS cache TTL in seconds. Defaults to 300 seconds. */
|
|
267
|
+
jwksCacheTtlSeconds?: number;
|
|
268
|
+
/** Allowed clock skew for `exp` and `iat` checks in seconds. Defaults to 60 seconds. */
|
|
269
|
+
clockSkewSeconds?: number;
|
|
270
|
+
/** Maximum accepted assertion lifetime in seconds. Defaults to 300 seconds. */
|
|
271
|
+
maxAssertionLifetimeSeconds?: number;
|
|
272
|
+
}
|
|
273
|
+
//#endregion
|
|
274
|
+
//#region src/oauth-provider.d.ts
|
|
5
275
|
/**
|
|
6
276
|
* Enum representing OAuth grant types
|
|
7
277
|
*/
|
|
@@ -9,6 +279,7 @@ declare enum GrantType {
|
|
|
9
279
|
AUTHORIZATION_CODE = "authorization_code",
|
|
10
280
|
REFRESH_TOKEN = "refresh_token",
|
|
11
281
|
TOKEN_EXCHANGE = "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
282
|
+
JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
12
283
|
}
|
|
13
284
|
/**
|
|
14
285
|
* Aliases for either type of Handler that makes .fetch required
|
|
@@ -84,6 +355,14 @@ interface TokenExchangeCallbackOptions {
|
|
|
84
355
|
* User who authorized this grant
|
|
85
356
|
*/
|
|
86
357
|
userId: string;
|
|
358
|
+
/**
|
|
359
|
+
* Identifier of the grant record this callback is operating on. Stable across
|
|
360
|
+
* refreshes for the lifetime of the grant. Pass this together with `userId`
|
|
361
|
+
* to {@link OAuthHelpers.revokeGrant} when the callback decides the grant
|
|
362
|
+
* should be torn down (for example, after an upstream refresh fails with a
|
|
363
|
+
* terminal error code).
|
|
364
|
+
*/
|
|
365
|
+
grantId: string;
|
|
87
366
|
/**
|
|
88
367
|
* List of scopes that were granted
|
|
89
368
|
*/
|
|
@@ -227,6 +506,15 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
227
506
|
* Defaults to false.
|
|
228
507
|
*/
|
|
229
508
|
allowTokenExchangeGrant?: boolean;
|
|
509
|
+
/**
|
|
510
|
+
* Experimental support for the MCP Enterprise-Managed Authorization extension.
|
|
511
|
+
* When enabled, the token endpoint accepts ID-JAG assertions using the JWT bearer
|
|
512
|
+
* grant type (`urn:ietf:params:oauth:grant-type:jwt-bearer`).
|
|
513
|
+
*
|
|
514
|
+
* This feature is opt-in because the MCP extension and underlying OAuth drafts are
|
|
515
|
+
* still evolving. Trusted issuers and a claim mapper are required.
|
|
516
|
+
*/
|
|
517
|
+
enterpriseManagedAuthorization?: EmaOptions<Env>;
|
|
230
518
|
/**
|
|
231
519
|
* Controls whether public clients (clients without a secret, like SPAs) can register via the
|
|
232
520
|
* dynamic client registration endpoint. When true, only confidential clients can register.
|
|
@@ -255,16 +543,26 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
255
543
|
*/
|
|
256
544
|
resolveExternalToken?: (input: ResolveExternalTokenInput) => Promise<ResolveExternalTokenResult | null>;
|
|
257
545
|
/**
|
|
258
|
-
* Optional callback function that is called whenever the OAuthProvider returns an error response
|
|
546
|
+
* Optional callback function that is called whenever the OAuthProvider returns an error response.
|
|
259
547
|
* This allows the client to emit notifications or perform other actions when an error occurs.
|
|
260
548
|
*
|
|
261
549
|
* If the function returns a Response, that will be used in place of the OAuthProvider's default one.
|
|
550
|
+
*
|
|
551
|
+
* `internal` (when present) carries a tagged, server-side-only reason that the library
|
|
552
|
+
* deliberately did NOT put on the wire — used for richer diagnostics where the public
|
|
553
|
+
* response must stay generic (e.g. JWT validation failures on the EMA path). Backwards
|
|
554
|
+
* compatible: existing callbacks ignoring this field continue to work unchanged.
|
|
262
555
|
*/
|
|
263
556
|
onError?: (error: {
|
|
264
557
|
code: string;
|
|
265
558
|
description: string;
|
|
266
559
|
status: number;
|
|
267
560
|
headers: Record<string, string>;
|
|
561
|
+
internal?: {
|
|
562
|
+
category: string;
|
|
563
|
+
reason: string;
|
|
564
|
+
detail?: unknown;
|
|
565
|
+
};
|
|
268
566
|
}) => Response | void;
|
|
269
567
|
/**
|
|
270
568
|
* Explicitly enable Client ID Metadata Document (CIMD) support.
|
|
@@ -511,6 +809,18 @@ interface ClientInfo {
|
|
|
511
809
|
* URL to the client's JSON Web Key Set for validating signatures
|
|
512
810
|
*/
|
|
513
811
|
jwksUri?: string;
|
|
812
|
+
/**
|
|
813
|
+
* RFC 7591 §2.2 internationalized variants of the human-readable client
|
|
814
|
+
* metadata fields, keyed by the raw member name including its BCP 47 language
|
|
815
|
+
* tag (e.g. `"client_name#ja"`, `"tos_uri#fr"`).
|
|
816
|
+
*
|
|
817
|
+
* Only the human-readable fields the RFC names are captured here:
|
|
818
|
+
* `client_name`, `client_uri`, `logo_uri`, `tos_uri`, and `policy_uri`.
|
|
819
|
+
* The canonical (un-tagged) values continue to live in their own typed
|
|
820
|
+
* fields above; this map holds only the locale-specific variants so that
|
|
821
|
+
* consumers can perform their own locale selection.
|
|
822
|
+
*/
|
|
823
|
+
i18n?: Record<string, string>;
|
|
514
824
|
/**
|
|
515
825
|
* List of email addresses for contacting the client developers
|
|
516
826
|
*/
|
|
@@ -980,5 +1290,33 @@ declare class OAuthError extends Error {
|
|
|
980
1290
|
readonly headers?: Record<string, string>;
|
|
981
1291
|
constructor(code: string, options: OAuthErrorOptions);
|
|
982
1292
|
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Validates a resource URI per RFC 8707 Section 2
|
|
1295
|
+
* @param uri - The URI string to validate
|
|
1296
|
+
* @returns true if valid, false otherwise
|
|
1297
|
+
*/
|
|
1298
|
+
declare function validateResourceUri(uri: string): boolean;
|
|
1299
|
+
/**
|
|
1300
|
+
* Checks if a requested resource matches a granted resource.
|
|
1301
|
+
* When originOnly is true, compares only the origin (scheme + host + port),
|
|
1302
|
+
* allowing path-aware resources to match origin-only grants.
|
|
1303
|
+
*/
|
|
1304
|
+
declare function resourceMatches(requested: string, granted: string, originOnly: boolean): boolean;
|
|
1305
|
+
/**
|
|
1306
|
+
* Decodes a base64url-encoded string to bytes.
|
|
1307
|
+
*/
|
|
1308
|
+
declare function base64UrlToBytes(base64Url: string): Uint8Array;
|
|
1309
|
+
/**
|
|
1310
|
+
* Parses a base64url-encoded JWT JSON part into an object.
|
|
1311
|
+
*/
|
|
1312
|
+
declare function parseJwtJsonPart(encoded: string): Record<string, unknown>;
|
|
1313
|
+
declare function isValidOAuthScopeToken(scopeToken: string): boolean;
|
|
1314
|
+
/**
|
|
1315
|
+
* Gets WebCrypto import and verify parameters for supported JOSE algorithms.
|
|
1316
|
+
*/
|
|
1317
|
+
declare function getJwtCryptoAlgorithms(alg: string): {
|
|
1318
|
+
importAlgorithm: Parameters<SubtleCrypto['importKey']>[2];
|
|
1319
|
+
verifyAlgorithm: Parameters<SubtleCrypto['verify']>[0];
|
|
1320
|
+
};
|
|
983
1321
|
//#endregion
|
|
984
|
-
export { AuthRequest, ClientInfo, CompleteAuthorizationOptions, ExchangeTokenOptions, Grant, GrantSummary, GrantType, ListOptions, ListResult, OAuthError, OAuthErrorOptions, OAuthHelpers, OAuthProvider, OAuthProvider as default, OAuthProviderOptions, OAuthTokenErrorCode, PurgeOptions, PurgeResult, ResolveExternalTokenInput, ResolveExternalTokenResult, Token, TokenBase, TokenExchangeCallbackOptions, TokenExchangeCallbackResult, TokenSummary, getOAuthApi };
|
|
1322
|
+
export { AuthRequest, ClientInfo, CompleteAuthorizationOptions, type EmaClaimsMapper, type EmaClaimsMapperInput, type EmaClaimsMapperResult, type EmaIdJagClaims, type EmaOptions, type EmaTrustedIssuer, type EmaTrustedIssuerResolver, type EmaTrustedIssuerResolverInput, type EmaValidationError, ExchangeTokenOptions, Grant, GrantSummary, GrantType, ListOptions, ListResult, OAuthError, OAuthErrorOptions, OAuthHelpers, OAuthProvider, OAuthProvider as default, OAuthProviderOptions, OAuthTokenErrorCode, PurgeOptions, PurgeResult, ResolveExternalTokenInput, ResolveExternalTokenResult, Token, TokenBase, TokenExchangeCallbackOptions, TokenExchangeCallbackResult, TokenSummary, base64UrlToBytes, getJwtCryptoAlgorithms, getOAuthApi, isValidOAuthScopeToken, parseJwtJsonPart, resourceMatches, validateResourceUri };
|