@better-auth/core 1.4.0-beta.8 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +41 -34
- package/dist/api/index.d.mts +3 -0
- package/dist/api/index.mjs +26 -0
- package/dist/async_hooks/index.d.mts +2 -10
- package/dist/async_hooks/index.mjs +2 -24
- package/dist/async_hooks-BfRfbd1J.mjs +18 -0
- package/dist/context/index.d.mts +54 -0
- package/dist/context/index.mjs +4 -0
- package/dist/context-DgQ9XGBl.mjs +114 -0
- package/dist/db/adapter/index.d.mts +3 -23
- package/dist/db/adapter/index.mjs +1 -1
- package/dist/db/index.d.mts +3 -127
- package/dist/db/index.mjs +46 -55
- package/dist/env/index.d.mts +2 -85
- package/dist/env/index.mjs +2 -299
- package/dist/env-DwlNAN_D.mjs +245 -0
- package/dist/error/index.d.mts +35 -0
- package/dist/error/index.mjs +4 -0
- package/dist/error-BhAKg8LX.mjs +45 -0
- package/dist/index-CdubV7uy.d.mts +82 -0
- package/dist/index-CkAWdKH8.d.mts +7352 -0
- package/dist/index-DgwIISs7.d.mts +7 -0
- package/dist/index.d.mts +3 -115
- package/dist/index.mjs +1 -1
- package/dist/oauth2/index.d.mts +3 -277
- package/dist/oauth2/index.mjs +2 -356
- package/dist/oauth2-DmgZmPEg.mjs +236 -0
- package/dist/social-providers/index.d.mts +3 -0
- package/dist/social-providers/index.mjs +2523 -0
- package/dist/utils/index.d.mts +9 -0
- package/dist/utils/index.mjs +3 -0
- package/dist/utils-C5EN75oV.mjs +7 -0
- package/package.json +90 -62
- package/src/api/index.ts +53 -0
- package/src/async_hooks/index.ts +1 -9
- package/src/context/endpoint-context.ts +49 -0
- package/src/context/index.ts +21 -0
- package/src/context/request-state.test.ts +94 -0
- package/src/context/request-state.ts +90 -0
- package/src/context/transaction.ts +73 -0
- package/src/db/adapter/index.ts +518 -8
- package/src/db/index.ts +12 -11
- package/src/db/plugin.ts +3 -3
- package/src/db/type.ts +55 -52
- package/src/env/color-depth.ts +5 -4
- package/src/env/env-impl.ts +2 -1
- package/src/env/index.ts +9 -9
- package/src/env/logger.test.ts +3 -2
- package/src/env/logger.ts +11 -9
- package/src/error/codes.ts +31 -0
- package/src/error/index.ts +11 -0
- package/src/index.ts +0 -2
- package/src/oauth2/client-credentials-token.ts +9 -9
- package/src/oauth2/create-authorization-url.ts +12 -12
- package/src/oauth2/index.ts +10 -11
- package/src/oauth2/oauth-provider.ts +96 -74
- package/src/oauth2/refresh-access-token.ts +12 -12
- package/src/oauth2/utils.ts +2 -0
- package/src/oauth2/validate-authorization-code.ts +13 -15
- package/src/social-providers/apple.ts +213 -0
- package/src/social-providers/atlassian.ts +132 -0
- package/src/social-providers/cognito.ts +269 -0
- package/src/social-providers/discord.ts +169 -0
- package/src/social-providers/dropbox.ts +112 -0
- package/src/social-providers/facebook.ts +206 -0
- package/src/social-providers/figma.ts +115 -0
- package/src/social-providers/github.ts +154 -0
- package/src/social-providers/gitlab.ts +155 -0
- package/src/social-providers/google.ts +171 -0
- package/src/social-providers/huggingface.ts +118 -0
- package/src/social-providers/index.ts +124 -0
- package/src/social-providers/kakao.ts +178 -0
- package/src/social-providers/kick.ts +93 -0
- package/src/social-providers/line.ts +169 -0
- package/src/social-providers/linear.ts +121 -0
- package/src/social-providers/linkedin.ts +110 -0
- package/src/social-providers/microsoft-entra-id.ts +259 -0
- package/src/social-providers/naver.ts +112 -0
- package/src/social-providers/notion.ts +108 -0
- package/src/social-providers/paybin.ts +122 -0
- package/src/social-providers/paypal.ts +263 -0
- package/src/social-providers/polar.ts +110 -0
- package/src/social-providers/reddit.ts +122 -0
- package/src/social-providers/roblox.ts +111 -0
- package/src/social-providers/salesforce.ts +159 -0
- package/src/social-providers/slack.ts +111 -0
- package/src/social-providers/spotify.ts +93 -0
- package/src/social-providers/tiktok.ts +210 -0
- package/src/social-providers/twitch.ts +111 -0
- package/src/social-providers/twitter.ts +198 -0
- package/src/social-providers/vk.ts +125 -0
- package/src/social-providers/zoom.ts +233 -0
- package/src/types/context.ts +270 -0
- package/src/types/cookie.ts +8 -0
- package/src/types/index.ts +21 -1
- package/src/types/init-options.ts +1328 -68
- package/src/types/plugin-client.ts +117 -0
- package/src/types/plugin.ts +158 -0
- package/src/utils/error-codes.ts +51 -0
- package/src/utils/index.ts +1 -0
- package/tsconfig.json +2 -5
- package/tsdown.config.ts +20 -0
- package/vitest.config.ts +3 -0
- package/build.config.ts +0 -19
- package/dist/async_hooks/index.cjs +0 -27
- package/dist/async_hooks/index.d.cts +0 -10
- package/dist/async_hooks/index.d.ts +0 -10
- package/dist/db/adapter/index.cjs +0 -2
- package/dist/db/adapter/index.d.cts +0 -23
- package/dist/db/adapter/index.d.ts +0 -23
- package/dist/db/index.cjs +0 -91
- package/dist/db/index.d.cts +0 -127
- package/dist/db/index.d.ts +0 -127
- package/dist/env/index.cjs +0 -315
- package/dist/env/index.d.cts +0 -85
- package/dist/env/index.d.ts +0 -85
- package/dist/index.cjs +0 -2
- package/dist/index.d.cts +0 -115
- package/dist/index.d.ts +0 -115
- package/dist/oauth2/index.cjs +0 -368
- package/dist/oauth2/index.d.cts +0 -277
- package/dist/oauth2/index.d.ts +0 -277
- package/dist/shared/core.DeNN5HMO.d.cts +0 -143
- package/dist/shared/core.DeNN5HMO.d.mts +0 -143
- package/dist/shared/core.DeNN5HMO.d.ts +0 -143
package/dist/oauth2/index.mjs
CHANGED
|
@@ -1,357 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { betterFetch } from '@better-fetch/fetch';
|
|
3
|
-
import { jwtVerify } from 'jose';
|
|
1
|
+
import { a as refreshAccessToken, c as getOAuth2Tokens, i as createRefreshAccessTokenRequest, l as clientCredentialsToken, n as validateAuthorizationCode, o as createAuthorizationURL, r as validateToken, s as generateCodeChallenge, t as createAuthorizationCodeRequest, u as createClientCredentialsTokenRequest } from "../oauth2-DmgZmPEg.mjs";
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
const getDate = (seconds) => {
|
|
7
|
-
const now = /* @__PURE__ */ new Date();
|
|
8
|
-
return new Date(now.getTime() + seconds * 1e3);
|
|
9
|
-
};
|
|
10
|
-
return {
|
|
11
|
-
tokenType: data.token_type,
|
|
12
|
-
accessToken: data.access_token,
|
|
13
|
-
refreshToken: data.refresh_token,
|
|
14
|
-
accessTokenExpiresAt: data.expires_in ? getDate(data.expires_in) : void 0,
|
|
15
|
-
refreshTokenExpiresAt: data.refresh_token_expires_in ? getDate(data.refresh_token_expires_in) : void 0,
|
|
16
|
-
scopes: data?.scope ? typeof data.scope === "string" ? data.scope.split(" ") : data.scope : [],
|
|
17
|
-
idToken: data.id_token
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
async function generateCodeChallenge(codeVerifier) {
|
|
21
|
-
const encoder = new TextEncoder();
|
|
22
|
-
const data = encoder.encode(codeVerifier);
|
|
23
|
-
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
24
|
-
return base64Url.encode(new Uint8Array(hash), {
|
|
25
|
-
padding: false
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async function createAuthorizationURL({
|
|
30
|
-
id,
|
|
31
|
-
options,
|
|
32
|
-
authorizationEndpoint,
|
|
33
|
-
state,
|
|
34
|
-
codeVerifier,
|
|
35
|
-
scopes,
|
|
36
|
-
claims,
|
|
37
|
-
redirectURI,
|
|
38
|
-
duration,
|
|
39
|
-
prompt,
|
|
40
|
-
accessType,
|
|
41
|
-
responseType,
|
|
42
|
-
display,
|
|
43
|
-
loginHint,
|
|
44
|
-
hd,
|
|
45
|
-
responseMode,
|
|
46
|
-
additionalParams,
|
|
47
|
-
scopeJoiner
|
|
48
|
-
}) {
|
|
49
|
-
const url = new URL(authorizationEndpoint);
|
|
50
|
-
url.searchParams.set("response_type", responseType || "code");
|
|
51
|
-
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
52
|
-
url.searchParams.set("client_id", primaryClientId);
|
|
53
|
-
url.searchParams.set("state", state);
|
|
54
|
-
url.searchParams.set("scope", scopes.join(scopeJoiner || " "));
|
|
55
|
-
url.searchParams.set("redirect_uri", options.redirectURI || redirectURI);
|
|
56
|
-
duration && url.searchParams.set("duration", duration);
|
|
57
|
-
display && url.searchParams.set("display", display);
|
|
58
|
-
loginHint && url.searchParams.set("login_hint", loginHint);
|
|
59
|
-
prompt && url.searchParams.set("prompt", prompt);
|
|
60
|
-
hd && url.searchParams.set("hd", hd);
|
|
61
|
-
accessType && url.searchParams.set("access_type", accessType);
|
|
62
|
-
responseMode && url.searchParams.set("response_mode", responseMode);
|
|
63
|
-
if (codeVerifier) {
|
|
64
|
-
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
65
|
-
url.searchParams.set("code_challenge_method", "S256");
|
|
66
|
-
url.searchParams.set("code_challenge", codeChallenge);
|
|
67
|
-
}
|
|
68
|
-
if (claims) {
|
|
69
|
-
const claimsObj = claims.reduce(
|
|
70
|
-
(acc, claim) => {
|
|
71
|
-
acc[claim] = null;
|
|
72
|
-
return acc;
|
|
73
|
-
},
|
|
74
|
-
{}
|
|
75
|
-
);
|
|
76
|
-
url.searchParams.set(
|
|
77
|
-
"claims",
|
|
78
|
-
JSON.stringify({
|
|
79
|
-
id_token: { email: null, email_verified: null, ...claimsObj }
|
|
80
|
-
})
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
if (additionalParams) {
|
|
84
|
-
Object.entries(additionalParams).forEach(([key, value]) => {
|
|
85
|
-
url.searchParams.set(key, value);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
return url;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function createAuthorizationCodeRequest({
|
|
92
|
-
code,
|
|
93
|
-
codeVerifier,
|
|
94
|
-
redirectURI,
|
|
95
|
-
options,
|
|
96
|
-
authentication,
|
|
97
|
-
deviceId,
|
|
98
|
-
headers,
|
|
99
|
-
additionalParams = {},
|
|
100
|
-
resource
|
|
101
|
-
}) {
|
|
102
|
-
const body = new URLSearchParams();
|
|
103
|
-
const requestHeaders = {
|
|
104
|
-
"content-type": "application/x-www-form-urlencoded",
|
|
105
|
-
accept: "application/json",
|
|
106
|
-
"user-agent": "better-auth",
|
|
107
|
-
...headers
|
|
108
|
-
};
|
|
109
|
-
body.set("grant_type", "authorization_code");
|
|
110
|
-
body.set("code", code);
|
|
111
|
-
codeVerifier && body.set("code_verifier", codeVerifier);
|
|
112
|
-
options.clientKey && body.set("client_key", options.clientKey);
|
|
113
|
-
deviceId && body.set("device_id", deviceId);
|
|
114
|
-
body.set("redirect_uri", options.redirectURI || redirectURI);
|
|
115
|
-
if (resource) {
|
|
116
|
-
if (typeof resource === "string") {
|
|
117
|
-
body.append("resource", resource);
|
|
118
|
-
} else {
|
|
119
|
-
for (const _resource of resource) {
|
|
120
|
-
body.append("resource", _resource);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (authentication === "basic") {
|
|
125
|
-
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
126
|
-
const encodedCredentials = base64.encode(
|
|
127
|
-
`${primaryClientId}:${options.clientSecret ?? ""}`
|
|
128
|
-
);
|
|
129
|
-
requestHeaders["authorization"] = `Basic ${encodedCredentials}`;
|
|
130
|
-
} else {
|
|
131
|
-
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
132
|
-
body.set("client_id", primaryClientId);
|
|
133
|
-
if (options.clientSecret) {
|
|
134
|
-
body.set("client_secret", options.clientSecret);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
for (const [key, value] of Object.entries(additionalParams)) {
|
|
138
|
-
if (!body.has(key)) body.append(key, value);
|
|
139
|
-
}
|
|
140
|
-
return {
|
|
141
|
-
body,
|
|
142
|
-
headers: requestHeaders
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
async function validateAuthorizationCode({
|
|
146
|
-
code,
|
|
147
|
-
codeVerifier,
|
|
148
|
-
redirectURI,
|
|
149
|
-
options,
|
|
150
|
-
tokenEndpoint,
|
|
151
|
-
authentication,
|
|
152
|
-
deviceId,
|
|
153
|
-
headers,
|
|
154
|
-
additionalParams = {},
|
|
155
|
-
resource
|
|
156
|
-
}) {
|
|
157
|
-
const { body, headers: requestHeaders } = createAuthorizationCodeRequest({
|
|
158
|
-
code,
|
|
159
|
-
codeVerifier,
|
|
160
|
-
redirectURI,
|
|
161
|
-
options,
|
|
162
|
-
authentication,
|
|
163
|
-
deviceId,
|
|
164
|
-
headers,
|
|
165
|
-
additionalParams,
|
|
166
|
-
resource
|
|
167
|
-
});
|
|
168
|
-
const { data, error } = await betterFetch(tokenEndpoint, {
|
|
169
|
-
method: "POST",
|
|
170
|
-
body,
|
|
171
|
-
headers: requestHeaders
|
|
172
|
-
});
|
|
173
|
-
if (error) {
|
|
174
|
-
throw error;
|
|
175
|
-
}
|
|
176
|
-
const tokens = getOAuth2Tokens(data);
|
|
177
|
-
return tokens;
|
|
178
|
-
}
|
|
179
|
-
async function validateToken(token, jwksEndpoint) {
|
|
180
|
-
const { data, error } = await betterFetch(jwksEndpoint, {
|
|
181
|
-
method: "GET",
|
|
182
|
-
headers: {
|
|
183
|
-
accept: "application/json",
|
|
184
|
-
"user-agent": "better-auth"
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
if (error) {
|
|
188
|
-
throw error;
|
|
189
|
-
}
|
|
190
|
-
const keys = data["keys"];
|
|
191
|
-
const header = JSON.parse(atob(token.split(".")[0]));
|
|
192
|
-
const key = keys.find((key2) => key2.kid === header.kid);
|
|
193
|
-
if (!key) {
|
|
194
|
-
throw new Error("Key not found");
|
|
195
|
-
}
|
|
196
|
-
const verified = await jwtVerify(token, key);
|
|
197
|
-
return verified;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function createRefreshAccessTokenRequest({
|
|
201
|
-
refreshToken,
|
|
202
|
-
options,
|
|
203
|
-
authentication,
|
|
204
|
-
extraParams,
|
|
205
|
-
resource
|
|
206
|
-
}) {
|
|
207
|
-
const body = new URLSearchParams();
|
|
208
|
-
const headers = {
|
|
209
|
-
"content-type": "application/x-www-form-urlencoded",
|
|
210
|
-
accept: "application/json"
|
|
211
|
-
};
|
|
212
|
-
body.set("grant_type", "refresh_token");
|
|
213
|
-
body.set("refresh_token", refreshToken);
|
|
214
|
-
if (authentication === "basic") {
|
|
215
|
-
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
216
|
-
if (primaryClientId) {
|
|
217
|
-
headers["authorization"] = "Basic " + base64.encode(`${primaryClientId}:${options.clientSecret ?? ""}`);
|
|
218
|
-
} else {
|
|
219
|
-
headers["authorization"] = "Basic " + base64.encode(`:${options.clientSecret ?? ""}`);
|
|
220
|
-
}
|
|
221
|
-
} else {
|
|
222
|
-
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
223
|
-
body.set("client_id", primaryClientId);
|
|
224
|
-
if (options.clientSecret) {
|
|
225
|
-
body.set("client_secret", options.clientSecret);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
if (resource) {
|
|
229
|
-
if (typeof resource === "string") {
|
|
230
|
-
body.append("resource", resource);
|
|
231
|
-
} else {
|
|
232
|
-
for (const _resource of resource) {
|
|
233
|
-
body.append("resource", _resource);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
if (extraParams) {
|
|
238
|
-
for (const [key, value] of Object.entries(extraParams)) {
|
|
239
|
-
body.set(key, value);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return {
|
|
243
|
-
body,
|
|
244
|
-
headers
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
async function refreshAccessToken({
|
|
248
|
-
refreshToken,
|
|
249
|
-
options,
|
|
250
|
-
tokenEndpoint,
|
|
251
|
-
authentication,
|
|
252
|
-
extraParams
|
|
253
|
-
}) {
|
|
254
|
-
const { body, headers } = createRefreshAccessTokenRequest({
|
|
255
|
-
refreshToken,
|
|
256
|
-
options,
|
|
257
|
-
authentication,
|
|
258
|
-
extraParams
|
|
259
|
-
});
|
|
260
|
-
const { data, error } = await betterFetch(tokenEndpoint, {
|
|
261
|
-
method: "POST",
|
|
262
|
-
body,
|
|
263
|
-
headers
|
|
264
|
-
});
|
|
265
|
-
if (error) {
|
|
266
|
-
throw error;
|
|
267
|
-
}
|
|
268
|
-
const tokens = {
|
|
269
|
-
accessToken: data.access_token,
|
|
270
|
-
refreshToken: data.refresh_token,
|
|
271
|
-
tokenType: data.token_type,
|
|
272
|
-
scopes: data.scope?.split(" "),
|
|
273
|
-
idToken: data.id_token
|
|
274
|
-
};
|
|
275
|
-
if (data.expires_in) {
|
|
276
|
-
const now = /* @__PURE__ */ new Date();
|
|
277
|
-
tokens.accessTokenExpiresAt = new Date(
|
|
278
|
-
now.getTime() + data.expires_in * 1e3
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
return tokens;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
function createClientCredentialsTokenRequest({
|
|
285
|
-
options,
|
|
286
|
-
scope,
|
|
287
|
-
authentication,
|
|
288
|
-
resource
|
|
289
|
-
}) {
|
|
290
|
-
const body = new URLSearchParams();
|
|
291
|
-
const headers = {
|
|
292
|
-
"content-type": "application/x-www-form-urlencoded",
|
|
293
|
-
accept: "application/json"
|
|
294
|
-
};
|
|
295
|
-
body.set("grant_type", "client_credentials");
|
|
296
|
-
scope && body.set("scope", scope);
|
|
297
|
-
if (resource) {
|
|
298
|
-
if (typeof resource === "string") {
|
|
299
|
-
body.append("resource", resource);
|
|
300
|
-
} else {
|
|
301
|
-
for (const _resource of resource) {
|
|
302
|
-
body.append("resource", _resource);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
if (authentication === "basic") {
|
|
307
|
-
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
308
|
-
const encodedCredentials = base64Url.encode(
|
|
309
|
-
`${primaryClientId}:${options.clientSecret}`
|
|
310
|
-
);
|
|
311
|
-
headers["authorization"] = `Basic ${encodedCredentials}`;
|
|
312
|
-
} else {
|
|
313
|
-
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
314
|
-
body.set("client_id", primaryClientId);
|
|
315
|
-
body.set("client_secret", options.clientSecret);
|
|
316
|
-
}
|
|
317
|
-
return {
|
|
318
|
-
body,
|
|
319
|
-
headers
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
async function clientCredentialsToken({
|
|
323
|
-
options,
|
|
324
|
-
tokenEndpoint,
|
|
325
|
-
scope,
|
|
326
|
-
authentication,
|
|
327
|
-
resource
|
|
328
|
-
}) {
|
|
329
|
-
const { body, headers } = createClientCredentialsTokenRequest({
|
|
330
|
-
options,
|
|
331
|
-
scope,
|
|
332
|
-
authentication,
|
|
333
|
-
resource
|
|
334
|
-
});
|
|
335
|
-
const { data, error } = await betterFetch(tokenEndpoint, {
|
|
336
|
-
method: "POST",
|
|
337
|
-
body,
|
|
338
|
-
headers
|
|
339
|
-
});
|
|
340
|
-
if (error) {
|
|
341
|
-
throw error;
|
|
342
|
-
}
|
|
343
|
-
const tokens = {
|
|
344
|
-
accessToken: data.access_token,
|
|
345
|
-
tokenType: data.token_type,
|
|
346
|
-
scopes: data.scope?.split(" ")
|
|
347
|
-
};
|
|
348
|
-
if (data.expires_in) {
|
|
349
|
-
const now = /* @__PURE__ */ new Date();
|
|
350
|
-
tokens.accessTokenExpiresAt = new Date(
|
|
351
|
-
now.getTime() + data.expires_in * 1e3
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
return tokens;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
export { clientCredentialsToken, createAuthorizationCodeRequest, createAuthorizationURL, createClientCredentialsTokenRequest, createRefreshAccessTokenRequest, generateCodeChallenge, getOAuth2Tokens, refreshAccessToken, validateAuthorizationCode, validateToken };
|
|
3
|
+
export { clientCredentialsToken, createAuthorizationCodeRequest, createAuthorizationURL, createClientCredentialsTokenRequest, createRefreshAccessTokenRequest, generateCodeChallenge, getOAuth2Tokens, refreshAccessToken, validateAuthorizationCode, validateToken };
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { base64, base64Url } from "@better-auth/utils/base64";
|
|
2
|
+
import { betterFetch } from "@better-fetch/fetch";
|
|
3
|
+
import { jwtVerify } from "jose";
|
|
4
|
+
|
|
5
|
+
//#region src/oauth2/client-credentials-token.ts
|
|
6
|
+
function createClientCredentialsTokenRequest({ options, scope, authentication, resource }) {
|
|
7
|
+
const body = new URLSearchParams();
|
|
8
|
+
const headers = {
|
|
9
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
10
|
+
accept: "application/json"
|
|
11
|
+
};
|
|
12
|
+
body.set("grant_type", "client_credentials");
|
|
13
|
+
scope && body.set("scope", scope);
|
|
14
|
+
if (resource) if (typeof resource === "string") body.append("resource", resource);
|
|
15
|
+
else for (const _resource of resource) body.append("resource", _resource);
|
|
16
|
+
if (authentication === "basic") {
|
|
17
|
+
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
18
|
+
headers["authorization"] = `Basic ${base64Url.encode(`${primaryClientId}:${options.clientSecret}`)}`;
|
|
19
|
+
} else {
|
|
20
|
+
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
21
|
+
body.set("client_id", primaryClientId);
|
|
22
|
+
body.set("client_secret", options.clientSecret);
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
body,
|
|
26
|
+
headers
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async function clientCredentialsToken({ options, tokenEndpoint, scope, authentication, resource }) {
|
|
30
|
+
const { body, headers } = createClientCredentialsTokenRequest({
|
|
31
|
+
options,
|
|
32
|
+
scope,
|
|
33
|
+
authentication,
|
|
34
|
+
resource
|
|
35
|
+
});
|
|
36
|
+
const { data, error } = await betterFetch(tokenEndpoint, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
body,
|
|
39
|
+
headers
|
|
40
|
+
});
|
|
41
|
+
if (error) throw error;
|
|
42
|
+
const tokens = {
|
|
43
|
+
accessToken: data.access_token,
|
|
44
|
+
tokenType: data.token_type,
|
|
45
|
+
scopes: data.scope?.split(" ")
|
|
46
|
+
};
|
|
47
|
+
if (data.expires_in) {
|
|
48
|
+
const now = /* @__PURE__ */ new Date();
|
|
49
|
+
tokens.accessTokenExpiresAt = new Date(now.getTime() + data.expires_in * 1e3);
|
|
50
|
+
}
|
|
51
|
+
return tokens;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/oauth2/utils.ts
|
|
56
|
+
function getOAuth2Tokens(data) {
|
|
57
|
+
const getDate = (seconds) => {
|
|
58
|
+
const now = /* @__PURE__ */ new Date();
|
|
59
|
+
return new Date(now.getTime() + seconds * 1e3);
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
tokenType: data.token_type,
|
|
63
|
+
accessToken: data.access_token,
|
|
64
|
+
refreshToken: data.refresh_token,
|
|
65
|
+
accessTokenExpiresAt: data.expires_in ? getDate(data.expires_in) : void 0,
|
|
66
|
+
refreshTokenExpiresAt: data.refresh_token_expires_in ? getDate(data.refresh_token_expires_in) : void 0,
|
|
67
|
+
scopes: data?.scope ? typeof data.scope === "string" ? data.scope.split(" ") : data.scope : [],
|
|
68
|
+
idToken: data.id_token,
|
|
69
|
+
raw: data
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async function generateCodeChallenge(codeVerifier) {
|
|
73
|
+
const data = new TextEncoder().encode(codeVerifier);
|
|
74
|
+
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
75
|
+
return base64Url.encode(new Uint8Array(hash), { padding: false });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/oauth2/create-authorization-url.ts
|
|
80
|
+
async function createAuthorizationURL({ id, options, authorizationEndpoint, state, codeVerifier, scopes, claims, redirectURI, duration, prompt, accessType, responseType, display, loginHint, hd, responseMode, additionalParams, scopeJoiner }) {
|
|
81
|
+
const url = new URL(authorizationEndpoint);
|
|
82
|
+
url.searchParams.set("response_type", responseType || "code");
|
|
83
|
+
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
84
|
+
url.searchParams.set("client_id", primaryClientId);
|
|
85
|
+
url.searchParams.set("state", state);
|
|
86
|
+
url.searchParams.set("scope", scopes.join(scopeJoiner || " "));
|
|
87
|
+
url.searchParams.set("redirect_uri", options.redirectURI || redirectURI);
|
|
88
|
+
duration && url.searchParams.set("duration", duration);
|
|
89
|
+
display && url.searchParams.set("display", display);
|
|
90
|
+
loginHint && url.searchParams.set("login_hint", loginHint);
|
|
91
|
+
prompt && url.searchParams.set("prompt", prompt);
|
|
92
|
+
hd && url.searchParams.set("hd", hd);
|
|
93
|
+
accessType && url.searchParams.set("access_type", accessType);
|
|
94
|
+
responseMode && url.searchParams.set("response_mode", responseMode);
|
|
95
|
+
if (codeVerifier) {
|
|
96
|
+
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
97
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
98
|
+
url.searchParams.set("code_challenge", codeChallenge);
|
|
99
|
+
}
|
|
100
|
+
if (claims) {
|
|
101
|
+
const claimsObj = claims.reduce((acc, claim) => {
|
|
102
|
+
acc[claim] = null;
|
|
103
|
+
return acc;
|
|
104
|
+
}, {});
|
|
105
|
+
url.searchParams.set("claims", JSON.stringify({ id_token: {
|
|
106
|
+
email: null,
|
|
107
|
+
email_verified: null,
|
|
108
|
+
...claimsObj
|
|
109
|
+
} }));
|
|
110
|
+
}
|
|
111
|
+
if (additionalParams) Object.entries(additionalParams).forEach(([key, value]) => {
|
|
112
|
+
url.searchParams.set(key, value);
|
|
113
|
+
});
|
|
114
|
+
return url;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/oauth2/refresh-access-token.ts
|
|
119
|
+
function createRefreshAccessTokenRequest({ refreshToken, options, authentication, extraParams, resource }) {
|
|
120
|
+
const body = new URLSearchParams();
|
|
121
|
+
const headers = {
|
|
122
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
123
|
+
accept: "application/json"
|
|
124
|
+
};
|
|
125
|
+
body.set("grant_type", "refresh_token");
|
|
126
|
+
body.set("refresh_token", refreshToken);
|
|
127
|
+
if (authentication === "basic") {
|
|
128
|
+
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
129
|
+
if (primaryClientId) headers["authorization"] = "Basic " + base64.encode(`${primaryClientId}:${options.clientSecret ?? ""}`);
|
|
130
|
+
else headers["authorization"] = "Basic " + base64.encode(`:${options.clientSecret ?? ""}`);
|
|
131
|
+
} else {
|
|
132
|
+
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
133
|
+
body.set("client_id", primaryClientId);
|
|
134
|
+
if (options.clientSecret) body.set("client_secret", options.clientSecret);
|
|
135
|
+
}
|
|
136
|
+
if (resource) if (typeof resource === "string") body.append("resource", resource);
|
|
137
|
+
else for (const _resource of resource) body.append("resource", _resource);
|
|
138
|
+
if (extraParams) for (const [key, value] of Object.entries(extraParams)) body.set(key, value);
|
|
139
|
+
return {
|
|
140
|
+
body,
|
|
141
|
+
headers
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
async function refreshAccessToken({ refreshToken, options, tokenEndpoint, authentication, extraParams }) {
|
|
145
|
+
const { body, headers } = createRefreshAccessTokenRequest({
|
|
146
|
+
refreshToken,
|
|
147
|
+
options,
|
|
148
|
+
authentication,
|
|
149
|
+
extraParams
|
|
150
|
+
});
|
|
151
|
+
const { data, error } = await betterFetch(tokenEndpoint, {
|
|
152
|
+
method: "POST",
|
|
153
|
+
body,
|
|
154
|
+
headers
|
|
155
|
+
});
|
|
156
|
+
if (error) throw error;
|
|
157
|
+
const tokens = {
|
|
158
|
+
accessToken: data.access_token,
|
|
159
|
+
refreshToken: data.refresh_token,
|
|
160
|
+
tokenType: data.token_type,
|
|
161
|
+
scopes: data.scope?.split(" "),
|
|
162
|
+
idToken: data.id_token
|
|
163
|
+
};
|
|
164
|
+
if (data.expires_in) {
|
|
165
|
+
const now = /* @__PURE__ */ new Date();
|
|
166
|
+
tokens.accessTokenExpiresAt = new Date(now.getTime() + data.expires_in * 1e3);
|
|
167
|
+
}
|
|
168
|
+
return tokens;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//#endregion
|
|
172
|
+
//#region src/oauth2/validate-authorization-code.ts
|
|
173
|
+
function createAuthorizationCodeRequest({ code, codeVerifier, redirectURI, options, authentication, deviceId, headers, additionalParams = {}, resource }) {
|
|
174
|
+
const body = new URLSearchParams();
|
|
175
|
+
const requestHeaders = {
|
|
176
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
177
|
+
accept: "application/json",
|
|
178
|
+
...headers
|
|
179
|
+
};
|
|
180
|
+
body.set("grant_type", "authorization_code");
|
|
181
|
+
body.set("code", code);
|
|
182
|
+
codeVerifier && body.set("code_verifier", codeVerifier);
|
|
183
|
+
options.clientKey && body.set("client_key", options.clientKey);
|
|
184
|
+
deviceId && body.set("device_id", deviceId);
|
|
185
|
+
body.set("redirect_uri", options.redirectURI || redirectURI);
|
|
186
|
+
if (resource) if (typeof resource === "string") body.append("resource", resource);
|
|
187
|
+
else for (const _resource of resource) body.append("resource", _resource);
|
|
188
|
+
if (authentication === "basic") {
|
|
189
|
+
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
190
|
+
requestHeaders["authorization"] = `Basic ${base64.encode(`${primaryClientId}:${options.clientSecret ?? ""}`)}`;
|
|
191
|
+
} else {
|
|
192
|
+
const primaryClientId = Array.isArray(options.clientId) ? options.clientId[0] : options.clientId;
|
|
193
|
+
body.set("client_id", primaryClientId);
|
|
194
|
+
if (options.clientSecret) body.set("client_secret", options.clientSecret);
|
|
195
|
+
}
|
|
196
|
+
for (const [key, value] of Object.entries(additionalParams)) if (!body.has(key)) body.append(key, value);
|
|
197
|
+
return {
|
|
198
|
+
body,
|
|
199
|
+
headers: requestHeaders
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
async function validateAuthorizationCode({ code, codeVerifier, redirectURI, options, tokenEndpoint, authentication, deviceId, headers, additionalParams = {}, resource }) {
|
|
203
|
+
const { body, headers: requestHeaders } = createAuthorizationCodeRequest({
|
|
204
|
+
code,
|
|
205
|
+
codeVerifier,
|
|
206
|
+
redirectURI,
|
|
207
|
+
options,
|
|
208
|
+
authentication,
|
|
209
|
+
deviceId,
|
|
210
|
+
headers,
|
|
211
|
+
additionalParams,
|
|
212
|
+
resource
|
|
213
|
+
});
|
|
214
|
+
const { data, error } = await betterFetch(tokenEndpoint, {
|
|
215
|
+
method: "POST",
|
|
216
|
+
body,
|
|
217
|
+
headers: requestHeaders
|
|
218
|
+
});
|
|
219
|
+
if (error) throw error;
|
|
220
|
+
return getOAuth2Tokens(data);
|
|
221
|
+
}
|
|
222
|
+
async function validateToken(token, jwksEndpoint) {
|
|
223
|
+
const { data, error } = await betterFetch(jwksEndpoint, {
|
|
224
|
+
method: "GET",
|
|
225
|
+
headers: { accept: "application/json" }
|
|
226
|
+
});
|
|
227
|
+
if (error) throw error;
|
|
228
|
+
const keys = data["keys"];
|
|
229
|
+
const header = JSON.parse(atob(token.split(".")[0]));
|
|
230
|
+
const key = keys.find((key$1) => key$1.kid === header.kid);
|
|
231
|
+
if (!key) throw new Error("Key not found");
|
|
232
|
+
return await jwtVerify(token, key);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
//#endregion
|
|
236
|
+
export { refreshAccessToken as a, getOAuth2Tokens as c, createRefreshAccessTokenRequest as i, clientCredentialsToken as l, validateAuthorizationCode as n, createAuthorizationURL as o, validateToken as r, generateCodeChallenge as s, createAuthorizationCodeRequest as t, createClientCredentialsTokenRequest as u };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { $ as PronounOption, $t as MicrosoftOptions, A as PayPalOptions, At as kick, B as line, Bt as SpotifyOptions, C as SocialProviderListEnum, Cn as apple, Ct as linkedin, D as PolarOptions, Dt as linear, E as socialProviders, Et as LinearUser, F as PaybinProfile, Ft as TwitterProfile, G as KakaoProfile, Gt as slack, H as NaverProfile, Ht as spotify, I as paybin, It as twitter, J as NotionProfile, Jt as huggingface, K as kakao, Kt as HuggingFaceOptions, L as LineIdTokenPayload, Lt as TwitchOptions, M as PayPalTokenResponse, Mt as DropboxProfile, N as paypal, Nt as dropbox, O as PolarProfile, Ot as KickOptions, P as PaybinOptions, Pt as TwitterOption, Q as PhoneNumber, Qt as MicrosoftEntraIDProfile, R as LineOptions, Rt as TwitchProfile, S as SocialProviderList, Sn as AppleProfile, St as LinkedInProfile, T as socialProviderList, Tt as LinearProfile, U as naver, Ut as SlackOptions, V as NaverOptions, Vt as SpotifyProfile, W as KakaoOptions, Wt as SlackProfile, X as AccountStatus, Xt as GoogleProfile, Y as notion, Yt as GoogleOptions, Z as LoginType, Zt as google, _n as AtlassianOptions, _t as tiktok, an as FigmaProfile, at as vk, bn as AppleNonConformUser, bt as gitlab, cn as FacebookProfile, ct as salesforce, dn as DiscordProfile, dt as roblox, en as microsoft, et as ZoomOptions, fn as discord, ft as RedditOptions, gn as getCognitoPublicKey, gt as TiktokProfile, hn as cognito, ht as TiktokOptions, in as FigmaOptions, it as VkProfile, j as PayPalProfile, jt as DropboxOptions, k as polar, kt as KickProfile, ln as facebook, lt as RobloxOptions, mn as CognitoProfile, mt as reddit, nn as GithubProfile, nt as zoom, on as figma, ot as SalesforceOptions, pn as CognitoOptions, pt as RedditProfile, q as NotionOptions, qt as HuggingFaceProfile, rn as github, rt as VkOption, sn as FacebookOptions, st as SalesforceProfile, tn as GithubOptions, tt as ZoomProfile, un as DiscordOptions, ut as RobloxProfile, vn as AtlassianProfile, vt as GitlabOptions, w as SocialProviders, wn as getApplePublicKey, wt as LinearOptions, x as SocialProvider, xn as AppleOptions, xt as LinkedInOptions, yn as atlassian, yt as GitlabProfile, z as LineUserInfo, zt as twitch } from "../index-CkAWdKH8.mjs";
|
|
2
|
+
import "../index-CdubV7uy.mjs";
|
|
3
|
+
export { AccountStatus, AppleNonConformUser, AppleOptions, AppleProfile, AtlassianOptions, AtlassianProfile, CognitoOptions, CognitoProfile, DiscordOptions, DiscordProfile, DropboxOptions, DropboxProfile, FacebookOptions, FacebookProfile, FigmaOptions, FigmaProfile, GithubOptions, GithubProfile, GitlabOptions, GitlabProfile, GoogleOptions, GoogleProfile, HuggingFaceOptions, HuggingFaceProfile, KakaoOptions, KakaoProfile, KickOptions, KickProfile, LineIdTokenPayload, LineOptions, LineUserInfo, LinearOptions, LinearProfile, LinearUser, LinkedInOptions, LinkedInProfile, LoginType, MicrosoftEntraIDProfile, MicrosoftOptions, NaverOptions, NaverProfile, NotionOptions, NotionProfile, PayPalOptions, PayPalProfile, PayPalTokenResponse, PaybinOptions, PaybinProfile, PhoneNumber, PolarOptions, PolarProfile, PronounOption, RedditOptions, RedditProfile, RobloxOptions, RobloxProfile, SalesforceOptions, SalesforceProfile, SlackOptions, SlackProfile, SocialProvider, SocialProviderList, SocialProviderListEnum, SocialProviders, SpotifyOptions, SpotifyProfile, TiktokOptions, TiktokProfile, TwitchOptions, TwitchProfile, TwitterOption, TwitterProfile, VkOption, VkProfile, ZoomOptions, ZoomProfile, apple, atlassian, cognito, discord, dropbox, facebook, figma, getApplePublicKey, getCognitoPublicKey, github, gitlab, google, huggingface, kakao, kick, line, linear, linkedin, microsoft, naver, notion, paybin, paypal, polar, reddit, roblox, salesforce, slack, socialProviderList, socialProviders, spotify, tiktok, twitch, twitter, vk, zoom };
|