From 1ea4469bec4d445cfdbe8648f2f361ff5f8a546f Mon Sep 17 00:00:00 2001 From: Kagami Sascha Rosylight Date: Sat, 11 Mar 2023 06:32:13 +0100 Subject: [PATCH] fix(frontend/MkSignup): prevent uncaught errors from interrupted signup (#10265) * fix(frontend/MkSignup): prevent uncaught errors from interrupted signup * nullable sitekey --------- Co-authored-by: tamaina --- .../frontend/src/components/MkCaptcha.vue | 5 +- packages/frontend/src/components/MkSignup.vue | 52 +++++++++---------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/packages/frontend/src/components/MkCaptcha.vue b/packages/frontend/src/components/MkCaptcha.vue index c72cc2ab1b..1875b507ca 100644 --- a/packages/frontend/src/components/MkCaptcha.vue +++ b/packages/frontend/src/components/MkCaptcha.vue @@ -10,7 +10,8 @@ import { ref, shallowRef, computed, onMounted, onBeforeUnmount, watch } from 'vu import { defaultStore } from '@/store'; import { i18n } from '@/i18n'; -type Captcha = { +// APIs provided by Captcha services +export type Captcha = { render(container: string | Node, options: { readonly [_ in 'sitekey' | 'theme' | 'type' | 'size' | 'tabindex' | 'callback' | 'expired' | 'expired-callback' | 'error-callback' | 'endpoint']?: unknown; }): string; @@ -32,7 +33,7 @@ declare global { const props = defineProps<{ provider: CaptchaProvider; - sitekey: string; + sitekey: string | null; // null will show error on request modelValue?: string | null; }>(); diff --git a/packages/frontend/src/components/MkSignup.vue b/packages/frontend/src/components/MkSignup.vue index 22a8063809..30279148f8 100644 --- a/packages/frontend/src/components/MkSignup.vue +++ b/packages/frontend/src/components/MkSignup.vue @@ -72,7 +72,7 @@ import { toUnicode } from 'punycode/'; import MkButton from './MkButton.vue'; import MkInput from './MkInput.vue'; import MkSwitch from './MkSwitch.vue'; -import MkCaptcha from '@/components/MkCaptcha.vue'; +import MkCaptcha, { type Captcha } from '@/components/MkCaptcha.vue'; import * as config from '@/config'; import * as os from '@/os'; import { login } from '@/account'; @@ -92,9 +92,9 @@ const emit = defineEmits<{ const host = toUnicode(config.host); -let hcaptcha = $ref(); -let recaptcha = $ref(); -let turnstile = $ref(); +let hcaptcha = $ref(); +let recaptcha = $ref(); +let turnstile = $ref(); let username: string = $ref(''); let password: string = $ref(''); @@ -208,19 +208,20 @@ function onChangePasswordRetype(): void { passwordRetypeState = password === retypedPassword ? 'match' : 'not-match'; } -function onSubmit(): void { +async function onSubmit(): Promise { if (submitting) return; submitting = true; - os.api('signup', { - username, - password, - emailAddress: email, - invitationCode, - 'hcaptcha-response': hCaptchaResponse, - 'g-recaptcha-response': reCaptchaResponse, - 'turnstile-response': turnstileResponse, - }).then(() => { + try { + await os.api('signup', { + username, + password, + emailAddress: email, + invitationCode, + 'hcaptcha-response': hCaptchaResponse, + 'g-recaptcha-response': reCaptchaResponse, + 'turnstile-response': turnstileResponse, + }); if (instance.emailRequiredForSignup) { os.alert({ type: 'success', @@ -229,28 +230,27 @@ function onSubmit(): void { }); emit('signupEmailPending'); } else { - os.api('signin', { + const res = await os.api('signin', { username, password, - }).then(res => { - emit('signup', res); - - if (props.autoSet) { - login(res.i); - } }); + emit('signup', res); + + if (props.autoSet) { + return login(res.i); + } } - }).catch(() => { + } catch { submitting = false; - hcaptcha.reset?.(); - recaptcha.reset?.(); - turnstile.reset?.(); + hcaptcha?.reset?.(); + recaptcha?.reset?.(); + turnstile?.reset?.(); os.alert({ type: 'error', text: i18n.ts.somethingHappened, }); - }); + } }