better-auth 0.0.9-beta.5 → 0.0.9-beta.7

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/index.js CHANGED
@@ -1750,17 +1750,24 @@ var changePassword = createAuthEndpoint(
1750
1750
  {
1751
1751
  method: "POST",
1752
1752
  body: z.object({
1753
+ /**
1754
+ * The new password to set
1755
+ */
1753
1756
  newPassword: z.string(),
1754
1757
  /**
1755
- * If the user has not set a password yet,
1756
- * they can set it with this field.
1758
+ * The current password of the user
1759
+ */
1760
+ currentPassword: z.string(),
1761
+ /**
1762
+ * revoke all sessions that are not the
1763
+ * current one logged in by the user
1757
1764
  */
1758
- oldPassword: z.string()
1765
+ revokeOtherSessions: z.boolean().optional()
1759
1766
  }),
1760
1767
  use: [sessionMiddleware]
1761
1768
  },
1762
1769
  async (ctx) => {
1763
- const { newPassword, oldPassword } = ctx.body;
1770
+ const { newPassword, currentPassword, revokeOtherSessions } = ctx.body;
1764
1771
  const session = ctx.context.session;
1765
1772
  const minPasswordLength = ctx.context.options?.emailAndPassword?.minPasswordLength || 8;
1766
1773
  if (newPassword.length < minPasswordLength) {
@@ -1790,7 +1797,7 @@ var changePassword = createAuthEndpoint(
1790
1797
  if (account.password) {
1791
1798
  const verify = await ctx.context.password.verify(
1792
1799
  account.password,
1793
- oldPassword
1800
+ currentPassword
1794
1801
  );
1795
1802
  if (!verify) {
1796
1803
  return ctx.json(null, {
@@ -1802,6 +1809,13 @@ var changePassword = createAuthEndpoint(
1802
1809
  await ctx.context.internalAdapter.updateAccount(account.id, {
1803
1810
  password: passwordHash
1804
1811
  });
1812
+ if (revokeOtherSessions) {
1813
+ await ctx.context.internalAdapter.deleteSessions(session.user.id);
1814
+ const newSession = await ctx.context.internalAdapter.createSession(
1815
+ session.user.id
1816
+ );
1817
+ await setSessionCookie(ctx, newSession.id);
1818
+ }
1805
1819
  return ctx.json(session.user);
1806
1820
  }
1807
1821
  );
@@ -1950,6 +1964,127 @@ var router = (ctx, _options) => {
1950
1964
  }
1951
1965
  });
1952
1966
  };
1967
+
1968
+ // src/adapters/get-tables.ts
1969
+ var getAuthTables = (options) => {
1970
+ const pluginSchema = options.plugins?.reduce(
1971
+ (acc, plugin) => {
1972
+ const schema = plugin.schema;
1973
+ if (!schema) return acc;
1974
+ for (const [key, value] of Object.entries(schema)) {
1975
+ acc[key] = {
1976
+ fields: {
1977
+ ...acc[key]?.fields,
1978
+ ...value.fields
1979
+ },
1980
+ tableName: key
1981
+ };
1982
+ }
1983
+ return acc;
1984
+ },
1985
+ {}
1986
+ );
1987
+ return {
1988
+ ...pluginSchema,
1989
+ user: {
1990
+ tableName: options.user?.modelName || "user",
1991
+ fields: {
1992
+ name: {
1993
+ type: "string"
1994
+ },
1995
+ email: {
1996
+ type: "string"
1997
+ },
1998
+ emailVerified: {
1999
+ type: "boolean",
2000
+ defaultValue: () => false
2001
+ },
2002
+ image: {
2003
+ type: "string",
2004
+ required: false
2005
+ },
2006
+ createdAt: {
2007
+ type: "date",
2008
+ defaultValue: () => /* @__PURE__ */ new Date()
2009
+ },
2010
+ updatedAt: {
2011
+ type: "date",
2012
+ defaultValue: () => /* @__PURE__ */ new Date()
2013
+ },
2014
+ ...pluginSchema?.user?.fields
2015
+ }
2016
+ },
2017
+ session: {
2018
+ tableName: options.session?.modelName || "session",
2019
+ fields: {
2020
+ expiresAt: {
2021
+ type: "date"
2022
+ },
2023
+ ipAddress: {
2024
+ type: "string",
2025
+ required: false
2026
+ },
2027
+ userAgent: {
2028
+ type: "string",
2029
+ required: false
2030
+ },
2031
+ userId: {
2032
+ type: "string",
2033
+ references: {
2034
+ model: "user",
2035
+ field: "id",
2036
+ onDelete: "cascade"
2037
+ }
2038
+ },
2039
+ ...pluginSchema?.session?.fields
2040
+ }
2041
+ },
2042
+ account: {
2043
+ tableName: options.account?.modelName || "account",
2044
+ fields: {
2045
+ accountId: {
2046
+ type: "string"
2047
+ },
2048
+ providerId: {
2049
+ type: "string"
2050
+ },
2051
+ userId: {
2052
+ type: "string",
2053
+ references: {
2054
+ model: "user",
2055
+ field: "id",
2056
+ onDelete: "cascade"
2057
+ }
2058
+ },
2059
+ accessToken: {
2060
+ type: "string",
2061
+ required: false
2062
+ },
2063
+ refreshToken: {
2064
+ type: "string",
2065
+ required: false
2066
+ },
2067
+ idToken: {
2068
+ type: "string",
2069
+ required: false
2070
+ },
2071
+ accessTokenExpiresAt: {
2072
+ type: "date",
2073
+ required: false
2074
+ },
2075
+ refreshTokenExpiresAt: {
2076
+ type: "date",
2077
+ required: false
2078
+ },
2079
+ password: {
2080
+ type: "string",
2081
+ required: false
2082
+ },
2083
+ ...pluginSchema?.account?.fields
2084
+ }
2085
+ }
2086
+ };
2087
+ };
1953
2088
  var { Pool } = pg;
1954
2089
  function convertWhere(w) {
1955
2090
  if (!w)
@@ -2177,127 +2312,6 @@ var getDatabaseType = (config2) => {
2177
2312
  return "sqlite";
2178
2313
  };
2179
2314
 
2180
- // src/adapters/get-tables.ts
2181
- var getAuthTables = (options) => {
2182
- const pluginSchema = options.plugins?.reduce(
2183
- (acc, plugin) => {
2184
- const schema = plugin.schema;
2185
- if (!schema) return acc;
2186
- for (const [key, value] of Object.entries(schema)) {
2187
- acc[key] = {
2188
- fields: {
2189
- ...acc[key]?.fields,
2190
- ...value.fields
2191
- },
2192
- tableName: key
2193
- };
2194
- }
2195
- return acc;
2196
- },
2197
- {}
2198
- );
2199
- return {
2200
- ...pluginSchema,
2201
- user: {
2202
- tableName: options.user?.modelName || "user",
2203
- fields: {
2204
- name: {
2205
- type: "string"
2206
- },
2207
- email: {
2208
- type: "string"
2209
- },
2210
- emailVerified: {
2211
- type: "boolean",
2212
- defaultValue: () => false
2213
- },
2214
- image: {
2215
- type: "string",
2216
- required: false
2217
- },
2218
- createdAt: {
2219
- type: "date",
2220
- defaultValue: () => /* @__PURE__ */ new Date()
2221
- },
2222
- updatedAt: {
2223
- type: "date",
2224
- defaultValue: () => /* @__PURE__ */ new Date()
2225
- },
2226
- ...pluginSchema?.user?.fields
2227
- }
2228
- },
2229
- session: {
2230
- tableName: options.session?.modelName || "session",
2231
- fields: {
2232
- expiresAt: {
2233
- type: "date"
2234
- },
2235
- ipAddress: {
2236
- type: "string",
2237
- required: false
2238
- },
2239
- userAgent: {
2240
- type: "string",
2241
- required: false
2242
- },
2243
- userId: {
2244
- type: "string",
2245
- references: {
2246
- model: "user",
2247
- field: "id",
2248
- onDelete: "cascade"
2249
- }
2250
- },
2251
- ...pluginSchema?.session?.fields
2252
- }
2253
- },
2254
- account: {
2255
- tableName: options.account?.modelName || "account",
2256
- fields: {
2257
- accountId: {
2258
- type: "string"
2259
- },
2260
- providerId: {
2261
- type: "string"
2262
- },
2263
- userId: {
2264
- type: "string",
2265
- references: {
2266
- model: "user",
2267
- field: "id",
2268
- onDelete: "cascade"
2269
- }
2270
- },
2271
- accessToken: {
2272
- type: "string",
2273
- required: false
2274
- },
2275
- refreshToken: {
2276
- type: "string",
2277
- required: false
2278
- },
2279
- idToken: {
2280
- type: "string",
2281
- required: false
2282
- },
2283
- accessTokenExpiresAt: {
2284
- type: "date",
2285
- required: false
2286
- },
2287
- refreshTokenExpiresAt: {
2288
- type: "date",
2289
- required: false
2290
- },
2291
- password: {
2292
- type: "string",
2293
- required: false
2294
- },
2295
- ...pluginSchema?.account?.fields
2296
- }
2297
- }
2298
- };
2299
- };
2300
-
2301
2315
  // src/adapters/utils.ts
2302
2316
  function getAdapter(options) {
2303
2317
  if (!options.database) {
@@ -2356,7 +2370,7 @@ var verifyPassword = async (hash, password) => {
2356
2370
  const targetKey = await generateKey(password, salt);
2357
2371
  return constantTimeEqual(targetKey, decodeHex(key));
2358
2372
  };
2359
- var createInternalAdapter = (adapter, options) => {
2373
+ var createInternalAdapter = (adapter, db, options) => {
2360
2374
  const sessionExpiration = options.session?.expiresIn || 60 * 60 * 24 * 7;
2361
2375
  const tables = getAuthTables(options);
2362
2376
  return {
@@ -2460,6 +2474,13 @@ var createInternalAdapter = (adapter, options) => {
2460
2474
  });
2461
2475
  return session;
2462
2476
  },
2477
+ /**
2478
+ * @requires db
2479
+ */
2480
+ deleteSessions: async (userId) => {
2481
+ const sessions = await db.deleteFrom(tables.session.tableName).where("userId", "=", userId).execute();
2482
+ return sessions;
2483
+ },
2463
2484
  findUserByEmail: async (email) => {
2464
2485
  const user = await adapter.findOne({
2465
2486
  model: tables.user.tableName,
@@ -2571,9 +2592,13 @@ var DEFAULT_SECRET = "better-auth-secret-123456789";
2571
2592
  var init = (options) => {
2572
2593
  const adapter = getAdapter(options);
2573
2594
  const db = createKyselyAdapter(options);
2595
+ if (!db) {
2596
+ throw new Error("No database adapter found");
2597
+ }
2574
2598
  const baseURL = getBaseURL(options.baseURL, options.basePath);
2575
2599
  const secret = options.secret || process.env.BETTER_AUTH_SECRET || process.env.AUTH_SECRET || DEFAULT_SECRET;
2576
2600
  const cookies = getCookies(options);
2601
+ const tables = getAuthTables(options);
2577
2602
  return {
2578
2603
  appName: options.appName || "Better Auth",
2579
2604
  options: {
@@ -2581,6 +2606,7 @@ var init = (options) => {
2581
2606
  baseURL: baseURL ? new URL(baseURL).origin : "",
2582
2607
  basePath: options.basePath || "/api/auth"
2583
2608
  },
2609
+ tables,
2584
2610
  baseURL: baseURL || "",
2585
2611
  session: {
2586
2612
  updateAge: options.session?.updateAge || 24 * 60 * 60,
@@ -2599,7 +2625,7 @@ var init = (options) => {
2599
2625
  verify: options.emailAndPassword?.password?.verify || verifyPassword
2600
2626
  },
2601
2627
  adapter,
2602
- internalAdapter: createInternalAdapter(adapter, options),
2628
+ internalAdapter: createInternalAdapter(adapter, db, options),
2603
2629
  createAuthCookie: createCookieGetter(options)
2604
2630
  };
2605
2631
  };