Tweak
This commit is contained in:
@@ -37,7 +37,7 @@ export interface RecoverPageProps {
|
||||
const Page: React.FC<RecoverPageProps> = ({ twoFactorType }) => {
|
||||
const { logout, showMiniDialog, onGenericError } = useBaseContext();
|
||||
|
||||
const [sessionID, setSessionID] = useState<string | null>(null);
|
||||
const [sessionID, setSessionID] = useState<string | undefined>(undefined);
|
||||
const [recoveryResponse, setRecoveryResponse] = useState<
|
||||
TwoFactorRecoveryResponse | undefined
|
||||
>(undefined);
|
||||
@@ -65,8 +65,8 @@ const Page: React.FC<RecoverPageProps> = ({ twoFactorType }) => {
|
||||
|
||||
useEffect(() => {
|
||||
const user = getData("user");
|
||||
const sid = user.passkeySessionID || user.twoFactorSessionID;
|
||||
if (!user?.email || !sid) {
|
||||
const sessionID = user.passkeySessionID || user.twoFactorSessionID;
|
||||
if (!user?.email || !sessionID) {
|
||||
void router.push("/");
|
||||
} else if (
|
||||
!(user.isTwoFactorEnabled || user.isTwoFactorEnabledPasskey) &&
|
||||
@@ -74,8 +74,8 @@ const Page: React.FC<RecoverPageProps> = ({ twoFactorType }) => {
|
||||
) {
|
||||
void router.push("/generate");
|
||||
} else {
|
||||
setSessionID(sid);
|
||||
void recoverTwoFactor(sid, twoFactorType)
|
||||
setSessionID(sessionID);
|
||||
void recoverTwoFactor(twoFactorType, sessionID)
|
||||
.then(setRecoveryResponse)
|
||||
.catch((e: unknown) => {
|
||||
log.error("Second factor recovery page setup failed", e);
|
||||
@@ -99,20 +99,18 @@ const Page: React.FC<RecoverPageProps> = ({ twoFactorType }) => {
|
||||
const handleSubmit: SingleInputFormProps["onSubmit"] | undefined = useMemo(
|
||||
() =>
|
||||
sessionID && recoveryResponse
|
||||
? async (recoveryKeyMnemonic: string, setFieldError) => {
|
||||
try {
|
||||
await recoverTwoFactorFinish(
|
||||
sessionID,
|
||||
twoFactorType,
|
||||
recoveryResponse,
|
||||
recoveryKeyMnemonic,
|
||||
);
|
||||
void router.push("/credentials");
|
||||
} catch (e) {
|
||||
log.error("Second factor recovery failed", e);
|
||||
setFieldError(t("incorrect_recovery_key"));
|
||||
}
|
||||
}
|
||||
? (recoveryKeyMnemonic, setFieldError) =>
|
||||
recoverTwoFactorFinish(
|
||||
twoFactorType,
|
||||
sessionID,
|
||||
recoveryResponse,
|
||||
recoveryKeyMnemonic,
|
||||
)
|
||||
.then(() => router.push("/credentials"))
|
||||
.catch((e: unknown) => {
|
||||
log.error("Second factor recovery failed", e);
|
||||
setFieldError(t("incorrect_recovery_key"));
|
||||
})
|
||||
: undefined,
|
||||
[twoFactorType, router, sessionID, recoveryResponse],
|
||||
);
|
||||
|
||||
@@ -623,11 +623,11 @@ export type TwoFactorRecoveryResponse = z.infer<
|
||||
* factor recovery secret (and nonce) from remote. The user can then decrypt
|
||||
* these using their recovery key to reset or bypass their second factor.
|
||||
*
|
||||
* @param twoFactorType The type of second factor to reset or bypass.
|
||||
*
|
||||
* @param sessionID A two factor session ID ({@link twoFactorSessionID} or
|
||||
* {@link passkeySessionID}) for the user.
|
||||
*
|
||||
* @param twoFactorType The type of second factor to reset or bypass.
|
||||
*
|
||||
* [Note: Second factor recovery]
|
||||
*
|
||||
* 1. When setting up a TOTP based second factor, client sends a (encrypted 2fa
|
||||
@@ -648,11 +648,11 @@ export type TwoFactorRecoveryResponse = z.infer<
|
||||
* (passkey based) the user's second factor.
|
||||
*/
|
||||
export const recoverTwoFactor = async (
|
||||
sessionID: string,
|
||||
twoFactorType: TwoFactorType,
|
||||
sessionID: string,
|
||||
): Promise<TwoFactorRecoveryResponse> => {
|
||||
const res = await fetch(
|
||||
await apiURL("/users/two-factor/recover", { sessionID, twoFactorType }),
|
||||
await apiURL("/users/two-factor/recover", { twoFactorType, sessionID }),
|
||||
{ headers: publicRequestHeaders() },
|
||||
);
|
||||
ensureOk(res);
|
||||
@@ -668,13 +668,13 @@ export const recoverTwoFactor = async (
|
||||
*
|
||||
* This completes the recovery process both locally, and on remote.
|
||||
*
|
||||
* @param twoFactorType The second factor type (same value as what would've been
|
||||
* passed to {@link recoverTwoFactor} for obtaining {@link recoveryResponse}).
|
||||
*
|
||||
* @param sessionID The second factor session ID (same value as what would've
|
||||
* been passed to {@link recoverTwoFactor} for obtaining
|
||||
* {@link recoveryResponse}).
|
||||
*
|
||||
* @param twoFactorType The second factor type (same value as what would've been
|
||||
* passed to {@link recoverTwoFactor} for obtaining {@link recoveryResponse}).
|
||||
*
|
||||
* @param recoveryResponse The response to a previous call to
|
||||
* {@link recoverTwoFactor}.
|
||||
*
|
||||
@@ -682,8 +682,8 @@ export const recoverTwoFactor = async (
|
||||
* by the user to complete recovery.
|
||||
*/
|
||||
export const recoverTwoFactorFinish = async (
|
||||
sessionID: string,
|
||||
twoFactorType: TwoFactorType,
|
||||
sessionID: string,
|
||||
recoveryResponse: TwoFactorRecoveryResponse,
|
||||
recoveryKeyMnemonic: string,
|
||||
) => {
|
||||
@@ -694,8 +694,8 @@ export const recoverTwoFactorFinish = async (
|
||||
await recoveryKeyFromMnemonic(recoveryKeyMnemonic),
|
||||
);
|
||||
const { keyAttributes, encryptedToken, token, id } = await removeTwoFactor(
|
||||
sessionID,
|
||||
twoFactorType,
|
||||
sessionID,
|
||||
twoFactorSecret,
|
||||
);
|
||||
await setLSUser({
|
||||
@@ -716,13 +716,13 @@ export interface TwoFactorVerificationResponse {
|
||||
}
|
||||
|
||||
export const removeTwoFactor = async (
|
||||
sessionID: string,
|
||||
twoFactorType: TwoFactorType,
|
||||
sessionID: string,
|
||||
secret: string,
|
||||
) => {
|
||||
const resp = await HTTPService.post(
|
||||
await apiURL("/users/two-factor/remove"),
|
||||
{ sessionID, twoFactorType, secret },
|
||||
{ twoFactorType, sessionID, secret },
|
||||
);
|
||||
return resp.data as TwoFactorVerificationResponse;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user