@better-auth/core 1.7.0-rc.1 → 1.7.0-rc.3
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/api/index.d.mts +28 -28
- package/dist/async_hooks/index.d.mts +0 -1
- package/dist/async_hooks/pure.index.d.mts +0 -1
- package/dist/context/endpoint-context.d.mts +1 -1
- package/dist/context/global.d.mts +0 -1
- package/dist/context/global.mjs +1 -1
- package/dist/context/request-state.d.mts +0 -1
- package/dist/context/request-state.mjs +8 -5
- package/dist/context/transaction.d.mts +8 -3
- package/dist/context/transaction.mjs +27 -10
- package/dist/db/adapter/factory.d.mts +3 -5
- package/dist/db/adapter/factory.mjs +7 -5
- package/dist/db/adapter/get-default-field-name.d.mts +2 -9
- package/dist/db/adapter/get-default-model-name.d.mts +1 -5
- package/dist/db/adapter/get-default-model-name.mjs +6 -5
- package/dist/db/adapter/get-field-attributes.d.mts +4 -11
- package/dist/db/adapter/get-field-name.d.mts +2 -9
- package/dist/db/adapter/get-id-field.d.mts +4 -12
- package/dist/db/adapter/get-model-name.d.mts +1 -5
- package/dist/db/adapter/index.d.mts +7 -32
- package/dist/db/adapter/types.d.mts +5 -17
- package/dist/db/adapter/utils.d.mts +0 -1
- package/dist/db/database-index.d.mts +44 -0
- package/dist/db/database-index.mjs +168 -0
- package/dist/db/get-tables.d.mts +7 -1
- package/dist/db/get-tables.mjs +47 -6
- package/dist/db/index.d.mts +3 -3
- package/dist/db/index.mjs +2 -2
- package/dist/db/internal.d.mts +3 -0
- package/dist/db/internal.mjs +3 -0
- package/dist/db/plugin.d.mts +4 -3
- package/dist/db/schema/account.d.mts +16 -3
- package/dist/db/schema/account.mjs +35 -2
- package/dist/db/schema/rate-limit.d.mts +1 -1
- package/dist/db/schema/rate-limit.mjs +9 -0
- package/dist/db/schema/session.d.mts +1 -1
- package/dist/db/schema/shared.d.mts +0 -1
- package/dist/db/schema/user.d.mts +1 -1
- package/dist/db/schema/verification.d.mts +1 -1
- package/dist/db/type.d.mts +17 -9
- package/dist/env/logger.d.mts +25 -25
- package/dist/error/codes.d.mts +0 -1
- package/dist/error/index.d.mts +0 -1
- package/dist/index.d.mts +1 -1
- package/dist/instrumentation/attributes.d.mts +0 -1
- package/dist/instrumentation/pure.index.d.mts +0 -1
- package/dist/instrumentation/tracer.mjs +1 -1
- package/dist/oauth2/authorization-params.d.mts +0 -1
- package/dist/oauth2/client-assertion.d.mts +3 -13
- package/dist/oauth2/client-credentials-token.d.mts +3 -17
- package/dist/oauth2/client-credentials-token.mjs +1 -4
- package/dist/oauth2/create-authorization-url.d.mts +3 -21
- package/dist/oauth2/dpop.d.mts +2 -23
- package/dist/oauth2/dpop.mjs +1 -1
- package/dist/oauth2/index.d.mts +3 -3
- package/dist/oauth2/index.mjs +2 -2
- package/dist/oauth2/oauth-provider.d.mts +94 -36
- package/dist/oauth2/refresh-access-token.d.mts +3 -19
- package/dist/oauth2/refresh-access-token.mjs +3 -9
- package/dist/oauth2/reject-redirects.mjs +1 -1
- package/dist/oauth2/token-endpoint-auth.d.mts +0 -1
- package/dist/oauth2/utils.d.mts +0 -1
- package/dist/oauth2/utils.mjs +2 -3
- package/dist/oauth2/validate-authorization-code.d.mts +5 -29
- package/dist/oauth2/verify-id-token.d.mts +3 -2
- package/dist/oauth2/verify-id-token.mjs +3 -3
- package/dist/oauth2/verify.d.mts +18 -9
- package/dist/oauth2/verify.mjs +68 -5
- package/dist/social-providers/apple.d.mts +9 -24
- package/dist/social-providers/apple.mjs +2 -1
- package/dist/social-providers/atlassian.d.mts +18 -19
- package/dist/social-providers/atlassian.mjs +1 -1
- package/dist/social-providers/cognito.d.mts +33 -22
- package/dist/social-providers/cognito.mjs +2 -2
- package/dist/social-providers/discord.d.mts +7 -20
- package/dist/social-providers/discord.mjs +1 -1
- package/dist/social-providers/dropbox.d.mts +7 -22
- package/dist/social-providers/dropbox.mjs +1 -1
- package/dist/social-providers/facebook.d.mts +19 -27
- package/dist/social-providers/facebook.mjs +6 -17
- package/dist/social-providers/figma.d.mts +7 -22
- package/dist/social-providers/figma.mjs +1 -1
- package/dist/social-providers/github.d.mts +7 -23
- package/dist/social-providers/github.mjs +1 -1
- package/dist/social-providers/gitlab.d.mts +6 -43
- package/dist/social-providers/gitlab.mjs +1 -1
- package/dist/social-providers/google.d.mts +10 -32
- package/dist/social-providers/google.mjs +2 -1
- package/dist/social-providers/huggingface.d.mts +7 -22
- package/dist/social-providers/huggingface.mjs +1 -1
- package/dist/social-providers/index.d.mts +229 -787
- package/dist/social-providers/kakao.d.mts +8 -33
- package/dist/social-providers/kakao.mjs +1 -1
- package/dist/social-providers/kick.d.mts +7 -22
- package/dist/social-providers/kick.mjs +1 -1
- package/dist/social-providers/line.d.mts +8 -44
- package/dist/social-providers/line.mjs +4 -6
- package/dist/social-providers/linear.d.mts +7 -21
- package/dist/social-providers/linear.mjs +1 -1
- package/dist/social-providers/linkedin.d.mts +7 -21
- package/dist/social-providers/linkedin.mjs +1 -1
- package/dist/social-providers/microsoft-entra-id.d.mts +8 -18
- package/dist/social-providers/microsoft-entra-id.mjs +24 -4
- package/dist/social-providers/naver.d.mts +27 -42
- package/dist/social-providers/naver.mjs +1 -1
- package/dist/social-providers/notion.d.mts +7 -21
- package/dist/social-providers/notion.mjs +1 -1
- package/dist/social-providers/paybin.d.mts +8 -23
- package/dist/social-providers/paybin.mjs +2 -1
- package/dist/social-providers/paypal.d.mts +8 -33
- package/dist/social-providers/paypal.mjs +1 -1
- package/dist/social-providers/polar.d.mts +7 -22
- package/dist/social-providers/polar.mjs +1 -1
- package/dist/social-providers/railway.d.mts +7 -22
- package/dist/social-providers/railway.mjs +1 -1
- package/dist/social-providers/reddit.d.mts +7 -20
- package/dist/social-providers/reddit.mjs +1 -1
- package/dist/social-providers/roblox.d.mts +7 -20
- package/dist/social-providers/roblox.mjs +1 -1
- package/dist/social-providers/salesforce.d.mts +7 -22
- package/dist/social-providers/salesforce.mjs +1 -1
- package/dist/social-providers/slack.d.mts +7 -20
- package/dist/social-providers/slack.mjs +1 -1
- package/dist/social-providers/spotify.d.mts +7 -22
- package/dist/social-providers/spotify.mjs +1 -1
- package/dist/social-providers/tiktok.d.mts +10 -22
- package/dist/social-providers/tiktok.mjs +1 -1
- package/dist/social-providers/twitch.d.mts +7 -20
- package/dist/social-providers/twitch.mjs +1 -1
- package/dist/social-providers/twitter.d.mts +29 -26
- package/dist/social-providers/twitter.mjs +1 -1
- package/dist/social-providers/vercel.d.mts +7 -22
- package/dist/social-providers/vercel.mjs +1 -1
- package/dist/social-providers/vk.d.mts +8 -24
- package/dist/social-providers/vk.mjs +5 -6
- package/dist/social-providers/wechat.d.mts +7 -19
- package/dist/social-providers/wechat.mjs +1 -1
- package/dist/social-providers/zoom.d.mts +9 -25
- package/dist/social-providers/zoom.mjs +1 -1
- package/dist/types/context.d.mts +16 -9
- package/dist/types/cookie.d.mts +0 -1
- package/dist/types/helper.d.mts +1 -1
- package/dist/types/index.d.mts +1 -1
- package/dist/types/init-options.d.mts +37 -26
- package/dist/types/plugin-client.d.mts +1 -3
- package/dist/types/plugin.d.mts +2 -2
- package/dist/utils/async.d.mts +0 -1
- package/dist/utils/db.d.mts +1 -0
- package/dist/utils/deprecate.d.mts +0 -1
- package/dist/utils/error-codes.d.mts +2 -2
- package/dist/utils/host.d.mts +27 -1
- package/dist/utils/host.mjs +1 -1
- package/dist/utils/ip.d.mts +1 -0
- package/dist/utils/ip.mjs +1 -1
- package/dist/utils/is-api-error.d.mts +0 -1
- package/dist/utils/redirect-uri.d.mts +6 -2
- package/dist/utils/redirect-uri.mjs +11 -1
- package/package.json +10 -2
- package/src/context/request-state.ts +26 -6
- package/src/context/transaction.ts +37 -18
- package/src/db/adapter/factory.ts +34 -28
- package/src/db/adapter/get-default-model-name.ts +23 -14
- package/src/db/database-index.ts +351 -0
- package/src/db/get-tables.ts +89 -9
- package/src/db/index.ts +4 -0
- package/src/db/internal.ts +12 -0
- package/src/db/plugin.ts +3 -1
- package/src/db/schema/account.ts +27 -1
- package/src/db/schema/user.ts +1 -1
- package/src/db/type.ts +12 -0
- package/src/error/codes.ts +1 -0
- package/src/oauth2/index.ts +5 -0
- package/src/oauth2/oauth-provider.ts +105 -36
- package/src/oauth2/verify-id-token.ts +4 -2
- package/src/oauth2/verify.ts +121 -12
- package/src/social-providers/apple.ts +2 -1
- package/src/social-providers/atlassian.ts +1 -1
- package/src/social-providers/cognito.ts +2 -2
- package/src/social-providers/discord.ts +1 -1
- package/src/social-providers/dropbox.ts +1 -1
- package/src/social-providers/facebook.ts +21 -28
- package/src/social-providers/figma.ts +1 -1
- package/src/social-providers/github.ts +1 -1
- package/src/social-providers/gitlab.ts +1 -1
- package/src/social-providers/google.ts +2 -1
- package/src/social-providers/huggingface.ts +1 -1
- package/src/social-providers/kakao.ts +1 -1
- package/src/social-providers/kick.ts +1 -1
- package/src/social-providers/line.ts +7 -12
- package/src/social-providers/linear.ts +1 -1
- package/src/social-providers/linkedin.ts +1 -1
- package/src/social-providers/microsoft-entra-id.ts +36 -27
- package/src/social-providers/naver.ts +1 -1
- package/src/social-providers/notion.ts +1 -1
- package/src/social-providers/paybin.ts +2 -1
- package/src/social-providers/paypal.ts +1 -1
- package/src/social-providers/polar.ts +1 -1
- package/src/social-providers/railway.ts +1 -1
- package/src/social-providers/reddit.ts +1 -1
- package/src/social-providers/roblox.ts +1 -1
- package/src/social-providers/salesforce.ts +1 -1
- package/src/social-providers/slack.ts +1 -1
- package/src/social-providers/spotify.ts +1 -1
- package/src/social-providers/tiktok.ts +2 -2
- package/src/social-providers/twitch.ts +1 -1
- package/src/social-providers/twitter.ts +1 -1
- package/src/social-providers/vercel.ts +1 -1
- package/src/social-providers/vk.ts +2 -2
- package/src/social-providers/wechat.ts +1 -1
- package/src/social-providers/zoom.ts +1 -1
- package/src/types/context.ts +21 -14
- package/src/types/init-options.ts +15 -14
- package/src/utils/redirect-uri.ts +20 -0
package/dist/oauth2/utils.mjs
CHANGED
|
@@ -16,8 +16,7 @@ function parseScopeField(scope) {
|
|
|
16
16
|
}
|
|
17
17
|
function getOAuth2Tokens(data) {
|
|
18
18
|
const getDate = (seconds) => {
|
|
19
|
-
|
|
20
|
-
return new Date(now.getTime() + seconds * 1e3);
|
|
19
|
+
return new Date((/* @__PURE__ */ new Date()).getTime() + seconds * 1e3);
|
|
21
20
|
};
|
|
22
21
|
return {
|
|
23
22
|
tokenType: data.token_type,
|
|
@@ -48,7 +47,7 @@ function applyDefaultAccessTokenExpiry(tokens, accessTokenExpiresIn) {
|
|
|
48
47
|
function mergeScopes(stored, incoming) {
|
|
49
48
|
const existing = stored ? stored.split(",").map((scope) => scope.trim()).filter(Boolean) : [];
|
|
50
49
|
const next = (incoming ?? []).map((scope) => scope.trim()).filter(Boolean);
|
|
51
|
-
return [
|
|
50
|
+
return [.../* @__PURE__ */ new Set([...existing, ...next])].join(",");
|
|
52
51
|
}
|
|
53
52
|
/**
|
|
54
53
|
* Return the provider's primary Client ID: the single string, or the entry at
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { AwaitableFunction } from "../types/helper.mjs";
|
|
2
|
+
import "../types/index.mjs";
|
|
2
3
|
import { OAuth2Tokens, ProviderOptions } from "./oauth-provider.mjs";
|
|
3
4
|
import { TokenEndpointAuth, TokenEndpointSecretAuthentication } from "./token-endpoint-auth.mjs";
|
|
4
|
-
import
|
|
5
|
-
|
|
5
|
+
import "./index.mjs";
|
|
6
6
|
//#region src/oauth2/validate-authorization-code.d.ts
|
|
7
7
|
interface AuthorizationCodeRequestInput {
|
|
8
8
|
code: string;
|
|
@@ -20,38 +20,14 @@ interface AuthorizationCodeRequestInput {
|
|
|
20
20
|
interface ValidateAuthorizationCodeInput extends AuthorizationCodeRequestInput {
|
|
21
21
|
tokenEndpoint: string;
|
|
22
22
|
}
|
|
23
|
-
declare function authorizationCodeRequest({
|
|
24
|
-
code,
|
|
25
|
-
codeVerifier,
|
|
26
|
-
redirectURI,
|
|
27
|
-
options,
|
|
28
|
-
authentication,
|
|
29
|
-
tokenEndpointAuth,
|
|
30
|
-
tokenEndpoint,
|
|
31
|
-
deviceId,
|
|
32
|
-
headers,
|
|
33
|
-
additionalParams,
|
|
34
|
-
resource
|
|
35
|
-
}: AuthorizationCodeRequestInput): Promise<{
|
|
23
|
+
declare function authorizationCodeRequest({ code, codeVerifier, redirectURI, options, authentication, tokenEndpointAuth, tokenEndpoint, deviceId, headers, additionalParams, resource }: AuthorizationCodeRequestInput): Promise<{
|
|
36
24
|
body: URLSearchParams;
|
|
37
25
|
headers: Record<string, string>;
|
|
38
26
|
}>;
|
|
39
|
-
declare function validateAuthorizationCode({
|
|
40
|
-
code,
|
|
41
|
-
codeVerifier,
|
|
42
|
-
redirectURI,
|
|
43
|
-
options,
|
|
44
|
-
tokenEndpoint,
|
|
45
|
-
authentication,
|
|
46
|
-
tokenEndpointAuth,
|
|
47
|
-
deviceId,
|
|
48
|
-
headers,
|
|
49
|
-
additionalParams,
|
|
50
|
-
resource
|
|
51
|
-
}: ValidateAuthorizationCodeInput): Promise<OAuth2Tokens>;
|
|
27
|
+
declare function validateAuthorizationCode({ code, codeVerifier, redirectURI, options, tokenEndpoint, authentication, tokenEndpointAuth, deviceId, headers, additionalParams, resource }: ValidateAuthorizationCodeInput): Promise<OAuth2Tokens>;
|
|
52
28
|
declare function validateToken(token: string, jwksEndpoint: string, options?: {
|
|
53
29
|
audience?: string | string[];
|
|
54
30
|
issuer?: string | string[];
|
|
55
|
-
}): Promise<jose.JWTVerifyResult<jose.JWTPayload> & jose.ResolvedKey>;
|
|
31
|
+
}): Promise<import("jose").JWTVerifyResult<import("jose").JWTPayload> & import("jose").ResolvedKey>;
|
|
56
32
|
//#endregion
|
|
57
33
|
export { authorizationCodeRequest, validateAuthorizationCode, validateToken };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { GenericEndpointContext } from "../types/context.mjs";
|
|
2
|
+
import "../types/index.mjs";
|
|
1
3
|
import { OAuthProvider } from "./oauth-provider.mjs";
|
|
2
|
-
|
|
3
4
|
//#region src/oauth2/verify-id-token.d.ts
|
|
4
5
|
type ProviderWithIdTokenConfig = Pick<OAuthProvider, "idToken" | "options">;
|
|
5
6
|
/**
|
|
@@ -22,6 +23,6 @@ declare function supportsIdTokenSignIn(provider: ProviderWithIdTokenConfig): boo
|
|
|
22
23
|
*
|
|
23
24
|
* @returns `true` only when the token is authentic for the provider.
|
|
24
25
|
*/
|
|
25
|
-
declare function verifyProviderIdToken(provider: ProviderWithIdTokenConfig, token: string, nonce?: string): Promise<boolean>;
|
|
26
|
+
declare function verifyProviderIdToken(provider: ProviderWithIdTokenConfig, token: string, nonce?: string, ctx?: GenericEndpointContext): Promise<boolean>;
|
|
26
27
|
//#endregion
|
|
27
28
|
export { supportsIdTokenSignIn, verifyProviderIdToken };
|
|
@@ -35,14 +35,14 @@ function supportsIdTokenSignIn(provider) {
|
|
|
35
35
|
*
|
|
36
36
|
* @returns `true` only when the token is authentic for the provider.
|
|
37
37
|
*/
|
|
38
|
-
async function verifyProviderIdToken(provider, token, nonce) {
|
|
38
|
+
async function verifyProviderIdToken(provider, token, nonce, ctx) {
|
|
39
39
|
const options = provider.options ?? {};
|
|
40
40
|
if (options.disableIdTokenSignIn) return false;
|
|
41
41
|
try {
|
|
42
|
-
if (options.verifyIdToken) return await options.verifyIdToken(token, nonce);
|
|
42
|
+
if (options.verifyIdToken) return await options.verifyIdToken(token, nonce, ctx);
|
|
43
43
|
const config = provider.idToken;
|
|
44
44
|
if (!config) return false;
|
|
45
|
-
if ("verify" in config) return await config.verify(token, nonce);
|
|
45
|
+
if ("verify" in config) return await config.verify(token, nonce, ctx);
|
|
46
46
|
if (token.split(".").length !== 3) return config.allowOpaqueToken === true;
|
|
47
47
|
const { alg } = decodeProtectedHeader(token);
|
|
48
48
|
const { payload } = await jwtVerify(token, config.jwks, {
|
package/dist/oauth2/verify.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { DpopReplayStore } from "./dpop.mjs";
|
|
2
|
+
import { APIError } from "better-call";
|
|
2
3
|
import { JSONWebKeySet, JWTPayload, JWTVerifyOptions } from "jose";
|
|
3
|
-
|
|
4
4
|
//#region src/oauth2/verify.d.ts
|
|
5
5
|
type JwksFetchOptions = {
|
|
6
|
-
/** Jwks url or promise of a Jwks */
|
|
6
|
+
/** Jwks url or promise of a Jwks */
|
|
7
|
+
jwksFetch: string | (() => Promise<JSONWebKeySet | undefined>);
|
|
7
8
|
/**
|
|
8
9
|
* Stable object to cache the result of a function `jwksFetch` under,
|
|
9
10
|
* with the same TTL and kid-miss refetch rules as string sources.
|
|
@@ -11,9 +12,6 @@ type JwksFetchOptions = {
|
|
|
11
12
|
*/
|
|
12
13
|
jwksCacheKey?: object;
|
|
13
14
|
};
|
|
14
|
-
/**
|
|
15
|
-
* @internal
|
|
16
|
-
*/
|
|
17
15
|
interface VerifyAccessTokenRemote {
|
|
18
16
|
/** Full url of the introspect endpoint. Should end with `/oauth2/introspect` */
|
|
19
17
|
introspectUrl: string;
|
|
@@ -45,8 +43,13 @@ interface VerifyAccessTokenRemote {
|
|
|
45
43
|
interface VerifyAccessTokenOptions {
|
|
46
44
|
/** Verify options */
|
|
47
45
|
verifyOptions: JWTVerifyOptions & Required<Pick<JWTVerifyOptions, "audience" | "issuer">>;
|
|
48
|
-
/** Scopes
|
|
49
|
-
|
|
46
|
+
/** Scopes the token must satisfy. */
|
|
47
|
+
requiredScopes?: readonly string[];
|
|
48
|
+
/**
|
|
49
|
+
* Determines whether a required scope is satisfied by the granted scope
|
|
50
|
+
* set. Defaults to exact set membership.
|
|
51
|
+
*/
|
|
52
|
+
isScopeSatisfied?: (requiredScope: string, grantedScopes: ReadonlySet<string>) => boolean;
|
|
50
53
|
/** Required to verify access token locally */
|
|
51
54
|
jwksUrl?: string;
|
|
52
55
|
/** If provided, can verify a token remotely */
|
|
@@ -87,9 +90,15 @@ declare function requestToResourceInput(request: Request): ResourceRequestInput;
|
|
|
87
90
|
* Can also be configured for remote verification.
|
|
88
91
|
*/
|
|
89
92
|
declare function verifyJwsAccessToken(token: string, opts: JwksFetchOptions & {
|
|
90
|
-
/** Verify options */
|
|
93
|
+
/** Verify options */
|
|
94
|
+
verifyOptions: JWTVerifyOptions & Required<Pick<JWTVerifyOptions, "audience" | "issuer">>;
|
|
91
95
|
}): Promise<JWTPayload>;
|
|
92
96
|
declare function getJwks(token: string, opts: JwksFetchOptions): Promise<JSONWebKeySet>;
|
|
97
|
+
declare function createInsufficientScopeError(requiredScopes: readonly string[], description?: string): APIError;
|
|
98
|
+
/**
|
|
99
|
+
* Returns whether an error is a typed RFC 6750 insufficient-scope failure.
|
|
100
|
+
*/
|
|
101
|
+
declare function isInsufficientScopeError(error: unknown): error is APIError;
|
|
93
102
|
/**
|
|
94
103
|
* Performs local verification of a bearer access token for your API.
|
|
95
104
|
*
|
|
@@ -112,4 +121,4 @@ declare function verifyBearerToken(token: string, opts: VerifyAccessTokenOptions
|
|
|
112
121
|
*/
|
|
113
122
|
declare function verifyAccessTokenRequest(request: ResourceRequestInput, opts: VerifyAccessTokenRequestOptions): Promise<JWTPayload>;
|
|
114
123
|
//#endregion
|
|
115
|
-
export { ResourceRequestInput, VerifyAccessTokenOptions, VerifyAccessTokenRequestOptions, getJwks, requestToResourceInput, verifyAccessTokenRequest, verifyBearerToken, verifyJwsAccessToken };
|
|
124
|
+
export { ResourceRequestInput, VerifyAccessTokenOptions, VerifyAccessTokenRemote, VerifyAccessTokenRequestOptions, createInsufficientScopeError, getJwks, isInsufficientScopeError, requestToResourceInput, verifyAccessTokenRequest, verifyBearerToken, verifyJwsAccessToken };
|
package/dist/oauth2/verify.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { createInMemoryDpopReplayStore, enforceDpopBinding, getDpopJktFromPayloa
|
|
|
4
4
|
import { APIError } from "better-call";
|
|
5
5
|
import { UnsecuredJWT, createLocalJWKSet, decodeProtectedHeader, errors, jwtVerify } from "jose";
|
|
6
6
|
//#region src/oauth2/verify.ts
|
|
7
|
-
const joseInfrastructureErrorCodes = new Set([
|
|
7
|
+
const joseInfrastructureErrorCodes = /* @__PURE__ */ new Set([
|
|
8
8
|
errors.JWKSTimeout.code,
|
|
9
9
|
errors.JWKSInvalid.code,
|
|
10
10
|
errors.JWKSMultipleMatchingKeys.code
|
|
@@ -207,12 +207,73 @@ async function verifyAccessTokenPayload(token, opts) {
|
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
if (!payload) throw new APIError("UNAUTHORIZED", { message: `no token payload` });
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
const grantedScopes = parseGrantedScopes(payload.scope);
|
|
211
|
+
if (opts.requiredScopes) {
|
|
212
|
+
const isScopeSatisfied = opts.isScopeSatisfied ?? ((requiredScope, scopes) => scopes.has(requiredScope));
|
|
213
|
+
const missingScopes = opts.requiredScopes.filter((scope) => !isScopeSatisfied(scope, grantedScopes));
|
|
214
|
+
if (missingScopes.length > 0) throw createInsufficientScopeError(missingScopes);
|
|
213
215
|
}
|
|
214
216
|
return payload;
|
|
215
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Build the RFC 6750 §3.1 insufficient-scope failure: the access token is valid
|
|
220
|
+
* but lacks scopes the operation needs.
|
|
221
|
+
*
|
|
222
|
+
* Resource-server challenge builders turn this into a `403` carrying a
|
|
223
|
+
* `WWW-Authenticate: Bearer error="insufficient_scope"` challenge that names
|
|
224
|
+
* `scopes`, so the client knows what to request when it re-authorizes. Throw it
|
|
225
|
+
* from a route handler to challenge for scopes only that operation needs; a
|
|
226
|
+
* plain `FORBIDDEN` stays a plain `403`, since a permission denial the client
|
|
227
|
+
* cannot fix by re-authorizing must not send the user through consent again.
|
|
228
|
+
*
|
|
229
|
+
* @param requiredScopes - Every scope the operation requires but the token lacks.
|
|
230
|
+
* @param description - RFC 6750 `error_description` text. It must use the
|
|
231
|
+
* printable ASCII character set allowed by the specification.
|
|
232
|
+
*/
|
|
233
|
+
const OAUTH_SCOPE_TOKEN_PATTERN = /^[\x21\x23-\x5b\x5d-\x7e]+$/;
|
|
234
|
+
const OAUTH_ERROR_DESCRIPTION_PATTERN = /^[\x20-\x21\x23-\x5b\x5d-\x7e]+$/;
|
|
235
|
+
const insufficientScopeErrors = /* @__PURE__ */ new WeakSet();
|
|
236
|
+
function isOAuthScopeToken(value) {
|
|
237
|
+
return OAUTH_SCOPE_TOKEN_PATTERN.test(value);
|
|
238
|
+
}
|
|
239
|
+
function validateScopeTokens(scopes, label) {
|
|
240
|
+
for (const scope of scopes) if (!isOAuthScopeToken(scope)) throw new TypeError(`invalid ${label}: ${JSON.stringify(scope)}`);
|
|
241
|
+
}
|
|
242
|
+
function validateRequiredScopes(opts) {
|
|
243
|
+
if (opts.requiredScopes) validateScopeTokens(opts.requiredScopes, "required scope");
|
|
244
|
+
}
|
|
245
|
+
function parseGrantedScopes(scope) {
|
|
246
|
+
if (scope === void 0) return /* @__PURE__ */ new Set();
|
|
247
|
+
if (typeof scope !== "string" || scope.length === 0 || scope.split(" ").some((token) => !isOAuthScopeToken(token))) throw new APIError("UNAUTHORIZED", {
|
|
248
|
+
message: "access token scope claim is invalid",
|
|
249
|
+
error: "invalid_token",
|
|
250
|
+
error_description: "access token scope claim is invalid"
|
|
251
|
+
});
|
|
252
|
+
return new Set(scope.split(" "));
|
|
253
|
+
}
|
|
254
|
+
function createInsufficientScopeError(requiredScopes, description = `access token is missing required scope: ${requiredScopes.join(" ")}`) {
|
|
255
|
+
if (requiredScopes.length === 0) throw new TypeError("requiredScopes must contain at least one scope");
|
|
256
|
+
validateScopeTokens(requiredScopes, "required scope");
|
|
257
|
+
if (typeof description !== "string" || !OAUTH_ERROR_DESCRIPTION_PATTERN.test(description)) throw new TypeError("invalid error_description");
|
|
258
|
+
const error = new APIError("FORBIDDEN", {
|
|
259
|
+
message: description,
|
|
260
|
+
error: "insufficient_scope",
|
|
261
|
+
error_description: description,
|
|
262
|
+
scope: [...new Set(requiredScopes)].join(" ")
|
|
263
|
+
});
|
|
264
|
+
insufficientScopeErrors.add(error);
|
|
265
|
+
return error;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Returns whether an error is a typed RFC 6750 insufficient-scope failure.
|
|
269
|
+
*/
|
|
270
|
+
function isInsufficientScopeError(error) {
|
|
271
|
+
if (!(error instanceof APIError) || !insufficientScopeErrors.has(error) || error.status !== "FORBIDDEN") return false;
|
|
272
|
+
const body = error.body;
|
|
273
|
+
if (body?.error !== "insufficient_scope" || typeof body.scope !== "string") return false;
|
|
274
|
+
const scopes = body.scope.split(" ");
|
|
275
|
+
return scopes.length > 0 && scopes.every(isOAuthScopeToken);
|
|
276
|
+
}
|
|
216
277
|
function throwDpopUnauthorized(message, error) {
|
|
217
278
|
throw new APIError("UNAUTHORIZED", error ? {
|
|
218
279
|
message,
|
|
@@ -231,6 +292,7 @@ function throwDpopUnauthorized(message, error) {
|
|
|
231
292
|
* alone.
|
|
232
293
|
*/
|
|
233
294
|
async function verifyBearerToken(token, opts) {
|
|
295
|
+
validateRequiredScopes(opts);
|
|
234
296
|
const payload = await verifyAccessTokenPayload(token, opts);
|
|
235
297
|
if (getDpopJktFromPayload(payload)) throwDpopUnauthorized("DPoP-bound access token requires verifyAccessTokenRequest", "invalid_token");
|
|
236
298
|
return payload;
|
|
@@ -245,6 +307,7 @@ async function verifyBearerToken(token, opts) {
|
|
|
245
307
|
* scheme, method, URL, DPoP proof, `ath`, and `cnf.jkt` binding.
|
|
246
308
|
*/
|
|
247
309
|
async function verifyAccessTokenRequest(request, opts) {
|
|
310
|
+
validateRequiredScopes(opts);
|
|
248
311
|
const authorization = parseAccessTokenAuthorization(request.authorizationHeader);
|
|
249
312
|
if (!authorization?.token) throwDpopUnauthorized("missing authorization header");
|
|
250
313
|
if (authorization.scheme === "Unknown") throwDpopUnauthorized("authorization scheme must be Bearer or DPoP", "invalid_token");
|
|
@@ -267,4 +330,4 @@ async function verifyAccessTokenRequest(request, opts) {
|
|
|
267
330
|
return payload;
|
|
268
331
|
}
|
|
269
332
|
//#endregion
|
|
270
|
-
export { getJwks, requestToResourceInput, verifyAccessTokenRequest, verifyBearerToken, verifyJwsAccessToken };
|
|
333
|
+
export { createInsufficientScopeError, getJwks, isInsufficientScopeError, jwksCache, requestToResourceInput, verifyAccessTokenRequest, verifyBearerToken, verifyJwsAccessToken };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import { OAuth2Tokens, OAuth2UserInfo, OAuthAccountKeyContext, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
+
import "../oauth2/index.mjs";
|
|
4
3
|
//#region src/social-providers/apple.d.ts
|
|
5
4
|
interface AppleProfile {
|
|
6
5
|
/**
|
|
@@ -69,12 +68,9 @@ interface AppleOptions extends ProviderOptions<AppleProfile> {
|
|
|
69
68
|
declare const apple: (options: AppleOptions) => {
|
|
70
69
|
id: "apple";
|
|
71
70
|
name: string;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
redirectURI,
|
|
76
|
-
additionalParams
|
|
77
|
-
}: {
|
|
71
|
+
accountSubject: ({ profile }: OAuthAccountKeyContext<AppleProfile>) => string;
|
|
72
|
+
accountIssuer: string;
|
|
73
|
+
createAuthorizationURL({ state, scopes, redirectURI, additionalParams }: {
|
|
78
74
|
state: string;
|
|
79
75
|
codeVerifier: string;
|
|
80
76
|
scopes?: string[] | undefined;
|
|
@@ -84,18 +80,14 @@ declare const apple: (options: AppleOptions) => {
|
|
|
84
80
|
idTokenNonce?: string | undefined;
|
|
85
81
|
additionalParams?: Record<string, string> | undefined;
|
|
86
82
|
}): Promise<URL>;
|
|
87
|
-
validateAuthorizationCode: ({
|
|
88
|
-
code,
|
|
89
|
-
codeVerifier,
|
|
90
|
-
redirectURI
|
|
91
|
-
}: {
|
|
83
|
+
validateAuthorizationCode: ({ code, codeVerifier, redirectURI }: {
|
|
92
84
|
code: string;
|
|
93
85
|
redirectURI: string;
|
|
94
86
|
codeVerifier?: string | undefined;
|
|
95
87
|
deviceId?: string | undefined;
|
|
96
88
|
}) => Promise<OAuth2Tokens>;
|
|
97
89
|
idToken: {
|
|
98
|
-
jwks: (header: jose.JWTHeaderParameters) => Promise<Uint8Array<ArrayBufferLike> | CryptoKey>;
|
|
90
|
+
jwks: (header: import("jose").JWTHeaderParameters) => Promise<Uint8Array<ArrayBufferLike> | CryptoKey>;
|
|
99
91
|
issuer: string;
|
|
100
92
|
audience: string | string[];
|
|
101
93
|
maxTokenAge: string;
|
|
@@ -112,15 +104,8 @@ declare const apple: (options: AppleOptions) => {
|
|
|
112
104
|
email?: string;
|
|
113
105
|
} | undefined;
|
|
114
106
|
}): Promise<{
|
|
115
|
-
user:
|
|
116
|
-
|
|
117
|
-
name?: string;
|
|
118
|
-
email?: string | null;
|
|
119
|
-
image?: string;
|
|
120
|
-
emailVerified: boolean;
|
|
121
|
-
[key: string]: any;
|
|
122
|
-
};
|
|
123
|
-
data: any;
|
|
107
|
+
user: OAuth2UserInfo & Record<string, unknown>;
|
|
108
|
+
data: AppleProfile;
|
|
124
109
|
} | null>;
|
|
125
110
|
options: AppleOptions;
|
|
126
111
|
};
|
|
@@ -12,6 +12,8 @@ const apple = (options) => {
|
|
|
12
12
|
return {
|
|
13
13
|
id: "apple",
|
|
14
14
|
name: "Apple",
|
|
15
|
+
accountSubject: ({ profile }) => profile.sub,
|
|
16
|
+
accountIssuer: "https://appleid.apple.com",
|
|
15
17
|
async createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
|
|
16
18
|
if (!getPrimaryClientId(options.clientId) || !options.clientSecret) {
|
|
17
19
|
logger.error("Client ID and client secret are required for Apple. Make sure to provide them in the options.");
|
|
@@ -71,7 +73,6 @@ const apple = (options) => {
|
|
|
71
73
|
const userMap = await options.mapProfileToUser?.(enrichedProfile);
|
|
72
74
|
return {
|
|
73
75
|
user: {
|
|
74
|
-
id: profile.sub,
|
|
75
76
|
name: enrichedProfile.name,
|
|
76
77
|
emailVerified,
|
|
77
78
|
email: profile.email,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
1
|
+
import { OAuth2Tokens, OAuth2UserInfo, OAuthAccountKeyContext, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
+
import "../oauth2/index.mjs";
|
|
2
3
|
//#region src/social-providers/atlassian.d.ts
|
|
3
4
|
interface AtlassianProfile {
|
|
4
5
|
account_type?: string | undefined;
|
|
@@ -21,13 +22,8 @@ interface AtlassianOptions extends ProviderOptions<AtlassianProfile> {
|
|
|
21
22
|
declare const atlassian: (options: AtlassianOptions) => {
|
|
22
23
|
id: "atlassian";
|
|
23
24
|
name: string;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
scopes,
|
|
27
|
-
codeVerifier,
|
|
28
|
-
redirectURI,
|
|
29
|
-
additionalParams
|
|
30
|
-
}: {
|
|
25
|
+
accountSubject: ({ profile }: OAuthAccountKeyContext<AtlassianProfile>) => string;
|
|
26
|
+
createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }: {
|
|
31
27
|
state: string;
|
|
32
28
|
codeVerifier: string;
|
|
33
29
|
scopes?: string[] | undefined;
|
|
@@ -37,11 +33,7 @@ declare const atlassian: (options: AtlassianOptions) => {
|
|
|
37
33
|
idTokenNonce?: string | undefined;
|
|
38
34
|
additionalParams?: Record<string, string> | undefined;
|
|
39
35
|
}): Promise<URL>;
|
|
40
|
-
validateAuthorizationCode: ({
|
|
41
|
-
code,
|
|
42
|
-
codeVerifier,
|
|
43
|
-
redirectURI
|
|
44
|
-
}: {
|
|
36
|
+
validateAuthorizationCode: ({ code, codeVerifier, redirectURI }: {
|
|
45
37
|
code: string;
|
|
46
38
|
redirectURI: string;
|
|
47
39
|
codeVerifier?: string | undefined;
|
|
@@ -58,15 +50,22 @@ declare const atlassian: (options: AtlassianOptions) => {
|
|
|
58
50
|
email?: string;
|
|
59
51
|
} | undefined;
|
|
60
52
|
}): Promise<{
|
|
53
|
+
user: OAuth2UserInfo & Record<string, unknown>;
|
|
54
|
+
data: AtlassianProfile;
|
|
55
|
+
} | {
|
|
61
56
|
user: {
|
|
62
|
-
id
|
|
63
|
-
name
|
|
64
|
-
email
|
|
65
|
-
image
|
|
57
|
+
id?: never;
|
|
58
|
+
name: string;
|
|
59
|
+
email: string | null;
|
|
60
|
+
image: string;
|
|
66
61
|
emailVerified: boolean;
|
|
67
|
-
[key: string]: any;
|
|
68
62
|
};
|
|
69
|
-
data:
|
|
63
|
+
data: {
|
|
64
|
+
account_id: string;
|
|
65
|
+
name: string;
|
|
66
|
+
email?: string | undefined;
|
|
67
|
+
picture?: string | undefined;
|
|
68
|
+
};
|
|
70
69
|
} | null>;
|
|
71
70
|
options: AtlassianOptions;
|
|
72
71
|
};
|
|
@@ -10,6 +10,7 @@ const atlassian = (options) => {
|
|
|
10
10
|
return {
|
|
11
11
|
id: "atlassian",
|
|
12
12
|
name: "Atlassian",
|
|
13
|
+
accountSubject: ({ profile }) => profile.account_id,
|
|
13
14
|
async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
|
|
14
15
|
if (!options.clientId || !options.clientSecret) {
|
|
15
16
|
logger.error("Client Id and Secret are required for Atlassian");
|
|
@@ -62,7 +63,6 @@ const atlassian = (options) => {
|
|
|
62
63
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
63
64
|
return {
|
|
64
65
|
user: {
|
|
65
|
-
id: profile.account_id,
|
|
66
66
|
name: profile.name,
|
|
67
67
|
email: profile.email,
|
|
68
68
|
image: profile.picture,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import { OAuth2Tokens, OAuth2UserInfo, OAuthAccountKeyContext, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
+
import "../oauth2/index.mjs";
|
|
4
3
|
//#region src/social-providers/cognito.d.ts
|
|
5
4
|
interface CognitoProfile {
|
|
6
5
|
sub: string;
|
|
@@ -49,13 +48,9 @@ interface CognitoOptions extends ProviderOptions<CognitoProfile> {
|
|
|
49
48
|
declare const cognito: (options: CognitoOptions) => {
|
|
50
49
|
id: "cognito";
|
|
51
50
|
name: string;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
codeVerifier,
|
|
56
|
-
redirectURI,
|
|
57
|
-
additionalParams
|
|
58
|
-
}: {
|
|
51
|
+
accountSubject: ({ profile }: OAuthAccountKeyContext<CognitoProfile>) => string;
|
|
52
|
+
accountIssuer: string;
|
|
53
|
+
createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }: {
|
|
59
54
|
state: string;
|
|
60
55
|
codeVerifier: string;
|
|
61
56
|
scopes?: string[] | undefined;
|
|
@@ -65,11 +60,7 @@ declare const cognito: (options: CognitoOptions) => {
|
|
|
65
60
|
idTokenNonce?: string | undefined;
|
|
66
61
|
additionalParams?: Record<string, string> | undefined;
|
|
67
62
|
}): Promise<URL>;
|
|
68
|
-
validateAuthorizationCode: ({
|
|
69
|
-
code,
|
|
70
|
-
codeVerifier,
|
|
71
|
-
redirectURI
|
|
72
|
-
}: {
|
|
63
|
+
validateAuthorizationCode: ({ code, codeVerifier, redirectURI }: {
|
|
73
64
|
code: string;
|
|
74
65
|
redirectURI: string;
|
|
75
66
|
codeVerifier?: string | undefined;
|
|
@@ -77,7 +68,7 @@ declare const cognito: (options: CognitoOptions) => {
|
|
|
77
68
|
}) => Promise<OAuth2Tokens>;
|
|
78
69
|
refreshAccessToken: (refreshToken: string) => Promise<OAuth2Tokens>;
|
|
79
70
|
idToken: {
|
|
80
|
-
jwks: (header: jose.JWTHeaderParameters) => Promise<Uint8Array<ArrayBufferLike> | CryptoKey>;
|
|
71
|
+
jwks: (header: import("jose").JWTHeaderParameters) => Promise<Uint8Array<ArrayBufferLike> | CryptoKey>;
|
|
81
72
|
issuer: string;
|
|
82
73
|
audience: string | string[];
|
|
83
74
|
maxTokenAge: string;
|
|
@@ -92,15 +83,35 @@ declare const cognito: (options: CognitoOptions) => {
|
|
|
92
83
|
email?: string;
|
|
93
84
|
} | undefined;
|
|
94
85
|
}): Promise<{
|
|
86
|
+
user: OAuth2UserInfo & Record<string, unknown>;
|
|
87
|
+
data: CognitoProfile;
|
|
88
|
+
} | {
|
|
95
89
|
user: {
|
|
96
|
-
id
|
|
97
|
-
name
|
|
98
|
-
email
|
|
99
|
-
image
|
|
90
|
+
id?: never;
|
|
91
|
+
name: string;
|
|
92
|
+
email: string | null;
|
|
93
|
+
image: string;
|
|
100
94
|
emailVerified: boolean;
|
|
101
|
-
[key: string]: any;
|
|
102
95
|
};
|
|
103
|
-
data:
|
|
96
|
+
data: {
|
|
97
|
+
name: string;
|
|
98
|
+
sub: string;
|
|
99
|
+
email: string;
|
|
100
|
+
email_verified: boolean;
|
|
101
|
+
given_name?: string | undefined;
|
|
102
|
+
family_name?: string | undefined;
|
|
103
|
+
picture?: string | undefined;
|
|
104
|
+
username?: string | undefined;
|
|
105
|
+
locale?: string | undefined;
|
|
106
|
+
phone_number?: string | undefined;
|
|
107
|
+
phone_number_verified?: boolean | undefined;
|
|
108
|
+
aud: string | (string & string[]);
|
|
109
|
+
iss: string;
|
|
110
|
+
exp: number;
|
|
111
|
+
iat: number;
|
|
112
|
+
jti?: string;
|
|
113
|
+
nbf?: number;
|
|
114
|
+
};
|
|
104
115
|
} | null>;
|
|
105
116
|
options: CognitoOptions;
|
|
106
117
|
};
|
|
@@ -19,6 +19,8 @@ const cognito = (options) => {
|
|
|
19
19
|
return {
|
|
20
20
|
id: "cognito",
|
|
21
21
|
name: "Cognito",
|
|
22
|
+
accountSubject: ({ profile }) => profile.sub,
|
|
23
|
+
accountIssuer: `https://cognito-idp.${options.region}.amazonaws.com/${options.userPoolId}`,
|
|
22
24
|
async createAuthorizationURL({ state, scopes, codeVerifier, redirectURI, additionalParams }) {
|
|
23
25
|
if (!getPrimaryClientId(options.clientId)) {
|
|
24
26
|
logger.error("ClientId is required for Amazon Cognito. Make sure to provide them in the options.");
|
|
@@ -98,7 +100,6 @@ const cognito = (options) => {
|
|
|
98
100
|
const userMap = await options.mapProfileToUser?.(enrichedProfile);
|
|
99
101
|
return {
|
|
100
102
|
user: {
|
|
101
|
-
id: profile.sub,
|
|
102
103
|
name: enrichedProfile.name,
|
|
103
104
|
email: profile.email,
|
|
104
105
|
image: profile.picture,
|
|
@@ -116,7 +117,6 @@ const cognito = (options) => {
|
|
|
116
117
|
const userMap = await options.mapProfileToUser?.(userInfo);
|
|
117
118
|
return {
|
|
118
119
|
user: {
|
|
119
|
-
id: userInfo.sub,
|
|
120
120
|
name: userInfo.name || userInfo.given_name || userInfo.username || "",
|
|
121
121
|
email: userInfo.email,
|
|
122
122
|
image: userInfo.picture,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { OAuth2Tokens, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
1
|
+
import { OAuth2Tokens, OAuth2UserInfo, OAuthAccountKeyContext, ProviderOptions } from "../oauth2/oauth-provider.mjs";
|
|
2
|
+
import "../oauth2/index.mjs";
|
|
2
3
|
//#region src/social-providers/discord.d.ts
|
|
3
4
|
interface DiscordProfile extends Record<string, any> {
|
|
4
5
|
/** the user's id (i.e. the numerical snowflake) */
|
|
@@ -77,12 +78,8 @@ interface DiscordOptions extends ProviderOptions<DiscordProfile> {
|
|
|
77
78
|
declare const discord: (options: DiscordOptions) => {
|
|
78
79
|
id: "discord";
|
|
79
80
|
name: string;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
scopes,
|
|
83
|
-
redirectURI,
|
|
84
|
-
additionalParams
|
|
85
|
-
}: {
|
|
81
|
+
accountSubject: ({ profile }: OAuthAccountKeyContext<DiscordProfile>) => string;
|
|
82
|
+
createAuthorizationURL({ state, scopes, redirectURI, additionalParams }: {
|
|
86
83
|
state: string;
|
|
87
84
|
codeVerifier: string;
|
|
88
85
|
scopes?: string[] | undefined;
|
|
@@ -92,10 +89,7 @@ declare const discord: (options: DiscordOptions) => {
|
|
|
92
89
|
idTokenNonce?: string | undefined;
|
|
93
90
|
additionalParams?: Record<string, string> | undefined;
|
|
94
91
|
}): Promise<URL>;
|
|
95
|
-
validateAuthorizationCode: ({
|
|
96
|
-
code,
|
|
97
|
-
redirectURI
|
|
98
|
-
}: {
|
|
92
|
+
validateAuthorizationCode: ({ code, redirectURI }: {
|
|
99
93
|
code: string;
|
|
100
94
|
redirectURI: string;
|
|
101
95
|
codeVerifier?: string | undefined;
|
|
@@ -112,15 +106,8 @@ declare const discord: (options: DiscordOptions) => {
|
|
|
112
106
|
email?: string;
|
|
113
107
|
} | undefined;
|
|
114
108
|
}): Promise<{
|
|
115
|
-
user:
|
|
116
|
-
|
|
117
|
-
name?: string;
|
|
118
|
-
email?: string | null;
|
|
119
|
-
image?: string;
|
|
120
|
-
emailVerified: boolean;
|
|
121
|
-
[key: string]: any;
|
|
122
|
-
};
|
|
123
|
-
data: any;
|
|
109
|
+
user: OAuth2UserInfo & Record<string, unknown>;
|
|
110
|
+
data: DiscordProfile;
|
|
124
111
|
} | null>;
|
|
125
112
|
options: DiscordOptions;
|
|
126
113
|
};
|
|
@@ -8,6 +8,7 @@ const discord = (options) => {
|
|
|
8
8
|
return {
|
|
9
9
|
id: "discord",
|
|
10
10
|
name: "Discord",
|
|
11
|
+
accountSubject: ({ profile }) => profile.id,
|
|
11
12
|
createAuthorizationURL({ state, scopes, redirectURI, additionalParams }) {
|
|
12
13
|
const _scopes = options.disableDefaultScope ? [] : ["identify", "email"];
|
|
13
14
|
if (scopes) _scopes.push(...scopes);
|
|
@@ -58,7 +59,6 @@ const discord = (options) => {
|
|
|
58
59
|
const userMap = await options.mapProfileToUser?.(profile);
|
|
59
60
|
return {
|
|
60
61
|
user: {
|
|
61
|
-
id: profile.id,
|
|
62
62
|
name: profile.global_name || profile.username || "",
|
|
63
63
|
email: profile.email,
|
|
64
64
|
emailVerified: profile.verified,
|