fix(frontend): mCaptchaが動作しない問題を修正

This commit is contained in:
kakkokari-gtyih 2026-01-27 19:18:33 +09:00
parent fc7655c808
commit d4aa6a3074
3 changed files with 53 additions and 19 deletions

View File

@ -19,6 +19,7 @@
"@analytics/google-analytics": "1.1.0",
"@discordapp/twemoji": "16.0.1",
"@github/webauthn-json": "2.1.1",
"@mcaptcha/core-glue": "0.1.0-alpha-5",
"@mcaptcha/vanilla-glue": "0.1.0-rc2",
"@misskey-dev/browser-image-resizer": "2024.1.0",
"@rollup/plugin-json": "6.1.0",

View File

@ -7,8 +7,12 @@ SPDX-License-Identifier: AGPL-3.0-only
<div>
<span v-if="!available">Loading<MkEllipsis/></span>
<div v-if="props.provider == 'mcaptcha'">
<div id="mcaptcha__widget-container" class="m-captcha-style"></div>
<div ref="captchaEl"></div>
<iframe
v-if="mCaptchaIframeUrl != null"
ref="mCaptchaIframe"
:src="mCaptchaIframeUrl"
style="border: none; max-width: 320px; width: 100%; height: 100%; max-height: 80px;"
></iframe>
</div>
<div v-if="props.provider == 'testcaptcha'" style="background: #eee; border: solid 1px #888; padding: 8px; color: #000; max-width: 320px; display: flex; gap: 10px; align-items: center; box-shadow: 2px 2px 6px #0004; border-radius: 4px;">
<img src="/client-assets/testcaptcha.png" style="width: 60px; height: 60px; "/>
@ -26,7 +30,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { ref, useTemplateRef, computed, onMounted, onBeforeUnmount, watch, onUnmounted } from 'vue';
import { ref, useTemplateRef, computed, onMounted, onBeforeUnmount, watch, onUnmounted, nextTick } from 'vue';
import type Reciever_typeReferenceOnly from '@mcaptcha/core-glue';
import { store } from '@/store.js';
// APIs provided by Captcha services
@ -71,6 +76,19 @@ const available = ref(false);
const captchaEl = useTemplateRef('captchaEl');
const captchaWidgetId = ref<string | undefined>(undefined);
let mCaptchaReciever: Reciever_typeReferenceOnly | null = null;
const mCaptchaIframe = useTemplateRef('mCaptchaIframe');
const mCaptchaRemoveState = ref(false);
const mCaptchaIframeUrl = computed(() => {
if (props.provider === 'mcaptcha' && !mCaptchaRemoveState.value && props.instanceUrl && props.sitekey) {
const url = new URL('/widget', props.instanceUrl);
url.searchParams.set('sitekey', props.sitekey);
return url.toString();
}
return null;
});
const testcaptchaInput = ref('');
const testcaptchaPassed = ref(false);
@ -129,8 +147,14 @@ function reset() {
if (_DEV_) console.warn(error);
}
}
testcaptchaPassed.value = false;
testcaptchaInput.value = '';
if (mCaptchaReciever != null) {
mCaptchaReciever.destroy();
mCaptchaReciever = null;
}
}
function remove() {
@ -143,6 +167,10 @@ function remove() {
if (_DEV_) console.warn(error);
}
}
if (props.provider === 'mcaptcha') {
mCaptchaRemoveState.value = true;
}
}
async function requestRender() {
@ -160,32 +188,29 @@ async function requestRender() {
'error-callback': () => callback(undefined),
});
} else if (props.provider === 'mcaptcha' && props.instanceUrl && props.sitekey) {
const { default: Widget } = await import('@mcaptcha/vanilla-glue');
new Widget({
const { default: Reciever } = await import('@mcaptcha/core-glue');
mCaptchaReciever = new Reciever({
siteKey: {
instanceUrl: new URL(props.instanceUrl),
key: props.sitekey,
instanceUrl: new URL(props.instanceUrl),
},
}, (token: string) => {
callback(token);
});
mCaptchaReciever.listen();
mCaptchaRemoveState.value = false;
} else {
window.setTimeout(requestRender, 1);
window.setTimeout(requestRender, 50);
}
}
function clearWidget() {
if (props.provider === 'mcaptcha') {
const container = window.document.getElementById('mcaptcha__widget-container');
if (container) {
container.innerHTML = '';
}
} else {
reset();
remove();
reset();
remove();
if (captchaEl.value) {
//
captchaEl.value.innerHTML = '';
}
if (captchaEl.value) {
//
captchaEl.value.innerHTML = '';
}
}

View File

@ -659,6 +659,9 @@ importers:
'@github/webauthn-json':
specifier: 2.1.1
version: 2.1.1
'@mcaptcha/core-glue':
specifier: 0.1.0-alpha-5
version: 0.1.0-alpha-5
'@mcaptcha/vanilla-glue':
specifier: 0.1.0-rc2
version: 0.1.0-rc2(bufferutil@4.1.0)(utf-8-validate@6.0.6)
@ -2725,6 +2728,9 @@ packages:
resolution: {integrity: sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==}
hasBin: true
'@mcaptcha/core-glue@0.1.0-alpha-5':
resolution: {integrity: sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==}
'@mcaptcha/core-glue@0.1.0-rc1':
resolution: {integrity: sha512-P4SgUioJDR38QpnP9sPY72NyaYex8MXD6RbzrfKra+ngamT26XjqVZEHBiZU2RT7u0SsWhuko4N1ntNOghsgpg==}
@ -13199,6 +13205,8 @@ snapshots:
- supports-color
optional: true
'@mcaptcha/core-glue@0.1.0-alpha-5': {}
'@mcaptcha/core-glue@0.1.0-rc1': {}
'@mcaptcha/vanilla-glue@0.1.0-rc2(bufferutil@4.1.0)(utf-8-validate@6.0.6)':