diff --git a/dashboard/src/components/dialogs/FallbackEmailDialog.vue b/dashboard/src/components/dialogs/FallbackEmailDialog.vue index 4ebdf8d4a..227c9dda3 100644 --- a/dashboard/src/components/dialogs/FallbackEmailDialog.vue +++ b/dashboard/src/components/dialogs/FallbackEmailDialog.vue @@ -32,11 +32,14 @@ async function onSubmit() { if (error) { if (error.status === 400) formError.value.email = error.body.message; else if (error.status === 412) formError.value.password = error.body.message; - else formError.value.generic = error.status ? error.body.message : 'Internal error'; + else { + formError.value.generic = error.status ? error.body.message : 'Internal error'; + console.error('Failed to set fallback email', error); + } busy.value = false; - return console.error('Failed to set email', error); + return; } emit('success'); diff --git a/dashboard/src/components/dialogs/PasswordChangeDialog.vue b/dashboard/src/components/dialogs/PasswordChangeDialog.vue new file mode 100644 index 000000000..ae6237687 --- /dev/null +++ b/dashboard/src/components/dialogs/PasswordChangeDialog.vue @@ -0,0 +1,104 @@ + + + + + + + + + {{ formError.generic }} + + + {{ $t('profile.changePassword.newPassword') }} + + {{ formError.newPassword }} + + + + {{ $t('profile.changePassword.newPasswordRepeat') }} + + {{ $t('profile.changePassword.errorPasswordsDontMatch') }} + + + + {{ $t('profile.changePassword.currentPassword') }} + + {{ formError.password }} + + + + + diff --git a/dashboard/src/components/dialogs/PrimaryEmailDialog.vue b/dashboard/src/components/dialogs/PrimaryEmailDialog.vue index 19ea6275a..9313b4928 100644 --- a/dashboard/src/components/dialogs/PrimaryEmailDialog.vue +++ b/dashboard/src/components/dialogs/PrimaryEmailDialog.vue @@ -32,11 +32,14 @@ async function onSubmit() { if (error) { if (error.status === 400) formError.value.email = error.body.message; else if (error.status === 412) formError.value.password = error.body.message; - else formError.value.generic = error.status ? error.body.message : 'Internal error'; + else { + formError.value.generic = error.status ? error.body.message : 'Internal error'; + console.error('Failed to set primary email', error); + } busy.value = false; - return console.error('Failed to set email', error); + return; } emit('success'); diff --git a/dashboard/src/models/ProfileModel.js b/dashboard/src/models/ProfileModel.js index 9f9eb6a7d..2af26baa0 100644 --- a/dashboard/src/models/ProfileModel.js +++ b/dashboard/src/models/ProfileModel.js @@ -66,17 +66,15 @@ function create() { return [null, result.body]; }, async setPassword(password, newPassword) { - let error, result; + let result; try { result = await fetcher.post(`${API_ORIGIN}/api/v1/profile/password`, { password, newPassword }, { access_token: accessToken }); } catch (e) { - error = e; + return [e]; } - if (error) return error; - if (result.status !== 204) return result; - - return null; + if (result.status !== 204) return [result]; + return [null]; }, async setDisplayName(displayName) { let error, result; diff --git a/dashboard/src/views/ProfileView.vue b/dashboard/src/views/ProfileView.vue index 9e810db1d..73470e5e2 100644 --- a/dashboard/src/views/ProfileView.vue +++ b/dashboard/src/views/ProfileView.vue @@ -12,6 +12,7 @@ import AppPasswords from '../components/AppPasswords.vue'; import SettingsItem from '../components/SettingsItem.vue'; import PrimaryEmailDialog from '../components/dialogs/PrimaryEmailDialog.vue'; import FallbackEmailDialog from '../components/dialogs/FallbackEmailDialog.vue'; +import PasswordChangeDialog from '../components/dialogs/PasswordChangeDialog.vue'; import Section from '../components/Section.vue'; import ApiTokens from '../components/ApiTokens.vue'; import ImagePicker from '../components/ImagePicker.vue'; @@ -31,6 +32,7 @@ const user = ref({}); const inputDialog = useTemplateRef('inputDialog'); const primaryEmailDialog = useTemplateRef('primaryEmailDialog'); const fallbackEmailDialog = useTemplateRef('fallbackEmailDialog'); +const passwordChangeDialog = useTemplateRef('passwordChangeDialog'); // Language selector const languages = ref([]); @@ -83,22 +85,8 @@ async function onAvatarSubmit(file) { await refreshProfile(); } -// Password changes async function onPasswordChange() { - const result = await inputDialog.value.prompt({ - message: [ t('profile.changePassword.newPassword'), t('profile.changePassword.newPasswordRepeat'), t('profile.changePassword.currentPassword') ], - type: [ 'password', 'password', 'password' ], - modal: false, - confirmLabel: t('main.dialog.save'), - confirmStyle: 'primary', - rejectLabel: t('main.dialog.cancel'), - rejectStyle: 'secondary', - }); - - if (!result || !result[0] || !result[1] || !result[2] || result[0] === result[1]) return; - - const error = await profileModel.setPassword(result[2], result[0]); - if (error) return console.error('Failed to change password', error); + passwordChangeDialog.value.open(); } @@ -214,6 +202,7 @@ onMounted(async () => { +