@convex-dev/better-auth 0.10.6 → 0.10.8
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/auth-options.d.ts +1 -1
- package/dist/auth-options.d.ts.map +1 -1
- package/dist/auth.js +1 -1
- package/dist/auth.js.map +1 -1
- package/dist/client/adapter-utils.d.ts +3 -3
- package/dist/client/adapter-utils.js +1 -1
- package/dist/client/adapter-utils.js.map +1 -1
- package/dist/client/adapter.d.ts.map +1 -1
- package/dist/client/adapter.js +14 -13
- package/dist/client/adapter.js.map +1 -1
- package/dist/client/create-api.d.ts +4 -2
- package/dist/client/create-api.d.ts.map +1 -1
- package/dist/client/create-api.js +2 -0
- package/dist/client/create-api.js.map +1 -1
- package/dist/client/create-client.d.ts.map +1 -1
- package/dist/client/create-client.js +3 -0
- package/dist/client/create-client.js.map +1 -1
- package/dist/component/_generated/component.d.ts +4 -8
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/adapter.d.ts +3 -1
- package/dist/component/adapter.d.ts.map +1 -1
- package/dist/component/adapterTest.d.ts +8 -15
- package/dist/component/adapterTest.d.ts.map +1 -1
- package/dist/component/adapterTest.js +393 -61
- package/dist/component/adapterTest.js.map +1 -1
- package/dist/nextjs/index.js +1 -1
- package/dist/nextjs/index.js.map +1 -1
- package/dist/plugins/convex/index.d.ts +2 -1
- package/dist/plugins/convex/index.d.ts.map +1 -1
- package/dist/plugins/convex/index.js +5 -3
- package/dist/plugins/convex/index.js.map +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +0 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react-start/index.js +1 -1
- package/dist/react-start/index.js.map +1 -1
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +4 -3
- package/src/auth-options.ts +1 -1
- package/src/auth.ts +1 -1
- package/src/client/adapter-utils.ts +1 -1
- package/src/client/adapter.test.ts +24 -440
- package/src/client/adapter.ts +18 -14
- package/src/client/create-api.ts +3 -1
- package/src/client/create-client.ts +3 -0
- package/src/component/_generated/component.ts +4 -8
- package/src/component/adapterTest.ts +470 -99
- package/src/nextjs/index.ts +1 -1
- package/src/plugins/convex/index.ts +6 -4
- package/src/react/index.tsx +0 -2
- package/src/react-start/index.ts +1 -1
- package/src/utils/index.ts +3 -1
|
@@ -1,116 +1,487 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { runAdapterTest } from "better-auth/adapters/test";
|
|
2
|
+
import { createClient } from "../client/index.js";
|
|
2
3
|
import type { GenericCtx } from "../client/index.js";
|
|
3
4
|
import { api } from "./_generated/api.js";
|
|
4
|
-
import {
|
|
5
|
+
import { action } from "./_generated/server.js";
|
|
6
|
+
import type { GenericActionCtx } from "convex/server";
|
|
7
|
+
import type { DataModel } from "./_generated/dataModel.js";
|
|
8
|
+
import type { BetterAuthOptions } from "better-auth";
|
|
9
|
+
import type { EmptyObject } from "convex-helpers";
|
|
5
10
|
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
RegisteredQuery,
|
|
11
|
-
} from "convex/server";
|
|
11
|
+
beforeEach as beforeEachType,
|
|
12
|
+
expect as expectType,
|
|
13
|
+
test as testType,
|
|
14
|
+
} from "vitest";
|
|
12
15
|
|
|
13
|
-
export const
|
|
16
|
+
export const getAdapter: (
|
|
14
17
|
ctx: GenericCtx<DataModel>
|
|
15
|
-
) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
export const serialize = (data: any) => {
|
|
34
|
-
if (!data) {
|
|
35
|
-
return data;
|
|
36
|
-
}
|
|
37
|
-
return Object.fromEntries(
|
|
38
|
-
Object.entries(data).map(([key, value]) => [
|
|
39
|
-
key,
|
|
40
|
-
value instanceof Date ? value.toISOString() : value,
|
|
41
|
-
])
|
|
42
|
-
);
|
|
43
|
-
};
|
|
18
|
+
) => Parameters<typeof runAdapterTest>[0]["getAdapter"] =
|
|
19
|
+
(ctx: GenericCtx<DataModel>) =>
|
|
20
|
+
async (opts?: Omit<BetterAuthOptions, "database">) => {
|
|
21
|
+
const authComponent = createClient<DataModel>(api as any, {
|
|
22
|
+
verbose: false,
|
|
23
|
+
});
|
|
24
|
+
const adapterFactory = authComponent.adapter(ctx);
|
|
25
|
+
const options = {
|
|
26
|
+
...(opts ?? {}),
|
|
27
|
+
user: {
|
|
28
|
+
...(opts?.user ?? {}),
|
|
29
|
+
// We don't currently support custom schema for tests, need to find a
|
|
30
|
+
// way to do this.
|
|
31
|
+
fields: undefined,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
return adapterFactory(options);
|
|
35
|
+
};
|
|
44
36
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
// Tests need to run inside of a Convex function to use the Convex adapter
|
|
38
|
+
export const runTests = action(
|
|
39
|
+
async (
|
|
40
|
+
ctx: GenericActionCtx<DataModel>,
|
|
41
|
+
args: { disableTests: Record<string, boolean> }
|
|
42
|
+
) => {
|
|
43
|
+
runAdapterTest({
|
|
44
|
+
getAdapter: getAdapter(ctx),
|
|
45
|
+
disableTests: args.disableTests,
|
|
46
|
+
});
|
|
53
47
|
}
|
|
54
48
|
);
|
|
55
49
|
|
|
56
|
-
export const
|
|
57
|
-
async (ctx:
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
50
|
+
export const runCustomTests = action(
|
|
51
|
+
async (ctx: GenericActionCtx<DataModel>, _args: EmptyObject) => {
|
|
52
|
+
const { beforeEach, test, expect } = await import("vitest");
|
|
53
|
+
runCustomAdapterTests({
|
|
54
|
+
beforeEach,
|
|
55
|
+
test,
|
|
56
|
+
expect,
|
|
57
|
+
getAdapter: getAdapter(ctx),
|
|
58
|
+
});
|
|
61
59
|
}
|
|
62
60
|
);
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
function runCustomAdapterTests({
|
|
63
|
+
beforeEach,
|
|
64
|
+
test,
|
|
65
|
+
expect,
|
|
66
|
+
getAdapter,
|
|
67
|
+
}: {
|
|
68
|
+
getAdapter: Parameters<typeof runAdapterTest>[0]["getAdapter"];
|
|
69
|
+
beforeEach: typeof beforeEachType;
|
|
70
|
+
test: typeof testType;
|
|
71
|
+
expect: typeof expectType;
|
|
72
|
+
}) {
|
|
73
|
+
beforeEach(async () => {
|
|
74
|
+
const adapter = await getAdapter();
|
|
75
|
+
await adapter.deleteMany({
|
|
76
|
+
model: "user",
|
|
77
|
+
where: [],
|
|
78
|
+
});
|
|
79
|
+
await adapter.deleteMany({
|
|
80
|
+
model: "session",
|
|
81
|
+
where: [],
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
test("should handle lone range operators", async () => {
|
|
85
|
+
const adapter = await getAdapter();
|
|
86
|
+
const user = await adapter.create({
|
|
87
|
+
model: "user",
|
|
88
|
+
data: {
|
|
89
|
+
name: "ab",
|
|
90
|
+
email: "a@a.com",
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
expect(
|
|
94
|
+
await adapter.findMany({
|
|
95
|
+
model: "user",
|
|
96
|
+
where: [
|
|
97
|
+
{
|
|
98
|
+
field: "name",
|
|
99
|
+
operator: "lt",
|
|
100
|
+
value: "a",
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
})
|
|
104
|
+
).toEqual([]);
|
|
105
|
+
expect(
|
|
106
|
+
await adapter.findMany({
|
|
107
|
+
model: "user",
|
|
108
|
+
where: [
|
|
109
|
+
{
|
|
110
|
+
field: "name",
|
|
111
|
+
operator: "lte",
|
|
112
|
+
value: "a",
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
})
|
|
116
|
+
).toEqual([]);
|
|
117
|
+
expect(
|
|
118
|
+
await adapter.findMany({
|
|
119
|
+
model: "user",
|
|
120
|
+
where: [
|
|
121
|
+
{
|
|
122
|
+
field: "name",
|
|
123
|
+
operator: "gt",
|
|
124
|
+
value: "a",
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
})
|
|
128
|
+
).toEqual([user]);
|
|
129
|
+
expect(
|
|
130
|
+
await adapter.findMany({
|
|
131
|
+
model: "user",
|
|
132
|
+
where: [
|
|
133
|
+
{
|
|
134
|
+
field: "name",
|
|
135
|
+
operator: "gte",
|
|
136
|
+
value: "ab",
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
})
|
|
140
|
+
).toEqual([user]);
|
|
141
|
+
});
|
|
71
142
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
143
|
+
test("should handle compound indexes that include id field", async () => {
|
|
144
|
+
const adapter = await getAdapter();
|
|
145
|
+
const user = await adapter.create({
|
|
146
|
+
model: "user",
|
|
147
|
+
data: {
|
|
148
|
+
name: "foo",
|
|
149
|
+
email: "foo@bar.com",
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
expect(
|
|
153
|
+
await adapter.findOne({
|
|
154
|
+
model: "user",
|
|
155
|
+
where: [
|
|
156
|
+
{
|
|
157
|
+
field: "id",
|
|
158
|
+
value: user.id,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
field: "name",
|
|
162
|
+
value: "wrong name",
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
})
|
|
166
|
+
).toEqual(null);
|
|
167
|
+
expect(
|
|
168
|
+
await adapter.findOne({
|
|
169
|
+
model: "user",
|
|
170
|
+
where: [
|
|
171
|
+
{
|
|
172
|
+
field: "id",
|
|
173
|
+
value: user.id,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
field: "name",
|
|
177
|
+
value: "foo",
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
})
|
|
181
|
+
).toEqual(user);
|
|
182
|
+
expect(
|
|
183
|
+
await adapter.findOne({
|
|
184
|
+
model: "user",
|
|
185
|
+
where: [
|
|
186
|
+
{
|
|
187
|
+
field: "id",
|
|
188
|
+
value: user.id,
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
field: "name",
|
|
192
|
+
value: "foo",
|
|
193
|
+
operator: "lt",
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
})
|
|
197
|
+
).toEqual(null);
|
|
198
|
+
expect(
|
|
199
|
+
await adapter.findOne({
|
|
200
|
+
model: "user",
|
|
201
|
+
where: [
|
|
202
|
+
{
|
|
203
|
+
field: "id",
|
|
204
|
+
value: user.id,
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
field: "name",
|
|
208
|
+
value: "foo",
|
|
209
|
+
operator: "lte",
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
})
|
|
213
|
+
).toEqual(user);
|
|
214
|
+
expect(
|
|
215
|
+
await adapter.findOne({
|
|
216
|
+
model: "user",
|
|
217
|
+
where: [
|
|
218
|
+
{
|
|
219
|
+
field: "id",
|
|
220
|
+
value: user.id,
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
field: "name",
|
|
224
|
+
value: "foo",
|
|
225
|
+
operator: "gt",
|
|
226
|
+
},
|
|
227
|
+
],
|
|
228
|
+
})
|
|
229
|
+
).toEqual(null);
|
|
230
|
+
expect(
|
|
231
|
+
await adapter.findOne({
|
|
232
|
+
model: "user",
|
|
233
|
+
where: [
|
|
234
|
+
{
|
|
235
|
+
field: "id",
|
|
236
|
+
value: user.id,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
field: "name",
|
|
240
|
+
value: "foo",
|
|
241
|
+
operator: "gte",
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
})
|
|
245
|
+
).toEqual(user);
|
|
246
|
+
expect(
|
|
247
|
+
await adapter.findOne({
|
|
248
|
+
model: "user",
|
|
249
|
+
where: [
|
|
250
|
+
{
|
|
251
|
+
field: "id",
|
|
252
|
+
value: user.id,
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
field: "name",
|
|
256
|
+
operator: "in",
|
|
257
|
+
value: ["wrong", "name"],
|
|
258
|
+
},
|
|
259
|
+
],
|
|
260
|
+
})
|
|
261
|
+
).toEqual(null);
|
|
262
|
+
expect(
|
|
263
|
+
await adapter.findOne({
|
|
264
|
+
model: "user",
|
|
265
|
+
where: [
|
|
266
|
+
{
|
|
267
|
+
field: "id",
|
|
268
|
+
value: user.id,
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
field: "name",
|
|
272
|
+
operator: "in",
|
|
273
|
+
value: ["foo"],
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
})
|
|
277
|
+
).toEqual(user);
|
|
278
|
+
});
|
|
279
|
+
test("should automatically paginate", async () => {
|
|
280
|
+
const adapter = await getAdapter();
|
|
281
|
+
for (let i = 0; i < 300; i++) {
|
|
282
|
+
await adapter.create({
|
|
283
|
+
model: "user",
|
|
284
|
+
data: {
|
|
285
|
+
name: `foo${i}`,
|
|
286
|
+
email: `foo${i}@bar.com`,
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
// Better Auth defaults to a limit of 100
|
|
291
|
+
expect(
|
|
292
|
+
await adapter.findMany({
|
|
293
|
+
model: "user",
|
|
294
|
+
})
|
|
295
|
+
).toHaveLength(100);
|
|
78
296
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
297
|
+
// Pagination has a hardcoded numItems max of 200, this tests that it can handle
|
|
298
|
+
// specified limits beyond that
|
|
299
|
+
expect(
|
|
300
|
+
await adapter.findMany({
|
|
301
|
+
model: "user",
|
|
302
|
+
limit: 250,
|
|
303
|
+
})
|
|
304
|
+
).toHaveLength(250);
|
|
305
|
+
expect(
|
|
306
|
+
await adapter.findMany({
|
|
307
|
+
model: "user",
|
|
308
|
+
limit: 350,
|
|
309
|
+
})
|
|
310
|
+
).toHaveLength(300);
|
|
311
|
+
});
|
|
312
|
+
test("should handle OR where clauses", async () => {
|
|
313
|
+
const adapter = await getAdapter();
|
|
314
|
+
const user = await adapter.create({
|
|
315
|
+
model: "user",
|
|
316
|
+
data: {
|
|
317
|
+
name: "foo",
|
|
318
|
+
email: "foo@bar.com",
|
|
319
|
+
},
|
|
320
|
+
});
|
|
321
|
+
expect(
|
|
322
|
+
await adapter.findOne({
|
|
323
|
+
model: "user",
|
|
324
|
+
where: [
|
|
325
|
+
{ field: "name", value: "bar", connector: "OR" },
|
|
326
|
+
{ field: "name", value: "foo", connector: "OR" },
|
|
327
|
+
],
|
|
328
|
+
})
|
|
329
|
+
).toEqual(user);
|
|
330
|
+
});
|
|
331
|
+
test("should handle OR where clauses with sortBy", async () => {
|
|
332
|
+
const adapter = await getAdapter();
|
|
333
|
+
const fooUser = await adapter.create({
|
|
334
|
+
model: "user",
|
|
335
|
+
data: {
|
|
336
|
+
name: "foo",
|
|
337
|
+
email: "foo@bar.com",
|
|
338
|
+
},
|
|
339
|
+
});
|
|
340
|
+
const barUser = await adapter.create({
|
|
341
|
+
model: "user",
|
|
342
|
+
data: {
|
|
343
|
+
name: "bar",
|
|
344
|
+
email: "bar@bar.com",
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
await adapter.create({
|
|
348
|
+
model: "user",
|
|
349
|
+
data: {
|
|
350
|
+
name: "baz",
|
|
351
|
+
email: "baz@bar.com",
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
expect(
|
|
355
|
+
await adapter.findMany({
|
|
356
|
+
model: "user",
|
|
357
|
+
where: [
|
|
358
|
+
{ field: "name", value: "bar", connector: "OR" },
|
|
359
|
+
{ field: "name", value: "foo", connector: "OR" },
|
|
360
|
+
],
|
|
361
|
+
sortBy: { field: "name", direction: "asc" },
|
|
362
|
+
})
|
|
363
|
+
).toEqual([barUser, fooUser]);
|
|
364
|
+
expect(
|
|
365
|
+
await adapter.findMany({
|
|
366
|
+
model: "user",
|
|
367
|
+
where: [
|
|
368
|
+
{ field: "name", value: "bar", connector: "OR" },
|
|
369
|
+
{ field: "name", value: "foo", connector: "OR" },
|
|
370
|
+
],
|
|
371
|
+
sortBy: { field: "name", direction: "desc" },
|
|
372
|
+
})
|
|
373
|
+
).toEqual([fooUser, barUser]);
|
|
374
|
+
});
|
|
375
|
+
test("should handle count", async () => {
|
|
376
|
+
const adapter = await getAdapter();
|
|
377
|
+
await adapter.create({
|
|
378
|
+
model: "user",
|
|
379
|
+
data: {
|
|
380
|
+
name: "foo",
|
|
381
|
+
email: "foo@bar.com",
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
await adapter.create({
|
|
385
|
+
model: "user",
|
|
386
|
+
data: {
|
|
387
|
+
name: "bar",
|
|
388
|
+
email: "bar@bar.com",
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
expect(
|
|
392
|
+
await adapter.count({
|
|
393
|
+
model: "user",
|
|
394
|
+
where: [{ field: "name", value: "foo" }],
|
|
395
|
+
})
|
|
396
|
+
).toEqual(1);
|
|
397
|
+
});
|
|
398
|
+
test("should handle queries with no index", async () => {
|
|
399
|
+
const adapter = await getAdapter();
|
|
400
|
+
const user = await adapter.create({
|
|
401
|
+
model: "user",
|
|
402
|
+
data: {
|
|
403
|
+
name: "foo",
|
|
404
|
+
email: "foo@bar.com",
|
|
405
|
+
emailVerified: true,
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
expect(
|
|
409
|
+
await adapter.findOne({
|
|
410
|
+
model: "user",
|
|
411
|
+
where: [{ field: "emailVerified", value: true }],
|
|
412
|
+
})
|
|
413
|
+
).toEqual(user);
|
|
414
|
+
expect(
|
|
415
|
+
await adapter.findOne({
|
|
416
|
+
model: "user",
|
|
417
|
+
where: [{ field: "emailVerified", value: false }],
|
|
418
|
+
})
|
|
419
|
+
).toEqual(null);
|
|
420
|
+
});
|
|
89
421
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
422
|
+
test("should handle compound operator on non-unique field without an index", async () => {
|
|
423
|
+
const adapter = await getAdapter();
|
|
424
|
+
await adapter.create({
|
|
425
|
+
model: "account",
|
|
426
|
+
data: {
|
|
427
|
+
accountId: "foo",
|
|
428
|
+
providerId: "bar",
|
|
429
|
+
userId: "baz",
|
|
430
|
+
accessTokenExpiresAt: null,
|
|
431
|
+
createdAt: Date.now(),
|
|
432
|
+
updatedAt: Date.now(),
|
|
433
|
+
},
|
|
434
|
+
});
|
|
435
|
+
expect(
|
|
436
|
+
await adapter.findOne({
|
|
437
|
+
model: "account",
|
|
438
|
+
where: [
|
|
439
|
+
{
|
|
440
|
+
operator: "lt",
|
|
441
|
+
connector: "AND",
|
|
442
|
+
field: "accessTokenExpiresAt",
|
|
443
|
+
value: Date.now(),
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
operator: "ne",
|
|
447
|
+
connector: "AND",
|
|
448
|
+
field: "accessTokenExpiresAt",
|
|
449
|
+
value: null,
|
|
450
|
+
},
|
|
451
|
+
],
|
|
452
|
+
})
|
|
453
|
+
).toEqual(null);
|
|
454
|
+
});
|
|
98
455
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
456
|
+
test("should fail to create a record with a unique field that already exists", async () => {
|
|
457
|
+
const adapter = await getAdapter();
|
|
458
|
+
await adapter.create({
|
|
459
|
+
model: "user",
|
|
460
|
+
data: { name: "foo", email: "foo@bar.com" },
|
|
461
|
+
});
|
|
462
|
+
await expect(
|
|
463
|
+
adapter.create({
|
|
464
|
+
model: "user",
|
|
465
|
+
data: { name: "foo", email: "foo@bar.com" },
|
|
466
|
+
})
|
|
467
|
+
).rejects.toThrow("user email already exists");
|
|
468
|
+
});
|
|
108
469
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
470
|
+
test("should be able to compare against a date", async () => {
|
|
471
|
+
const adapter = await getAdapter();
|
|
472
|
+
const user = await adapter.create({
|
|
473
|
+
model: "user",
|
|
474
|
+
data: {
|
|
475
|
+
name: "foo",
|
|
476
|
+
email: "foo@bar.com",
|
|
477
|
+
createdAt: new Date().toISOString(),
|
|
478
|
+
},
|
|
479
|
+
});
|
|
480
|
+
expect(
|
|
481
|
+
await adapter.findOne({
|
|
482
|
+
model: "user",
|
|
483
|
+
where: [{ field: "createdAt", value: new Date().toISOString() }],
|
|
484
|
+
})
|
|
485
|
+
).toEqual(user);
|
|
486
|
+
});
|
|
487
|
+
}
|
package/src/nextjs/index.ts
CHANGED
|
@@ -45,7 +45,7 @@ const handler = (request: Request, siteUrl: string) => {
|
|
|
45
45
|
const nextUrl = `${siteUrl}${requestUrl.pathname}${requestUrl.search}`;
|
|
46
46
|
const newRequest = new Request(nextUrl, request);
|
|
47
47
|
newRequest.headers.set("accept-encoding", "application/json");
|
|
48
|
-
newRequest.headers.set("host", siteUrl);
|
|
48
|
+
newRequest.headers.set("host", new URL(siteUrl).host);
|
|
49
49
|
return fetch(newRequest, { method: request.method, redirect: "manual" });
|
|
50
50
|
};
|
|
51
51
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
BetterAuthOptions,
|
|
3
2
|
BetterAuthPlugin,
|
|
4
3
|
Session,
|
|
5
4
|
User,
|
|
6
5
|
} from "better-auth";
|
|
6
|
+
import type { BetterAuthOptions } from "better-auth/minimal";
|
|
7
7
|
import { createAuthMiddleware, sessionMiddleware } from "better-auth/api";
|
|
8
8
|
import {
|
|
9
9
|
createAuthEndpoint,
|
|
@@ -53,6 +53,7 @@ const parseAuthConfig = (authConfig: AuthConfig, opts: { jwks?: string }) => {
|
|
|
53
53
|
);
|
|
54
54
|
}
|
|
55
55
|
if (!isDataUriJwks && opts.jwks) {
|
|
56
|
+
// eslint-disable-next-line no-console
|
|
56
57
|
console.warn(
|
|
57
58
|
"Static JWKS provided to Convex plugin, but not to auth config. This adds an unnecessary network request for token verification."
|
|
58
59
|
);
|
|
@@ -241,8 +242,9 @@ export const convex = (opts: {
|
|
|
241
242
|
return {
|
|
242
243
|
id: "convex",
|
|
243
244
|
init: (ctx) => {
|
|
244
|
-
const { options, logger } = ctx;
|
|
245
|
+
const { options, logger: _logger } = ctx;
|
|
245
246
|
if (options.basePath !== "/api/auth" && !opts.options?.basePath) {
|
|
247
|
+
// eslint-disable-next-line no-console
|
|
246
248
|
console.warn(
|
|
247
249
|
`Better Auth basePath set to ${options.basePath} but no basePath is set in the Convex plugin. This is probably a mistake.`
|
|
248
250
|
);
|
|
@@ -251,6 +253,7 @@ export const convex = (opts: {
|
|
|
251
253
|
opts.options?.basePath &&
|
|
252
254
|
options.basePath !== opts.options?.basePath
|
|
253
255
|
) {
|
|
256
|
+
// eslint-disable-next-line no-console
|
|
254
257
|
console.warn(
|
|
255
258
|
`Better Auth basePath ${options.basePath} does not match Convex plugin basePath ${opts.options?.basePath}. This is probably a mistake.`
|
|
256
259
|
);
|
|
@@ -321,7 +324,6 @@ export const convex = (opts: {
|
|
|
321
324
|
},
|
|
322
325
|
{
|
|
323
326
|
matcher: (ctx) => {
|
|
324
|
-
console.log(ctx.path, ctx.context.session);
|
|
325
327
|
return (
|
|
326
328
|
ctx.path?.startsWith("/sign-out") ||
|
|
327
329
|
ctx.path?.startsWith("/delete-user") ||
|
|
@@ -329,7 +331,6 @@ export const convex = (opts: {
|
|
|
329
331
|
);
|
|
330
332
|
},
|
|
331
333
|
handler: createAuthMiddleware(async (ctx) => {
|
|
332
|
-
console.log("clearing jwt cookie");
|
|
333
334
|
const jwtCookie = ctx.context.createAuthCookie(JWT_COOKIE_NAME, {
|
|
334
335
|
maxAge: 0,
|
|
335
336
|
});
|
|
@@ -579,6 +580,7 @@ export const convex = (opts: {
|
|
|
579
580
|
});
|
|
580
581
|
return await runEndpoint();
|
|
581
582
|
} else {
|
|
583
|
+
// eslint-disable-next-line no-console
|
|
582
584
|
console.error(
|
|
583
585
|
"Try temporarily setting jwksRotateOnTokenGenerationError: true on the Convex Better Auth plugin."
|
|
584
586
|
);
|
package/src/react/index.tsx
CHANGED
|
@@ -180,9 +180,7 @@ class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
|
180
180
|
return { error };
|
|
181
181
|
}
|
|
182
182
|
async componentDidCatch(error: Error) {
|
|
183
|
-
console.log("error", error);
|
|
184
183
|
if (this.props.isAuthError(error)) {
|
|
185
|
-
console.log("unauth");
|
|
186
184
|
await this.props.onUnauth();
|
|
187
185
|
}
|
|
188
186
|
}
|
package/src/react-start/index.ts
CHANGED
|
@@ -64,7 +64,7 @@ const handler = (request: Request, opts: { convexSiteUrl: string }) => {
|
|
|
64
64
|
const nextUrl = `${opts.convexSiteUrl}${requestUrl.pathname}${requestUrl.search}`;
|
|
65
65
|
const headers = new Headers(request.headers);
|
|
66
66
|
headers.set("accept-encoding", "application/json");
|
|
67
|
-
headers.set("host", opts.convexSiteUrl);
|
|
67
|
+
headers.set("host", new URL(opts.convexSiteUrl).host);
|
|
68
68
|
return fetch(nextUrl, {
|
|
69
69
|
method: request.method,
|
|
70
70
|
headers,
|
package/src/utils/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { betterFetch } from "@better-fetch/fetch";
|
|
2
|
-
import type { Auth
|
|
2
|
+
import type { Auth } from "better-auth";
|
|
3
|
+
import type { betterAuth } from "better-auth/minimal";
|
|
3
4
|
import { getSessionCookie } from "better-auth/cookies";
|
|
4
5
|
import type {
|
|
5
6
|
AuthProvider,
|
|
@@ -143,6 +144,7 @@ export const getToken = async (
|
|
|
143
144
|
return { isFresh: false, token };
|
|
144
145
|
}
|
|
145
146
|
} catch (error) {
|
|
147
|
+
// eslint-disable-next-line no-console
|
|
146
148
|
console.error("Error decoding JWT", error);
|
|
147
149
|
}
|
|
148
150
|
return await fetchToken();
|