better-auth 1.7.15 → 1.7.17

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 (68) hide show
  1. package/dist/api/index.d.mts +2 -1
  2. package/dist/api/index.mjs +3 -2
  3. package/dist/api/routes/account.mjs +14 -6
  4. package/dist/api/routes/email-verification.mjs +29 -37
  5. package/dist/api/routes/sign-in.mjs +2 -2
  6. package/dist/api/routes/sign-up.mjs +1 -1
  7. package/dist/api/routes/update-user.mjs +10 -4
  8. package/dist/api/state/session-source.d.mts +10 -0
  9. package/dist/api/state/session-source.mjs +28 -0
  10. package/dist/auth/trusted-origins.mjs +33 -8
  11. package/dist/client/index.d.mts +2 -1
  12. package/dist/cookies/index.mjs +1 -0
  13. package/dist/db/internal-adapter.mjs +28 -10
  14. package/dist/index.d.mts +2 -2
  15. package/dist/index.mjs +2 -2
  16. package/dist/oauth2/link-account.d.mts +3 -5
  17. package/dist/oauth2/link-account.mjs +33 -3
  18. package/dist/oauth2/state.d.mts +6 -5
  19. package/dist/package.mjs +1 -1
  20. package/dist/plugins/admin/access/statement.d.mts +10 -10
  21. package/dist/plugins/admin/access/statement.mjs +2 -0
  22. package/dist/plugins/admin/admin.d.mts +4 -3
  23. package/dist/plugins/admin/client.d.mts +5 -4
  24. package/dist/plugins/admin/error-codes.d.mts +1 -0
  25. package/dist/plugins/admin/error-codes.mjs +1 -0
  26. package/dist/plugins/admin/routes.mjs +8 -0
  27. package/dist/plugins/anonymous/index.mjs +2 -1
  28. package/dist/plugins/device-authorization/routes.mjs +4 -4
  29. package/dist/plugins/email-otp/routes.mjs +33 -50
  30. package/dist/plugins/generic-oauth/index.mjs +54 -30
  31. package/dist/plugins/index.d.mts +2 -1
  32. package/dist/plugins/index.mjs +2 -1
  33. package/dist/plugins/oauth-proxy/index.mjs +1 -1
  34. package/dist/plugins/one-tap/index.mjs +1 -1
  35. package/dist/plugins/organization/adapter.mjs +1 -0
  36. package/dist/plugins/organization/client.d.mts +1 -0
  37. package/dist/plugins/organization/error-codes.d.mts +1 -0
  38. package/dist/plugins/organization/error-codes.mjs +1 -0
  39. package/dist/plugins/organization/has-permission.d.mts +2 -3
  40. package/dist/plugins/organization/has-permission.mjs +62 -23
  41. package/dist/plugins/organization/index.d.mts +2 -1
  42. package/dist/plugins/organization/index.mjs +2 -1
  43. package/dist/plugins/organization/organization.d.mts +2 -2
  44. package/dist/plugins/organization/organization.mjs +1 -3
  45. package/dist/plugins/organization/permission.mjs +3 -3
  46. package/dist/plugins/organization/roles.d.mts +8 -0
  47. package/dist/plugins/organization/roles.mjs +26 -0
  48. package/dist/plugins/organization/routes/crud-access-control.mjs +2 -1
  49. package/dist/plugins/organization/routes/crud-invites.mjs +22 -11
  50. package/dist/plugins/organization/routes/crud-members.mjs +10 -14
  51. package/dist/plugins/organization/routes/crud-org.mjs +12 -3
  52. package/dist/plugins/phone-number/client.d.mts +2 -0
  53. package/dist/plugins/phone-number/error-codes.d.mts +2 -0
  54. package/dist/plugins/phone-number/error-codes.mjs +2 -0
  55. package/dist/plugins/phone-number/index.d.mts +25 -1
  56. package/dist/plugins/phone-number/index.mjs +22 -6
  57. package/dist/plugins/phone-number/routes.mjs +34 -35
  58. package/dist/plugins/two-factor/backup-codes/index.d.mts +2 -2
  59. package/dist/plugins/two-factor/index.d.mts +15 -8
  60. package/dist/plugins/two-factor/index.mjs +74 -26
  61. package/dist/plugins/two-factor/otp/index.d.mts +2 -2
  62. package/dist/plugins/two-factor/totp/index.d.mts +2 -2
  63. package/dist/plugins/two-factor/verify-two-factor.mjs +4 -2
  64. package/dist/plugins/username/index.mjs +1 -1
  65. package/dist/state.d.mts +6 -0
  66. package/dist/state.mjs +5 -2
  67. package/dist/utils/index.d.mts +2 -2
  68. package/package.json +11 -11
@@ -198,7 +198,7 @@ export declare const otp2fa: (options?: OTPOptions | undefined) => {
198
198
  user: UserWithTwoFactor;
199
199
  } | {
200
200
  token: string;
201
- user: Record<string, any> & {
201
+ user: {
202
202
  id: string;
203
203
  createdAt: Date;
204
204
  updatedAt: Date;
@@ -206,7 +206,7 @@ export declare const otp2fa: (options?: OTPOptions | undefined) => {
206
206
  emailVerified: boolean;
207
207
  name: string;
208
208
  image?: string | null | undefined;
209
- };
209
+ } & Record<string, any>;
210
210
  }>;
211
211
  };
212
212
  };
@@ -201,7 +201,7 @@ export declare const totp2fa: (options?: TOTPOptions | undefined) => {
201
201
  user: UserWithTwoFactor;
202
202
  } | {
203
203
  token: string;
204
- user: Record<string, any> & {
204
+ user: {
205
205
  id: string;
206
206
  createdAt: Date;
207
207
  updatedAt: Date;
@@ -209,7 +209,7 @@ export declare const totp2fa: (options?: TOTPOptions | undefined) => {
209
209
  emailVerified: boolean;
210
210
  name: string;
211
211
  image?: string | null | undefined;
212
- };
212
+ } & Record<string, any>;
213
213
  }>;
214
214
  };
215
215
  };
@@ -1,7 +1,8 @@
1
1
  import { parseUserOutput } from "../../db/schema.mjs";
2
2
  import { generateRandomString } from "../../crypto/random.mjs";
3
3
  import { expireCookie, setSessionCookie } from "../../cookies/index.mjs";
4
- import { getSessionFromCtx } from "../../api/routes/session.mjs";
4
+ import { getAuthoritativeSessionFromCtx } from "../../api/routes/session.mjs";
5
+ import { isSessionOutsideStore } from "../../api/state/session-source.mjs";
5
6
  import { TWO_FACTOR_ERROR_CODES } from "./error-code.mjs";
6
7
  import { TRUST_DEVICE_COOKIE_NAME, TWO_FACTOR_COOKIE_NAME } from "./constant.mjs";
7
8
  import { APIError } from "@better-auth/core/error";
@@ -11,7 +12,8 @@ async function verifyTwoFactor(ctx) {
11
12
  const invalid = (errorKey) => {
12
13
  throw APIError.from("UNAUTHORIZED", TWO_FACTOR_ERROR_CODES[errorKey]);
13
14
  };
14
- const session = await getSessionFromCtx(ctx);
15
+ const requestSession = ctx.context.session;
16
+ const session = requestSession && await isSessionOutsideStore(requestSession.session.token) ? requestSession : await getAuthoritativeSessionFromCtx(ctx);
15
17
  if (!session) {
16
18
  const twoFactorCookie = ctx.context.createAuthCookie(TWO_FACTOR_COOKIE_NAME);
17
19
  const signedTwoFactorCookie = await ctx.getSignedCookie(twoFactorCookie.name, ctx.context.secret);
@@ -187,7 +187,7 @@ const usernameImpl = (options, includeDisplayUsername) => {
187
187
  if (ctx.context.options?.emailAndPassword?.requireEmailVerification && !user.emailVerified) {
188
188
  if (!ctx.context.options?.emailVerification?.sendVerificationEmail) throw APIError.from("FORBIDDEN", USERNAME_ERROR_CODES.EMAIL_NOT_VERIFIED);
189
189
  if (ctx.context.options?.emailVerification?.sendOnSignIn) {
190
- const token = await createEmailVerificationToken(ctx.context.secret, user.email, void 0, ctx.context.options.emailVerification?.expiresIn);
190
+ const token = await createEmailVerificationToken(ctx.context.secret, user.email, void 0, ctx.context.options.emailVerification?.expiresIn, { userId: user.id });
191
191
  const url = `${ctx.context.baseURL}/verify-email?token=${token}&callbackURL=${encodeURIComponent(ctx.body.callbackURL || "/")}`;
192
192
  await ctx.context.runInBackgroundOrAwait(ctx.context.options.emailVerification.sendVerificationEmail({
193
193
  user,
package/dist/state.d.mts CHANGED
@@ -12,12 +12,17 @@ declare const stateDataSchema: z.ZodObject<{
12
12
  link: z.ZodOptional<z.ZodObject<{
13
13
  email: z.ZodString;
14
14
  userId: z.ZodCoercedString<unknown>;
15
+ encryptedSessionToken: z.ZodOptional<z.ZodString>;
15
16
  }, z.core.$strip>>;
16
17
  requestSignUp: z.ZodOptional<z.ZodBoolean>;
17
18
  idTokenNonce: z.ZodOptional<z.ZodString>;
18
19
  serverContext: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
19
20
  }, z.core.$loose>;
20
21
  export type StateData = z.infer<typeof stateDataSchema>;
22
+ /**
23
+ * Verification key for database-backed OAuth and SAML relay state.
24
+ */
25
+ export declare const getAuthStateVerificationIdentifier: (state: string) => string;
21
26
  export declare function generateGenericState(c: GenericEndpointContext, stateData: StateData, settings?: {
22
27
  cookieName: string;
23
28
  }): Promise<{
@@ -38,6 +43,7 @@ export declare function parseGenericState(c: GenericEndpointContext, state: stri
38
43
  link?: {
39
44
  email: string;
40
45
  userId: string;
46
+ encryptedSessionToken?: string | undefined;
41
47
  } | undefined;
42
48
  requestSignUp?: boolean | undefined;
43
49
  idTokenNonce?: string | undefined;
package/dist/state.mjs CHANGED
@@ -18,7 +18,8 @@ const stateDataSchema = z.looseObject({
18
18
  oauthState: z.string().optional(),
19
19
  link: z.object({
20
20
  email: z.string(),
21
- userId: z.coerce.string()
21
+ userId: z.coerce.string(),
22
+ encryptedSessionToken: z.string().optional()
22
23
  }).optional(),
23
24
  requestSignUp: z.boolean().optional(),
24
25
  /**
@@ -33,7 +34,9 @@ const stateDataSchema = z.looseObject({
33
34
  */
34
35
  serverContext: z.record(z.string(), z.unknown()).optional()
35
36
  });
36
- /** Verification key for database-backed OAuth and SAML relay state. */
37
+ /**
38
+ * Verification key for database-backed OAuth and SAML relay state.
39
+ */
37
40
  const getAuthStateVerificationIdentifier = (state) => `auth-state:${state}`;
38
41
  const INTERNAL_STATE_KEYS = new Set(Object.keys(stateDataSchema.shape));
39
42
  var StateError = class extends BetterAuthError {
@@ -1,5 +1,5 @@
1
+ import { StateData, generateGenericState, getAuthStateVerificationIdentifier, parseGenericState } from "../state.mjs";
1
2
  import { GenerateStateOptions, generateIdTokenNonce, generateState, parseState } from "../oauth2/state.mjs";
2
- import { StateData, generateGenericState, parseGenericState } from "../state.mjs";
3
3
  import { HIDE_METADATA } from "./hide-metadata.mjs";
4
4
  import { getBaseURL, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, resolveBaseURL, resolveDynamicBaseURL, trimTrailingSlashes } from "./url.mjs";
5
- export { GenerateStateOptions, HIDE_METADATA, type StateData, generateGenericState, generateIdTokenNonce, generateState, getBaseURL, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, parseGenericState, parseState, resolveBaseURL, resolveDynamicBaseURL, trimTrailingSlashes };
5
+ export { GenerateStateOptions, HIDE_METADATA, type StateData, generateGenericState, generateIdTokenNonce, generateState, getAuthStateVerificationIdentifier, getBaseURL, getHost, getHostFromSource, getOrigin, getProtocol, getProtocolFromSource, isDynamicBaseURLConfig, isRequestLike, matchesHostPattern, parseGenericState, parseState, resolveBaseURL, resolveDynamicBaseURL, trimTrailingSlashes };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-auth",
3
- "version": "1.7.15",
3
+ "version": "1.7.17",
4
4
  "description": "The most comprehensive authentication framework for TypeScript.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -497,19 +497,19 @@
497
497
  "@better-fetch/fetch": "1.3.3",
498
498
  "@noble/ciphers": "^2.2.0",
499
499
  "@noble/hashes": "^2.2.0",
500
- "better-call": "1.4.4",
500
+ "better-call": "1.4.5",
501
501
  "defu": "^6.1.4",
502
502
  "jose": "^6.2.3",
503
503
  "kysely": "^0.28.17 || ^0.29.0",
504
504
  "nanostores": "^1.3.0",
505
505
  "zod": "^4.5.4",
506
- "@better-auth/core": "1.7.15",
507
- "@better-auth/drizzle-adapter": "1.7.15",
508
- "@better-auth/kysely-adapter": "1.7.15",
509
- "@better-auth/memory-adapter": "1.7.15",
510
- "@better-auth/mongo-adapter": "1.7.15",
511
- "@better-auth/prisma-adapter": "1.7.15",
512
- "@better-auth/telemetry": "1.7.15"
506
+ "@better-auth/core": "1.7.17",
507
+ "@better-auth/drizzle-adapter": "1.7.17",
508
+ "@better-auth/kysely-adapter": "1.7.17",
509
+ "@better-auth/memory-adapter": "1.7.17",
510
+ "@better-auth/mongo-adapter": "1.7.17",
511
+ "@better-auth/prisma-adapter": "1.7.17",
512
+ "@better-auth/telemetry": "1.7.17"
513
513
  },
514
514
  "devDependencies": {
515
515
  "@lynx-js/react": "^0.121.2",
@@ -529,8 +529,8 @@
529
529
  "msw": "^2.14.6",
530
530
  "next": "^16.4.2",
531
531
  "oauth2-mock-server": "^9.0.0",
532
- "react": "^19.2.7",
533
- "react-dom": "^19.2.7",
532
+ "react": "^19.3.1",
533
+ "react-dom": "^19.3.1",
534
534
  "solid-js": "^1.9.11",
535
535
  "tsdown": "0.23.1",
536
536
  "type-fest": "^5.7.0",