@robelest/convex-auth 0.0.2-preview.1 → 0.0.2

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 (145) hide show
  1. package/dist/bin.cjs +466 -63
  2. package/dist/client/index.d.ts +211 -30
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js +673 -59
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/component/_generated/api.d.ts +56 -1
  7. package/dist/component/_generated/api.d.ts.map +1 -1
  8. package/dist/component/_generated/api.js.map +1 -1
  9. package/dist/component/_generated/component.d.ts +93 -3
  10. package/dist/component/_generated/component.d.ts.map +1 -1
  11. package/dist/component/convex.config.d.ts.map +1 -1
  12. package/dist/component/convex.config.js +2 -0
  13. package/dist/component/convex.config.js.map +1 -1
  14. package/dist/component/index.d.ts +5 -3
  15. package/dist/component/index.d.ts.map +1 -1
  16. package/dist/component/index.js +5 -3
  17. package/dist/component/index.js.map +1 -1
  18. package/dist/component/portalBridge.d.ts +80 -0
  19. package/dist/component/portalBridge.d.ts.map +1 -0
  20. package/dist/component/portalBridge.js +102 -0
  21. package/dist/component/portalBridge.js.map +1 -0
  22. package/dist/component/public.d.ts +193 -9
  23. package/dist/component/public.d.ts.map +1 -1
  24. package/dist/component/public.js +204 -33
  25. package/dist/component/public.js.map +1 -1
  26. package/dist/component/schema.d.ts +89 -9
  27. package/dist/component/schema.d.ts.map +1 -1
  28. package/dist/component/schema.js +68 -7
  29. package/dist/component/schema.js.map +1 -1
  30. package/dist/providers/{Anonymous.d.ts → anonymous.d.ts} +8 -8
  31. package/dist/providers/{Anonymous.d.ts.map → anonymous.d.ts.map} +1 -1
  32. package/dist/providers/{Anonymous.js → anonymous.js} +9 -10
  33. package/dist/providers/anonymous.js.map +1 -0
  34. package/dist/providers/{ConvexCredentials.d.ts → credentials.d.ts} +11 -11
  35. package/dist/providers/credentials.d.ts.map +1 -0
  36. package/dist/providers/{ConvexCredentials.js → credentials.js} +8 -8
  37. package/dist/providers/credentials.js.map +1 -0
  38. package/dist/providers/{Email.d.ts → email.d.ts} +6 -6
  39. package/dist/providers/email.d.ts.map +1 -0
  40. package/dist/providers/{Email.js → email.js} +6 -6
  41. package/dist/providers/email.js.map +1 -0
  42. package/dist/providers/passkey.d.ts +20 -0
  43. package/dist/providers/passkey.d.ts.map +1 -0
  44. package/dist/providers/passkey.js +32 -0
  45. package/dist/providers/passkey.js.map +1 -0
  46. package/dist/providers/{Password.d.ts → password.d.ts} +10 -10
  47. package/dist/providers/{Password.d.ts.map → password.d.ts.map} +1 -1
  48. package/dist/providers/{Password.js → password.js} +19 -20
  49. package/dist/providers/password.js.map +1 -0
  50. package/dist/providers/{Phone.d.ts → phone.d.ts} +3 -3
  51. package/dist/providers/{Phone.d.ts.map → phone.d.ts.map} +1 -1
  52. package/dist/providers/{Phone.js → phone.js} +3 -3
  53. package/dist/providers/{Phone.js.map → phone.js.map} +1 -1
  54. package/dist/providers/totp.d.ts +14 -0
  55. package/dist/providers/totp.d.ts.map +1 -0
  56. package/dist/providers/totp.js +23 -0
  57. package/dist/providers/totp.js.map +1 -0
  58. package/dist/server/convex-auth.d.ts +243 -0
  59. package/dist/server/convex-auth.d.ts.map +1 -0
  60. package/dist/server/convex-auth.js +365 -0
  61. package/dist/server/convex-auth.js.map +1 -0
  62. package/dist/server/implementation/index.d.ts +153 -166
  63. package/dist/server/implementation/index.d.ts.map +1 -1
  64. package/dist/server/implementation/index.js +162 -105
  65. package/dist/server/implementation/index.js.map +1 -1
  66. package/dist/server/implementation/passkey.d.ts +33 -0
  67. package/dist/server/implementation/passkey.d.ts.map +1 -0
  68. package/dist/server/implementation/passkey.js +450 -0
  69. package/dist/server/implementation/passkey.js.map +1 -0
  70. package/dist/server/implementation/redirects.d.ts.map +1 -1
  71. package/dist/server/implementation/redirects.js +4 -9
  72. package/dist/server/implementation/redirects.js.map +1 -1
  73. package/dist/server/implementation/sessions.d.ts +2 -20
  74. package/dist/server/implementation/sessions.d.ts.map +1 -1
  75. package/dist/server/implementation/sessions.js +2 -20
  76. package/dist/server/implementation/sessions.js.map +1 -1
  77. package/dist/server/implementation/signIn.d.ts +13 -0
  78. package/dist/server/implementation/signIn.d.ts.map +1 -1
  79. package/dist/server/implementation/signIn.js +26 -1
  80. package/dist/server/implementation/signIn.js.map +1 -1
  81. package/dist/server/implementation/totp.d.ts +40 -0
  82. package/dist/server/implementation/totp.d.ts.map +1 -0
  83. package/dist/server/implementation/totp.js +211 -0
  84. package/dist/server/implementation/totp.js.map +1 -0
  85. package/dist/server/index.d.ts +18 -0
  86. package/dist/server/index.d.ts.map +1 -1
  87. package/dist/server/index.js +255 -0
  88. package/dist/server/index.js.map +1 -1
  89. package/dist/server/portal-email.d.ts +19 -0
  90. package/dist/server/portal-email.d.ts.map +1 -0
  91. package/dist/server/portal-email.js +89 -0
  92. package/dist/server/portal-email.js.map +1 -0
  93. package/dist/server/portal.d.ts +116 -0
  94. package/dist/server/portal.d.ts.map +1 -0
  95. package/dist/server/portal.js +294 -0
  96. package/dist/server/portal.js.map +1 -0
  97. package/dist/server/provider_utils.d.ts +1 -1
  98. package/dist/server/provider_utils.d.ts.map +1 -1
  99. package/dist/server/provider_utils.js +39 -1
  100. package/dist/server/provider_utils.js.map +1 -1
  101. package/dist/server/types.d.ts +128 -11
  102. package/dist/server/types.d.ts.map +1 -1
  103. package/package.json +7 -7
  104. package/src/cli/index.ts +48 -6
  105. package/src/cli/portal-link.ts +112 -0
  106. package/src/cli/portal-upload.ts +411 -0
  107. package/src/client/index.ts +823 -109
  108. package/src/component/_generated/api.ts +72 -1
  109. package/src/component/_generated/component.ts +180 -4
  110. package/src/component/convex.config.ts +3 -0
  111. package/src/component/index.ts +5 -10
  112. package/src/component/portalBridge.ts +116 -0
  113. package/src/component/public.ts +231 -37
  114. package/src/component/schema.ts +70 -7
  115. package/src/providers/{Anonymous.ts → anonymous.ts} +10 -11
  116. package/src/providers/{ConvexCredentials.ts → credentials.ts} +11 -11
  117. package/src/providers/{Email.ts → email.ts} +5 -5
  118. package/src/providers/passkey.ts +35 -0
  119. package/src/providers/{Password.ts → password.ts} +22 -27
  120. package/src/providers/{Phone.ts → phone.ts} +2 -2
  121. package/src/providers/totp.ts +26 -0
  122. package/src/server/convex-auth.ts +470 -0
  123. package/src/server/implementation/index.ts +228 -239
  124. package/src/server/implementation/passkey.ts +650 -0
  125. package/src/server/implementation/redirects.ts +4 -11
  126. package/src/server/implementation/sessions.ts +2 -20
  127. package/src/server/implementation/signIn.ts +39 -1
  128. package/src/server/implementation/totp.ts +366 -0
  129. package/src/server/index.ts +373 -0
  130. package/src/server/portal-email.ts +95 -0
  131. package/src/server/portal.ts +375 -0
  132. package/src/server/provider_utils.ts +42 -1
  133. package/src/server/types.ts +161 -10
  134. package/dist/providers/Anonymous.js.map +0 -1
  135. package/dist/providers/ConvexCredentials.d.ts.map +0 -1
  136. package/dist/providers/ConvexCredentials.js.map +0 -1
  137. package/dist/providers/Email.d.ts.map +0 -1
  138. package/dist/providers/Email.js.map +0 -1
  139. package/dist/providers/Password.js.map +0 -1
  140. package/providers/Anonymous/package.json +0 -6
  141. package/providers/ConvexCredentials/package.json +0 -6
  142. package/providers/Email/package.json +0 -6
  143. package/providers/Password/package.json +0 -6
  144. package/providers/Phone/package.json +0 -6
  145. package/server/package.json +0 -6
@@ -1,3 +1,16 @@
1
+ /** List all users. */
2
+ export declare const userList: import("convex/server").RegisteredQuery<"public", {}, Promise<{
3
+ _id: import("convex/values").GenericId<"user">;
4
+ _creationTime: number;
5
+ name?: string | undefined;
6
+ email?: string | undefined;
7
+ phone?: string | undefined;
8
+ image?: string | undefined;
9
+ emailVerificationTime?: number | undefined;
10
+ phoneVerificationTime?: number | undefined;
11
+ isAnonymous?: boolean | undefined;
12
+ extend?: any;
13
+ }[]>>;
1
14
  /** Retrieve a user by their document ID. */
2
15
  export declare const userGetById: import("convex/server").RegisteredQuery<"public", {
3
16
  userId: import("convex/values").GenericId<"user">;
@@ -65,6 +78,19 @@ export declare const userPatch: import("convex/server").RegisteredMutation<"publ
65
78
  userId: import("convex/values").GenericId<"user">;
66
79
  data: any;
67
80
  }, Promise<void>>;
81
+ /** List all accounts for a user. */
82
+ export declare const accountListByUser: import("convex/server").RegisteredQuery<"public", {
83
+ userId: import("convex/values").GenericId<"user">;
84
+ }, Promise<{
85
+ _id: import("convex/values").GenericId<"account">;
86
+ _creationTime: number;
87
+ secret?: string | undefined;
88
+ emailVerified?: string | undefined;
89
+ phoneVerified?: string | undefined;
90
+ userId: import("convex/values").GenericId<"user">;
91
+ provider: string;
92
+ providerAccountId: string;
93
+ }[]>>;
68
94
  /** Look up an account by provider and provider-specific account ID. */
69
95
  export declare const accountGet: import("convex/server").RegisteredQuery<"public", {
70
96
  provider: string;
@@ -108,6 +134,13 @@ export declare const accountPatch: import("convex/server").RegisteredMutation<"p
108
134
  export declare const accountDelete: import("convex/server").RegisteredMutation<"public", {
109
135
  accountId: import("convex/values").GenericId<"account">;
110
136
  }, Promise<void>>;
137
+ /** List all sessions. */
138
+ export declare const sessionList: import("convex/server").RegisteredQuery<"public", {}, Promise<{
139
+ _id: import("convex/values").GenericId<"session">;
140
+ _creationTime: number;
141
+ userId: import("convex/values").GenericId<"user">;
142
+ expirationTime: number;
143
+ }[]>>;
111
144
  /** Create a new session for a user with an expiration time. */
112
145
  export declare const sessionCreate: import("convex/server").RegisteredMutation<"public", {
113
146
  userId: import("convex/values").GenericId<"user">;
@@ -268,6 +301,139 @@ export declare const refreshTokenGetActive: import("convex/server").RegisteredQu
268
301
  expirationTime: number;
269
302
  sessionId: import("convex/values").GenericId<"session">;
270
303
  } | null>>;
304
+ /** Store a new passkey credential for a user. */
305
+ export declare const passkeyInsert: import("convex/server").RegisteredMutation<"public", {
306
+ name?: string | undefined;
307
+ transports?: string[] | undefined;
308
+ userId: import("convex/values").GenericId<"user">;
309
+ credentialId: string;
310
+ publicKey: ArrayBuffer;
311
+ algorithm: number;
312
+ counter: number;
313
+ deviceType: string;
314
+ backedUp: boolean;
315
+ createdAt: number;
316
+ }, Promise<import("convex/values").GenericId<"passkey">>>;
317
+ /** Look up a passkey by its credential ID. */
318
+ export declare const passkeyGetByCredentialId: import("convex/server").RegisteredQuery<"public", {
319
+ credentialId: string;
320
+ }, Promise<{
321
+ _id: import("convex/values").GenericId<"passkey">;
322
+ _creationTime: number;
323
+ name?: string | undefined;
324
+ transports?: string[] | undefined;
325
+ lastUsedAt?: number | undefined;
326
+ userId: import("convex/values").GenericId<"user">;
327
+ credentialId: string;
328
+ publicKey: ArrayBuffer;
329
+ algorithm: number;
330
+ counter: number;
331
+ deviceType: string;
332
+ backedUp: boolean;
333
+ createdAt: number;
334
+ } | null>>;
335
+ /** List all passkeys for a user. */
336
+ export declare const passkeyListByUserId: import("convex/server").RegisteredQuery<"public", {
337
+ userId: import("convex/values").GenericId<"user">;
338
+ }, Promise<{
339
+ _id: import("convex/values").GenericId<"passkey">;
340
+ _creationTime: number;
341
+ name?: string | undefined;
342
+ transports?: string[] | undefined;
343
+ lastUsedAt?: number | undefined;
344
+ userId: import("convex/values").GenericId<"user">;
345
+ credentialId: string;
346
+ publicKey: ArrayBuffer;
347
+ algorithm: number;
348
+ counter: number;
349
+ deviceType: string;
350
+ backedUp: boolean;
351
+ createdAt: number;
352
+ }[]>>;
353
+ /** Update a passkey's counter and last used timestamp after authentication. */
354
+ export declare const passkeyUpdateCounter: import("convex/server").RegisteredMutation<"public", {
355
+ counter: number;
356
+ lastUsedAt: number;
357
+ passkeyId: import("convex/values").GenericId<"passkey">;
358
+ }, Promise<void>>;
359
+ /** Update a passkey's metadata (name). */
360
+ export declare const passkeyUpdateMeta: import("convex/server").RegisteredMutation<"public", {
361
+ data: any;
362
+ passkeyId: import("convex/values").GenericId<"passkey">;
363
+ }, Promise<void>>;
364
+ /** Delete a passkey credential. */
365
+ export declare const passkeyDelete: import("convex/server").RegisteredMutation<"public", {
366
+ passkeyId: import("convex/values").GenericId<"passkey">;
367
+ }, Promise<void>>;
368
+ /** Store a new TOTP enrollment for a user. */
369
+ export declare const totpInsert: import("convex/server").RegisteredMutation<"public", {
370
+ name?: string | undefined;
371
+ secret: ArrayBuffer;
372
+ userId: import("convex/values").GenericId<"user">;
373
+ createdAt: number;
374
+ digits: number;
375
+ period: number;
376
+ verified: boolean;
377
+ }, Promise<import("convex/values").GenericId<"totp">>>;
378
+ /** Get a verified TOTP enrollment for a user (returns first match). */
379
+ export declare const totpGetVerifiedByUserId: import("convex/server").RegisteredQuery<"public", {
380
+ userId: import("convex/values").GenericId<"user">;
381
+ }, Promise<{
382
+ _id: import("convex/values").GenericId<"totp">;
383
+ _creationTime: number;
384
+ name?: string | undefined;
385
+ lastUsedAt?: number | undefined;
386
+ secret: ArrayBuffer;
387
+ userId: import("convex/values").GenericId<"user">;
388
+ createdAt: number;
389
+ digits: number;
390
+ period: number;
391
+ verified: boolean;
392
+ } | null>>;
393
+ /** List all TOTP enrollments for a user. */
394
+ export declare const totpListByUserId: import("convex/server").RegisteredQuery<"public", {
395
+ userId: import("convex/values").GenericId<"user">;
396
+ }, Promise<{
397
+ _id: import("convex/values").GenericId<"totp">;
398
+ _creationTime: number;
399
+ name?: string | undefined;
400
+ lastUsedAt?: number | undefined;
401
+ secret: ArrayBuffer;
402
+ userId: import("convex/values").GenericId<"user">;
403
+ createdAt: number;
404
+ digits: number;
405
+ period: number;
406
+ verified: boolean;
407
+ }[]>>;
408
+ /** Get a TOTP enrollment by its ID. */
409
+ export declare const totpGetById: import("convex/server").RegisteredQuery<"public", {
410
+ totpId: import("convex/values").GenericId<"totp">;
411
+ }, Promise<{
412
+ _id: import("convex/values").GenericId<"totp">;
413
+ _creationTime: number;
414
+ name?: string | undefined;
415
+ lastUsedAt?: number | undefined;
416
+ secret: ArrayBuffer;
417
+ userId: import("convex/values").GenericId<"user">;
418
+ createdAt: number;
419
+ digits: number;
420
+ period: number;
421
+ verified: boolean;
422
+ } | null>>;
423
+ /** Mark a TOTP enrollment as verified (setup complete). */
424
+ export declare const totpMarkVerified: import("convex/server").RegisteredMutation<"public", {
425
+ lastUsedAt: number;
426
+ totpId: import("convex/values").GenericId<"totp">;
427
+ }, Promise<void>>;
428
+ /** Update a TOTP enrollment's last used timestamp. */
429
+ export declare const totpUpdateLastUsed: import("convex/server").RegisteredMutation<"public", {
430
+ lastUsedAt: number;
431
+ totpId: import("convex/values").GenericId<"totp">;
432
+ }, Promise<void>>;
433
+ /** Delete a TOTP enrollment. */
434
+ export declare const totpDelete: import("convex/server").RegisteredMutation<"public", {
435
+ totpId: import("convex/values").GenericId<"totp">;
436
+ }, Promise<void>>;
271
437
  /** Look up a rate limit entry by its identifier. */
272
438
  export declare const rateLimitGet: import("convex/server").RegisteredQuery<"public", {
273
439
  identifier: string;
@@ -445,14 +611,14 @@ export declare const memberUpdate: import("convex/server").RegisteredMutation<"p
445
611
  * @returns The ID of the new invite record.
446
612
  */
447
613
  export declare const inviteCreate: import("convex/server").RegisteredMutation<"public", {
614
+ email?: string | undefined;
448
615
  extend?: any;
449
616
  groupId?: import("convex/values").GenericId<"group"> | undefined;
450
617
  role?: string | undefined;
451
- email: string;
618
+ invitedByUserId?: import("convex/values").GenericId<"user"> | undefined;
619
+ expiresTime?: number | undefined;
452
620
  status: "pending" | "accepted" | "revoked" | "expired";
453
- invitedByUserId: import("convex/values").GenericId<"user">;
454
621
  tokenHash: string;
455
- expiresTime: number;
456
622
  }, Promise<import("convex/values").GenericId<"invite">>>;
457
623
  /** Retrieve an invite by its document ID. Returns `null` if not found. */
458
624
  export declare const inviteGet: import("convex/server").RegisteredQuery<"public", {
@@ -460,16 +626,33 @@ export declare const inviteGet: import("convex/server").RegisteredQuery<"public"
460
626
  }, Promise<{
461
627
  _id: import("convex/values").GenericId<"invite">;
462
628
  _creationTime: number;
629
+ email?: string | undefined;
463
630
  extend?: any;
464
631
  groupId?: import("convex/values").GenericId<"group"> | undefined;
465
632
  role?: string | undefined;
633
+ invitedByUserId?: import("convex/values").GenericId<"user"> | undefined;
634
+ expiresTime?: number | undefined;
635
+ acceptedByUserId?: import("convex/values").GenericId<"user"> | undefined;
636
+ acceptedTime?: number | undefined;
637
+ status: "pending" | "accepted" | "revoked" | "expired";
638
+ tokenHash: string;
639
+ } | null>>;
640
+ /** Retrieve an invite by its token hash. Returns `null` if not found. */
641
+ export declare const inviteGetByTokenHash: import("convex/server").RegisteredQuery<"public", {
642
+ tokenHash: string;
643
+ }, Promise<{
644
+ _id: import("convex/values").GenericId<"invite">;
645
+ _creationTime: number;
646
+ email?: string | undefined;
647
+ extend?: any;
648
+ groupId?: import("convex/values").GenericId<"group"> | undefined;
649
+ role?: string | undefined;
650
+ invitedByUserId?: import("convex/values").GenericId<"user"> | undefined;
651
+ expiresTime?: number | undefined;
466
652
  acceptedByUserId?: import("convex/values").GenericId<"user"> | undefined;
467
653
  acceptedTime?: number | undefined;
468
- email: string;
469
654
  status: "pending" | "accepted" | "revoked" | "expired";
470
- invitedByUserId: import("convex/values").GenericId<"user">;
471
655
  tokenHash: string;
472
- expiresTime: number;
473
656
  } | null>>;
474
657
  /**
475
658
  * List invites, optionally filtered by group and/or status.
@@ -481,16 +664,16 @@ export declare const inviteList: import("convex/server").RegisteredQuery<"public
481
664
  }, Promise<{
482
665
  _id: import("convex/values").GenericId<"invite">;
483
666
  _creationTime: number;
667
+ email?: string | undefined;
484
668
  extend?: any;
485
669
  groupId?: import("convex/values").GenericId<"group"> | undefined;
486
670
  role?: string | undefined;
671
+ invitedByUserId?: import("convex/values").GenericId<"user"> | undefined;
672
+ expiresTime?: number | undefined;
487
673
  acceptedByUserId?: import("convex/values").GenericId<"user"> | undefined;
488
674
  acceptedTime?: number | undefined;
489
- email: string;
490
675
  status: "pending" | "accepted" | "revoked" | "expired";
491
- invitedByUserId: import("convex/values").GenericId<"user">;
492
676
  tokenHash: string;
493
- expiresTime: number;
494
677
  }[]>>;
495
678
  /**
496
679
  * Accept a pending invitation.
@@ -502,6 +685,7 @@ export declare const inviteList: import("convex/server").RegisteredQuery<"public
502
685
  * The caller is responsible for creating the corresponding member record.
503
686
  */
504
687
  export declare const inviteAccept: import("convex/server").RegisteredMutation<"public", {
688
+ acceptedByUserId?: import("convex/values").GenericId<"user"> | undefined;
505
689
  inviteId: import("convex/values").GenericId<"invite">;
506
690
  }, Promise<void>>;
507
691
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/component/public.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/component/public.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,13 @@ import { mutation, query } from "./_generated/server";
3
3
  // ============================================================================
4
4
  // Users
5
5
  // ============================================================================
6
+ /** List all users. */
7
+ export const userList = query({
8
+ args: {},
9
+ handler: async (ctx) => {
10
+ return await ctx.db.query("user").collect();
11
+ },
12
+ });
6
13
  /** Retrieve a user by their document ID. */
7
14
  export const userGetById = query({
8
15
  args: { userId: v.id("user") },
@@ -70,6 +77,16 @@ export const userPatch = mutation({
70
77
  // ============================================================================
71
78
  // Accounts
72
79
  // ============================================================================
80
+ /** List all accounts for a user. */
81
+ export const accountListByUser = query({
82
+ args: { userId: v.id("user") },
83
+ handler: async (ctx, { userId }) => {
84
+ return await ctx.db
85
+ .query("account")
86
+ .withIndex("userIdAndProvider", (q) => q.eq("userId", userId))
87
+ .collect();
88
+ },
89
+ });
73
90
  /** Look up an account by provider and provider-specific account ID. */
74
91
  export const accountGet = query({
75
92
  args: { provider: v.string(), providerAccountId: v.string() },
@@ -116,6 +133,13 @@ export const accountDelete = mutation({
116
133
  // ============================================================================
117
134
  // Sessions
118
135
  // ============================================================================
136
+ /** List all sessions. */
137
+ export const sessionList = query({
138
+ args: {},
139
+ handler: async (ctx) => {
140
+ return await ctx.db.query("session").collect();
141
+ },
142
+ });
119
143
  /** Create a new session for a user with an expiration time. */
120
144
  export const sessionCreate = mutation({
121
145
  args: { userId: v.id("user"), expirationTime: v.number() },
@@ -315,6 +339,135 @@ export const refreshTokenGetActive = query({
315
339
  },
316
340
  });
317
341
  // ============================================================================
342
+ // Passkeys
343
+ // ============================================================================
344
+ /** Store a new passkey credential for a user. */
345
+ export const passkeyInsert = mutation({
346
+ args: {
347
+ userId: v.id("user"),
348
+ credentialId: v.string(),
349
+ publicKey: v.bytes(),
350
+ algorithm: v.number(),
351
+ counter: v.number(),
352
+ transports: v.optional(v.array(v.string())),
353
+ deviceType: v.string(),
354
+ backedUp: v.boolean(),
355
+ name: v.optional(v.string()),
356
+ createdAt: v.number(),
357
+ },
358
+ handler: async (ctx, args) => {
359
+ return await ctx.db.insert("passkey", args);
360
+ },
361
+ });
362
+ /** Look up a passkey by its credential ID. */
363
+ export const passkeyGetByCredentialId = query({
364
+ args: { credentialId: v.string() },
365
+ handler: async (ctx, { credentialId }) => {
366
+ return await ctx.db
367
+ .query("passkey")
368
+ .withIndex("credentialId", (q) => q.eq("credentialId", credentialId))
369
+ .unique();
370
+ },
371
+ });
372
+ /** List all passkeys for a user. */
373
+ export const passkeyListByUserId = query({
374
+ args: { userId: v.id("user") },
375
+ handler: async (ctx, { userId }) => {
376
+ return await ctx.db
377
+ .query("passkey")
378
+ .withIndex("userId", (q) => q.eq("userId", userId))
379
+ .collect();
380
+ },
381
+ });
382
+ /** Update a passkey's counter and last used timestamp after authentication. */
383
+ export const passkeyUpdateCounter = mutation({
384
+ args: { passkeyId: v.id("passkey"), counter: v.number(), lastUsedAt: v.number() },
385
+ handler: async (ctx, { passkeyId, counter, lastUsedAt }) => {
386
+ await ctx.db.patch(passkeyId, { counter, lastUsedAt });
387
+ },
388
+ });
389
+ /** Update a passkey's metadata (name). */
390
+ export const passkeyUpdateMeta = mutation({
391
+ args: { passkeyId: v.id("passkey"), data: v.any() },
392
+ handler: async (ctx, { passkeyId, data }) => {
393
+ await ctx.db.patch(passkeyId, data);
394
+ },
395
+ });
396
+ /** Delete a passkey credential. */
397
+ export const passkeyDelete = mutation({
398
+ args: { passkeyId: v.id("passkey") },
399
+ handler: async (ctx, { passkeyId }) => {
400
+ await ctx.db.delete(passkeyId);
401
+ },
402
+ });
403
+ // ============================================================================
404
+ // TOTP Two-Factor Authentication
405
+ // ============================================================================
406
+ /** Store a new TOTP enrollment for a user. */
407
+ export const totpInsert = mutation({
408
+ args: {
409
+ userId: v.id("user"),
410
+ secret: v.bytes(),
411
+ digits: v.number(),
412
+ period: v.number(),
413
+ verified: v.boolean(),
414
+ name: v.optional(v.string()),
415
+ createdAt: v.number(),
416
+ },
417
+ handler: async (ctx, args) => {
418
+ return await ctx.db.insert("totp", args);
419
+ },
420
+ });
421
+ /** Get a verified TOTP enrollment for a user (returns first match). */
422
+ export const totpGetVerifiedByUserId = query({
423
+ args: { userId: v.id("user") },
424
+ handler: async (ctx, { userId }) => {
425
+ return await ctx.db
426
+ .query("totp")
427
+ .withIndex("userId", (q) => q.eq("userId", userId))
428
+ .filter((q) => q.eq(q.field("verified"), true))
429
+ .first();
430
+ },
431
+ });
432
+ /** List all TOTP enrollments for a user. */
433
+ export const totpListByUserId = query({
434
+ args: { userId: v.id("user") },
435
+ handler: async (ctx, { userId }) => {
436
+ return await ctx.db
437
+ .query("totp")
438
+ .withIndex("userId", (q) => q.eq("userId", userId))
439
+ .collect();
440
+ },
441
+ });
442
+ /** Get a TOTP enrollment by its ID. */
443
+ export const totpGetById = query({
444
+ args: { totpId: v.id("totp") },
445
+ handler: async (ctx, { totpId }) => {
446
+ return await ctx.db.get(totpId);
447
+ },
448
+ });
449
+ /** Mark a TOTP enrollment as verified (setup complete). */
450
+ export const totpMarkVerified = mutation({
451
+ args: { totpId: v.id("totp"), lastUsedAt: v.number() },
452
+ handler: async (ctx, { totpId, lastUsedAt }) => {
453
+ await ctx.db.patch(totpId, { verified: true, lastUsedAt });
454
+ },
455
+ });
456
+ /** Update a TOTP enrollment's last used timestamp. */
457
+ export const totpUpdateLastUsed = mutation({
458
+ args: { totpId: v.id("totp"), lastUsedAt: v.number() },
459
+ handler: async (ctx, { totpId, lastUsedAt }) => {
460
+ await ctx.db.patch(totpId, { lastUsedAt });
461
+ },
462
+ });
463
+ /** Delete a TOTP enrollment. */
464
+ export const totpDelete = mutation({
465
+ args: { totpId: v.id("totp") },
466
+ handler: async (ctx, { totpId }) => {
467
+ await ctx.db.delete(totpId);
468
+ },
469
+ });
470
+ // ============================================================================
318
471
  // Rate Limits
319
472
  // ============================================================================
320
473
  /** Look up a rate limit entry by its identifier. */
@@ -555,44 +708,48 @@ export const memberUpdate = mutation({
555
708
  export const inviteCreate = mutation({
556
709
  args: {
557
710
  groupId: v.optional(v.id("group")),
558
- invitedByUserId: v.id("user"),
559
- email: v.string(),
711
+ invitedByUserId: v.optional(v.id("user")),
712
+ email: v.optional(v.string()),
560
713
  tokenHash: v.string(),
561
714
  role: v.optional(v.string()),
562
715
  status: v.union(v.literal("pending"), v.literal("accepted"), v.literal("revoked"), v.literal("expired")),
563
- expiresTime: v.number(),
716
+ expiresTime: v.optional(v.number()),
564
717
  extend: v.optional(v.any()),
565
718
  },
566
719
  handler: async (ctx, args) => {
567
- if (args.groupId !== undefined) {
568
- const existingGroupInvite = await ctx.db
569
- .query("invite")
570
- .withIndex("groupIdAndStatus", (q) => q.eq("groupId", args.groupId).eq("status", "pending"))
571
- .filter((q) => q.eq(q.field("email"), args.email))
572
- .first();
573
- if (existingGroupInvite !== null) {
574
- throw new ConvexError({
575
- code: "DUPLICATE_INVITE",
576
- message: "A pending invite already exists for this email in this group",
577
- email: args.email,
578
- groupId: args.groupId,
579
- existingInviteId: existingGroupInvite._id,
580
- });
720
+ // Only check for duplicates when an email is provided.
721
+ // CLI-generated invites (no email) are always allowed.
722
+ if (args.email !== undefined) {
723
+ if (args.groupId !== undefined) {
724
+ const existingGroupInvite = await ctx.db
725
+ .query("invite")
726
+ .withIndex("groupIdAndStatus", (q) => q.eq("groupId", args.groupId).eq("status", "pending"))
727
+ .filter((q) => q.eq(q.field("email"), args.email))
728
+ .first();
729
+ if (existingGroupInvite !== null) {
730
+ throw new ConvexError({
731
+ code: "DUPLICATE_INVITE",
732
+ message: "A pending invite already exists for this email in this group",
733
+ email: args.email,
734
+ groupId: args.groupId,
735
+ existingInviteId: existingGroupInvite._id,
736
+ });
737
+ }
581
738
  }
582
- }
583
- else {
584
- const existingPlatformInvite = await ctx.db
585
- .query("invite")
586
- .withIndex("emailAndStatus", (q) => q.eq("email", args.email).eq("status", "pending"))
587
- .filter((q) => q.eq(q.field("groupId"), undefined))
588
- .first();
589
- if (existingPlatformInvite !== null) {
590
- throw new ConvexError({
591
- code: "DUPLICATE_INVITE",
592
- message: "A pending platform invite already exists for this email",
593
- email: args.email,
594
- existingInviteId: existingPlatformInvite._id,
595
- });
739
+ else {
740
+ const existingPlatformInvite = await ctx.db
741
+ .query("invite")
742
+ .withIndex("emailAndStatus", (q) => q.eq("email", args.email).eq("status", "pending"))
743
+ .filter((q) => q.eq(q.field("groupId"), undefined))
744
+ .first();
745
+ if (existingPlatformInvite !== null) {
746
+ throw new ConvexError({
747
+ code: "DUPLICATE_INVITE",
748
+ message: "A pending platform invite already exists for this email",
749
+ email: args.email,
750
+ existingInviteId: existingPlatformInvite._id,
751
+ });
752
+ }
596
753
  }
597
754
  }
598
755
  return await ctx.db.insert("invite", args);
@@ -605,6 +762,16 @@ export const inviteGet = query({
605
762
  return await ctx.db.get(inviteId);
606
763
  },
607
764
  });
765
+ /** Retrieve an invite by its token hash. Returns `null` if not found. */
766
+ export const inviteGetByTokenHash = query({
767
+ args: { tokenHash: v.string() },
768
+ handler: async (ctx, { tokenHash }) => {
769
+ return await ctx.db
770
+ .query("invite")
771
+ .withIndex("tokenHash", (q) => q.eq("tokenHash", tokenHash))
772
+ .unique();
773
+ },
774
+ });
608
775
  /**
609
776
  * List invites, optionally filtered by group and/or status.
610
777
  * Both `groupId` and `status` are optional filters.
@@ -646,8 +813,11 @@ export const inviteList = query({
646
813
  * The caller is responsible for creating the corresponding member record.
647
814
  */
648
815
  export const inviteAccept = mutation({
649
- args: { inviteId: v.id("invite") },
650
- handler: async (ctx, { inviteId }) => {
816
+ args: {
817
+ inviteId: v.id("invite"),
818
+ acceptedByUserId: v.optional(v.id("user")),
819
+ },
820
+ handler: async (ctx, { inviteId, acceptedByUserId }) => {
651
821
  const invite = await ctx.db.get(inviteId);
652
822
  if (invite === null) {
653
823
  throw new ConvexError({
@@ -667,6 +837,7 @@ export const inviteAccept = mutation({
667
837
  await ctx.db.patch(inviteId, {
668
838
  status: "accepted",
669
839
  acceptedTime: Date.now(),
840
+ ...(acceptedByUserId ? { acceptedByUserId } : {}),
670
841
  });
671
842
  },
672
843
  });