@@ -32,7 +32,11 @@ SPDX-License-Identifier: AGPL-3.0-only
32
32
<template #prefix><i class="ti ti-lock"></i></template>
33
33
<template #caption><button class="_textButton" type="button" @click="resetPassword">{{ i18n.ts.forgotPassword }}</button></template>
34
34
</MkInput>
35
- <MkButton type="submit" large primary rounded :disabled="signing" style="margin: 0 auto;">{{ signing ? i18n.ts.loggingIn : i18n.ts.login }}</MkButton>
35
+ <MkCaptcha v-if="instance.enableHcaptcha" ref="hcaptcha" v-model="hCaptchaResponse" :class="$style.captcha" provider="hcaptcha" :sitekey="instance.hcaptchaSiteKey"/>
36
+ <MkCaptcha v-if="instance.enableMcaptcha" ref="mcaptcha" v-model="mCaptchaResponse" :class="$style.captcha" provider="mcaptcha" :sitekey="instance.mcaptchaSiteKey" :instanceUrl="instance.mcaptchaInstanceUrl"/>
37
+ <MkCaptcha v-if="instance.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" :class="$style.captcha" provider="recaptcha" :sitekey="instance.recaptchaSiteKey"/>
38
+ <MkCaptcha v-if="instance.enableTurnstile" ref="turnstile" v-model="turnstileResponse" :class="$style.captcha" provider="turnstile" :sitekey="instance.turnstileSiteKey"/>
39
+ <MkButton type="submit" large primary rounded :disabled="captchaFailed || signing" style="margin: 0 auto;">{{ signing ? i18n.ts.loggingIn : i18n.ts.login }}</MkButton>
36
40
</div>
37
41
<div v-if="totpLogin" class="2fa-signin" :class="{ securityKeys: user && user.securityKeys }">
38
42
<div v-if="user && user.securityKeys" class="twofa-group tap-group">
@@ -68,7 +72,7 @@ SPDX-License-Identifier: AGPL-3.0-only
68
72
</template>
69
73
70
74
<script lang="ts" setup>
71
- import { defineAsyncComponent, ref } from 'vue';
75
+ import { computed, defineAsyncComponent, ref } from 'vue';
72
76
import { toUnicode } from 'punycode/';
73
77
import * as Misskey from 'misskey-js';
74
78
import { supported as webAuthnSupported, get as webAuthnRequest, parseRequestOptionsFromJSON } from '@github/webauthn-json/browser-ponyfill';
@@ -86,6 +90,8 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
86
90
import { login } from '@/account.js';
87
91
import { i18n } from '@/i18n.js';
88
92
import { showSystemAccountDialog } from '@/scripts/show-system-account-dialog.js';
93
+ import { instance } from '@/instance.js';
94
+ import MkCaptcha, { type Captcha } from '@/components/MkCaptcha.vue';
89
95
90
96
const signing = ref(false);
91
97
const user = ref<Misskey.entities.UserDetailed | null>(null);
@@ -99,6 +105,22 @@ const isBackupCode = ref(false);
99
105
const queryingKey = ref(false);
100
106
let credentialRequest: CredentialRequestOptions | null = null;
101
107
const passkey_context = ref('');
108
+ const hcaptcha = ref<Captcha | undefined>();
109
+ const mcaptcha = ref<Captcha | undefined>();
110
+ const recaptcha = ref<Captcha | undefined>();
111
+ const turnstile = ref<Captcha | undefined>();
112
+ const hCaptchaResponse = ref<string | null>(null);
113
+ const mCaptchaResponse = ref<string | null>(null);
114
+ const reCaptchaResponse = ref<string | null>(null);
115
+ const turnstileResponse = ref<string | null>(null);
116
+
117
+ const captchaFailed = computed((): boolean => {
118
+ return (
119
+ instance.enableHcaptcha && !hCaptchaResponse.value ||
120
+ instance.enableMcaptcha && !mCaptchaResponse.value ||
121
+ instance.enableRecaptcha && !reCaptchaResponse.value ||
122
+ instance.enableTurnstile && !turnstileResponse.value);
123
+ });
102
124
103
125
const emit = defineEmits<{
104
126
(ev: 'login', v: any): void;
@@ -233,6 +255,10 @@ function onSubmit(): void {
233
255
misskeyApi('signin', {
234
256
username: username.value,
235
257
password: password.value,
258
+ 'hcaptcha-response': hCaptchaResponse.value,
259
+ 'm-captcha-response': mCaptchaResponse.value,
260
+ 'g-recaptcha-response': reCaptchaResponse.value,
261
+ 'turnstile-response': turnstileResponse.value,
236
262
token: user.value?.twoFactorEnabled ? token.value : undefined,
237
263
}).then(res => {
238
264
emit('login', res);
@@ -242,6 +268,11 @@ function onSubmit(): void {
242
268
}
243
269
244
270
function loginFailed(err: any): void {
271
+ hcaptcha.value?.reset?.();
272
+ mcaptcha.value?.reset?.();
273
+ recaptcha.value?.reset?.();
274
+ turnstile.value?.reset?.();
275
+
245
276
switch (err.id) {
246
277
case '6cc579cc-885d-43d8-95c2-b8c7fc963280': {
247
278
os.alert({
0 commit comments