fix: 登録フォームにおける競合状態を修正 (#10267)

* fix: 登録フォームにおける競合状態を修正

* エラーを修正
This commit is contained in:
RyotaK 2023-03-08 16:32:13 +09:00 committed by GitHub
parent dd6569a1bb
commit 116dd097bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 7 deletions

View File

@ -62,6 +62,10 @@ describe('After setup instance', () => {
cy.get('[data-cy-signup-submit]').click(); cy.get('[data-cy-signup-submit]').click();
cy.wait('@signup'); cy.wait('@signup');
});
it('signup with duplicated username', () => {
cy.registerUser('alice', 'alice1234');
cy.visitHome(); cy.visitHome();

View File

@ -110,6 +110,8 @@ let ToSAgreement: boolean = $ref(false);
let hCaptchaResponse = $ref(null); let hCaptchaResponse = $ref(null);
let reCaptchaResponse = $ref(null); let reCaptchaResponse = $ref(null);
let turnstileResponse = $ref(null); let turnstileResponse = $ref(null);
let usernameAbortController: null | AbortController = $ref(null);
let emailAbortController: null | AbortController = $ref(null);
const shouldDisableSubmitting = $computed((): boolean => { const shouldDisableSubmitting = $computed((): boolean => {
return submitting || return submitting ||
@ -141,14 +143,20 @@ function onChangeUsername(): void {
} }
} }
if (usernameAbortController != null) {
usernameAbortController.abort();
}
usernameState = 'wait'; usernameState = 'wait';
usernameAbortController = new AbortController();
os.api('username/available', { os.api('username/available', {
username, username,
}).then(result => { }, undefined, usernameAbortController.signal).then(result => {
usernameState = result.available ? 'ok' : 'unavailable'; usernameState = result.available ? 'ok' : 'unavailable';
}).catch(() => { }).catch((err) => {
usernameState = 'error'; if (err.name !== 'AbortError') {
usernameState = 'error';
}
}); });
} }
@ -158,11 +166,15 @@ function onChangeEmail(): void {
return; return;
} }
if (emailAbortController != null) {
emailAbortController.abort();
}
emailState = 'wait'; emailState = 'wait';
emailAbortController = new AbortController();
os.api('email-address/available', { os.api('email-address/available', {
emailAddress: email, emailAddress: email,
}).then(result => { }, undefined, emailAbortController.signal).then(result => {
emailState = result.available ? 'ok' : emailState = result.available ? 'ok' :
result.reason === 'used' ? 'unavailable:used' : result.reason === 'used' ? 'unavailable:used' :
result.reason === 'format' ? 'unavailable:format' : result.reason === 'format' ? 'unavailable:format' :
@ -170,8 +182,10 @@ function onChangeEmail(): void {
result.reason === 'mx' ? 'unavailable:mx' : result.reason === 'mx' ? 'unavailable:mx' :
result.reason === 'smtp' ? 'unavailable:smtp' : result.reason === 'smtp' ? 'unavailable:smtp' :
'unavailable'; 'unavailable';
}).catch(() => { }).catch((err) => {
emailState = 'error'; if (err.name !== 'AbortError') {
emailState = 'error';
}
}); });
} }

View File

@ -5,7 +5,7 @@ import { $i } from '@/account';
export const pendingApiRequestsCount = ref(0); export const pendingApiRequestsCount = ref(0);
// Implements Misskey.api.ApiClient.request // Implements Misskey.api.ApiClient.request
export function api<E extends keyof Endpoints, P extends Endpoints[E]['req']>(endpoint: E, data: P = {} as any, token?: string | null | undefined): Promise<Endpoints[E]['res']> { export function api<E extends keyof Endpoints, P extends Endpoints[E]['req']>(endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise<Endpoints[E]['res']> {
pendingApiRequestsCount.value++; pendingApiRequestsCount.value++;
const onFinally = () => { const onFinally = () => {
@ -26,6 +26,7 @@ export function api<E extends keyof Endpoints, P extends Endpoints[E]['req']>(en
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
signal,
}).then(async (res) => { }).then(async (res) => {
const body = res.status === 204 ? null : await res.json(); const body = res.status === 204 ? null : await res.json();