@better-auth/oauth-provider 1.7.0-beta.0 → 1.7.0-beta.2
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/{client-assertion-DZqo-L5j.mjs → client-assertion-CderPEmR.mjs} +12 -3
- 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.d.mts +50 -6
- package/dist/index.mjs +467 -237
- package/dist/{oauth-C8aTlaAC.d.mts → oauth-CU79t-eG.d.mts} +102 -5
- package/dist/{oauth-Dh4YXCXY.d.mts → oauth-DJcZ8MMZ.d.mts} +152 -23
- package/dist/{utils-CIbcUsZ5.mjs → utils-Cx_XnD9i.mjs} +35 -3
- package/dist/{version-BGWhjYBb.mjs → version-CZxZ64qJ.mjs} +1 -1
- package/package.json +5 -5
|
@@ -315,6 +315,46 @@ type InternallySupportedScopes = "openid" | "profile" | "email" | "offline_acces
|
|
|
315
315
|
type Scope = LiteralString | InternallySupportedScopes;
|
|
316
316
|
type Prompt = "none" | "consent" | "login" | "create" | "select_account";
|
|
317
317
|
type AuthorizePrompt = Prompt | "login consent" | "select_account consent";
|
|
318
|
+
/**
|
|
319
|
+
* Describes how to resolve a `client_id` from an external source (a URL-based
|
|
320
|
+
* metadata document, a federated registry, an attestation header, etc.) and
|
|
321
|
+
* what fields that source contributes to discovery metadata.
|
|
322
|
+
*
|
|
323
|
+
* Plugins install one of these onto {@link OAuthOptions.clientDiscovery}.
|
|
324
|
+
* The host walks the configured entries in order and returns the first
|
|
325
|
+
* non-null `resolve()` result.
|
|
326
|
+
*/
|
|
327
|
+
interface ClientDiscovery<Scopes extends readonly Scope[] = InternallySupportedScopes[]> {
|
|
328
|
+
/**
|
|
329
|
+
* Stable identifier used in error messages and diagnostics. Convention
|
|
330
|
+
* is to match the plugin id (for example `"cimd"`).
|
|
331
|
+
*/
|
|
332
|
+
readonly id: string;
|
|
333
|
+
/**
|
|
334
|
+
* Return `true` if this discovery handles the given `client_id`. Called
|
|
335
|
+
* on every `getClient()` lookup for every configured discovery, so keep
|
|
336
|
+
* it cheap and synchronous.
|
|
337
|
+
*/
|
|
338
|
+
matches: (clientId: string) => boolean;
|
|
339
|
+
/**
|
|
340
|
+
* Resolve a client when this discovery matches. Receives the existing DB
|
|
341
|
+
* record (or `null`) so an implementation can decide between creating,
|
|
342
|
+
* refreshing, or passing through to the database result.
|
|
343
|
+
*
|
|
344
|
+
* Return:
|
|
345
|
+
* - a client record: `getClient()` returns it (creation / refresh / takeover).
|
|
346
|
+
* - `null`: `getClient()` falls through to the next matching discovery
|
|
347
|
+
* or to the database record (if any).
|
|
348
|
+
*/
|
|
349
|
+
resolve: (ctx: GenericEndpointContext, clientId: string, existing: SchemaClient<Scopes> | null) => Awaitable<SchemaClient<Scopes> | null>;
|
|
350
|
+
/**
|
|
351
|
+
* Fields merged into `/.well-known/oauth-authorization-server` and
|
|
352
|
+
* `/.well-known/openid-configuration` responses. Useful for advertising
|
|
353
|
+
* RFC-registered discovery flags like
|
|
354
|
+
* `client_id_metadata_document_supported`.
|
|
355
|
+
*/
|
|
356
|
+
discoveryMetadata?: Record<string, unknown>;
|
|
357
|
+
}
|
|
318
358
|
interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScopes[]> {
|
|
319
359
|
/**
|
|
320
360
|
* Custom schema definitions
|
|
@@ -412,10 +452,13 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
412
452
|
/**
|
|
413
453
|
* Allow unauthenticated dynamic client registration.
|
|
414
454
|
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
455
|
+
* When enabled, the `/oauth2/register` endpoint accepts requests
|
|
456
|
+
* without a session, but only for public clients
|
|
457
|
+
* (`token_endpoint_auth_method: "none"`).
|
|
458
|
+
*
|
|
459
|
+
* For verified client discovery (MCP), consider installing the
|
|
460
|
+
* `@better-auth/cimd` plugin, which verifies client identity through
|
|
461
|
+
* domain ownership via Client ID Metadata Documents.
|
|
419
462
|
*
|
|
420
463
|
* @default false
|
|
421
464
|
*/
|
|
@@ -426,6 +469,21 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
426
469
|
* @default false
|
|
427
470
|
*/
|
|
428
471
|
allowDynamicClientRegistration?: boolean;
|
|
472
|
+
/**
|
|
473
|
+
* Discovery implementations consulted by `getClient()` when resolving
|
|
474
|
+
* a `client_id`. Each entry decides whether it handles the `client_id`
|
|
475
|
+
* via {@link ClientDiscovery.matches}, then creates, refreshes, or
|
|
476
|
+
* passes on a client record. Entries run in order; the first one to
|
|
477
|
+
* return a client wins.
|
|
478
|
+
*
|
|
479
|
+
* Each entry also contributes {@link ClientDiscovery.discoveryMetadata}
|
|
480
|
+
* into the `/.well-known/oauth-authorization-server` and
|
|
481
|
+
* `/.well-known/openid-configuration` responses.
|
|
482
|
+
*
|
|
483
|
+
* Plugins such as `@better-auth/cimd` install an entry here at init
|
|
484
|
+
* time; users can also pass discovery implementations directly.
|
|
485
|
+
*/
|
|
486
|
+
clientDiscovery?: ClientDiscovery<Scopes> | ClientDiscovery<Scopes>[];
|
|
429
487
|
/**
|
|
430
488
|
* List of scopes for newly registered clients
|
|
431
489
|
* if not requested.
|
|
@@ -768,6 +826,34 @@ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScop
|
|
|
768
826
|
resource?: string; /** oAuthClient metadata */
|
|
769
827
|
metadata?: Record<string, any>;
|
|
770
828
|
}) => Awaitable<Record<string, any>>;
|
|
829
|
+
/**
|
|
830
|
+
* Custom fields to include in the token response body.
|
|
831
|
+
*
|
|
832
|
+
* Unlike `customAccessTokenClaims` (which adds claims inside the JWT payload),
|
|
833
|
+
* this adds fields to the JSON response envelope alongside `access_token`,
|
|
834
|
+
* `token_type`, etc. Standard OAuth fields (`access_token`, `token_type`,
|
|
835
|
+
* `expires_in`, `expires_at`, `refresh_token`, `scope`, `id_token`) cannot
|
|
836
|
+
* be overridden.
|
|
837
|
+
*
|
|
838
|
+
* @param info - context that may be useful when creating custom fields
|
|
839
|
+
*/
|
|
840
|
+
customTokenResponseFields?: (info: {
|
|
841
|
+
/** The grant type being processed */grantType: GrantType;
|
|
842
|
+
/**
|
|
843
|
+
* The user, if applicable.
|
|
844
|
+
* Undefined for `client_credentials` (M2M, no user).
|
|
845
|
+
* Always present for `authorization_code` and `refresh_token`.
|
|
846
|
+
*/
|
|
847
|
+
user?: (User & Record<string, unknown>) | null; /** Scopes granted for this token */
|
|
848
|
+
scopes: Scopes; /** oAuthClient metadata */
|
|
849
|
+
metadata?: Record<string, any>;
|
|
850
|
+
/**
|
|
851
|
+
* The authorization code verification value.
|
|
852
|
+
* Only present for `authorization_code` grant. Contains the original
|
|
853
|
+
* authorization request parameters (`query`), `referenceId`, `sessionId`, etc.
|
|
854
|
+
*/
|
|
855
|
+
verificationValue?: VerificationValue;
|
|
856
|
+
}) => Awaitable<Record<string, unknown>>;
|
|
771
857
|
/**
|
|
772
858
|
* Overwrite specific /.well-known/openid-configuration
|
|
773
859
|
* values so they are not available publically.
|
|
@@ -1476,6 +1562,17 @@ interface AuthServerMetadata {
|
|
|
1476
1562
|
* @default true
|
|
1477
1563
|
*/
|
|
1478
1564
|
authorization_response_iss_parameter_supported?: boolean;
|
|
1565
|
+
/**
|
|
1566
|
+
* Whether the authorization server supports discovering clients via
|
|
1567
|
+
* [Client ID Metadata Documents](https://datatracker.ietf.org/doc/draft-ietf-oauth-client-id-metadata-document/)
|
|
1568
|
+
* (an HTTPS URL as `client_id`).
|
|
1569
|
+
*
|
|
1570
|
+
* Set at runtime by the `@better-auth/cimd` plugin (or any other
|
|
1571
|
+
* `ClientDiscovery` that contributes this field via
|
|
1572
|
+
* {@link ClientDiscovery.discoveryMetadata}). oauth-provider never sets
|
|
1573
|
+
* it on its own.
|
|
1574
|
+
*/
|
|
1575
|
+
client_id_metadata_document_supported?: boolean;
|
|
1479
1576
|
}
|
|
1480
1577
|
/**
|
|
1481
1578
|
* Metadata returned by the openid-configuration endpoint:
|
|
@@ -1642,4 +1739,4 @@ interface ResourceServerMetadata {
|
|
|
1642
1739
|
dpop_bound_access_tokens_required?: boolean;
|
|
1643
1740
|
}
|
|
1644
1741
|
//#endregion
|
|
1645
|
-
export {
|
|
1742
|
+
export { Scope as _, OIDCMetadata as a, Awaitable as b, AuthorizePrompt as c, OAuthConsent as d, OAuthOpaqueAccessToken as f, SchemaClient as g, Prompt as h, OAuthClient as i, ClientDiscovery as l, OAuthRefreshToken as m, AuthServerMetadata as n, ResourceServerMetadata as o, OAuthOptions as p, GrantType as r, TokenEndpointAuthMethod as s, AuthMethod as t, OAuthAuthorizationQuery as u, StoreTokenType as v, VerificationValue as y };
|
|
@@ -1,10 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as Scope, d as OAuthConsent, h as Prompt, i as OAuthClient, p as OAuthOptions, r as GrantType, s as TokenEndpointAuthMethod, t as AuthMethod } from "./oauth-CU79t-eG.mjs";
|
|
2
2
|
import * as better_call0 from "better-call";
|
|
3
3
|
import * as z from "zod";
|
|
4
4
|
import * as better_auth_plugins0 from "better-auth/plugins";
|
|
5
5
|
import * as jose from "jose";
|
|
6
6
|
import * as better_auth0 from "better-auth";
|
|
7
7
|
|
|
8
|
+
//#region src/oauth-endpoint.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* Canonical OAuth 2.0 / OpenID Connect error codes. The union is the single
|
|
11
|
+
* vocabulary for every error-emitting surface in this plugin: token, authorize,
|
|
12
|
+
* revoke, introspect, register, userinfo, logout, consent, and the redirect
|
|
13
|
+
* error channel. Entries are grouped by source RFC so the declaration doubles
|
|
14
|
+
* as a specification map.
|
|
15
|
+
*
|
|
16
|
+
* The trailing `(string & {})` keeps the type open for product-specific codes
|
|
17
|
+
* (e.g. `"invalid_verification"`, `"invalid_user"`) while preserving editor
|
|
18
|
+
* autocomplete for the listed standard codes. Prefer a standard code whenever
|
|
19
|
+
* one applies; fall back to a custom string only for states no RFC covers.
|
|
20
|
+
*/
|
|
21
|
+
type OAuthErrorCode = "invalid_request" | "invalid_client" | "invalid_grant" | "unauthorized_client" | "unsupported_grant_type" | "unsupported_response_type" | "invalid_scope" | "access_denied" | "server_error" | "temporarily_unavailable" | "invalid_token" | "unsupported_token_type" | "invalid_redirect_uri" | "invalid_client_metadata" | "invalid_software_statement" | "unapproved_software_statement" | "invalid_target" | "invalid_request_object" | "login_required" | "consent_required" | "interaction_required" | "account_selection_required" | "invalid_request_uri" | "request_not_supported" | "request_uri_not_supported" | "registration_not_supported" | (string & {});
|
|
22
|
+
type OAuthFieldErrorCodeMap = {
|
|
23
|
+
missing?: OAuthErrorCode;
|
|
24
|
+
invalid?: OAuthErrorCode;
|
|
25
|
+
};
|
|
26
|
+
type OAuthFieldErrorCode = OAuthErrorCode | OAuthFieldErrorCodeMap;
|
|
27
|
+
interface OAuthEndpointErrorResult {
|
|
28
|
+
error: OAuthErrorCode;
|
|
29
|
+
error_description: string;
|
|
30
|
+
}
|
|
31
|
+
interface OAuthEndpointRedirectContext<Ctx = unknown> {
|
|
32
|
+
error: OAuthErrorCode;
|
|
33
|
+
error_description: string;
|
|
34
|
+
ctx: Ctx;
|
|
35
|
+
}
|
|
36
|
+
type OAuthRedirectOnError<Ctx = any> = (result: OAuthEndpointRedirectContext<Ctx>) => unknown;
|
|
37
|
+
//#endregion
|
|
8
38
|
//#region src/oauth.d.ts
|
|
9
39
|
declare module "@better-auth/core" {
|
|
10
40
|
interface BetterAuthPluginRegistry<AuthOptions, Options> {
|
|
@@ -54,7 +84,64 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
54
84
|
metadata: {
|
|
55
85
|
SERVER_ONLY: true;
|
|
56
86
|
};
|
|
57
|
-
},
|
|
87
|
+
}, {
|
|
88
|
+
jwks_uri?: string | undefined;
|
|
89
|
+
userinfo_endpoint: string;
|
|
90
|
+
acr_values_supported: string[];
|
|
91
|
+
subject_types_supported: ("public" | "pairwise")[];
|
|
92
|
+
claims_supported: string[];
|
|
93
|
+
end_session_endpoint: string;
|
|
94
|
+
prompt_values_supported: Prompt[];
|
|
95
|
+
issuer: string;
|
|
96
|
+
authorization_endpoint: string;
|
|
97
|
+
token_endpoint: string;
|
|
98
|
+
registration_endpoint: string;
|
|
99
|
+
scopes_supported?: string[] | undefined;
|
|
100
|
+
response_types_supported: "code"[];
|
|
101
|
+
response_modes_supported: "query"[];
|
|
102
|
+
grant_types_supported: GrantType[];
|
|
103
|
+
token_endpoint_auth_methods_supported?: TokenEndpointAuthMethod[] | undefined;
|
|
104
|
+
token_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[] | undefined;
|
|
105
|
+
service_documentation?: string | undefined;
|
|
106
|
+
ui_locales_supported?: string[] | undefined;
|
|
107
|
+
op_policy_uri?: string | undefined;
|
|
108
|
+
op_tos_uri?: string | undefined;
|
|
109
|
+
revocation_endpoint?: string | undefined;
|
|
110
|
+
revocation_endpoint_auth_methods_supported?: AuthMethod[] | undefined;
|
|
111
|
+
revocation_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[] | undefined;
|
|
112
|
+
introspection_endpoint?: string | undefined;
|
|
113
|
+
introspection_endpoint_auth_methods_supported?: AuthMethod[] | undefined;
|
|
114
|
+
introspection_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[] | undefined;
|
|
115
|
+
code_challenge_methods_supported: "S256"[];
|
|
116
|
+
authorization_response_iss_parameter_supported?: boolean | undefined;
|
|
117
|
+
client_id_metadata_document_supported?: boolean | undefined;
|
|
118
|
+
id_token_signing_alg_values_supported: better_auth_plugins0.JWSAlgorithms[] | ["HS256"];
|
|
119
|
+
} | {
|
|
120
|
+
issuer: string;
|
|
121
|
+
authorization_endpoint: string;
|
|
122
|
+
token_endpoint: string;
|
|
123
|
+
jwks_uri?: string;
|
|
124
|
+
registration_endpoint: string;
|
|
125
|
+
scopes_supported?: string[];
|
|
126
|
+
response_types_supported: "code"[];
|
|
127
|
+
response_modes_supported: "query"[];
|
|
128
|
+
grant_types_supported: GrantType[];
|
|
129
|
+
token_endpoint_auth_methods_supported?: TokenEndpointAuthMethod[];
|
|
130
|
+
token_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[];
|
|
131
|
+
service_documentation?: string;
|
|
132
|
+
ui_locales_supported?: string[];
|
|
133
|
+
op_policy_uri?: string;
|
|
134
|
+
op_tos_uri?: string;
|
|
135
|
+
revocation_endpoint?: string;
|
|
136
|
+
revocation_endpoint_auth_methods_supported?: AuthMethod[];
|
|
137
|
+
revocation_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[];
|
|
138
|
+
introspection_endpoint?: string;
|
|
139
|
+
introspection_endpoint_auth_methods_supported?: AuthMethod[];
|
|
140
|
+
introspection_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[];
|
|
141
|
+
code_challenge_methods_supported: "S256"[];
|
|
142
|
+
authorization_response_iss_parameter_supported?: boolean;
|
|
143
|
+
client_id_metadata_document_supported?: boolean;
|
|
144
|
+
}>;
|
|
58
145
|
/**
|
|
59
146
|
* A server-only endpoint that helps provide the
|
|
60
147
|
* OpenId configuration at the well-known endpoint.
|
|
@@ -67,26 +154,56 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
67
154
|
metadata: {
|
|
68
155
|
SERVER_ONLY: true;
|
|
69
156
|
};
|
|
70
|
-
},
|
|
157
|
+
}, {
|
|
158
|
+
jwks_uri?: string | undefined;
|
|
159
|
+
userinfo_endpoint: string;
|
|
160
|
+
acr_values_supported: string[];
|
|
161
|
+
subject_types_supported: ("public" | "pairwise")[];
|
|
162
|
+
claims_supported: string[];
|
|
163
|
+
end_session_endpoint: string;
|
|
164
|
+
prompt_values_supported: Prompt[];
|
|
165
|
+
issuer: string;
|
|
166
|
+
authorization_endpoint: string;
|
|
167
|
+
token_endpoint: string;
|
|
168
|
+
registration_endpoint: string;
|
|
169
|
+
scopes_supported?: string[] | undefined;
|
|
170
|
+
response_types_supported: "code"[];
|
|
171
|
+
response_modes_supported: "query"[];
|
|
172
|
+
grant_types_supported: GrantType[];
|
|
173
|
+
token_endpoint_auth_methods_supported?: TokenEndpointAuthMethod[] | undefined;
|
|
174
|
+
token_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[] | undefined;
|
|
175
|
+
service_documentation?: string | undefined;
|
|
176
|
+
ui_locales_supported?: string[] | undefined;
|
|
177
|
+
op_policy_uri?: string | undefined;
|
|
178
|
+
op_tos_uri?: string | undefined;
|
|
179
|
+
revocation_endpoint?: string | undefined;
|
|
180
|
+
revocation_endpoint_auth_methods_supported?: AuthMethod[] | undefined;
|
|
181
|
+
revocation_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[] | undefined;
|
|
182
|
+
introspection_endpoint?: string | undefined;
|
|
183
|
+
introspection_endpoint_auth_methods_supported?: AuthMethod[] | undefined;
|
|
184
|
+
introspection_endpoint_auth_signing_alg_values_supported?: better_auth0.AssertionSigningAlgorithm[] | undefined;
|
|
185
|
+
code_challenge_methods_supported: "S256"[];
|
|
186
|
+
authorization_response_iss_parameter_supported?: boolean | undefined;
|
|
187
|
+
client_id_metadata_document_supported?: boolean | undefined;
|
|
71
188
|
id_token_signing_alg_values_supported: better_auth_plugins0.JWSAlgorithms[] | ["HS256"];
|
|
72
189
|
}>;
|
|
73
190
|
oauth2Authorize: better_call0.StrictEndpoint<"/oauth2/authorize", {
|
|
74
191
|
method: "GET";
|
|
75
192
|
query: z.ZodObject<{
|
|
76
|
-
response_type: z.ZodOptional<z.ZodEnum<{
|
|
193
|
+
response_type: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodEnum<{
|
|
77
194
|
code: "code";
|
|
78
|
-
}
|
|
195
|
+
}>>>;
|
|
79
196
|
client_id: z.ZodString;
|
|
80
197
|
redirect_uri: z.ZodOptional<z.ZodURL>;
|
|
81
198
|
scope: z.ZodOptional<z.ZodString>;
|
|
82
199
|
state: z.ZodOptional<z.ZodString>;
|
|
83
200
|
request_uri: z.ZodOptional<z.ZodString>;
|
|
84
201
|
code_challenge: z.ZodOptional<z.ZodString>;
|
|
85
|
-
code_challenge_method: z.ZodOptional<z.ZodEnum<{
|
|
202
|
+
code_challenge_method: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodEnum<{
|
|
86
203
|
S256: "S256";
|
|
87
|
-
}
|
|
204
|
+
}>>>;
|
|
88
205
|
nonce: z.ZodOptional<z.ZodString>;
|
|
89
|
-
prompt: z.ZodOptional<z.ZodEnum<{
|
|
206
|
+
prompt: z.ZodOptional<z.ZodPipe<z.ZodString, z.ZodEnum<{
|
|
90
207
|
none: "none";
|
|
91
208
|
consent: "consent";
|
|
92
209
|
login: "login";
|
|
@@ -94,8 +211,14 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
94
211
|
select_account: "select_account";
|
|
95
212
|
"login consent": "login consent";
|
|
96
213
|
"select_account consent": "select_account consent";
|
|
97
|
-
}
|
|
214
|
+
}>>>;
|
|
98
215
|
}, z.core.$strip>;
|
|
216
|
+
redirectOnError: OAuthRedirectOnError<better_auth0.GenericEndpointContext>;
|
|
217
|
+
errorCodesByField: {
|
|
218
|
+
response_type: {
|
|
219
|
+
invalid: "unsupported_response_type";
|
|
220
|
+
};
|
|
221
|
+
};
|
|
99
222
|
metadata: {
|
|
100
223
|
openapi: {
|
|
101
224
|
description: string;
|
|
@@ -291,11 +414,11 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
291
414
|
oauth2Token: better_call0.StrictEndpoint<"/oauth2/token", {
|
|
292
415
|
method: "POST";
|
|
293
416
|
body: z.ZodObject<{
|
|
294
|
-
grant_type: z.ZodEnum<{
|
|
417
|
+
grant_type: z.ZodPipe<z.ZodString, z.ZodEnum<{
|
|
295
418
|
authorization_code: "authorization_code";
|
|
296
419
|
client_credentials: "client_credentials";
|
|
297
420
|
refresh_token: "refresh_token";
|
|
298
|
-
}
|
|
421
|
+
}>>;
|
|
299
422
|
client_id: z.ZodOptional<z.ZodString>;
|
|
300
423
|
client_secret: z.ZodOptional<z.ZodString>;
|
|
301
424
|
client_assertion: z.ZodOptional<z.ZodString>;
|
|
@@ -307,6 +430,12 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
307
430
|
resource: z.ZodOptional<z.ZodString>;
|
|
308
431
|
scope: z.ZodOptional<z.ZodString>;
|
|
309
432
|
}, z.core.$strip>;
|
|
433
|
+
errorCodesByField: {
|
|
434
|
+
grant_type: {
|
|
435
|
+
missing: "invalid_request";
|
|
436
|
+
invalid: "unsupported_grant_type";
|
|
437
|
+
};
|
|
438
|
+
};
|
|
310
439
|
metadata: {
|
|
311
440
|
allowedMediaTypes: string[];
|
|
312
441
|
openapi: {
|
|
@@ -430,8 +559,10 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
430
559
|
access_token: string;
|
|
431
560
|
expires_in: number;
|
|
432
561
|
expires_at: number;
|
|
433
|
-
token_type:
|
|
562
|
+
token_type: "Bearer";
|
|
563
|
+
refresh_token: string | undefined;
|
|
434
564
|
scope: string;
|
|
565
|
+
id_token: string | undefined;
|
|
435
566
|
}>;
|
|
436
567
|
oauth2Introspect: better_call0.StrictEndpoint<"/oauth2/introspect", {
|
|
437
568
|
method: "POST";
|
|
@@ -441,10 +572,7 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
441
572
|
client_assertion: z.ZodOptional<z.ZodString>;
|
|
442
573
|
client_assertion_type: z.ZodOptional<z.ZodString>;
|
|
443
574
|
token: z.ZodString;
|
|
444
|
-
token_type_hint: z.ZodOptional<z.
|
|
445
|
-
refresh_token: "refresh_token";
|
|
446
|
-
access_token: "access_token";
|
|
447
|
-
}>>;
|
|
575
|
+
token_type_hint: z.ZodOptional<z.ZodString>;
|
|
448
576
|
}, z.core.$strip>;
|
|
449
577
|
metadata: {
|
|
450
578
|
allowedMediaTypes: string[];
|
|
@@ -471,7 +599,6 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
471
599
|
};
|
|
472
600
|
token_type_hint: {
|
|
473
601
|
type: string;
|
|
474
|
-
enum: string[];
|
|
475
602
|
description: string;
|
|
476
603
|
};
|
|
477
604
|
resource: {
|
|
@@ -580,10 +707,7 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
580
707
|
client_assertion: z.ZodOptional<z.ZodString>;
|
|
581
708
|
client_assertion_type: z.ZodOptional<z.ZodString>;
|
|
582
709
|
token: z.ZodString;
|
|
583
|
-
token_type_hint: z.ZodOptional<z.
|
|
584
|
-
refresh_token: "refresh_token";
|
|
585
|
-
access_token: "access_token";
|
|
586
|
-
}>>;
|
|
710
|
+
token_type_hint: z.ZodOptional<z.ZodString>;
|
|
587
711
|
}, z.core.$strip>;
|
|
588
712
|
metadata: {
|
|
589
713
|
allowedMediaTypes: string[];
|
|
@@ -610,7 +734,6 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
610
734
|
};
|
|
611
735
|
token_type_hint: {
|
|
612
736
|
type: string;
|
|
613
|
-
enum: string[];
|
|
614
737
|
description: string;
|
|
615
738
|
};
|
|
616
739
|
};
|
|
@@ -862,6 +985,12 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
862
985
|
}>>;
|
|
863
986
|
skip_consent: z.ZodOptional<z.ZodNever>;
|
|
864
987
|
}, z.core.$strip>;
|
|
988
|
+
errorCodesByField: {
|
|
989
|
+
redirect_uris: "invalid_redirect_uri";
|
|
990
|
+
post_logout_redirect_uris: "invalid_redirect_uri";
|
|
991
|
+
software_statement: "invalid_software_statement";
|
|
992
|
+
};
|
|
993
|
+
defaultError: "invalid_client_metadata";
|
|
865
994
|
metadata: {
|
|
866
995
|
openapi: {
|
|
867
996
|
description: string;
|
|
@@ -2107,4 +2236,4 @@ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => {
|
|
|
2107
2236
|
})[];
|
|
2108
2237
|
};
|
|
2109
2238
|
//#endregion
|
|
2110
|
-
export { oauthProvider as n, getOAuthProviderState as t };
|
|
2239
|
+
export { OAuthErrorCode as a, OAuthRedirectOnError as c, OAuthEndpointRedirectContext as i, oauthProvider as n, OAuthFieldErrorCode as o, OAuthEndpointErrorResult as r, OAuthFieldErrorCodeMap as s, getOAuthProviderState as t };
|
|
@@ -89,17 +89,49 @@ async function verifyOAuthQueryParams(oauth_query, secret) {
|
|
|
89
89
|
async function getClient(ctx, options, clientId) {
|
|
90
90
|
const trustedClient = cachedTrustedClients.get(clientId);
|
|
91
91
|
if (trustedClient) return Object.assign({}, trustedClient);
|
|
92
|
-
|
|
92
|
+
let dbClient = await ctx.context.adapter.findOne({
|
|
93
93
|
model: options.schema?.oauthClient?.modelName ?? "oauthClient",
|
|
94
94
|
where: [{
|
|
95
95
|
field: "clientId",
|
|
96
96
|
value: clientId
|
|
97
97
|
}]
|
|
98
98
|
});
|
|
99
|
+
const discoveries = toClientDiscoveryArray(options.clientDiscovery);
|
|
100
|
+
for (const discovery of discoveries) {
|
|
101
|
+
if (!discovery.matches(clientId)) continue;
|
|
102
|
+
const resolved = await discovery.resolve(ctx, clientId, dbClient);
|
|
103
|
+
if (resolved) {
|
|
104
|
+
dbClient = resolved;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
99
108
|
if (dbClient && options.cachedTrustedClients?.has(clientId)) cachedTrustedClients.set(clientId, Object.assign({}, dbClient));
|
|
100
109
|
return dbClient;
|
|
101
110
|
}
|
|
102
111
|
/**
|
|
112
|
+
* Normalize the `clientDiscovery` option into an array. Accepts a single
|
|
113
|
+
* {@link ClientDiscovery}, an array of them, or `undefined`.
|
|
114
|
+
*
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
function toClientDiscoveryArray(discovery) {
|
|
118
|
+
if (!discovery) return [];
|
|
119
|
+
return Array.isArray(discovery) ? discovery : [discovery];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Merge `discoveryMetadata` from every configured {@link ClientDiscovery}
|
|
123
|
+
* into a single object. Entries are spread in order; later entries override
|
|
124
|
+
* earlier ones on key collisions.
|
|
125
|
+
*
|
|
126
|
+
* @internal
|
|
127
|
+
*/
|
|
128
|
+
function mergeDiscoveryMetadata(discovery) {
|
|
129
|
+
return toClientDiscoveryArray(discovery).reduce((acc, d) => ({
|
|
130
|
+
...acc,
|
|
131
|
+
...d.discoveryMetadata ?? {}
|
|
132
|
+
}), {});
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
103
135
|
* Default client secret hasher using SHA-256
|
|
104
136
|
*
|
|
105
137
|
* @internal
|
|
@@ -292,7 +324,7 @@ async function extractClientCredentials(ctx, opts, expectedAudience) {
|
|
|
292
324
|
error_description: "client_assertion cannot be combined with client_secret or Basic auth",
|
|
293
325
|
error: "invalid_client"
|
|
294
326
|
});
|
|
295
|
-
const { verifyClientAssertion: verify } = await import("./client-assertion-
|
|
327
|
+
const { verifyClientAssertion: verify } = await import("./client-assertion-CderPEmR.mjs").then((n) => n.t);
|
|
296
328
|
const result = await verify(ctx, opts, body.client_assertion, body.client_assertion_type, body.client_id, expectedAudience);
|
|
297
329
|
return {
|
|
298
330
|
method: "private_key_jwt",
|
|
@@ -414,4 +446,4 @@ function isPKCERequired(client, requestedScopes) {
|
|
|
414
446
|
return false;
|
|
415
447
|
}
|
|
416
448
|
//#endregion
|
|
417
|
-
export {
|
|
449
|
+
export { storeClientSecret as _, getClient as a, validateClientCredentials as b, getStoredToken as c, normalizeTimestampValue as d, parseClientMetadata as f, searchParamsToQuery as g, resolveSubjectIdentifier as h, extractClientCredentials as i, isPKCERequired as l, resolveSessionAuthTime as m, deleteFromPrompt as n, getJwtPlugin as o, parsePrompt as p, destructureCredentials as r, getOAuthProviderPlugin as s, decryptStoredClientSecret as t, mergeDiscoveryMetadata as u, storeToken as v, verifyOAuthQueryParams as x, toClientDiscoveryArray as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/oauth-provider",
|
|
3
|
-
"version": "1.7.0-beta.
|
|
3
|
+
"version": "1.7.0-beta.2",
|
|
4
4
|
"description": "An oauth provider plugin for Better Auth",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,15 +64,15 @@
|
|
|
64
64
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
65
65
|
"listhen": "^1.9.0",
|
|
66
66
|
"tsdown": "0.21.1",
|
|
67
|
-
"@better-auth/core": "1.7.0-beta.
|
|
68
|
-
"better-auth": "1.7.0-beta.
|
|
67
|
+
"@better-auth/core": "1.7.0-beta.2",
|
|
68
|
+
"better-auth": "1.7.0-beta.2"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"@better-auth/utils": "0.4.0",
|
|
72
72
|
"@better-fetch/fetch": "1.1.21",
|
|
73
73
|
"better-call": "1.3.5",
|
|
74
|
-
"@better-auth/core": "^1.7.0-beta.
|
|
75
|
-
"better-auth": "^1.7.0-beta.
|
|
74
|
+
"@better-auth/core": "^1.7.0-beta.2",
|
|
75
|
+
"better-auth": "^1.7.0-beta.2"
|
|
76
76
|
},
|
|
77
77
|
"scripts": {
|
|
78
78
|
"build": "tsdown",
|