mirror of
https://git.suyu.dev/suyu/website.git
synced 2026-01-03 13:14:32 +01:00
sign up page with captcha
This commit is contained in:
parent
2cf9d54d24
commit
2ddf2c7d31
14 changed files with 370 additions and 174 deletions
111
src/components/HCaptcha.svelte
Normal file
111
src/components/HCaptcha.svelte
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<script lang="ts" context="module">
|
||||
declare global {
|
||||
interface Window {
|
||||
sitekey: string;
|
||||
hcaptchaOnLoad: Function | null;
|
||||
onSuccess: Function | null;
|
||||
onError: Function;
|
||||
onClose: Function;
|
||||
hcaptcha: any;
|
||||
}
|
||||
}
|
||||
|
||||
declare var hcaptcha: any;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onDestroy, createEventDispatcher, onMount } from "svelte";
|
||||
// @ts-ignore
|
||||
const browser = import.meta.env.SSR === undefined ? true : !import.meta.env.SSR;
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
export let sitekey: string;
|
||||
export let apihost: string = "https://js.hcaptcha.com/1/api.js";
|
||||
export let hl: string = "";
|
||||
export let reCaptchaCompat: boolean = false;
|
||||
export let theme: "light" | "dark" = "light";
|
||||
export let size: "normal" | "compact" | "invisible" = "normal";
|
||||
|
||||
export const reset = () => {
|
||||
if (mounted && loaded && widgetID) hcaptcha.reset(widgetID);
|
||||
};
|
||||
|
||||
export const execute = (options) => {
|
||||
if (mounted && loaded && widgetID) return hcaptcha.execute(widgetID, options);
|
||||
};
|
||||
|
||||
// ensure that all captcha divs on a page are uniquely identifiable
|
||||
const id = Math.floor(Math.random() * 100);
|
||||
|
||||
let mounted = false;
|
||||
let loaded = false;
|
||||
let widgetID;
|
||||
|
||||
// construct the script tag for hCaptcha remote resources
|
||||
const query = new URLSearchParams({
|
||||
recaptchacompat: reCaptchaCompat ? "on" : "off",
|
||||
onload: "hcaptchaOnLoad",
|
||||
render: "explicit",
|
||||
});
|
||||
const scriptSrc = `${apihost}?${query.toString()}`;
|
||||
|
||||
onMount(() => {
|
||||
if (browser && !sitekey) sitekey = window.sitekey;
|
||||
|
||||
if (browser) {
|
||||
window.hcaptchaOnLoad = () => {
|
||||
// consumers can attach custom on:load handlers
|
||||
dispatch("load");
|
||||
loaded = true;
|
||||
};
|
||||
|
||||
window.onSuccess = (token) => {
|
||||
dispatch("success", {
|
||||
token: token,
|
||||
});
|
||||
};
|
||||
|
||||
window.onError = () => {
|
||||
dispatch("error");
|
||||
};
|
||||
|
||||
window.onClose = () => {
|
||||
dispatch("close");
|
||||
};
|
||||
}
|
||||
|
||||
dispatch("mount");
|
||||
mounted = true;
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (browser) {
|
||||
window.hcaptchaOnLoad = null;
|
||||
window.onSuccess = null;
|
||||
}
|
||||
// guard against script loading race conditions
|
||||
// i.e. if component is destroyed before hcaptcha reference is loaded
|
||||
if (loaded) hcaptcha = null;
|
||||
});
|
||||
|
||||
$: if (mounted && loaded) {
|
||||
widgetID = hcaptcha.render(`h-captcha-${id}`, {
|
||||
sitekey,
|
||||
hl, // force a specific localisation
|
||||
theme,
|
||||
callback: "onSuccess",
|
||||
"error-callback": "onError",
|
||||
"close-callback": "onClose",
|
||||
size,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
{#if mounted && !window?.hcaptcha}
|
||||
<script src={scriptSrc} async defer></script>
|
||||
{/if}
|
||||
</svelte:head>
|
||||
|
||||
<div id="h-captcha-{id}" />
|
||||
Loading…
Add table
Add a link
Reference in a new issue