fix(frontend): ユーザー登録完了時にサインインAPIを別途使用していたのを修正 (#14738)
* fix(frontend): ユーザー登録完了時にサインインAPIを別途使用していたのを修正 * emitされるオブジェクトの型を変更したことに伴う修正 * Update Changelog
This commit is contained in:
parent
4a356f1ba7
commit
a624546812
10 changed files with 72 additions and 59 deletions
|
@ -4,7 +4,7 @@
|
||||||
-
|
-
|
||||||
|
|
||||||
### Client
|
### Client
|
||||||
-
|
- メールアドレス不要でCaptchaが有効な場合にアカウント登録完了後自動でのログインに失敗する問題を修正
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
-
|
-
|
||||||
|
|
|
@ -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(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3095,7 +3095,9 @@ type SigninWithPasskeyRequest = {
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
type SigninWithPasskeyResponse = {
|
type SigninWithPasskeyResponse = {
|
||||||
signinResponse: SigninFlowResponse;
|
signinResponse: SigninFlowResponse & {
|
||||||
|
finished: true;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in a new issue