Merge tag '2024.10.1' into feature/2024.10
This commit is contained in:
commit
f079edaf3c
454 changed files with 9728 additions and 3363 deletions
|
|
@ -21,12 +21,12 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template #caption>
|
||||
<div><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.cannotBeChangedLater }}</div>
|
||||
<span v-if="usernameState === 'wait'" style="color:#999"><MkLoading :em="true"/> {{ i18n.ts.checking }}</span>
|
||||
<span v-else-if="usernameState === 'ok'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
|
||||
<span v-else-if="usernameState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
|
||||
<span v-else-if="usernameState === 'error'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
|
||||
<span v-else-if="usernameState === 'invalid-format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.usernameInvalidFormat }}</span>
|
||||
<span v-else-if="usernameState === 'min-range'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooShort }}</span>
|
||||
<span v-else-if="usernameState === 'max-range'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooLong }}</span>
|
||||
<span v-else-if="usernameState === 'ok'" style="color: var(--MI_THEME-success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
|
||||
<span v-else-if="usernameState === 'unavailable'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
|
||||
<span v-else-if="usernameState === 'error'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
|
||||
<span v-else-if="usernameState === 'invalid-format'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.usernameInvalidFormat }}</span>
|
||||
<span v-else-if="usernameState === 'min-range'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooShort }}</span>
|
||||
<span v-else-if="usernameState === 'max-range'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.tooLong }}</span>
|
||||
</template>
|
||||
</MkInput>
|
||||
<MkInput v-if="instance.emailRequiredForSignup" v-model="email" :debounce="true" type="email" :spellcheck="false" required data-cy-signup-email @update:modelValue="onChangeEmail">
|
||||
|
|
@ -34,32 +34,32 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<template #prefix><i class="ti ti-mail"></i></template>
|
||||
<template #caption>
|
||||
<span v-if="emailState === 'wait'" style="color:#999"><MkLoading :em="true"/> {{ i18n.ts.checking }}</span>
|
||||
<span v-else-if="emailState === 'ok'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:used'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:format'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:banned'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.banned }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
|
||||
<span v-else-if="emailState === 'unavailable'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
|
||||
<span v-else-if="emailState === 'error'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
|
||||
<span v-else-if="emailState === 'ok'" style="color: var(--MI_THEME-success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.available }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:used'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.used }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:format'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.format }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:disposable'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.disposable }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:banned'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.banned }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:mx'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.mx }}</span>
|
||||
<span v-else-if="emailState === 'unavailable:smtp'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts._emailUnavailable.smtp }}</span>
|
||||
<span v-else-if="emailState === 'unavailable'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.unavailable }}</span>
|
||||
<span v-else-if="emailState === 'error'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.error }}</span>
|
||||
</template>
|
||||
</MkInput>
|
||||
<MkInput v-model="password" type="password" autocomplete="new-password" required data-cy-signup-password @update:modelValue="onChangePassword">
|
||||
<template #label>{{ i18n.ts.password }}</template>
|
||||
<template #prefix><i class="ti ti-lock"></i></template>
|
||||
<template #caption>
|
||||
<span v-if="passwordStrength == 'low'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.weakPassword }}</span>
|
||||
<span v-if="passwordStrength == 'medium'" style="color: var(--warn)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.normalPassword }}</span>
|
||||
<span v-if="passwordStrength == 'high'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.strongPassword }}</span>
|
||||
<span v-if="passwordStrength == 'low'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.weakPassword }}</span>
|
||||
<span v-if="passwordStrength == 'medium'" style="color: var(--MI_THEME-warn)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.normalPassword }}</span>
|
||||
<span v-if="passwordStrength == 'high'" style="color: var(--MI_THEME-success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.strongPassword }}</span>
|
||||
</template>
|
||||
</MkInput>
|
||||
<MkInput v-model="retypedPassword" type="password" autocomplete="new-password" required data-cy-signup-password-retype @update:modelValue="onChangePasswordRetype">
|
||||
<template #label>{{ i18n.ts.password }} ({{ i18n.ts.retype }})</template>
|
||||
<template #prefix><i class="ti ti-lock"></i></template>
|
||||
<template #caption>
|
||||
<span v-if="passwordRetypeState == 'match'" style="color: var(--success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.passwordMatched }}</span>
|
||||
<span v-if="passwordRetypeState == 'not-match'" style="color: var(--error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.passwordNotMatched }}</span>
|
||||
<span v-if="passwordRetypeState == 'match'" style="color: var(--MI_THEME-success)"><i class="ti ti-check ti-fw"></i> {{ i18n.ts.passwordMatched }}</span>
|
||||
<span v-if="passwordRetypeState == 'not-match'" style="color: var(--MI_THEME-error)"><i class="ti ti-alert-triangle ti-fw"></i> {{ i18n.ts.passwordNotMatched }}</span>
|
||||
</template>
|
||||
</MkInput>
|
||||
<MkInput v-if="instance.approvalRequiredForSignup" v-model="reason" type="text" :spellcheck="false" required data-cy-signup-reason>
|
||||
|
|
@ -71,6 +71,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkCaptcha v-if="instance.enableRecaptcha" ref="recaptcha" v-model="reCaptchaResponse" :class="$style.captcha" provider="recaptcha" :sitekey="instance.recaptchaSiteKey"/>
|
||||
<MkCaptcha v-if="instance.enableTurnstile" ref="turnstile" v-model="turnstileResponse" :class="$style.captcha" provider="turnstile" :sitekey="instance.turnstileSiteKey"/>
|
||||
<MkCaptcha v-if="instance.enableFC" ref="fc" v-model="fcResponse" :class="$style.captcha" provider="fc" :sitekey="instance.fcSiteKey"/>
|
||||
<MkCaptcha v-if="instance.enableTestcaptcha" ref="testcaptcha" v-model="testcaptchaResponse" :class="$style.captcha" provider="testcaptcha"/>
|
||||
<MkButton type="submit" :disabled="shouldDisableSubmitting" large gradate rounded data-cy-signup-submit style="margin: 0 auto;">
|
||||
<template v-if="submitting">
|
||||
<MkLoading :em="true" :colored="false"/>
|
||||
|
|
@ -86,10 +87,10 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
import { ref, computed } from 'vue';
|
||||
import { toUnicode } from 'punycode/';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import * as config from '@@/js/config.js';
|
||||
import MkButton from './MkButton.vue';
|
||||
import MkInput from './MkInput.vue';
|
||||
import MkCaptcha, { type Captcha } from '@/components/MkCaptcha.vue';
|
||||
import * as config from '@@/js/config.js';
|
||||
import * as os from '@/os.js';
|
||||
import { misskeyApi } from '@/scripts/misskey-api.js';
|
||||
import { login } from '@/account.js';
|
||||
|
|
@ -103,7 +104,7 @@ const props = withDefaults(defineProps<{
|
|||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: 'signup', user: Misskey.entities.SigninResponse): void;
|
||||
(ev: 'signup', user: Misskey.entities.SignupResponse): void;
|
||||
(ev: 'signupEmailPending'): void;
|
||||
(ev: 'approvalPending'): void;
|
||||
}>();
|
||||
|
|
@ -111,9 +112,11 @@ const emit = defineEmits<{
|
|||
const host = toUnicode(config.host);
|
||||
|
||||
const hcaptcha = ref<Captcha | undefined>();
|
||||
const mcaptcha = ref<Captcha | undefined>();
|
||||
const recaptcha = ref<Captcha | undefined>();
|
||||
const turnstile = ref<Captcha | undefined>();
|
||||
const fc = ref<Captcha | undefined>();
|
||||
const testcaptcha = ref<Captcha | undefined>();
|
||||
|
||||
const username = ref<string>('');
|
||||
const password = ref<string>('');
|
||||
|
|
@ -131,6 +134,7 @@ const mCaptchaResponse = ref<string | null>(null);
|
|||
const reCaptchaResponse = ref<string | null>(null);
|
||||
const turnstileResponse = ref<string | null>(null);
|
||||
const fcResponse = ref<string | null>(null);
|
||||
const testcaptchaResponse = ref<string | null>(null);
|
||||
const usernameAbortController = ref<null | AbortController>(null);
|
||||
const emailAbortController = ref<null | AbortController>(null);
|
||||
|
||||
|
|
@ -141,6 +145,7 @@ const shouldDisableSubmitting = computed((): boolean => {
|
|||
instance.enableRecaptcha && !reCaptchaResponse.value ||
|
||||
instance.enableTurnstile && !turnstileResponse.value ||
|
||||
instance.enableFC && !fcResponse.value ||
|
||||
instance.enableTestcaptcha && !testcaptchaResponse.value ||
|
||||
instance.emailRequiredForSignup && emailState.value !== 'ok' ||
|
||||
usernameState.value !== 'ok' ||
|
||||
passwordRetypeState.value !== 'match';
|
||||
|
|
@ -259,20 +264,33 @@ async function onSubmit(): Promise<void> {
|
|||
if (submitting.value) return;
|
||||
submitting.value = true;
|
||||
|
||||
try {
|
||||
await misskeyApi('signup', {
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
emailAddress: email.value,
|
||||
invitationCode: invitationCode.value,
|
||||
reason: reason.value,
|
||||
'hcaptcha-response': hCaptchaResponse.value,
|
||||
'm-captcha-response': mCaptchaResponse.value,
|
||||
'g-recaptcha-response': reCaptchaResponse.value,
|
||||
'turnstile-response': turnstileResponse.value,
|
||||
'frc-captcha-solution': fcResponse.value,
|
||||
});
|
||||
if (instance.emailRequiredForSignup) {
|
||||
const signupPayload: Misskey.entities.SignupRequest = {
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
emailAddress: email.value,
|
||||
invitationCode: invitationCode.value,
|
||||
reason: reason.value,
|
||||
'hcaptcha-response': hCaptchaResponse.value,
|
||||
'm-captcha-response': mCaptchaResponse.value,
|
||||
'g-recaptcha-response': reCaptchaResponse.value,
|
||||
'turnstile-response': turnstileResponse.value,
|
||||
'frc-captcha-solution': fcResponse.value,
|
||||
'testcaptcha-response': testcaptchaResponse.value,
|
||||
};
|
||||
|
||||
const res = await fetch(`${config.apiUrl}/signup`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(signupPayload),
|
||||
}).catch(() => {
|
||||
onSignupApiError();
|
||||
return null;
|
||||
});
|
||||
|
||||
if (res) {
|
||||
if (res.status === 204 || instance.emailRequiredForSignup) {
|
||||
os.alert({
|
||||
type: 'success',
|
||||
title: i18n.ts._signup.almostThere,
|
||||
|
|
@ -287,28 +305,33 @@ async function onSubmit(): Promise<void> {
|
|||
});
|
||||
emit('approvalPending');
|
||||
} else {
|
||||
const res = await misskeyApi('signin', {
|
||||
username: username.value,
|
||||
password: password.value,
|
||||
});
|
||||
emit('signup', res);
|
||||
const resJson = (await res.json()) as Misskey.entities.SignupResponse;
|
||||
if (_DEV_) console.log(resJson);
|
||||
|
||||
emit('signup', resJson);
|
||||
|
||||
if (props.autoSet) {
|
||||
return login(res.i);
|
||||
await login(resJson.token);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
submitting.value = false;
|
||||
hcaptcha.value?.reset?.();
|
||||
recaptcha.value?.reset?.();
|
||||
turnstile.value?.reset?.();
|
||||
fc.value?.reset?.();
|
||||
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: i18n.ts.somethingHappened,
|
||||
});
|
||||
}
|
||||
|
||||
submitting.value = false;
|
||||
}
|
||||
|
||||
function onSignupApiError() {
|
||||
submitting.value = false;
|
||||
hcaptcha.value?.reset?.();
|
||||
mcaptcha.value?.reset?.();
|
||||
recaptcha.value?.reset?.();
|
||||
turnstile.value?.reset?.();
|
||||
fc.value?.reset?.();
|
||||
testcaptcha.value?.reset?.();
|
||||
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: i18n.ts.somethingHappened,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -317,8 +340,8 @@ async function onSubmit(): Promise<void> {
|
|||
padding: 16px;
|
||||
text-align: center;
|
||||
font-size: 26px;
|
||||
background-color: var(--accentedBg);
|
||||
color: var(--accent);
|
||||
background-color: var(--MI_THEME-accentedBg);
|
||||
color: var(--MI_THEME-accent);
|
||||
}
|
||||
|
||||
.captcha {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue