better-auth 1.7.17 → 1.7.18
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/db/internal-adapter.mjs +35 -18
- package/dist/package.mjs +1 -1
- package/dist/test-utils/test-instance.mjs +43 -33
- package/package.json +8 -8
|
@@ -38,7 +38,7 @@ const createInternalAdapter = (adapter, ctx) => {
|
|
|
38
38
|
* or `deleteUserSessions` sweeping a user's accumulated preserved rows) would
|
|
39
39
|
* re-match it and re-fire the hooks, re-dispatching back-channel logout.
|
|
40
40
|
*/
|
|
41
|
-
const endPreservedSessions = (where) => {
|
|
41
|
+
const endPreservedSessions = (where, afterEnd) => {
|
|
42
42
|
const liveSessions = [...where, {
|
|
43
43
|
field: "expiresAt",
|
|
44
44
|
value: /* @__PURE__ */ new Date(),
|
|
@@ -51,6 +51,7 @@ const createInternalAdapter = (adapter, ctx) => {
|
|
|
51
51
|
where: liveSessions,
|
|
52
52
|
update: { expiresAt: /* @__PURE__ */ new Date() }
|
|
53
53
|
});
|
|
54
|
+
await afterEnd?.();
|
|
54
55
|
},
|
|
55
56
|
executeMainFn: false
|
|
56
57
|
});
|
|
@@ -91,7 +92,7 @@ const createInternalAdapter = (adapter, ctx) => {
|
|
|
91
92
|
const previousRevokedBefore = Number(await secondaryStorage.get(revokedBeforeKey(userId)));
|
|
92
93
|
await secondaryStorage.set(revokedBeforeKey(userId), String(Math.max(revokedAt, previousRevokedBefore || 0)), revokedBeforeTTL);
|
|
93
94
|
const deletedTokens = new Set(sessionReferences.map((session) => session.token));
|
|
94
|
-
for (const
|
|
95
|
+
for (const token of deletedTokens) await secondaryStorage.delete(token);
|
|
95
96
|
const activeSessionsKey = `active-sessions-${userId}`;
|
|
96
97
|
const currentSessionReferences = await getActiveSessionReferences(userId);
|
|
97
98
|
const now = Date.now();
|
|
@@ -104,9 +105,10 @@ const createInternalAdapter = (adapter, ctx) => {
|
|
|
104
105
|
}
|
|
105
106
|
await secondaryStorage.delete(activeSessionsKey);
|
|
106
107
|
}
|
|
107
|
-
async function queueCachedUserSessionDeletion(userId, sessionReferences
|
|
108
|
+
async function queueCachedUserSessionDeletion(userId, sessionReferences) {
|
|
108
109
|
if (!secondaryStorage) return;
|
|
109
110
|
const references = sessionReferences ?? await getActiveSessionReferences(userId);
|
|
111
|
+
const revokedAt = Date.now();
|
|
110
112
|
await queueAfterTransactionHook(() => deleteCachedUserSessions(userId, references, revokedAt), { onError(error) {
|
|
111
113
|
logger.error("Failed to delete committed user sessions from secondary storage", error);
|
|
112
114
|
} });
|
|
@@ -531,25 +533,40 @@ const createInternalAdapter = (adapter, ctx) => {
|
|
|
531
533
|
}], "account", void 0);
|
|
532
534
|
},
|
|
533
535
|
deleteUserSessions: async (userId) => {
|
|
534
|
-
const revokedAt = Date.now();
|
|
535
536
|
const sessionReferences = await getActiveSessionReferences(userId);
|
|
536
|
-
if (secondaryStorage) {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
537
|
+
if (!secondaryStorage) {
|
|
538
|
+
await deleteManyWithHooks([{
|
|
539
|
+
field: "userId",
|
|
540
|
+
value: userId
|
|
541
|
+
}], "session", void 0);
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
if (!options.session?.storeSessionInDatabase) {
|
|
545
|
+
await queueCachedUserSessionDeletion(userId, sessionReferences);
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
const revokeCachedSessions = async () => queueCachedUserSessionDeletion(userId, [...sessionReferences, ...await getActiveSessionReferences(userId)]);
|
|
549
|
+
if (ctx.options.session?.preserveSessionInDatabase) {
|
|
550
|
+
await endPreservedSessions([{
|
|
551
|
+
field: "userId",
|
|
552
|
+
value: userId
|
|
553
|
+
}], revokeCachedSessions);
|
|
554
|
+
return;
|
|
548
555
|
}
|
|
549
|
-
|
|
556
|
+
await deleteManyWithHooks([{
|
|
550
557
|
field: "userId",
|
|
551
558
|
value: userId
|
|
552
|
-
}], "session",
|
|
559
|
+
}], "session", {
|
|
560
|
+
fn: async (where) => {
|
|
561
|
+
const deleted = await (await getCurrentAdapter(adapter)).deleteMany({
|
|
562
|
+
model: "session",
|
|
563
|
+
where
|
|
564
|
+
});
|
|
565
|
+
await revokeCachedSessions();
|
|
566
|
+
return deleted;
|
|
567
|
+
},
|
|
568
|
+
executeMainFn: false
|
|
569
|
+
});
|
|
553
570
|
},
|
|
554
571
|
deleteSessions: async (sessionTokens) => {
|
|
555
572
|
if (secondaryStorage) {
|
package/dist/package.mjs
CHANGED
|
@@ -32,6 +32,8 @@ const testPassword = {
|
|
|
32
32
|
async function getTestInstance(options, config) {
|
|
33
33
|
const testWith = config?.testWith || "sqlite";
|
|
34
34
|
const postgresSchema = testWith === "postgres" ? `ba_test_${randomUUID().replaceAll("-", "_")}` : void 0;
|
|
35
|
+
const mysqlServerURL = "mysql://root:root_password@127.0.0.1:3306";
|
|
36
|
+
const mysqlDatabase = testWith === "mysql" ? `ba_test_${randomUUID().replaceAll("-", "_")}` : void 0;
|
|
35
37
|
const quotePostgresIdentifier = (identifier) => `"${identifier.replaceAll("\"", "\"\"")}"`;
|
|
36
38
|
async function getPostgres() {
|
|
37
39
|
const { Kysely, PostgresDialect } = await import("kysely");
|
|
@@ -49,8 +51,14 @@ async function getTestInstance(options, config) {
|
|
|
49
51
|
}
|
|
50
52
|
async function getMysql() {
|
|
51
53
|
const { Kysely, MysqlDialect } = await import("kysely");
|
|
52
|
-
const { createPool } = await import("mysql2
|
|
53
|
-
|
|
54
|
+
const { createConnection, createPool } = await import("mysql2");
|
|
55
|
+
const admin = createConnection(mysqlServerURL).promise();
|
|
56
|
+
try {
|
|
57
|
+
await admin.query(`CREATE DATABASE \`${mysqlDatabase}\``);
|
|
58
|
+
} finally {
|
|
59
|
+
await admin.end();
|
|
60
|
+
}
|
|
61
|
+
return new Kysely({ dialect: new MysqlDialect({ pool: createPool(`${mysqlServerURL}/${mysqlDatabase}`) }) });
|
|
54
62
|
}
|
|
55
63
|
async function mongodbClient() {
|
|
56
64
|
const { MongoClient } = await import("mongodb");
|
|
@@ -64,6 +72,9 @@ async function getTestInstance(options, config) {
|
|
|
64
72
|
};
|
|
65
73
|
return await dbClient("mongodb://127.0.0.1:27017", "better-auth");
|
|
66
74
|
}
|
|
75
|
+
const postgres = testWith === "postgres" ? await getPostgres() : void 0;
|
|
76
|
+
const mysql = testWith === "mysql" ? await getMysql() : void 0;
|
|
77
|
+
const sqlite = testWith === "sqlite" ? await getSqlite() : void 0;
|
|
67
78
|
const opts = {
|
|
68
79
|
socialProviders: {
|
|
69
80
|
github: {
|
|
@@ -76,20 +87,45 @@ async function getTestInstance(options, config) {
|
|
|
76
87
|
}
|
|
77
88
|
},
|
|
78
89
|
secret: "better-auth-secret-that-is-long-enough-for-validation-test",
|
|
79
|
-
database:
|
|
80
|
-
db:
|
|
90
|
+
database: postgres ? {
|
|
91
|
+
db: postgres,
|
|
81
92
|
type: "postgres",
|
|
82
93
|
transaction: config?.transaction
|
|
83
|
-
} : testWith === "mongodb" ? await Promise.all([mongodbClient(), await import("../adapters/mongodb-adapter/index.mjs")]).then(([db, { mongodbAdapter }]) => mongodbAdapter(db)) :
|
|
84
|
-
db:
|
|
94
|
+
} : testWith === "mongodb" ? await Promise.all([mongodbClient(), await import("../adapters/mongodb-adapter/index.mjs")]).then(([db, { mongodbAdapter }]) => mongodbAdapter(db)) : mysql ? {
|
|
95
|
+
db: mysql,
|
|
85
96
|
type: "mysql",
|
|
86
97
|
transaction: config?.transaction
|
|
87
|
-
} :
|
|
98
|
+
} : sqlite,
|
|
88
99
|
emailAndPassword: { enabled: true },
|
|
89
100
|
rateLimit: { enabled: false },
|
|
90
101
|
advanced: { cookies: {} },
|
|
91
102
|
logger: { level: "debug" }
|
|
92
103
|
};
|
|
104
|
+
const cleanup = async () => {
|
|
105
|
+
if (testWith === "mongodb") {
|
|
106
|
+
await (await mongodbClient()).dropDatabase();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (postgres) {
|
|
110
|
+
try {
|
|
111
|
+
if (postgresSchema) await sql.raw(`DROP SCHEMA IF EXISTS ${quotePostgresIdentifier(postgresSchema)} CASCADE`).execute(postgres);
|
|
112
|
+
else await sql`DROP SCHEMA public CASCADE; CREATE SCHEMA public;`.execute(postgres);
|
|
113
|
+
} finally {
|
|
114
|
+
await postgres.destroy();
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (mysql) {
|
|
119
|
+
try {
|
|
120
|
+
await sql.raw(`DROP DATABASE IF EXISTS \`${mysqlDatabase}\``).execute(mysql);
|
|
121
|
+
} finally {
|
|
122
|
+
await mysql.destroy();
|
|
123
|
+
}
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (sqlite) sqlite.close();
|
|
127
|
+
};
|
|
128
|
+
cleanupSet.add(cleanup);
|
|
93
129
|
const authOptions = {
|
|
94
130
|
baseURL: "http://localhost:" + (config?.port || 3e3),
|
|
95
131
|
...opts,
|
|
@@ -126,32 +162,6 @@ async function getTestInstance(options, config) {
|
|
|
126
162
|
});
|
|
127
163
|
}
|
|
128
164
|
await createTestUser();
|
|
129
|
-
const cleanup = async () => {
|
|
130
|
-
if (testWith === "mongodb") {
|
|
131
|
-
await (await mongodbClient()).dropDatabase();
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (testWith === "postgres") {
|
|
135
|
-
const postgres = await getPostgres();
|
|
136
|
-
if (postgresSchema) await sql.raw(`DROP SCHEMA IF EXISTS ${quotePostgresIdentifier(postgresSchema)} CASCADE`).execute(postgres);
|
|
137
|
-
else await sql`DROP SCHEMA public CASCADE; CREATE SCHEMA public;`.execute(postgres);
|
|
138
|
-
await postgres.destroy();
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
if (testWith === "mysql") {
|
|
142
|
-
const mysql = await getMysql();
|
|
143
|
-
await sql`SET FOREIGN_KEY_CHECKS = 0;`.execute(mysql);
|
|
144
|
-
const tables = await mysql.introspection.getTables();
|
|
145
|
-
for (const table of tables) await mysql.deleteFrom(table.name).execute();
|
|
146
|
-
await sql`SET FOREIGN_KEY_CHECKS = 1;`.execute(mysql);
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
if (testWith === "sqlite") {
|
|
150
|
-
(await getSqlite()).close();
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
cleanupSet.add(cleanup);
|
|
155
165
|
const customFetchImpl = async (url, init) => {
|
|
156
166
|
const headers = init?.headers || {};
|
|
157
167
|
const storageHeaders = currentUserContextStorage.getStore()?.headers;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "better-auth",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.18",
|
|
4
4
|
"description": "The most comprehensive authentication framework for TypeScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -503,13 +503,13 @@
|
|
|
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.
|
|
507
|
-
"@better-auth/drizzle-adapter": "1.7.
|
|
508
|
-
"@better-auth/kysely-adapter": "1.7.
|
|
509
|
-
"@better-auth/memory-adapter": "1.7.
|
|
510
|
-
"@better-auth/mongo-adapter": "1.7.
|
|
511
|
-
"@better-auth/prisma-adapter": "1.7.
|
|
512
|
-
"@better-auth/telemetry": "1.7.
|
|
506
|
+
"@better-auth/core": "1.7.18",
|
|
507
|
+
"@better-auth/drizzle-adapter": "1.7.18",
|
|
508
|
+
"@better-auth/kysely-adapter": "1.7.18",
|
|
509
|
+
"@better-auth/memory-adapter": "1.7.18",
|
|
510
|
+
"@better-auth/mongo-adapter": "1.7.18",
|
|
511
|
+
"@better-auth/prisma-adapter": "1.7.18",
|
|
512
|
+
"@better-auth/telemetry": "1.7.18"
|
|
513
513
|
},
|
|
514
514
|
"devDependencies": {
|
|
515
515
|
"@lynx-js/react": "^0.121.2",
|