@@ -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';
@@ -85,6 +89,8 @@ import * as os from '@/os.js';
85
89
import { misskeyApi } from '@/scripts/misskey-api.js';
86
90
import { login } from '@/account.js';
87
91
import { i18n } from '@/i18n.js';
92
+ import { instance } from '@/instance.js';
93
+ import MkCaptcha, { type Captcha } from '@/components/MkCaptcha.vue';
88
94
89
95
const signing = ref(false);
90
96
const user = ref<Misskey.entities.UserDetailed | null>(null);
@@ -98,6 +104,22 @@ const isBackupCode = ref(false);
98
104
const queryingKey = ref(false);
99
105
let credentialRequest: CredentialRequestOptions | null = null;
100
106
const passkey_context = ref('');
107
+ const hcaptcha = ref<Captcha | undefined>();
108
+ const mcaptcha = ref<Captcha | undefined>();
109
+ const recaptcha = ref<Captcha | undefined>();
110
+ const turnstile = ref<Captcha | undefined>();
111
+ const hCaptchaResponse = ref<string | null>(null);
112
+ const mCaptchaResponse = ref<string | null>(null);
113
+ const reCaptchaResponse = ref<string | null>(null);
114
+ const turnstileResponse = ref<string | null>(null);
115
+
116
+ const captchaFailed = computed((): boolean => {
117
+ return (
118
+ instance.enableHcaptcha && !hCaptchaResponse.value ||
119
+ instance.enableMcaptcha && !mCaptchaResponse.value ||
120
+ instance.enableRecaptcha && !reCaptchaResponse.value ||
121
+ instance.enableTurnstile && !turnstileResponse.value);
122
+ });
101
123
102
124
const emit = defineEmits<{
103
125
(ev: 'login', v: any): void;
@@ -227,6 +249,10 @@ function onSubmit(): void {
227
249
misskeyApi('signin', {
228
250
username: username.value,
229
251
password: password.value,
252
+ 'hcaptcha-response': hCaptchaResponse.value,
253
+ 'm-captcha-response': mCaptchaResponse.value,
254
+ 'g-recaptcha-response': reCaptchaResponse.value,
255
+ 'turnstile-response': turnstileResponse.value,
230
256
token: user.value?.twoFactorEnabled ? token.value : undefined,
231
257
}).then(res => {
232
258
emit('login', res);
@@ -236,6 +262,11 @@ function onSubmit(): void {
236
262
}
237
263
238
264
function loginFailed(err: any): void {
265
+ hcaptcha.value?.reset?.();
266
+ mcaptcha.value?.reset?.();
267
+ recaptcha.value?.reset?.();
268
+ turnstile.value?.reset?.();
269
+
239
270
switch (err.id) {
240
271
case '6cc579cc-885d-43d8-95c2-b8c7fc963280': {
241
272
os.alert({
0 commit comments