@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
309 lines (308 loc) • 8.82 kB
JavaScript
'use client';
import { jsx as t, jsxs as f, Fragment as $ } from "react/jsx-runtime";
import "@emotion/styled";
import { Button as G } from "../../../ui/button/button.js";
import { CheckCircleIcon as H, XCircleIcon as J, ArrowPathIcon as K, EnvelopeIcon as O } from "@heroicons/react/24/outline";
import { useState as g, useMemo as W, useEffect as q, useCallback as T } from "react";
import { ResendEmailButton as Q } from "./resend-email-button.js";
import { useAuth as Z } from "../../../../hooks/use-auth.js";
import { useConfig as _ } from "../../../../hooks/use-config.js";
import { withErrorBoundary as L } from "../../common/error-boundary.js";
import { VerificationError as z, VerificationInput as ee } from "../../common/verification.js";
function re({
organizationId: E,
email: u,
autoSubmit: N = !0,
codeLength: h = 6,
resendDelay: p = 30,
maxResendAttempts: C = 3,
expirationTime: b = 300,
// 5 minutes
onVerificationSuccess: k,
onVerificationError: a,
onCodeSent: B,
onCodeResent: D,
token: V
}) {
const {
resendVerification: M,
verifyIdentity: I,
extractEmailFromUrl: c,
extractTokenFromUrl: l
} = Z(), [n, P] = g(""), [x, i] = g("idle"), [S, e] = g(null), [m, R] = g(0), [w, A] = g(0), [v, j] = g(null), d = W(() => V || l(), [V, l]), o = W(() => u || c(), [u, c]);
q(() => {
if (w > 0) {
const r = setTimeout(
() => A((s) => s - 1),
1e3
);
return () => clearTimeout(r);
}
}, [w]), q(() => {
if (v) {
const s = setInterval(() => {
/* @__PURE__ */ new Date() > v && (i("expired"), e("Verification code has expired"));
}, 1e3);
return () => clearInterval(s);
}
}, [v]), q(() => {
N && n.length === h && x === "sent" && y();
}, [n, h, N, x]), q(() => {
d && d !== "" && U();
}, [n, h, N, x]);
const U = T(async () => {
if (!d) {
i("error"), e("No verification token found.");
return;
}
try {
i("verifying"), e(null);
const r = await I("email", {
token: d
});
if (r.verified)
i("verified"), k?.({
email: o || "",
verified: !0
});
else
throw new Error(r.message ?? "Invalid verification code");
} catch (r) {
const s = r instanceof Error ? r : new Error("Verification failed");
i("error"), e(s.message), a?.(s);
}
}, [d]), F = T(async () => {
if (!o || !E) {
e("Missing required parameters for email verification");
return;
}
try {
i("sending"), e(null);
const r = await M({
email: o,
type: "email"
});
if (r.success)
i("sent"), A(p), j(new Date(Date.now() + b * 1e3)), B?.();
else
throw new Error(r.message || "Failed to send verification code");
} catch (r) {
const s = r instanceof Error ? r : new Error("Failed to send verification code");
i("error"), e(s.message), a?.(s);
}
}, [
o,
E,
M,
p,
b,
B,
a
]), Y = T(async () => {
if (m >= C) {
e("Maximum resend attempts reached");
return;
}
try {
R((r) => r + 1), await F(), D?.(m + 1);
} catch (r) {
const s = r instanceof Error ? r : new Error("Failed to resend verification code");
a?.(s);
}
}, [
m,
C,
F,
D,
a
]), y = T(async () => {
if (!n || n.length !== h) {
e("Please enter a valid verification code");
return;
}
if (!o || !E) {
e("Missing required parameters for verification");
return;
}
try {
if (i("verifying"), e(null), (await I("email", {
code: n,
token: d ?? ""
})).verified)
i("verified"), k?.({
email: o || "",
verified: !0
});
else
throw new Error("Invalid verification code");
} catch (r) {
const s = r instanceof Error ? r : new Error("Verification failed");
i("error"), e(s.message), a?.(s);
}
}, [
n,
h,
E,
I,
o,
V,
k,
a
]), X = T(() => {
P(""), i("idle"), e(null), R(0), A(0), j(null);
}, []);
return {
code: n,
setCode: P,
status: x,
error: S,
resendAttempts: m,
timeRemaining: w,
expiresAt: v,
canResend: w === 0 && m < C,
sendCode: F,
resendCode: Y,
handleVerify: y,
reset: X
};
}
const fe = L(function({
email: u,
organizationId: N,
autoSubmit: h = !0,
codeLength: p = 6,
resendDelay: C = 30,
maxResendAttempts: b = 3,
expirationTime: k = 300,
onVerificationSuccess: a,
onVerificationError: B,
onCodeSent: D,
onCodeResent: V,
className: M,
style: I,
disabled: c = !1,
size: l = "md",
radius: n = "md"
}) {
const { config: P, components: x } = _(), {
code: i,
setCode: S,
status: e,
error: m,
resendAttempts: R,
timeRemaining: w,
canResend: A,
sendCode: v,
resendCode: j,
handleVerify: d
} = re({
email: u,
organizationId: N,
autoSubmit: h,
codeLength: p,
resendDelay: C,
maxResendAttempts: b,
expirationTime: k,
onVerificationSuccess: a,
onVerificationError: B,
onCodeSent: D,
onCodeResent: V
}), o = x.Button ?? G, U = (y) => {
y.length <= p && S(y);
}, F = (y) => {
y.preventDefault(), d();
};
return /* @__PURE__ */ t("div", { className: M, style: I, children: e === "verified" ? /* @__PURE__ */ f("div", { className: "text-center py-8", children: [
/* @__PURE__ */ t(H, { className: "h-16 w-16 text-success mx-auto mb-4" }),
/* @__PURE__ */ t("h3", { className: "text-lg font-semibold mb-2", children: "Email Verified!" }),
/* @__PURE__ */ t("p", { className: "text-default-500", children: "Your email address has been successfully verified." })
] }) : e === "expired" ? /* @__PURE__ */ f("div", { className: "text-center py-8", children: [
/* @__PURE__ */ t(J, { className: "h-16 w-16 text-warning mx-auto mb-4" }),
/* @__PURE__ */ t("h3", { className: "text-lg font-semibold mb-2", children: "Code Expired" }),
/* @__PURE__ */ t("p", { className: "text-default-500 mb-4", children: "The verification code has expired. Please request a new one." }),
/* @__PURE__ */ t(
o,
{
color: "primary",
onClick: v,
disabled: c,
size: l,
radius: n,
startContent: /* @__PURE__ */ t(K, { className: "h-4 w-4" }),
children: "Send New Code"
}
)
] }) : /* @__PURE__ */ f("form", { onSubmit: F, className: "space-y-4", children: [
/* @__PURE__ */ f("div", { className: "text-center", children: [
/* @__PURE__ */ t(O, { className: "h-12 w-12 text-primary mx-auto mb-4" }),
/* @__PURE__ */ t("h3", { className: "text-lg font-semibold mb-2", children: "Verify Your Email" }),
u && /* @__PURE__ */ f("p", { className: "text-default-500 mb-4", children: [
"We've sent a verification code to ",
u
] })
] }),
m && /* @__PURE__ */ t(z, { error: m }),
u && /* @__PURE__ */ f($, { children: [
/* @__PURE__ */ f("div", { className: "space-y-4", children: [
/* @__PURE__ */ t(
ee,
{
value: i,
onChange: U,
length: p,
disabled: c || e === "verifying",
placeholder: "Enter verification code",
size: l,
radius: n
}
),
/* @__PURE__ */ t(
o,
{
type: "submit",
color: "primary",
className: "w-full",
size: l,
radius: n,
isLoading: e === "verifying",
disabled: c || i.length !== p || e === "verifying",
children: e === "verifying" ? "Verifying..." : "Verify Email"
}
),
/* @__PURE__ */ f("div", { className: "flex items-center justify-between", children: [
/* @__PURE__ */ t("span", { className: "text-sm text-default-500", children: "Didn't receive the code?" }),
/* @__PURE__ */ t(
Q,
{
onResend: j,
disabled: c || !A,
remainingTime: w,
attempt: R,
maxAttempts: b,
size: l,
radius: n
}
)
] })
] }),
e === "idle" && /* @__PURE__ */ t(
o,
{
color: "primary",
variant: "flat",
className: "w-full",
size: l,
radius: n,
onClick: v,
disabled: c,
isLoading: e === "sending",
children: e === "sending" ? "Sending..." : "Send Verification Code"
}
)
] })
] }) });
});
export {
fe as EmailVerification
};
//# sourceMappingURL=email-verification.js.map