better-auth 1.6.7 → 1.6.9

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/README.md CHANGED
@@ -1,32 +1,31 @@
1
- <p align="center">
1
+ <div align="center">
2
2
  <picture>
3
- <source media="(prefers-color-scheme: dark)" srcset="https://github.com/better-auth/better-auth/blob/main/banner-dark.png?raw=true" />
4
- <source media="(prefers-color-scheme: light)" srcset="https://github.com/better-auth/better-auth/blob/main/banner.png?raw=true" />
5
- <img alt="Better Auth Logo" src="https://github.com/better-auth/better-auth/blob/main/banner.png?raw=true" />
3
+ <source srcset="https://github.com/better-auth/better-auth/blob/main/banner-dark.png?raw=true" media="(prefers-color-scheme: dark)"/>
4
+ <source srcset="https://github.com/better-auth/better-auth/blob/main/banner-light.png?raw=true" media="(prefers-color-scheme: light)"/>
5
+ <img src="https://github.com/better-auth/better-auth/blob/main/banner-light.png?raw=true" alt="Better Auth Logo"/>
6
6
  </picture>
7
7
 
8
- <h1 align="center">
9
- Better Auth
10
- </h1>
8
+ [![npm](https://img.shields.io/npm/dm/better-auth?style=flat&colorA=000000&colorB=000000)](https://npm.chart.dev/better-auth?primary=neutral&gray=neutral&theme=dark)
9
+ [![npm version](https://img.shields.io/npm/v/better-auth.svg?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/better-auth)
10
+ [![GitHub stars](https://img.shields.io/github/stars/better-auth/better-auth?style=flat&colorA=000000&colorB=000000)](https://github.com/better-auth/better-auth/stargazers)
11
11
 
12
- <p align="center">
13
- The most comprehensive authentication framework for TypeScript
14
- <br />
15
- <a href="https://better-auth.com"><strong>Learn more »</strong></a>
16
- <br />
17
- <br />
12
+ <p>
18
13
  <a href="https://discord.gg/better-auth">Discord</a>
19
14
  ·
20
15
  <a href="https://better-auth.com">Website</a>
21
16
  ·
22
17
  <a href="https://github.com/better-auth/better-auth/issues">Issues</a>
23
18
  </p>
24
- </p>
19
+ </div>
20
+
21
+ ## Better Auth
22
+
23
+ Better Auth is a framework-agnostic authentication (and authorization) framework for TypeScript. It provides a comprehensive set of features out of the box and includes a plugin ecosystem that simplifies adding advanced functionalities with minimal code in a short amount of time. Whether you need 2FA, multi-tenant support, or other complex features, it lets you focus on building your actual application instead of reinventing the wheel.
25
24
 
26
25
  ## Getting Started
27
26
 
28
27
  ```bash
29
- pnpm install better-auth
28
+ npm i better-auth
30
29
  ```
31
30
 
32
31
  Read the [Installation Guide](https://better-auth.com/docs/installation) to
@@ -1,6 +1,7 @@
1
1
  import { parseAccountOutput } from "../../db/schema.mjs";
2
2
  import { getAccountCookie, setAccountCookie } from "../../cookies/session-store.mjs";
3
3
  import { getAwaitableValue } from "../../context/helpers.mjs";
4
+ import { missingEmailLogMessage } from "../../oauth2/errors.mjs";
4
5
  import { generateState } from "../../oauth2/state.mjs";
5
6
  import { decryptOAuthToken, setTokenUtil } from "../../oauth2/utils.mjs";
6
7
  import { freshSessionMiddleware, getSessionFromCtx, sessionMiddleware } from "./session.mjs";
@@ -133,7 +134,7 @@ const linkSocialAccount = createAuthEndpoint("/link-social", {
133
134
  }
134
135
  const linkingUserId = String(linkingUserInfo.user.id);
135
136
  if (!linkingUserInfo.user.email) {
136
- c.context.logger.error("User email not found", { provider: c.body.provider });
137
+ c.context.logger.error(missingEmailLogMessage(c.body.provider, { source: "id_token" }), { provider: c.body.provider });
137
138
  throw APIError.from("UNAUTHORIZED", BASE_ERROR_CODES.USER_EMAIL_NOT_FOUND);
138
139
  }
139
140
  if ((await c.context.internalAdapter.findAccounts(session.user.id)).find((a) => a.providerId === provider.id && a.accountId === linkingUserId)) return c.json({
@@ -1,5 +1,6 @@
1
1
  import { setSessionCookie } from "../../cookies/index.mjs";
2
2
  import { getAwaitableValue } from "../../context/helpers.mjs";
3
+ import { missingEmailLogMessage } from "../../oauth2/errors.mjs";
3
4
  import { parseState } from "../../oauth2/state.mjs";
4
5
  import { setTokenUtil } from "../../oauth2/utils.mjs";
5
6
  import { handleOAuthUserInfo } from "../../oauth2/link-account.mjs";
@@ -134,7 +135,7 @@ const callbackOAuth = createAuthEndpoint("/callback/:id", {
134
135
  throw c.redirect(toRedirectTo);
135
136
  }
136
137
  if (!userInfo.email) {
137
- c.context.logger.error("Provider did not return email. This could be due to misconfiguration in the provider settings.");
138
+ c.context.logger.error(missingEmailLogMessage(provider.id));
138
139
  return redirectOnError("email_not_found");
139
140
  }
140
141
  const accountData = {
@@ -2,6 +2,7 @@ import { formCsrfMiddleware } from "../middlewares/origin-check.mjs";
2
2
  import { parseUserOutput } from "../../db/schema.mjs";
3
3
  import { setSessionCookie } from "../../cookies/index.mjs";
4
4
  import { getAwaitableValue } from "../../context/helpers.mjs";
5
+ import { missingEmailLogMessage } from "../../oauth2/errors.mjs";
5
6
  import { generateState } from "../../oauth2/state.mjs";
6
7
  import { handleOAuthUserInfo } from "../../oauth2/link-account.mjs";
7
8
  import { createEmailVerificationToken } from "./email-verification.mjs";
@@ -100,7 +101,7 @@ const signInSocial = () => createAuthEndpoint("/sign-in/social", {
100
101
  throw APIError.from("UNAUTHORIZED", BASE_ERROR_CODES.FAILED_TO_GET_USER_INFO);
101
102
  }
102
103
  if (!userInfo.user.email) {
103
- c.context.logger.error("User email not found", { provider: c.body.provider });
104
+ c.context.logger.error(missingEmailLogMessage(c.body.provider, { source: "id_token" }), { provider: c.body.provider });
104
105
  throw APIError.from("UNAUTHORIZED", BASE_ERROR_CODES.USER_EMAIL_NOT_FOUND);
105
106
  }
106
107
  const data = await handleOAuthUserInfo(c, {
@@ -0,0 +1,12 @@
1
+ //#region src/oauth2/errors.ts
2
+ const HANDLING_DOCS_URL = "https://www.better-auth.com/docs/concepts/oauth#handling-providers-without-email";
3
+ /**
4
+ * Build the logger message shown when an OAuth provider does not return an
5
+ * email address. Kept in one place so every rejection site points users at
6
+ * the same workaround docs.
7
+ */
8
+ function missingEmailLogMessage(providerId, options) {
9
+ return `${options?.source === "generic" ? `Generic OAuth provider "${providerId}"` : `Provider "${providerId}"`} did not return an email${options?.source === "id_token" ? " in the id token" : ""}. Either request the provider's email scope, or synthesize one via \`mapProfileToUser\`. See ${HANDLING_DOCS_URL}`;
10
+ }
11
+ //#endregion
12
+ export { missingEmailLogMessage };
package/dist/package.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "1.6.7";
2
+ var version = "1.6.9";
3
3
  //#endregion
4
4
  export { version };
@@ -1,4 +1,5 @@
1
1
  import { setSessionCookie } from "../../cookies/index.mjs";
2
+ import { missingEmailLogMessage } from "../../oauth2/errors.mjs";
2
3
  import { generateState, parseState } from "../../oauth2/state.mjs";
3
4
  import { setTokenUtil } from "../../oauth2/utils.mjs";
4
5
  import { sessionMiddleware } from "../../api/routes/session.mjs";
@@ -209,7 +210,7 @@ const oAuth2Callback = (options) => createAuthEndpoint("/oauth2/callback/:provid
209
210
  const mapUser = providerConfig.mapProfileToUser ? await providerConfig.mapProfileToUser(userInfo) : userInfo;
210
211
  const email = mapUser.email ? mapUser.email.toLowerCase() : userInfo.email?.toLowerCase();
211
212
  if (!email) {
212
- ctx.context.logger.error("Unable to get user info", userInfo);
213
+ ctx.context.logger.error(missingEmailLogMessage(providerConfig.providerId, { source: "generic" }), userInfo);
213
214
  throw redirectOnError("email_is_missing");
214
215
  }
215
216
  const id = mapUser.id ? String(mapUser.id) : String(userInfo.id);
@@ -396,7 +396,7 @@ declare const getOrgAdapter: <O extends OrganizationOptions>(context: AuthContex
396
396
  } ? FieldAttributeToObject<RemoveFieldsWithReturnedFalse<Field>> : {}) extends infer T_3 ? { [K_3 in keyof T_3]: T_3[K_3] } : never)[] | undefined;
397
397
  }) | null>;
398
398
  listOrganizations: (userId: string) => Promise<InferOrganization<O>[]>;
399
- createTeam: (data: Omit<TeamInput, "id">) => Promise<{
399
+ createTeam: (data: TeamInput) => Promise<{
400
400
  id: string;
401
401
  name: string;
402
402
  organizationId: string;
@@ -357,7 +357,8 @@ const getOrgAdapter = (context, options) => {
357
357
  createTeam: async (data) => {
358
358
  return await (await getCurrentAdapter(baseAdapter)).create({
359
359
  model: "team",
360
- data
360
+ data,
361
+ forceAllowId: true
361
362
  });
362
363
  },
363
364
  findTeamById: async ({ teamId, organizationId, includeTeamMembers }) => {
@@ -553,7 +554,8 @@ const getOrgAdapter = (context, options) => {
553
554
  inviterId: user.id,
554
555
  ...invitation,
555
556
  teamId: invitation.teamIds.length > 0 ? invitation.teamIds.join(",") : null
556
- }
557
+ },
558
+ forceAllowId: true
557
559
  });
558
560
  },
559
561
  findInvitationById: async (id) => {
@@ -294,7 +294,7 @@ type InvitationInput = z.input<typeof invitationSchema>;
294
294
  type MemberInput = z.input<typeof memberSchema>;
295
295
  type TeamMemberInput = z.input<typeof teamMemberSchema>;
296
296
  type OrganizationInput = z.input<typeof organizationSchema>;
297
- type TeamInput = z.infer<typeof teamSchema>;
297
+ type TeamInput = z.input<typeof teamSchema>;
298
298
  type OrganizationRole = z.infer<typeof organizationRoleSchema>;
299
299
  declare const defaultRolesSchema: z.ZodUnion<readonly [z.ZodEnum<{
300
300
  admin: "admin";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-auth",
3
- "version": "1.6.7",
3
+ "version": "1.6.9",
4
4
  "description": "The most comprehensive authentication framework for TypeScript.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -489,13 +489,13 @@
489
489
  "kysely": "^0.28.14",
490
490
  "nanostores": "^1.1.1",
491
491
  "zod": "^4.3.6",
492
- "@better-auth/core": "1.6.7",
493
- "@better-auth/drizzle-adapter": "1.6.7",
494
- "@better-auth/kysely-adapter": "1.6.7",
495
- "@better-auth/memory-adapter": "1.6.7",
496
- "@better-auth/mongo-adapter": "1.6.7",
497
- "@better-auth/prisma-adapter": "1.6.7",
498
- "@better-auth/telemetry": "1.6.7"
492
+ "@better-auth/core": "1.6.9",
493
+ "@better-auth/drizzle-adapter": "1.6.9",
494
+ "@better-auth/kysely-adapter": "1.6.9",
495
+ "@better-auth/memory-adapter": "1.6.9",
496
+ "@better-auth/mongo-adapter": "1.6.9",
497
+ "@better-auth/prisma-adapter": "1.6.9",
498
+ "@better-auth/telemetry": "1.6.9"
499
499
  },
500
500
  "devDependencies": {
501
501
  "@lynx-js/react": "^0.116.3",