better-auth 1.2.0-beta.1 → 1.2.0-beta.11

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.
Files changed (205) hide show
  1. package/dist/adapters/drizzle.cjs +12 -5
  2. package/dist/adapters/drizzle.d.cts +6 -2
  3. package/dist/adapters/drizzle.d.ts +6 -2
  4. package/dist/adapters/drizzle.js +11 -4
  5. package/dist/adapters/kysely.cjs +5 -5
  6. package/dist/adapters/kysely.d.cts +6 -2
  7. package/dist/adapters/kysely.d.ts +6 -2
  8. package/dist/adapters/kysely.js +3 -3
  9. package/dist/adapters/memory.cjs +4 -4
  10. package/dist/adapters/memory.d.cts +6 -2
  11. package/dist/adapters/memory.d.ts +6 -2
  12. package/dist/adapters/memory.js +3 -3
  13. package/dist/adapters/mongodb.cjs +26 -8
  14. package/dist/adapters/mongodb.d.cts +6 -2
  15. package/dist/adapters/mongodb.d.ts +6 -2
  16. package/dist/adapters/mongodb.js +24 -6
  17. package/dist/adapters/prisma.cjs +18 -5
  18. package/dist/adapters/prisma.d.cts +6 -2
  19. package/dist/adapters/prisma.d.ts +6 -2
  20. package/dist/adapters/prisma.js +16 -3
  21. package/dist/adapters/test.cjs +1 -1
  22. package/dist/adapters/test.d.cts +2 -2
  23. package/dist/adapters/test.d.ts +2 -2
  24. package/dist/adapters/test.js +1 -1
  25. package/dist/api.cjs +48 -44
  26. package/dist/api.d.cts +3 -3
  27. package/dist/api.d.ts +3 -3
  28. package/dist/api.js +5 -5
  29. package/dist/{auth-DcMc3BIq.d.ts → auth-C-uLTIcY.d.ts} +12002 -7646
  30. package/dist/{auth-D4rdpxtI.d.cts → auth-lDfjrjVd.d.cts} +12002 -7646
  31. package/dist/{chunk-MGJLVQOV.js → chunk-2OAHQPLI.js} +100 -38
  32. package/dist/{chunk-5E75URIA.cjs → chunk-2Z6CVQHH.cjs} +0 -4
  33. package/dist/{chunk-WVLPJXQR.cjs → chunk-3FWLBBDV.cjs} +109 -51
  34. package/dist/{chunk-WDOY7YUW.cjs → chunk-6P33VPUY.cjs} +106 -44
  35. package/dist/{chunk-ADGXBH3Y.js → chunk-6XMAWIGH.js} +29 -26
  36. package/dist/{chunk-G7HOSQ5N.cjs → chunk-75MYIQ34.cjs} +15 -18
  37. package/dist/{chunk-YW3B2ST3.js → chunk-BY25AMN4.js} +116 -5
  38. package/dist/{chunk-LZ5DEQVH.cjs → chunk-C4T7TNDG.cjs} +3 -3
  39. package/dist/{chunk-PJ4KWXLQ.cjs → chunk-DH5E7574.cjs} +8 -8
  40. package/dist/{chunk-5RY45WFV.js → chunk-DIIVSN3J.js} +36 -13
  41. package/dist/{chunk-OSBTXYDD.cjs → chunk-GQKBG2VQ.cjs} +125 -14
  42. package/dist/{chunk-BKFMDM3P.js → chunk-HRI7BYTU.js} +115 -16
  43. package/dist/{chunk-6O2GLU2U.cjs → chunk-ICONG5HP.cjs} +18 -13
  44. package/dist/{chunk-3EY3LSQR.js → chunk-IVS5VS3V.js} +75 -36
  45. package/dist/{chunk-YRUDZRY3.cjs → chunk-IYCSNEDU.cjs} +79 -56
  46. package/dist/{chunk-NU4SXYJ5.cjs → chunk-JDAHD767.cjs} +198 -42
  47. package/dist/{chunk-UP6VJQDB.js → chunk-JHLVXVME.js} +17 -10
  48. package/dist/{chunk-WLXFBYQ6.cjs → chunk-JU56U5MW.cjs} +79 -9
  49. package/dist/{chunk-QFYRLTM5.cjs → chunk-JYPC7ZAL.cjs} +52 -49
  50. package/dist/{chunk-UHGAA4GH.cjs → chunk-KNVDJ4WK.cjs} +5 -5
  51. package/dist/{chunk-CVDYU5OC.js → chunk-M6SPJGF4.js} +5 -8
  52. package/dist/{chunk-BAPXDO3E.cjs → chunk-MKNA7SED.cjs} +125 -26
  53. package/dist/{chunk-GTM45OYP.cjs → chunk-NQFRXDEY.cjs} +3 -3
  54. package/dist/{chunk-FXNG3YQA.js → chunk-NXQP77NI.js} +146 -79
  55. package/dist/{chunk-FA6UYV37.js → chunk-PR54V2QL.js} +29 -10
  56. package/dist/{chunk-JLATHUM5.cjs → chunk-QBYD37C7.cjs} +21 -14
  57. package/dist/{chunk-E6LJZ5ME.js → chunk-QFIG4XKQ.js} +1 -1
  58. package/dist/{chunk-764RYNTE.cjs → chunk-QS2XIJC4.cjs} +63 -29
  59. package/dist/{chunk-GTQM7JU7.js → chunk-R42K7GPF.js} +3 -1
  60. package/dist/{chunk-3BWJXTLC.cjs → chunk-RHWADEUT.cjs} +81 -58
  61. package/dist/{chunk-JNZYTS3B.js → chunk-RS2A52JD.js} +1 -1
  62. package/dist/{chunk-5OBRFII2.js → chunk-SIAKIOPW.js} +81 -23
  63. package/dist/{chunk-V6RGXSG4.cjs → chunk-SVC7H7K4.cjs} +3 -1
  64. package/dist/{chunk-EM73ZZSP.cjs → chunk-TID6AR5K.cjs} +49 -30
  65. package/dist/{chunk-VXDYNCOX.js → chunk-TODG5RSV.js} +172 -19
  66. package/dist/{chunk-VPCROEJW.cjs → chunk-TZ2VLKIG.cjs} +170 -103
  67. package/dist/{chunk-WGCTQNSQ.js → chunk-UHBMFLSF.js} +1 -1
  68. package/dist/{chunk-PIWBUHRB.cjs → chunk-UPQLFVFU.cjs} +83 -43
  69. package/dist/{chunk-B5UCLTPZ.cjs → chunk-UQC2FUXC.cjs} +2 -1
  70. package/dist/{chunk-RGG6OEA3.js → chunk-VUXQHI6K.js} +60 -26
  71. package/dist/{chunk-2LQ7T2GE.js → chunk-WUUDJ3TF.js} +3 -3
  72. package/dist/{chunk-HZBNUY7E.js → chunk-WZ6OIVJK.js} +2 -1
  73. package/dist/{chunk-5XAVWKUN.js → chunk-X4X6WCXH.js} +74 -4
  74. package/dist/{chunk-NPO64SVN.js → chunk-ZFUBVSZD.js} +0 -4
  75. package/dist/{chunk-S6MI7ZLE.js → chunk-ZKNBNGHR.js} +12 -7
  76. package/dist/{chunk-5KMF6HGF.js → chunk-ZUGWIOG4.js} +75 -52
  77. package/dist/client/plugins.cjs +215 -21
  78. package/dist/client/plugins.d.cts +176 -10
  79. package/dist/client/plugins.d.ts +176 -10
  80. package/dist/client/plugins.js +214 -14
  81. package/dist/client.d.cts +6 -7
  82. package/dist/client.d.ts +6 -7
  83. package/dist/cookies.d.cts +2 -2
  84. package/dist/cookies.d.ts +2 -2
  85. package/dist/db.cjs +29 -29
  86. package/dist/db.d.cts +6 -6
  87. package/dist/db.d.ts +6 -6
  88. package/dist/db.js +3 -3
  89. package/dist/index-BX_H-j6k.d.cts +7755 -0
  90. package/dist/{index-Ba5bMY6A.d.cts → index-BuRgaJZR.d.cts} +194 -2
  91. package/dist/index-D5zWKzf9.d.ts +7755 -0
  92. package/dist/{index-XrJz4AYF.d.ts → index-moQjyfmm.d.ts} +194 -2
  93. package/dist/index.cjs +19 -19
  94. package/dist/index.d.cts +3 -3
  95. package/dist/index.d.ts +3 -3
  96. package/dist/index.js +9 -9
  97. package/dist/next-js.cjs +24 -24
  98. package/dist/next-js.d.cts +2 -2
  99. package/dist/next-js.d.ts +2 -2
  100. package/dist/next-js.js +23 -23
  101. package/dist/node.d.cts +2 -2
  102. package/dist/node.d.ts +2 -2
  103. package/dist/oauth2.cjs +9 -9
  104. package/dist/oauth2.d.cts +6 -5
  105. package/dist/oauth2.d.ts +6 -5
  106. package/dist/oauth2.js +2 -2
  107. package/dist/plugins/admin.cjs +7 -7
  108. package/dist/plugins/admin.d.cts +163 -32
  109. package/dist/plugins/admin.d.ts +163 -32
  110. package/dist/plugins/admin.js +6 -6
  111. package/dist/plugins/anonymous.cjs +7 -7
  112. package/dist/plugins/anonymous.d.cts +8 -4
  113. package/dist/plugins/anonymous.d.ts +8 -4
  114. package/dist/plugins/anonymous.js +6 -6
  115. package/dist/plugins/bearer.cjs +7 -7
  116. package/dist/plugins/bearer.d.cts +2 -2
  117. package/dist/plugins/bearer.d.ts +2 -2
  118. package/dist/plugins/bearer.js +6 -6
  119. package/dist/{plugin → plugins}/custom-session.cjs +7 -7
  120. package/dist/{plugin → plugins}/custom-session.d.cts +8 -4
  121. package/dist/{plugin → plugins}/custom-session.d.ts +8 -4
  122. package/dist/{plugin → plugins}/custom-session.js +6 -6
  123. package/dist/plugins/email-otp.cjs +7 -7
  124. package/dist/plugins/email-otp.d.cts +44 -16
  125. package/dist/plugins/email-otp.d.ts +44 -16
  126. package/dist/plugins/email-otp.js +6 -6
  127. package/dist/plugins/generic-oauth.cjs +7 -7
  128. package/dist/plugins/generic-oauth.d.cts +95 -6
  129. package/dist/plugins/generic-oauth.d.ts +95 -6
  130. package/dist/plugins/generic-oauth.js +6 -6
  131. package/dist/plugins/jwt.cjs +7 -7
  132. package/dist/plugins/jwt.d.cts +28 -6
  133. package/dist/plugins/jwt.d.ts +28 -6
  134. package/dist/plugins/jwt.js +6 -6
  135. package/dist/plugins/magic-link.cjs +7 -7
  136. package/dist/plugins/magic-link.d.cts +16 -4
  137. package/dist/plugins/magic-link.d.ts +16 -4
  138. package/dist/plugins/magic-link.js +6 -6
  139. package/dist/plugins/multi-session.cjs +7 -7
  140. package/dist/plugins/multi-session.d.cts +20 -8
  141. package/dist/plugins/multi-session.d.ts +20 -8
  142. package/dist/plugins/multi-session.js +6 -6
  143. package/dist/plugins/oidc-provider.cjs +7 -7
  144. package/dist/plugins/oidc-provider.d.cts +58 -15
  145. package/dist/plugins/oidc-provider.d.ts +58 -15
  146. package/dist/plugins/oidc-provider.js +6 -6
  147. package/dist/plugins/one-tap.cjs +7 -7
  148. package/dist/plugins/one-tap.d.cts +13 -2
  149. package/dist/plugins/one-tap.d.ts +13 -2
  150. package/dist/plugins/one-tap.js +6 -6
  151. package/dist/plugins/open-api.cjs +8 -8
  152. package/dist/plugins/open-api.d.cts +14 -6
  153. package/dist/plugins/open-api.d.ts +14 -6
  154. package/dist/plugins/open-api.js +7 -7
  155. package/dist/plugins/organization.cjs +7 -7
  156. package/dist/plugins/organization.d.cts +3 -3
  157. package/dist/plugins/organization.d.ts +3 -3
  158. package/dist/plugins/organization.js +6 -6
  159. package/dist/plugins/passkey.cjs +19 -31
  160. package/dist/plugins/passkey.d.cts +45 -148
  161. package/dist/plugins/passkey.d.ts +45 -148
  162. package/dist/plugins/passkey.js +5 -9
  163. package/dist/plugins/phone-number.cjs +7 -7
  164. package/dist/plugins/phone-number.d.cts +122 -9
  165. package/dist/plugins/phone-number.d.ts +122 -9
  166. package/dist/plugins/phone-number.js +6 -6
  167. package/dist/plugins/sso.cjs +27 -19
  168. package/dist/plugins/sso.d.cts +24 -8
  169. package/dist/plugins/sso.d.ts +24 -8
  170. package/dist/plugins/sso.js +14 -6
  171. package/dist/plugins/two-factor.cjs +7 -7
  172. package/dist/plugins/two-factor.d.cts +62 -22
  173. package/dist/plugins/two-factor.d.ts +62 -22
  174. package/dist/plugins/two-factor.js +6 -6
  175. package/dist/plugins/username.cjs +7 -7
  176. package/dist/plugins/username.d.cts +36 -4
  177. package/dist/plugins/username.d.ts +36 -4
  178. package/dist/plugins/username.js +6 -6
  179. package/dist/plugins.cjs +43 -43
  180. package/dist/plugins.d.cts +11 -7
  181. package/dist/plugins.d.ts +11 -7
  182. package/dist/plugins.js +23 -23
  183. package/dist/react.d.cts +7 -9
  184. package/dist/react.d.ts +7 -9
  185. package/dist/social.cjs +32 -20
  186. package/dist/social.d.cts +1 -1
  187. package/dist/social.d.ts +1 -1
  188. package/dist/social.js +3 -3
  189. package/dist/solid.d.cts +7 -7
  190. package/dist/solid.d.ts +7 -7
  191. package/dist/{state-Cm8el5M1.d.ts → state-CLmFUxz3.d.ts} +1 -1
  192. package/dist/{state-DcraY2_H.d.cts → state-CZgzjtR5.d.cts} +1 -1
  193. package/dist/svelte-kit.d.cts +2 -2
  194. package/dist/svelte-kit.d.ts +2 -2
  195. package/dist/svelte.d.cts +7 -7
  196. package/dist/svelte.d.ts +7 -7
  197. package/dist/types.d.cts +4 -4
  198. package/dist/types.d.ts +4 -4
  199. package/dist/vue.d.cts +7 -7
  200. package/dist/vue.d.ts +7 -7
  201. package/package.json +4 -4
  202. package/dist/chunk-4WCY4Y5J.js +0 -173
  203. package/dist/chunk-5AZFOKWY.cjs +0 -176
  204. package/dist/index-CvlKSqnF.d.cts +0 -4023
  205. package/dist/index-Ivs2EsUL.d.ts +0 -4023
@@ -1,7 +1,7 @@
1
- import { createAuthEndpoint, handleOAuthUserInfo } from './chunk-3EY3LSQR.js';
2
- import { createAuthorizationURL, validateAuthorizationCode } from './chunk-GTQM7JU7.js';
1
+ import { createAuthEndpoint, handleOAuthUserInfo, sessionMiddleware, BASE_ERROR_CODES } from './chunk-IVS5VS3V.js';
2
+ import { createAuthorizationURL, validateAuthorizationCode } from './chunk-R42K7GPF.js';
3
3
  import { setSessionCookie } from './chunk-QQGZ3XGI.js';
4
- import { generateState, parseState } from './chunk-NPO64SVN.js';
4
+ import { generateState, parseState } from './chunk-ZFUBVSZD.js';
5
5
  import { betterFetch } from '@better-fetch/fetch';
6
6
  import { APIError } from 'better-call';
7
7
  import { z } from 'zod';
@@ -142,6 +142,9 @@ var genericOAuth = (options) => {
142
142
  }).optional(),
143
143
  disableRedirect: z.boolean({
144
144
  description: "Disable redirect"
145
+ }).optional(),
146
+ scopes: z.array(z.string(), {
147
+ message: "Scopes to be passed to the provider authorization request."
145
148
  }).optional()
146
149
  }),
147
150
  metadata: {
@@ -234,7 +237,7 @@ var genericOAuth = (options) => {
234
237
  authorizationEndpoint: finalAuthUrl,
235
238
  state,
236
239
  codeVerifier: pkce ? codeVerifier : void 0,
237
- scopes: scopes || [],
240
+ scopes: ctx.body.scopes ? [...ctx.body.scopes, ...scopes || []] : scopes || [],
238
241
  redirectURI: `${ctx.context.baseURL}/oauth2/callback/${providerId}`
239
242
  });
240
243
  if (responseType && responseType !== "code") {
@@ -306,7 +309,7 @@ var genericOAuth = (options) => {
306
309
  }
307
310
  let tokens = void 0;
308
311
  const parsedState = await parseState(ctx);
309
- const { callbackURL, codeVerifier, errorURL, newUserURL } = parsedState;
312
+ const { callbackURL, codeVerifier, errorURL, newUserURL, link } = parsedState;
310
313
  const code = ctx.query.code;
311
314
  let finalTokenUrl = provider.tokenUrl;
312
315
  let finalUserInfoUrl = provider.userInfoUrl;
@@ -358,6 +361,27 @@ var genericOAuth = (options) => {
358
361
  );
359
362
  }
360
363
  const mapUser = provider.mapProfileToUser ? await provider.mapProfileToUser(userInfo) : null;
364
+ if (link) {
365
+ if (ctx.context.options.account?.accountLinking?.allowDifferentEmails !== true && link.email !== userInfo.email.toLowerCase()) {
366
+ return redirectOnError("email_doesn't_match");
367
+ }
368
+ const newAccount = await ctx.context.internalAdapter.createAccount({
369
+ userId: link.userId,
370
+ providerId: provider.providerId,
371
+ accountId: userInfo.id
372
+ });
373
+ if (!newAccount) {
374
+ return redirectOnError("unable_to_link_account");
375
+ }
376
+ let toRedirectTo2;
377
+ try {
378
+ const url = callbackURL;
379
+ toRedirectTo2 = url.toString();
380
+ } catch {
381
+ toRedirectTo2 = callbackURL;
382
+ }
383
+ throw ctx.redirect(toRedirectTo2);
384
+ }
361
385
  const result = await handleOAuthUserInfo(ctx, {
362
386
  userInfo: {
363
387
  ...userInfo,
@@ -392,6 +416,93 @@ var genericOAuth = (options) => {
392
416
  }
393
417
  throw ctx.redirect(toRedirectTo);
394
418
  }
419
+ ),
420
+ oAuth2LinkAccount: createAuthEndpoint(
421
+ "/oauth2/link",
422
+ {
423
+ method: "POST",
424
+ body: z.object({
425
+ providerId: z.string(),
426
+ callbackURL: z.string()
427
+ }),
428
+ use: [sessionMiddleware]
429
+ },
430
+ async (c) => {
431
+ const session = c.context.session;
432
+ const account = await c.context.internalAdapter.findAccounts(
433
+ session.user.id
434
+ );
435
+ const existingAccount = account.find(
436
+ (a) => a.providerId === c.body.providerId
437
+ );
438
+ if (existingAccount) {
439
+ throw new APIError("BAD_REQUEST", {
440
+ message: BASE_ERROR_CODES.SOCIAL_ACCOUNT_ALREADY_LINKED
441
+ });
442
+ }
443
+ const provider = options.config.find(
444
+ (p) => p.providerId === c.body.providerId
445
+ );
446
+ if (!provider) {
447
+ throw new APIError("NOT_FOUND", {
448
+ message: BASE_ERROR_CODES.PROVIDER_NOT_FOUND
449
+ });
450
+ }
451
+ const {
452
+ providerId,
453
+ clientId,
454
+ clientSecret,
455
+ redirectURI,
456
+ authorizationUrl,
457
+ discoveryUrl,
458
+ pkce,
459
+ scopes
460
+ } = provider;
461
+ let finalAuthUrl = authorizationUrl;
462
+ if (!finalAuthUrl) {
463
+ if (!discoveryUrl) {
464
+ throw new APIError("BAD_REQUEST", {
465
+ message: ERROR_CODES.INVALID_OAUTH_CONFIGURATION
466
+ });
467
+ }
468
+ const discovery = await betterFetch(discoveryUrl, {
469
+ onError(context) {
470
+ c.context.logger.error(context.error.message, context.error, {
471
+ discoveryUrl
472
+ });
473
+ }
474
+ });
475
+ if (discovery.data) {
476
+ finalAuthUrl = discovery.data.authorization_endpoint;
477
+ }
478
+ }
479
+ if (!finalAuthUrl) {
480
+ throw new APIError("BAD_REQUEST", {
481
+ message: ERROR_CODES.INVALID_OAUTH_CONFIGURATION
482
+ });
483
+ }
484
+ const state = await generateState(c, {
485
+ userId: session.user.id,
486
+ email: session.user.email
487
+ });
488
+ const url = await createAuthorizationURL({
489
+ id: providerId,
490
+ options: {
491
+ clientId,
492
+ clientSecret,
493
+ redirectURI: redirectURI || `${c.context.baseURL}/oauth2/callback`
494
+ },
495
+ authorizationEndpoint: finalAuthUrl,
496
+ state: state.state,
497
+ codeVerifier: pkce ? state.codeVerifier : void 0,
498
+ scopes: scopes || [],
499
+ redirectURI: `${c.context.baseURL}/oauth2/callback/${providerId}`
500
+ });
501
+ return c.json({
502
+ url: url.toString(),
503
+ redirect: true
504
+ });
505
+ }
395
506
  )
396
507
  },
397
508
  $ERROR_CODES: ERROR_CODES
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var chunkPIWBUHRB_cjs = require('./chunk-PIWBUHRB.cjs');
3
+ var chunkUPQLFVFU_cjs = require('./chunk-UPQLFVFU.cjs');
4
4
  var zod = require('zod');
5
5
 
6
6
  var customSession = (fn, options) => {
7
7
  return {
8
8
  id: "custom-session",
9
9
  endpoints: {
10
- getSession: chunkPIWBUHRB_cjs.createAuthEndpoint(
10
+ getSession: chunkUPQLFVFU_cjs.createAuthEndpoint(
11
11
  "/get-session",
12
12
  {
13
13
  method: "GET",
@@ -30,7 +30,7 @@ var customSession = (fn, options) => {
30
30
  )
31
31
  },
32
32
  async (ctx) => {
33
- const session = await chunkPIWBUHRB_cjs.getSessionFromCtx(ctx);
33
+ const session = await chunkUPQLFVFU_cjs.getSessionFromCtx(ctx);
34
34
  if (!session) {
35
35
  return ctx.json(null);
36
36
  }
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkPIWBUHRB_cjs = require('./chunk-PIWBUHRB.cjs');
3
+ var chunkUPQLFVFU_cjs = require('./chunk-UPQLFVFU.cjs');
4
4
  var chunkS5UORXJH_cjs = require('./chunk-S5UORXJH.cjs');
5
5
  var chunkV6HE2MP7_cjs = require('./chunk-V6HE2MP7.cjs');
6
- var chunkB5UCLTPZ_cjs = require('./chunk-B5UCLTPZ.cjs');
6
+ var chunkUQC2FUXC_cjs = require('./chunk-UQC2FUXC.cjs');
7
7
 
8
8
  // src/plugins/anonymous/index.ts
9
9
  var schema = {
@@ -25,7 +25,7 @@ var anonymous = (options) => {
25
25
  return {
26
26
  id: "anonymous",
27
27
  endpoints: {
28
- signInAnonymous: chunkPIWBUHRB_cjs.createAuthEndpoint(
28
+ signInAnonymous: chunkUPQLFVFU_cjs.createAuthEndpoint(
29
29
  "/sign-in/anonymous",
30
30
  {
31
31
  method: "POST",
@@ -67,7 +67,7 @@ var anonymous = (options) => {
67
67
  name: "Anonymous",
68
68
  createdAt: /* @__PURE__ */ new Date(),
69
69
  updatedAt: /* @__PURE__ */ new Date()
70
- });
70
+ }, ctx);
71
71
  if (!newUser) {
72
72
  throw ctx.error("INTERNAL_SERVER_ERROR", {
73
73
  message: ERROR_CODES.FAILED_TO_CREATE_USER
@@ -109,14 +109,14 @@ var anonymous = (options) => {
109
109
  matcher(ctx) {
110
110
  return ctx.path.startsWith("/sign-in") || ctx.path.startsWith("/sign-up") || ctx.path.startsWith("/callback") || ctx.path.startsWith("/oauth2/callback") || ctx.path.startsWith("/magic-link/verify") || ctx.path.startsWith("/email-otp/verify-email");
111
111
  },
112
- handler: chunkPIWBUHRB_cjs.createAuthMiddleware(async (ctx) => {
112
+ handler: chunkUPQLFVFU_cjs.createAuthMiddleware(async (ctx) => {
113
113
  const setCookie = ctx.context.responseHeaders?.get("set-cookie");
114
114
  const sessionTokenName = ctx.context.authCookies.sessionToken.name;
115
115
  const sessionCookie = chunkV6HE2MP7_cjs.parseSetCookieHeader(setCookie || "").get(sessionTokenName)?.value.split(".")[0];
116
116
  if (!sessionCookie) {
117
117
  return;
118
118
  }
119
- const session = await chunkPIWBUHRB_cjs.getSessionFromCtx(
119
+ const session = await chunkUPQLFVFU_cjs.getSessionFromCtx(
120
120
  ctx,
121
121
  {
122
122
  disableRefresh: true
@@ -126,7 +126,7 @@ var anonymous = (options) => {
126
126
  return;
127
127
  }
128
128
  if (ctx.path === "/sign-in/anonymous") {
129
- throw new chunkPIWBUHRB_cjs.APIError("BAD_REQUEST", {
129
+ throw new chunkUPQLFVFU_cjs.APIError("BAD_REQUEST", {
130
130
  message: ERROR_CODES.ANONYMOUS_USERS_CANNOT_SIGN_IN_AGAIN_ANONYMOUSLY
131
131
  });
132
132
  }
@@ -147,7 +147,7 @@ var anonymous = (options) => {
147
147
  }
148
148
  ]
149
149
  },
150
- schema: chunkB5UCLTPZ_cjs.mergeSchema(schema, options?.schema),
150
+ schema: chunkUQC2FUXC_cjs.mergeSchema(schema, options?.schema),
151
151
  $ERROR_CODES: ERROR_CODES
152
152
  };
153
153
  };
@@ -1,4 +1,4 @@
1
- import { createAuthMiddleware, createAuthEndpoint, sessionMiddleware, APIError, getSessionFromCtx } from './chunk-3EY3LSQR.js';
1
+ import { createAuthMiddleware, createAuthEndpoint, sessionMiddleware, APIError, getSessionFromCtx } from './chunk-IVS5VS3V.js';
2
2
  import { parseSetCookieHeader } from './chunk-QQGZ3XGI.js';
3
3
  import { generateRandomString } from './chunk-DBPOZRMS.js';
4
4
  import { SignJWT } from 'jose';
@@ -6,6 +6,7 @@ import { z } from 'zod';
6
6
  import { subtle } from '@better-auth/utils';
7
7
  import { APIError as APIError$1 } from 'better-call';
8
8
  import { createHash } from '@better-auth/utils/hash';
9
+ import { base64 } from '@better-auth/utils/base64';
9
10
 
10
11
  // src/plugins/oidc-provider/schema.ts
11
12
  var schema = {
@@ -258,7 +259,8 @@ async function authorize(ctx, options) {
258
259
  requireConsent: query.prompt === "consent",
259
260
  state: query.prompt === "consent" ? query.state : null,
260
261
  codeChallenge: query.code_challenge,
261
- codeChallengeMethod: query.code_challenge_method
262
+ codeChallengeMethod: query.code_challenge_method,
263
+ nonce: query.nonce
262
264
  }),
263
265
  identifier: code,
264
266
  expiresAt
@@ -330,7 +332,7 @@ var getMetadata = (ctx, options) => {
330
332
  issuer,
331
333
  authorization_endpoint: `${baseURL}/oauth2/authorize`,
332
334
  token_endpoint: `${baseURL}/oauth2/token`,
333
- userInfo_endpoint: `${baseURL}/oauth2/userinfo`,
335
+ userinfo_endpoint: `${baseURL}/oauth2/userinfo`,
334
336
  jwks_uri: `${baseURL}/jwks`,
335
337
  registration_endpoint: `${baseURL}/oauth2/register`,
336
338
  scopes_supported: ["openid", "profile", "email", "offline_access"],
@@ -473,9 +475,6 @@ var oidcProvider = (options) => {
473
475
  });
474
476
  }
475
477
  if (verification.expiresAt < /* @__PURE__ */ new Date()) {
476
- await ctx.context.internalAdapter.deleteVerificationValue(
477
- verification.id
478
- );
479
478
  throw new APIError("UNAUTHORIZED", {
480
479
  error_description: "Code expired",
481
480
  error: "invalid_grant"
@@ -555,9 +554,35 @@ var oidcProvider = (options) => {
555
554
  error: "invalid_request"
556
555
  });
557
556
  }
557
+ let { client_id, client_secret } = body;
558
+ const authorization = ctx.request?.headers.get("authorization") || null;
559
+ if (authorization && !client_id && !client_secret && authorization.startsWith("Basic ")) {
560
+ try {
561
+ const encoded = authorization.replace("Basic ", "");
562
+ const decoded = new TextDecoder().decode(base64.decode(encoded));
563
+ if (!decoded.includes(":")) {
564
+ throw new APIError("UNAUTHORIZED", {
565
+ error_description: "invalid authorization header format",
566
+ error: "invalid_client"
567
+ });
568
+ }
569
+ const [id, secret] = decoded.split(":");
570
+ if (!id || !secret) {
571
+ throw new APIError("UNAUTHORIZED", {
572
+ error_description: "invalid authorization header format",
573
+ error: "invalid_client"
574
+ });
575
+ }
576
+ client_id = id;
577
+ client_secret = secret;
578
+ } catch (error) {
579
+ throw new APIError("UNAUTHORIZED", {
580
+ error_description: "invalid authorization header format",
581
+ error: "invalid_client"
582
+ });
583
+ }
584
+ }
558
585
  const {
559
- client_id,
560
- client_secret,
561
586
  grant_type,
562
587
  code,
563
588
  redirect_uri,
@@ -650,9 +675,6 @@ var oidcProvider = (options) => {
650
675
  });
651
676
  }
652
677
  if (verificationValue.expiresAt < /* @__PURE__ */ new Date()) {
653
- await ctx.context.internalAdapter.deleteVerificationValue(
654
- verificationValue.id
655
- );
656
678
  throw new APIError("UNAUTHORIZED", {
657
679
  error_description: "code expired",
658
680
  error: "invalid_grant"
@@ -749,7 +771,7 @@ var oidcProvider = (options) => {
749
771
  }
750
772
  const requestedScopes = value.scope;
751
773
  await ctx.context.internalAdapter.deleteVerificationValue(
752
- code.toString()
774
+ verificationValue.id
753
775
  );
754
776
  const accessToken = generateRandomString(32, "a-z", "A-Z");
755
777
  const refreshToken = generateRandomString(32, "A-Z", "a-z");
@@ -813,7 +835,7 @@ var oidcProvider = (options) => {
813
835
  aud: client_id.toString(),
814
836
  iat: Date.now(),
815
837
  auth_time: ctx.context.session?.session.createdAt.getTime(),
816
- nonce: body.nonce,
838
+ nonce: value.nonce,
817
839
  acr: "urn:mace:incommon:iap:silver",
818
840
  // default to silver - ⚠︎ this should be configurable and should be validated against the client's metadata
819
841
  ...userClaims
@@ -893,6 +915,7 @@ var oidcProvider = (options) => {
893
915
  }
894
916
  const requestedScopes = accessToken.scopes.split(" ");
895
917
  const userClaims = {
918
+ sub: user.id,
896
919
  email: requestedScopes.includes("email") ? user.email : void 0,
897
920
  name: requestedScopes.includes("profile") ? user.name : void 0,
898
921
  picture: requestedScopes.includes("profile") ? user.image : void 0,
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunkPIWBUHRB_cjs = require('./chunk-PIWBUHRB.cjs');
4
- var chunkV6RGXSG4_cjs = require('./chunk-V6RGXSG4.cjs');
3
+ var chunkUPQLFVFU_cjs = require('./chunk-UPQLFVFU.cjs');
4
+ var chunkSVC7H7K4_cjs = require('./chunk-SVC7H7K4.cjs');
5
5
  var chunkV6HE2MP7_cjs = require('./chunk-V6HE2MP7.cjs');
6
- var chunk5E75URIA_cjs = require('./chunk-5E75URIA.cjs');
6
+ var chunk2Z6CVQHH_cjs = require('./chunk-2Z6CVQHH.cjs');
7
7
  var fetch = require('@better-fetch/fetch');
8
8
  var betterCall = require('better-call');
9
9
  var zod = require('zod');
@@ -54,7 +54,7 @@ var genericOAuth = (options) => {
54
54
  id: c.providerId,
55
55
  name: c.providerId,
56
56
  createAuthorizationURL(data) {
57
- return chunkV6RGXSG4_cjs.createAuthorizationURL({
57
+ return chunkSVC7H7K4_cjs.createAuthorizationURL({
58
58
  id: c.providerId,
59
59
  options: {
60
60
  clientId: c.clientId,
@@ -84,7 +84,7 @@ var genericOAuth = (options) => {
84
84
  message: "Invalid OAuth configuration. Token URL not found."
85
85
  });
86
86
  }
87
- return chunkV6RGXSG4_cjs.validateAuthorizationCode({
87
+ return chunkSVC7H7K4_cjs.validateAuthorizationCode({
88
88
  code: data.code,
89
89
  codeVerifier: data.codeVerifier,
90
90
  redirectURI: data.redirectURI,
@@ -125,7 +125,7 @@ var genericOAuth = (options) => {
125
125
  };
126
126
  },
127
127
  endpoints: {
128
- signInWithOAuth2: chunkPIWBUHRB_cjs.createAuthEndpoint(
128
+ signInWithOAuth2: chunkUPQLFVFU_cjs.createAuthEndpoint(
129
129
  "/sign-in/oauth2",
130
130
  {
131
131
  method: "POST",
@@ -144,6 +144,9 @@ var genericOAuth = (options) => {
144
144
  }).optional(),
145
145
  disableRedirect: zod.z.boolean({
146
146
  description: "Disable redirect"
147
+ }).optional(),
148
+ scopes: zod.z.array(zod.z.string(), {
149
+ message: "Scopes to be passed to the provider authorization request."
147
150
  }).optional()
148
151
  }),
149
152
  metadata: {
@@ -225,8 +228,8 @@ var genericOAuth = (options) => {
225
228
  }
226
229
  finalAuthUrl = withAdditionalParams.toString();
227
230
  }
228
- const { state, codeVerifier } = await chunk5E75URIA_cjs.generateState(ctx);
229
- const authUrl = await chunkV6RGXSG4_cjs.createAuthorizationURL({
231
+ const { state, codeVerifier } = await chunk2Z6CVQHH_cjs.generateState(ctx);
232
+ const authUrl = await chunkSVC7H7K4_cjs.createAuthorizationURL({
230
233
  id: providerId,
231
234
  options: {
232
235
  clientId,
@@ -236,7 +239,7 @@ var genericOAuth = (options) => {
236
239
  authorizationEndpoint: finalAuthUrl,
237
240
  state,
238
241
  codeVerifier: pkce ? codeVerifier : void 0,
239
- scopes: scopes || [],
242
+ scopes: ctx.body.scopes ? [...ctx.body.scopes, ...scopes || []] : scopes || [],
240
243
  redirectURI: `${ctx.context.baseURL}/oauth2/callback/${providerId}`
241
244
  });
242
245
  if (responseType && responseType !== "code") {
@@ -254,7 +257,7 @@ var genericOAuth = (options) => {
254
257
  });
255
258
  }
256
259
  ),
257
- oAuth2Callback: chunkPIWBUHRB_cjs.createAuthEndpoint(
260
+ oAuth2Callback: chunkUPQLFVFU_cjs.createAuthEndpoint(
258
261
  "/oauth2/callback/:providerId",
259
262
  {
260
263
  method: "GET",
@@ -307,8 +310,8 @@ var genericOAuth = (options) => {
307
310
  });
308
311
  }
309
312
  let tokens = void 0;
310
- const parsedState = await chunk5E75URIA_cjs.parseState(ctx);
311
- const { callbackURL, codeVerifier, errorURL, newUserURL } = parsedState;
313
+ const parsedState = await chunk2Z6CVQHH_cjs.parseState(ctx);
314
+ const { callbackURL, codeVerifier, errorURL, newUserURL, link } = parsedState;
312
315
  const code = ctx.query.code;
313
316
  let finalTokenUrl = provider.tokenUrl;
314
317
  let finalUserInfoUrl = provider.userInfoUrl;
@@ -327,7 +330,7 @@ var genericOAuth = (options) => {
327
330
  message: "Invalid OAuth configuration."
328
331
  });
329
332
  }
330
- tokens = await chunkV6RGXSG4_cjs.validateAuthorizationCode({
333
+ tokens = await chunkSVC7H7K4_cjs.validateAuthorizationCode({
331
334
  code,
332
335
  codeVerifier: provider.pkce ? codeVerifier : void 0,
333
336
  redirectURI: `${ctx.context.baseURL}/oauth2/callback/${provider.providerId}`,
@@ -360,7 +363,28 @@ var genericOAuth = (options) => {
360
363
  );
361
364
  }
362
365
  const mapUser = provider.mapProfileToUser ? await provider.mapProfileToUser(userInfo) : null;
363
- const result = await chunkPIWBUHRB_cjs.handleOAuthUserInfo(ctx, {
366
+ if (link) {
367
+ if (ctx.context.options.account?.accountLinking?.allowDifferentEmails !== true && link.email !== userInfo.email.toLowerCase()) {
368
+ return redirectOnError("email_doesn't_match");
369
+ }
370
+ const newAccount = await ctx.context.internalAdapter.createAccount({
371
+ userId: link.userId,
372
+ providerId: provider.providerId,
373
+ accountId: userInfo.id
374
+ });
375
+ if (!newAccount) {
376
+ return redirectOnError("unable_to_link_account");
377
+ }
378
+ let toRedirectTo2;
379
+ try {
380
+ const url = callbackURL;
381
+ toRedirectTo2 = url.toString();
382
+ } catch {
383
+ toRedirectTo2 = callbackURL;
384
+ }
385
+ throw ctx.redirect(toRedirectTo2);
386
+ }
387
+ const result = await chunkUPQLFVFU_cjs.handleOAuthUserInfo(ctx, {
364
388
  userInfo: {
365
389
  ...userInfo,
366
390
  ...mapUser
@@ -394,6 +418,93 @@ var genericOAuth = (options) => {
394
418
  }
395
419
  throw ctx.redirect(toRedirectTo);
396
420
  }
421
+ ),
422
+ oAuth2LinkAccount: chunkUPQLFVFU_cjs.createAuthEndpoint(
423
+ "/oauth2/link",
424
+ {
425
+ method: "POST",
426
+ body: zod.z.object({
427
+ providerId: zod.z.string(),
428
+ callbackURL: zod.z.string()
429
+ }),
430
+ use: [chunkUPQLFVFU_cjs.sessionMiddleware]
431
+ },
432
+ async (c) => {
433
+ const session = c.context.session;
434
+ const account = await c.context.internalAdapter.findAccounts(
435
+ session.user.id
436
+ );
437
+ const existingAccount = account.find(
438
+ (a) => a.providerId === c.body.providerId
439
+ );
440
+ if (existingAccount) {
441
+ throw new betterCall.APIError("BAD_REQUEST", {
442
+ message: chunkUPQLFVFU_cjs.BASE_ERROR_CODES.SOCIAL_ACCOUNT_ALREADY_LINKED
443
+ });
444
+ }
445
+ const provider = options.config.find(
446
+ (p) => p.providerId === c.body.providerId
447
+ );
448
+ if (!provider) {
449
+ throw new betterCall.APIError("NOT_FOUND", {
450
+ message: chunkUPQLFVFU_cjs.BASE_ERROR_CODES.PROVIDER_NOT_FOUND
451
+ });
452
+ }
453
+ const {
454
+ providerId,
455
+ clientId,
456
+ clientSecret,
457
+ redirectURI,
458
+ authorizationUrl,
459
+ discoveryUrl,
460
+ pkce,
461
+ scopes
462
+ } = provider;
463
+ let finalAuthUrl = authorizationUrl;
464
+ if (!finalAuthUrl) {
465
+ if (!discoveryUrl) {
466
+ throw new betterCall.APIError("BAD_REQUEST", {
467
+ message: ERROR_CODES.INVALID_OAUTH_CONFIGURATION
468
+ });
469
+ }
470
+ const discovery = await fetch.betterFetch(discoveryUrl, {
471
+ onError(context) {
472
+ c.context.logger.error(context.error.message, context.error, {
473
+ discoveryUrl
474
+ });
475
+ }
476
+ });
477
+ if (discovery.data) {
478
+ finalAuthUrl = discovery.data.authorization_endpoint;
479
+ }
480
+ }
481
+ if (!finalAuthUrl) {
482
+ throw new betterCall.APIError("BAD_REQUEST", {
483
+ message: ERROR_CODES.INVALID_OAUTH_CONFIGURATION
484
+ });
485
+ }
486
+ const state = await chunk2Z6CVQHH_cjs.generateState(c, {
487
+ userId: session.user.id,
488
+ email: session.user.email
489
+ });
490
+ const url = await chunkSVC7H7K4_cjs.createAuthorizationURL({
491
+ id: providerId,
492
+ options: {
493
+ clientId,
494
+ clientSecret,
495
+ redirectURI: redirectURI || `${c.context.baseURL}/oauth2/callback`
496
+ },
497
+ authorizationEndpoint: finalAuthUrl,
498
+ state: state.state,
499
+ codeVerifier: pkce ? state.codeVerifier : void 0,
500
+ scopes: scopes || [],
501
+ redirectURI: `${c.context.baseURL}/oauth2/callback/${providerId}`
502
+ });
503
+ return c.json({
504
+ url: url.toString(),
505
+ redirect: true
506
+ });
507
+ }
397
508
  )
398
509
  },
399
510
  $ERROR_CODES: ERROR_CODES