@carlonicora/nextjs-jsonapi 1.40.1 → 1.41.0

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 (165) hide show
  1. package/README.md +3 -3
  2. package/dist/AuthComponent-BuWc2C4g.d.ts +28 -0
  3. package/dist/AuthComponent-fLVGdvSr.d.mts +28 -0
  4. package/dist/{BlockNoteEditor-EKY4AHVK.mjs → BlockNoteEditor-B3RQ4VQ7.mjs} +5 -5
  5. package/dist/{BlockNoteEditor-4G3L3LSF.js → BlockNoteEditor-VUAWVZF4.js} +15 -15
  6. package/dist/{BlockNoteEditor-4G3L3LSF.js.map → BlockNoteEditor-VUAWVZF4.js.map} +1 -1
  7. package/dist/JsonApiRequest-MUPAO7DI.js +24 -0
  8. package/dist/{JsonApiRequest-GR3L56A5.js.map → JsonApiRequest-MUPAO7DI.js.map} +1 -1
  9. package/dist/{JsonApiRequest-K5BRU7RE.mjs → JsonApiRequest-XCQHVVYD.mjs} +2 -2
  10. package/dist/auth.interface-8XglqHir.d.mts +33 -0
  11. package/dist/auth.interface-BJGKQ0zr.d.ts +33 -0
  12. package/dist/billing/index.js +409 -415
  13. package/dist/billing/index.js.map +1 -1
  14. package/dist/billing/index.mjs +4 -10
  15. package/dist/billing/index.mjs.map +1 -1
  16. package/dist/{chunk-BAOP6PTD.mjs → chunk-BJNQZGMN.mjs} +1618 -666
  17. package/dist/chunk-BJNQZGMN.mjs.map +1 -0
  18. package/dist/{chunk-U4MTVHOC.mjs → chunk-GCQUTWZ2.mjs} +11 -4
  19. package/dist/{chunk-U4MTVHOC.mjs.map → chunk-GCQUTWZ2.mjs.map} +1 -1
  20. package/dist/{chunk-ZNGEVB5M.js → chunk-L5F5ZN5F.js} +960 -140
  21. package/dist/chunk-L5F5ZN5F.js.map +1 -0
  22. package/dist/{chunk-RRIYLEY6.mjs → chunk-LBIC4GJK.mjs} +2 -2
  23. package/dist/{chunk-T5YYOT4Z.js → chunk-OODZEX6P.js} +3 -3
  24. package/dist/{chunk-T5YYOT4Z.js.map → chunk-OODZEX6P.js.map} +1 -1
  25. package/dist/{chunk-GVN7XC3U.mjs → chunk-PHNL4QUF.mjs} +835 -15
  26. package/dist/chunk-PHNL4QUF.mjs.map +1 -0
  27. package/dist/{chunk-GKY5DAIH.js → chunk-QPWHMXE2.js} +1505 -553
  28. package/dist/chunk-QPWHMXE2.js.map +1 -0
  29. package/dist/{chunk-FM6WRAN5.js → chunk-WLS4D6VG.js} +12 -5
  30. package/dist/chunk-WLS4D6VG.js.map +1 -0
  31. package/dist/client/index.d.mts +4 -4
  32. package/dist/client/index.d.ts +4 -4
  33. package/dist/client/index.js +5 -5
  34. package/dist/client/index.mjs +4 -4
  35. package/dist/components/index.d.mts +69 -8
  36. package/dist/components/index.d.ts +69 -8
  37. package/dist/components/index.js +27 -5
  38. package/dist/components/index.js.map +1 -1
  39. package/dist/components/index.mjs +26 -4
  40. package/dist/{config-BxwhHdCD.d.mts → config-BW5u1e9P.d.mts} +1 -1
  41. package/dist/{config-BbaBV_yk.d.ts → config-BozK5PY0.d.ts} +1 -1
  42. package/dist/{content.interface-CgUu4771.d.ts → content.interface-CpCDB1Uk.d.ts} +1 -1
  43. package/dist/{content.interface-CWV0q4lZ.d.mts → content.interface-b-mzkL_q.d.mts} +1 -1
  44. package/dist/contexts/index.d.mts +2 -2
  45. package/dist/contexts/index.d.ts +2 -2
  46. package/dist/contexts/index.js +5 -5
  47. package/dist/contexts/index.mjs +4 -4
  48. package/dist/core/index.d.mts +407 -7
  49. package/dist/core/index.d.ts +407 -7
  50. package/dist/core/index.js +61 -3
  51. package/dist/core/index.js.map +1 -1
  52. package/dist/core/index.mjs +60 -2
  53. package/dist/index.d.mts +8 -6
  54. package/dist/index.d.ts +8 -6
  55. package/dist/index.js +62 -4
  56. package/dist/index.js.map +1 -1
  57. package/dist/index.mjs +61 -3
  58. package/dist/{notification.interface-XARGKJAq.d.ts → notification.interface-CR2PuV6Y.d.ts} +1 -0
  59. package/dist/{notification.interface-DIln2r7X.d.mts → notification.interface-D241WNUx.d.mts} +1 -0
  60. package/dist/{s3.service-BoOF5-ln.d.mts → s3.service-D0rbmLFp.d.mts} +10 -31
  61. package/dist/{s3.service-Mxo-7wQ6.d.ts → s3.service-DOwqcUDT.d.ts} +10 -31
  62. package/dist/scripts/generate-web-module/generator.js +26 -26
  63. package/dist/scripts/generate-web-module/generator.js.map +1 -1
  64. package/dist/scripts/generate-web-module/utils/file-writer.js +9 -9
  65. package/dist/scripts/generate-web-module/utils/file-writer.js.map +1 -1
  66. package/dist/server/index.d.mts +4 -3
  67. package/dist/server/index.d.ts +4 -3
  68. package/dist/server/index.js +12 -12
  69. package/dist/server/index.mjs +2 -2
  70. package/dist/{useSocket-awibcC9B.d.ts → useSocket-CC8SkXdm.d.ts} +1 -1
  71. package/dist/{useSocket-BILAdmZ0.d.mts → useSocket-CttIHn2P.d.mts} +1 -1
  72. package/package.json +4 -1
  73. package/scripts/generate-web-module/generator.ts +26 -26
  74. package/scripts/generate-web-module/utils/file-writer.ts +9 -9
  75. package/src/components/pages/PageContentContainer.tsx +22 -9
  76. package/src/core/abstracts/AbstractService.ts +2 -0
  77. package/src/core/factories/JsonApiDataFactory.ts +2 -1
  78. package/src/core/index.ts +14 -0
  79. package/src/core/registry/DataClassRegistry.ts +7 -1
  80. package/src/core/registry/ModuleRegistry.ts +15 -0
  81. package/src/features/auth/backup-code-verify.module.ts +9 -0
  82. package/src/features/auth/components/containers/SecurityContainer.tsx +11 -0
  83. package/src/features/auth/components/containers/index.ts +1 -0
  84. package/src/features/auth/components/forms/Login.tsx +15 -3
  85. package/src/features/auth/components/forms/Register.tsx +1 -9
  86. package/src/features/auth/components/forms/TwoFactorChallenge.tsx +202 -0
  87. package/src/features/auth/components/forms/index.ts +1 -0
  88. package/src/features/auth/components/index.ts +1 -0
  89. package/src/features/auth/components/two-factor/BackupCodesDialog.tsx +148 -0
  90. package/src/features/auth/components/two-factor/DisableTwoFactorDialog.tsx +74 -0
  91. package/src/features/auth/components/two-factor/PasskeyButton.tsx +59 -0
  92. package/src/features/auth/components/two-factor/PasskeyList.tsx +172 -0
  93. package/src/features/auth/components/two-factor/PasskeySetupDialog.tsx +105 -0
  94. package/src/features/auth/components/two-factor/TotpAuthenticatorList.tsx +104 -0
  95. package/src/features/auth/components/two-factor/TotpInput.tsx +90 -0
  96. package/src/features/auth/components/two-factor/TotpSetupDialog.tsx +161 -0
  97. package/src/features/auth/components/two-factor/TwoFactorSettings.tsx +175 -0
  98. package/src/features/auth/components/two-factor/index.ts +9 -0
  99. package/src/features/auth/contexts/AuthContext.tsx +9 -0
  100. package/src/features/auth/data/auth.service.ts +18 -1
  101. package/src/features/auth/data/backup-code-verify.ts +20 -0
  102. package/src/features/auth/data/index.ts +21 -0
  103. package/src/features/auth/data/passkey-authentication-options.interface.ts +7 -0
  104. package/src/features/auth/data/passkey-authentication-options.ts +37 -0
  105. package/src/features/auth/data/passkey-registration-options.ts +46 -0
  106. package/src/features/auth/data/passkey-registration-verify.ts +62 -0
  107. package/src/features/auth/data/passkey-rename.ts +20 -0
  108. package/src/features/auth/data/passkey-verify-login.ts +23 -0
  109. package/src/features/auth/data/passkey.interface.ts +9 -0
  110. package/src/features/auth/data/passkey.ts +40 -0
  111. package/src/features/auth/data/totp-authenticator.interface.ts +7 -0
  112. package/src/features/auth/data/totp-authenticator.ts +28 -0
  113. package/src/features/auth/data/totp-setup.interface.ts +5 -0
  114. package/src/features/auth/data/totp-setup.ts +48 -0
  115. package/src/features/auth/data/totp-verify-login.ts +20 -0
  116. package/src/features/auth/data/totp-verify.ts +22 -0
  117. package/src/features/auth/data/two-factor-challenge.interface.ts +7 -0
  118. package/src/features/auth/data/two-factor-challenge.ts +45 -0
  119. package/src/features/auth/data/two-factor-enable.ts +20 -0
  120. package/src/features/auth/data/two-factor-status.interface.ts +11 -0
  121. package/src/features/auth/data/two-factor-status.ts +40 -0
  122. package/src/features/auth/data/two-factor.service.ts +331 -0
  123. package/src/features/auth/enums/AuthComponent.ts +1 -0
  124. package/src/features/auth/index.ts +13 -0
  125. package/src/features/auth/passkey-authentication-options.module.ts +9 -0
  126. package/src/features/auth/passkey-registration-options.module.ts +9 -0
  127. package/src/features/auth/passkey-registration-verify.module.ts +9 -0
  128. package/src/features/auth/passkey-rename.module.ts +9 -0
  129. package/src/features/auth/passkey-verify-login.module.ts +9 -0
  130. package/src/features/auth/passkey.module.ts +9 -0
  131. package/src/features/auth/totp-authenticator.module.ts +9 -0
  132. package/src/features/auth/totp-setup.module.ts +9 -0
  133. package/src/features/auth/totp-verify-login.module.ts +9 -0
  134. package/src/features/auth/totp-verify.module.ts +9 -0
  135. package/src/features/auth/two-factor-challenge.module.ts +9 -0
  136. package/src/features/auth/two-factor-enable.module.ts +9 -0
  137. package/src/features/auth/two-factor-status.module.ts +9 -0
  138. package/src/features/billing/modules/billing.module.ts +1 -0
  139. package/src/features/billing/stripe-customer/stripe-customer.module.ts +1 -0
  140. package/src/features/billing/stripe-customer/stripe-payment-method.module.ts +1 -0
  141. package/src/features/billing/stripe-invoice/stripe-invoice.module.ts +1 -0
  142. package/src/features/billing/stripe-price/stripe-price.module.ts +1 -0
  143. package/src/features/billing/stripe-product/stripe-product.module.ts +1 -0
  144. package/src/features/billing/stripe-promotion-code/stripe-promotion-code.module.ts +1 -0
  145. package/src/features/billing/stripe-subscription/data/stripe-subscription.ts +0 -5
  146. package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +0 -8
  147. package/src/features/billing/stripe-subscription/stripe-subscription.module.ts +1 -0
  148. package/src/features/billing/stripe-usage/stripe-usage.module.ts +1 -0
  149. package/src/features/user/data/user.interface.ts +1 -0
  150. package/src/features/user/data/user.ts +6 -0
  151. package/src/features/waitlist/data/WaitlistService.ts +1 -8
  152. package/src/features/waitlist/waitlist-stats.module.ts +1 -0
  153. package/src/shadcnui/ui/resizable.tsx +33 -11
  154. package/src/unified/JsonApiRequest.ts +2 -1
  155. package/dist/AuthComponent-hxOPs9o8.d.mts +0 -11
  156. package/dist/AuthComponent-hxOPs9o8.d.ts +0 -11
  157. package/dist/JsonApiRequest-GR3L56A5.js +0 -24
  158. package/dist/chunk-BAOP6PTD.mjs.map +0 -1
  159. package/dist/chunk-FM6WRAN5.js.map +0 -1
  160. package/dist/chunk-GKY5DAIH.js.map +0 -1
  161. package/dist/chunk-GVN7XC3U.mjs.map +0 -1
  162. package/dist/chunk-ZNGEVB5M.js.map +0 -1
  163. /package/dist/{BlockNoteEditor-EKY4AHVK.mjs.map → BlockNoteEditor-B3RQ4VQ7.mjs.map} +0 -0
  164. /package/dist/{JsonApiRequest-K5BRU7RE.mjs.map → JsonApiRequest-XCQHVVYD.mjs.map} +0 -0
  165. /package/dist/{chunk-RRIYLEY6.mjs.map → chunk-LBIC4GJK.mjs.map} +0 -0
@@ -0,0 +1,22 @@
1
+ import { AbstractApiData } from "../../../core";
2
+
3
+ export type TotpVerifyInput = {
4
+ id: string;
5
+ authenticatorId: string;
6
+ code: string;
7
+ };
8
+
9
+ export class TotpVerify extends AbstractApiData {
10
+ createJsonApi(data: TotpVerifyInput) {
11
+ return {
12
+ data: {
13
+ type: "totp-authenticators",
14
+ id: data.id,
15
+ attributes: {
16
+ authenticatorId: data.authenticatorId,
17
+ code: data.code,
18
+ },
19
+ },
20
+ };
21
+ }
22
+ }
@@ -0,0 +1,7 @@
1
+ import { ApiDataInterface } from "../../../core";
2
+
3
+ export interface TwoFactorChallengeInterface extends ApiDataInterface {
4
+ get pendingToken(): string;
5
+ get availableMethods(): ("totp" | "passkey" | "backup")[];
6
+ get expiresAt(): Date;
7
+ }
@@ -0,0 +1,45 @@
1
+ import { AbstractApiData, JsonApiHydratedDataInterface } from "../../../core";
2
+ import { TwoFactorChallengeInterface } from "./two-factor-challenge.interface";
3
+
4
+ export type TwoFactorChallengeInput = {
5
+ id: string;
6
+ method: "totp" | "passkey" | "backup";
7
+ };
8
+
9
+ export class TwoFactorChallenge extends AbstractApiData implements TwoFactorChallengeInterface {
10
+ private _pendingToken: string = "";
11
+ private _availableMethods: ("totp" | "passkey" | "backup")[] = [];
12
+ private _expiresAt: Date = new Date();
13
+
14
+ get pendingToken(): string {
15
+ return this._pendingToken;
16
+ }
17
+
18
+ get availableMethods(): ("totp" | "passkey" | "backup")[] {
19
+ return this._availableMethods;
20
+ }
21
+
22
+ get expiresAt(): Date {
23
+ return this._expiresAt;
24
+ }
25
+
26
+ rehydrate(data: JsonApiHydratedDataInterface): this {
27
+ super.rehydrate(data);
28
+ this._pendingToken = data.jsonApi.attributes.pendingToken ?? "";
29
+ this._availableMethods = data.jsonApi.attributes.availableMethods ?? [];
30
+ this._expiresAt = data.jsonApi.attributes.expiresAt ? new Date(data.jsonApi.attributes.expiresAt) : new Date();
31
+ return this;
32
+ }
33
+
34
+ createJsonApi(data: TwoFactorChallengeInput) {
35
+ return {
36
+ data: {
37
+ type: "two-factor-configs",
38
+ id: data.id,
39
+ attributes: {
40
+ method: data.method,
41
+ },
42
+ },
43
+ };
44
+ }
45
+ }
@@ -0,0 +1,20 @@
1
+ import { AbstractApiData } from "../../../core";
2
+
3
+ export type TwoFactorEnableInput = {
4
+ id: string;
5
+ preferredMethod: "totp" | "passkey";
6
+ };
7
+
8
+ export class TwoFactorEnable extends AbstractApiData {
9
+ createJsonApi(data: TwoFactorEnableInput) {
10
+ return {
11
+ data: {
12
+ type: "two-factor-configs",
13
+ id: data.id,
14
+ attributes: {
15
+ preferredMethod: data.preferredMethod,
16
+ },
17
+ },
18
+ };
19
+ }
20
+ }
@@ -0,0 +1,11 @@
1
+ import { ApiDataInterface } from "../../../core";
2
+ import { TotpAuthenticatorInterface } from "./totp-authenticator.interface";
3
+ import { PasskeyInterface } from "./passkey.interface";
4
+
5
+ export interface TwoFactorStatusInterface extends ApiDataInterface {
6
+ get isEnabled(): boolean;
7
+ get preferredMethod(): "totp" | "passkey" | undefined;
8
+ get totpAuthenticators(): TotpAuthenticatorInterface[];
9
+ get passkeys(): PasskeyInterface[];
10
+ get backupCodesCount(): number;
11
+ }
@@ -0,0 +1,40 @@
1
+ import { AbstractApiData, JsonApiHydratedDataInterface } from "../../../core";
2
+ import { TwoFactorStatusInterface } from "./two-factor-status.interface";
3
+ import { TotpAuthenticatorInterface } from "./totp-authenticator.interface";
4
+ import { PasskeyInterface } from "./passkey.interface";
5
+
6
+ export class TwoFactorStatus extends AbstractApiData implements TwoFactorStatusInterface {
7
+ private _isEnabled: boolean = false;
8
+ private _preferredMethod?: "totp" | "passkey";
9
+ private _totpAuthenticators: TotpAuthenticatorInterface[] = [];
10
+ private _passkeys: PasskeyInterface[] = [];
11
+ private _backupCodesCount: number = 0;
12
+
13
+ get isEnabled(): boolean {
14
+ return this._isEnabled;
15
+ }
16
+
17
+ get preferredMethod(): "totp" | "passkey" | undefined {
18
+ return this._preferredMethod;
19
+ }
20
+
21
+ get totpAuthenticators(): TotpAuthenticatorInterface[] {
22
+ return this._totpAuthenticators;
23
+ }
24
+
25
+ get passkeys(): PasskeyInterface[] {
26
+ return this._passkeys;
27
+ }
28
+
29
+ get backupCodesCount(): number {
30
+ return this._backupCodesCount;
31
+ }
32
+
33
+ rehydrate(data: JsonApiHydratedDataInterface): this {
34
+ super.rehydrate(data);
35
+ this._isEnabled = data.jsonApi.attributes.isEnabled ?? false;
36
+ this._preferredMethod = data.jsonApi.attributes.preferredMethod;
37
+ this._backupCodesCount = data.jsonApi.attributes.backupCodesCount ?? 0;
38
+ return this;
39
+ }
40
+ }
@@ -0,0 +1,331 @@
1
+ import { AuthenticationResponseJSON, RegistrationResponseJSON } from "@simplewebauthn/browser";
2
+ import { AbstractService, EndpointCreator, HttpMethod, Modules } from "../../../core";
3
+ import { getTokenHandler } from "../config";
4
+ import { AuthInterface } from "./auth.interface";
5
+ import { PasskeyInterface } from "./passkey.interface";
6
+ import { PasskeyAuthenticationOptionsInterface } from "./passkey-authentication-options.interface";
7
+ import { PasskeyRegistrationOptionsInterface } from "./passkey-registration-options";
8
+ import { TotpAuthenticatorInterface } from "./totp-authenticator.interface";
9
+ import { TotpSetupInterface } from "./totp-setup.interface";
10
+ import { TwoFactorChallengeInterface } from "./two-factor-challenge.interface";
11
+ import { TwoFactorStatusInterface } from "./two-factor-status.interface";
12
+
13
+ export class TwoFactorService extends AbstractService {
14
+ // ============================================================
15
+ // Status
16
+ // ============================================================
17
+
18
+ static async getStatus(): Promise<TwoFactorStatusInterface> {
19
+ return this.callApi<TwoFactorStatusInterface>({
20
+ type: Modules.TwoFactorStatus,
21
+ method: HttpMethod.GET,
22
+ endpoint: new EndpointCreator({
23
+ endpoint: Modules.Auth,
24
+ id: "two-factor",
25
+ childEndpoint: "status",
26
+ }).generate(),
27
+ });
28
+ }
29
+
30
+ static async enable(params: { id: string; preferredMethod: "totp" | "passkey" }): Promise<void> {
31
+ await this.callApi({
32
+ type: Modules.TwoFactorEnable,
33
+ method: HttpMethod.POST,
34
+ endpoint: new EndpointCreator({
35
+ endpoint: Modules.Auth,
36
+ id: "two-factor",
37
+ childEndpoint: "enable",
38
+ }).generate(),
39
+ input: params,
40
+ });
41
+ }
42
+
43
+ static async disable(params: { code: string }): Promise<void> {
44
+ await this.callApi({
45
+ type: Modules.Auth,
46
+ method: HttpMethod.POST,
47
+ endpoint: new EndpointCreator({
48
+ endpoint: Modules.Auth,
49
+ id: "two-factor",
50
+ childEndpoint: "disable",
51
+ }).generate(),
52
+ input: { code: params.code },
53
+ });
54
+ }
55
+
56
+ // ============================================================
57
+ // TOTP
58
+ // ============================================================
59
+
60
+ static async setupTotp(params: { id: string; name: string; accountName: string }): Promise<TotpSetupInterface> {
61
+ return this.callApi<TotpSetupInterface>({
62
+ type: Modules.TotpSetup,
63
+ method: HttpMethod.POST,
64
+ endpoint: new EndpointCreator({
65
+ endpoint: Modules.Auth,
66
+ id: "totp",
67
+ childEndpoint: "setup",
68
+ }).generate(),
69
+ input: params,
70
+ });
71
+ }
72
+
73
+ static async verifyTotpSetup(params: { id: string; authenticatorId: string; code: string }): Promise<void> {
74
+ await this.callApi({
75
+ type: Modules.TotpVerify,
76
+ method: HttpMethod.POST,
77
+ endpoint: new EndpointCreator({
78
+ endpoint: Modules.Auth,
79
+ id: "totp",
80
+ childEndpoint: "verify-setup",
81
+ }).generate(),
82
+ input: params,
83
+ });
84
+ }
85
+
86
+ static async listTotpAuthenticators(): Promise<TotpAuthenticatorInterface[]> {
87
+ return this.callApi<TotpAuthenticatorInterface[]>({
88
+ type: Modules.TotpAuthenticator,
89
+ method: HttpMethod.GET,
90
+ endpoint: new EndpointCreator({
91
+ endpoint: Modules.Auth,
92
+ id: "totp",
93
+ childEndpoint: "authenticators",
94
+ }).generate(),
95
+ });
96
+ }
97
+
98
+ static async deleteTotpAuthenticator(params: { id: string }): Promise<void> {
99
+ await this.callApi({
100
+ type: Modules.Auth,
101
+ method: HttpMethod.DELETE,
102
+ endpoint: new EndpointCreator({
103
+ endpoint: Modules.Auth,
104
+ id: "totp",
105
+ childEndpoint: "authenticators",
106
+ childId: params.id,
107
+ }).generate(),
108
+ });
109
+ }
110
+
111
+ // ============================================================
112
+ // Passkeys
113
+ // ============================================================
114
+
115
+ static async getPasskeyRegistrationOptions(params: {
116
+ id: string;
117
+ userName: string;
118
+ userDisplayName?: string;
119
+ }): Promise<PasskeyRegistrationOptionsInterface> {
120
+ return this.callApi<PasskeyRegistrationOptionsInterface>({
121
+ type: Modules.PasskeyRegistrationOptions,
122
+ method: HttpMethod.POST,
123
+ endpoint: new EndpointCreator({
124
+ endpoint: Modules.Auth,
125
+ id: "passkey",
126
+ childEndpoint: "register",
127
+ childId: "options",
128
+ }).generate(),
129
+ input: params,
130
+ });
131
+ }
132
+
133
+ static async verifyPasskeyRegistration(params: {
134
+ id: string;
135
+ pendingId: string;
136
+ name: string;
137
+ response: RegistrationResponseJSON;
138
+ }): Promise<PasskeyInterface> {
139
+ return this.callApi<PasskeyInterface>({
140
+ type: Modules.PasskeyRegistrationVerify,
141
+ method: HttpMethod.POST,
142
+ endpoint: new EndpointCreator({
143
+ endpoint: Modules.Auth,
144
+ id: "passkey",
145
+ childEndpoint: "register",
146
+ childId: "verify",
147
+ }).generate(),
148
+ input: params,
149
+ });
150
+ }
151
+
152
+ static async listPasskeys(): Promise<PasskeyInterface[]> {
153
+ return this.callApi<PasskeyInterface[]>({
154
+ type: Modules.Passkey,
155
+ method: HttpMethod.GET,
156
+ endpoint: new EndpointCreator({
157
+ endpoint: Modules.Auth,
158
+ id: "passkeys",
159
+ }).generate(),
160
+ });
161
+ }
162
+
163
+ static async deletePasskey(params: { id: string }): Promise<void> {
164
+ await this.callApi({
165
+ type: Modules.Auth,
166
+ method: HttpMethod.DELETE,
167
+ endpoint: new EndpointCreator({
168
+ endpoint: Modules.Auth,
169
+ id: "passkeys",
170
+ childEndpoint: params.id,
171
+ }).generate(),
172
+ });
173
+ }
174
+
175
+ static async renamePasskey(params: { id: string; name: string }): Promise<PasskeyInterface> {
176
+ return this.callApi<PasskeyInterface>({
177
+ type: Modules.PasskeyRename,
178
+ method: HttpMethod.PATCH,
179
+ endpoint: new EndpointCreator({
180
+ endpoint: Modules.Auth,
181
+ id: "passkeys",
182
+ childEndpoint: params.id,
183
+ }).generate(),
184
+ input: { id: params.id, name: params.name },
185
+ });
186
+ }
187
+
188
+ // ============================================================
189
+ // Backup Codes
190
+ // ============================================================
191
+
192
+ static async generateBackupCodes(): Promise<string[]> {
193
+ const response = await this.callApi<{ codes: string[] }>({
194
+ type: Modules.Auth,
195
+ method: HttpMethod.POST,
196
+ endpoint: new EndpointCreator({
197
+ endpoint: Modules.Auth,
198
+ id: "backup-codes",
199
+ childEndpoint: "generate",
200
+ }).generate(),
201
+ });
202
+ return response.codes;
203
+ }
204
+
205
+ static async getBackupCodesCount(): Promise<number> {
206
+ const response = await this.callApi<{ count: number }>({
207
+ type: Modules.Auth,
208
+ method: HttpMethod.GET,
209
+ endpoint: new EndpointCreator({
210
+ endpoint: Modules.Auth,
211
+ id: "backup-codes",
212
+ childEndpoint: "count",
213
+ }).generate(),
214
+ });
215
+ return response.count;
216
+ }
217
+
218
+ // ============================================================
219
+ // Login 2FA Verification
220
+ // ============================================================
221
+
222
+ private static async handleSuccessfulAuth(auth: AuthInterface): Promise<AuthInterface> {
223
+ const handler = getTokenHandler();
224
+ if (handler) {
225
+ await handler.updateToken({
226
+ token: auth.token,
227
+ refreshToken: auth.refreshToken,
228
+ userId: auth.user.id,
229
+ companyId: auth.user.company?.id,
230
+ roles: auth.user.roles.map((role) => role.id),
231
+ features: auth.user.company?.features?.map((feature) => feature.id) ?? [],
232
+ modules: auth.user.modules.map((module) => ({
233
+ id: module.id,
234
+ permissions: module.permissions,
235
+ })),
236
+ });
237
+ }
238
+
239
+ return auth;
240
+ }
241
+
242
+ static async getChallenge(params: {
243
+ id: string;
244
+ pendingToken: string;
245
+ method: "totp" | "passkey" | "backup";
246
+ }): Promise<TwoFactorChallengeInterface> {
247
+ return this.callApi<TwoFactorChallengeInterface>({
248
+ type: Modules.TwoFactorChallenge,
249
+ method: HttpMethod.POST,
250
+ endpoint: new EndpointCreator({
251
+ endpoint: Modules.Auth,
252
+ id: "two-factor",
253
+ childEndpoint: "challenge",
254
+ }).generate(),
255
+ input: { id: params.id, method: params.method },
256
+ });
257
+ }
258
+
259
+ static async verifyTotp(params: { id: string; pendingToken: string; code: string }): Promise<AuthInterface> {
260
+ const auth = await this.callApi<AuthInterface>({
261
+ type: Modules.TotpVerifyLogin, // Request: { type: "totp-authenticators", attributes: { code } }
262
+ responseType: Modules.Auth, // Response: Auth with user relationship
263
+ method: HttpMethod.POST,
264
+ endpoint: new EndpointCreator({
265
+ endpoint: Modules.Auth,
266
+ id: "two-factor",
267
+ childEndpoint: "verify",
268
+ childId: "totp",
269
+ }).generate(),
270
+ input: { id: params.id, code: params.code },
271
+ token: params.pendingToken,
272
+ });
273
+
274
+ return this.handleSuccessfulAuth(auth);
275
+ }
276
+
277
+ static async getPasskeyAuthOptions(params: { pendingToken: string }): Promise<PasskeyAuthenticationOptionsInterface> {
278
+ return this.callApi<PasskeyAuthenticationOptionsInterface>({
279
+ type: Modules.PasskeyAuthenticationOptions,
280
+ method: HttpMethod.POST,
281
+ endpoint: new EndpointCreator({
282
+ endpoint: Modules.Auth,
283
+ id: "two-factor",
284
+ childEndpoint: "verify/passkey",
285
+ childId: "options",
286
+ }).generate(),
287
+ token: params.pendingToken,
288
+ });
289
+ }
290
+
291
+ static async verifyPasskey(params: {
292
+ id: string;
293
+ pendingToken: string;
294
+ pendingId: string;
295
+ credential: AuthenticationResponseJSON;
296
+ }): Promise<AuthInterface> {
297
+ const auth = await this.callApi<AuthInterface>({
298
+ type: Modules.PasskeyVerifyLogin, // Request: passkey verification format
299
+ responseType: Modules.Auth, // Response: Auth with user relationship
300
+ method: HttpMethod.POST,
301
+ endpoint: new EndpointCreator({
302
+ endpoint: Modules.Auth,
303
+ id: "two-factor",
304
+ childEndpoint: "verify",
305
+ childId: "passkey",
306
+ }).generate(),
307
+ input: { id: params.id, pendingId: params.pendingId, response: params.credential },
308
+ token: params.pendingToken,
309
+ });
310
+
311
+ return this.handleSuccessfulAuth(auth);
312
+ }
313
+
314
+ static async verifyBackupCode(params: { id: string; pendingToken: string; code: string }): Promise<AuthInterface> {
315
+ const auth = await this.callApi<AuthInterface>({
316
+ type: Modules.BackupCodeVerify, // Request: backup code verification format
317
+ responseType: Modules.Auth, // Response: Auth with user relationship
318
+ method: HttpMethod.POST,
319
+ endpoint: new EndpointCreator({
320
+ endpoint: Modules.Auth,
321
+ id: "two-factor",
322
+ childEndpoint: "verify",
323
+ childId: "backup",
324
+ }).generate(),
325
+ input: { id: params.id, code: params.code },
326
+ token: params.pendingToken,
327
+ });
328
+
329
+ return this.handleSuccessfulAuth(auth);
330
+ }
331
+ }
@@ -6,4 +6,5 @@ export enum AuthComponent {
6
6
  AcceptInvitation,
7
7
  Register,
8
8
  Landing,
9
+ TwoFactorChallenge = "2fa_challenge",
9
10
  }
@@ -1,4 +1,17 @@
1
1
  export * from "./auth.module";
2
+ export * from "./totp-authenticator.module";
3
+ export * from "./totp-setup.module";
4
+ export * from "./totp-verify.module";
5
+ export * from "./totp-verify-login.module";
6
+ export * from "./passkey.module";
7
+ export * from "./passkey-registration-options.module";
8
+ export * from "./passkey-registration-verify.module";
9
+ export * from "./passkey-rename.module";
10
+ export * from "./passkey-verify-login.module";
11
+ export * from "./passkey-authentication-options.module";
12
+ export * from "./two-factor-enable.module";
13
+ export * from "./two-factor-challenge.module";
14
+ export * from "./backup-code-verify.module";
2
15
  export { configureAuth, type TokenHandler, type TokenParams } from "./config";
3
16
  export * from "./data";
4
17
  export * from "./enums";
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { PasskeyAuthenticationOptions } from "./data/passkey-authentication-options";
3
+
4
+ export const PasskeyAuthenticationOptionsModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "passkey-authentication-options",
7
+ pageUrl: "/passkeys",
8
+ model: PasskeyAuthenticationOptions,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { PasskeyRegistrationOptions } from "./data/passkey-registration-options";
3
+
4
+ export const PasskeyRegistrationOptionsModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "passkey-registration-options",
7
+ pageUrl: "/passkeys",
8
+ model: PasskeyRegistrationOptions,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { PasskeyRegistrationVerify } from "./data/passkey-registration-verify";
3
+
4
+ export const PasskeyRegistrationVerifyModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "passkey-registration-verify",
7
+ pageUrl: "/passkeys",
8
+ model: PasskeyRegistrationVerify,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { PasskeyRename } from "./data/passkey-rename";
3
+
4
+ export const PasskeyRenameModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "passkey-rename",
7
+ pageUrl: "/passkeys-rename",
8
+ model: PasskeyRename,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { PasskeyVerifyLogin } from "./data/passkey-verify-login";
3
+
4
+ export const PasskeyVerifyLoginModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "passkey-verify-login",
7
+ pageUrl: "/passkeys",
8
+ model: PasskeyVerifyLogin,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { Passkey } from "./data/passkey";
3
+
4
+ export const PasskeyModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "passkeys",
7
+ pageUrl: "/passkeys",
8
+ model: Passkey,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { TotpAuthenticator } from "./data/totp-authenticator";
3
+
4
+ export const TotpAuthenticatorModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "totp-authenticators",
7
+ pageUrl: "/totp-authenticators",
8
+ model: TotpAuthenticator,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { TotpSetup } from "./data/totp-setup";
3
+
4
+ export const TotpSetupModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "totp-setup",
7
+ pageUrl: "/totp-setup",
8
+ model: TotpSetup,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { TotpVerifyLogin } from "./data/totp-verify-login";
3
+
4
+ export const TotpVerifyLoginModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "totp-verify-login",
7
+ pageUrl: "/totp-verify-login",
8
+ model: TotpVerifyLogin,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { TotpVerify } from "./data/totp-verify";
3
+
4
+ export const TotpVerifyModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "totp-verify",
7
+ pageUrl: "/totp-verify",
8
+ model: TotpVerify,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { TwoFactorChallenge } from "./data/two-factor-challenge";
3
+
4
+ export const TwoFactorChallengeModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "two-factor-challenge",
7
+ pageUrl: "/two-factor-challenge",
8
+ model: TwoFactorChallenge,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { TwoFactorEnable } from "./data/two-factor-enable";
3
+
4
+ export const TwoFactorEnableModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "two-factor-enable",
7
+ pageUrl: "/two-factor-enable",
8
+ model: TwoFactorEnable,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { ModuleFactory } from "../../permissions";
2
+ import { TwoFactorStatus } from "./data/two-factor-status";
3
+
4
+ export const TwoFactorStatusModule = (factory: ModuleFactory) =>
5
+ factory({
6
+ name: "two-factor-status",
7
+ pageUrl: "/two-factor-status",
8
+ model: TwoFactorStatus,
9
+ });
@@ -4,6 +4,7 @@ import { Billing } from "../data/Billing";
4
4
  export const BillingModule = (factory: ModuleFactory) =>
5
5
  factory({
6
6
  name: "billing",
7
+ pageUrl: "/billing",
7
8
  model: Billing,
8
9
  moduleId: "3266b307-5a9a-46f9-b78d-631f672f8735",
9
10
  });
@@ -4,6 +4,7 @@ import { StripeCustomer } from "./data";
4
4
  export const StripeCustomerModule = (factory: ModuleFactory) =>
5
5
  factory({
6
6
  name: "stripe-customers",
7
+ pageUrl: "/stripe-customers",
7
8
  model: StripeCustomer,
8
9
  moduleId: "25a80cb3-bf18-47fd-963a-639212519920",
9
10
  });
@@ -4,6 +4,7 @@ import { PaymentMethod } from "./data/payment-method";
4
4
  export const StripePaymentMethodModule = (factory: ModuleFactory) =>
5
5
  factory({
6
6
  name: "stripe-payment-methods",
7
+ pageUrl: "/stripe-payment-methods",
7
8
  model: PaymentMethod,
8
9
  moduleId: "e8f7d6c5-b4a3-4928-8170-1f2e3d4c5b6a",
9
10
  });