@convex-dev/better-auth 0.7.11 → 0.7.13

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 (51) hide show
  1. package/README.md +4 -3
  2. package/dist/commonjs/client/index.d.ts +313 -280
  3. package/dist/commonjs/client/index.d.ts.map +1 -1
  4. package/dist/commonjs/client/index.js +4 -5
  5. package/dist/commonjs/client/index.js.map +1 -1
  6. package/dist/commonjs/component/lib.d.ts +113 -97
  7. package/dist/commonjs/component/lib.d.ts.map +1 -1
  8. package/dist/commonjs/component/lib.js +31 -18
  9. package/dist/commonjs/component/lib.js.map +1 -1
  10. package/dist/commonjs/component/schema.d.ts +235 -199
  11. package/dist/commonjs/component/schema.d.ts.map +1 -1
  12. package/dist/commonjs/component/schema.js +125 -102
  13. package/dist/commonjs/component/schema.js.map +1 -1
  14. package/dist/commonjs/component/util.d.ts +491 -404
  15. package/dist/commonjs/component/util.d.ts.map +1 -1
  16. package/dist/commonjs/nextjs/index.d.ts.map +1 -1
  17. package/dist/commonjs/nextjs/index.js +18 -2
  18. package/dist/commonjs/nextjs/index.js.map +1 -1
  19. package/dist/commonjs/plugins/convex/index.d.ts +19 -11
  20. package/dist/commonjs/plugins/convex/index.d.ts.map +1 -1
  21. package/dist/commonjs/plugins/convex/index.js +27 -1
  22. package/dist/commonjs/plugins/convex/index.js.map +1 -1
  23. package/dist/commonjs/react-start/index.d.ts +6 -6
  24. package/dist/esm/client/index.d.ts +313 -280
  25. package/dist/esm/client/index.d.ts.map +1 -1
  26. package/dist/esm/client/index.js +4 -5
  27. package/dist/esm/client/index.js.map +1 -1
  28. package/dist/esm/component/lib.d.ts +113 -97
  29. package/dist/esm/component/lib.d.ts.map +1 -1
  30. package/dist/esm/component/lib.js +31 -18
  31. package/dist/esm/component/lib.js.map +1 -1
  32. package/dist/esm/component/schema.d.ts +235 -199
  33. package/dist/esm/component/schema.d.ts.map +1 -1
  34. package/dist/esm/component/schema.js +125 -102
  35. package/dist/esm/component/schema.js.map +1 -1
  36. package/dist/esm/component/util.d.ts +491 -404
  37. package/dist/esm/component/util.d.ts.map +1 -1
  38. package/dist/esm/nextjs/index.d.ts.map +1 -1
  39. package/dist/esm/nextjs/index.js +18 -2
  40. package/dist/esm/nextjs/index.js.map +1 -1
  41. package/dist/esm/plugins/convex/index.d.ts +19 -11
  42. package/dist/esm/plugins/convex/index.d.ts.map +1 -1
  43. package/dist/esm/plugins/convex/index.js +27 -1
  44. package/dist/esm/plugins/convex/index.js.map +1 -1
  45. package/dist/esm/react-start/index.d.ts +6 -6
  46. package/package.json +5 -5
  47. package/src/client/index.ts +4 -5
  48. package/src/component/lib.ts +42 -27
  49. package/src/component/schema.ts +127 -102
  50. package/src/nextjs/index.ts +23 -2
  51. package/src/plugins/convex/index.ts +28 -1
@@ -10,26 +10,26 @@ const schema = defineSchema({
10
10
  name: v.string(),
11
11
  email: v.string(),
12
12
  emailVerified: v.boolean(),
13
- image: v.optional(v.string()),
13
+ image: v.optional(v.union(v.null(), v.string())),
14
14
  createdAt: v.number(),
15
15
  updatedAt: v.number(),
16
- twoFactorEnabled: v.optional(v.boolean()),
17
- isAnonymous: v.optional(v.boolean()),
18
- username: v.optional(v.string()),
19
- displayUsername: v.optional(v.string()),
20
- phoneNumber: v.optional(v.string()),
21
- phoneNumberVerified: v.optional(v.boolean()),
22
- role: v.optional(v.string()),
23
- banned: v.optional(v.boolean()),
24
- banReason: v.optional(v.string()),
25
- banExpires: v.optional(v.number()),
26
- stripeCustomerId: v.optional(v.string()),
27
- userId: v.optional(v.string()),
16
+ twoFactorEnabled: v.optional(v.union(v.null(), v.boolean())),
17
+ isAnonymous: v.optional(v.union(v.null(), v.boolean())),
18
+ username: v.optional(v.union(v.null(), v.string())),
19
+ displayUsername: v.optional(v.union(v.null(), v.string())),
20
+ phoneNumber: v.optional(v.union(v.null(), v.string())),
21
+ phoneNumberVerified: v.optional(v.union(v.null(), v.boolean())),
22
+ role: v.optional(v.union(v.null(), v.string())),
23
+ banned: v.optional(v.union(v.null(), v.boolean())),
24
+ banReason: v.optional(v.union(v.null(), v.string())),
25
+ banExpires: v.optional(v.union(v.null(), v.number())),
26
+ stripeCustomerId: v.optional(v.union(v.null(), v.string())),
27
+ userId: v.optional(v.union(v.null(), v.string())),
28
+ teamId: v.optional(v.union(v.null(), v.string())),
28
29
  })
29
30
  .index("email_name", ["email","name"])
30
31
  .index("name", ["name"])
31
32
  .index("userId", ["userId"])
32
- .index("email", ["email"])
33
33
  .index("username", ["username"])
34
34
  .index("phoneNumber", ["phoneNumber"]),
35
35
 
@@ -38,11 +38,12 @@ const schema = defineSchema({
38
38
  token: v.string(),
39
39
  createdAt: v.number(),
40
40
  updatedAt: v.number(),
41
- ipAddress: v.optional(v.string()),
42
- userAgent: v.optional(v.string()),
41
+ ipAddress: v.optional(v.union(v.null(), v.string())),
42
+ userAgent: v.optional(v.union(v.null(), v.string())),
43
43
  userId: v.string(),
44
- impersonatedBy: v.optional(v.string()),
45
- activeOrganizationId: v.optional(v.string()),
44
+ impersonatedBy: v.optional(v.union(v.null(), v.string())),
45
+ activeOrganizationId: v.optional(v.union(v.null(), v.string())),
46
+ activeTeamId: v.optional(v.union(v.null(), v.string())),
46
47
  })
47
48
  .index("expiresAt", ["expiresAt"])
48
49
  .index("expiresAt_userId", ["expiresAt","userId"])
@@ -53,13 +54,13 @@ const schema = defineSchema({
53
54
  accountId: v.string(),
54
55
  providerId: v.string(),
55
56
  userId: v.string(),
56
- accessToken: v.optional(v.string()),
57
- refreshToken: v.optional(v.string()),
58
- idToken: v.optional(v.string()),
59
- accessTokenExpiresAt: v.optional(v.number()),
60
- refreshTokenExpiresAt: v.optional(v.number()),
61
- scope: v.optional(v.string()),
62
- password: v.optional(v.string()),
57
+ accessToken: v.optional(v.union(v.null(), v.string())),
58
+ refreshToken: v.optional(v.union(v.null(), v.string())),
59
+ idToken: v.optional(v.union(v.null(), v.string())),
60
+ accessTokenExpiresAt: v.optional(v.union(v.null(), v.number())),
61
+ refreshTokenExpiresAt: v.optional(v.union(v.null(), v.number())),
62
+ scope: v.optional(v.union(v.null(), v.string())),
63
+ password: v.optional(v.union(v.null(), v.string())),
63
64
  createdAt: v.number(),
64
65
  updatedAt: v.number(),
65
66
  })
@@ -72,8 +73,8 @@ const schema = defineSchema({
72
73
  identifier: v.string(),
73
74
  value: v.string(),
74
75
  expiresAt: v.number(),
75
- createdAt: v.optional(v.number()),
76
- updatedAt: v.optional(v.number()),
76
+ createdAt: v.optional(v.union(v.null(), v.number())),
77
+ updatedAt: v.optional(v.union(v.null(), v.number())),
77
78
  })
78
79
  .index("expiresAt", ["expiresAt"])
79
80
  .index("identifier", ["identifier"]),
@@ -86,90 +87,90 @@ const schema = defineSchema({
86
87
  .index("userId", ["userId"]),
87
88
 
88
89
  passkey: defineTable({
89
- name: v.optional(v.string()),
90
+ name: v.optional(v.union(v.null(), v.string())),
90
91
  publicKey: v.string(),
91
92
  userId: v.string(),
92
93
  credentialID: v.string(),
93
94
  counter: v.number(),
94
95
  deviceType: v.string(),
95
96
  backedUp: v.boolean(),
96
- transports: v.optional(v.string()),
97
- createdAt: v.optional(v.number()),
98
- aaguid: v.optional(v.string()),
97
+ transports: v.optional(v.union(v.null(), v.string())),
98
+ createdAt: v.optional(v.union(v.null(), v.number())),
99
+ aaguid: v.optional(v.union(v.null(), v.string())),
99
100
  })
100
101
  .index("credentialID", ["credentialID"])
101
102
  .index("userId", ["userId"]),
102
103
 
103
104
  apikey: defineTable({
104
- name: v.optional(v.string()),
105
- start: v.optional(v.string()),
106
- prefix: v.optional(v.string()),
105
+ name: v.optional(v.union(v.null(), v.string())),
106
+ start: v.optional(v.union(v.null(), v.string())),
107
+ prefix: v.optional(v.union(v.null(), v.string())),
107
108
  key: v.string(),
108
109
  userId: v.string(),
109
- refillInterval: v.optional(v.number()),
110
- refillAmount: v.optional(v.number()),
111
- lastRefillAt: v.optional(v.number()),
112
- enabled: v.optional(v.boolean()),
113
- rateLimitEnabled: v.optional(v.boolean()),
114
- rateLimitTimeWindow: v.optional(v.number()),
115
- rateLimitMax: v.optional(v.number()),
116
- requestCount: v.optional(v.number()),
117
- remaining: v.optional(v.number()),
118
- lastRequest: v.optional(v.number()),
119
- expiresAt: v.optional(v.number()),
110
+ refillInterval: v.optional(v.union(v.null(), v.number())),
111
+ refillAmount: v.optional(v.union(v.null(), v.number())),
112
+ lastRefillAt: v.optional(v.union(v.null(), v.number())),
113
+ enabled: v.optional(v.union(v.null(), v.boolean())),
114
+ rateLimitEnabled: v.optional(v.union(v.null(), v.boolean())),
115
+ rateLimitTimeWindow: v.optional(v.union(v.null(), v.number())),
116
+ rateLimitMax: v.optional(v.union(v.null(), v.number())),
117
+ requestCount: v.optional(v.union(v.null(), v.number())),
118
+ remaining: v.optional(v.union(v.null(), v.number())),
119
+ lastRequest: v.optional(v.union(v.null(), v.number())),
120
+ expiresAt: v.optional(v.union(v.null(), v.number())),
120
121
  createdAt: v.number(),
121
122
  updatedAt: v.number(),
122
- permissions: v.optional(v.string()),
123
- metadata: v.optional(v.string()),
123
+ permissions: v.optional(v.union(v.null(), v.string())),
124
+ metadata: v.optional(v.union(v.null(), v.string())),
124
125
  })
125
126
  .index("key", ["key"])
126
127
  .index("userId", ["userId"]),
127
128
 
128
129
  oauthApplication: defineTable({
129
- name: v.optional(v.string()),
130
- icon: v.optional(v.string()),
131
- metadata: v.optional(v.string()),
132
- clientId: v.optional(v.string()),
133
- clientSecret: v.optional(v.string()),
134
- redirectURLs: v.optional(v.string()),
135
- type: v.optional(v.string()),
136
- disabled: v.optional(v.boolean()),
137
- userId: v.optional(v.string()),
138
- createdAt: v.optional(v.number()),
139
- updatedAt: v.optional(v.number()),
130
+ name: v.optional(v.union(v.null(), v.string())),
131
+ icon: v.optional(v.union(v.null(), v.string())),
132
+ metadata: v.optional(v.union(v.null(), v.string())),
133
+ clientId: v.optional(v.union(v.null(), v.string())),
134
+ clientSecret: v.optional(v.union(v.null(), v.string())),
135
+ redirectURLs: v.optional(v.union(v.null(), v.string())),
136
+ type: v.optional(v.union(v.null(), v.string())),
137
+ disabled: v.optional(v.union(v.null(), v.boolean())),
138
+ userId: v.optional(v.union(v.null(), v.string())),
139
+ createdAt: v.optional(v.union(v.null(), v.number())),
140
+ updatedAt: v.optional(v.union(v.null(), v.number())),
140
141
  })
141
142
  .index("clientId", ["clientId"]),
142
143
 
143
144
  oauthAccessToken: defineTable({
144
- accessToken: v.optional(v.string()),
145
- refreshToken: v.optional(v.string()),
146
- accessTokenExpiresAt: v.optional(v.number()),
147
- refreshTokenExpiresAt: v.optional(v.number()),
148
- clientId: v.optional(v.string()),
149
- userId: v.optional(v.string()),
150
- scopes: v.optional(v.string()),
151
- createdAt: v.optional(v.number()),
152
- updatedAt: v.optional(v.number()),
145
+ accessToken: v.optional(v.union(v.null(), v.string())),
146
+ refreshToken: v.optional(v.union(v.null(), v.string())),
147
+ accessTokenExpiresAt: v.optional(v.union(v.null(), v.number())),
148
+ refreshTokenExpiresAt: v.optional(v.union(v.null(), v.number())),
149
+ clientId: v.optional(v.union(v.null(), v.string())),
150
+ userId: v.optional(v.union(v.null(), v.string())),
151
+ scopes: v.optional(v.union(v.null(), v.string())),
152
+ createdAt: v.optional(v.union(v.null(), v.number())),
153
+ updatedAt: v.optional(v.union(v.null(), v.number())),
153
154
  })
154
155
  .index("accessToken", ["accessToken"])
155
156
  .index("refreshToken", ["refreshToken"]),
156
157
 
157
158
  oauthConsent: defineTable({
158
- clientId: v.optional(v.string()),
159
- userId: v.optional(v.string()),
160
- scopes: v.optional(v.string()),
161
- createdAt: v.optional(v.number()),
162
- updatedAt: v.optional(v.number()),
163
- consentGiven: v.optional(v.boolean()),
159
+ clientId: v.optional(v.union(v.null(), v.string())),
160
+ userId: v.optional(v.union(v.null(), v.string())),
161
+ scopes: v.optional(v.union(v.null(), v.string())),
162
+ createdAt: v.optional(v.union(v.null(), v.number())),
163
+ updatedAt: v.optional(v.union(v.null(), v.number())),
164
+ consentGiven: v.optional(v.union(v.null(), v.boolean())),
164
165
  })
165
166
  .index("clientId_userId", ["clientId","userId"]),
166
167
 
167
168
  organization: defineTable({
168
169
  name: v.string(),
169
- slug: v.optional(v.string()),
170
- logo: v.optional(v.string()),
170
+ slug: v.optional(v.union(v.null(), v.string())),
171
+ logo: v.optional(v.union(v.null(), v.string())),
171
172
  createdAt: v.number(),
172
- metadata: v.optional(v.string()),
173
+ metadata: v.optional(v.union(v.null(), v.string())),
173
174
  })
174
175
  .index("name", ["name"])
175
176
  .index("slug", ["slug"]),
@@ -178,28 +179,23 @@ const schema = defineSchema({
178
179
  organizationId: v.string(),
179
180
  userId: v.string(),
180
181
  role: v.string(),
181
- teamId: v.optional(v.string()),
182
182
  createdAt: v.number(),
183
183
  })
184
184
  .index("organizationId_userId", ["organizationId","userId"])
185
- .index("organizationId", ["organizationId"])
186
185
  .index("userId", ["userId"])
187
- .index("role", ["role"])
188
- .index("teamId", ["teamId"]),
186
+ .index("role", ["role"]),
189
187
 
190
188
  invitation: defineTable({
191
189
  organizationId: v.string(),
192
190
  email: v.string(),
193
- role: v.optional(v.string()),
194
- teamId: v.optional(v.string()),
191
+ role: v.optional(v.union(v.null(), v.string())),
192
+ teamId: v.optional(v.union(v.null(), v.string())),
195
193
  status: v.string(),
196
194
  expiresAt: v.number(),
197
195
  inviterId: v.string(),
198
196
  })
199
197
  .index("email_organizationId_status", ["email","organizationId","status"])
200
198
  .index("organizationId_status", ["organizationId","status"])
201
- .index("organizationId", ["organizationId"])
202
- .index("email", ["email"])
203
199
  .index("role", ["role"])
204
200
  .index("teamId", ["teamId"])
205
201
  .index("status", ["status"])
@@ -209,17 +205,24 @@ const schema = defineSchema({
209
205
  name: v.string(),
210
206
  organizationId: v.string(),
211
207
  createdAt: v.number(),
212
- updatedAt: v.optional(v.number()),
208
+ updatedAt: v.optional(v.union(v.null(), v.number())),
213
209
  })
214
210
  .index("organizationId", ["organizationId"]),
215
211
 
212
+ teamMember: defineTable({
213
+ teamId: v.string(),
214
+ userId: v.string(),
215
+ createdAt: v.optional(v.union(v.null(), v.number())),
216
+ })
217
+ .index("userId", ["userId"]),
218
+
216
219
  ssoProvider: defineTable({
217
220
  issuer: v.string(),
218
- oidcConfig: v.optional(v.string()),
219
- samlConfig: v.optional(v.string()),
220
- userId: v.optional(v.string()),
221
+ oidcConfig: v.optional(v.union(v.null(), v.string())),
222
+ samlConfig: v.optional(v.union(v.null(), v.string())),
223
+ userId: v.optional(v.union(v.null(), v.string())),
221
224
  providerId: v.string(),
222
- organizationId: v.optional(v.string()),
225
+ organizationId: v.optional(v.union(v.null(), v.string())),
223
226
  domain: v.string(),
224
227
  })
225
228
  .index("organizationId", ["organizationId"])
@@ -236,22 +239,31 @@ const schema = defineSchema({
236
239
  subscription: defineTable({
237
240
  plan: v.string(),
238
241
  referenceId: v.string(),
239
- stripeCustomerId: v.optional(v.string()),
240
- stripeSubscriptionId: v.optional(v.string()),
241
- status: v.optional(v.string()),
242
- periodStart: v.optional(v.number()),
243
- periodEnd: v.optional(v.number()),
244
- cancelAtPeriodEnd: v.optional(v.boolean()),
245
- seats: v.optional(v.number()),
242
+ stripeCustomerId: v.optional(v.union(v.null(), v.string())),
243
+ stripeSubscriptionId: v.optional(v.union(v.null(), v.string())),
244
+ status: v.optional(v.union(v.null(), v.string())),
245
+ periodStart: v.optional(v.union(v.null(), v.number())),
246
+ periodEnd: v.optional(v.union(v.null(), v.number())),
247
+ cancelAtPeriodEnd: v.optional(v.union(v.null(), v.boolean())),
248
+ seats: v.optional(v.union(v.null(), v.number())),
246
249
  })
247
250
  .index("stripeSubscriptionId", ["stripeSubscriptionId"])
248
251
  .index("stripeCustomerId", ["stripeCustomerId"])
249
252
  .index("referenceId", ["referenceId"]),
250
253
 
254
+ walletAddress: defineTable({
255
+ userId: v.string(),
256
+ address: v.string(),
257
+ chainId: v.number(),
258
+ isPrimary: v.optional(v.union(v.null(), v.boolean())),
259
+ createdAt: v.number(),
260
+ })
261
+ .index("userId", ["userId"]),
262
+
251
263
  rateLimit: defineTable({
252
- key: v.optional(v.string()),
253
- count: v.optional(v.number()),
254
- lastRequest: v.optional(v.number()),
264
+ key: v.optional(v.union(v.null(), v.string())),
265
+ count: v.optional(v.union(v.null(), v.number())),
266
+ lastRequest: v.optional(v.union(v.null(), v.number())),
255
267
  })
256
268
  .index("key", ["key"]),
257
269
 
@@ -359,9 +371,6 @@ export const specialFields = {
359
371
  },
360
372
  role: {
361
373
  sortable: true
362
- },
363
- teamId: {
364
- sortable: true
365
374
  }
366
375
  },
367
376
  invitation: {
@@ -398,6 +407,14 @@ export const specialFields = {
398
407
  }
399
408
  }
400
409
  },
410
+ teamMember: {
411
+ userId: {
412
+ references: {
413
+ model: "user",
414
+ field: "id"
415
+ }
416
+ }
417
+ },
401
418
  ssoProvider: {
402
419
  userId: {
403
420
  references: {
@@ -408,5 +425,13 @@ export const specialFields = {
408
425
  providerId: {
409
426
  unique: true
410
427
  }
428
+ },
429
+ walletAddress: {
430
+ userId: {
431
+ references: {
432
+ model: "user",
433
+ field: "id"
434
+ }
435
+ }
411
436
  }
412
437
  };
@@ -11,8 +11,29 @@ export const getToken = async (
11
11
  const auth = createAuth({} as any);
12
12
  const createCookie = createCookieGetter(auth.options);
13
13
  const cookie = createCookie(JWT_COOKIE_NAME);
14
- const token = cookieStore.get(cookie.name);
15
- return token?.value;
14
+ const tokenCookie = cookieStore.get(cookie.name);
15
+
16
+ // Warn if there's a secure cookie mismatch between Convex and Next.js
17
+ if (!tokenCookie?.value) {
18
+ const isSecure = cookie.name.startsWith("__Secure-");
19
+ const insecureCookieName = cookie.name.replace("__Secure-", "");
20
+ const insecureCookie = cookieStore.get(insecureCookieName);
21
+ const secureCookieName = isSecure
22
+ ? cookie.name
23
+ : `__Secure-${insecureCookieName}`;
24
+ const secureCookie = cookieStore.get(secureCookieName);
25
+ if (isSecure && insecureCookie) {
26
+ console.warn(
27
+ `Looking for secure cookie ${cookie.name} but found insecure cookie ${insecureCookie.name}`
28
+ );
29
+ }
30
+ if (!isSecure && secureCookie) {
31
+ console.warn(
32
+ `Looking for insecure cookie ${cookie.name} but found secure cookie ${secureCookie.name}`
33
+ );
34
+ }
35
+ }
36
+ return tokenCookie?.value;
16
37
  };
17
38
 
18
39
  const handler = (request: Request, opts?: { convexSiteUrl?: string }) => {
@@ -77,7 +77,34 @@ export const convex = <O extends BetterAuthOptions>(
77
77
  return {
78
78
  id: "convex",
79
79
  hooks: {
80
- before: [...bearer.hooks.before],
80
+ before: [
81
+ {
82
+ matcher: (ctx) => {
83
+ return !!ctx.body?.userId;
84
+ },
85
+ handler: createAuthMiddleware(async (ctx) => {
86
+ const user: { id: string } | null =
87
+ await ctx.context.adapter.findOne({
88
+ model: "user",
89
+ where: [
90
+ {
91
+ field: "userId",
92
+ operator: "eq",
93
+ value: ctx.body?.userId,
94
+ },
95
+ ],
96
+ });
97
+ if (!user) {
98
+ throw new Error("User not found");
99
+ }
100
+ ctx.body.userId = user.id;
101
+ return {
102
+ context: ctx,
103
+ };
104
+ }),
105
+ },
106
+ ...bearer.hooks.before,
107
+ ],
81
108
  after: [
82
109
  ...oidcProvider.hooks.after,
83
110
  {