Skip to content

Commit 4910fff

Browse files
fix(frontend): mCaptchaが動作しない問題を修正 (#17127)
* fix(frontend): mCaptchaが動作しない問題を修正 * Update Changelog * remove mcaptcha vanila glue
1 parent fc7655c commit 4910fff

File tree

4 files changed

+63
-308
lines changed

4 files changed

+63
-308
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
- Fix: ファイルタブのセンシティブメディアを開く際に確認ダイアログを出す設定が適用されない問題を修正
2424
- Fix: 2月29日を誕生日に設定している場合、閏年以外は3月1日を誕生日として扱うように修正
2525
- Fix: `Mk:C:container``borderWidth` が正しく反映されない問題を修正
26+
- Fix: mCaptchaが正しく動作しない問題を修正
2627

2728
### Server
2829
- Enhance: OAuthのクライアント情報取得(Client Information Discovery)において、IndieWeb Living Standard 11 July 2024で定義されているJSONドキュメント形式に対応しました

packages/frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"@analytics/google-analytics": "1.1.0",
2020
"@discordapp/twemoji": "16.0.1",
2121
"@github/webauthn-json": "2.1.1",
22-
"@mcaptcha/vanilla-glue": "0.1.0-rc2",
22+
"@mcaptcha/core-glue": "0.1.0-alpha-5",
2323
"@misskey-dev/browser-image-resizer": "2024.1.0",
2424
"@rollup/plugin-json": "6.1.0",
2525
"@rollup/plugin-replace": "6.0.3",

packages/frontend/src/components/MkCaptcha.vue

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ SPDX-License-Identifier: AGPL-3.0-only
77
<div>
88
<span v-if="!available">Loading<MkEllipsis/></span>
99
<div v-if="props.provider == 'mcaptcha'">
10-
<div id="mcaptcha__widget-container" class="m-captcha-style"></div>
11-
<div ref="captchaEl"></div>
10+
<iframe
11+
v-if="mCaptchaIframeUrl != null"
12+
ref="mCaptchaIframe"
13+
:src="mCaptchaIframeUrl"
14+
style="border: none; max-width: 320px; width: 100%; height: 100%; max-height: 80px;"
15+
></iframe>
1216
</div>
1317
<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;">
1418
<img src="/client-assets/testcaptcha.png" style="width: 60px; height: 60px; "/>
@@ -26,7 +30,8 @@ SPDX-License-Identifier: AGPL-3.0-only
2630
</template>
2731

2832
<script lang="ts" setup>
29-
import { ref, useTemplateRef, computed, onMounted, onBeforeUnmount, watch, onUnmounted } from 'vue';
33+
import { ref, useTemplateRef, computed, onMounted, onBeforeUnmount, watch, onUnmounted, nextTick } from 'vue';
34+
import type Reciever_typeReferenceOnly from '@mcaptcha/core-glue';
3035
import { store } from '@/store.js';
3136
3237
// APIs provided by Captcha services
@@ -71,6 +76,19 @@ const available = ref(false);
7176
7277
const captchaEl = useTemplateRef('captchaEl');
7378
const captchaWidgetId = ref<string | undefined>(undefined);
79+
80+
let mCaptchaReciever: Reciever_typeReferenceOnly | null = null;
81+
const mCaptchaIframe = useTemplateRef('mCaptchaIframe');
82+
const mCaptchaRemoveState = ref(false);
83+
const mCaptchaIframeUrl = computed(() => {
84+
if (props.provider === 'mcaptcha' && !mCaptchaRemoveState.value && props.instanceUrl && props.sitekey) {
85+
const url = new URL('/widget', props.instanceUrl);
86+
url.searchParams.set('sitekey', props.sitekey);
87+
return url.toString();
88+
}
89+
return null;
90+
});
91+
7492
const testcaptchaInput = ref('');
7593
const testcaptchaPassed = ref(false);
7694
@@ -129,8 +147,14 @@ function reset() {
129147
if (_DEV_) console.warn(error);
130148
}
131149
}
150+
132151
testcaptchaPassed.value = false;
133152
testcaptchaInput.value = '';
153+
154+
if (mCaptchaReciever != null) {
155+
mCaptchaReciever.destroy();
156+
mCaptchaReciever = null;
157+
}
134158
}
135159
136160
function remove() {
@@ -143,6 +167,10 @@ function remove() {
143167
if (_DEV_) console.warn(error);
144168
}
145169
}
170+
171+
if (props.provider === 'mcaptcha') {
172+
mCaptchaRemoveState.value = true;
173+
}
146174
}
147175
148176
async function requestRender() {
@@ -160,32 +188,29 @@ async function requestRender() {
160188
'error-callback': () => callback(undefined),
161189
});
162190
} else if (props.provider === 'mcaptcha' && props.instanceUrl && props.sitekey) {
163-
const { default: Widget } = await import('@mcaptcha/vanilla-glue');
164-
new Widget({
191+
const { default: Reciever } = await import('@mcaptcha/core-glue');
192+
mCaptchaReciever = new Reciever({
165193
siteKey: {
166-
instanceUrl: new URL(props.instanceUrl),
167194
key: props.sitekey,
195+
instanceUrl: new URL(props.instanceUrl),
168196
},
197+
}, (token: string) => {
198+
callback(token);
169199
});
200+
mCaptchaReciever.listen();
201+
mCaptchaRemoveState.value = false;
170202
} else {
171-
window.setTimeout(requestRender, 1);
203+
window.setTimeout(requestRender, 50);
172204
}
173205
}
174206
175207
function clearWidget() {
176-
if (props.provider === 'mcaptcha') {
177-
const container = window.document.getElementById('mcaptcha__widget-container');
178-
if (container) {
179-
container.innerHTML = '';
180-
}
181-
} else {
182-
reset();
183-
remove();
208+
reset();
209+
remove();
184210
185-
if (captchaEl.value) {
186-
// レンダリング先のコンテナの中身を掃除し、フォームが増殖するのを抑止
187-
captchaEl.value.innerHTML = '';
188-
}
211+
if (captchaEl.value) {
212+
// レンダリング先のコンテナの中身を掃除し、フォームが増殖するのを抑止
213+
captchaEl.value.innerHTML = '';
189214
}
190215
}
191216

0 commit comments

Comments
 (0)