fix(frontend): ユーザー登録完了時にサインインAPIを別途使用していたのを修正 (#14738)

* fix(frontend): ユーザー登録完了時にサインインAPIを別途使用していたのを修正

* emitされるオブジェクトの型を変更したことに伴う修正

* Update Changelog
This commit is contained in:
かっこかり 2024-10-10 14:05:20 +09:00 committed by GitHub
parent 4a356f1ba7
commit a624546812
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 72 additions and 59 deletions

View File

@ -4,7 +4,7 @@
- -
### Client ### Client
- - メールアドレス不要でCaptchaが有効な場合にアカウント登録完了後自動でのログインに失敗する問題を修正
### Server ### Server
- -

View File

@ -226,7 +226,7 @@ export async function openAccountMenu(opts: {
function showSigninDialog() { function showSigninDialog() {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSigninDialog.vue')), {}, { const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSigninDialog.vue')), {}, {
done: res => { done: (res: Misskey.entities.SigninFlowResponse & { finished: true }) => {
addAccount(res.id, res.i); addAccount(res.id, res.i);
success(); success();
}, },
@ -236,9 +236,9 @@ export async function openAccountMenu(opts: {
function createAccount() { function createAccount() {
const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSignupDialog.vue')), {}, { const { dispose } = popup(defineAsyncComponent(() => import('@/components/MkSignupDialog.vue')), {}, {
done: res => { done: (res: Misskey.entities.SignupResponse) => {
addAccount(res.id, res.i); addAccount(res.id, res.token);
switchAccountWithToken(res.i); switchAccountWithToken(res.token);
}, },
closed: () => dispose(), closed: () => dispose(),
}); });

View File

@ -83,7 +83,7 @@ import type { AuthenticationPublicKeyCredential } from '@github/webauthn-json/br
import type { OpenOnRemoteOptions } from '@/scripts/please-login.js'; import type { OpenOnRemoteOptions } from '@/scripts/please-login.js';
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'login', v: Misskey.entities.SigninFlowResponse): void; (ev: 'login', v: Misskey.entities.SigninFlowResponse & { finished: true }): void;
}>(); }>();
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
@ -276,7 +276,7 @@ async function tryLogin(req: Partial<Misskey.entities.SigninFlowRequest>): Promi
}); });
} }
async function onLoginSucceeded(res: Misskey.entities.SigninFlowResponse & { finished: true; }) { async function onLoginSucceeded(res: Misskey.entities.SigninFlowResponse & { finished: true }) {
if (props.autoSet) { if (props.autoSet) {
await login(res.i); await login(res.i);
} }

View File

@ -23,6 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import * as Misskey from 'misskey-js';
import { shallowRef } from 'vue'; import { shallowRef } from 'vue';
import type { OpenOnRemoteOptions } from '@/scripts/please-login.js'; import type { OpenOnRemoteOptions } from '@/scripts/please-login.js';
import MkSignin from '@/components/MkSignin.vue'; import MkSignin from '@/components/MkSignin.vue';
@ -40,7 +41,7 @@ withDefaults(defineProps<{
}); });
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'done', v: any): void; (ev: 'done', v: Misskey.entities.SigninFlowResponse & { finished: true }): void;
(ev: 'closed'): void; (ev: 'closed'): void;
(ev: 'cancelled'): void; (ev: 'cancelled'): void;
}>(); }>();
@ -52,7 +53,7 @@ function onClose() {
if (modal.value) modal.value.close(); if (modal.value) modal.value.close();
} }
function onLogin(res) { function onLogin(res: Misskey.entities.SigninFlowResponse & { finished: true }) {
emit('done', res); emit('done', res);
if (modal.value) modal.value.close(); if (modal.value) modal.value.close();
} }

View File

@ -98,7 +98,7 @@ const props = withDefaults(defineProps<{
}); });
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'signup', user: Misskey.entities.SigninFlowResponse): void; (ev: 'signup', user: Misskey.entities.SignupResponse): void;
(ev: 'signupEmailPending'): void; (ev: 'signupEmailPending'): void;
}>(); }>();
@ -250,18 +250,30 @@ async function onSubmit(): Promise<void> {
if (submitting.value) return; if (submitting.value) return;
submitting.value = true; submitting.value = true;
try { const signupPayload: Misskey.entities.SignupRequest = {
await misskeyApi('signup', { username: username.value,
username: username.value, password: password.value,
password: password.value, emailAddress: email.value,
emailAddress: email.value, invitationCode: invitationCode.value,
invitationCode: invitationCode.value, 'hcaptcha-response': hCaptchaResponse.value,
'hcaptcha-response': hCaptchaResponse.value, 'm-captcha-response': mCaptchaResponse.value,
'm-captcha-response': mCaptchaResponse.value, 'g-recaptcha-response': reCaptchaResponse.value,
'g-recaptcha-response': reCaptchaResponse.value, 'turnstile-response': turnstileResponse.value,
'turnstile-response': turnstileResponse.value, };
});
if (instance.emailRequiredForSignup) { 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({ os.alert({
type: 'success', type: 'success',
title: i18n.ts._signup.almostThere, title: i18n.ts._signup.almostThere,
@ -269,33 +281,31 @@ async function onSubmit(): Promise<void> {
}); });
emit('signupEmailPending'); emit('signupEmailPending');
} else { } else {
const res = await misskeyApi('signin-flow', { const resJson = (await res.json()) as Misskey.entities.SignupResponse;
username: username.value, if (_DEV_) console.log(resJson);
password: password.value,
});
emit('signup', res);
if (props.autoSet && res.finished) { emit('signup', resJson);
return login(res.i);
} else { if (props.autoSet) {
os.alert({ await login(resJson.token);
type: 'error',
text: i18n.ts.somethingHappened,
});
} }
} }
} catch {
submitting.value = false;
hcaptcha.value?.reset?.();
mcaptcha.value?.reset?.();
recaptcha.value?.reset?.();
turnstile.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?.();
os.alert({
type: 'error',
text: i18n.ts.somethingHappened,
});
} }
</script> </script>

View File

@ -47,7 +47,7 @@ const props = withDefaults(defineProps<{
}); });
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'done', res: Misskey.entities.SigninFlowResponse): void; (ev: 'done', res: Misskey.entities.SignupResponse): void;
(ev: 'closed'): void; (ev: 'closed'): void;
}>(); }>();
@ -55,7 +55,7 @@ const dialog = shallowRef<InstanceType<typeof MkModalWindow>>();
const isAcceptedServerRule = ref(false); const isAcceptedServerRule = ref(false);
function onSignup(res: Misskey.entities.SigninFlowResponse) { function onSignup(res: Misskey.entities.SignupResponse) {
emit('done', res); emit('done', res);
dialog.value?.close(); dialog.value?.close();
} }

View File

@ -23,7 +23,7 @@ import { acct } from '@/filters/user.js';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
user: Misskey.entities.User; user: Misskey.entities.User;
withChart: boolean; withChart?: boolean;
}>(), { }>(), {
withChart: true, withChart: true,
}); });

View File

@ -45,7 +45,7 @@ const init = async () => {
}); });
}; };
function menu(account, ev) { function menu(account: Misskey.entities.UserDetailed, ev: MouseEvent) {
os.popupMenu([{ os.popupMenu([{
text: i18n.ts.switch, text: i18n.ts.switch,
icon: 'ti ti-switch-horizontal', icon: 'ti ti-switch-horizontal',
@ -58,7 +58,7 @@ function menu(account, ev) {
}], ev.currentTarget ?? ev.target); }], ev.currentTarget ?? ev.target);
} }
function addAccount(ev) { function addAccount(ev: MouseEvent) {
os.popupMenu([{ os.popupMenu([{
text: i18n.ts.existingAccount, text: i18n.ts.existingAccount,
action: () => { addExistingAccount(); }, action: () => { addExistingAccount(); },
@ -68,14 +68,14 @@ function addAccount(ev) {
}], ev.currentTarget ?? ev.target); }], ev.currentTarget ?? ev.target);
} }
async function removeAccount(account) { async function removeAccount(account: Misskey.entities.UserDetailed) {
await _removeAccount(account.id); await _removeAccount(account.id);
accounts.value = accounts.value.filter(x => x.id !== account.id); accounts.value = accounts.value.filter(x => x.id !== account.id);
} }
function addExistingAccount() { function addExistingAccount() {
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkSigninDialog.vue')), {}, { const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkSigninDialog.vue')), {}, {
done: async res => { done: async (res: Misskey.entities.SigninFlowResponse & { finished: true }) => {
await addAccounts(res.id, res.i); await addAccounts(res.id, res.i);
os.success(); os.success();
init(); init();
@ -86,17 +86,17 @@ function addExistingAccount() {
function createAccount() { function createAccount() {
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkSignupDialog.vue')), {}, { const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkSignupDialog.vue')), {}, {
done: async res => { done: async (res: Misskey.entities.SignupResponse) => {
await addAccounts(res.id, res.i); await addAccounts(res.id, res.token);
switchAccountWithToken(res.i); switchAccountWithToken(res.token);
}, },
closed: () => dispose(), closed: () => dispose(),
}); });
} }
async function switchAccount(account: any) { async function switchAccount(account: any) {
const fetchedAccounts: any[] = await getAccounts(); const fetchedAccounts = await getAccounts();
const token = fetchedAccounts.find(x => x.id === account.id).token; const token = fetchedAccounts.find(x => x.id === account.id)!.token;
switchAccountWithToken(token); switchAccountWithToken(token);
} }

View File

@ -3095,7 +3095,9 @@ type SigninWithPasskeyRequest = {
// @public (undocumented) // @public (undocumented)
type SigninWithPasskeyResponse = { type SigninWithPasskeyResponse = {
signinResponse: SigninFlowResponse; signinResponse: SigninFlowResponse & {
finished: true;
};
}; };
// @public (undocumented) // @public (undocumented)

View File

@ -308,7 +308,7 @@ export type SigninWithPasskeyInitResponse = {
}; };
export type SigninWithPasskeyResponse = { export type SigninWithPasskeyResponse = {
signinResponse: SigninFlowResponse; signinResponse: SigninFlowResponse & { finished: true };
}; };
type Values<T extends Record<PropertyKey, unknown>> = T[keyof T]; type Values<T extends Record<PropertyKey, unknown>> = T[keyof T];