@better-auth/oauth-provider 1.7.9 → 1.8.0-beta.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/dist/{authorize-D8r6mvZx.mjs → authorize-92EtLsBi.mjs} +735 -502
- package/dist/client-resource.d.mts +1 -1
- package/dist/client-resource.mjs +2 -2
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +1 -1
- package/dist/index-sGnh4IfY.d.mts +275 -0
- package/dist/index.d.mts +4 -203
- package/dist/index.mjs +198 -41
- package/dist/internal.d.mts +108 -40
- package/dist/internal.mjs +4 -2
- package/dist/{introspect-7WCMPe5Z.mjs → introspect-CEo9Q06v.mjs} +318 -237
- package/dist/{oauth-DAMtT2vg.d.mts → oauth-BlEuA8oD.d.mts} +380 -20
- package/dist/{oauth-BWgg8X-A.d.mts → oauth-mdkaIwmm.d.mts} +191 -86
- package/dist/{utils-DKU5wblX.mjs → utils-BMNe8Sg2.mjs} +343 -5
- package/dist/{version-DVUrz-nv.mjs → version-DeABnmP9.mjs} +1 -1
- package/package.json +6 -6
|
@@ -1,10 +1,49 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
import { PrivateKeyJwtSigningAlgorithm } from "@better-auth/core/oauth2";
|
|
3
|
-
import { JWTPayload } from "jose";
|
|
4
3
|
import { JWSAlgorithms } from "better-auth/plugins";
|
|
4
|
+
import { JWTPayload } from "jose";
|
|
5
5
|
import { InferOptionSchema, Session, User } from "better-auth/types";
|
|
6
6
|
import { GenericEndpointContext, LiteralString } from "@better-auth/core";
|
|
7
7
|
|
|
8
|
+
//#region src/register.d.ts
|
|
9
|
+
type OAuthClientRegistrationMetadata = Omit<OAuthClient, "client_id" | "redirect_uris" | "client_secret_expires_at"> & {
|
|
10
|
+
client_id?: string;
|
|
11
|
+
redirect_uris?: string[];
|
|
12
|
+
client_secret_expires_at?: number | string;
|
|
13
|
+
metadata?: Record<string, unknown>;
|
|
14
|
+
resources?: string[];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Rejects a URI the server will POST to unless it is an absolute https URL
|
|
18
|
+
* with no fragment or credentials on a publicly routable host. Back-channel
|
|
19
|
+
* endpoints use it as an SSRF guard, since the server, not the browser, calls
|
|
20
|
+
* them.
|
|
21
|
+
*/
|
|
22
|
+
declare function assertPublicRoutableHttpsUri(field: string, uri: string): void;
|
|
23
|
+
interface OAuthClientRegistrationResult {
|
|
24
|
+
client: SchemaClient<Scope[]>;
|
|
25
|
+
clientSecret?: string;
|
|
26
|
+
resources: string[];
|
|
27
|
+
created: boolean;
|
|
28
|
+
}
|
|
29
|
+
interface RegisterClientMetadataDocumentInput {
|
|
30
|
+
metadata: OAuthClient;
|
|
31
|
+
clientId: string;
|
|
32
|
+
clientDiscoveryId: string;
|
|
33
|
+
existingClient?: SchemaClient<Scope[]>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* First-party persistence seam for a validated Client ID Metadata Document.
|
|
37
|
+
*
|
|
38
|
+
* This operation owns both initial creation and atomic replacement. It never
|
|
39
|
+
* generates a client secret, preserves operator-controlled flags on
|
|
40
|
+
* replacement, and ensures server-default resource links in the same
|
|
41
|
+
* transaction.
|
|
42
|
+
*
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
declare function registerClientMetadataDocument(ctx: GenericEndpointContext, opts: OAuthOptions<Scope[]>, input: RegisterClientMetadataDocumentInput): Promise<OAuthClientRegistrationResult>;
|
|
46
|
+
//#endregion
|
|
8
47
|
//#region src/schema.d.ts
|
|
9
48
|
declare const schema: {
|
|
10
49
|
oauthClient: {
|
|
@@ -40,6 +79,10 @@ declare const schema: {
|
|
|
40
79
|
type: "string";
|
|
41
80
|
required: false;
|
|
42
81
|
};
|
|
82
|
+
sectorIdentifier: {
|
|
83
|
+
type: "string";
|
|
84
|
+
required: false;
|
|
85
|
+
};
|
|
43
86
|
scopes: {
|
|
44
87
|
type: "string[]";
|
|
45
88
|
required: false;
|
|
@@ -118,6 +161,14 @@ declare const schema: {
|
|
|
118
161
|
type: "boolean";
|
|
119
162
|
required: false;
|
|
120
163
|
};
|
|
164
|
+
frontchannelLogoutUri: {
|
|
165
|
+
type: "string";
|
|
166
|
+
required: false;
|
|
167
|
+
};
|
|
168
|
+
frontchannelLogoutSessionRequired: {
|
|
169
|
+
type: "boolean";
|
|
170
|
+
required: false;
|
|
171
|
+
};
|
|
121
172
|
tokenEndpointAuthMethod: {
|
|
122
173
|
type: "string";
|
|
123
174
|
required: false;
|
|
@@ -371,6 +422,14 @@ declare const schema: {
|
|
|
371
422
|
type: "date";
|
|
372
423
|
required: false;
|
|
373
424
|
};
|
|
425
|
+
acr: {
|
|
426
|
+
type: "string";
|
|
427
|
+
required: false;
|
|
428
|
+
};
|
|
429
|
+
amr: {
|
|
430
|
+
type: "string[]";
|
|
431
|
+
required: false;
|
|
432
|
+
};
|
|
374
433
|
confirmation: {
|
|
375
434
|
type: "json";
|
|
376
435
|
required: false;
|
|
@@ -582,6 +641,8 @@ declare const clientRegistrationRequestSchema: z.ZodObject<{
|
|
|
582
641
|
post_logout_redirect_uris: z.ZodOptional<z.ZodArray<z.ZodURL>>;
|
|
583
642
|
backchannel_logout_uri: z.ZodOptional<z.ZodURL>;
|
|
584
643
|
backchannel_logout_session_required: z.ZodOptional<z.ZodBoolean>;
|
|
644
|
+
frontchannel_logout_uri: z.ZodOptional<z.ZodURL>;
|
|
645
|
+
frontchannel_logout_session_required: z.ZodOptional<z.ZodBoolean>;
|
|
585
646
|
token_endpoint_auth_method: z.ZodOptional<z.ZodString>;
|
|
586
647
|
jwks: z.ZodOptional<z.ZodObject<{
|
|
587
648
|
keys: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
@@ -614,26 +675,27 @@ declare const clientRegistrationRequestSchema: z.ZodObject<{
|
|
|
614
675
|
* unknown extension without unsafe casts or ad-hoc allowlists.
|
|
615
676
|
*/
|
|
616
677
|
declare const oauthClientMetadataSchema: z.ZodObject<{
|
|
617
|
-
contacts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
618
678
|
jwks: z.ZodOptional<z.ZodObject<{
|
|
619
679
|
keys: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
620
680
|
}, z.core.$strip>>;
|
|
621
|
-
|
|
681
|
+
contacts: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
622
682
|
scope: z.ZodOptional<z.ZodString>;
|
|
623
|
-
redirect_uris: z.ZodOptional<z.ZodArray<z.ZodURL>>;
|
|
624
683
|
client_name: z.ZodOptional<z.ZodString>;
|
|
625
684
|
client_uri: z.ZodOptional<z.ZodString>;
|
|
626
685
|
logo_uri: z.ZodOptional<z.ZodString>;
|
|
627
686
|
tos_uri: z.ZodOptional<z.ZodString>;
|
|
628
687
|
policy_uri: z.ZodOptional<z.ZodString>;
|
|
688
|
+
jwks_uri: z.ZodOptional<z.ZodString>;
|
|
629
689
|
software_id: z.ZodOptional<z.ZodString>;
|
|
630
690
|
software_version: z.ZodOptional<z.ZodString>;
|
|
631
691
|
software_statement: z.ZodOptional<z.ZodString>;
|
|
692
|
+
redirect_uris: z.ZodOptional<z.ZodArray<z.ZodURL>>;
|
|
632
693
|
post_logout_redirect_uris: z.ZodOptional<z.ZodArray<z.ZodURL>>;
|
|
633
694
|
backchannel_logout_uri: z.ZodOptional<z.ZodURL>;
|
|
634
695
|
backchannel_logout_session_required: z.ZodOptional<z.ZodBoolean>;
|
|
696
|
+
frontchannel_logout_uri: z.ZodOptional<z.ZodURL>;
|
|
697
|
+
frontchannel_logout_session_required: z.ZodOptional<z.ZodBoolean>;
|
|
635
698
|
token_endpoint_auth_method: z.ZodOptional<z.ZodString>;
|
|
636
|
-
jwks_uri: z.ZodOptional<z.ZodString>;
|
|
637
699
|
grant_types: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
638
700
|
response_types: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
639
701
|
code: "code";
|
|
@@ -642,11 +704,12 @@ declare const oauthClientMetadataSchema: z.ZodObject<{
|
|
|
642
704
|
web: "web";
|
|
643
705
|
native: "native";
|
|
644
706
|
}>>;
|
|
707
|
+
dpop_bound_access_tokens: z.ZodOptional<z.ZodBoolean>;
|
|
645
708
|
subject_type: z.ZodOptional<z.ZodEnum<{
|
|
646
709
|
public: "public";
|
|
647
710
|
pairwise: "pairwise";
|
|
648
711
|
}>>;
|
|
649
|
-
|
|
712
|
+
resources: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
650
713
|
client_id: z.ZodString;
|
|
651
714
|
client_secret: z.ZodOptional<z.ZodString>;
|
|
652
715
|
client_secret_expires_at: z.ZodOptional<z.ZodNumber>;
|
|
@@ -666,6 +729,55 @@ type ClientRegistrationRequest = z.infer<typeof clientRegistrationRequestSchema>
|
|
|
666
729
|
//#endregion
|
|
667
730
|
//#region src/types/index.d.ts
|
|
668
731
|
type StoreTokenType = "access_token" | "refresh_token" | "authorization_code" | (string & {});
|
|
732
|
+
/**
|
|
733
|
+
* The authentication context the provider asserts in ID tokens
|
|
734
|
+
* (OIDC Core 1.0 §2).
|
|
735
|
+
*/
|
|
736
|
+
interface OAuthAuthenticationContext {
|
|
737
|
+
/**
|
|
738
|
+
* Authentication Context Class Reference the session satisfies. Must be one
|
|
739
|
+
* of `acrValuesSupported`. Defaults to `"0"`.
|
|
740
|
+
*/
|
|
741
|
+
acr?: string;
|
|
742
|
+
/**
|
|
743
|
+
* Authentication Methods References used for the session, such as
|
|
744
|
+
* `["pwd", "otp"]` (RFC 8176).
|
|
745
|
+
*/
|
|
746
|
+
amr?: string[];
|
|
747
|
+
}
|
|
748
|
+
interface OAuthAuthenticationContextOptions<Scopes extends readonly Scope[] = InternallySupportedScopes[]> {
|
|
749
|
+
/**
|
|
750
|
+
* ACR values this provider can assert, advertised as
|
|
751
|
+
* `acr_values_supported` in discovery. Include `"0"` when `resolve` can
|
|
752
|
+
* return no `acr`.
|
|
753
|
+
*/
|
|
754
|
+
acrValuesSupported: string[];
|
|
755
|
+
/**
|
|
756
|
+
* Returns the `acr` and `amr` the current session establishes. Called when
|
|
757
|
+
* the user approves an authorization request or a device code. Return only
|
|
758
|
+
* what the session actually proved; do not raise `acr` to match
|
|
759
|
+
* `requestedAcrValues`.
|
|
760
|
+
*
|
|
761
|
+
* An essential `acr` request (`claims.id_token.acr.essential`) that the
|
|
762
|
+
* returned `acr` does not satisfy fails with `access_denied`. A voluntary
|
|
763
|
+
* request (`acr_values` or a non-essential `acr` claim) never fails.
|
|
764
|
+
*
|
|
765
|
+
* Not called for requests without the `openid` scope, which issue no ID
|
|
766
|
+
* token.
|
|
767
|
+
*/
|
|
768
|
+
resolve: (info: {
|
|
769
|
+
user: User & Record<string, unknown>;
|
|
770
|
+
session: Session & Record<string, unknown>;
|
|
771
|
+
client: SchemaClient<Scopes>; /** Scopes being approved */
|
|
772
|
+
scopes: string[]; /** Headers of the request approving the authorization */
|
|
773
|
+
headers: Headers;
|
|
774
|
+
/**
|
|
775
|
+
* ACR values the client requested, from `claims.id_token.acr` and
|
|
776
|
+
* `acr_values`, in order of preference.
|
|
777
|
+
*/
|
|
778
|
+
requestedAcrValues: string[];
|
|
779
|
+
}) => Awaitable<OAuthAuthenticationContext | undefined>;
|
|
780
|
+
}
|
|
669
781
|
type InternallySupportedScopes = "openid" | "profile" | "email" | "offline_access";
|
|
670
782
|
type Scope = LiteralString | InternallySupportedScopes;
|
|
671
783
|
/**
|
|
@@ -779,6 +891,10 @@ interface OAuthTokenIssueParams {
|
|
|
779
891
|
id: string;
|
|
780
892
|
};
|
|
781
893
|
authTime?: Date;
|
|
894
|
+
/** The `acr` ID token claim. Defaults to `"0"`. */
|
|
895
|
+
acr?: string;
|
|
896
|
+
/** The `amr` ID token claim. */
|
|
897
|
+
amr?: string[];
|
|
782
898
|
verificationValue?: VerificationValue;
|
|
783
899
|
resources?: string[];
|
|
784
900
|
/** Full original authorized resources for the grant, used to seed refresh tokens. */
|
|
@@ -820,6 +936,14 @@ interface OAuthTokenIssueParams {
|
|
|
820
936
|
* is stamped after, and cannot be overridden by, contributed claims.
|
|
821
937
|
*/
|
|
822
938
|
confirmation?: Confirmation;
|
|
939
|
+
/**
|
|
940
|
+
* Latest time the access token may expire. The authorization server issues
|
|
941
|
+
* the earlier of this and its configured lifetime, so a grant derived from
|
|
942
|
+
* another token (for example RFC 8693 token exchange) cannot outlive it.
|
|
943
|
+
* If it is not in the future, issuance fails with `invalid_request`. Refresh
|
|
944
|
+
* and ID tokens are not capped, so such a grant should not issue them.
|
|
945
|
+
*/
|
|
946
|
+
maxExpiresAt?: Date;
|
|
823
947
|
}
|
|
824
948
|
interface OAuthTokenResponse {
|
|
825
949
|
access_token: string;
|
|
@@ -852,7 +976,10 @@ interface OAuthProviderApi {
|
|
|
852
976
|
* or none). For assertion-based methods, the RFC 7523 audience is bound to the
|
|
853
977
|
* endpoint serving the request, so an assertion cannot be replayed across
|
|
854
978
|
* endpoints. Returns the authenticated client, plus any `confirmation` an
|
|
855
|
-
* assertion strategy proved.
|
|
979
|
+
* assertion strategy proved. A companion endpoint that accepts
|
|
980
|
+
* `application/x-www-form-urlencoded` must set `cloneRequest: true` in its
|
|
981
|
+
* endpoint options because client authentication re-reads the raw form body
|
|
982
|
+
* to enforce credential cardinality and reject mixed authentication methods.
|
|
856
983
|
*/
|
|
857
984
|
authenticateClient: (request?: OAuthClientAuthenticationRequest) => Awaitable<OAuthAuthenticatedClient>;
|
|
858
985
|
/**
|
|
@@ -869,6 +996,21 @@ interface OAuthProviderApi {
|
|
|
869
996
|
* calling it.
|
|
870
997
|
*/
|
|
871
998
|
issueTokens: (params: OAuthTokenIssueParams) => Awaitable<OAuthTokenResponse>;
|
|
999
|
+
/**
|
|
1000
|
+
* Resolves the sender-constraint the tokens for this request will carry: the
|
|
1001
|
+
* `confirmation` the client proved at authentication, or else the DPoP proof
|
|
1002
|
+
* on this request, verified and required by the same rules `issueTokens`
|
|
1003
|
+
* applies. A grant that consumes a one-time credential (a device code, a CIBA
|
|
1004
|
+
* request) calls this before the claim and passes the result to
|
|
1005
|
+
* `issueTokens` as `confirmation`, so a rejected proof leaves the credential
|
|
1006
|
+
* for a retry with a valid one.
|
|
1007
|
+
*/
|
|
1008
|
+
resolveConfirmation: (params: {
|
|
1009
|
+
client: SchemaClient<Scope[]>;
|
|
1010
|
+
scopes: string[];
|
|
1011
|
+
resources?: string[];
|
|
1012
|
+
confirmation?: Confirmation;
|
|
1013
|
+
}) => Promise<Confirmation | undefined>;
|
|
872
1014
|
/**
|
|
873
1015
|
* Computes the stored lookup key for a token value (the same hash the
|
|
874
1016
|
* provider persists), so a caller can find or revoke a previously issued
|
|
@@ -998,7 +1140,7 @@ interface OAuthUserInfoExtensionInput {
|
|
|
998
1140
|
* `extendOAuthProvider(ctx, extension)` (or the `oauthProvider({ extensions })`
|
|
999
1141
|
* option).
|
|
1000
1142
|
*
|
|
1001
|
-
* All
|
|
1143
|
+
* All seven kinds live on one object so a single protocol plugin (for example
|
|
1002
1144
|
* RFC 8693 token exchange, which adds a grant, advertises metadata, and emits
|
|
1003
1145
|
* claims) registers atomically and the host validates the combined surface in
|
|
1004
1146
|
* one place. Every field is independently optional, so a single-concern plugin
|
|
@@ -1006,10 +1148,11 @@ interface OAuthUserInfoExtensionInput {
|
|
|
1006
1148
|
* just the one it needs. This is the shape every future OAuth RFC plugin copies.
|
|
1007
1149
|
*
|
|
1008
1150
|
* Two contribution disciplines:
|
|
1009
|
-
* - Dispatched kinds (`grants`, `clientAuthentication`)
|
|
1010
|
-
* extensions: registering a grant type, auth method,
|
|
1011
|
-
*
|
|
1012
|
-
* would otherwise be
|
|
1151
|
+
* - Dispatched kinds (`grants`, `clientAuthentication`, `interactionRequests`)
|
|
1152
|
+
* must be disjoint across extensions: registering a grant type, auth method,
|
|
1153
|
+
* assertion type, or interaction parameter that another extension already
|
|
1154
|
+
* registered is rejected at setup, since the second would otherwise be
|
|
1155
|
+
* silently unreachable.
|
|
1013
1156
|
* - Additive kinds (`metadata`, `claims`) never override authorization-server
|
|
1014
1157
|
* core; a key already owned by the provider is kept, and a key two extensions
|
|
1015
1158
|
* both contribute resolves to the first-registered extension.
|
|
@@ -1059,6 +1202,117 @@ interface OAuthProviderExtension {
|
|
|
1059
1202
|
* registry, an attestation header) contributes it here.
|
|
1060
1203
|
*/
|
|
1061
1204
|
clientDiscovery?: ClientDiscovery | ClientDiscovery[];
|
|
1205
|
+
/**
|
|
1206
|
+
* Client registration metadata the extension defines, such as CIBA's
|
|
1207
|
+
* `backchannel_token_delivery_mode`. Extension fields live in the client's
|
|
1208
|
+
* `metadata`.
|
|
1209
|
+
*/
|
|
1210
|
+
clientMetadata?: {
|
|
1211
|
+
/**
|
|
1212
|
+
* Top-level registration fields the extension defines. Dynamic client
|
|
1213
|
+
* registration (RFC 7591 §2) and client metadata documents (CIMD) both
|
|
1214
|
+
* ignore unrecognized fields; they keep these and store them in the
|
|
1215
|
+
* client's `metadata`, where admin-created clients put them too. Core
|
|
1216
|
+
* and server-owned client fields cannot be claimed.
|
|
1217
|
+
*/
|
|
1218
|
+
fields?: string[];
|
|
1219
|
+
/**
|
|
1220
|
+
* Validates the extension's fields when a client is registered through
|
|
1221
|
+
* dynamic registration or a client metadata document, or created or
|
|
1222
|
+
* updated by an admin. Throw an `APIError` with `invalid_client_metadata`
|
|
1223
|
+
* to reject the client.
|
|
1224
|
+
*/
|
|
1225
|
+
validate?: (input: OAuthClientMetadataExtensionInput) => Awaitable<void>;
|
|
1226
|
+
};
|
|
1227
|
+
/**
|
|
1228
|
+
* Requests other than an authorization request that users approve through
|
|
1229
|
+
* the `/oauth2/authorize` sign-in, account selection, post-login, and
|
|
1230
|
+
* consent pages, keyed by the query parameter that identifies one, such as
|
|
1231
|
+
* `user_code`. Every interaction page resumes them through
|
|
1232
|
+
* `/oauth2/authorize`.
|
|
1233
|
+
*/
|
|
1234
|
+
interactionRequests?: Record<string, OAuthInteractionRequestHandler>;
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Parameters signed into each interaction page. An authorization request
|
|
1238
|
+
* carries its `redirect_uri`; other interaction requests have none and add
|
|
1239
|
+
* their own identifying parameter, such as `user_code`.
|
|
1240
|
+
*/
|
|
1241
|
+
type OAuthInteractionQuery = Omit<OAuthAuthorizationQuery, "redirect_uri"> & {
|
|
1242
|
+
redirect_uri?: string | undefined;
|
|
1243
|
+
};
|
|
1244
|
+
/**
|
|
1245
|
+
* A request the user reviews through the `/oauth2/authorize` sign-in,
|
|
1246
|
+
* account selection, signup, post-login, and consent pages.
|
|
1247
|
+
*/
|
|
1248
|
+
interface OAuthInteractionRequest {
|
|
1249
|
+
/** Signed into each interaction page; carries `prompt` and `max_age`. */
|
|
1250
|
+
query: OAuthInteractionQuery;
|
|
1251
|
+
/** The provider sends the user to the error page when this client is disabled. */
|
|
1252
|
+
client: SchemaClient<Scope[]>;
|
|
1253
|
+
/**
|
|
1254
|
+
* Show the consent page even when consent is stored or the client skips
|
|
1255
|
+
* it, and approve only in the request where the user accepts on that page.
|
|
1256
|
+
*/
|
|
1257
|
+
requireConsent?: boolean | undefined;
|
|
1258
|
+
/**
|
|
1259
|
+
* Records the approval once every interaction is complete and returns the
|
|
1260
|
+
* URL to send the user to.
|
|
1261
|
+
*/
|
|
1262
|
+
approve: (approval: {
|
|
1263
|
+
query: OAuthInteractionQuery;
|
|
1264
|
+
userId: string;
|
|
1265
|
+
sessionId: string;
|
|
1266
|
+
authTime: number;
|
|
1267
|
+
acr?: string;
|
|
1268
|
+
amr?: string[];
|
|
1269
|
+
referenceId?: string;
|
|
1270
|
+
}) => Promise<string>;
|
|
1271
|
+
}
|
|
1272
|
+
/** Loads and denies one kind of {@link OAuthInteractionRequest}. */
|
|
1273
|
+
interface OAuthInteractionRequestHandler {
|
|
1274
|
+
/**
|
|
1275
|
+
* Loads the request identified by `value`. On a direct `/oauth2/authorize`
|
|
1276
|
+
* request only `value` comes from the caller; when resuming after an
|
|
1277
|
+
* interaction page, `signedQuery` is the query this server signed into it.
|
|
1278
|
+
* Throw an `APIError` when the request can no longer be approved.
|
|
1279
|
+
*/
|
|
1280
|
+
load: (input: {
|
|
1281
|
+
ctx: GenericEndpointContext;
|
|
1282
|
+
opts: OAuthOptions<Scope[]>;
|
|
1283
|
+
value: string;
|
|
1284
|
+
signedQuery?: OAuthInteractionQuery | undefined;
|
|
1285
|
+
}) => Promise<OAuthInteractionRequest>;
|
|
1286
|
+
/**
|
|
1287
|
+
* Records a denial from the consent page and returns the URL to send the
|
|
1288
|
+
* user to.
|
|
1289
|
+
*/
|
|
1290
|
+
deny: (input: {
|
|
1291
|
+
ctx: GenericEndpointContext;
|
|
1292
|
+
value: string;
|
|
1293
|
+
userId: string;
|
|
1294
|
+
}) => Promise<string>;
|
|
1295
|
+
/**
|
|
1296
|
+
* Where to send the user when the request cannot be loaded, approved, or
|
|
1297
|
+
* denied, such as a page where they can correct it. The provider appends
|
|
1298
|
+
* `error` and `error_description`. Defaults to the provider error page.
|
|
1299
|
+
*/
|
|
1300
|
+
errorPage?: (input: {
|
|
1301
|
+
ctx: GenericEndpointContext;
|
|
1302
|
+
value: string;
|
|
1303
|
+
}) => string;
|
|
1304
|
+
}
|
|
1305
|
+
interface OAuthClientMetadataExtensionInput {
|
|
1306
|
+
/**
|
|
1307
|
+
* The client's core registration metadata after provider defaults. Read
|
|
1308
|
+
* extension fields from `metadata`, not from here.
|
|
1309
|
+
*/
|
|
1310
|
+
client: Omit<OAuthClientRegistrationMetadata, "metadata">;
|
|
1311
|
+
/**
|
|
1312
|
+
* The client's `metadata` as it will be stored, with reserved client field
|
|
1313
|
+
* names removed. Extension fields are read from here.
|
|
1314
|
+
*/
|
|
1315
|
+
metadata: Record<string, unknown>;
|
|
1062
1316
|
}
|
|
1063
1317
|
/**
|
|
1064
1318
|
* Result of authorizing an RFC 7591 initial access token, returned by
|
|
@@ -1316,6 +1570,21 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
1316
1570
|
* @default 300 (5 minutes)
|
|
1317
1571
|
*/
|
|
1318
1572
|
assertionMaxLifetime?: number;
|
|
1573
|
+
/**
|
|
1574
|
+
* Lets a confidential `private_key_jwt` client replace its own inline `jwks`
|
|
1575
|
+
* at `POST /oauth2/client/rotate-keys`, authenticated by a client assertion
|
|
1576
|
+
* signed with one of its current keys. No user session is involved.
|
|
1577
|
+
*
|
|
1578
|
+
* Clients that publish their keys at a `jwks_uri` rotate them there, so they
|
|
1579
|
+
* cannot use this endpoint.
|
|
1580
|
+
*
|
|
1581
|
+
* Each rotation assertion must be single-use, so the provider refuses to
|
|
1582
|
+
* start with this enabled on the memory adapter or with
|
|
1583
|
+
* `advanced.database.generateId: "serial"`, neither of which enforces it.
|
|
1584
|
+
*
|
|
1585
|
+
* @default false
|
|
1586
|
+
*/
|
|
1587
|
+
allowClientKeyRotation?: boolean;
|
|
1319
1588
|
/**
|
|
1320
1589
|
* Allows /oauth2/public-client-prelogin endpoint to be
|
|
1321
1590
|
* requestable prior to login via a valid oauth_query.
|
|
@@ -1434,14 +1703,16 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
1434
1703
|
* field.
|
|
1435
1704
|
*
|
|
1436
1705
|
* - `"web"`: the OIDC Registration §2 default. Omitted `application_type` is
|
|
1437
|
-
* treated as `web`, so custom-scheme redirect URIs are
|
|
1706
|
+
* treated as `web`, so custom-scheme and loopback redirect URIs are
|
|
1707
|
+
* rejected.
|
|
1438
1708
|
* - `"native"`: omitted `application_type` is treated as `native`.
|
|
1439
1709
|
* - `"infer"`: omitted `application_type` is treated as `native` when any
|
|
1440
|
-
* `redirect_uris` entry uses a non-http(s) scheme
|
|
1441
|
-
*
|
|
1442
|
-
*
|
|
1443
|
-
*
|
|
1444
|
-
*
|
|
1710
|
+
* `redirect_uris` entry uses a non-http(s) scheme or is `http` on
|
|
1711
|
+
* `localhost`, `127.0.0.1`, or `[::1]`; otherwise `web`. Every redirect URI
|
|
1712
|
+
* of an inferred native client is then validated against the native rules.
|
|
1713
|
+
* Lets native MCP clients that omit `application_type` (for example Cursor,
|
|
1714
|
+
* or older Claude Code releases with an `http://127.0.0.1` callback)
|
|
1715
|
+
* register without loosening web-client redirect policy.
|
|
1445
1716
|
*
|
|
1446
1717
|
* An `application_type` the client actually sends is never overridden.
|
|
1447
1718
|
* Applies only to dynamic client registration; managed clients and Client ID
|
|
@@ -1626,7 +1897,8 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
1626
1897
|
*/
|
|
1627
1898
|
page: string;
|
|
1628
1899
|
/**
|
|
1629
|
-
* A value to tie to the consent reference_id.
|
|
1900
|
+
* A value to tie to the consent reference_id. Consent is stored
|
|
1901
|
+
* per reference; `undefined` or `""` uses consent given without one.
|
|
1630
1902
|
*
|
|
1631
1903
|
* Note that YOU must fail in this function if the requested
|
|
1632
1904
|
* scope doesn't have a reference id and it should.
|
|
@@ -1752,6 +2024,14 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
1752
2024
|
*/
|
|
1753
2025
|
requestedClaims: string[];
|
|
1754
2026
|
}) => Awaitable<Record<string, any>>;
|
|
2027
|
+
/**
|
|
2028
|
+
* Asserts the `acr` and `amr` ID token claims for each approved
|
|
2029
|
+
* authorization request.
|
|
2030
|
+
*
|
|
2031
|
+
* Without this option, ID tokens carry `acr: "0"` (OIDC level 0) and no
|
|
2032
|
+
* `amr`.
|
|
2033
|
+
*/
|
|
2034
|
+
authenticationContext?: OAuthAuthenticationContextOptions<Scopes>;
|
|
1755
2035
|
/**
|
|
1756
2036
|
* Custom claims attached to OIDC id tokens.
|
|
1757
2037
|
*
|
|
@@ -1937,6 +2217,7 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
1937
2217
|
* introspect: { window: 60, max: 100 },
|
|
1938
2218
|
* revoke: { window: 60, max: 30 },
|
|
1939
2219
|
* register: { window: 60, max: 5 },
|
|
2220
|
+
* rotateClientKeys: { window: 60, max: 5 },
|
|
1940
2221
|
* userinfo: { window: 60, max: 60 },
|
|
1941
2222
|
* }
|
|
1942
2223
|
* ```
|
|
@@ -1982,6 +2263,14 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
1982
2263
|
window: number;
|
|
1983
2264
|
max: number;
|
|
1984
2265
|
} | false;
|
|
2266
|
+
/**
|
|
2267
|
+
* Rate limit for /oauth2/client/rotate-keys endpoint
|
|
2268
|
+
* @default { window: 60, max: 5 }
|
|
2269
|
+
*/
|
|
2270
|
+
rotateClientKeys?: {
|
|
2271
|
+
window: number;
|
|
2272
|
+
max: number;
|
|
2273
|
+
} | false;
|
|
1985
2274
|
/**
|
|
1986
2275
|
* Rate limit for /oauth2/userinfo endpoint
|
|
1987
2276
|
* @default { window: 60, max: 60 }
|
|
@@ -2282,6 +2571,8 @@ interface VerificationValue {
|
|
|
2282
2571
|
resource?: string[];
|
|
2283
2572
|
referenceId?: string;
|
|
2284
2573
|
authTime?: number;
|
|
2574
|
+
acr?: string;
|
|
2575
|
+
amr?: string[];
|
|
2285
2576
|
}
|
|
2286
2577
|
/**
|
|
2287
2578
|
* Client registered values as used within the plugin
|
|
@@ -2378,6 +2669,25 @@ interface SchemaClient<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
2378
2669
|
* @default false
|
|
2379
2670
|
*/
|
|
2380
2671
|
backchannelLogoutSessionRequired?: boolean;
|
|
2672
|
+
/**
|
|
2673
|
+
* RP URL rendered in a hidden iframe on the OP's logout page when the
|
|
2674
|
+
* end-user's session ends at `/oauth2/end-session`. Registering it is the
|
|
2675
|
+
* per-client opt-in for front-channel logout. Must be absolute, without a
|
|
2676
|
+
* fragment, and share the scheme, host, and port of a registered redirect
|
|
2677
|
+
* URI.
|
|
2678
|
+
*
|
|
2679
|
+
* @see https://openid.net/specs/openid-connect-frontchannel-1_0.html#RPLogout
|
|
2680
|
+
*/
|
|
2681
|
+
frontchannelLogoutUri?: string;
|
|
2682
|
+
/**
|
|
2683
|
+
* When true, the RP requires `iss` and `sid` query parameters on its
|
|
2684
|
+
* front-channel logout URI. The OP includes both whenever it notifies a
|
|
2685
|
+
* front-channel client, so this flag is stored but does not change
|
|
2686
|
+
* delivery.
|
|
2687
|
+
*
|
|
2688
|
+
* @default false
|
|
2689
|
+
*/
|
|
2690
|
+
frontchannelLogoutSessionRequired?: boolean;
|
|
2381
2691
|
tokenEndpointAuthMethod?: TokenEndpointAuthMethod;
|
|
2382
2692
|
grantTypes?: GrantType[];
|
|
2383
2693
|
responseTypes?: "code"[];
|
|
@@ -2410,6 +2720,12 @@ interface SchemaClient<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
2410
2720
|
enableEndSession?: boolean;
|
|
2411
2721
|
/** Subject identifier type: "public" (default) or "pairwise" */
|
|
2412
2722
|
subjectType?: "public" | "pairwise";
|
|
2723
|
+
/**
|
|
2724
|
+
* Pairwise sector, set by the server when the client is created. `null`
|
|
2725
|
+
* for clients created before sectors were stored; those keep the sector
|
|
2726
|
+
* derived from their first redirect URI host.
|
|
2727
|
+
*/
|
|
2728
|
+
sectorIdentifier?: string | null;
|
|
2413
2729
|
/** Reference to the owner of this client. Eg. Organization, Team, Profile */
|
|
2414
2730
|
referenceId?: string;
|
|
2415
2731
|
/**
|
|
@@ -2526,6 +2842,10 @@ interface OAuthRefreshToken<Scopes extends readonly Scope[] = InternallySupporte
|
|
|
2526
2842
|
* Persisted so refreshed ID tokens can include a correct `auth_time` claim.
|
|
2527
2843
|
*/
|
|
2528
2844
|
authTime?: Date;
|
|
2845
|
+
/** The `acr` asserted at authorization, carried forward on rotation. */
|
|
2846
|
+
acr?: string;
|
|
2847
|
+
/** The `amr` asserted at authorization, carried forward on rotation. */
|
|
2848
|
+
amr?: string[];
|
|
2529
2849
|
/**
|
|
2530
2850
|
* Scopes granted for this refresh token.
|
|
2531
2851
|
*
|
|
@@ -2791,6 +3111,27 @@ interface AuthServerMetadata {
|
|
|
2791
3111
|
* @see https://datatracker.ietf.org/doc/html/rfc9449
|
|
2792
3112
|
*/
|
|
2793
3113
|
dpop_signing_alg_values_supported?: JWSAlgorithms[];
|
|
3114
|
+
/**
|
|
3115
|
+
* Boolean value specifying whether the OP supports HTTP-based (front-channel)
|
|
3116
|
+
* logout, with true indicating support.
|
|
3117
|
+
*
|
|
3118
|
+
* Registered in the "OAuth Authorization Server Metadata" IANA registry
|
|
3119
|
+
* under OpenID Connect Front-Channel Logout 1.0, so this may appear at both
|
|
3120
|
+
* `.well-known/oauth-authorization-server` and `.well-known/openid-configuration`.
|
|
3121
|
+
*
|
|
3122
|
+
* @default false
|
|
3123
|
+
* @see https://openid.net/specs/openid-connect-frontchannel-1_0.html#OPLogout
|
|
3124
|
+
*/
|
|
3125
|
+
frontchannel_logout_supported?: boolean;
|
|
3126
|
+
/**
|
|
3127
|
+
* Boolean value specifying whether the OP can pass `iss` (issuer) and `sid`
|
|
3128
|
+
* (session ID) query parameters to identify the RP session with the OP when
|
|
3129
|
+
* the `frontchannel_logout_uri` is used.
|
|
3130
|
+
*
|
|
3131
|
+
* @default false
|
|
3132
|
+
* @see https://openid.net/specs/openid-connect-frontchannel-1_0.html#OPLogout
|
|
3133
|
+
*/
|
|
3134
|
+
frontchannel_logout_session_supported?: boolean;
|
|
2794
3135
|
}
|
|
2795
3136
|
/**
|
|
2796
3137
|
* Metadata returned by the openid-configuration endpoint:
|
|
@@ -2930,6 +3271,25 @@ interface OAuthClient {
|
|
|
2930
3271
|
* @see https://openid.net/specs/openid-connect-backchannel-1_0.html#RPMetadata
|
|
2931
3272
|
*/
|
|
2932
3273
|
backchannel_logout_session_required?: boolean;
|
|
3274
|
+
/**
|
|
3275
|
+
* RP URL that the OP renders in a hidden iframe on its logout page so the
|
|
3276
|
+
* RP can log itself out when the end-user's OP session ends at
|
|
3277
|
+
* `/oauth2/end-session`. Must share the scheme, host, and port of one of
|
|
3278
|
+
* the client's `redirect_uris`.
|
|
3279
|
+
*
|
|
3280
|
+
* @see https://openid.net/specs/openid-connect-frontchannel-1_0.html#RPLogout
|
|
3281
|
+
*/
|
|
3282
|
+
frontchannel_logout_uri?: string;
|
|
3283
|
+
/**
|
|
3284
|
+
* When true, the RP requires `iss` and `sid` query parameters on its
|
|
3285
|
+
* `frontchannel_logout_uri`. The OP includes both whenever it notifies a
|
|
3286
|
+
* front-channel client, so this flag is stored but does not change
|
|
3287
|
+
* delivery.
|
|
3288
|
+
*
|
|
3289
|
+
* @default false
|
|
3290
|
+
* @see https://openid.net/specs/openid-connect-frontchannel-1_0.html#RPLogout
|
|
3291
|
+
*/
|
|
3292
|
+
frontchannel_logout_session_required?: boolean;
|
|
2933
3293
|
token_endpoint_auth_method?: TokenEndpointAuthMethod;
|
|
2934
3294
|
grant_types?: GrantType[];
|
|
2935
3295
|
response_types?: "code"[];
|
|
@@ -3007,4 +3367,4 @@ interface ResourceServerMetadata {
|
|
|
3007
3367
|
dpop_bound_access_tokens_required?: boolean;
|
|
3008
3368
|
}
|
|
3009
3369
|
//#endregion
|
|
3010
|
-
export {
|
|
3370
|
+
export { OAuthClientMetadata as $, OAuthExtensionGrantHandler as A, OAuthRefreshToken as B, OAuthClientAuthenticationRequest as C, OAuthClientRegistrationResponse as D, OAuthClientMetadataExtensionInput as E, OAuthMetadataExtensionInput as F, OAuthUserInfoExtensionInput as G, OAuthResourceInput as H, OAuthOpaqueAccessToken as I, Scope as J, Prompt as K, OAuthOptions as L, OAuthInteractionQuery as M, OAuthInteractionRequest as N, OAuthClientResource as O, OAuthInteractionRequestHandler as P, ClientRegistrationRequest as Q, OAuthProviderApi as R, OAuthClientAuthenticationInput as S, OAuthClientAuthenticationStrategy as T, OAuthTokenIssueParams as U, OAuthResource as V, OAuthTokenResponse as W, StoredAuthorizationQuery as X, StoreTokenType as Y, VerificationValue as Z, OAuthAuthenticationContext as _, GrantType as a, OAuthClientRegistrationResult as at, OAuthClaimExtensionInput as b, ResourceServerMetadata as c, registerClientMetadataDocument as ct, ActiveAccessTokenPayload as d, ResourceUriSchema as et, AuthorizePrompt as f, OAuthAuthenticatedClient as g, InitialAccessTokenAuthorization as h, Confirmation as i, OAuthClientRegistrationMetadata as it, OAuthExtensionGrantHandlerInput as j, OAuthConsent as k, TokenEndpointAuthMethod as l, ClientMetadataResourceFetch as m, AuthServerMetadata as n, oauthClientMetadataSchema as nt, OAuthClient as o, RegisterClientMetadataDocumentInput as ot, ClientDiscovery as p, SchemaClient as q, BearerMethodsSupported as r, Awaitable as rt, OIDCMetadata as s, assertPublicRoutableHttpsUri as st, AuthMethod as t, clientRegistrationRequestSchema as tt, TokenType as u, OAuthAuthenticationContextOptions as v, OAuthClientAuthenticationResult as w, OAuthClientAdministrativeResponse as x, OAuthAuthorizationQuery as y, OAuthProviderExtension as z };
|