@djangocfg/api 2.1.227 → 2.1.229

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 (55) hide show
  1. package/README.md +8 -9
  2. package/dist/auth-server.cjs +4 -9
  3. package/dist/auth-server.cjs.map +1 -1
  4. package/dist/auth-server.mjs +4 -9
  5. package/dist/auth-server.mjs.map +1 -1
  6. package/dist/auth.cjs +120 -158
  7. package/dist/auth.cjs.map +1 -1
  8. package/dist/auth.d.cts +120 -177
  9. package/dist/auth.d.ts +120 -177
  10. package/dist/auth.mjs +149 -191
  11. package/dist/auth.mjs.map +1 -1
  12. package/dist/clients.cjs +5 -11
  13. package/dist/clients.cjs.map +1 -1
  14. package/dist/clients.d.cts +253 -254
  15. package/dist/clients.d.ts +253 -254
  16. package/dist/clients.mjs +5 -11
  17. package/dist/clients.mjs.map +1 -1
  18. package/dist/hooks.cjs +4 -9
  19. package/dist/hooks.cjs.map +1 -1
  20. package/dist/hooks.d.cts +64 -85
  21. package/dist/hooks.d.ts +64 -85
  22. package/dist/hooks.mjs +4 -9
  23. package/dist/hooks.mjs.map +1 -1
  24. package/dist/index.cjs +5 -11
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +109 -99
  27. package/dist/index.d.ts +109 -99
  28. package/dist/index.mjs +5 -11
  29. package/dist/index.mjs.map +1 -1
  30. package/package.json +2 -2
  31. package/src/_api/generated/cfg_accounts/_utils/schemas/OTPErrorResponse.schema.ts +24 -2
  32. package/src/_api/generated/cfg_accounts/_utils/schemas/OTPRequestRequest.schema.ts +0 -2
  33. package/src/_api/generated/cfg_accounts/_utils/schemas/OTPVerifyRequest.schema.ts +0 -2
  34. package/src/_api/generated/cfg_accounts/accounts/client.ts +1 -1
  35. package/src/_api/generated/cfg_accounts/accounts/models.ts +37 -38
  36. package/src/_api/generated/cfg_accounts/accounts__oauth/models.ts +36 -36
  37. package/src/_api/generated/cfg_accounts/accounts__user_profile/models.ts +15 -15
  38. package/src/_api/generated/cfg_accounts/enums.ts +0 -10
  39. package/src/_api/generated/cfg_accounts/schema.json +31 -25
  40. package/src/_api/generated/cfg_centrifugo/centrifugo__centrifugo_admin_api/models.ts +74 -74
  41. package/src/_api/generated/cfg_centrifugo/centrifugo__centrifugo_monitoring/models.ts +36 -36
  42. package/src/_api/generated/cfg_centrifugo/centrifugo__centrifugo_testing/models.ts +22 -22
  43. package/src/_api/generated/cfg_totp/totp__totp_management/models.ts +10 -10
  44. package/src/_api/generated/cfg_totp/totp__totp_setup/models.ts +22 -22
  45. package/src/_api/generated/cfg_totp/totp__totp_verification/models.ts +8 -8
  46. package/src/auth/context/AccountsContext.tsx +6 -2
  47. package/src/auth/context/AuthContext.tsx +32 -39
  48. package/src/auth/context/types.ts +5 -9
  49. package/src/auth/hooks/index.ts +1 -1
  50. package/src/auth/hooks/useAuthForm.ts +42 -75
  51. package/src/auth/hooks/useAuthFormState.ts +35 -6
  52. package/src/auth/hooks/useAuthValidation.ts +5 -65
  53. package/src/auth/hooks/useTwoFactor.ts +17 -2
  54. package/src/auth/types/form.ts +25 -70
  55. package/src/auth/types/index.ts +2 -6
@@ -3,6 +3,7 @@
3
3
  import { useCallback, useState } from 'react';
4
4
 
5
5
  import { apiAccounts, apiTotp } from '../../clients';
6
+ import { APIError } from '../../_api/generated/cfg_totp/errors';
6
7
  import { Analytics, AnalyticsCategory, AnalyticsEvent } from '../utils/analytics';
7
8
  import { authLogger } from '../utils/logger';
8
9
  import { useCfgRouter } from './useCfgRouter';
@@ -27,6 +28,8 @@ export interface UseTwoFactorReturn {
27
28
  warning: string | null;
28
29
  /** Remaining backup codes (if backup code was used) */
29
30
  remainingBackupCodes: number | null;
31
+ /** Remaining verification attempts before lockout */
32
+ attemptsRemaining: number | null;
30
33
  /** Verify TOTP code */
31
34
  verifyTOTP: (sessionId: string, code: string) => Promise<boolean>;
32
35
  /** Verify backup code */
@@ -68,6 +71,7 @@ export const useTwoFactor = (options: UseTwoFactorOptions = {}): UseTwoFactorRet
68
71
  const [error, setError] = useState<string | null>(null);
69
72
  const [warning, setWarning] = useState<string | null>(null);
70
73
  const [remainingBackupCodes, setRemainingBackupCodes] = useState<number | null>(null);
74
+ const [attemptsRemaining, setAttemptsRemaining] = useState<number | null>(null);
71
75
 
72
76
  const clearError = useCallback(() => {
73
77
  setError(null);
@@ -155,8 +159,13 @@ export const useTwoFactor = (options: UseTwoFactorOptions = {}): UseTwoFactorRet
155
159
  return true;
156
160
 
157
161
  } catch (err) {
158
- const errorMessage = err instanceof Error ? err.message : 'Invalid verification code';
159
162
  authLogger.error('2FA TOTP verification error:', err);
163
+ const errorMessage = err instanceof APIError
164
+ ? (err.response?.error || err.response?.detail || err.response?.message || err.errorMessage)
165
+ : (err instanceof Error ? err.message : 'Invalid verification code');
166
+ if (err instanceof APIError && typeof err.response?.attempts_remaining === 'number') {
167
+ setAttemptsRemaining(err.response.attempts_remaining);
168
+ }
160
169
  setError(errorMessage);
161
170
  onError?.(errorMessage);
162
171
 
@@ -209,8 +218,13 @@ export const useTwoFactor = (options: UseTwoFactorOptions = {}): UseTwoFactorRet
209
218
  return true;
210
219
 
211
220
  } catch (err) {
212
- const errorMessage = err instanceof Error ? err.message : 'Invalid backup code';
213
221
  authLogger.error('2FA backup code verification error:', err);
222
+ const errorMessage = err instanceof APIError
223
+ ? (err.response?.error || err.response?.detail || err.response?.message || err.errorMessage)
224
+ : (err instanceof Error ? err.message : 'Invalid backup code');
225
+ if (err instanceof APIError && typeof err.response?.attempts_remaining === 'number') {
226
+ setAttemptsRemaining(err.response.attempts_remaining);
227
+ }
214
228
  setError(errorMessage);
215
229
  onError?.(errorMessage);
216
230
 
@@ -231,6 +245,7 @@ export const useTwoFactor = (options: UseTwoFactorOptions = {}): UseTwoFactorRet
231
245
  error,
232
246
  warning,
233
247
  remainingBackupCodes,
248
+ attemptsRemaining,
234
249
  verifyTOTP,
235
250
  verifyBackupCode,
236
251
  clearError,
@@ -8,21 +8,29 @@
8
8
  import type { MutableRefObject } from 'react';
9
9
 
10
10
  // ─────────────────────────────────────────────────────────────────────────────
11
- // Channel & Step Types
11
+ // Step Types
12
12
  // ─────────────────────────────────────────────────────────────────────────────
13
13
 
14
- export type AuthChannel = 'email' | 'phone';
15
14
  export type AuthStep = 'identifier' | 'otp' | '2fa' | '2fa-setup' | 'success';
16
15
 
16
+ // ─────────────────────────────────────────────────────────────────────────────
17
+ // OTP Result Types
18
+ // ─────────────────────────────────────────────────────────────────────────────
19
+
20
+ export interface OTPRequestResult {
21
+ success: boolean;
22
+ message: string;
23
+ statusCode?: number;
24
+ retryAfter?: number;
25
+ }
26
+
17
27
  // ─────────────────────────────────────────────────────────────────────────────
18
28
  // Form State
19
29
  // ─────────────────────────────────────────────────────────────────────────────
20
30
 
21
31
  export interface AuthFormState {
22
- /** Email or phone number */
32
+ /** Email address */
23
33
  identifier: string;
24
- /** Current auth channel */
25
- channel: AuthChannel;
26
34
  /** OTP code input */
27
35
  otp: string;
28
36
  /** Loading state */
@@ -41,6 +49,12 @@ export interface AuthFormState {
41
49
  twoFactorCode: string;
42
50
  /** Using backup code instead of TOTP */
43
51
  useBackupCode: boolean;
52
+ /** Seconds remaining until rate limit lifts (0 = not rate limited) */
53
+ rateLimitSeconds: number;
54
+ /** True when rateLimitSeconds > 0 — submit should be disabled */
55
+ isRateLimited: boolean;
56
+ /** Formatted countdown label, e.g. "19:00" or "42s" */
57
+ rateLimitLabel: string;
44
58
  }
45
59
 
46
60
  // ─────────────────────────────────────────────────────────────────────────────
@@ -49,7 +63,6 @@ export interface AuthFormState {
49
63
 
50
64
  export interface AuthFormStateHandlers {
51
65
  setIdentifier: (identifier: string) => void;
52
- setChannel: (channel: AuthChannel) => void;
53
66
  setOtp: (otp: string) => void;
54
67
  setAcceptedTerms: (accepted: boolean) => void;
55
68
  setError: (error: string) => void;
@@ -60,6 +73,8 @@ export interface AuthFormStateHandlers {
60
73
  setShouldPrompt2FA: (prompt: boolean) => void;
61
74
  setTwoFactorCode: (code: string) => void;
62
75
  setUseBackupCode: (useBackup: boolean) => void;
76
+ /** Start a countdown timer that disables submit for `seconds` seconds */
77
+ startRateLimitCountdown: (seconds: number) => void;
63
78
  }
64
79
 
65
80
  export interface AuthFormSubmitHandlers {
@@ -81,10 +96,8 @@ export interface AuthFormSubmitHandlers {
81
96
  // ─────────────────────────────────────────────────────────────────────────────
82
97
 
83
98
  export interface AuthFormValidation {
84
- /** Detect channel from identifier string */
85
- detectChannelFromIdentifier: (identifier: string) => AuthChannel | null;
86
99
  /** Validate identifier format */
87
- validateIdentifier: (identifier: string, channel?: AuthChannel) => boolean;
100
+ validateIdentifier: (identifier: string) => boolean;
88
101
  }
89
102
 
90
103
  // ─────────────────────────────────────────────────────────────────────────────
@@ -105,6 +118,8 @@ export interface AuthForm2FAState {
105
118
  is2FALoading: boolean;
106
119
  /** Warning message from 2FA (e.g., low backup codes) */
107
120
  twoFactorWarning: string | null;
121
+ /** Remaining attempts before 2FA lockout (null = unknown) */
122
+ twoFactorAttemptsRemaining: number | null;
108
123
  }
109
124
 
110
125
  // ─────────────────────────────────────────────────────────────────────────────
@@ -125,7 +140,7 @@ export interface AuthFormReturn extends
125
140
 
126
141
  export interface UseAuthFormOptions {
127
142
  /** Callback when identifier step succeeds */
128
- onIdentifierSuccess?: (identifier: string, channel: AuthChannel) => void;
143
+ onIdentifierSuccess?: (identifier: string) => void;
129
144
  /** Callback when OTP verification succeeds */
130
145
  onOTPSuccess?: () => void;
131
146
  /** Callback on any error */
@@ -147,63 +162,3 @@ export interface UseAuthFormOptions {
147
162
  enable2FASetup?: boolean;
148
163
  }
149
164
 
150
- // ─────────────────────────────────────────────────────────────────────────────
151
- // Layout Context (UI-specific additions)
152
- // ─────────────────────────────────────────────────────────────────────────────
153
-
154
- export interface AuthLayoutConfig {
155
- /** Support page URL */
156
- supportUrl?: string;
157
- /** Terms of service URL */
158
- termsUrl?: string;
159
- /** Privacy policy URL */
160
- privacyUrl?: string;
161
- /** Source URL for tracking */
162
- sourceUrl: string;
163
- /** Enable phone authentication tab */
164
- enablePhoneAuth?: boolean;
165
- /** Enable GitHub OAuth button */
166
- enableGithubAuth?: boolean;
167
- /** Logo URL for success screen (SVG recommended) */
168
- logoUrl?: string;
169
- /** URL to redirect after successful auth (default: /dashboard) */
170
- redirectUrl?: string;
171
- /**
172
- * Enable 2FA setup prompt after successful authentication.
173
- * When true (default), users without 2FA will see a setup prompt after login.
174
- * When false, users go directly to success without 2FA setup prompt.
175
- * Note: This only affects the setup prompt - existing 2FA verification still works.
176
- * @default true
177
- */
178
- enable2FASetup?: boolean;
179
- }
180
-
181
- export interface AuthFormContextType extends AuthFormReturn, AuthLayoutConfig {}
182
-
183
- // ─────────────────────────────────────────────────────────────────────────────
184
- // Layout Props
185
- // ─────────────────────────────────────────────────────────────────────────────
186
-
187
- export interface AuthLayoutProps extends AuthLayoutConfig {
188
- children?: React.ReactNode;
189
- className?: string;
190
- /** URL to redirect after successful auth (default: /dashboard) */
191
- redirectUrl?: string;
192
- /** Callback when identifier step succeeds */
193
- onIdentifierSuccess?: (identifier: string, channel: AuthChannel) => void;
194
- /** Callback when OTP verification succeeds */
195
- onOTPSuccess?: () => void;
196
- /** Callback when OAuth succeeds */
197
- onOAuthSuccess?: (user: any, isNewUser: boolean, provider: string) => void;
198
- /** Callback on any error */
199
- onError?: (message: string) => void;
200
- }
201
-
202
- // ─────────────────────────────────────────────────────────────────────────────
203
- // Help Component Props
204
- // ─────────────────────────────────────────────────────────────────────────────
205
-
206
- export interface AuthHelpProps {
207
- className?: string;
208
- variant?: 'default' | 'compact';
209
- }
@@ -2,9 +2,8 @@
2
2
  * Auth Types - Single source of truth
3
3
  */
4
4
 
5
- // Form types (for auth forms and layouts)
5
+ // Form types (auth logic only)
6
6
  export type {
7
- AuthChannel,
8
7
  AuthStep,
9
8
  AuthFormState,
10
9
  AuthFormStateHandlers,
@@ -13,10 +12,7 @@ export type {
13
12
  AuthFormAutoSubmit,
14
13
  AuthFormReturn,
15
14
  UseAuthFormOptions,
16
- AuthLayoutConfig,
17
- AuthFormContextType,
18
- AuthLayoutProps,
19
- AuthHelpProps,
15
+ OTPRequestResult,
20
16
  } from './form';
21
17
 
22
18
  // Re-export context types