@better-auth/core 1.5.5 → 1.5.7-beta.1
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 +41 -14
- package/dist/api/index.mjs +1 -2
- package/dist/api/index.mjs.map +1 -1
- package/dist/async_hooks/index.mjs +1 -1
- package/dist/async_hooks/pure.index.mjs +1 -1
- package/dist/async_hooks/pure.index.mjs.map +1 -1
- package/dist/context/endpoint-context.d.mts +1 -2
- package/dist/context/endpoint-context.mjs +1 -2
- package/dist/context/endpoint-context.mjs.map +1 -1
- package/dist/context/global.mjs +2 -2
- package/dist/context/global.mjs.map +1 -1
- package/dist/context/index.mjs +1 -2
- package/dist/context/request-state.mjs +1 -2
- package/dist/context/request-state.mjs.map +1 -1
- package/dist/context/transaction.mjs +1 -2
- package/dist/context/transaction.mjs.map +1 -1
- package/dist/db/adapter/factory.d.mts +0 -2
- package/dist/db/adapter/factory.mjs +54 -22
- package/dist/db/adapter/factory.mjs.map +1 -1
- package/dist/db/adapter/get-default-field-name.mjs +1 -2
- package/dist/db/adapter/get-default-field-name.mjs.map +1 -1
- package/dist/db/adapter/get-default-model-name.mjs +1 -2
- package/dist/db/adapter/get-default-model-name.mjs.map +1 -1
- package/dist/db/adapter/get-field-attributes.d.mts +0 -3
- package/dist/db/adapter/get-field-attributes.mjs +1 -2
- package/dist/db/adapter/get-field-attributes.mjs.map +1 -1
- package/dist/db/adapter/get-field-name.mjs +1 -2
- package/dist/db/adapter/get-field-name.mjs.map +1 -1
- package/dist/db/adapter/get-id-field.d.mts +0 -3
- package/dist/db/adapter/get-id-field.mjs +3 -4
- package/dist/db/adapter/get-id-field.mjs.map +1 -1
- package/dist/db/adapter/get-model-name.mjs +1 -2
- package/dist/db/adapter/get-model-name.mjs.map +1 -1
- package/dist/db/adapter/index.d.mts +0 -2
- package/dist/db/adapter/index.mjs +1 -2
- package/dist/db/adapter/index.mjs.map +1 -1
- package/dist/db/adapter/types.d.mts +0 -2
- package/dist/db/adapter/utils.mjs +1 -1
- package/dist/db/adapter/utils.mjs.map +1 -1
- package/dist/db/get-tables.d.mts +0 -2
- package/dist/db/get-tables.mjs +1 -1
- package/dist/db/index.mjs +1 -2
- package/dist/db/schema/account.d.mts +0 -1
- package/dist/db/schema/account.mjs +1 -2
- package/dist/db/schema/account.mjs.map +1 -1
- package/dist/db/schema/rate-limit.d.mts +0 -1
- package/dist/db/schema/rate-limit.mjs +1 -2
- package/dist/db/schema/rate-limit.mjs.map +1 -1
- package/dist/db/schema/session.d.mts +0 -1
- package/dist/db/schema/session.mjs +1 -2
- package/dist/db/schema/session.mjs.map +1 -1
- package/dist/db/schema/shared.mjs +1 -2
- package/dist/db/schema/shared.mjs.map +1 -1
- package/dist/db/schema/user.d.mts +0 -1
- package/dist/db/schema/user.mjs +1 -2
- package/dist/db/schema/user.mjs.map +1 -1
- package/dist/db/schema/verification.d.mts +0 -1
- package/dist/db/schema/verification.mjs +1 -2
- package/dist/db/schema/verification.mjs.map +1 -1
- package/dist/db/type.d.mts +0 -1
- package/dist/env/color-depth.mjs +1 -2
- package/dist/env/color-depth.mjs.map +1 -1
- package/dist/env/env-impl.mjs +1 -1
- package/dist/env/env-impl.mjs.map +1 -1
- package/dist/env/index.mjs +1 -2
- package/dist/env/logger.mjs +1 -2
- package/dist/env/logger.mjs.map +1 -1
- package/dist/error/codes.mjs +1 -2
- package/dist/error/codes.mjs.map +1 -1
- package/dist/error/index.mjs +1 -2
- package/dist/error/index.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/instrumentation/attributes.d.mts +12 -0
- package/dist/instrumentation/attributes.mjs +12 -0
- package/dist/instrumentation/attributes.mjs.map +1 -0
- package/dist/instrumentation/index.d.mts +3 -0
- package/dist/instrumentation/index.mjs +3 -0
- package/dist/instrumentation/tracer.d.mts +14 -0
- package/dist/instrumentation/tracer.mjs +36 -0
- package/dist/instrumentation/tracer.mjs.map +1 -0
- package/dist/oauth2/client-credentials-token.d.mts +0 -1
- package/dist/oauth2/client-credentials-token.mjs +1 -2
- package/dist/oauth2/client-credentials-token.mjs.map +1 -1
- package/dist/oauth2/create-authorization-url.d.mts +0 -3
- package/dist/oauth2/create-authorization-url.mjs +1 -2
- package/dist/oauth2/create-authorization-url.mjs.map +1 -1
- package/dist/oauth2/index.mjs +1 -2
- package/dist/oauth2/oauth-provider.d.mts +0 -2
- package/dist/oauth2/refresh-access-token.d.mts +0 -1
- package/dist/oauth2/refresh-access-token.mjs +1 -2
- package/dist/oauth2/refresh-access-token.mjs.map +1 -1
- package/dist/oauth2/utils.mjs +1 -2
- package/dist/oauth2/utils.mjs.map +1 -1
- package/dist/oauth2/validate-authorization-code.d.mts +0 -2
- package/dist/oauth2/validate-authorization-code.mjs +1 -2
- package/dist/oauth2/validate-authorization-code.mjs.map +1 -1
- package/dist/oauth2/verify.mjs +1 -2
- package/dist/oauth2/verify.mjs.map +1 -1
- package/dist/social-providers/apple.d.mts +0 -2
- package/dist/social-providers/apple.mjs +2 -3
- package/dist/social-providers/apple.mjs.map +1 -1
- package/dist/social-providers/atlassian.d.mts +0 -2
- package/dist/social-providers/atlassian.mjs +4 -4
- package/dist/social-providers/atlassian.mjs.map +1 -1
- package/dist/social-providers/cognito.d.mts +0 -2
- package/dist/social-providers/cognito.mjs +1 -2
- package/dist/social-providers/cognito.mjs.map +1 -1
- package/dist/social-providers/discord.d.mts +0 -2
- package/dist/social-providers/discord.mjs +4 -4
- package/dist/social-providers/discord.mjs.map +1 -1
- package/dist/social-providers/dropbox.d.mts +0 -2
- package/dist/social-providers/dropbox.mjs +1 -2
- package/dist/social-providers/dropbox.mjs.map +1 -1
- package/dist/social-providers/facebook.d.mts +0 -2
- package/dist/social-providers/facebook.mjs +1 -2
- package/dist/social-providers/facebook.mjs.map +1 -1
- package/dist/social-providers/figma.d.mts +0 -2
- package/dist/social-providers/figma.mjs +4 -4
- package/dist/social-providers/figma.mjs.map +1 -1
- package/dist/social-providers/github.d.mts +0 -2
- package/dist/social-providers/github.mjs +2 -3
- package/dist/social-providers/github.mjs.map +1 -1
- package/dist/social-providers/gitlab.d.mts +0 -2
- package/dist/social-providers/gitlab.mjs +1 -2
- package/dist/social-providers/gitlab.mjs.map +1 -1
- package/dist/social-providers/google.d.mts +0 -2
- package/dist/social-providers/google.mjs +1 -2
- package/dist/social-providers/google.mjs.map +1 -1
- package/dist/social-providers/huggingface.d.mts +0 -2
- package/dist/social-providers/huggingface.mjs +4 -4
- package/dist/social-providers/huggingface.mjs.map +1 -1
- package/dist/social-providers/index.d.mts +61 -3
- package/dist/social-providers/index.mjs +5 -4
- package/dist/social-providers/index.mjs.map +1 -1
- package/dist/social-providers/kakao.d.mts +0 -2
- package/dist/social-providers/kakao.mjs +4 -4
- package/dist/social-providers/kakao.mjs.map +1 -1
- package/dist/social-providers/kick.d.mts +0 -2
- package/dist/social-providers/kick.mjs +1 -2
- package/dist/social-providers/kick.mjs.map +1 -1
- package/dist/social-providers/line.d.mts +0 -2
- package/dist/social-providers/line.mjs +1 -2
- package/dist/social-providers/line.mjs.map +1 -1
- package/dist/social-providers/linear.d.mts +0 -2
- package/dist/social-providers/linear.mjs +1 -2
- package/dist/social-providers/linear.mjs.map +1 -1
- package/dist/social-providers/linkedin.d.mts +0 -2
- package/dist/social-providers/linkedin.mjs +1 -2
- package/dist/social-providers/linkedin.mjs.map +1 -1
- package/dist/social-providers/microsoft-entra-id.d.mts +0 -2
- package/dist/social-providers/microsoft-entra-id.mjs +1 -2
- package/dist/social-providers/microsoft-entra-id.mjs.map +1 -1
- package/dist/social-providers/naver.d.mts +0 -2
- package/dist/social-providers/naver.mjs +4 -4
- package/dist/social-providers/naver.mjs.map +1 -1
- package/dist/social-providers/notion.d.mts +0 -2
- package/dist/social-providers/notion.mjs +1 -2
- package/dist/social-providers/notion.mjs.map +1 -1
- package/dist/social-providers/paybin.d.mts +0 -2
- package/dist/social-providers/paybin.mjs +1 -2
- package/dist/social-providers/paybin.mjs.map +1 -1
- package/dist/social-providers/paypal.d.mts +0 -2
- package/dist/social-providers/paypal.mjs +1 -2
- package/dist/social-providers/paypal.mjs.map +1 -1
- package/dist/social-providers/polar.d.mts +0 -2
- package/dist/social-providers/polar.mjs +4 -4
- package/dist/social-providers/polar.mjs.map +1 -1
- package/dist/social-providers/railway.d.mts +0 -2
- package/dist/social-providers/railway.mjs +1 -2
- package/dist/social-providers/railway.mjs.map +1 -1
- package/dist/social-providers/reddit.d.mts +0 -2
- package/dist/social-providers/reddit.mjs +1 -2
- package/dist/social-providers/reddit.mjs.map +1 -1
- package/dist/social-providers/roblox.d.mts +0 -2
- package/dist/social-providers/roblox.mjs +4 -4
- package/dist/social-providers/roblox.mjs.map +1 -1
- package/dist/social-providers/salesforce.d.mts +0 -2
- package/dist/social-providers/salesforce.mjs +1 -2
- package/dist/social-providers/salesforce.mjs.map +1 -1
- package/dist/social-providers/slack.d.mts +0 -2
- package/dist/social-providers/slack.mjs +4 -4
- package/dist/social-providers/slack.mjs.map +1 -1
- package/dist/social-providers/spotify.d.mts +0 -2
- package/dist/social-providers/spotify.mjs +4 -4
- package/dist/social-providers/spotify.mjs.map +1 -1
- package/dist/social-providers/tiktok.d.mts +0 -2
- package/dist/social-providers/tiktok.mjs +4 -4
- package/dist/social-providers/tiktok.mjs.map +1 -1
- package/dist/social-providers/twitch.d.mts +0 -2
- package/dist/social-providers/twitch.mjs +4 -4
- package/dist/social-providers/twitch.mjs.map +1 -1
- package/dist/social-providers/twitter.d.mts +0 -2
- package/dist/social-providers/twitter.mjs +4 -4
- package/dist/social-providers/twitter.mjs.map +1 -1
- package/dist/social-providers/vercel.d.mts +0 -2
- package/dist/social-providers/vercel.mjs +1 -2
- package/dist/social-providers/vercel.mjs.map +1 -1
- package/dist/social-providers/vk.d.mts +0 -2
- package/dist/social-providers/vk.mjs +4 -4
- package/dist/social-providers/vk.mjs.map +1 -1
- package/dist/social-providers/wechat.d.mts +114 -0
- package/dist/social-providers/wechat.mjs +83 -0
- package/dist/social-providers/wechat.mjs.map +1 -0
- package/dist/social-providers/zoom.d.mts +0 -2
- package/dist/social-providers/zoom.mjs +1 -2
- package/dist/social-providers/zoom.mjs.map +1 -1
- package/dist/types/context.d.mts +1 -5
- package/dist/types/init-options.d.mts +0 -1
- package/dist/types/plugin.d.mts +4 -2
- package/dist/utils/db.d.mts +0 -2
- package/dist/utils/db.mjs +1 -1
- package/dist/utils/deprecate.mjs +1 -1
- package/dist/utils/error-codes.mjs +1 -1
- package/dist/utils/fetch-metadata.mjs +1 -1
- package/dist/utils/id.mjs +1 -2
- package/dist/utils/id.mjs.map +1 -1
- package/dist/utils/ip.mjs +1 -2
- package/dist/utils/ip.mjs.map +1 -1
- package/dist/utils/json.mjs +1 -2
- package/dist/utils/json.mjs.map +1 -1
- package/dist/utils/string.mjs +1 -1
- package/dist/utils/url.mjs +1 -1
- package/package.json +18 -5
- package/src/api/index.ts +151 -41
- package/src/context/endpoint-context.ts +2 -1
- package/src/db/adapter/factory.ts +119 -47
- package/src/db/adapter/get-id-field.test.ts +222 -0
- package/src/db/adapter/get-id-field.ts +15 -4
- package/src/instrumentation/attributes.ts +22 -0
- package/src/instrumentation/index.ts +2 -0
- package/src/instrumentation/instrumentation.test.ts +139 -0
- package/src/instrumentation/tracer.ts +62 -0
- package/src/social-providers/apple.ts +1 -1
- package/src/social-providers/atlassian.ts +3 -2
- package/src/social-providers/discord.ts +3 -2
- package/src/social-providers/figma.ts +3 -2
- package/src/social-providers/github.ts +1 -1
- package/src/social-providers/huggingface.ts +3 -2
- package/src/social-providers/index.ts +3 -0
- package/src/social-providers/kakao.ts +3 -2
- package/src/social-providers/naver.ts +3 -2
- package/src/social-providers/polar.ts +3 -2
- package/src/social-providers/roblox.ts +3 -2
- package/src/social-providers/slack.ts +3 -2
- package/src/social-providers/spotify.ts +3 -2
- package/src/social-providers/tiktok.ts +3 -2
- package/src/social-providers/twitch.ts +3 -2
- package/src/social-providers/twitter.ts +3 -2
- package/src/social-providers/vk.ts +3 -2
- package/src/social-providers/wechat.ts +213 -0
- package/src/types/context.ts +1 -3
- package/src/types/plugin.ts +14 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
2
|
+
|
|
3
|
+
const INSTRUMENTATION_SCOPE = "better-auth";
|
|
4
|
+
const INSTRUMENTATION_VERSION = import.meta.env?.BETTER_AUTH_VERSION ?? "1.0.0";
|
|
5
|
+
|
|
6
|
+
const tracer = trace.getTracer(INSTRUMENTATION_SCOPE, INSTRUMENTATION_VERSION);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a child span whose lifetime is bound to the execution of the given function
|
|
10
|
+
*
|
|
11
|
+
* @param name - The name of the span.
|
|
12
|
+
* @param attributes - The attributes of the span.
|
|
13
|
+
* @param fn - The function to execute within the span.
|
|
14
|
+
* @returns The result of the function.
|
|
15
|
+
*/
|
|
16
|
+
export function withSpan<T>(
|
|
17
|
+
name: string,
|
|
18
|
+
attributes: Record<string, string | number | boolean>,
|
|
19
|
+
fn: () => T,
|
|
20
|
+
): T;
|
|
21
|
+
export function withSpan<T>(
|
|
22
|
+
name: string,
|
|
23
|
+
attributes: Record<string, string | number | boolean>,
|
|
24
|
+
fn: () => Promise<T>,
|
|
25
|
+
): Promise<T>;
|
|
26
|
+
export function withSpan<T>(
|
|
27
|
+
name: string,
|
|
28
|
+
attributes: Record<string, string | number | boolean>,
|
|
29
|
+
fn: () => T | Promise<T>,
|
|
30
|
+
): T | Promise<T> {
|
|
31
|
+
return tracer.startActiveSpan(name, { attributes }, (span) => {
|
|
32
|
+
try {
|
|
33
|
+
const result = fn();
|
|
34
|
+
if (result instanceof Promise) {
|
|
35
|
+
return result
|
|
36
|
+
.then((value) => {
|
|
37
|
+
span.end();
|
|
38
|
+
return value;
|
|
39
|
+
})
|
|
40
|
+
.catch((err) => {
|
|
41
|
+
span.recordException(err);
|
|
42
|
+
span.setStatus({
|
|
43
|
+
code: SpanStatusCode.ERROR,
|
|
44
|
+
message: String(err.message ?? err),
|
|
45
|
+
});
|
|
46
|
+
span.end();
|
|
47
|
+
throw err;
|
|
48
|
+
}) as Promise<T>;
|
|
49
|
+
}
|
|
50
|
+
span.end();
|
|
51
|
+
return result;
|
|
52
|
+
} catch (err) {
|
|
53
|
+
span.recordException(err as Error);
|
|
54
|
+
span.setStatus({
|
|
55
|
+
code: SpanStatusCode.ERROR,
|
|
56
|
+
message: String((err as Error)?.message ?? err),
|
|
57
|
+
});
|
|
58
|
+
span.end();
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -30,6 +30,7 @@ export interface AtlassianOptions extends ProviderOptions<AtlassianProfile> {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export const atlassian = (options: AtlassianOptions) => {
|
|
33
|
+
const tokenEndpoint = "https://auth.atlassian.com/oauth/token";
|
|
33
34
|
return {
|
|
34
35
|
id: "atlassian",
|
|
35
36
|
name: "Atlassian",
|
|
@@ -70,7 +71,7 @@ export const atlassian = (options: AtlassianOptions) => {
|
|
|
70
71
|
codeVerifier,
|
|
71
72
|
redirectURI,
|
|
72
73
|
options,
|
|
73
|
-
tokenEndpoint
|
|
74
|
+
tokenEndpoint,
|
|
74
75
|
});
|
|
75
76
|
},
|
|
76
77
|
|
|
@@ -83,7 +84,7 @@ export const atlassian = (options: AtlassianOptions) => {
|
|
|
83
84
|
clientId: options.clientId,
|
|
84
85
|
clientSecret: options.clientSecret,
|
|
85
86
|
},
|
|
86
|
-
tokenEndpoint
|
|
87
|
+
tokenEndpoint,
|
|
87
88
|
});
|
|
88
89
|
},
|
|
89
90
|
|
|
@@ -80,6 +80,7 @@ export interface DiscordOptions extends ProviderOptions<DiscordProfile> {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
export const discord = (options: DiscordOptions) => {
|
|
83
|
+
const tokenEndpoint = "https://discord.com/api/oauth2/token";
|
|
83
84
|
return {
|
|
84
85
|
id: "discord",
|
|
85
86
|
name: "Discord",
|
|
@@ -109,7 +110,7 @@ export const discord = (options: DiscordOptions) => {
|
|
|
109
110
|
code,
|
|
110
111
|
redirectURI,
|
|
111
112
|
options,
|
|
112
|
-
tokenEndpoint
|
|
113
|
+
tokenEndpoint,
|
|
113
114
|
});
|
|
114
115
|
},
|
|
115
116
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -122,7 +123,7 @@ export const discord = (options: DiscordOptions) => {
|
|
|
122
123
|
clientKey: options.clientKey,
|
|
123
124
|
clientSecret: options.clientSecret,
|
|
124
125
|
},
|
|
125
|
-
tokenEndpoint
|
|
126
|
+
tokenEndpoint,
|
|
126
127
|
});
|
|
127
128
|
},
|
|
128
129
|
async getUserInfo(token) {
|
|
@@ -20,6 +20,7 @@ export interface FigmaOptions extends ProviderOptions<FigmaProfile> {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const figma = (options: FigmaOptions) => {
|
|
23
|
+
const tokenEndpoint = "https://api.figma.com/v1/oauth/token";
|
|
23
24
|
return {
|
|
24
25
|
id: "figma",
|
|
25
26
|
name: "Figma",
|
|
@@ -56,7 +57,7 @@ export const figma = (options: FigmaOptions) => {
|
|
|
56
57
|
codeVerifier,
|
|
57
58
|
redirectURI,
|
|
58
59
|
options,
|
|
59
|
-
tokenEndpoint
|
|
60
|
+
tokenEndpoint,
|
|
60
61
|
authentication: "basic",
|
|
61
62
|
});
|
|
62
63
|
},
|
|
@@ -70,7 +71,7 @@ export const figma = (options: FigmaOptions) => {
|
|
|
70
71
|
clientKey: options.clientKey,
|
|
71
72
|
clientSecret: options.clientSecret,
|
|
72
73
|
},
|
|
73
|
-
tokenEndpoint
|
|
74
|
+
tokenEndpoint,
|
|
74
75
|
authentication: "basic",
|
|
75
76
|
});
|
|
76
77
|
},
|
|
@@ -126,7 +126,7 @@ export const github = (options: GithubOptions) => {
|
|
|
126
126
|
clientKey: options.clientKey,
|
|
127
127
|
clientSecret: options.clientSecret,
|
|
128
128
|
},
|
|
129
|
-
tokenEndpoint
|
|
129
|
+
tokenEndpoint,
|
|
130
130
|
});
|
|
131
131
|
},
|
|
132
132
|
async getUserInfo(token) {
|
|
@@ -43,6 +43,7 @@ export interface HuggingFaceOptions
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
export const huggingface = (options: HuggingFaceOptions) => {
|
|
46
|
+
const tokenEndpoint = "https://huggingface.co/oauth/token";
|
|
46
47
|
return {
|
|
47
48
|
id: "huggingface",
|
|
48
49
|
name: "Hugging Face",
|
|
@@ -68,7 +69,7 @@ export const huggingface = (options: HuggingFaceOptions) => {
|
|
|
68
69
|
codeVerifier,
|
|
69
70
|
redirectURI,
|
|
70
71
|
options,
|
|
71
|
-
tokenEndpoint
|
|
72
|
+
tokenEndpoint,
|
|
72
73
|
});
|
|
73
74
|
},
|
|
74
75
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -81,7 +82,7 @@ export const huggingface = (options: HuggingFaceOptions) => {
|
|
|
81
82
|
clientKey: options.clientKey,
|
|
82
83
|
clientSecret: options.clientSecret,
|
|
83
84
|
},
|
|
84
|
-
tokenEndpoint
|
|
85
|
+
tokenEndpoint,
|
|
85
86
|
});
|
|
86
87
|
},
|
|
87
88
|
async getUserInfo(token) {
|
|
@@ -33,6 +33,7 @@ import { twitch } from "./twitch";
|
|
|
33
33
|
import { twitter } from "./twitter";
|
|
34
34
|
import { vercel } from "./vercel";
|
|
35
35
|
import { vk } from "./vk";
|
|
36
|
+
import { wechat } from "./wechat";
|
|
36
37
|
import { zoom } from "./zoom";
|
|
37
38
|
|
|
38
39
|
export const socialProviders = {
|
|
@@ -70,6 +71,7 @@ export const socialProviders = {
|
|
|
70
71
|
polar,
|
|
71
72
|
railway,
|
|
72
73
|
vercel,
|
|
74
|
+
wechat,
|
|
73
75
|
};
|
|
74
76
|
|
|
75
77
|
export const socialProviderList = Object.keys(socialProviders) as [
|
|
@@ -126,6 +128,7 @@ export * from "./twitch";
|
|
|
126
128
|
export * from "./twitter";
|
|
127
129
|
export * from "./vercel";
|
|
128
130
|
export * from "./vk";
|
|
131
|
+
export * from "./wechat";
|
|
129
132
|
export * from "./zoom";
|
|
130
133
|
|
|
131
134
|
export type SocialProviderList = typeof socialProviderList;
|
|
@@ -102,6 +102,7 @@ export interface KakaoOptions extends ProviderOptions<KakaoProfile> {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
export const kakao = (options: KakaoOptions) => {
|
|
105
|
+
const tokenEndpoint = "https://kauth.kakao.com/oauth/token";
|
|
105
106
|
return {
|
|
106
107
|
id: "kakao",
|
|
107
108
|
name: "Kakao",
|
|
@@ -125,7 +126,7 @@ export const kakao = (options: KakaoOptions) => {
|
|
|
125
126
|
code,
|
|
126
127
|
redirectURI,
|
|
127
128
|
options,
|
|
128
|
-
tokenEndpoint
|
|
129
|
+
tokenEndpoint,
|
|
129
130
|
});
|
|
130
131
|
},
|
|
131
132
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -138,7 +139,7 @@ export const kakao = (options: KakaoOptions) => {
|
|
|
138
139
|
clientKey: options.clientKey,
|
|
139
140
|
clientSecret: options.clientSecret,
|
|
140
141
|
},
|
|
141
|
-
tokenEndpoint
|
|
142
|
+
tokenEndpoint,
|
|
142
143
|
});
|
|
143
144
|
},
|
|
144
145
|
async getUserInfo(token) {
|
|
@@ -40,6 +40,7 @@ export interface NaverOptions extends ProviderOptions<NaverProfile> {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export const naver = (options: NaverOptions) => {
|
|
43
|
+
const tokenEndpoint = "https://nid.naver.com/oauth2.0/token";
|
|
43
44
|
return {
|
|
44
45
|
id: "naver",
|
|
45
46
|
name: "Naver",
|
|
@@ -61,7 +62,7 @@ export const naver = (options: NaverOptions) => {
|
|
|
61
62
|
code,
|
|
62
63
|
redirectURI,
|
|
63
64
|
options,
|
|
64
|
-
tokenEndpoint
|
|
65
|
+
tokenEndpoint,
|
|
65
66
|
});
|
|
66
67
|
},
|
|
67
68
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -74,7 +75,7 @@ export const naver = (options: NaverOptions) => {
|
|
|
74
75
|
clientKey: options.clientKey,
|
|
75
76
|
clientSecret: options.clientSecret,
|
|
76
77
|
},
|
|
77
|
-
tokenEndpoint
|
|
78
|
+
tokenEndpoint,
|
|
78
79
|
});
|
|
79
80
|
},
|
|
80
81
|
async getUserInfo(token) {
|
|
@@ -33,6 +33,7 @@ export interface PolarProfile {
|
|
|
33
33
|
export interface PolarOptions extends ProviderOptions<PolarProfile> {}
|
|
34
34
|
|
|
35
35
|
export const polar = (options: PolarOptions) => {
|
|
36
|
+
const tokenEndpoint = "https://api.polar.sh/v1/oauth2/token";
|
|
36
37
|
return {
|
|
37
38
|
id: "polar",
|
|
38
39
|
name: "Polar",
|
|
@@ -59,7 +60,7 @@ export const polar = (options: PolarOptions) => {
|
|
|
59
60
|
codeVerifier,
|
|
60
61
|
redirectURI,
|
|
61
62
|
options,
|
|
62
|
-
tokenEndpoint
|
|
63
|
+
tokenEndpoint,
|
|
63
64
|
});
|
|
64
65
|
},
|
|
65
66
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -72,7 +73,7 @@ export const polar = (options: PolarOptions) => {
|
|
|
72
73
|
clientKey: options.clientKey,
|
|
73
74
|
clientSecret: options.clientSecret,
|
|
74
75
|
},
|
|
75
|
-
tokenEndpoint
|
|
76
|
+
tokenEndpoint,
|
|
76
77
|
});
|
|
77
78
|
},
|
|
78
79
|
async getUserInfo(token) {
|
|
@@ -33,6 +33,7 @@ export interface RobloxOptions extends ProviderOptions<RobloxProfile> {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export const roblox = (options: RobloxOptions) => {
|
|
36
|
+
const tokenEndpoint = "https://apis.roblox.com/oauth/v1/token";
|
|
36
37
|
return {
|
|
37
38
|
id: "roblox",
|
|
38
39
|
name: "Roblox",
|
|
@@ -55,7 +56,7 @@ export const roblox = (options: RobloxOptions) => {
|
|
|
55
56
|
code,
|
|
56
57
|
redirectURI: options.redirectURI || redirectURI,
|
|
57
58
|
options,
|
|
58
|
-
tokenEndpoint
|
|
59
|
+
tokenEndpoint,
|
|
59
60
|
authentication: "post",
|
|
60
61
|
});
|
|
61
62
|
},
|
|
@@ -69,7 +70,7 @@ export const roblox = (options: RobloxOptions) => {
|
|
|
69
70
|
clientKey: options.clientKey,
|
|
70
71
|
clientSecret: options.clientSecret,
|
|
71
72
|
},
|
|
72
|
-
tokenEndpoint
|
|
73
|
+
tokenEndpoint,
|
|
73
74
|
});
|
|
74
75
|
},
|
|
75
76
|
async getUserInfo(token) {
|
|
@@ -38,6 +38,7 @@ export interface SlackOptions extends ProviderOptions<SlackProfile> {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export const slack = (options: SlackOptions) => {
|
|
41
|
+
const tokenEndpoint = "https://slack.com/api/openid.connect.token";
|
|
41
42
|
return {
|
|
42
43
|
id: "slack",
|
|
43
44
|
name: "Slack",
|
|
@@ -60,7 +61,7 @@ export const slack = (options: SlackOptions) => {
|
|
|
60
61
|
code,
|
|
61
62
|
redirectURI,
|
|
62
63
|
options,
|
|
63
|
-
tokenEndpoint
|
|
64
|
+
tokenEndpoint,
|
|
64
65
|
});
|
|
65
66
|
},
|
|
66
67
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -73,7 +74,7 @@ export const slack = (options: SlackOptions) => {
|
|
|
73
74
|
clientKey: options.clientKey,
|
|
74
75
|
clientSecret: options.clientSecret,
|
|
75
76
|
},
|
|
76
|
-
tokenEndpoint
|
|
77
|
+
tokenEndpoint,
|
|
77
78
|
});
|
|
78
79
|
},
|
|
79
80
|
async getUserInfo(token) {
|
|
@@ -20,6 +20,7 @@ export interface SpotifyOptions extends ProviderOptions<SpotifyProfile> {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const spotify = (options: SpotifyOptions) => {
|
|
23
|
+
const tokenEndpoint = "https://accounts.spotify.com/api/token";
|
|
23
24
|
return {
|
|
24
25
|
id: "spotify",
|
|
25
26
|
name: "Spotify",
|
|
@@ -43,7 +44,7 @@ export const spotify = (options: SpotifyOptions) => {
|
|
|
43
44
|
codeVerifier,
|
|
44
45
|
redirectURI,
|
|
45
46
|
options,
|
|
46
|
-
tokenEndpoint
|
|
47
|
+
tokenEndpoint,
|
|
47
48
|
});
|
|
48
49
|
},
|
|
49
50
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -56,7 +57,7 @@ export const spotify = (options: SpotifyOptions) => {
|
|
|
56
57
|
clientKey: options.clientKey,
|
|
57
58
|
clientSecret: options.clientSecret,
|
|
58
59
|
},
|
|
59
|
-
tokenEndpoint
|
|
60
|
+
tokenEndpoint,
|
|
60
61
|
});
|
|
61
62
|
},
|
|
62
63
|
async getUserInfo(token) {
|
|
@@ -127,6 +127,7 @@ export interface TiktokOptions extends ProviderOptions {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
export const tiktok = (options: TiktokOptions) => {
|
|
130
|
+
const tokenEndpoint = "https://open.tiktokapis.com/v2/oauth/token/";
|
|
130
131
|
return {
|
|
131
132
|
id: "tiktok",
|
|
132
133
|
name: "TikTok",
|
|
@@ -151,7 +152,7 @@ export const tiktok = (options: TiktokOptions) => {
|
|
|
151
152
|
clientKey: options.clientKey,
|
|
152
153
|
clientSecret: options.clientSecret,
|
|
153
154
|
},
|
|
154
|
-
tokenEndpoint
|
|
155
|
+
tokenEndpoint,
|
|
155
156
|
});
|
|
156
157
|
},
|
|
157
158
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -162,7 +163,7 @@ export const tiktok = (options: TiktokOptions) => {
|
|
|
162
163
|
options: {
|
|
163
164
|
clientSecret: options.clientSecret,
|
|
164
165
|
},
|
|
165
|
-
tokenEndpoint
|
|
166
|
+
tokenEndpoint,
|
|
166
167
|
authentication: "post",
|
|
167
168
|
extraParams: {
|
|
168
169
|
client_key: options.clientKey,
|
|
@@ -38,6 +38,7 @@ export interface TwitchOptions extends ProviderOptions<TwitchProfile> {
|
|
|
38
38
|
claims?: string[] | undefined;
|
|
39
39
|
}
|
|
40
40
|
export const twitch = (options: TwitchOptions) => {
|
|
41
|
+
const tokenEndpoint = "https://id.twitch.tv/oauth2/token";
|
|
41
42
|
return {
|
|
42
43
|
id: "twitch",
|
|
43
44
|
name: "Twitch",
|
|
@@ -67,7 +68,7 @@ export const twitch = (options: TwitchOptions) => {
|
|
|
67
68
|
code,
|
|
68
69
|
redirectURI,
|
|
69
70
|
options,
|
|
70
|
-
tokenEndpoint
|
|
71
|
+
tokenEndpoint,
|
|
71
72
|
});
|
|
72
73
|
},
|
|
73
74
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -80,7 +81,7 @@ export const twitch = (options: TwitchOptions) => {
|
|
|
80
81
|
clientKey: options.clientKey,
|
|
81
82
|
clientSecret: options.clientSecret,
|
|
82
83
|
},
|
|
83
|
-
tokenEndpoint
|
|
84
|
+
tokenEndpoint,
|
|
84
85
|
});
|
|
85
86
|
},
|
|
86
87
|
async getUserInfo(token) {
|
|
@@ -104,6 +104,7 @@ export interface TwitterOption extends ProviderOptions<TwitterProfile> {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
export const twitter = (options: TwitterOption) => {
|
|
107
|
+
const tokenEndpoint = "https://api.x.com/2/oauth2/token";
|
|
107
108
|
return {
|
|
108
109
|
id: "twitter",
|
|
109
110
|
name: "Twitter",
|
|
@@ -130,7 +131,7 @@ export const twitter = (options: TwitterOption) => {
|
|
|
130
131
|
authentication: "basic",
|
|
131
132
|
redirectURI,
|
|
132
133
|
options,
|
|
133
|
-
tokenEndpoint
|
|
134
|
+
tokenEndpoint,
|
|
134
135
|
});
|
|
135
136
|
},
|
|
136
137
|
|
|
@@ -145,7 +146,7 @@ export const twitter = (options: TwitterOption) => {
|
|
|
145
146
|
clientSecret: options.clientSecret,
|
|
146
147
|
},
|
|
147
148
|
authentication: "basic",
|
|
148
|
-
tokenEndpoint
|
|
149
|
+
tokenEndpoint,
|
|
149
150
|
});
|
|
150
151
|
},
|
|
151
152
|
async getUserInfo(token) {
|
|
@@ -26,6 +26,7 @@ export interface VkOption extends ProviderOptions {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export const vk = (options: VkOption) => {
|
|
29
|
+
const tokenEndpoint = "https://id.vk.com/oauth2/auth";
|
|
29
30
|
return {
|
|
30
31
|
id: "vk",
|
|
31
32
|
name: "VK",
|
|
@@ -57,7 +58,7 @@ export const vk = (options: VkOption) => {
|
|
|
57
58
|
redirectURI: options.redirectURI || redirectURI,
|
|
58
59
|
options,
|
|
59
60
|
deviceId,
|
|
60
|
-
tokenEndpoint
|
|
61
|
+
tokenEndpoint,
|
|
61
62
|
});
|
|
62
63
|
},
|
|
63
64
|
refreshAccessToken: options.refreshAccessToken
|
|
@@ -70,7 +71,7 @@ export const vk = (options: VkOption) => {
|
|
|
70
71
|
clientKey: options.clientKey,
|
|
71
72
|
clientSecret: options.clientSecret,
|
|
72
73
|
},
|
|
73
|
-
tokenEndpoint
|
|
74
|
+
tokenEndpoint,
|
|
74
75
|
});
|
|
75
76
|
},
|
|
76
77
|
async getUserInfo(data) {
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
2
|
+
import type { OAuth2Tokens, OAuthProvider, ProviderOptions } from "../oauth2";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* WeChat user profile information
|
|
6
|
+
* @see https://developers.weixin.qq.com/doc/oplatform/en/Website_App/WeChat_Login/Wechat_Login.html
|
|
7
|
+
*/
|
|
8
|
+
export interface WeChatProfile extends Record<string, any> {
|
|
9
|
+
/**
|
|
10
|
+
* User's unique OpenID
|
|
11
|
+
*/
|
|
12
|
+
openid: string;
|
|
13
|
+
/**
|
|
14
|
+
* User's nickname
|
|
15
|
+
*/
|
|
16
|
+
nickname: string;
|
|
17
|
+
/**
|
|
18
|
+
* User's avatar image URL
|
|
19
|
+
*/
|
|
20
|
+
headimgurl: string;
|
|
21
|
+
/**
|
|
22
|
+
* User's privileges
|
|
23
|
+
*/
|
|
24
|
+
privilege: string[];
|
|
25
|
+
/**
|
|
26
|
+
* User's UnionID (unique across the developer's various applications)
|
|
27
|
+
*/
|
|
28
|
+
unionid?: string;
|
|
29
|
+
/** @note Email is currently unsupported by WeChat */
|
|
30
|
+
email?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface WeChatOptions extends ProviderOptions<WeChatProfile> {
|
|
34
|
+
/**
|
|
35
|
+
* WeChat App ID
|
|
36
|
+
*/
|
|
37
|
+
clientId: string;
|
|
38
|
+
/**
|
|
39
|
+
* WeChat App Secret
|
|
40
|
+
*/
|
|
41
|
+
clientSecret: string;
|
|
42
|
+
/**
|
|
43
|
+
* Platform type for WeChat login
|
|
44
|
+
* - Currently only supports "WebsiteApp" for WeChat Website Application (网站应用)
|
|
45
|
+
* @default "WebsiteApp"
|
|
46
|
+
*/
|
|
47
|
+
platformType?: "WebsiteApp";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* UI language for the WeChat login page
|
|
51
|
+
* cn for Simplified Chinese, en for English
|
|
52
|
+
* @default "cn" if left undefined
|
|
53
|
+
*/
|
|
54
|
+
lang?: "cn" | "en";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const wechat = (options: WeChatOptions) => {
|
|
58
|
+
return {
|
|
59
|
+
id: "wechat",
|
|
60
|
+
name: "WeChat",
|
|
61
|
+
createAuthorizationURL({ state, scopes, redirectURI }) {
|
|
62
|
+
const _scopes = options.disableDefaultScope ? [] : ["snsapi_login"];
|
|
63
|
+
options.scope && _scopes.push(...options.scope);
|
|
64
|
+
scopes && _scopes.push(...scopes);
|
|
65
|
+
|
|
66
|
+
// WeChat uses non-standard OAuth2 parameters (appid instead of client_id)
|
|
67
|
+
// and requires a fragment (#wechat_redirect), so we construct the URL manually.
|
|
68
|
+
const url = new URL("https://open.weixin.qq.com/connect/qrconnect");
|
|
69
|
+
url.searchParams.set("scope", _scopes.join(","));
|
|
70
|
+
url.searchParams.set("response_type", "code");
|
|
71
|
+
url.searchParams.set("appid", options.clientId);
|
|
72
|
+
url.searchParams.set("redirect_uri", options.redirectURI || redirectURI);
|
|
73
|
+
url.searchParams.set("state", state);
|
|
74
|
+
url.searchParams.set("lang", options.lang || "cn");
|
|
75
|
+
url.hash = "wechat_redirect";
|
|
76
|
+
|
|
77
|
+
return url;
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
// WeChat uses non-standard token exchange (appid/secret instead of
|
|
81
|
+
// client_id/client_secret, GET instead of POST), so shared helpers
|
|
82
|
+
// like validateAuthorizationCode/getOAuth2Tokens cannot be used directly.
|
|
83
|
+
validateAuthorizationCode: async ({ code }) => {
|
|
84
|
+
const params = new URLSearchParams({
|
|
85
|
+
appid: options.clientId,
|
|
86
|
+
secret: options.clientSecret,
|
|
87
|
+
code: code,
|
|
88
|
+
grant_type: "authorization_code",
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const { data: tokenData, error } = await betterFetch<{
|
|
92
|
+
access_token: string;
|
|
93
|
+
expires_in: number;
|
|
94
|
+
refresh_token: string;
|
|
95
|
+
openid: string;
|
|
96
|
+
scope: string;
|
|
97
|
+
unionid?: string;
|
|
98
|
+
errcode?: number;
|
|
99
|
+
errmsg?: string;
|
|
100
|
+
}>(
|
|
101
|
+
"https://api.weixin.qq.com/sns/oauth2/access_token?" +
|
|
102
|
+
params.toString(),
|
|
103
|
+
{
|
|
104
|
+
method: "GET",
|
|
105
|
+
},
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
if (error || !tokenData || tokenData.errcode) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`Failed to validate authorization code: ${tokenData?.errmsg || error?.message || "Unknown error"}`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
tokenType: "Bearer" as const,
|
|
116
|
+
accessToken: tokenData.access_token,
|
|
117
|
+
refreshToken: tokenData.refresh_token,
|
|
118
|
+
accessTokenExpiresAt: new Date(
|
|
119
|
+
Date.now() + tokenData.expires_in * 1000,
|
|
120
|
+
),
|
|
121
|
+
scopes: tokenData.scope.split(","),
|
|
122
|
+
// WeChat requires openid for the userinfo endpoint, which is
|
|
123
|
+
// returned alongside the access token.
|
|
124
|
+
openid: tokenData.openid,
|
|
125
|
+
unionid: tokenData.unionid,
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
refreshAccessToken: options.refreshAccessToken
|
|
130
|
+
? options.refreshAccessToken
|
|
131
|
+
: async (refreshToken) => {
|
|
132
|
+
const params = new URLSearchParams({
|
|
133
|
+
appid: options.clientId,
|
|
134
|
+
grant_type: "refresh_token",
|
|
135
|
+
refresh_token: refreshToken,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const { data: tokenData, error } = await betterFetch<{
|
|
139
|
+
access_token: string;
|
|
140
|
+
expires_in: number;
|
|
141
|
+
refresh_token: string;
|
|
142
|
+
openid: string;
|
|
143
|
+
scope: string;
|
|
144
|
+
errcode?: number;
|
|
145
|
+
errmsg?: string;
|
|
146
|
+
}>(
|
|
147
|
+
"https://api.weixin.qq.com/sns/oauth2/refresh_token?" +
|
|
148
|
+
params.toString(),
|
|
149
|
+
{
|
|
150
|
+
method: "GET",
|
|
151
|
+
},
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
if (error || !tokenData || tokenData.errcode) {
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Failed to refresh access token: ${tokenData?.errmsg || error?.message || "Unknown error"}`,
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
tokenType: "Bearer" as const,
|
|
162
|
+
accessToken: tokenData.access_token,
|
|
163
|
+
refreshToken: tokenData.refresh_token,
|
|
164
|
+
accessTokenExpiresAt: new Date(
|
|
165
|
+
Date.now() + tokenData.expires_in * 1000,
|
|
166
|
+
),
|
|
167
|
+
scopes: tokenData.scope.split(","),
|
|
168
|
+
};
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
async getUserInfo(token) {
|
|
172
|
+
if (options.getUserInfo) {
|
|
173
|
+
return options.getUserInfo(token);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const openid = (token as OAuth2Tokens & { openid?: string }).openid;
|
|
177
|
+
|
|
178
|
+
if (!openid) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const params = new URLSearchParams({
|
|
183
|
+
access_token: token.accessToken || "",
|
|
184
|
+
openid: openid,
|
|
185
|
+
lang: "zh_CN",
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const { data: profile, error } = await betterFetch<
|
|
189
|
+
WeChatProfile & { errcode?: number; errmsg?: string }
|
|
190
|
+
>("https://api.weixin.qq.com/sns/userinfo?" + params.toString(), {
|
|
191
|
+
method: "GET",
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
if (error || !profile || profile.errcode) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const userMap = await options.mapProfileToUser?.(profile);
|
|
199
|
+
return {
|
|
200
|
+
user: {
|
|
201
|
+
id: profile.unionid || profile.openid || openid,
|
|
202
|
+
name: profile.nickname,
|
|
203
|
+
email: profile.email || null,
|
|
204
|
+
image: profile.headimgurl,
|
|
205
|
+
emailVerified: false,
|
|
206
|
+
...userMap,
|
|
207
|
+
},
|
|
208
|
+
data: profile,
|
|
209
|
+
};
|
|
210
|
+
},
|
|
211
|
+
options,
|
|
212
|
+
} satisfies OAuthProvider<WeChatProfile, WeChatOptions>;
|
|
213
|
+
};
|