@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.
- package/README.md +8 -9
- package/dist/auth-server.cjs +4 -9
- package/dist/auth-server.cjs.map +1 -1
- package/dist/auth-server.mjs +4 -9
- package/dist/auth-server.mjs.map +1 -1
- package/dist/auth.cjs +120 -158
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +120 -177
- package/dist/auth.d.ts +120 -177
- package/dist/auth.mjs +149 -191
- package/dist/auth.mjs.map +1 -1
- package/dist/clients.cjs +5 -11
- package/dist/clients.cjs.map +1 -1
- package/dist/clients.d.cts +253 -254
- package/dist/clients.d.ts +253 -254
- package/dist/clients.mjs +5 -11
- package/dist/clients.mjs.map +1 -1
- package/dist/hooks.cjs +4 -9
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +64 -85
- package/dist/hooks.d.ts +64 -85
- package/dist/hooks.mjs +4 -9
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.cjs +5 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +109 -99
- package/dist/index.d.ts +109 -99
- package/dist/index.mjs +5 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/_api/generated/cfg_accounts/_utils/schemas/OTPErrorResponse.schema.ts +24 -2
- package/src/_api/generated/cfg_accounts/_utils/schemas/OTPRequestRequest.schema.ts +0 -2
- package/src/_api/generated/cfg_accounts/_utils/schemas/OTPVerifyRequest.schema.ts +0 -2
- package/src/_api/generated/cfg_accounts/accounts/client.ts +1 -1
- package/src/_api/generated/cfg_accounts/accounts/models.ts +37 -38
- package/src/_api/generated/cfg_accounts/accounts__oauth/models.ts +36 -36
- package/src/_api/generated/cfg_accounts/accounts__user_profile/models.ts +15 -15
- package/src/_api/generated/cfg_accounts/enums.ts +0 -10
- package/src/_api/generated/cfg_accounts/schema.json +31 -25
- package/src/_api/generated/cfg_centrifugo/centrifugo__centrifugo_admin_api/models.ts +74 -74
- package/src/_api/generated/cfg_centrifugo/centrifugo__centrifugo_monitoring/models.ts +36 -36
- package/src/_api/generated/cfg_centrifugo/centrifugo__centrifugo_testing/models.ts +22 -22
- package/src/_api/generated/cfg_totp/totp__totp_management/models.ts +10 -10
- package/src/_api/generated/cfg_totp/totp__totp_setup/models.ts +22 -22
- package/src/_api/generated/cfg_totp/totp__totp_verification/models.ts +8 -8
- package/src/auth/context/AccountsContext.tsx +6 -2
- package/src/auth/context/AuthContext.tsx +32 -39
- package/src/auth/context/types.ts +5 -9
- package/src/auth/hooks/index.ts +1 -1
- package/src/auth/hooks/useAuthForm.ts +42 -75
- package/src/auth/hooks/useAuthFormState.ts +35 -6
- package/src/auth/hooks/useAuthValidation.ts +5 -65
- package/src/auth/hooks/useTwoFactor.ts +17 -2
- package/src/auth/types/form.ts +25 -70
- 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,
|
package/src/auth/types/form.ts
CHANGED
|
@@ -8,21 +8,29 @@
|
|
|
8
8
|
import type { MutableRefObject } from 'react';
|
|
9
9
|
|
|
10
10
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
-
//
|
|
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
|
|
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
|
|
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
|
|
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
|
-
}
|
package/src/auth/types/index.ts
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* Auth Types - Single source of truth
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
// Form types (
|
|
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
|
-
|
|
17
|
-
AuthFormContextType,
|
|
18
|
-
AuthLayoutProps,
|
|
19
|
-
AuthHelpProps,
|
|
15
|
+
OTPRequestResult,
|
|
20
16
|
} from './form';
|
|
21
17
|
|
|
22
18
|
// Re-export context types
|