@hammadj/better-auth-oauth-provider 1.5.0-beta.9

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.
@@ -0,0 +1,1268 @@
1
+ import { verifyAccessToken } from "better-auth/oauth2";
2
+ import { JWSAlgorithms, JwtOptions } from "better-auth/plugins";
3
+ import { JWTPayload } from "jose";
4
+ import { InferOptionSchema, Session, User } from "better-auth/types";
5
+ import { GenericEndpointContext, LiteralString } from "@better-auth/core";
6
+
7
+ //#region src/types/helpers.d.ts
8
+ type Awaitable<T> = Promise<T> | T;
9
+ //#endregion
10
+ //#region src/mcp.d.ts
11
+ /**
12
+ * A request middleware handler that checks and responds with
13
+ * a WWW-Authenticate header for unauthenticated responses.
14
+ *
15
+ * @external
16
+ */
17
+ declare const mcpHandler: (/** Resource is the same url as the audience */
18
+
19
+ verifyOptions: Parameters<typeof verifyAccessToken>[1], handler: (req: Request, jwt: JWTPayload) => Awaitable<Response>, opts?: {
20
+ /** Maps non-url (ie urn, client) resources to resource_metadata */resourceMetadataMappings: Record<string, string>;
21
+ }) => (req: Request) => Promise<Response>;
22
+ //#endregion
23
+ //#region src/schema.d.ts
24
+ declare const schema: BetterAuthPluginDBSchema;
25
+ //#endregion
26
+ //#region src/types/oauth.d.ts
27
+ /**
28
+ * Supported grant types of the token endpoint
29
+ */
30
+ type GrantType = "authorization_code" | "client_credentials" | "refresh_token";
31
+ type AuthMethod = "client_secret_basic" | "client_secret_post";
32
+ type TokenEndpointAuthMethod = AuthMethod | "none";
33
+ type BearerMethodsSupported = "header" | "body";
34
+ /**
35
+ * Metadata for authentication servers.
36
+ *
37
+ * @see https://datatracker.ietf.org/doc/html/rfc8414#section-2
38
+ */
39
+ interface AuthServerMetadata {
40
+ /**
41
+ * The issuer identifier, this is the URL of the provider and can be used to verify
42
+ * the `iss` claim in the ID token.
43
+ *
44
+ * default: the value set for the issuer in the jwt plugin,
45
+ * otherwise the base URL of the auth server (e.g. `https://example.com`)
46
+ */
47
+ issuer: string;
48
+ /**
49
+ * The URL of the authorization endpoint.
50
+ *
51
+ * @default `/oauth2/authorize`
52
+ */
53
+ authorization_endpoint: string;
54
+ /**
55
+ * The URL of the token endpoint.
56
+ *
57
+ * @default `/oauth2/token`
58
+ */
59
+ token_endpoint: string;
60
+ /**
61
+ * The URL of the jwks_uri endpoint.
62
+ *
63
+ * For JWKS to work, you must install the `jwt` plugin.
64
+ *
65
+ * This value is automatically set to `/jwks` if the `jwt` plugin is installed.
66
+ *
67
+ * @default `/jwks`
68
+ */
69
+ jwks_uri?: string;
70
+ /**
71
+ * The URL of the dynamic client registration endpoint.
72
+ *
73
+ * @default `/oauth2/register`
74
+ */
75
+ registration_endpoint: string;
76
+ /**
77
+ * Supported scopes.
78
+ */
79
+ scopes_supported?: string[];
80
+ /**
81
+ * Supported response types. (for /authorize endpoint)
82
+ */
83
+ response_types_supported: "code"[];
84
+ /**
85
+ * Supported response modes.
86
+ *
87
+ * `query`: the authorization code is returned in the query string
88
+ */
89
+ response_modes_supported: "query"[];
90
+ /**
91
+ * Supported grant types.
92
+ */
93
+ grant_types_supported: GrantType[];
94
+ /**
95
+ * Supported token endpoint authentication methods.
96
+ *
97
+ * @default
98
+ * ["client_secret_basic", "client_secret_post"]
99
+ */
100
+ token_endpoint_auth_methods_supported?: TokenEndpointAuthMethod[];
101
+ /**
102
+ * Array containing a list of the JWS signing
103
+ * algorithms ("alg" values) supported by the token endpoint for
104
+ * the signature on the JWT used to authenticate the client at the
105
+ * token endpoint for the "private_key_jwt" and "client_secret_jwt"
106
+ * authentication methods (see field token_endpoint_auth_methods_supported).
107
+ */
108
+ token_endpoint_auth_signing_alg_values_supported?: JWSAlgorithms[];
109
+ /**
110
+ * URL of a page containing human-readable information
111
+ * that developers might want or need to know when using the
112
+ * authorization server
113
+ */
114
+ service_documentation?: string;
115
+ /**
116
+ * Languages and scripts supported for the user interface,
117
+ * represented as an array of language tag values from BCP 47
118
+ * [RFC5646](https://datatracker.ietf.org/doc/html/rfc5646)
119
+ */
120
+ ui_locales_supported?: string[];
121
+ /**
122
+ * URL that the authorization server provides to the
123
+ * person registering the client to read about the authorization
124
+ * server's requirements on how the client can use the data provided
125
+ * by the authorization server.
126
+ */
127
+ op_policy_uri?: string;
128
+ /**
129
+ * URL that the authorization server provides to the
130
+ * person registering the client to read about the authorization
131
+ * server's terms of service.
132
+ */
133
+ op_tos_uri?: string;
134
+ /**
135
+ * URL of the authorization server's OAuth 2.0 revocation
136
+ * endpoint [RFC7009](https://datatracker.ietf.org/doc/html/rfc7009)
137
+ */
138
+ revocation_endpoint?: string;
139
+ /**
140
+ * Array containing a list of client authentication
141
+ * methods supported by this revocation endpoint
142
+ *
143
+ * @default
144
+ * ["client_secret_basic", "client_secret_post"]
145
+ */
146
+ revocation_endpoint_auth_methods_supported?: AuthMethod[];
147
+ /**
148
+ * Array containing a list of the JWS signing
149
+ * algorithms ("alg" values) supported by the revocation endpoint for
150
+ * the signature on the JWT used to authenticate the client at the
151
+ * token endpoint for the "private_key_jwt" and "client_secret_jwt"
152
+ * authentication methods (see field revocation_endpoint_auth_methods_supported).
153
+ */
154
+ revocation_endpoint_auth_signing_alg_values_supported?: JWSAlgorithms[];
155
+ /**
156
+ * URL of the authorization server's OAuth 2.0
157
+ * introspection endpoint [RFC7662](https://datatracker.ietf.org/doc/html/rfc7662)
158
+ */
159
+ introspection_endpoint?: string;
160
+ /**
161
+ * Array containing a list of client authentication
162
+ * methods supported by this introspection endpoint
163
+ *
164
+ * @default
165
+ * ["client_secret_basic", "client_secret_post"]
166
+ */
167
+ introspection_endpoint_auth_methods_supported?: AuthMethod[];
168
+ /**
169
+ * Array containing a list of the JWS signing
170
+ * algorithms ("alg" values) supported by the introspection endpoint
171
+ * used to authenticate the client at the token endpoint for
172
+ * the "private_key_jwt" and "client_secret_jwt" authentication methods
173
+ * (see field introspection_endpoint_auth_methods_supported).
174
+ */
175
+ introspection_endpoint_auth_signing_alg_values_supported?: JWSAlgorithms[];
176
+ /**
177
+ * Supported code challenge methods.
178
+ *
179
+ * @default ["S256"]
180
+ */
181
+ code_challenge_methods_supported: "S256"[];
182
+ }
183
+ /**
184
+ * Metadata returned by the openid-configuration endpoint:
185
+ * /.well-known/openid-configuration
186
+ *
187
+ * NOTE: Url structure is different by appending to the end
188
+ * of the url instead of the base.
189
+ *
190
+ * @see https://datatracker.ietf.org/doc/html/rfc8414#section-5
191
+ */
192
+ interface OIDCMetadata extends AuthServerMetadata {
193
+ /**
194
+ * The URL of the userinfo endpoint.
195
+ *
196
+ * @default `/oauth2/userinfo`
197
+ */
198
+ userinfo_endpoint: string;
199
+ /**
200
+ * acr_values supported.
201
+ *
202
+ * - `urn:mace:incommon:iap:silver`: Silver level of assurance
203
+ * - `urn:mace:incommon:iap:bronze`: Bronze level of assurance
204
+ *
205
+ * Determination of acr_value is considered bronze by default.
206
+ * Silver level determination coming soon.
207
+ *
208
+ * @default
209
+ * ["urn:mace:incommon:iap:bronze"]
210
+ * @see https://incommon.org/federation/attributes.html
211
+ */
212
+ acr_values_supported: string[];
213
+ /**
214
+ * Supported subject types.
215
+ *
216
+ * pairwise: the subject identifier is unique to the client
217
+ * public: the subject identifier is unique to the server
218
+ *
219
+ * only `public` is supported.
220
+ */
221
+ subject_types_supported: "public"[];
222
+ /**
223
+ * Supported ID token signing algorithms.
224
+ *
225
+ * Automatically uses the same algorithm used in the JWK Plugin.
226
+ * Support for symmetric algorithms is strictly prohibited
227
+ * to sharing key vulnerabilities!
228
+ *
229
+ * @default
230
+ * ["EdDSA"]
231
+ */
232
+ id_token_signing_alg_values_supported: JWSAlgorithms[];
233
+ /**
234
+ * Supported claims.
235
+ *
236
+ * @default
237
+ * ["sub", "iss", "aud", "exp", "nbf", "iat", "jti", "email", "email_verified", "name", "family_name", "given_name", "sid", "scope", "azp"]
238
+ */
239
+ claims_supported: string[];
240
+ /**
241
+ * RP-Initiated Logout Endpoint
242
+ *
243
+ * @see https://openid.net/specs/openid-connect-rpinitiated-1_0.html
244
+ */
245
+ end_session_endpoint: string;
246
+ /**
247
+ * Prompt values supported by this OIDC server
248
+ *
249
+ * @see https://openid.net/specs/openid-connect-prompt-create-1_0.html#OpenID.Discovery
250
+ */
251
+ prompt_values_supported: Prompt[];
252
+ }
253
+ /**
254
+ * OAuth 2.0 Dynamic Client Registration Schema
255
+ *
256
+ * Current spec is based on OAuth 2.0, but shall use
257
+ * OAuth 2.1 restrictions.
258
+ *
259
+ * https://datatracker.ietf.org/doc/html/rfc7591#section-2
260
+ */
261
+ interface OAuthClient {
262
+ client_id: string;
263
+ client_secret?: string;
264
+ client_secret_expires_at?: number;
265
+ scope?: string;
266
+ user_id?: string | null;
267
+ client_id_issued_at?: number;
268
+ client_name?: string;
269
+ client_uri?: string;
270
+ logo_uri?: string;
271
+ contacts?: string[];
272
+ tos_uri?: string;
273
+ policy_uri?: string;
274
+ jwks?: string[];
275
+ jwks_uri?: string;
276
+ software_id?: string;
277
+ software_version?: string;
278
+ software_statement?: string;
279
+ redirect_uris: string[];
280
+ post_logout_redirect_uris?: string[];
281
+ token_endpoint_auth_method?: "none" | "client_secret_basic" | "client_secret_post";
282
+ grant_types?: GrantType[];
283
+ response_types?: "code"[];
284
+ public?: boolean;
285
+ type?: "web" | "native" | "user-agent-based";
286
+ disabled?: boolean;
287
+ skip_consent?: boolean;
288
+ enable_end_session?: boolean;
289
+ reference_id?: string;
290
+ [key: string]: unknown;
291
+ }
292
+ /**
293
+ * Resource metadata server as defined by RFC 9728
294
+ *
295
+ * @see https://datatracker.ietf.org/doc/html/rfc9728#Terminology
296
+ */
297
+ interface ResourceServerMetadata {
298
+ /**
299
+ * The protected resource's resource identifier,
300
+ * which is a URL that uses the https scheme and
301
+ * has no fragment component. It also SHOULD NOT
302
+ * include a query component, but it may if
303
+ * necessary.
304
+ *
305
+ * This SHOULD match the aud field of your JWT.
306
+ */
307
+ resource: string;
308
+ /**
309
+ * Each server should pertain to one issuer.
310
+ *
311
+ * MCP requires at least one server.
312
+ *
313
+ * @default [`${baseUrl}/.well-known/oauth-authorization-server`]
314
+ */
315
+ authorization_servers?: string[];
316
+ jwks_uri?: string;
317
+ scopes_supported?: string[];
318
+ bearer_methods_supported?: BearerMethodsSupported[];
319
+ resource_signing_alg_values_supported?: JWSAlgorithms[];
320
+ resource_name?: string;
321
+ resource_documentation?: string;
322
+ resource_policy_uri?: string;
323
+ resource_tos_uri?: string;
324
+ tls_client_certificate_bound_access_tokens?: boolean;
325
+ authorization_details_types_supported?: string;
326
+ dpop_signing_alg_values_supported?: JWSAlgorithms[];
327
+ dpop_bound_access_tokens_required?: boolean;
328
+ }
329
+ //#endregion
330
+ //#region src/types/index.d.ts
331
+ type StoreTokenType = "access_token" | "refresh_token" | "authorization_code";
332
+ type InternallySupportedScopes = "openid" | "profile" | "email" | "offline_access";
333
+ type Scope = LiteralString | InternallySupportedScopes;
334
+ type Prompt = "none" | "consent" | "login" | "create" | "select_account";
335
+ type AuthorizePrompt = Prompt | "login consent" | "select_account consent";
336
+ interface OAuthOptions<Scopes extends readonly Scope[] = InternallySupportedScopes[]> {
337
+ /**
338
+ * Custom schema definitions
339
+ */
340
+ schema?: InferOptionSchema<typeof schema>;
341
+ /**
342
+ * The scopes that the client is allowed to request.
343
+ * Must contain "openid" to be considered an OIDC server,
344
+ * otherwise it is just an OAuth server.
345
+ *
346
+ * @see https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
347
+ * @default
348
+ * ```ts
349
+ * ["openid", "profile", "email", "offline_access"]
350
+ * ```
351
+ */
352
+ scopes?: Scopes;
353
+ /**
354
+ * List of valid audiences if there are multiple.
355
+ *
356
+ * @default baseURL
357
+ * @example [
358
+ * "https://api.example.com",
359
+ * "https://api.example.com/mcp",
360
+ * ]
361
+ */
362
+ validAudiences?: string[];
363
+ /**
364
+ * Automatically cache trusted clients by client_id.
365
+ * Clients are cached at request.
366
+ *
367
+ * Additionally, cached trusted clients are immutable
368
+ * through the CRUD endpoints.
369
+ */
370
+ cachedTrustedClients?: Set<string>;
371
+ /**
372
+ * The amount of time in seconds that the access token is valid for.
373
+ *
374
+ * @default 3600 (1 hour) - Industry standard
375
+ */
376
+ accessTokenExpiresIn?: number;
377
+ /**
378
+ * The amount of time in seconds that a client
379
+ * credentials grant access token is valid for.
380
+ *
381
+ * @default 3600 (1 hour)
382
+ */
383
+ m2mAccessTokenExpiresIn?: number;
384
+ /**
385
+ * The amount of time in seconds that id token is valid for.
386
+ *
387
+ * @default 36000 (10 hours) - Recommended by the OIDC spec
388
+ */
389
+ idTokenExpiresIn?: number;
390
+ /**
391
+ * The amount of time in seconds that the refresh token is valid for.
392
+ * Typical industry standard is 30 days
393
+ *
394
+ * @default 2592000 (30 days)
395
+ */
396
+ refreshTokenExpiresIn?: number;
397
+ /**
398
+ * The amount of time in seconds that the authorization code is valid for.
399
+ *
400
+ * @default 600 (10 minutes) - Recommended by the OIDC spec
401
+ */
402
+ codeExpiresIn?: number;
403
+ /**
404
+ * Create access token expirations based on scope.
405
+ *
406
+ * This is useful for higher-privilege scopes that
407
+ * require shorter expiration times. The earliest
408
+ * expiration will take precedence. If not specified,
409
+ * the default will take place.
410
+ *
411
+ * Note: values should be lower than the defaults
412
+ * `accessTokenExpiresIn` and `m2mAccessTokenExpiresIn`
413
+ *
414
+ * @example
415
+ * { "write:payments": "5m", "read:payments": "30m" }
416
+ */
417
+ scopeExpirations?: { [K in Scopes[number]]?: number | string | Date };
418
+ /**
419
+ * Allow unauthenticated dynamic client registration.
420
+ *
421
+ * Support for `allowUnauthenticatedClientRegistration` **will be deprecated**
422
+ * when the MCP protocol standardizes unauthenticated dynamic client registration.
423
+ * As of writing, both [Client ID Metadata Documents](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/991)
424
+ * and [`software_statement` and `jwks_uri`](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1032) are under debate.
425
+ *
426
+ * @default false
427
+ */
428
+ allowUnauthenticatedClientRegistration?: boolean;
429
+ /**
430
+ * Allow dynamic client registration.
431
+ *
432
+ * @default false
433
+ */
434
+ allowDynamicClientRegistration?: boolean;
435
+ /**
436
+ * List of scopes for newly registered clients
437
+ * if not requested.
438
+ *
439
+ * For scopes that shall automatically adapt to your scopes
440
+ * list in the future (ie scopes: undefined), create that client
441
+ * using the server's `createOAuthClient` function.
442
+ *
443
+ * @default scopes
444
+ */
445
+ clientRegistrationDefaultScopes?: Scopes;
446
+ /**
447
+ * List of scopes for allowed clients in addition to
448
+ * those listed in the default scope. Finalized allowed list is
449
+ * the union of the default scopes and this list.
450
+ *
451
+ * If both clientRegistrationDefaultScopes and this
452
+ * are undefined, only scopes listed in the scopes option
453
+ * are allowed.
454
+ *
455
+ * @default - clientRegistrationDefaultScopes
456
+ */
457
+ clientRegistrationAllowedScopes?: Scopes;
458
+ /**
459
+ * How long a dynamically created confidential client
460
+ * should last for.
461
+ *
462
+ * - If a `number` is passed as an argument it is used as the claim directly.
463
+ * - If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the
464
+ * claim.
465
+ * - If a `string` is passed as an argument it is resolved to a time span, and then added to the
466
+ * current unix timestamp and used as the claim.
467
+ *
468
+ * Format used for time span should be a number followed by a unit, such as "5 minutes" or "1
469
+ * day".
470
+ *
471
+ * Valid units are: "sec", "secs", "second", "seconds", "s", "minute", "minutes", "min", "mins",
472
+ * "m", "hour", "hours", "hr", "hrs", "h", "day", "days", "d", "week", "weeks", "w", "year",
473
+ * "years", "yr", "yrs", and "y". It is not possible to specify months. 365.25 days is used as an
474
+ * alias for a year.
475
+ *
476
+ * If the string is suffixed with "ago", or prefixed with a "-", the resulting time span gets
477
+ * subtracted from the current unix timestamp. A "from now" suffix can also be used for
478
+ * readability when adding to the current unix timestamp.
479
+ *
480
+ * @default - undefined (does not expire)
481
+ */
482
+ clientRegistrationClientSecretExpiration?: number | string | Date;
483
+ /**
484
+ * Returns the reference id which owns the oauth clients.
485
+ *
486
+ * For example, it can be an organization, team, etc.
487
+ * When provided, user_id of the client will be undefined
488
+ * and the owner is defined under the field `reference_id`.
489
+ *
490
+ * With the organization plugin: @example ({ session }) => {
491
+ * return session?.activeOrganizationId;
492
+ * }
493
+ */
494
+ clientReference?: (context: {
495
+ user?: User & Record<string, unknown>;
496
+ session?: Session & Record<string, unknown>;
497
+ }) => Awaitable<string | undefined>;
498
+ /**
499
+ * RBAC on OAuth Clients.
500
+ *
501
+ * Provides context to help determine if a user can perform
502
+ * a specific action.
503
+ */
504
+ clientPrivileges?: (context: {
505
+ headers: Headers;
506
+ action: "create" | "read" | "update" | "delete" | "list" | "rotate";
507
+ user?: User & Record<string, unknown>;
508
+ session?: Session & Record<string, unknown>;
509
+ }) => Awaitable<boolean | undefined>;
510
+ /**
511
+ * List default scopes when using the token endpoint's
512
+ * grant type "client_credentials". This is used
513
+ * only when oauthClients are stored in the database
514
+ * without a scope and you do not want all `scopes` to be given.
515
+ *
516
+ * @default undefined
517
+ */
518
+ clientCredentialGrantDefaultScopes?: Scopes;
519
+ /**
520
+ * Grant types supported by the token endpoint
521
+ *
522
+ * @default
523
+ * ["authorization_code", "client_credentials", "refresh_token"]
524
+ */
525
+ grantTypes?: GrantType[];
526
+ /**
527
+ * The URL to the login page. This is used if the client requests the `login`
528
+ * prompt.
529
+ */
530
+ loginPage: string;
531
+ /**
532
+ * A URL to the consent page where the user will be redirected if the client
533
+ * requests consent.
534
+ *
535
+ * After the user consents, they should be redirected by the client to the
536
+ * `redirect_uri` with the authorization code.
537
+ *
538
+ * When the server redirects the user to the consent page, it will include the
539
+ * following query parameters:
540
+ *
541
+ * - `client_id` - The ID of the client.
542
+ * - `scope` - The requested scopes.
543
+ * - `code` - The authorization code.
544
+ *
545
+ * once the user consents, you need to call the `/oauth2/consent` endpoint
546
+ * with the code and `accept: true` to complete the authorization. Which will
547
+ * then return the client to the `redirect_uri` with the authorization code.
548
+ *
549
+ * @example
550
+ * ```ts
551
+ * consentPage: "/consent"
552
+ * ```
553
+ */
554
+ consentPage: string;
555
+ /**
556
+ * Sign Up page settings associated with `prompt: "create"`
557
+ * @see https://openid.net/specs/openid-connect-prompt-create-1_0.html
558
+ */
559
+ signup?: {
560
+ /**
561
+ * A URL to the Sign Up page where the user will be redirected
562
+ * to continue a signup flow.
563
+ *
564
+ * Upon completion of signup, you need to call the `/oauth2/continue`
565
+ * with `created: true` to continue the login flow.
566
+ *
567
+ * @default loginPage
568
+ * @example `/sign-up`
569
+ */
570
+ page?: string;
571
+ /**
572
+ * To add registration steps, specify the page(s) to redirect to.
573
+ *
574
+ * Note: the account would need to be logged in (or selected)
575
+ * to specify steps.
576
+ *
577
+ * If true, user with redirect to `page`.
578
+ * If string, user with redirect to the page specified by string.
579
+ * If false, user has completed registration and will continue auth flow.
580
+ *
581
+ * @param context
582
+ */
583
+ shouldRedirect?: (context: {
584
+ headers: Headers;
585
+ user: User & Record<string, unknown>;
586
+ session: Session & Record<string, unknown>;
587
+ scopes: Scopes;
588
+ }) => Awaitable<boolean | string>;
589
+ };
590
+ /**
591
+ * Select Account page settings associated with `prompt: "select_account"`
592
+ */
593
+ selectAccount?: {
594
+ /**
595
+ * A URL to the account selection page where the user will be redirected if
596
+ * the user must select an account (eg. multi-session).
597
+ *
598
+ * Once the user selects an account, you need to call the `/oauth2/continue`
599
+ * with `selected: true` to continue the login flow.
600
+ *
601
+ * @default loginPage
602
+ */
603
+ page?: string;
604
+ /**
605
+ * Checks to see if an account needs selection
606
+ * for the `/oauth2/authorize` endpoint.
607
+ *
608
+ * @returns
609
+ * - `true`: account is not selected and needs selection
610
+ * - `false`: intended user or account already selected
611
+ */
612
+ shouldRedirect: (context: {
613
+ headers: Headers;
614
+ user: User & Record<string, unknown>;
615
+ session: Session & Record<string, unknown>;
616
+ scopes: Scopes;
617
+ }) => Awaitable<boolean>;
618
+ };
619
+ /**
620
+ * Post login page settings
621
+ */
622
+ postLogin?: {
623
+ /**
624
+ * The page `shouldRedirect` should redirect to.
625
+ */
626
+ page: string;
627
+ /**
628
+ * A value to tie to the consent reference_id.
629
+ *
630
+ * Note that YOU must fail in this function if the requested
631
+ * scope doesn't have a reference id and it should.
632
+ */
633
+ consentReferenceId: (context: {
634
+ user: User & Record<string, unknown>;
635
+ session: Session & Record<string, unknown>;
636
+ scopes: Scopes;
637
+ }) => Awaitable<string | undefined>;
638
+ /**
639
+ * After login and before consent, request the user to
640
+ * select an additional choice for `/oauth2/authorize`.
641
+ * For example, allow selection of an organization or team.
642
+ *
643
+ * Upon selection of a specific account, use `/oauth2/continue`
644
+ * with `postLogin: true` to continue the login flow.
645
+ *
646
+ * @returns
647
+ * - `true`: account is not selected and needs selection
648
+ * - `false`: intended user or account selected
649
+ */
650
+ shouldRedirect: (context: {
651
+ headers: Headers;
652
+ user: User & Record<string, unknown>;
653
+ session: Session & Record<string, unknown>;
654
+ scopes: Scopes;
655
+ }) => Awaitable<boolean>;
656
+ };
657
+ /**
658
+ * Format your refresh tokens the returned to oauth clients.
659
+ * For example with JWE encryption/decryption logic.
660
+ *
661
+ * If you changed the format after production deployment,
662
+ * ensure that the prior version can still be decoded.
663
+ *
664
+ * NOTE: `prefix.refreshToken` is internally handled,
665
+ * so `token` only contains the stored database token.
666
+ */
667
+ formatRefreshToken?: {
668
+ /**
669
+ * Custom session token format sent to client.
670
+ */
671
+ encrypt: (token: string, sessionId?: string) => Awaitable<string>;
672
+ /**
673
+ * Decodes the custom session token.
674
+ *
675
+ * @returns {string | undefined} sessionId - if returned,
676
+ * should be same as the one received in `encode`.
677
+ * There is an added benefit that updates to the session occur
678
+ * via id instead of token.
679
+ * @returns {string} token - should be same as the one
680
+ * received in `encode`
681
+ */
682
+ decrypt: (token: string) => Awaitable<{
683
+ sessionId?: string;
684
+ token: string;
685
+ }>;
686
+ };
687
+ /**
688
+ * Store the client secret in your database in a secure way
689
+ * Note: This will not affect the client secret sent to the user,
690
+ * it will only affect the client secret stored in your database
691
+ *
692
+ * When disableJwtPlugin = false (recommended):
693
+ * - "hashed" - The client secret is hashed using the `hash` function.
694
+ * - {
695
+ * hash: (clientSecret: string) => Awaitable<string>,
696
+ * verify?: (clientSecret: string, storedHash: string) => Awaitable<boolean>
697
+ * } - A function that hashes the client secret.
698
+ *
699
+ * When disableJwtPlugin = true:
700
+ * - "encrypted" - The client secret is encrypted using the `encrypt` function.
701
+ * - {
702
+ * encrypt: (clientSecret: string) => Awaitable<string>,
703
+ * decrypt: (storedSecret: string) => Awaitable<string>
704
+ * } - A function that encrypts and decrypts the client secret.
705
+ *
706
+ * @default
707
+ * options.disableJwtPlugin ? "encrypted" : "hashed"
708
+ */
709
+ storeClientSecret?: "hashed" | "encrypted" | {
710
+ hash: (clientSecret: string) => Awaitable<string>;
711
+ verify?: (clientSecret: string, storedHash: string) => Awaitable<boolean>;
712
+ } | {
713
+ encrypt: (clientSecret: string) => Awaitable<string>;
714
+ decrypt: (storedSecret: string) => Awaitable<string>;
715
+ };
716
+ /**
717
+ * Storage method of opaque access tokens and refresh tokens on your database.
718
+ *
719
+ * - "hashed" - The client secret is hashed using the `hash` function.
720
+ * - {
721
+ * hash: (token: string, type: StoreTokenType) => Awaitable<string>
722
+ * } - A function that hashes the token
723
+ *
724
+ * @default "hashed"
725
+ */
726
+ storeTokens?: "hashed" | {
727
+ hash: (token: string, type: StoreTokenType) => Awaitable<string>;
728
+ };
729
+ /**
730
+ * Custom claims provided at the OIDC `userinfo` endpoint.
731
+ *
732
+ * @param info - context that may be useful when creating custom claims
733
+ * @returns Additional claims for userinfo request
734
+ */
735
+ customUserInfoClaims?: (info: {
736
+ /** The user object */user: User & Record<string, unknown>;
737
+ /** The scopes from the access token used
738
+ * in the /userinfo request (matches jwt.scopes) */
739
+ scopes: Scopes; /** The access token payload used in the /userinfo request */
740
+ jwt: JWTPayload;
741
+ }) => Awaitable<Record<string, any>>;
742
+ /**
743
+ * Custom claims attached to OIDC id tokens.
744
+ *
745
+ * To remain OIDC-compliant, claims should be
746
+ * namespaced with a URI. For example, a site
747
+ * example.com should namespace an organization at
748
+ * https://example.com/organization.
749
+ *
750
+ * @param info - context that may be useful when creating custom claims
751
+ */
752
+ customIdTokenClaims?: (info: {
753
+ /** The user object if token is associated to a user. */user: User & Record<string, unknown>; /** Scopes granted for this token */
754
+ scopes: Scopes; /** oAuthClient metadata */
755
+ metadata?: Record<string, any>;
756
+ }) => Awaitable<Record<string, any>>;
757
+ /**
758
+ * Custom claims attached to access tokens.
759
+ *
760
+ * Claims are added for both the token and introspect endpoints.
761
+ *
762
+ * Use the user and referenceId fields to fetch
763
+ * for membership roles/permissions to attach for the token.
764
+ * Note that scopes are those that requested,
765
+ * permissions are what the the user can actually do which
766
+ * must be done in this function.
767
+ *
768
+ * @param info - context that may be useful when creating custom claims
769
+ */
770
+ customAccessTokenClaims?: (info: {
771
+ /** The user object if token is associated to a user. Null if user doesn't exist. Undefined if user not applicable. */user?: (User & Record<string, unknown>) | null; /** reference of the consent/authorization */
772
+ referenceId?: string; /** Scopes granted for this token */
773
+ scopes: Scopes; /** The resource requesting. Provided by the token endpoint. */
774
+ resource?: string; /** oAuthClient metadata */
775
+ metadata?: Record<string, any>;
776
+ }) => Awaitable<Record<string, any>>;
777
+ /**
778
+ * Overwrite specific /.well-known/openid-configuration
779
+ * values so they are not available publically.
780
+ * This may be important if not all clients need specific scopes.
781
+ */
782
+ advertisedMetadata?: {
783
+ /**
784
+ * Advertised scopes_supported located at /.well-known/openid-configuration
785
+ *
786
+ * All values must be found in the scope field
787
+ */
788
+ scopes_supported?: Scopes;
789
+ /**
790
+ * Advertised claims_supported located at /.well-known/openid-configuration
791
+ *
792
+ * Internally supported claims:
793
+ * ["sub", "iss", "aud", "exp", "iat", "sid", "scope", "azp"]
794
+ */
795
+ claims_supported?: string[];
796
+ };
797
+ /**
798
+ * Attach prefixes to returned token types.
799
+ * NOTE: The prefix is not stored in the database.
800
+ *
801
+ * Useful when also using the [API Key Plugin](../api-key/index.ts)
802
+ * or Secret Scanners (ie Github Secret Scanning, GitGuardian, Trufflehog).
803
+ *
804
+ * We recommend to append an underscore to make it more identifiable.
805
+ */
806
+ prefix?: {
807
+ /**
808
+ * Prefix on returned opaque access tokens.
809
+ *
810
+ * Additionally, we recommend you add the prefix prior to the first deployment
811
+ * otherwise you must utilize this with `generateOpaqueAccessToken` (storing the full
812
+ * encoded value on the database).
813
+ *
814
+ * @example "domain_at_"
815
+ * @default undefined
816
+ */
817
+ opaqueAccessToken?: string;
818
+ /**
819
+ * Prefix on returned refresh tokens.
820
+ *
821
+ * Additionally, we recommend you add the prefix prior to the first deployment
822
+ * otherwise you must utilize this with `generateRefreshToken` (storing the full
823
+ * encoded value on the database).
824
+ *
825
+ * @example "domain_rt_"
826
+ * @default undefined
827
+ */
828
+ refreshToken?: string;
829
+ /**
830
+ * Prefix on returned client secrets.
831
+ *
832
+ * Additionally, we recommend you add the prefix prior to the first deployment
833
+ * otherwise you must utilize this with `generateClientSecret` (storing the full
834
+ * encoded value on the database).
835
+ *
836
+ * @example "domain_cs_"
837
+ * @default undefined
838
+ */
839
+ clientSecret?: string;
840
+ };
841
+ /**
842
+ * Custom function to generate a client ID.
843
+ *
844
+ * @default
845
+ * generateRandomString(32, "A-Z", "a-z")
846
+ */
847
+ generateClientId?: () => string;
848
+ /**
849
+ * Custom function to generate a client secret.
850
+ *
851
+ * @default
852
+ * generateRandomString(32, "A-Z", "a-z")
853
+ */
854
+ generateClientSecret?: () => string;
855
+ /**
856
+ * Generate a unique access token to save on the database.
857
+ *
858
+ * @default
859
+ * generateRandomString(32, "A-Z", "a-z")
860
+ */
861
+ generateOpaqueAccessToken?: () => Awaitable<string>;
862
+ /**
863
+ * Generate a unique refresh token to save on the database.
864
+ *
865
+ * @default
866
+ * generateRandomString(32, "A-Z", "a-z")
867
+ */
868
+ generateRefreshToken?: () => Awaitable<string>;
869
+ /**
870
+ * Confirmations that individually silences specific well-known endpoint
871
+ * configuration warnings.
872
+ *
873
+ * Only set these specific values if you see the error as they
874
+ * are configuration specific.
875
+ */
876
+ silenceWarnings?: {
877
+ /**
878
+ * Config warning for `/.well-known/oauth-authorization-server/[issuer-path]`
879
+ *
880
+ * @default false
881
+ */
882
+ oauthAuthServerConfig?: boolean;
883
+ /**
884
+ * Config warning for `[issuer-path]/.well-known/openid-configuration`
885
+ *
886
+ * @default false
887
+ */
888
+ openidConfig?: boolean;
889
+ };
890
+ /**
891
+ * By default, access and id tokens can be issued and verified
892
+ * through the JWT plugin.
893
+ *
894
+ * You can disable the JWT requirement in which access tokens
895
+ * will always be opaque and id tokens are always signed
896
+ * with HS256 using the client secret.
897
+ *
898
+ * @default false
899
+ */
900
+ disableJwtPlugin?: boolean;
901
+ }
902
+ interface OAuthAuthorizationQuery {
903
+ /**
904
+ * The response type.
905
+ * - "code": authorization code flow.
906
+ */
907
+ response_type: "code";
908
+ /**
909
+ * The redirect URI for the client. Must be one of the registered redirect URLs for the client.
910
+ */
911
+ redirect_uri: string;
912
+ /**
913
+ * The scope of the request. Must be a space-separated list of case sensitive strings.
914
+ *
915
+ * - "openid" is required for most requests to obtain user id (ie sub)
916
+ * - "profile" is required for requests that require user profile information.
917
+ * - "email" is required for requests that require user email information.
918
+ * - "offline_access" is required for requests that require a refresh token.
919
+ */
920
+ scope?: string;
921
+ /**
922
+ * Opaque value used to maintain state between the request and the callback. Typically,
923
+ * Cross-Site Request Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the
924
+ * value of this parameter with a browser cookie.
925
+ *
926
+ * Note: Better Auth stores the state in a database instead of a cookie. - This is to minimize
927
+ * the complication with native apps and other clients that may not have access to cookies.
928
+ */
929
+ state: string;
930
+ /**
931
+ * The client ID. Must be the ID of a registered client.
932
+ */
933
+ client_id: string;
934
+ /**
935
+ * The prompt parameter is used to specify the type of user interaction that is required.
936
+ */
937
+ prompt?: AuthorizePrompt;
938
+ /**
939
+ * The display parameter is used to specify how the authorization server displays the
940
+ * authentication and consent user interface pages to the end user.
941
+ */
942
+ display?: "page" | "popup" | "touch" | "wap";
943
+ /**
944
+ * End-User's preferred languages and scripts for the user interface, represented as a
945
+ * space-separated list of BCP47 [RFC5646] language tag values, ordered by preference. For
946
+ * instance, the value "fr-CA fr en" represents a preference for French as spoken in Canada,
947
+ * then French (without a region designation), followed by English (without a region
948
+ * designation).
949
+ *
950
+ * Better Auth does not support this parameter yet. It'll not throw an error if it's provided,
951
+ *
952
+ * 🏗️ currently not implemented
953
+ */
954
+ ui_locales?: string;
955
+ /**
956
+ * The maximum authentication age.
957
+ *
958
+ * Specifies the allowable elapsed time in seconds since the last time the End-User was
959
+ * actively authenticated by the provider. If the elapsed time is greater than this value, the
960
+ * provider MUST attempt to actively re-authenticate the End-User.
961
+ *
962
+ * Note that max_age=0 is equivalent to prompt=login.
963
+ */
964
+ max_age?: number;
965
+ /**
966
+ * Requested Authentication Context Class Reference values.
967
+ *
968
+ * Space-separated string that
969
+ * specifies the acr values that the Authorization Server is being requested to use for
970
+ * processing this Authentication Request, with the values appearing in order of preference.
971
+ * The Authentication Context Class satisfied by the authentication performed is returned as
972
+ * the acr Claim Value, as specified in Section 2. The acr Claim is requested as a Voluntary
973
+ * Claim by this parameter.
974
+ */
975
+ acr_values?: string;
976
+ /**
977
+ * Hint to the Authorization Server about the login identifier the End-User might use to log in
978
+ * (if necessary). This hint can be used by an RP if it first asks the End-User for their
979
+ * e-mail address (or other identifier) and then wants to pass that value as a hint to the
980
+ * discovered authorization service. It is RECOMMENDED that the hint value match the value used
981
+ * for discovery. This value MAY also be a phone number in the format specified for the
982
+ * phone_number Claim. The use of this parameter is left to the OP's discretion.
983
+ */
984
+ login_hint?: string;
985
+ /**
986
+ * ID Token previously issued by the Authorization Server being passed as a hint about the
987
+ * End-User's current or past authenticated session with the Client.
988
+ *
989
+ * 🏗️ currently not implemented
990
+ */
991
+ id_token_hint?: string;
992
+ /**
993
+ * Code challenge
994
+ */
995
+ code_challenge?: string;
996
+ /**
997
+ * Code challenge method used
998
+ */
999
+ code_challenge_method?: "S256";
1000
+ /**
1001
+ * String value used to associate a Client session with an ID Token, and to mitigate replay
1002
+ * attacks. The value is passed through unmodified from the Authentication Request to the ID Token.
1003
+ * If present in the ID Token, Clients MUST verify that the nonce Claim Value is equal to the
1004
+ * value of the nonce parameter sent in the Authentication Request. If present in the
1005
+ * Authentication Request, Authorization Servers MUST include a nonce Claim in the ID Token
1006
+ * with the Claim Value being the nonce value sent in the Authentication Request.
1007
+ */
1008
+ nonce?: string;
1009
+ }
1010
+ /**
1011
+ * Stored within the verification.value field
1012
+ * in JSON format.
1013
+ *
1014
+ * It is stored in JSON to prevent
1015
+ * direct searches by field on the db
1016
+ */
1017
+ interface VerificationValue {
1018
+ type: "authorization_code";
1019
+ query: OAuthAuthorizationQuery;
1020
+ sessionId: string;
1021
+ userId: string;
1022
+ referenceId?: string;
1023
+ }
1024
+ /**
1025
+ * Client registered values as used within the plugin
1026
+ */
1027
+ interface SchemaClient<Scopes extends readonly Scope[] = InternallySupportedScopes[]> {
1028
+ /**
1029
+ * Client ID
1030
+ *
1031
+ * size 32
1032
+ *
1033
+ * as described on https://www.rfc-editor.org/rfc/rfc6749.html#section-2.2
1034
+ */
1035
+ clientId: string;
1036
+ /**
1037
+ * Client Secret
1038
+ *
1039
+ * A secret for the client, if required by the authorization server.
1040
+ *
1041
+ * size 32
1042
+ */
1043
+ clientSecret?: string;
1044
+ /** Whether the client is disabled or not. */
1045
+ disabled?: boolean;
1046
+ /**
1047
+ * Restricts scopes allowed for the client.
1048
+ *
1049
+ * If not defined, any scope can be requested.
1050
+ */
1051
+ scopes?: Scopes;
1052
+ /** User who owns this client */
1053
+ userId?: string | null;
1054
+ /** Created time */
1055
+ createdAt?: Date;
1056
+ /** Last updated time */
1057
+ updatedAt?: Date;
1058
+ /** Expires time */
1059
+ expiresAt?: Date;
1060
+ /** The name of the client. */
1061
+ name?: string;
1062
+ /** Linkable uri of the client. */
1063
+ uri?: string;
1064
+ /** The icon of the client. */
1065
+ icon?: string;
1066
+ /** List of contacts for the client. */
1067
+ contacts?: string[];
1068
+ /** Client Terms of Service Uri */
1069
+ tos?: string;
1070
+ /** Client Privacy Policy Uri */
1071
+ policy?: string;
1072
+ softwareId?: string;
1073
+ softwareVersion?: string;
1074
+ softwareStatement?: string;
1075
+ /**
1076
+ * List of registered redirect URLs. Must include the whole URL, including the protocol, port,
1077
+ * and path.
1078
+ *
1079
+ * For example, `https://example.com/auth/callback`
1080
+ */
1081
+ redirectUris?: string[];
1082
+ /**
1083
+ * List of registered post-logout redirect URIs. Used for RP-Initiated Logout.
1084
+ * Must include the whole URL, including the protocol, port, and path.
1085
+ *
1086
+ * For example, `https://example.com/logout/callback`
1087
+ */
1088
+ postLogoutRedirectUris?: string[];
1089
+ tokenEndpointAuthMethod?: "none" | "client_secret_basic" | "client_secret_post";
1090
+ grantTypes?: GrantType[];
1091
+ responseTypes?: "code"[];
1092
+ /**
1093
+ * Indicates whether the client is public or confidential.
1094
+ * If public, refreshing tokens doesn't require
1095
+ * a client_secret. Clients are considered confidential by default.
1096
+ *
1097
+ * Uses `token_endpoint_auth_method` field or `type` field to determine
1098
+ *
1099
+ * Described https://www.rfc-editor.org/rfc/rfc6749.html#section-2.1
1100
+ *
1101
+ * @default undefined
1102
+ */
1103
+ public?: boolean;
1104
+ /**
1105
+ * The client type
1106
+ *
1107
+ * Described https://www.rfc-editor.org/rfc/rfc6749.html#section-2.1
1108
+ *
1109
+ * - web - A web application (confidential client)
1110
+ * - native - A mobile application (public client)
1111
+ * - user-agent-based - A user-agent-based application (public client)
1112
+ */
1113
+ type?: "web" | "native" | "user-agent-based";
1114
+ /** Used to indicate if consent screen can be skipped */
1115
+ skipConsent?: boolean;
1116
+ /** Used to enable client to logout via the `/oauth2/end-session` endpoint */
1117
+ enableEndSession?: boolean;
1118
+ /** Reference to the owner of this client. Eg. Organization, Team, Profile */
1119
+ referenceId?: string;
1120
+ /**
1121
+ * Additional metadata about the client.
1122
+ */
1123
+ metadata?: string;
1124
+ }
1125
+ interface OAuthOpaqueAccessToken<Scopes extends readonly Scope[] = InternallySupportedScopes[]> {
1126
+ /**
1127
+ * The opaque access token.
1128
+ */
1129
+ token: string;
1130
+ /**
1131
+ * The client ID of the client that requested the access token.
1132
+ */
1133
+ clientId: string;
1134
+ /**
1135
+ * The session ID the access token is associated with.
1136
+ *
1137
+ * Not available in client credentials grant
1138
+ * where no user session is involved.
1139
+ */
1140
+ sessionId?: string;
1141
+ /**
1142
+ * The user ID the access token is associated with.
1143
+ *
1144
+ * Not available in client credentials grant
1145
+ * where no user is involved.
1146
+ */
1147
+ userId?: string;
1148
+ /**
1149
+ * Reference Id of the consent/authorization.
1150
+ *
1151
+ * Not available in client credentials grant
1152
+ * where no user is involved.
1153
+ */
1154
+ referenceId?: string;
1155
+ /**
1156
+ * The refresh token the access token is associated with.
1157
+ *
1158
+ * Not available without the "offline_access" scope
1159
+ */
1160
+ refreshId?: string;
1161
+ /** The expiration date of the access token. */
1162
+ expiresAt: Date;
1163
+ /** The creation date of the access token. */
1164
+ createdAt: Date;
1165
+ /**
1166
+ * Scope granted for the access token.
1167
+ *
1168
+ * Shall match the refreshId.scopes if refreshId is provided.
1169
+ */
1170
+ scopes: Scopes;
1171
+ }
1172
+ /**
1173
+ * Refresh Token Database Schema
1174
+ */
1175
+ interface OAuthRefreshToken<Scopes extends readonly Scope[] = InternallySupportedScopes[]> {
1176
+ token: string;
1177
+ sessionId: string;
1178
+ userId: string;
1179
+ referenceId?: string;
1180
+ clientId?: string;
1181
+ expiresAt: Date;
1182
+ createdAt: Date;
1183
+ /**
1184
+ * When token was revoked. If set, token is considered a replay attack.
1185
+ */
1186
+ revoked?: Date;
1187
+ /**
1188
+ * Scopes granted for this refresh token.
1189
+ *
1190
+ * Considered Immutable once granted.
1191
+ */
1192
+ scopes: Scopes;
1193
+ }
1194
+ /**
1195
+ * Consent Database Schema
1196
+ */
1197
+ type OAuthConsent<Scopes extends readonly Scope[] = InternallySupportedScopes[]> = {
1198
+ id: string;
1199
+ clientId: string;
1200
+ userId: string;
1201
+ referenceId?: string;
1202
+ scopes: Scopes;
1203
+ createdAt: Date;
1204
+ updatedAt: Date;
1205
+ };
1206
+ //#endregion
1207
+ //#region src/metadata.d.ts
1208
+ declare function authServerMetadata(ctx: GenericEndpointContext, opts?: JwtOptions, overrides?: {
1209
+ scopes_supported?: AuthServerMetadata["scopes_supported"];
1210
+ public_client_supported?: boolean;
1211
+ grant_types_supported?: GrantType[];
1212
+ jwt_disabled?: boolean;
1213
+ }): AuthServerMetadata;
1214
+ declare function oidcServerMetadata(ctx: GenericEndpointContext, opts: OAuthOptions<Scope[]> & {
1215
+ claims?: string[];
1216
+ }): Omit<OIDCMetadata, "id_token_signing_alg_values_supported"> & {
1217
+ id_token_signing_alg_values_supported: JWSAlgorithms[] | ["HS256"];
1218
+ };
1219
+ /**
1220
+ * Provides an exportable `/.well-known/oauth-authorization-server`.
1221
+ *
1222
+ * Useful when basePath prevents the endpoint from being located at the root
1223
+ * and must be provided manually.
1224
+ *
1225
+ * @external
1226
+ */
1227
+ declare const oauthProviderAuthServerMetadata: <Auth extends {
1228
+ api: {
1229
+ getOAuthServerConfig: (...args: any) => any;
1230
+ };
1231
+ }>(auth: Auth, opts?: {
1232
+ headers?: HeadersInit;
1233
+ }) => (_request: Request) => Promise<Response>;
1234
+ /**
1235
+ * Provides an exportable `/.well-known/openid-configuration`.
1236
+ *
1237
+ * Useful when basePath prevents the endpoint from being located at the root
1238
+ * and must be provided manually.
1239
+ *
1240
+ * @external
1241
+ */
1242
+ declare const oauthProviderOpenIdConfigMetadata: <Auth extends {
1243
+ api: {
1244
+ getOpenIdConfig: (...args: any) => any;
1245
+ };
1246
+ }>(auth: Auth, opts?: {
1247
+ headers?: HeadersInit;
1248
+ }) => (_request: Request) => Promise<Response>;
1249
+ //#endregion
1250
+ //#region src/oauth.d.ts
1251
+ declare module "@better-auth/core" {
1252
+ interface BetterAuthPluginRegistry<AuthOptions, Options> {
1253
+ "oauth-provider": {
1254
+ creator: typeof oauthProvider;
1255
+ };
1256
+ }
1257
+ }
1258
+ /**
1259
+ * oAuth 2.1 provider plugin for Better Auth.
1260
+ *
1261
+ * @see https://better-auth.com/docs/plugins/oauth-provider
1262
+ * @param options - The options for the oAuth Provider plugin.
1263
+ * @returns A Better Auth plugin.
1264
+ */
1265
+ declare const oauthProvider: <O extends OAuthOptions<Scope[]>>(options: O) => BetterAuthPlugin;
1266
+ //#endregion
1267
+ export { type AuthServerMetadata, AuthorizePrompt, OAuthAuthorizationQuery, type OAuthClient, OAuthConsent, OAuthOpaqueAccessToken, OAuthOptions, OAuthRefreshToken, type OIDCMetadata, Prompt, type ResourceServerMetadata, SchemaClient, Scope, StoreTokenType, VerificationValue, authServerMetadata, mcpHandler, oauthProvider, oauthProviderAuthServerMetadata, oauthProviderOpenIdConfigMetadata, oidcServerMetadata };
1268
+ //# sourceMappingURL=index.d.mts.map