transcriptor-web/bootstrap/ssr/assets/TwoFactorAuthenticationForm-BLalZpWn.js
2025-04-05 15:58:14 +02:00

291 lines
12 KiB
JavaScript

import { jsxs, jsx } from "react/jsx-runtime";
import { router } from "@inertiajs/core";
import { useForm } from "@inertiajs/react";
import axios from "axios";
import classNames from "classnames";
import { useState, useRef } from "react";
import { A as ActionSection } from "./Modal-D5yHmTM4.js";
import { u as useRoute } from "../app.js";
import { D as DialogModal } from "./DialogModal-D0pyMzH2.js";
import { T as TextInput, I as InputError } from "./TextInput-CMJy2hIv.js";
import { P as PrimaryButton } from "./PrimaryButton-C2B8UWiv.js";
import { S as SecondaryButton } from "./SecondaryButton-G68tKuYQ.js";
import { D as DangerButton } from "./DangerButton-BAZynYAq.js";
import { I as InputLabel } from "./InputLabel-DhqxoV6M.js";
import { u as useTypedPage } from "./useTypedPage-Do3SqtsL.js";
import "./SectionTitle-DnuUNpyS.js";
import "@headlessui/react";
import "react-dom";
import "lodash";
import "react-dom/client";
function ConfirmsPassword({
title = "Confirm Password",
content = "For your security, please confirm your password to continue.",
button = "Confirm",
onConfirm,
children
}) {
const route = useRoute();
const [confirmingPassword, setConfirmingPassword] = useState(false);
const [form, setForm] = useState({
password: "",
error: "",
processing: false
});
const passwordRef = useRef(null);
function startConfirmingPassword() {
axios.get(route("password.confirmation")).then((response) => {
if (response.data.confirmed) {
onConfirm();
} else {
setConfirmingPassword(true);
setTimeout(() => {
var _a;
return (_a = passwordRef.current) == null ? void 0 : _a.focus();
}, 250);
}
});
}
function confirmPassword() {
setForm({ ...form, processing: true });
axios.post(route("password.confirm"), {
password: form.password
}).then(() => {
closeModal();
setTimeout(() => onConfirm(), 250);
}).catch((error) => {
var _a;
setForm({
...form,
processing: false,
error: error.response.data.errors.password[0]
});
(_a = passwordRef.current) == null ? void 0 : _a.focus();
});
}
function closeModal() {
setConfirmingPassword(false);
setForm({ processing: false, password: "", error: "" });
}
return /* @__PURE__ */ jsxs("span", { children: [
/* @__PURE__ */ jsx("span", { onClick: startConfirmingPassword, children }),
/* @__PURE__ */ jsxs(DialogModal, { isOpen: confirmingPassword, onClose: closeModal, children: [
/* @__PURE__ */ jsxs(DialogModal.Content, { title, children: [
content,
/* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
/* @__PURE__ */ jsx(
TextInput,
{
ref: passwordRef,
type: "password",
className: "mt-1 block w-3/4",
placeholder: "Password",
value: form.password,
onChange: (e) => setForm({ ...form, password: e.currentTarget.value })
}
),
/* @__PURE__ */ jsx(InputError, { message: form.error, className: "mt-2" })
] })
] }),
/* @__PURE__ */ jsxs(DialogModal.Footer, { children: [
/* @__PURE__ */ jsx(SecondaryButton, { onClick: closeModal, children: "Cancel" }),
/* @__PURE__ */ jsx(
PrimaryButton,
{
className: classNames("ml-2", { "opacity-25": form.processing }),
onClick: confirmPassword,
disabled: form.processing,
children: button
}
)
] })
] })
] });
}
function TwoFactorAuthenticationForm({
requiresConfirmation
}) {
var _a, _b, _c;
const page = useTypedPage();
const [enabling, setEnabling] = useState(false);
const [disabling, setDisabling] = useState(false);
const [qrCode, setQrCode] = useState(null);
const [recoveryCodes, setRecoveryCodes] = useState([]);
const [confirming, setConfirming] = useState(false);
const [setupKey, setSetupKey] = useState(null);
const confirmationForm = useForm({
code: ""
});
const twoFactorEnabled = !enabling && ((_c = (_b = (_a = page.props) == null ? void 0 : _a.auth) == null ? void 0 : _b.user) == null ? void 0 : _c.two_factor_enabled);
function enableTwoFactorAuthentication() {
setEnabling(true);
router.post(
"/user/two-factor-authentication",
{},
{
preserveScroll: true,
onSuccess() {
return Promise.all([
showQrCode(),
showSetupKey(),
showRecoveryCodes()
]);
},
onFinish() {
setEnabling(false);
setConfirming(requiresConfirmation);
}
}
);
}
function showSetupKey() {
return axios.get("/user/two-factor-secret-key").then((response) => {
setSetupKey(response.data.secretKey);
});
}
function confirmTwoFactorAuthentication() {
confirmationForm.post("/user/confirmed-two-factor-authentication", {
preserveScroll: true,
preserveState: true,
errorBag: "confirmTwoFactorAuthentication",
onSuccess: () => {
setConfirming(false);
setQrCode(null);
setSetupKey(null);
}
});
}
function showQrCode() {
return axios.get("/user/two-factor-qr-code").then((response) => {
setQrCode(response.data.svg);
});
}
function showRecoveryCodes() {
return axios.get("/user/two-factor-recovery-codes").then((response) => {
setRecoveryCodes(response.data);
});
}
function regenerateRecoveryCodes() {
axios.post("/user/two-factor-recovery-codes").then(() => {
showRecoveryCodes();
});
}
function disableTwoFactorAuthentication() {
setDisabling(true);
router.delete("/user/two-factor-authentication", {
preserveScroll: true,
onSuccess() {
setDisabling(false);
setConfirming(false);
}
});
}
return /* @__PURE__ */ jsxs(
ActionSection,
{
title: "Two Factor Authentication",
description: "Add additional security to your account using two factor authentication.",
children: [
(() => {
if (twoFactorEnabled && !confirming) {
return /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100", children: "You have enabled two factor authentication." });
}
if (confirming) {
return /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100", children: "Finish enabling two factor authentication." });
}
return /* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-gray-100", children: "You have not enabled two factor authentication." });
})(),
/* @__PURE__ */ jsx("div", { className: "mt-3 max-w-xl text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsx("p", { children: "When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone's Google Authenticator application." }) }),
twoFactorEnabled || confirming ? /* @__PURE__ */ jsxs("div", { children: [
qrCode ? /* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("div", { className: "mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400", children: confirming ? /* @__PURE__ */ jsx("p", { className: "font-semibold", children: "To finish enabling two factor authentication, scan the following QR code using your phone's authenticator application or enter the setup key and provide the generated OTP code." }) : /* @__PURE__ */ jsx("p", { children: "Two factor authentication is now enabled. Scan the following QR code using your phone's authenticator application or enter the setup key." }) }),
/* @__PURE__ */ jsx(
"div",
{
className: "mt-4",
dangerouslySetInnerHTML: { __html: qrCode || "" }
}
),
setupKey && /* @__PURE__ */ jsx("div", { className: "mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsxs("p", { className: "font-semibold", children: [
"Setup Key:",
" ",
/* @__PURE__ */ jsx(
"span",
{
dangerouslySetInnerHTML: { __html: setupKey || "" }
}
)
] }) }),
confirming && /* @__PURE__ */ jsxs("div", { className: "mt-4", children: [
/* @__PURE__ */ jsx(InputLabel, { htmlFor: "code", value: "Code" }),
/* @__PURE__ */ jsx(
TextInput,
{
id: "code",
type: "text",
name: "code",
className: "block mt-1 w-1/2",
inputMode: "numeric",
autoFocus: true,
autoComplete: "one-time-code",
value: confirmationForm.data.code,
onChange: (e) => confirmationForm.setData("code", e.currentTarget.value)
}
),
/* @__PURE__ */ jsx(
InputError,
{
message: confirmationForm.errors.code,
className: "mt-2"
}
)
] })
] }) : null,
recoveryCodes.length > 0 && !confirming ? /* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("div", { className: "mt-4 max-w-xl text-sm text-gray-600 dark:text-gray-400", children: /* @__PURE__ */ jsx("p", { className: "font-semibold", children: "Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost." }) }),
/* @__PURE__ */ jsx("div", { className: "grid gap-1 max-w-xl mt-4 px-4 py-4 font-mono text-sm bg-gray-100 dark:bg-gray-900 rounded-lg", children: recoveryCodes.map((code) => /* @__PURE__ */ jsx("div", { children: code }, code)) })
] }) : null
] }) : null,
/* @__PURE__ */ jsx("div", { className: "mt-5", children: twoFactorEnabled || confirming ? /* @__PURE__ */ jsxs("div", { children: [
confirming ? /* @__PURE__ */ jsx(ConfirmsPassword, { onConfirm: confirmTwoFactorAuthentication, children: /* @__PURE__ */ jsx(
PrimaryButton,
{
className: classNames("mr-3", { "opacity-25": enabling }),
disabled: enabling,
children: "Confirm"
}
) }) : null,
recoveryCodes.length > 0 && !confirming ? /* @__PURE__ */ jsx(ConfirmsPassword, { onConfirm: regenerateRecoveryCodes, children: /* @__PURE__ */ jsx(SecondaryButton, { className: "mr-3", children: "Regenerate Recovery Codes" }) }) : null,
recoveryCodes.length === 0 && !confirming ? /* @__PURE__ */ jsx(ConfirmsPassword, { onConfirm: showRecoveryCodes, children: /* @__PURE__ */ jsx(SecondaryButton, { className: "mr-3", children: "Show Recovery Codes" }) }) : null,
confirming ? /* @__PURE__ */ jsx(ConfirmsPassword, { onConfirm: disableTwoFactorAuthentication, children: /* @__PURE__ */ jsx(
SecondaryButton,
{
className: classNames("mr-3", { "opacity-25": disabling }),
disabled: disabling,
children: "Cancel"
}
) }) : /* @__PURE__ */ jsx(ConfirmsPassword, { onConfirm: disableTwoFactorAuthentication, children: /* @__PURE__ */ jsx(
DangerButton,
{
className: classNames({ "opacity-25": disabling }),
disabled: disabling,
children: "Disable"
}
) })
] }) : /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ConfirmsPassword, { onConfirm: enableTwoFactorAuthentication, children: /* @__PURE__ */ jsx(
PrimaryButton,
{
type: "button",
className: classNames({ "opacity-25": enabling }),
disabled: enabling,
children: "Enable"
}
) }) }) })
]
}
);
}
export {
TwoFactorAuthenticationForm as default
};