feat(auth): add 2FA setup UI and login challenge step
This commit is contained in:
@@ -4,6 +4,7 @@ import { Box, Button, Chip, Paper, Typography } from "@mui/material";
|
||||
|
||||
import { api, getApiErrorMessage } from "../api";
|
||||
import { clearAuthClientState, getAuthPersistencePreference } from "../auth";
|
||||
import TwoFactorChallenge from "./TwoFactorChallenge";
|
||||
import { useToast } from "../toast";
|
||||
import { useI18n } from "../i18n/I18nProvider";
|
||||
|
||||
@@ -52,6 +53,7 @@ export default function GoogleAuthCard({ onSignedIn }: { onSignedIn?: () => void
|
||||
const [me, setMe] = useState<MeResponse | null>(null);
|
||||
const [working, setWorking] = useState(false);
|
||||
const [allowRegistration, setAllowRegistration] = useState(false);
|
||||
const [pendingToken, setPendingToken] = useState<string | null>(null);
|
||||
const hostRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const clientId = (process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID || "").trim();
|
||||
@@ -109,10 +111,14 @@ export default function GoogleAuthCard({ onSignedIn }: { onSignedIn?: () => void
|
||||
toast(res.data?.email ? t("googleLinkedSuccessWithEmail", { email: res.data.email }) : t("googleLinkedSuccess"), "success");
|
||||
await refreshMe();
|
||||
} else {
|
||||
await api.post("/auth/google/exchange", { token: credential, rememberMe: getAuthPersistencePreference() === "local" });
|
||||
window.dispatchEvent(new Event("auth-changed"));
|
||||
toast(t("googleSignedIn"), "success");
|
||||
onSignedIn?.();
|
||||
const res = await api.post<{ requiresTwoFactor?: boolean; pendingToken?: string }>("/auth/google/exchange", { token: credential, rememberMe: getAuthPersistencePreference() === "local" });
|
||||
if (res.data?.requiresTwoFactor && res.data.pendingToken) {
|
||||
setPendingToken(res.data.pendingToken);
|
||||
} else {
|
||||
window.dispatchEvent(new Event("auth-changed"));
|
||||
toast(t("googleSignedIn"), "success");
|
||||
onSignedIn?.();
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
toast(getApiErrorMessage(e, t("googleAuthFailed")), "error");
|
||||
@@ -151,7 +157,20 @@ export default function GoogleAuthCard({ onSignedIn }: { onSignedIn?: () => void
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
{clientId && (
|
||||
{clientId && pendingToken && (
|
||||
<TwoFactorChallenge
|
||||
pendingToken={pendingToken}
|
||||
onCancel={() => setPendingToken(null)}
|
||||
onSuccess={() => {
|
||||
setPendingToken(null);
|
||||
window.dispatchEvent(new Event("auth-changed"));
|
||||
toast(t("googleSignedIn"), "success");
|
||||
onSignedIn?.();
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{clientId && !pendingToken && (
|
||||
<Box sx={{ display: "flex", flexDirection: "column", gap: 1.25 }}>
|
||||
<Box sx={{ display: "flex", gap: 1, flexWrap: "wrap" }}>
|
||||
<Chip size="small" label={me?.googleLink?.linked ? t("googleLinked") : t("googleAvailableToLink")} color={me?.googleLink?.linked ? "success" : "default"} variant={me?.googleLink?.linked ? "filled" : "outlined"} />
|
||||
|
||||
Reference in New Issue
Block a user