@djangocfg/api 2.1.457 → 2.1.460
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 +1 -1
- package/dist/auth.cjs +54 -31
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +51 -57
- package/dist/auth.d.ts +51 -57
- package/dist/auth.mjs +54 -31
- package/dist/auth.mjs.map +1 -1
- package/package.json +2 -2
- package/src/auth/__tests__/useAuthForm.2fa.test.ts +2 -2
- package/src/auth/hooks/index.ts +11 -7
- package/src/auth/hooks/twoFactor.shared.ts +54 -0
- package/src/auth/hooks/useAuthForm.ts +2 -2
- package/src/auth/hooks/useTwoFactor.ts +55 -241
- package/src/auth/hooks/useTwoFactorSetup.ts +9 -47
- package/src/auth/hooks/useTwoFactorStatus.ts +6 -40
- package/src/auth/hooks/useTwoFactorVerify.ts +214 -0
package/dist/auth.d.cts
CHANGED
|
@@ -697,7 +697,7 @@ interface UseGithubAuthReturn {
|
|
|
697
697
|
*/
|
|
698
698
|
declare const useGithubAuth: (options?: UseGithubAuthOptions) => UseGithubAuthReturn;
|
|
699
699
|
|
|
700
|
-
interface
|
|
700
|
+
interface UseTwoFactorVerifyOptions {
|
|
701
701
|
/** Callback on successful 2FA verification */
|
|
702
702
|
onSuccess?: (user: any) => void;
|
|
703
703
|
/** Callback on error */
|
|
@@ -707,7 +707,7 @@ interface UseTwoFactorOptions {
|
|
|
707
707
|
/** Skip automatic redirect after success (caller handles navigation) */
|
|
708
708
|
skipRedirect?: boolean;
|
|
709
709
|
}
|
|
710
|
-
interface
|
|
710
|
+
interface UseTwoFactorVerifyReturn {
|
|
711
711
|
/** Loading state */
|
|
712
712
|
isLoading: boolean;
|
|
713
713
|
/** Error message */
|
|
@@ -726,31 +726,13 @@ interface UseTwoFactorReturn {
|
|
|
726
726
|
clearError: () => void;
|
|
727
727
|
}
|
|
728
728
|
/**
|
|
729
|
-
*
|
|
730
|
-
*
|
|
731
|
-
* Usage:
|
|
732
|
-
* 1. After OTP/OAuth verification returns requires_2fa=true and session_id
|
|
733
|
-
* 2. Show 2FA form and collect TOTP code from user
|
|
734
|
-
* 3. Call verifyTOTP(sessionId, code) to complete authentication
|
|
735
|
-
*
|
|
736
|
-
* @example
|
|
737
|
-
* ```tsx
|
|
738
|
-
* const { isLoading, error, verifyTOTP, verifyBackupCode } = useTwoFactor({
|
|
739
|
-
* onSuccess: (user) => console.log('Logged in:', user),
|
|
740
|
-
* onError: (error) => console.error(error),
|
|
741
|
-
* redirectUrl: '/dashboard',
|
|
742
|
-
* });
|
|
729
|
+
* 2FA verification during login (internal — composed by {@link useTwoFactor}).
|
|
743
730
|
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
* } else {
|
|
748
|
-
* await verifyTOTP(sessionId, code);
|
|
749
|
-
* }
|
|
750
|
-
* };
|
|
751
|
-
* ```
|
|
731
|
+
* After OTP/OAuth verification returns requires_2fa=true and a session_id,
|
|
732
|
+
* collect the TOTP (or backup) code and call verifyTOTP/verifyBackupCode to
|
|
733
|
+
* complete authentication.
|
|
752
734
|
*/
|
|
753
|
-
declare const
|
|
735
|
+
declare const useTwoFactorVerify: (options?: UseTwoFactorVerifyOptions) => UseTwoFactorVerifyReturn;
|
|
754
736
|
|
|
755
737
|
interface TwoFactorSetupData {
|
|
756
738
|
/** Device ID to use for confirmation */
|
|
@@ -793,38 +775,9 @@ interface UseTwoFactorSetupReturn {
|
|
|
793
775
|
clearError: () => void;
|
|
794
776
|
}
|
|
795
777
|
/**
|
|
796
|
-
*
|
|
797
|
-
*
|
|
798
|
-
* Flow:
|
|
799
|
-
* 1. Call startSetup() to get QR code and provisioning URI
|
|
800
|
-
* 2. User scans QR code with authenticator app
|
|
801
|
-
* 3. Call confirmSetup(code) with the 6-digit code from app
|
|
802
|
-
* 4. Show backup codes to user (they must save these!)
|
|
803
|
-
*
|
|
804
|
-
* @example
|
|
805
|
-
* ```tsx
|
|
806
|
-
* const {
|
|
807
|
-
* isLoading,
|
|
808
|
-
* error,
|
|
809
|
-
* setupData,
|
|
810
|
-
* backupCodes,
|
|
811
|
-
* setupStep,
|
|
812
|
-
* startSetup,
|
|
813
|
-
* confirmSetup,
|
|
814
|
-
* } = useTwoFactorSetup({
|
|
815
|
-
* onComplete: (codes) => console.log('Backup codes:', codes),
|
|
816
|
-
* onError: (error) => console.error(error),
|
|
817
|
-
* });
|
|
818
|
-
*
|
|
819
|
-
* // Start setup
|
|
820
|
-
* const data = await startSetup('My iPhone');
|
|
778
|
+
* 2FA setup — enabling TOTP (internal, composed by {@link useTwoFactor}).
|
|
821
779
|
*
|
|
822
|
-
*
|
|
823
|
-
* <QRCodeSVG value={data.provisioningUri} />
|
|
824
|
-
*
|
|
825
|
-
* // Confirm with code from app
|
|
826
|
-
* const codes = await confirmSetup('123456');
|
|
827
|
-
* ```
|
|
780
|
+
* Flow: startSetup() → user scans QR → confirmSetup(code) → show backup codes.
|
|
828
781
|
*/
|
|
829
782
|
declare const useTwoFactorSetup: (options?: UseTwoFactorSetupOptions) => UseTwoFactorSetupReturn;
|
|
830
783
|
|
|
@@ -851,8 +804,49 @@ interface UseTwoFactorStatusReturn {
|
|
|
851
804
|
/** Clear error */
|
|
852
805
|
clearError: () => void;
|
|
853
806
|
}
|
|
807
|
+
/**
|
|
808
|
+
* Read and manage 2FA status (internal, composed by {@link useTwoFactor}).
|
|
809
|
+
*
|
|
810
|
+
* Fetches the device list / enabled flag and disables 2FA.
|
|
811
|
+
*/
|
|
854
812
|
declare const useTwoFactorStatus: () => UseTwoFactorStatusReturn;
|
|
855
813
|
|
|
814
|
+
interface UseTwoFactorOptions {
|
|
815
|
+
/** Options for the login-time verification namespace */
|
|
816
|
+
verify?: UseTwoFactorVerifyOptions;
|
|
817
|
+
/** Options for the setup (enable) namespace */
|
|
818
|
+
setup?: UseTwoFactorSetupOptions;
|
|
819
|
+
}
|
|
820
|
+
interface UseTwoFactorReturn {
|
|
821
|
+
/** Verify a 2FA challenge during login (TOTP / backup code). */
|
|
822
|
+
verify: UseTwoFactorVerifyReturn;
|
|
823
|
+
/** Enable 2FA — QR provisioning → confirm → backup codes. */
|
|
824
|
+
setup: UseTwoFactorSetupReturn;
|
|
825
|
+
/** Read device list / enabled flag and disable 2FA. */
|
|
826
|
+
status: UseTwoFactorStatusReturn;
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Single entry point for all two-factor authentication flows.
|
|
830
|
+
*
|
|
831
|
+
* The three concerns — **verify** (login), **setup** (enable) and **status**
|
|
832
|
+
* (manage/disable) — are distinct verbs over the same `CfgTotp*` API, so each
|
|
833
|
+
* is exposed as its own namespace with an independent loading/error surface:
|
|
834
|
+
*
|
|
835
|
+
* @example
|
|
836
|
+
* ```tsx
|
|
837
|
+
* const two = useTwoFactor({ verify: { redirectUrl: '/dashboard' } });
|
|
838
|
+
*
|
|
839
|
+
* await two.verify.verifyTOTP(sessionId, code); // login
|
|
840
|
+
* await two.setup.startSetup('My iPhone'); // enable
|
|
841
|
+
* await two.status.fetchStatus(); // manage
|
|
842
|
+
* ```
|
|
843
|
+
*
|
|
844
|
+
* Consumers that only need one concern can compose the underlying hooks
|
|
845
|
+
* directly (`useTwoFactorVerify` / `useTwoFactorSetup` / `useTwoFactorStatus`),
|
|
846
|
+
* all re-exported alongside this one, to avoid mounting the others' state.
|
|
847
|
+
*/
|
|
848
|
+
declare const useTwoFactor: (options?: UseTwoFactorOptions) => UseTwoFactorReturn;
|
|
849
|
+
|
|
856
850
|
interface AuthRedirectOptions {
|
|
857
851
|
fallbackUrl?: string;
|
|
858
852
|
clearOnUse?: boolean;
|
|
@@ -1111,4 +1105,4 @@ declare const Analytics: {
|
|
|
1111
1105
|
setUser(userId: string): void;
|
|
1112
1106
|
};
|
|
1113
1107
|
|
|
1114
|
-
export { AUTH_CONSTANTS, type AccountsContextValue, AccountsProvider, Analytics, AnalyticsCategory, type AnalyticsCategoryType, AnalyticsEvent, type AnalyticsEventType, type AuthConfig, AuthContext, type AuthContextType, type AuthFormAutoSubmit, type AuthFormReturn, type AuthFormState, type AuthFormStateHandlers, type AuthFormSubmitHandlers, type AuthFormValidation, AuthProvider, type AuthProviderProps, type AuthStep, type DeleteAccountResult, type GuardInput, type OTPRequestResult, type PatchedCfgUserUpdateRequest, PatchedCfgUserUpdateRequestSchema, type ProfileCacheOptions, type SessionSnapshot, type SessionStatus, type TwoFactorDevice, type TwoFactorSetupData, type UseAuthFormOptions, type UseAuthFormStateReturn, type UseAutoAuthOptions, type UseDeleteAccountReturn, type UseGithubAuthOptions, type UseGithubAuthReturn, type UseTwoFactorOptions, type UseTwoFactorReturn, type UseTwoFactorSetupOptions, type UseTwoFactorSetupReturn, type UseTwoFactorStatusReturn, type UserProfile, type WebmailLink, authLogger, clearProfileCache, consumeSavedRedirect, decodeBase64, encodeBase64, formatAuthError, getCacheMetadata, getCachedProfile, hasValidCache, isAllowedAuthPath, logger, normalizePath, peekSavedRedirect, resolveGuardIsAuthenticated, resolveGuardIsLoading, setCachedProfile, shouldRedirectToAuth, useAccountsContext, useAuth, useAuthForm, useAuthFormState, useAuthRedirectManager, useAuthValidation, useAutoAuth, useBase64, useCfgRouter, useDeleteAccount, useGithubAuth, useLocalStorage, useQueryParams, useSession, useSessionStorage, useTwoFactor, useTwoFactorSetup, useTwoFactorStatus, validateEmail, validateIdentifier };
|
|
1108
|
+
export { AUTH_CONSTANTS, type AccountsContextValue, AccountsProvider, Analytics, AnalyticsCategory, type AnalyticsCategoryType, AnalyticsEvent, type AnalyticsEventType, type AuthConfig, AuthContext, type AuthContextType, type AuthFormAutoSubmit, type AuthFormReturn, type AuthFormState, type AuthFormStateHandlers, type AuthFormSubmitHandlers, type AuthFormValidation, AuthProvider, type AuthProviderProps, type AuthStep, type DeleteAccountResult, type GuardInput, type OTPRequestResult, type PatchedCfgUserUpdateRequest, PatchedCfgUserUpdateRequestSchema, type ProfileCacheOptions, type SessionSnapshot, type SessionStatus, type TwoFactorDevice, type TwoFactorSetupData, type UseAuthFormOptions, type UseAuthFormStateReturn, type UseAutoAuthOptions, type UseDeleteAccountReturn, type UseGithubAuthOptions, type UseGithubAuthReturn, type UseTwoFactorOptions, type UseTwoFactorReturn, type UseTwoFactorSetupOptions, type UseTwoFactorSetupReturn, type UseTwoFactorStatusReturn, type UseTwoFactorVerifyOptions, type UseTwoFactorVerifyReturn, type UserProfile, type WebmailLink, authLogger, clearProfileCache, consumeSavedRedirect, decodeBase64, encodeBase64, formatAuthError, getCacheMetadata, getCachedProfile, hasValidCache, isAllowedAuthPath, logger, normalizePath, peekSavedRedirect, resolveGuardIsAuthenticated, resolveGuardIsLoading, setCachedProfile, shouldRedirectToAuth, useAccountsContext, useAuth, useAuthForm, useAuthFormState, useAuthRedirectManager, useAuthValidation, useAutoAuth, useBase64, useCfgRouter, useDeleteAccount, useGithubAuth, useLocalStorage, useQueryParams, useSession, useSessionStorage, useTwoFactor, useTwoFactorSetup, useTwoFactorStatus, useTwoFactorVerify, validateEmail, validateIdentifier };
|
package/dist/auth.d.ts
CHANGED
|
@@ -697,7 +697,7 @@ interface UseGithubAuthReturn {
|
|
|
697
697
|
*/
|
|
698
698
|
declare const useGithubAuth: (options?: UseGithubAuthOptions) => UseGithubAuthReturn;
|
|
699
699
|
|
|
700
|
-
interface
|
|
700
|
+
interface UseTwoFactorVerifyOptions {
|
|
701
701
|
/** Callback on successful 2FA verification */
|
|
702
702
|
onSuccess?: (user: any) => void;
|
|
703
703
|
/** Callback on error */
|
|
@@ -707,7 +707,7 @@ interface UseTwoFactorOptions {
|
|
|
707
707
|
/** Skip automatic redirect after success (caller handles navigation) */
|
|
708
708
|
skipRedirect?: boolean;
|
|
709
709
|
}
|
|
710
|
-
interface
|
|
710
|
+
interface UseTwoFactorVerifyReturn {
|
|
711
711
|
/** Loading state */
|
|
712
712
|
isLoading: boolean;
|
|
713
713
|
/** Error message */
|
|
@@ -726,31 +726,13 @@ interface UseTwoFactorReturn {
|
|
|
726
726
|
clearError: () => void;
|
|
727
727
|
}
|
|
728
728
|
/**
|
|
729
|
-
*
|
|
730
|
-
*
|
|
731
|
-
* Usage:
|
|
732
|
-
* 1. After OTP/OAuth verification returns requires_2fa=true and session_id
|
|
733
|
-
* 2. Show 2FA form and collect TOTP code from user
|
|
734
|
-
* 3. Call verifyTOTP(sessionId, code) to complete authentication
|
|
735
|
-
*
|
|
736
|
-
* @example
|
|
737
|
-
* ```tsx
|
|
738
|
-
* const { isLoading, error, verifyTOTP, verifyBackupCode } = useTwoFactor({
|
|
739
|
-
* onSuccess: (user) => console.log('Logged in:', user),
|
|
740
|
-
* onError: (error) => console.error(error),
|
|
741
|
-
* redirectUrl: '/dashboard',
|
|
742
|
-
* });
|
|
729
|
+
* 2FA verification during login (internal — composed by {@link useTwoFactor}).
|
|
743
730
|
*
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
* } else {
|
|
748
|
-
* await verifyTOTP(sessionId, code);
|
|
749
|
-
* }
|
|
750
|
-
* };
|
|
751
|
-
* ```
|
|
731
|
+
* After OTP/OAuth verification returns requires_2fa=true and a session_id,
|
|
732
|
+
* collect the TOTP (or backup) code and call verifyTOTP/verifyBackupCode to
|
|
733
|
+
* complete authentication.
|
|
752
734
|
*/
|
|
753
|
-
declare const
|
|
735
|
+
declare const useTwoFactorVerify: (options?: UseTwoFactorVerifyOptions) => UseTwoFactorVerifyReturn;
|
|
754
736
|
|
|
755
737
|
interface TwoFactorSetupData {
|
|
756
738
|
/** Device ID to use for confirmation */
|
|
@@ -793,38 +775,9 @@ interface UseTwoFactorSetupReturn {
|
|
|
793
775
|
clearError: () => void;
|
|
794
776
|
}
|
|
795
777
|
/**
|
|
796
|
-
*
|
|
797
|
-
*
|
|
798
|
-
* Flow:
|
|
799
|
-
* 1. Call startSetup() to get QR code and provisioning URI
|
|
800
|
-
* 2. User scans QR code with authenticator app
|
|
801
|
-
* 3. Call confirmSetup(code) with the 6-digit code from app
|
|
802
|
-
* 4. Show backup codes to user (they must save these!)
|
|
803
|
-
*
|
|
804
|
-
* @example
|
|
805
|
-
* ```tsx
|
|
806
|
-
* const {
|
|
807
|
-
* isLoading,
|
|
808
|
-
* error,
|
|
809
|
-
* setupData,
|
|
810
|
-
* backupCodes,
|
|
811
|
-
* setupStep,
|
|
812
|
-
* startSetup,
|
|
813
|
-
* confirmSetup,
|
|
814
|
-
* } = useTwoFactorSetup({
|
|
815
|
-
* onComplete: (codes) => console.log('Backup codes:', codes),
|
|
816
|
-
* onError: (error) => console.error(error),
|
|
817
|
-
* });
|
|
818
|
-
*
|
|
819
|
-
* // Start setup
|
|
820
|
-
* const data = await startSetup('My iPhone');
|
|
778
|
+
* 2FA setup — enabling TOTP (internal, composed by {@link useTwoFactor}).
|
|
821
779
|
*
|
|
822
|
-
*
|
|
823
|
-
* <QRCodeSVG value={data.provisioningUri} />
|
|
824
|
-
*
|
|
825
|
-
* // Confirm with code from app
|
|
826
|
-
* const codes = await confirmSetup('123456');
|
|
827
|
-
* ```
|
|
780
|
+
* Flow: startSetup() → user scans QR → confirmSetup(code) → show backup codes.
|
|
828
781
|
*/
|
|
829
782
|
declare const useTwoFactorSetup: (options?: UseTwoFactorSetupOptions) => UseTwoFactorSetupReturn;
|
|
830
783
|
|
|
@@ -851,8 +804,49 @@ interface UseTwoFactorStatusReturn {
|
|
|
851
804
|
/** Clear error */
|
|
852
805
|
clearError: () => void;
|
|
853
806
|
}
|
|
807
|
+
/**
|
|
808
|
+
* Read and manage 2FA status (internal, composed by {@link useTwoFactor}).
|
|
809
|
+
*
|
|
810
|
+
* Fetches the device list / enabled flag and disables 2FA.
|
|
811
|
+
*/
|
|
854
812
|
declare const useTwoFactorStatus: () => UseTwoFactorStatusReturn;
|
|
855
813
|
|
|
814
|
+
interface UseTwoFactorOptions {
|
|
815
|
+
/** Options for the login-time verification namespace */
|
|
816
|
+
verify?: UseTwoFactorVerifyOptions;
|
|
817
|
+
/** Options for the setup (enable) namespace */
|
|
818
|
+
setup?: UseTwoFactorSetupOptions;
|
|
819
|
+
}
|
|
820
|
+
interface UseTwoFactorReturn {
|
|
821
|
+
/** Verify a 2FA challenge during login (TOTP / backup code). */
|
|
822
|
+
verify: UseTwoFactorVerifyReturn;
|
|
823
|
+
/** Enable 2FA — QR provisioning → confirm → backup codes. */
|
|
824
|
+
setup: UseTwoFactorSetupReturn;
|
|
825
|
+
/** Read device list / enabled flag and disable 2FA. */
|
|
826
|
+
status: UseTwoFactorStatusReturn;
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Single entry point for all two-factor authentication flows.
|
|
830
|
+
*
|
|
831
|
+
* The three concerns — **verify** (login), **setup** (enable) and **status**
|
|
832
|
+
* (manage/disable) — are distinct verbs over the same `CfgTotp*` API, so each
|
|
833
|
+
* is exposed as its own namespace with an independent loading/error surface:
|
|
834
|
+
*
|
|
835
|
+
* @example
|
|
836
|
+
* ```tsx
|
|
837
|
+
* const two = useTwoFactor({ verify: { redirectUrl: '/dashboard' } });
|
|
838
|
+
*
|
|
839
|
+
* await two.verify.verifyTOTP(sessionId, code); // login
|
|
840
|
+
* await two.setup.startSetup('My iPhone'); // enable
|
|
841
|
+
* await two.status.fetchStatus(); // manage
|
|
842
|
+
* ```
|
|
843
|
+
*
|
|
844
|
+
* Consumers that only need one concern can compose the underlying hooks
|
|
845
|
+
* directly (`useTwoFactorVerify` / `useTwoFactorSetup` / `useTwoFactorStatus`),
|
|
846
|
+
* all re-exported alongside this one, to avoid mounting the others' state.
|
|
847
|
+
*/
|
|
848
|
+
declare const useTwoFactor: (options?: UseTwoFactorOptions) => UseTwoFactorReturn;
|
|
849
|
+
|
|
856
850
|
interface AuthRedirectOptions {
|
|
857
851
|
fallbackUrl?: string;
|
|
858
852
|
clearOnUse?: boolean;
|
|
@@ -1111,4 +1105,4 @@ declare const Analytics: {
|
|
|
1111
1105
|
setUser(userId: string): void;
|
|
1112
1106
|
};
|
|
1113
1107
|
|
|
1114
|
-
export { AUTH_CONSTANTS, type AccountsContextValue, AccountsProvider, Analytics, AnalyticsCategory, type AnalyticsCategoryType, AnalyticsEvent, type AnalyticsEventType, type AuthConfig, AuthContext, type AuthContextType, type AuthFormAutoSubmit, type AuthFormReturn, type AuthFormState, type AuthFormStateHandlers, type AuthFormSubmitHandlers, type AuthFormValidation, AuthProvider, type AuthProviderProps, type AuthStep, type DeleteAccountResult, type GuardInput, type OTPRequestResult, type PatchedCfgUserUpdateRequest, PatchedCfgUserUpdateRequestSchema, type ProfileCacheOptions, type SessionSnapshot, type SessionStatus, type TwoFactorDevice, type TwoFactorSetupData, type UseAuthFormOptions, type UseAuthFormStateReturn, type UseAutoAuthOptions, type UseDeleteAccountReturn, type UseGithubAuthOptions, type UseGithubAuthReturn, type UseTwoFactorOptions, type UseTwoFactorReturn, type UseTwoFactorSetupOptions, type UseTwoFactorSetupReturn, type UseTwoFactorStatusReturn, type UserProfile, type WebmailLink, authLogger, clearProfileCache, consumeSavedRedirect, decodeBase64, encodeBase64, formatAuthError, getCacheMetadata, getCachedProfile, hasValidCache, isAllowedAuthPath, logger, normalizePath, peekSavedRedirect, resolveGuardIsAuthenticated, resolveGuardIsLoading, setCachedProfile, shouldRedirectToAuth, useAccountsContext, useAuth, useAuthForm, useAuthFormState, useAuthRedirectManager, useAuthValidation, useAutoAuth, useBase64, useCfgRouter, useDeleteAccount, useGithubAuth, useLocalStorage, useQueryParams, useSession, useSessionStorage, useTwoFactor, useTwoFactorSetup, useTwoFactorStatus, validateEmail, validateIdentifier };
|
|
1108
|
+
export { AUTH_CONSTANTS, type AccountsContextValue, AccountsProvider, Analytics, AnalyticsCategory, type AnalyticsCategoryType, AnalyticsEvent, type AnalyticsEventType, type AuthConfig, AuthContext, type AuthContextType, type AuthFormAutoSubmit, type AuthFormReturn, type AuthFormState, type AuthFormStateHandlers, type AuthFormSubmitHandlers, type AuthFormValidation, AuthProvider, type AuthProviderProps, type AuthStep, type DeleteAccountResult, type GuardInput, type OTPRequestResult, type PatchedCfgUserUpdateRequest, PatchedCfgUserUpdateRequestSchema, type ProfileCacheOptions, type SessionSnapshot, type SessionStatus, type TwoFactorDevice, type TwoFactorSetupData, type UseAuthFormOptions, type UseAuthFormStateReturn, type UseAutoAuthOptions, type UseDeleteAccountReturn, type UseGithubAuthOptions, type UseGithubAuthReturn, type UseTwoFactorOptions, type UseTwoFactorReturn, type UseTwoFactorSetupOptions, type UseTwoFactorSetupReturn, type UseTwoFactorStatusReturn, type UseTwoFactorVerifyOptions, type UseTwoFactorVerifyReturn, type UserProfile, type WebmailLink, authLogger, clearProfileCache, consumeSavedRedirect, decodeBase64, encodeBase64, formatAuthError, getCacheMetadata, getCachedProfile, hasValidCache, isAllowedAuthPath, logger, normalizePath, peekSavedRedirect, resolveGuardIsAuthenticated, resolveGuardIsLoading, setCachedProfile, shouldRedirectToAuth, useAccountsContext, useAuth, useAuthForm, useAuthFormState, useAuthRedirectManager, useAuthValidation, useAutoAuth, useBase64, useCfgRouter, useDeleteAccount, useGithubAuth, useLocalStorage, useQueryParams, useSession, useSessionStorage, useTwoFactor, useTwoFactorSetup, useTwoFactorStatus, useTwoFactorVerify, validateEmail, validateIdentifier };
|
package/dist/auth.mjs
CHANGED
|
@@ -1081,7 +1081,7 @@ var useAutoAuth = /* @__PURE__ */ __name((options = {}) => {
|
|
|
1081
1081
|
};
|
|
1082
1082
|
}, "useAutoAuth");
|
|
1083
1083
|
|
|
1084
|
-
// src/auth/hooks/
|
|
1084
|
+
// src/auth/hooks/useTwoFactorVerify.ts
|
|
1085
1085
|
import { useCallback as useCallback4, useState as useState4 } from "react";
|
|
1086
1086
|
|
|
1087
1087
|
// src/_api/generated/core/bodySerializer.gen.ts
|
|
@@ -2609,8 +2609,35 @@ var useAuthRedirectManager = /* @__PURE__ */ __name((options = {}) => {
|
|
|
2609
2609
|
};
|
|
2610
2610
|
}, "useAuthRedirectManager");
|
|
2611
2611
|
|
|
2612
|
-
// src/auth/hooks/
|
|
2613
|
-
var
|
|
2612
|
+
// src/auth/hooks/twoFactor.shared.ts
|
|
2613
|
+
var TOTP_CODE_LENGTH = 6;
|
|
2614
|
+
function extractTwoFactorError(err, fallback) {
|
|
2615
|
+
if (err instanceof APIError) {
|
|
2616
|
+
const body = err.response ?? null;
|
|
2617
|
+
if (typeof body?.error === "string") return body.error;
|
|
2618
|
+
if (typeof body?.detail === "string") return body.detail;
|
|
2619
|
+
if (typeof body?.message === "string") return body.message;
|
|
2620
|
+
return err.errorMessage ?? err.message;
|
|
2621
|
+
}
|
|
2622
|
+
if (err instanceof Error) return err.message;
|
|
2623
|
+
return fallback;
|
|
2624
|
+
}
|
|
2625
|
+
__name(extractTwoFactorError, "extractTwoFactorError");
|
|
2626
|
+
function extractAttemptsRemaining(err) {
|
|
2627
|
+
if (err instanceof APIError) {
|
|
2628
|
+
const body = err.response ?? null;
|
|
2629
|
+
if (typeof body?.attempts_remaining === "number") return body.attempts_remaining;
|
|
2630
|
+
}
|
|
2631
|
+
return null;
|
|
2632
|
+
}
|
|
2633
|
+
__name(extractAttemptsRemaining, "extractAttemptsRemaining");
|
|
2634
|
+
function isValidTotpCode(code) {
|
|
2635
|
+
return !!code && code.length === TOTP_CODE_LENGTH;
|
|
2636
|
+
}
|
|
2637
|
+
__name(isValidTotpCode, "isValidTotpCode");
|
|
2638
|
+
|
|
2639
|
+
// src/auth/hooks/useTwoFactorVerify.ts
|
|
2640
|
+
var useTwoFactorVerify = /* @__PURE__ */ __name((options = {}) => {
|
|
2614
2641
|
const { onSuccess, onError, redirectUrl, skipRedirect = false } = options;
|
|
2615
2642
|
const router = useCfgRouter();
|
|
2616
2643
|
const [isLoading, setIsLoading] = useState4(false);
|
|
@@ -2650,7 +2677,7 @@ var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
|
|
|
2650
2677
|
onError?.(msg);
|
|
2651
2678
|
return false;
|
|
2652
2679
|
}
|
|
2653
|
-
if (!code
|
|
2680
|
+
if (!isValidTotpCode(code)) {
|
|
2654
2681
|
const msg = "Please enter a 6-digit code";
|
|
2655
2682
|
setError(msg);
|
|
2656
2683
|
onError?.(msg);
|
|
@@ -2672,10 +2699,9 @@ var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
|
|
|
2672
2699
|
return true;
|
|
2673
2700
|
} catch (err) {
|
|
2674
2701
|
authLogger.error("2FA TOTP verification error:", err);
|
|
2675
|
-
const errorMessage = err
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
}
|
|
2702
|
+
const errorMessage = extractTwoFactorError(err, "Invalid verification code");
|
|
2703
|
+
const attempts = extractAttemptsRemaining(err);
|
|
2704
|
+
if (attempts !== null) setAttemptsRemaining(attempts);
|
|
2679
2705
|
setError(errorMessage);
|
|
2680
2706
|
onError?.(errorMessage);
|
|
2681
2707
|
Analytics.event("auth_otp_verify_fail" /* AUTH_OTP_VERIFY_FAIL */, {
|
|
@@ -2719,10 +2745,9 @@ var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
|
|
|
2719
2745
|
return true;
|
|
2720
2746
|
} catch (err) {
|
|
2721
2747
|
authLogger.error("2FA backup code verification error:", err);
|
|
2722
|
-
const errorMessage = err
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
}
|
|
2748
|
+
const errorMessage = extractTwoFactorError(err, "Invalid backup code");
|
|
2749
|
+
const attempts = extractAttemptsRemaining(err);
|
|
2750
|
+
if (attempts !== null) setAttemptsRemaining(attempts);
|
|
2726
2751
|
setError(errorMessage);
|
|
2727
2752
|
onError?.(errorMessage);
|
|
2728
2753
|
Analytics.event("auth_otp_verify_fail" /* AUTH_OTP_VERIFY_FAIL */, {
|
|
@@ -2744,7 +2769,7 @@ var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
|
|
|
2744
2769
|
verifyBackupCode,
|
|
2745
2770
|
clearError
|
|
2746
2771
|
};
|
|
2747
|
-
}, "
|
|
2772
|
+
}, "useTwoFactorVerify");
|
|
2748
2773
|
|
|
2749
2774
|
// src/auth/hooks/useAuthForm.ts
|
|
2750
2775
|
var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
@@ -2788,7 +2813,7 @@ var useAuthForm = /* @__PURE__ */ __name((options) => {
|
|
|
2788
2813
|
startRateLimitCountdown,
|
|
2789
2814
|
setWebmail
|
|
2790
2815
|
} = formState;
|
|
2791
|
-
const twoFactor =
|
|
2816
|
+
const twoFactor = useTwoFactorVerify({
|
|
2792
2817
|
onSuccess: /* @__PURE__ */ __name(() => {
|
|
2793
2818
|
authLogger.info("2FA verification successful, showing success screen");
|
|
2794
2819
|
setStep("success");
|
|
@@ -3179,7 +3204,7 @@ var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3179
3204
|
authLogger.info("2FA setup initiated, expires in:", data.expiresIn, "seconds");
|
|
3180
3205
|
return data;
|
|
3181
3206
|
} catch (err) {
|
|
3182
|
-
const errorMessage = err
|
|
3207
|
+
const errorMessage = extractTwoFactorError(err, "Failed to start 2FA setup");
|
|
3183
3208
|
authLogger.error("2FA setup error:", err);
|
|
3184
3209
|
setError(errorMessage);
|
|
3185
3210
|
setSetupStep("idle");
|
|
@@ -3196,7 +3221,7 @@ var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3196
3221
|
onError?.(msg);
|
|
3197
3222
|
return null;
|
|
3198
3223
|
}
|
|
3199
|
-
if (!code
|
|
3224
|
+
if (!isValidTotpCode(code)) {
|
|
3200
3225
|
const msg = "Please enter a 6-digit code";
|
|
3201
3226
|
setError(msg);
|
|
3202
3227
|
onError?.(msg);
|
|
@@ -3220,7 +3245,7 @@ var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3220
3245
|
onComplete?.(codes);
|
|
3221
3246
|
return codes;
|
|
3222
3247
|
} catch (err) {
|
|
3223
|
-
const errorMessage = err
|
|
3248
|
+
const errorMessage = extractTwoFactorError(err, "Invalid code. Please try again.");
|
|
3224
3249
|
authLogger.error("2FA setup confirmation error:", err);
|
|
3225
3250
|
setError(errorMessage);
|
|
3226
3251
|
setSetupStep("scanning");
|
|
@@ -3246,17 +3271,6 @@ var useTwoFactorSetup = /* @__PURE__ */ __name((options = {}) => {
|
|
|
3246
3271
|
|
|
3247
3272
|
// src/auth/hooks/useTwoFactorStatus.ts
|
|
3248
3273
|
import { useCallback as useCallback8, useState as useState7 } from "react";
|
|
3249
|
-
function extractErrorMessage(err, fallback) {
|
|
3250
|
-
if (err instanceof APIError) {
|
|
3251
|
-
const body = err.response;
|
|
3252
|
-
if (typeof body?.error === "string") return body.error;
|
|
3253
|
-
if (typeof body?.detail === "string") return body.detail;
|
|
3254
|
-
return err.message;
|
|
3255
|
-
}
|
|
3256
|
-
if (err instanceof Error) return err.message;
|
|
3257
|
-
return fallback;
|
|
3258
|
-
}
|
|
3259
|
-
__name(extractErrorMessage, "extractErrorMessage");
|
|
3260
3274
|
var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
|
|
3261
3275
|
const [isLoading, setIsLoading] = useState7(false);
|
|
3262
3276
|
const [error, setError] = useState7(null);
|
|
@@ -3283,7 +3297,7 @@ var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
|
|
|
3283
3297
|
setHas2FAEnabled(response.has_2fa_enabled);
|
|
3284
3298
|
authLogger.info("2FA status:", response.has_2fa_enabled ? "enabled" : "disabled");
|
|
3285
3299
|
} catch (err) {
|
|
3286
|
-
const errorMessage =
|
|
3300
|
+
const errorMessage = extractTwoFactorError(err, "Failed to fetch 2FA status");
|
|
3287
3301
|
authLogger.error("Failed to fetch 2FA status:", err);
|
|
3288
3302
|
setError(errorMessage);
|
|
3289
3303
|
} finally {
|
|
@@ -3291,7 +3305,7 @@ var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
|
|
|
3291
3305
|
}
|
|
3292
3306
|
}, []);
|
|
3293
3307
|
const disable2FA = useCallback8(async (code) => {
|
|
3294
|
-
if (!code
|
|
3308
|
+
if (!isValidTotpCode(code)) {
|
|
3295
3309
|
setError("Please enter a 6-digit code");
|
|
3296
3310
|
return false;
|
|
3297
3311
|
}
|
|
@@ -3305,7 +3319,7 @@ var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
|
|
|
3305
3319
|
authLogger.info("2FA disabled successfully");
|
|
3306
3320
|
return true;
|
|
3307
3321
|
} catch (err) {
|
|
3308
|
-
const errorMessage =
|
|
3322
|
+
const errorMessage = extractTwoFactorError(err, "Invalid verification code");
|
|
3309
3323
|
authLogger.error("Failed to disable 2FA:", err);
|
|
3310
3324
|
setError(errorMessage);
|
|
3311
3325
|
return false;
|
|
@@ -3324,6 +3338,14 @@ var useTwoFactorStatus = /* @__PURE__ */ __name(() => {
|
|
|
3324
3338
|
};
|
|
3325
3339
|
}, "useTwoFactorStatus");
|
|
3326
3340
|
|
|
3341
|
+
// src/auth/hooks/useTwoFactor.ts
|
|
3342
|
+
var useTwoFactor = /* @__PURE__ */ __name((options = {}) => {
|
|
3343
|
+
const verify = useTwoFactorVerify(options.verify);
|
|
3344
|
+
const setup = useTwoFactorSetup(options.setup);
|
|
3345
|
+
const status = useTwoFactorStatus();
|
|
3346
|
+
return { verify, setup, status };
|
|
3347
|
+
}, "useTwoFactor");
|
|
3348
|
+
|
|
3327
3349
|
// src/auth/hooks/useLocalStorage.ts
|
|
3328
3350
|
import { useState as useState8 } from "react";
|
|
3329
3351
|
function useLocalStorage(key, initialValue) {
|
|
@@ -4815,6 +4837,7 @@ export {
|
|
|
4815
4837
|
useTwoFactor,
|
|
4816
4838
|
useTwoFactorSetup,
|
|
4817
4839
|
useTwoFactorStatus,
|
|
4840
|
+
useTwoFactorVerify,
|
|
4818
4841
|
validateEmail,
|
|
4819
4842
|
validateIdentifier
|
|
4820
4843
|
};
|