feat: Auto submit 2FA if all inputs have a value (#9729)

* auto submit 2FA if all inputs have a value

* organize imports

* Fix duplicate text issue, this label is part of TwoFactor

* Fixed test that was failing due to enable-2fa not clickable anymore due to auto-submit

* Remove extra newline for clarity

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
pull/10151/head
Afzal Sayed 2023-07-13 23:54:57 +03:00 committed by GitHub
parent 1419c534c8
commit 58d6bb840a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 3 deletions

View File

@ -1,8 +1,9 @@
import type { BaseSyntheticEvent } from "react";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
import { useCallbackRef } from "@calcom/lib/hooks/useCallbackRef";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Dialog, DialogContent, Form } from "@calcom/ui";
@ -127,6 +128,17 @@ const EnableTwoFactorModal = ({ onEnable, onCancel }: EnableTwoFactorModalProps)
}
}
const handleEnableRef = useCallbackRef(handleEnable);
const totpCode = form.watch("totpCode");
// auto submit 2FA if all inputs have a value
useEffect(() => {
if (totpCode?.trim().length === 6) {
form.handleSubmit(handleEnableRef.current)();
}
}, [form, handleEnableRef, totpCode]);
return (
<Dialog open={true}>
<DialogContent>

View File

@ -1,8 +1,9 @@
import type { BaseSyntheticEvent } from "react";
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
import { useCallbackRef } from "@calcom/lib/hooks/useCallbackRef";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Dialog, DialogContent, DialogFooter, Form, TextField } from "@calcom/ui";
@ -129,6 +130,17 @@ const EnableTwoFactorModal = ({ onEnable, onCancel, open, onOpenChange }: Enable
}
}
const handleEnableRef = useCallbackRef(handleEnable);
const totpCode = form.watch("totpCode");
// auto submit 2FA if all inputs have a value
useEffect(() => {
if (totpCode?.trim().length === 6) {
form.handleSubmit(handleEnableRef.current)();
}
}, [form, handleEnableRef, totpCode]);
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent title={t("enable_2fa")} description={setupDescriptions[step]} type="creation">

View File

@ -102,7 +102,7 @@ test.describe("2FA Tests", async () => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await fillOtp({ page, secret: secret! });
await page.click('[data-testid="enable-2fa"]');
await expect(page.locator(`[data-testid=two-factor-switch][data-state="checked"]`)).toBeVisible();
return user;

View File

@ -0,0 +1,14 @@
import { useRef } from "react";
import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect";
export const useCallbackRef = <C>(callback: C) => {
const callbackRef = useRef(callback);
useIsomorphicLayoutEffect(() => {
callbackRef.current = callback;
});
return callbackRef;
};
export default useCallbackRef;