From 41d5afbffb693676f50df706e367d7c46a37adcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8A=E3=81=95=E3=82=80=E3=81=AE=E3=81=B2=E3=81=A8?= <46447427+samunohito@users.noreply.github.com> Date: Thu, 19 Dec 2024 09:38:11 +0900 Subject: [PATCH] =?UTF-8?q?feat(frontend):=20CAPTCHA=E3=81=AE=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E5=A4=89=E6=9B=B4=E6=99=82=E3=81=AF=E5=AE=9F=E9=9A=9B?= =?UTF-8?q?=E3=81=AB=E6=A4=9C=E8=A8=BC=E3=82=92=E9=80=9A=E9=81=8E=E3=81=97?= =?UTF-8?q?=E3=81=AA=E3=81=84=E3=81=A8=E4=BF=9D=E5=AD=98=E3=81=A7=E3=81=8D?= =?UTF-8?q?=E3=81=AA=E3=81=84=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/src/components/MkCaptcha.vue | 38 +++++++++--- .../frontend/src/components/MkFormFooter.vue | 3 +- packages/frontend/src/index.html | 2 +- .../src/pages/admin/bot-protection.vue | 62 ++++++++++++++++--- 4 files changed, 86 insertions(+), 19 deletions(-) diff --git a/packages/frontend/src/components/MkCaptcha.vue b/packages/frontend/src/components/MkCaptcha.vue index 264cf9af06..1b69580d45 100644 --- a/packages/frontend/src/components/MkCaptcha.vue +++ b/packages/frontend/src/components/MkCaptcha.vue @@ -94,6 +94,14 @@ const scriptId = computed(() => `script-${props.provider}`); const captcha = computed(() => window[variable.value] || {} as unknown as Captcha); +watch(() => [props.instanceUrl, props.sitekey], async () => { + // 変更があったときはリフレッシュと再レンダリングをしておかないと、変更後の値で再検証が出来ない + if (available.value) { + callback(undefined); + await requestRender(); + } +}); + if (loaded || props.provider === 'mcaptcha' || props.provider === 'testcaptcha') { available.value = true; } else if (src.value !== null) { @@ -106,20 +114,34 @@ if (loaded || props.provider === 'mcaptcha' || props.provider === 'testcaptcha') } function reset() { - if (captcha.value.reset) captcha.value.reset(); + if (captcha.value.reset) { + try { + captcha.value.reset(); + } catch (error: unknown) { + // ignore + if (_DEV_) console.warn(error); + } + } testcaptchaPassed.value = false; testcaptchaInput.value = ''; } async function requestRender() { if (captcha.value.render && captchaEl.value instanceof Element) { - captcha.value.render(captchaEl.value, { - sitekey: props.sitekey, - theme: defaultStore.state.darkMode ? 'dark' : 'light', - callback: callback, - 'expired-callback': () => callback(undefined), - 'error-callback': () => callback(undefined), - }); + // 設定値の変更時などのタイミングで再レンダリングを行う際はリセットしておく必要がある + reset(); + + if (props.sitekey && props.sitekey.length > 0) { + captcha.value.render(captchaEl.value, { + sitekey: props.sitekey, + theme: defaultStore.state.darkMode ? 'dark' : 'light', + callback: callback, + 'expired-callback': () => callback(undefined), + 'error-callback': () => callback(undefined), + }); + } else { + captchaEl.value.innerHTML = ''; + } } else if (props.provider === 'mcaptcha' && props.instanceUrl && props.sitekey) { const { default: Widget } = await import('@mcaptcha/vanilla-glue'); new Widget({ diff --git a/packages/frontend/src/components/MkFormFooter.vue b/packages/frontend/src/components/MkFormFooter.vue index f409f6ce50..e23629f506 100644 --- a/packages/frontend/src/components/MkFormFooter.vue +++ b/packages/frontend/src/components/MkFormFooter.vue @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.tsx.thereAreNChanges({ n: form.modifiedCount.value }) }}
{{ i18n.ts.discard }} - {{ i18n.ts.save }} + {{ i18n.ts.save }}
@@ -26,6 +26,7 @@ const props = defineProps<{ discard: () => void; save: () => void; }; + canSaving: boolean; }>(); diff --git a/packages/frontend/src/index.html b/packages/frontend/src/index.html index 08ff0c58dd..0be589262f 100644 --- a/packages/frontend/src/index.html +++ b/packages/frontend/src/index.html @@ -18,7 +18,7 @@ http-equiv="Content-Security-Policy" content="default-src 'self' https://newassets.hcaptcha.com/ https://challenges.cloudflare.com/ http://localhost:7493/; worker-src 'self'; - script-src 'self' 'unsafe-eval' https://*.hcaptcha.com https://challenges.cloudflare.com https://esm.sh; + script-src 'self' 'unsafe-eval' https://*.hcaptcha.com https://*.recaptcha.net https://*.gstatic.com https://challenges.cloudflare.com https://esm.sh; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: www.google.com xn--931a.moe localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000; media-src 'self' localhost:3000 localhost:5173 127.0.0.1:5173 127.0.0.1:3000; diff --git a/packages/frontend/src/pages/admin/bot-protection.vue b/packages/frontend/src/pages/admin/bot-protection.vue index d07add4408..07a744a6d5 100644 --- a/packages/frontend/src/pages/admin/bot-protection.vue +++ b/packages/frontend/src/pages/admin/bot-protection.vue @@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
@@ -36,11 +36,18 @@ SPDX-License-Identifier: AGPL-3.0-only - + - + + +
+
サイトキーに"10000000-ffff-ffff-ffff-000000000001"と入力することで動作をテスト出来ます。
本番運用時には必ず正規のサイトキーを設定してください。
+ +
+
+ + + +
@@ -99,7 +121,7 @@ SPDX-License-Identifier: AGPL-3.0-only + +