@cloudflare/workers-oauth-provider 0.8.3 → 0.9.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/README.md +356 -451
- package/dist/oauth-provider.d.ts +140 -29
- package/dist/oauth-provider.js +430 -148
- package/package.json +5 -3
package/dist/oauth-provider.d.ts
CHANGED
|
@@ -39,6 +39,9 @@ type EmaValidationError = {
|
|
|
39
39
|
reason: 'aud_mismatch';
|
|
40
40
|
expected: string;
|
|
41
41
|
got: string | string[];
|
|
42
|
+
} | {
|
|
43
|
+
reason: 'unsupported_claim';
|
|
44
|
+
claim: 'authorization_details' | 'cnf';
|
|
42
45
|
} | {
|
|
43
46
|
reason: 'expired';
|
|
44
47
|
exp: number;
|
|
@@ -295,6 +298,9 @@ interface EmaOptions<Env = Cloudflare.Env> {
|
|
|
295
298
|
allowPublicClients?: boolean;
|
|
296
299
|
}
|
|
297
300
|
//#endregion
|
|
301
|
+
//#region src/oauth-capabilities.d.ts
|
|
302
|
+
declare function isValidOAuthScopeToken(scopeToken: string): boolean;
|
|
303
|
+
//#endregion
|
|
298
304
|
//#region src/oauth-provider.d.ts
|
|
299
305
|
/**
|
|
300
306
|
* Enum representing OAuth grant types
|
|
@@ -446,7 +452,7 @@ interface ClientRegistrationCallbackResult {
|
|
|
446
452
|
/**
|
|
447
453
|
* Input parameters for the resolveExternalToken callback function
|
|
448
454
|
*/
|
|
449
|
-
interface ResolveExternalTokenInput {
|
|
455
|
+
interface ResolveExternalTokenInput<Env = Cloudflare.Env> {
|
|
450
456
|
/**
|
|
451
457
|
* The token string that was provided in the Authorization header
|
|
452
458
|
*/
|
|
@@ -458,21 +464,25 @@ interface ResolveExternalTokenInput {
|
|
|
458
464
|
/**
|
|
459
465
|
* Cloudflare Worker environment variables
|
|
460
466
|
*/
|
|
461
|
-
env:
|
|
467
|
+
env: Env;
|
|
462
468
|
}
|
|
463
469
|
/**
|
|
464
470
|
* Result returned from the resolveExternalToken callback function
|
|
465
471
|
*/
|
|
466
472
|
interface ResolveExternalTokenResult {
|
|
467
473
|
/**
|
|
468
|
-
* Application-specific properties that will be passed to the API handlers
|
|
469
|
-
* These properties are set in the execution context (ctx.props)
|
|
474
|
+
* Application-specific properties that will be passed to the API handlers.
|
|
475
|
+
* These properties are set in the execution context (`ctx.props`) after the
|
|
476
|
+
* external bearer credential is validated.
|
|
470
477
|
*/
|
|
471
478
|
props: any;
|
|
472
479
|
/**
|
|
473
|
-
*
|
|
474
|
-
* If provided, will be validated against the resource server identity
|
|
480
|
+
* Protected resource audience established by the external validator.
|
|
475
481
|
*
|
|
482
|
+
* A JWT may carry this value as an `aud` claim. For an opaque API token or
|
|
483
|
+
* PAT, the callback can supply the local resource URI as policy after
|
|
484
|
+
* successful validation. When `resourceMetadata.resource` is configured,
|
|
485
|
+
* this value is required and must match it exactly.
|
|
476
486
|
*/
|
|
477
487
|
audience?: string | string[];
|
|
478
488
|
}
|
|
@@ -548,8 +558,9 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
548
558
|
*/
|
|
549
559
|
clientRegistrationTTL?: number;
|
|
550
560
|
/**
|
|
551
|
-
*
|
|
552
|
-
*
|
|
561
|
+
* Scopes supported by the authorization server.
|
|
562
|
+
* These are advertised only in authorization server metadata; configure
|
|
563
|
+
* `resourceMetadata.scopes_supported` separately for protected resource requirements.
|
|
553
564
|
*/
|
|
554
565
|
scopesSupported?: string[];
|
|
555
566
|
/**
|
|
@@ -559,10 +570,9 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
559
570
|
*/
|
|
560
571
|
allowImplicitFlow?: boolean;
|
|
561
572
|
/**
|
|
562
|
-
* Controls whether the plain PKCE method is allowed.
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
* Defaults to true for backward compatibility.
|
|
573
|
+
* Controls whether the legacy plain PKCE method is allowed.
|
|
574
|
+
* Defaults to false so PKCE challenges use S256 exclusively.
|
|
575
|
+
* Set to true only for compatibility with clients that cannot use S256.
|
|
566
576
|
*/
|
|
567
577
|
allowPlainPKCE?: boolean;
|
|
568
578
|
/**
|
|
@@ -604,15 +614,18 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
604
614
|
*/
|
|
605
615
|
tokenExchangeCallback?: (options: TokenExchangeCallbackOptions) => Promise<TokenExchangeCallbackResult | void> | TokenExchangeCallbackResult | void;
|
|
606
616
|
/**
|
|
607
|
-
* Optional callback
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
* the
|
|
617
|
+
* Optional callback called when a provided bearer credential was not found
|
|
618
|
+
* in the internal KV. It can validate an external OAuth access token, opaque
|
|
619
|
+
* API token, personal access token (PAT), or another bearer credential and
|
|
620
|
+
* set the application props passed to the protected handler.
|
|
611
621
|
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
622
|
+
* Return props to authenticate the request, or `null` for a generic `invalid_token` response.
|
|
623
|
+
* Throw this package's exported {@link ExternalTokenError} to return an intentional
|
|
624
|
+
* structured error response for an upstream validation failure.
|
|
625
|
+
* All other thrown errors, including {@link OAuthError}, remain unexpected
|
|
626
|
+
* failures and are re-thrown for backwards compatibility.
|
|
614
627
|
*/
|
|
615
|
-
resolveExternalToken?: (input: ResolveExternalTokenInput) => Promise<ResolveExternalTokenResult | null>;
|
|
628
|
+
resolveExternalToken?: (input: ResolveExternalTokenInput<Env>) => Promise<ResolveExternalTokenResult | null>;
|
|
616
629
|
/**
|
|
617
630
|
* Optional callback function that is called whenever the OAuthProvider returns an error response.
|
|
618
631
|
* This allows the client to emit notifications or perform other actions when an error occurs.
|
|
@@ -623,6 +636,11 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
623
636
|
* deliberately did NOT put on the wire — used for richer diagnostics where the public
|
|
624
637
|
* response must stay generic (e.g. JWT validation failures on the EMA path). Backwards
|
|
625
638
|
* compatible: existing callbacks ignoring this field continue to work unchanged.
|
|
639
|
+
*
|
|
640
|
+
* `request` (when present) is the HTTP request that produced the error response, so the
|
|
641
|
+
* callback can correlate the error with per-request state such as request-keyed telemetry.
|
|
642
|
+
* Currently populated for CIMD metadata fetch failures at the token endpoint. Backwards
|
|
643
|
+
* compatible in the same way as `internal`.
|
|
626
644
|
*/
|
|
627
645
|
onError?: (error: {
|
|
628
646
|
code: string;
|
|
@@ -634,6 +652,7 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
634
652
|
reason: string;
|
|
635
653
|
detail?: unknown;
|
|
636
654
|
};
|
|
655
|
+
request?: Request;
|
|
637
656
|
}) => Response | void;
|
|
638
657
|
/**
|
|
639
658
|
* Explicitly enable Client ID Metadata Document (CIMD) support.
|
|
@@ -648,6 +667,7 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
648
667
|
* with an origin-only resource (e.g. `https://server.com`) to be used with
|
|
649
668
|
* path-aware resource requests (e.g. `https://server.com/mcp`), enabling seamless
|
|
650
669
|
* migration from pre-0.4.0 versions that stored origin-only resource URIs.
|
|
670
|
+
* Explicit `resourceMetadata.resource` configuration always uses exact matching.
|
|
651
671
|
*
|
|
652
672
|
* Defaults to false (strict exact matching per RFC 8707).
|
|
653
673
|
*/
|
|
@@ -662,7 +682,11 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
662
682
|
resourceMetadata?: {
|
|
663
683
|
/**
|
|
664
684
|
* The protected resource identifier URL (RFC 9728 `resource` field).
|
|
665
|
-
*
|
|
685
|
+
*
|
|
686
|
+
* Configuring this value pins authorization requests, token requests, and
|
|
687
|
+
* access-token audiences to this exact resource. If omitted, the provider
|
|
688
|
+
* accepts valid RFC 8707 resource indicators and uses the authorization
|
|
689
|
+
* request origin as the default when the client does not send one.
|
|
666
690
|
*/
|
|
667
691
|
resource?: string;
|
|
668
692
|
/**
|
|
@@ -672,8 +696,10 @@ interface OAuthProviderOptions<Env = Cloudflare.Env> {
|
|
|
672
696
|
*/
|
|
673
697
|
authorization_servers?: string[];
|
|
674
698
|
/**
|
|
675
|
-
*
|
|
676
|
-
*
|
|
699
|
+
* Minimal scopes required for basic protected resource functionality.
|
|
700
|
+
* These scopes are advertised in Protected Resource Metadata and used as
|
|
701
|
+
* baseline bearer challenge guidance. `offline_access` is omitted because
|
|
702
|
+
* refresh-token issuance is an authorization server capability.
|
|
677
703
|
*/
|
|
678
704
|
scopes_supported?: string[];
|
|
679
705
|
/**
|
|
@@ -695,18 +721,23 @@ interface OAuthHelpers {
|
|
|
695
721
|
* Parses an OAuth authorization request from the HTTP request
|
|
696
722
|
* @param request - The HTTP request containing OAuth parameters
|
|
697
723
|
* @returns The parsed authorization request parameters
|
|
724
|
+
* @throws Error when the response type is missing, unsupported, or not registered for the client
|
|
725
|
+
* @throws {@link CimdFetchError} when the client ID is a CIMD URL whose document cannot be resolved
|
|
698
726
|
*/
|
|
699
727
|
parseAuthRequest(request: Request): Promise<AuthRequest>;
|
|
700
728
|
/**
|
|
701
729
|
* Looks up a client by its client ID
|
|
702
730
|
* @param clientId - The client ID to look up
|
|
703
|
-
* @returns A Promise resolving to the client info, or null if not
|
|
731
|
+
* @returns A Promise resolving to the client info, or null if the client does not exist
|
|
732
|
+
* @throws {@link CimdFetchError} when the client ID is a CIMD URL whose document cannot be resolved
|
|
704
733
|
*/
|
|
705
734
|
lookupClient(clientId: string): Promise<ClientInfo | null>;
|
|
706
735
|
/**
|
|
707
736
|
* Completes an authorization request by creating a grant and authorization code
|
|
708
737
|
* @param options - Options specifying the grant details
|
|
709
738
|
* @returns A Promise resolving to an object containing the redirect URL
|
|
739
|
+
* @throws Error when the request's response type is not permitted
|
|
740
|
+
* @throws {@link CimdFetchError} when the client ID is a CIMD URL whose document cannot be resolved
|
|
710
741
|
*/
|
|
711
742
|
completeAuthorization(options: CompleteAuthorizationOptions): Promise<{
|
|
712
743
|
redirectTo: string;
|
|
@@ -762,6 +793,7 @@ interface OAuthHelpers {
|
|
|
762
793
|
* Implements OAuth 2.0 Token Exchange (RFC 8693)
|
|
763
794
|
* @param options - Options for token exchange including subject token and optional modifications
|
|
764
795
|
* @returns Promise resolving to token response with new access token
|
|
796
|
+
* @throws {@link CimdFetchError} when the grant's client ID is a CIMD URL whose document cannot be resolved
|
|
765
797
|
*/
|
|
766
798
|
exchangeToken(options: ExchangeTokenOptions): Promise<TokenResponse>;
|
|
767
799
|
/**
|
|
@@ -838,6 +870,11 @@ interface AuthRequest {
|
|
|
838
870
|
* Resource parameter indicating target resource(s) (RFC 8707)
|
|
839
871
|
*/
|
|
840
872
|
resource?: string | string[];
|
|
873
|
+
/**
|
|
874
|
+
* Authorization server issuer recorded while parsing this request.
|
|
875
|
+
* Include it as `iss` in successful and error authorization responses.
|
|
876
|
+
*/
|
|
877
|
+
issuer?: string;
|
|
841
878
|
}
|
|
842
879
|
/**
|
|
843
880
|
* OAuth client registration information
|
|
@@ -1317,11 +1354,10 @@ interface OAuthErrorOptions {
|
|
|
1317
1354
|
headers?: Record<string, string>;
|
|
1318
1355
|
}
|
|
1319
1356
|
/**
|
|
1320
|
-
* Structured OAuth 2.0 error.
|
|
1357
|
+
* Structured OAuth 2.0 token-endpoint error.
|
|
1321
1358
|
*
|
|
1322
|
-
* Throw from a `tokenExchangeCallback`
|
|
1323
|
-
*
|
|
1324
|
-
* `/token` error response (`{ error, error_description }`) instead of a
|
|
1359
|
+
* Throw from a `tokenExchangeCallback` or any code it calls to surface a
|
|
1360
|
+
* standard OAuth token response (`{ error, error_description }`) instead of a
|
|
1325
1361
|
* generic `500 Internal Server Error`.
|
|
1326
1362
|
*
|
|
1327
1363
|
* Anything thrown that is **not** an `OAuthError` continues to surface as
|
|
@@ -1371,6 +1407,82 @@ declare class OAuthError extends Error {
|
|
|
1371
1407
|
readonly headers?: Record<string, string>;
|
|
1372
1408
|
constructor(code: string, options: OAuthErrorOptions);
|
|
1373
1409
|
}
|
|
1410
|
+
/** Options accepted by the {@link ExternalTokenError} constructor. */
|
|
1411
|
+
interface ExternalTokenErrorOptions {
|
|
1412
|
+
/**
|
|
1413
|
+
* Public description returned in the OAuth `error_description` field.
|
|
1414
|
+
* Do not include credentials, upstream response bodies, or private diagnostics.
|
|
1415
|
+
*/
|
|
1416
|
+
description: string;
|
|
1417
|
+
/** HTTP status returned to the protected-resource client. */
|
|
1418
|
+
statusCode: number;
|
|
1419
|
+
/** Additional public response headers, such as `Retry-After`. */
|
|
1420
|
+
headers?: Record<string, string>;
|
|
1421
|
+
/**
|
|
1422
|
+
* Minimum scopes needed for the protected-resource operation.
|
|
1423
|
+
*
|
|
1424
|
+
* For `403 insufficient_scope`, these values are validated, deduplicated,
|
|
1425
|
+
* and added to the synthesized `WWW-Authenticate` challenge. Each value must
|
|
1426
|
+
* use the OAuth scope-token grammar from RFC 6749 §3.3.
|
|
1427
|
+
*/
|
|
1428
|
+
requiredScopes?: string[];
|
|
1429
|
+
}
|
|
1430
|
+
/**
|
|
1431
|
+
* Intentional public error from an external bearer-token validator.
|
|
1432
|
+
*
|
|
1433
|
+
* Throw only from `resolveExternalToken` when an expected validation outcome
|
|
1434
|
+
* should become a structured protected-resource response. Ordinary errors and
|
|
1435
|
+
* {@link OAuthError} retain their pre-existing behavior and propagate as
|
|
1436
|
+
* unexpected failures.
|
|
1437
|
+
*/
|
|
1438
|
+
declare class ExternalTokenError extends Error {
|
|
1439
|
+
/** OAuth error code returned in the response body and, when applicable, challenge. */
|
|
1440
|
+
readonly code: OAuthTokenErrorCode;
|
|
1441
|
+
/** Public description returned as `error_description`. */
|
|
1442
|
+
readonly description: string;
|
|
1443
|
+
/** HTTP status returned to the protected-resource client. */
|
|
1444
|
+
readonly statusCode: number;
|
|
1445
|
+
/** Additional public response headers. */
|
|
1446
|
+
readonly headers?: Record<string, string>;
|
|
1447
|
+
/** Minimum scopes for an `insufficient_scope` challenge. */
|
|
1448
|
+
readonly requiredScopes?: string[];
|
|
1449
|
+
/**
|
|
1450
|
+
* Creates an intentional external-token validation error.
|
|
1451
|
+
* @param code - Standard OAuth error code to return
|
|
1452
|
+
* @param options - Public response details
|
|
1453
|
+
*/
|
|
1454
|
+
constructor(code: OAuthTokenErrorCode, options: ExternalTokenErrorOptions);
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Thrown when fetching a Client ID Metadata Document (CIMD) fails — the
|
|
1458
|
+
* server-to-server fetch errored, timed out, or returned an invalid document.
|
|
1459
|
+
* Distinct from a client that simply does not exist, which is reported as a
|
|
1460
|
+
* null client lookup result.
|
|
1461
|
+
*
|
|
1462
|
+
* At the token endpoint the provider handles this itself: the wire response
|
|
1463
|
+
* stays a generic `invalid_client` / "Client not found", and the failure is
|
|
1464
|
+
* reported through the `onError` hook's `internal` field (category
|
|
1465
|
+
* `client-id-metadata-document`) together with the originating `request`.
|
|
1466
|
+
*
|
|
1467
|
+
* `OAuthHelpers` methods that look up clients (`lookupClient`, and methods
|
|
1468
|
+
* built on it such as `exchangeToken`) let this error propagate to the
|
|
1469
|
+
* caller. Callers that previously relied on a `null` result for these
|
|
1470
|
+
* failures should catch it to preserve their error contract.
|
|
1471
|
+
*/
|
|
1472
|
+
declare class CimdFetchError extends Error {
|
|
1473
|
+
/** Stable reason slug suitable for telemetry and control flow. */
|
|
1474
|
+
readonly reason: "metadata_resolution_failed";
|
|
1475
|
+
/** The CIMD URL whose fetch or validation failed. */
|
|
1476
|
+
readonly metadataUrl: string;
|
|
1477
|
+
/** The underlying failure message (e.g. "Failed to fetch client metadata: HTTP 403"). */
|
|
1478
|
+
readonly detail: string;
|
|
1479
|
+
/**
|
|
1480
|
+
* Creates an error for a failed CIMD fetch or validation.
|
|
1481
|
+
* @param metadataUrl - The CIMD URL that could not be resolved
|
|
1482
|
+
* @param cause - The underlying fetch or validation failure
|
|
1483
|
+
*/
|
|
1484
|
+
constructor(metadataUrl: string, cause: unknown);
|
|
1485
|
+
}
|
|
1374
1486
|
/**
|
|
1375
1487
|
* Validates a resource URI per RFC 8707 Section 2
|
|
1376
1488
|
* @param uri - The URI string to validate
|
|
@@ -1391,7 +1503,6 @@ declare function base64UrlToBytes(base64Url: string): Uint8Array;
|
|
|
1391
1503
|
* Parses a base64url-encoded JWT JSON part into an object.
|
|
1392
1504
|
*/
|
|
1393
1505
|
declare function parseJwtJsonPart(encoded: string): Record<string, unknown>;
|
|
1394
|
-
declare function isValidOAuthScopeToken(scopeToken: string): boolean;
|
|
1395
1506
|
/**
|
|
1396
1507
|
* Gets WebCrypto import and verify parameters for supported JOSE algorithms.
|
|
1397
1508
|
*/
|
|
@@ -1400,4 +1511,4 @@ declare function getJwtCryptoAlgorithms(alg: string): {
|
|
|
1400
1511
|
verifyAlgorithm: Parameters<SubtleCrypto['verify']>[0];
|
|
1401
1512
|
};
|
|
1402
1513
|
//#endregion
|
|
1403
|
-
export { AuthRequest, ClientInfo, ClientRegistrationCallbackOptions, ClientRegistrationCallbackResult, 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 };
|
|
1514
|
+
export { AuthRequest, CimdFetchError, ClientInfo, ClientRegistrationCallbackOptions, ClientRegistrationCallbackResult, CompleteAuthorizationOptions, type EmaClaimsMapper, type EmaClaimsMapperInput, type EmaClaimsMapperResult, type EmaIdJagClaims, type EmaOptions, type EmaTrustedIssuer, type EmaTrustedIssuerResolver, type EmaTrustedIssuerResolverInput, type EmaValidationError, ExchangeTokenOptions, ExternalTokenError, ExternalTokenErrorOptions, 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 };
|