From d2c44b1c39e2fff3632e6cdbcddd16792f11f3de Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Wed, 11 Jun 2025 18:16:00 +0200 Subject: [PATCH] Various frontend fixes when connected user is a domain admin --- .gitignore | 1 + frontend/src/api/account.js | 5 +++ frontend/src/api/repository.js | 11 +++++-- .../src/components/account/ProfileForm.vue | 25 +++++++++++---- .../admin/domains/DomainAdminList.vue | 1 + .../components/admin/domains/DomainList.vue | 15 ++++++--- .../admin/identities/AccountCreationForm.vue | 26 +++++++++------ .../admin/identities/AccountEditForm.vue | 31 ++++++++++++------ .../form_steps/AccountGeneralForm.vue | 7 ++++ .../form_steps/AccountMailboxForm.vue | 2 +- .../form_steps/AccountPasswordSubForm.vue | 32 ++++++------------- .../form_steps/AliasGeneralForm.vue | 1 + frontend/src/composables/permissions.js | 19 +++++++++++ frontend/src/stores/auth.store.js | 5 +++ .../src/views/admin/domains/DomainsView.vue | 5 ++- .../views/admin/identities/AccountView.vue | 10 ++++-- modoboa/admin/api/v2/serializers.py | 25 +++++++++------ modoboa/admin/api/v2/viewsets.py | 2 +- modoboa/admin/models/alias.py | 12 +++++-- modoboa/core/api/v2/.#serializers.py | 1 + 20 files changed, 162 insertions(+), 74 deletions(-) create mode 100644 frontend/src/composables/permissions.js create mode 120000 modoboa/core/api/v2/.#serializers.py diff --git a/.gitignore b/.gitignore index cdc60680c..31a3fa9ed 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ modoboa.kdev4 test_project/cert.crt test_project/cert.key test_project/envfile +test_project/media # Docker docker/collections diff --git a/frontend/src/api/account.js b/frontend/src/api/account.js index e0782641f..39e5f77b9 100644 --- a/frontend/src/api/account.js +++ b/frontend/src/api/account.js @@ -9,6 +9,11 @@ export default { checkPassword(value) { return repository.post(`/${resource}/me/password/`, { password: value }) }, + setPassword(data) { + return repository.post(`/${resource}/me/password/change/`, data, { + ignoreErrors: true, + }) + }, verifyTFACode(code) { const payload = { code } return repository.post(`${resource}/tfa/verify/`, payload) diff --git a/frontend/src/api/repository.js b/frontend/src/api/repository.js index 15725b251..459935c68 100644 --- a/frontend/src/api/repository.js +++ b/frontend/src/api/repository.js @@ -36,9 +36,16 @@ _axios.interceptors.response.use( return Promise.reject(error) } if (error.response.status !== 401 || router.currentRoute.name === 'Login') { - if (error.response.status !== 518) { + if ( + error.response.status !== 518 && + error.config && + !error.config.ignoreErrors + ) { const busStore = useBusStore() - busStore.displayNotification({ msg: error.response.data, type: 'error' }) + busStore.displayNotification({ + msg: error.response.data, + type: 'error', + }) } return Promise.reject(error) } diff --git a/frontend/src/components/account/ProfileForm.vue b/frontend/src/components/account/ProfileForm.vue index 2594d5cdd..9c5833568 100644 --- a/frontend/src/components/account/ProfileForm.vue +++ b/frontend/src/components/account/ProfileForm.vue @@ -70,7 +70,11 @@ - + {{ $gettext('Update Password') }} @@ -97,6 +101,7 @@ const account = computed(() => authStore.authUser) const form = ref({}) const profileForm = ref() const passwordForm = ref() +const passwordFormErrors = ref({}) const languages = ref([]) const panel = ref(0) const loadingUpdateProfile = ref(false) @@ -136,12 +141,20 @@ async function updatePassword() { return } loadingPasswordUpdate.value = true - authStore - .updateAccount({ password: form.value.password }) - .then(() => { - busStore.displayNotification({ msg: $gettext('Password updated') }) + try { + await authStore.updatePassword({ + password: form.value.password, + new_password: form.value.new_password, }) - .finally(() => (loadingPasswordUpdate.value = false)) + busStore.displayNotification({ msg: $gettext('Password updated') }) + passwordForm.value.reset() + } catch (err) { + if (err.status === 400) { + passwordFormErrors.value = err.response.data + } + } finally { + loadingPasswordUpdate.value = false + } } onMounted(() => { diff --git a/frontend/src/components/admin/domains/DomainAdminList.vue b/frontend/src/components/admin/domains/DomainAdminList.vue index 8b43b7073..6d705e6f4 100644 --- a/frontend/src/components/admin/domains/DomainAdminList.vue +++ b/frontend/src/components/admin/domains/DomainAdminList.vue @@ -19,6 +19,7 @@ v-model="selectedAccount" :label="$gettext('Select an account')" :items="accounts" + variant="outlined" item-title="username" class="mt-5" return-object diff --git a/frontend/src/components/admin/domains/DomainList.vue b/frontend/src/components/admin/domains/DomainList.vue index f616d1d32..e57f8be8c 100644 --- a/frontend/src/components/admin/domains/DomainList.vue +++ b/frontend/src/components/admin/domains/DomainList.vue @@ -106,7 +106,7 @@ - +
diff --git a/frontend/src/components/admin/identities/form_steps/AliasGeneralForm.vue b/frontend/src/components/admin/identities/form_steps/AliasGeneralForm.vue index 9cc31659d..2d8c5f923 100644 --- a/frontend/src/components/admin/identities/form_steps/AliasGeneralForm.vue +++ b/frontend/src/components/admin/identities/form_steps/AliasGeneralForm.vue @@ -36,6 +36,7 @@