@robelest/convex-auth 0.0.4-preview.28 → 0.0.4-preview.29

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 (50) hide show
  1. package/dist/bin.js +4 -1
  2. package/dist/component/_generated/component.d.ts +344 -0
  3. package/dist/component/convex.config.d.ts +2 -2
  4. package/dist/component/model.d.ts +25 -25
  5. package/dist/component/model.js +1 -0
  6. package/dist/component/public/factors/totp.js +12 -0
  7. package/dist/component/public/groups/core.js +89 -1
  8. package/dist/component/public/groups/members.js +39 -1
  9. package/dist/component/public/identity/accounts.js +22 -3
  10. package/dist/component/public/identity/users.js +79 -5
  11. package/dist/component/public/sso/audit.js +5 -2
  12. package/dist/component/public/sso/core.js +3 -3
  13. package/dist/component/public/sso/domains.js +7 -3
  14. package/dist/component/public/sso/scim.js +36 -1
  15. package/dist/component/public.js +5 -5
  16. package/dist/component/schema.d.ts +293 -289
  17. package/dist/component/schema.js +2 -1
  18. package/dist/core/index.d.ts +63 -27
  19. package/dist/core/index.js +1 -0
  20. package/dist/providers/credentials.d.ts +12 -0
  21. package/dist/providers/password.js +28 -7
  22. package/dist/server/auth-context.d.ts +17 -0
  23. package/dist/server/auth-context.js +1 -1
  24. package/dist/server/auth.d.ts +18 -6
  25. package/dist/server/auth.js +1 -0
  26. package/dist/server/context.js +11 -5
  27. package/dist/server/contract.js +44 -12
  28. package/dist/server/core.js +146 -149
  29. package/dist/server/ctxCache.js +94 -0
  30. package/dist/server/limits.js +39 -9
  31. package/dist/server/mounts.d.ts +85 -85
  32. package/dist/server/mutations/credentialsSignIn.js +114 -0
  33. package/dist/server/mutations/index.js +2 -1
  34. package/dist/server/mutations/refresh.js +25 -12
  35. package/dist/server/mutations/retrieve.js +2 -1
  36. package/dist/server/mutations/signin.js +27 -9
  37. package/dist/server/mutations/store.js +5 -0
  38. package/dist/server/mutations/verify.js +32 -8
  39. package/dist/server/runtime.d.ts +81 -47
  40. package/dist/server/services/group.js +23 -16
  41. package/dist/server/sessions.d.ts +21 -0
  42. package/dist/server/sessions.js +37 -27
  43. package/dist/server/signin.js +32 -9
  44. package/dist/server/sso/domain.js +1 -2
  45. package/dist/server/sso/oidc.js +1 -1
  46. package/dist/server/tokens.js +19 -3
  47. package/dist/server/users.js +3 -2
  48. package/dist/server/utils/span.js +18 -0
  49. package/package.json +1 -1
  50. package/README.md +0 -161
package/dist/bin.js CHANGED
@@ -6255,7 +6255,10 @@ gradient.pastel = pastel;
6255
6255
  //#region src/cli/keys.ts
6256
6256
  async function generateKeys() {
6257
6257
  try {
6258
- const keys = await generateKeyPair("RS256", { extractable: true });
6258
+ const keys = await generateKeyPair("EdDSA", {
6259
+ crv: "Ed25519",
6260
+ extractable: true
6261
+ });
6259
6262
  const privateKey = await exportPKCS8(keys.privateKey);
6260
6263
  const publicKey = await exportJWK(keys.publicKey);
6261
6264
  const jwks = JSON.stringify({ keys: [{
@@ -16,6 +16,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
16
16
  public: {
17
17
  accountDelete: FunctionReference<"mutation", "internal", {
18
18
  accountId: string;
19
+ requireOtherAccount?: boolean;
19
20
  }, null, Name>;
20
21
  accountGet: FunctionReference<"query", "internal", {
21
22
  provider: string;
@@ -290,6 +291,68 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
290
291
  }, null, Name>;
291
292
  };
292
293
  };
294
+ groupAncestors: FunctionReference<"query", "internal", {
295
+ groupId: string;
296
+ includeSelf?: boolean;
297
+ maxDepth?: number;
298
+ }, {
299
+ ancestors: Array<{
300
+ _creationTime: number;
301
+ _id: string;
302
+ extend?: any;
303
+ isRoot?: boolean;
304
+ name: string;
305
+ parentGroupId?: string;
306
+ policy?: {
307
+ extend?: any;
308
+ identity: {
309
+ accountLinking: {
310
+ oidc: "verifiedEmail" | "none";
311
+ saml: "verifiedEmail" | "none";
312
+ };
313
+ };
314
+ provisioning: {
315
+ deprovision: {
316
+ mode: "soft" | "hard";
317
+ };
318
+ groups: {
319
+ mapping?: Record<string, Array<string>>;
320
+ mode: "ignore" | "sync";
321
+ source: "protocol";
322
+ };
323
+ jit: {
324
+ defaultRole?: string;
325
+ defaultRoleIds?: Array<string>;
326
+ mode: "off" | "createUser" | "createUserAndMembership";
327
+ };
328
+ roles: {
329
+ mapping?: Record<string, Array<string>>;
330
+ mode: "ignore" | "map";
331
+ source: "protocol";
332
+ };
333
+ scimReuse: {
334
+ user: "externalId" | "none";
335
+ };
336
+ user: {
337
+ authority: "app" | "sso" | "scim";
338
+ createOnSignIn: boolean;
339
+ updateProfileFromScim: "never" | "missing" | "always";
340
+ updateProfileOnLogin: "never" | "missing" | "always";
341
+ };
342
+ };
343
+ version: 1;
344
+ };
345
+ rootGroupId?: string;
346
+ slug?: string;
347
+ tags?: Array<{
348
+ key: string;
349
+ value: string;
350
+ }>;
351
+ type?: string;
352
+ }>;
353
+ cycleDetected: boolean;
354
+ maxDepthReached: boolean;
355
+ }, Name>;
293
356
  groupAuditEventCreate: FunctionReference<"mutation", "internal", {
294
357
  actorId?: string;
295
358
  actorType: "user" | "system" | "scim" | "api_key" | "webhook";
@@ -347,6 +410,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
347
410
  }, null, Name>;
348
411
  groupConnectionDomainList: FunctionReference<"query", "internal", {
349
412
  connectionId: string;
413
+ limit?: number;
350
414
  }, Array<{
351
415
  _creationTime: number;
352
416
  _id: string;
@@ -529,6 +593,25 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
529
593
  resourceType: "user" | "group";
530
594
  userId?: string;
531
595
  } | null, Name>;
596
+ groupConnectionScimIdentityGetByGroupConnectionAndUsers: FunctionReference<"query", "internal", {
597
+ connectionId: string;
598
+ userIds: Array<string>;
599
+ }, Array<{
600
+ identity: {
601
+ _creationTime: number;
602
+ _id: string;
603
+ active?: boolean;
604
+ connectionId: string;
605
+ externalId: string;
606
+ groupId: string;
607
+ lastProvisionedAt?: number;
608
+ mappedGroupId?: string;
609
+ raw?: any;
610
+ resourceType: "user" | "group";
611
+ userId?: string;
612
+ } | null;
613
+ userId: string;
614
+ }>, Name>;
532
615
  groupConnectionScimIdentityGetByMappedGroup: FunctionReference<"query", "internal", {
533
616
  mappedGroupId: string;
534
617
  }, {
@@ -682,6 +765,62 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
682
765
  }>;
683
766
  type?: string;
684
767
  } | null, Name>;
768
+ groupGetMany: FunctionReference<"query", "internal", {
769
+ groupIds: Array<string>;
770
+ }, Array<{
771
+ _creationTime: number;
772
+ _id: string;
773
+ extend?: any;
774
+ isRoot?: boolean;
775
+ name: string;
776
+ parentGroupId?: string;
777
+ policy?: {
778
+ extend?: any;
779
+ identity: {
780
+ accountLinking: {
781
+ oidc: "verifiedEmail" | "none";
782
+ saml: "verifiedEmail" | "none";
783
+ };
784
+ };
785
+ provisioning: {
786
+ deprovision: {
787
+ mode: "soft" | "hard";
788
+ };
789
+ groups: {
790
+ mapping?: Record<string, Array<string>>;
791
+ mode: "ignore" | "sync";
792
+ source: "protocol";
793
+ };
794
+ jit: {
795
+ defaultRole?: string;
796
+ defaultRoleIds?: Array<string>;
797
+ mode: "off" | "createUser" | "createUserAndMembership";
798
+ };
799
+ roles: {
800
+ mapping?: Record<string, Array<string>>;
801
+ mode: "ignore" | "map";
802
+ source: "protocol";
803
+ };
804
+ scimReuse: {
805
+ user: "externalId" | "none";
806
+ };
807
+ user: {
808
+ authority: "app" | "sso" | "scim";
809
+ createOnSignIn: boolean;
810
+ updateProfileFromScim: "never" | "missing" | "always";
811
+ updateProfileOnLogin: "never" | "missing" | "always";
812
+ };
813
+ };
814
+ version: 1;
815
+ };
816
+ rootGroupId?: string;
817
+ slug?: string;
818
+ tags?: Array<{
819
+ key: string;
820
+ value: string;
821
+ }>;
822
+ type?: string;
823
+ } | null>, Name>;
685
824
  groupList: FunctionReference<"query", "internal", {
686
825
  cursor?: string | null;
687
826
  limit?: number;
@@ -761,6 +900,68 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
761
900
  }, Name>;
762
901
  groups: {
763
902
  core: {
903
+ groupAncestors: FunctionReference<"query", "internal", {
904
+ groupId: string;
905
+ includeSelf?: boolean;
906
+ maxDepth?: number;
907
+ }, {
908
+ ancestors: Array<{
909
+ _creationTime: number;
910
+ _id: string;
911
+ extend?: any;
912
+ isRoot?: boolean;
913
+ name: string;
914
+ parentGroupId?: string;
915
+ policy?: {
916
+ extend?: any;
917
+ identity: {
918
+ accountLinking: {
919
+ oidc: "verifiedEmail" | "none";
920
+ saml: "verifiedEmail" | "none";
921
+ };
922
+ };
923
+ provisioning: {
924
+ deprovision: {
925
+ mode: "soft" | "hard";
926
+ };
927
+ groups: {
928
+ mapping?: Record<string, Array<string>>;
929
+ mode: "ignore" | "sync";
930
+ source: "protocol";
931
+ };
932
+ jit: {
933
+ defaultRole?: string;
934
+ defaultRoleIds?: Array<string>;
935
+ mode: "off" | "createUser" | "createUserAndMembership";
936
+ };
937
+ roles: {
938
+ mapping?: Record<string, Array<string>>;
939
+ mode: "ignore" | "map";
940
+ source: "protocol";
941
+ };
942
+ scimReuse: {
943
+ user: "externalId" | "none";
944
+ };
945
+ user: {
946
+ authority: "app" | "sso" | "scim";
947
+ createOnSignIn: boolean;
948
+ updateProfileFromScim: "never" | "missing" | "always";
949
+ updateProfileOnLogin: "never" | "missing" | "always";
950
+ };
951
+ };
952
+ version: 1;
953
+ };
954
+ rootGroupId?: string;
955
+ slug?: string;
956
+ tags?: Array<{
957
+ key: string;
958
+ value: string;
959
+ }>;
960
+ type?: string;
961
+ }>;
962
+ cycleDetected: boolean;
963
+ maxDepthReached: boolean;
964
+ }, Name>;
764
965
  groupCreate: FunctionReference<"mutation", "internal", {
765
966
  extend?: any;
766
967
  name: string;
@@ -831,6 +1032,62 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
831
1032
  }>;
832
1033
  type?: string;
833
1034
  } | null, Name>;
1035
+ groupGetMany: FunctionReference<"query", "internal", {
1036
+ groupIds: Array<string>;
1037
+ }, Array<{
1038
+ _creationTime: number;
1039
+ _id: string;
1040
+ extend?: any;
1041
+ isRoot?: boolean;
1042
+ name: string;
1043
+ parentGroupId?: string;
1044
+ policy?: {
1045
+ extend?: any;
1046
+ identity: {
1047
+ accountLinking: {
1048
+ oidc: "verifiedEmail" | "none";
1049
+ saml: "verifiedEmail" | "none";
1050
+ };
1051
+ };
1052
+ provisioning: {
1053
+ deprovision: {
1054
+ mode: "soft" | "hard";
1055
+ };
1056
+ groups: {
1057
+ mapping?: Record<string, Array<string>>;
1058
+ mode: "ignore" | "sync";
1059
+ source: "protocol";
1060
+ };
1061
+ jit: {
1062
+ defaultRole?: string;
1063
+ defaultRoleIds?: Array<string>;
1064
+ mode: "off" | "createUser" | "createUserAndMembership";
1065
+ };
1066
+ roles: {
1067
+ mapping?: Record<string, Array<string>>;
1068
+ mode: "ignore" | "map";
1069
+ source: "protocol";
1070
+ };
1071
+ scimReuse: {
1072
+ user: "externalId" | "none";
1073
+ };
1074
+ user: {
1075
+ authority: "app" | "sso" | "scim";
1076
+ createOnSignIn: boolean;
1077
+ updateProfileFromScim: "never" | "missing" | "always";
1078
+ updateProfileOnLogin: "never" | "missing" | "always";
1079
+ };
1080
+ };
1081
+ version: 1;
1082
+ };
1083
+ rootGroupId?: string;
1084
+ slug?: string;
1085
+ tags?: Array<{
1086
+ key: string;
1087
+ value: string;
1088
+ }>;
1089
+ type?: string;
1090
+ } | null>, Name>;
834
1091
  groupList: FunctionReference<"query", "internal", {
835
1092
  cursor?: string | null;
836
1093
  limit?: number;
@@ -1041,6 +1298,19 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1041
1298
  status?: string;
1042
1299
  userId: string;
1043
1300
  } | null, Name>;
1301
+ memberGetByGroupAndUserMany: FunctionReference<"query", "internal", {
1302
+ groupIds: Array<string>;
1303
+ userId: string;
1304
+ }, Array<{
1305
+ _creationTime: number;
1306
+ _id: string;
1307
+ extend?: any;
1308
+ groupId: string;
1309
+ role?: string;
1310
+ roleIds?: Array<string>;
1311
+ status?: string;
1312
+ userId: string;
1313
+ } | null>, Name>;
1044
1314
  memberList: FunctionReference<"query", "internal", {
1045
1315
  cursor?: string | null;
1046
1316
  limit?: number;
@@ -1200,6 +1470,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1200
1470
  accounts: {
1201
1471
  accountDelete: FunctionReference<"mutation", "internal", {
1202
1472
  accountId: string;
1473
+ requireOtherAccount?: boolean;
1203
1474
  }, null, Name>;
1204
1475
  accountGet: FunctionReference<"query", "internal", {
1205
1476
  provider: string;
@@ -1413,6 +1684,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1413
1684
  };
1414
1685
  users: {
1415
1686
  userDelete: FunctionReference<"mutation", "internal", {
1687
+ cascade?: boolean;
1416
1688
  userId: string;
1417
1689
  }, null, Name>;
1418
1690
  userFindByVerifiedEmail: FunctionReference<"query", "internal", {
@@ -1423,6 +1695,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1423
1695
  email?: string;
1424
1696
  emailVerificationTime?: number;
1425
1697
  extend?: any;
1698
+ hasTotp?: boolean;
1426
1699
  image?: string;
1427
1700
  isAnonymous?: boolean;
1428
1701
  name?: string;
@@ -1437,6 +1710,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1437
1710
  email?: string;
1438
1711
  emailVerificationTime?: number;
1439
1712
  extend?: any;
1713
+ hasTotp?: boolean;
1440
1714
  image?: string;
1441
1715
  isAnonymous?: boolean;
1442
1716
  name?: string;
@@ -1451,12 +1725,28 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1451
1725
  email?: string;
1452
1726
  emailVerificationTime?: number;
1453
1727
  extend?: any;
1728
+ hasTotp?: boolean;
1454
1729
  image?: string;
1455
1730
  isAnonymous?: boolean;
1456
1731
  name?: string;
1457
1732
  phone?: string;
1458
1733
  phoneVerificationTime?: number;
1459
1734
  } | null, Name>;
1735
+ userGetMany: FunctionReference<"query", "internal", {
1736
+ userIds: Array<string>;
1737
+ }, Array<{
1738
+ _creationTime: number;
1739
+ _id: string;
1740
+ email?: string;
1741
+ emailVerificationTime?: number;
1742
+ extend?: any;
1743
+ hasTotp?: boolean;
1744
+ image?: string;
1745
+ isAnonymous?: boolean;
1746
+ name?: string;
1747
+ phone?: string;
1748
+ phoneVerificationTime?: number;
1749
+ } | null>, Name>;
1460
1750
  userInsert: FunctionReference<"mutation", "internal", {
1461
1751
  data: any;
1462
1752
  }, string, Name>;
@@ -1478,6 +1768,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1478
1768
  email?: string;
1479
1769
  emailVerificationTime?: number;
1480
1770
  extend?: any;
1771
+ hasTotp?: boolean;
1481
1772
  image?: string;
1482
1773
  isAnonymous?: boolean;
1483
1774
  name?: string;
@@ -1782,6 +2073,19 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
1782
2073
  status?: string;
1783
2074
  userId: string;
1784
2075
  } | null, Name>;
2076
+ memberGetByGroupAndUserMany: FunctionReference<"query", "internal", {
2077
+ groupIds: Array<string>;
2078
+ userId: string;
2079
+ }, Array<{
2080
+ _creationTime: number;
2081
+ _id: string;
2082
+ extend?: any;
2083
+ groupId: string;
2084
+ role?: string;
2085
+ roleIds?: Array<string>;
2086
+ status?: string;
2087
+ userId: string;
2088
+ } | null>, Name>;
1785
2089
  memberList: FunctionReference<"query", "internal", {
1786
2090
  cursor?: string | null;
1787
2091
  limit?: number;
@@ -2319,6 +2623,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2319
2623
  }, null, Name>;
2320
2624
  groupConnectionDomainList: FunctionReference<"query", "internal", {
2321
2625
  connectionId: string;
2626
+ limit?: number;
2322
2627
  }, Array<{
2323
2628
  _creationTime: number;
2324
2629
  _id: string;
@@ -2442,6 +2747,25 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2442
2747
  resourceType: "user" | "group";
2443
2748
  userId?: string;
2444
2749
  } | null, Name>;
2750
+ groupConnectionScimIdentityGetByGroupConnectionAndUsers: FunctionReference<"query", "internal", {
2751
+ connectionId: string;
2752
+ userIds: Array<string>;
2753
+ }, Array<{
2754
+ identity: {
2755
+ _creationTime: number;
2756
+ _id: string;
2757
+ active?: boolean;
2758
+ connectionId: string;
2759
+ externalId: string;
2760
+ groupId: string;
2761
+ lastProvisionedAt?: number;
2762
+ mappedGroupId?: string;
2763
+ raw?: any;
2764
+ resourceType: "user" | "group";
2765
+ userId?: string;
2766
+ } | null;
2767
+ userId: string;
2768
+ }>, Name>;
2445
2769
  groupConnectionScimIdentityGetByMappedGroup: FunctionReference<"query", "internal", {
2446
2770
  mappedGroupId: string;
2447
2771
  }, {
@@ -2686,6 +3010,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2686
3010
  totpId: string;
2687
3011
  }, null, Name>;
2688
3012
  userDelete: FunctionReference<"mutation", "internal", {
3013
+ cascade?: boolean;
2689
3014
  userId: string;
2690
3015
  }, null, Name>;
2691
3016
  userFindByVerifiedEmail: FunctionReference<"query", "internal", {
@@ -2696,6 +3021,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2696
3021
  email?: string;
2697
3022
  emailVerificationTime?: number;
2698
3023
  extend?: any;
3024
+ hasTotp?: boolean;
2699
3025
  image?: string;
2700
3026
  isAnonymous?: boolean;
2701
3027
  name?: string;
@@ -2710,6 +3036,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2710
3036
  email?: string;
2711
3037
  emailVerificationTime?: number;
2712
3038
  extend?: any;
3039
+ hasTotp?: boolean;
2713
3040
  image?: string;
2714
3041
  isAnonymous?: boolean;
2715
3042
  name?: string;
@@ -2724,12 +3051,28 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2724
3051
  email?: string;
2725
3052
  emailVerificationTime?: number;
2726
3053
  extend?: any;
3054
+ hasTotp?: boolean;
2727
3055
  image?: string;
2728
3056
  isAnonymous?: boolean;
2729
3057
  name?: string;
2730
3058
  phone?: string;
2731
3059
  phoneVerificationTime?: number;
2732
3060
  } | null, Name>;
3061
+ userGetMany: FunctionReference<"query", "internal", {
3062
+ userIds: Array<string>;
3063
+ }, Array<{
3064
+ _creationTime: number;
3065
+ _id: string;
3066
+ email?: string;
3067
+ emailVerificationTime?: number;
3068
+ extend?: any;
3069
+ hasTotp?: boolean;
3070
+ image?: string;
3071
+ isAnonymous?: boolean;
3072
+ name?: string;
3073
+ phone?: string;
3074
+ phoneVerificationTime?: number;
3075
+ } | null>, Name>;
2733
3076
  userInsert: FunctionReference<"mutation", "internal", {
2734
3077
  data: any;
2735
3078
  }, string, Name>;
@@ -2751,6 +3094,7 @@ type ComponentApi<Name extends string | undefined = string | undefined> = {
2751
3094
  email?: string;
2752
3095
  emailVerificationTime?: number;
2753
3096
  extend?: any;
3097
+ hasTotp?: boolean;
2754
3098
  image?: string;
2755
3099
  isAnonymous?: boolean;
2756
3100
  name?: string;
@@ -1,7 +1,7 @@
1
- import * as convex_server0 from "convex/server";
1
+ import * as convex_server7 from "convex/server";
2
2
 
3
3
  //#region src/component/convex.config.d.ts
4
- declare const component: convex_server0.ComponentDefinition<any>;
4
+ declare const component: convex_server7.ComponentDefinition<any>;
5
5
  //#endregion
6
6
  export { component as default };
7
7
  //# sourceMappingURL=convex.config.d.ts.map
@@ -1,7 +1,7 @@
1
- import * as convex_values475 from "convex/values";
1
+ import * as convex_values478 from "convex/values";
2
2
 
3
3
  //#region src/component/model.d.ts
4
- declare const vApiKeyDoc: convex_values475.VObject<{
4
+ declare const vApiKeyDoc: convex_values478.VObject<{
5
5
  lastUsedAt?: number | undefined;
6
6
  expiresAt?: number | undefined;
7
7
  rateLimit?: {
@@ -16,7 +16,7 @@ declare const vApiKeyDoc: convex_values475.VObject<{
16
16
  _creationTime: number;
17
17
  name: string;
18
18
  revoked: boolean;
19
- userId: convex_values475.GenericId<"User">;
19
+ userId: convex_values478.GenericId<"User">;
20
20
  prefix: string;
21
21
  hashedKey: string;
22
22
  scopes: {
@@ -24,43 +24,43 @@ declare const vApiKeyDoc: convex_values475.VObject<{
24
24
  actions: string[];
25
25
  }[];
26
26
  createdAt: number;
27
- _id: convex_values475.GenericId<"ApiKey">;
27
+ _id: convex_values478.GenericId<"ApiKey">;
28
28
  }, {
29
- userId: convex_values475.VId<convex_values475.GenericId<"User">, "required">;
30
- prefix: convex_values475.VString<string, "required">;
31
- hashedKey: convex_values475.VString<string, "required">;
32
- name: convex_values475.VString<string, "required">;
33
- scopes: convex_values475.VArray<{
29
+ userId: convex_values478.VId<convex_values478.GenericId<"User">, "required">;
30
+ prefix: convex_values478.VString<string, "required">;
31
+ hashedKey: convex_values478.VString<string, "required">;
32
+ name: convex_values478.VString<string, "required">;
33
+ scopes: convex_values478.VArray<{
34
34
  resource: string;
35
35
  actions: string[];
36
- }[], convex_values475.VObject<{
36
+ }[], convex_values478.VObject<{
37
37
  resource: string;
38
38
  actions: string[];
39
39
  }, {
40
- resource: convex_values475.VString<string, "required">;
41
- actions: convex_values475.VArray<string[], convex_values475.VString<string, "required">, "required">;
40
+ resource: convex_values478.VString<string, "required">;
41
+ actions: convex_values478.VArray<string[], convex_values478.VString<string, "required">, "required">;
42
42
  }, "required", "resource" | "actions">, "required">;
43
- rateLimit: convex_values475.VObject<{
43
+ rateLimit: convex_values478.VObject<{
44
44
  maxRequests: number;
45
45
  windowMs: number;
46
46
  } | undefined, {
47
- maxRequests: convex_values475.VFloat64<number, "required">;
48
- windowMs: convex_values475.VFloat64<number, "required">;
47
+ maxRequests: convex_values478.VFloat64<number, "required">;
48
+ windowMs: convex_values478.VFloat64<number, "required">;
49
49
  }, "optional", "maxRequests" | "windowMs">;
50
- rateLimitState: convex_values475.VObject<{
50
+ rateLimitState: convex_values478.VObject<{
51
51
  attemptsLeft: number;
52
52
  lastAttemptTime: number;
53
53
  } | undefined, {
54
- attemptsLeft: convex_values475.VFloat64<number, "required">;
55
- lastAttemptTime: convex_values475.VFloat64<number, "required">;
54
+ attemptsLeft: convex_values478.VFloat64<number, "required">;
55
+ lastAttemptTime: convex_values478.VFloat64<number, "required">;
56
56
  }, "optional", "attemptsLeft" | "lastAttemptTime">;
57
- expiresAt: convex_values475.VFloat64<number | undefined, "optional">;
58
- lastUsedAt: convex_values475.VFloat64<number | undefined, "optional">;
59
- createdAt: convex_values475.VFloat64<number, "required">;
60
- revoked: convex_values475.VBoolean<boolean, "required">;
61
- metadata: convex_values475.VAny<any, "optional", string>;
62
- _id: convex_values475.VId<convex_values475.GenericId<"ApiKey">, "required">;
63
- _creationTime: convex_values475.VFloat64<number, "required">;
57
+ expiresAt: convex_values478.VFloat64<number | undefined, "optional">;
58
+ lastUsedAt: convex_values478.VFloat64<number | undefined, "optional">;
59
+ createdAt: convex_values478.VFloat64<number, "required">;
60
+ revoked: convex_values478.VBoolean<boolean, "required">;
61
+ metadata: convex_values478.VAny<any, "optional", string>;
62
+ _id: convex_values478.VId<convex_values478.GenericId<"ApiKey">, "required">;
63
+ _creationTime: convex_values478.VFloat64<number, "required">;
64
64
  }, "required", "_creationTime" | "name" | "revoked" | "lastUsedAt" | "expiresAt" | "userId" | "prefix" | "hashedKey" | "scopes" | "rateLimit" | "rateLimitState" | "createdAt" | "metadata" | "_id" | "rateLimit.maxRequests" | "rateLimit.windowMs" | "rateLimitState.attemptsLeft" | "rateLimitState.lastAttemptTime" | `metadata.${string}`>;
65
65
  //#endregion
66
66
  export { vApiKeyDoc };
@@ -116,6 +116,7 @@ const vUserDoc = v.object({
116
116
  phone: v.optional(v.string()),
117
117
  phoneVerificationTime: v.optional(v.number()),
118
118
  isAnonymous: v.optional(v.boolean()),
119
+ hasTotp: v.optional(v.boolean()),
119
120
  extend: v.optional(v.any())
120
121
  });
121
122
  const vSessionDoc = v.object({
@@ -183,6 +183,11 @@ const totpMarkVerified = mutation({
183
183
  verified: true,
184
184
  lastUsedAt
185
185
  });
186
+ const factor = await ctx.db.get("TotpFactor", totpId);
187
+ if (factor !== null) {
188
+ const user = await ctx.db.get("User", factor.userId);
189
+ if (user !== null && user.hasTotp !== true) await ctx.db.patch("User", factor.userId, { hasTotp: true });
190
+ }
186
191
  return null;
187
192
  }
188
193
  });
@@ -244,7 +249,14 @@ const totpDelete = mutation({
244
249
  args: { totpId: v.id("TotpFactor") },
245
250
  returns: v.null(),
246
251
  handler: async (ctx, { totpId }) => {
252
+ const factor = await ctx.db.get("TotpFactor", totpId);
247
253
  await ctx.db.delete("TotpFactor", totpId);
254
+ if (factor !== null && factor.verified) {
255
+ if (await ctx.db.query("TotpFactor").withIndex("user_id_verified", (q) => q.eq("userId", factor.userId).eq("verified", true)).first() === null) {
256
+ const user = await ctx.db.get("User", factor.userId);
257
+ if (user !== null && user.hasTotp === true) await ctx.db.patch("User", factor.userId, { hasTotp: false });
258
+ }
259
+ }
248
260
  return null;
249
261
  }
250
262
  });