mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-07-25 03:55:58 -04:00
switch to cloudflare turnstile
This commit is contained in:
@@ -1,36 +1,21 @@
|
||||
import HCaptcha from "@hcaptcha/react-hcaptcha";
|
||||
import Turnstile from "react-turnstile";
|
||||
import useHasMounted from "../../hooks/useHasMounted";
|
||||
import useTheme from "../../hooks/useTheme";
|
||||
import type { ComponentPropsWithoutRef } from "react";
|
||||
|
||||
export type CaptchaProps = {
|
||||
size?: "normal" | "compact" | "invisible";
|
||||
theme?: "light" | "dark";
|
||||
export type CaptchaProps = Omit<ComponentPropsWithoutRef<typeof Turnstile>, "sitekey"> & {
|
||||
className?: string;
|
||||
|
||||
// callbacks pulled verbatim from node_modules/@hcaptcha/react-hcaptcha/types/index.d.ts
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
onExpire?: () => any;
|
||||
onOpen?: () => any;
|
||||
onClose?: () => any;
|
||||
onChalExpired?: () => any;
|
||||
onError?: (event: string) => any;
|
||||
onVerify?: (token: string, ekey: string) => any;
|
||||
onLoad?: () => any;
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
};
|
||||
|
||||
const Captcha = ({ size = "normal", theme, className, ...rest }: CaptchaProps) => {
|
||||
const Captcha = ({ theme, className, ...rest }: CaptchaProps) => {
|
||||
const hasMounted = useHasMounted();
|
||||
const { activeTheme } = useTheme();
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{hasMounted && (
|
||||
<HCaptcha
|
||||
sitekey={process.env.NEXT_PUBLIC_HCAPTCHA_SITE_KEY || "10000000-ffff-ffff-ffff-000000000001"}
|
||||
reCaptchaCompat={false}
|
||||
tabIndex={0}
|
||||
size={size}
|
||||
<Turnstile
|
||||
sitekey={process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY || "1x00000000000000000000AA"}
|
||||
theme={theme || (activeTheme === "dark" ? activeTheme : "light")}
|
||||
{...rest}
|
||||
/>
|
||||
|
||||
@@ -55,7 +55,7 @@ const MarkdownTipIcon = styled(SiMarkdown, {
|
||||
marginRight: "0.25em",
|
||||
});
|
||||
|
||||
const HCaptcha = styled(Captcha, {
|
||||
const Turnstile = styled(Captcha, {
|
||||
margin: "1em 0",
|
||||
});
|
||||
|
||||
@@ -133,7 +133,7 @@ type FormValues = {
|
||||
name: string;
|
||||
email: string;
|
||||
message: string;
|
||||
"h-captcha-response": string;
|
||||
"cf-turnstile-response": string;
|
||||
};
|
||||
|
||||
export type ContactFormProps = {
|
||||
@@ -195,7 +195,7 @@ const ContactForm = ({ className }: ContactFormProps) => {
|
||||
name: "",
|
||||
email: "",
|
||||
message: "",
|
||||
"h-captcha-response": "",
|
||||
"cf-turnstile-response": "",
|
||||
}}
|
||||
validate={(values: FormValues) => {
|
||||
const errors: Partial<Record<keyof FormValues, boolean>> = {};
|
||||
@@ -203,9 +203,9 @@ const ContactForm = ({ className }: ContactFormProps) => {
|
||||
errors.name = !values.name;
|
||||
errors.email = !values.email; // also loosely validated that it's email-like via browser (not foolproof)
|
||||
errors.message = !values.message;
|
||||
errors["h-captcha-response"] = !values["h-captcha-response"];
|
||||
errors["cf-turnstile-response"] = !values["cf-turnstile-response"];
|
||||
|
||||
if (!errors.name && !errors.email && !errors.message && !errors["h-captcha-response"]) {
|
||||
if (!errors.name && !errors.email && !errors.message && !errors["cf-turnstile-response"]) {
|
||||
setFeedback("");
|
||||
return {};
|
||||
} else {
|
||||
@@ -267,7 +267,7 @@ const ContactForm = ({ className }: ContactFormProps) => {
|
||||
](https://jarv.is), and <code>`code`</code>.
|
||||
</MarkdownTip>
|
||||
|
||||
<HCaptcha onVerify={(token) => setFieldValue("h-captcha-response", token)} />
|
||||
<Turnstile onVerify={(token) => setFieldValue("cf-turnstile-response", token)} />
|
||||
|
||||
<ActionRow>
|
||||
<SubmitButton
|
||||
|
||||
Reference in New Issue
Block a user