]> source.dussan.org Git - nextcloud-server.git/commitdiff
let user choose notification email in user settings
authorArthur Schiwon <blizzz@arthur-schiwon.de>
Tue, 14 Sep 2021 21:51:48 +0000 (23:51 +0200)
committerArthur Schiwon <blizzz@arthur-schiwon.de>
Wed, 15 Sep 2021 13:38:40 +0000 (15:38 +0200)
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
apps/settings/lib/Settings/Personal/PersonalInfo.php
apps/settings/src/components/PersonalInfo/EmailSection/Email.vue
apps/settings/src/components/PersonalInfo/EmailSection/EmailSection.vue
apps/settings/src/constants/AccountPropertyConstants.js
apps/settings/src/service/PersonalInfo/EmailService.js

index 0a84f20f5135259146d71a82b4e89615c99d2f68..d03b01b3f4673cfe1747d9ab3625c179e039dc54 100644 (file)
@@ -231,7 +231,7 @@ class PersonalInfo implements ISettings {
         * @return array
         */
        private function getEmails(IAccount $account): array {
-               $primaryEmail = [
+               $systemEmail = [
                        'value' => $account->getProperty(IAccountManager::PROPERTY_EMAIL)->getValue(),
                        'scope' => $account->getProperty(IAccountManager::PROPERTY_EMAIL)->getScope(),
                        'verified' => $account->getProperty(IAccountManager::PROPERTY_EMAIL)->getVerified(),
@@ -249,8 +249,9 @@ class PersonalInfo implements ISettings {
                );
 
                $emails = [
-                       'primaryEmail' => $primaryEmail,
+                       'primaryEmail' => $systemEmail,
                        'additionalEmails' => $additionalEmails,
+                       'notificationEmail' => (string)$account->getUser()->getPrimaryEMailAddress(),
                ];
 
                return $emails;
index 294283ffbaabbf49215f77e24a1a94174b0f931b..8095152fd43885aec3db454a2a3d5dc0d6ff23c9 100644 (file)
                                                @click.stop.prevent="deleteEmail">
                                                {{ deleteEmailLabel }}
                                        </ActionButton>
+                                       <ActionButton
+                                               :aria-label="setNotificationMailLabel"
+                                               :close-after-click="true"
+                                               :disabled="setNotificationDisabled"
+                                               icon="icon-favorite"
+                                               @click.stop.prevent="setNotificationMail">
+                                               {{ setNotificationMailLabel }}
+                                       </ActionButton>
                                </Actions>
                        </div>
                </div>
 
-               <em v-if="primary">
+               <em v-if="isNotificationEmail">
                        {{ t('settings', 'Primary email for password reset and notifications') }}
                </em>
        </div>
 <script>
 import Actions from '@nextcloud/vue/dist/Components/Actions'
 import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
-import { showError } from '@nextcloud/dialogs'
+import {showError} from '@nextcloud/dialogs'
 import debounce from 'debounce'
 
 import FederationControl from '../shared/FederationControl'
 
-import { ACCOUNT_PROPERTY_READABLE_ENUM } from '../../../constants/AccountPropertyConstants'
-import { savePrimaryEmail, saveAdditionalEmail, saveAdditionalEmailScope, updateAdditionalEmail, removeAdditionalEmail } from '../../../service/PersonalInfo/EmailService'
-import { validateEmail } from '../../../utils/validate'
+import {ACCOUNT_PROPERTY_READABLE_ENUM} from '../../../constants/AccountPropertyConstants'
+import {
+       removeAdditionalEmail,
+       saveAdditionalEmail,
+       saveAdditionalEmailScope,
+       saveNotificationEmail,
+       savePrimaryEmail,
+       updateAdditionalEmail
+} from '../../../service/PersonalInfo/EmailService'
+import {validateEmail} from '../../../utils/validate'
 
 export default {
        name: 'Email',
@@ -113,6 +128,10 @@ export default {
                        type: String,
                        required: true,
                },
+               activeNotificationEmail: {
+                       type: String,
+                       default: '',
+               },
        },
 
        data() {
@@ -123,6 +142,8 @@ export default {
                        saveAdditionalEmailScope,
                        showCheckmarkIcon: false,
                        showErrorIcon: false,
+                       isNotificationEmail: (this.email === this.activeNotificationEmail)
+                               || (this.primary && this.activeNotificationEmail === ''),
                }
        },
 
@@ -145,6 +166,17 @@ export default {
                        return t('settings', 'Delete email')
                },
 
+         setNotificationDisabled() {
+                       return this.isNotificationEmail
+               },
+
+         setNotificationMailLabel() {
+                       if (this.isNotificationEmail) {
+                               return t('settings', 'Your primary email')
+                       }
+                       return t('settings', 'Set as primary mail')
+               },
+
                federationDisabled() {
                        return !this.initialEmail
                },
@@ -239,6 +271,21 @@ export default {
                        }
                },
 
+               async setNotificationMail() {
+                 try {
+                         const responseData = await saveNotificationEmail(this.primary ? '' : this.initialEmail)
+                         this.handleResponse({
+                                 notificationEmail: this.primary ? '' : this.initialEmail,
+                                 status: responseData.ocs?.meta?.status,
+                         })
+                 } catch (e) {
+                         this.handleResponse({
+                                 errorMessage: 'Unable to choose this email for notifications',
+                                 error: e,
+                         })
+                 }
+               },
+
                async updateAdditionalEmail(email) {
                        try {
                                const responseData = await updateAdditionalEmail(this.initialEmail, email)
@@ -276,10 +323,14 @@ export default {
                        }
                },
 
-               handleResponse({ email, status, errorMessage, error }) {
+               handleResponse({ email, notificationEmail, status, errorMessage, error }) {
                        if (status === 'ok') {
                                // Ensure that local state reflects server state
-                               this.initialEmail = email
+                               if (email) {
+                                       this.initialEmail = email
+                               } else if (notificationEmail) {
+                                       this.activeNotificationEmail = notificationEmail
+                               }
                                this.showCheckmarkIcon = true
                                setTimeout(() => { this.showCheckmarkIcon = false }, 2000)
                        } else {
index 0ae18a6fe9b3c6f46f61214839e522569c612c84..709029e1894d7e46e7a5ff2b60e8b82f462e3596 100644 (file)
@@ -36,6 +36,7 @@
                                :primary="true"
                                :scope.sync="primaryEmail.scope"
                                :email.sync="primaryEmail.value"
+                               :active-notification-email.sync="notificationEmail"
                                @update:email="onUpdateEmail" />
                </template>
                <span v-else>
@@ -46,6 +47,7 @@
                        :index="index"
                        :scope.sync="additionalEmail.scope"
                        :email.sync="additionalEmail.value"
+                       :active-notification-email.sync="notificationEmail"
                        @update:email="onUpdateEmail"
                        @delete-additional-email="onDeleteAdditionalEmail(index)" />
        </section>
@@ -62,7 +64,7 @@ import { ACCOUNT_PROPERTY_READABLE_ENUM, DEFAULT_ADDITIONAL_EMAIL_SCOPE } from '
 import { savePrimaryEmail, savePrimaryEmailScope, removeAdditionalEmail } from '../../../service/PersonalInfo/EmailService'
 import { validateEmail } from '../../../utils/validate'
 
-const { emails: { additionalEmails, primaryEmail } } = loadState('settings', 'personalInfoParameters', {})
+const { emails: { additionalEmails, primaryEmail, notificationEmail } } = loadState('settings', 'personalInfoParameters', {})
 const { displayNameChangeSupported } = loadState('settings', 'accountParameters', {})
 
 export default {
@@ -80,6 +82,7 @@ export default {
                        displayNameChangeSupported,
                        primaryEmail,
                        savePrimaryEmailScope,
+                       notificationEmail,
                }
        },
 
@@ -126,6 +129,10 @@ export default {
                        }
                },
 
+               async onUpdateNotificationEmail(email) {
+                       this.notificationEmail = email
+               },
+
                async updatePrimaryEmail() {
                        try {
                                const responseData = await savePrimaryEmail(this.primaryEmailValue)
index 0288ee679ce66a30a4b7c1407bd681d147f576e1..9d3fd4ee97b1e078c6d411253a4c25cc612d498a 100644 (file)
@@ -33,6 +33,7 @@ export const ACCOUNT_PROPERTY_ENUM = Object.freeze({
        DISPLAYNAME: 'displayname',
        EMAIL: 'email',
        EMAIL_COLLECTION: 'additional_mail',
+       NOTIFICATION_EMAIL: 'notify_email',
        PHONE: 'phone',
        TWITTER: 'twitter',
        WEBSITE: 'website',
index 00e2373736c76d4b16a4699c81fa33c746bb784e..a1f7a57f72b3f95d074130a03b109d0aaaa7c40e 100644 (file)
@@ -69,6 +69,26 @@ export const saveAdditionalEmail = async(email) => {
        return res.data
 }
 
+/**
+ * Save the notification email of the user
+ *
+ * @param {string} email the notification email
+ * @returns {object}
+ */
+export const saveNotificationEmail = async(email) => {
+       const userId = getCurrentUser().uid
+       const url = generateOcsUrl('cloud/users/{userId}', { userId })
+
+       await confirmPassword()
+
+       const res = await axios.put(url, {
+               key: ACCOUNT_PROPERTY_ENUM.NOTIFICATION_EMAIL,
+               value: email,
+       })
+
+       return res.data
+}
+
 /**
  * Remove an additional email of the user
  *