diff options
author | nztqa <nztqa@users.noreply.github.com> | 2017-08-07 17:40:50 +0900 |
---|---|---|
committer | nztqa <nztqa@users.noreply.github.com> | 2017-08-07 17:40:50 +0900 |
commit | 6a10257fd7230d08d9a64fc4877e85972375498d (patch) | |
tree | 263bed8ce542bda6f31f09eb521362c76b3c3440 | |
parent | 57219df16afbc0c512e15ed9801308591b41d318 (diff) | |
download | wekan-6a10257fd7230d08d9a64fc4877e85972375498d.tar.gz wekan-6a10257fd7230d08d9a64fc4877e85972375498d.tar.bz2 wekan-6a10257fd7230d08d9a64fc4877e85972375498d.zip |
Add change email address
Set allow email change in admin panel
-rw-r--r-- | .eslintrc.json | 3 | ||||
-rw-r--r-- | client/components/settings/settingBody.jade | 16 | ||||
-rw-r--r-- | client/components/settings/settingBody.js | 22 | ||||
-rw-r--r-- | client/components/users/userHeader.jade | 8 | ||||
-rw-r--r-- | client/components/users/userHeader.js | 43 | ||||
-rw-r--r-- | i18n/en.i18n.json | 7 | ||||
-rw-r--r-- | models/accountSettings.js | 33 | ||||
-rw-r--r-- | models/users.js | 22 | ||||
-rw-r--r-- | server/publications/accountSettings.js | 3 |
9 files changed, 153 insertions, 4 deletions
diff --git a/.eslintrc.json b/.eslintrc.json index c1ee03b8..51b2037f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -129,6 +129,7 @@ "JsonRoutes": true, "Authentication": true, "Integrations": true, - "HTTP": true + "HTTP": true, + "AccountSettings": true } } diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index 1c6e3b7f..5864efd5 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -12,6 +12,8 @@ template(name="setting") a.js-setting-menu(data-id="registration-setting") {{_ 'registration'}} li a.js-setting-menu(data-id="email-setting") {{_ 'email'}} + li + a.js-setting-menu(data-id="account-setting") {{_ 'accounts'}} .main-body if loading.get +spinner @@ -19,6 +21,8 @@ template(name="setting") +general else if emailSetting.get +email + else if accountSetting.get + +accountSettings template(name="general") ul#registration-setting.setting-detail @@ -80,3 +84,15 @@ template(name='email') li button.js-save.primary {{_ 'save'}} + +template(name='accountSettings') + ul#account-setting.setting-detail + li.smtp-form + .title {{_ 'accounts-allowEmailChange'}} + .form-group.flex + input.form-control#accounts-allowEmailChange(type="radio" name="allowEmailChange" value="true" checked="{{#if allowEmailChange}}checked{{/if}}") + span {{_ 'yes'}} + input.form-control#accounts-allowEmailChange(type="radio" name="allowEmailChange" value="false" checked="{{#unless allowEmailChange}}checked{{/unless}}") + span {{_ 'no'}} + li + button.js-accounts-save.primary {{_ 'save'}} diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js index f96312a5..a2993426 100644 --- a/client/components/settings/settingBody.js +++ b/client/components/settings/settingBody.js @@ -1,5 +1,6 @@ Meteor.subscribe('setting'); Meteor.subscribe('mailServer'); +Meteor.subscribe('accountSettings'); BlazeComponent.extendComponent({ onCreated() { @@ -7,6 +8,7 @@ BlazeComponent.extendComponent({ this.loading = new ReactiveVar(false); this.generalSetting = new ReactiveVar(true); this.emailSetting = new ReactiveVar(false); + this.accountSetting = new ReactiveVar(false); }, setError(error) { @@ -62,6 +64,7 @@ BlazeComponent.extendComponent({ const targetID = target.data('id'); this.generalSetting.set('registration-setting' === targetID); this.emailSetting.set('email-setting' === targetID); + this.accountSetting.set('account-setting' === targetID); } }, @@ -130,3 +133,22 @@ BlazeComponent.extendComponent({ }]; }, }).register('setting'); + +BlazeComponent.extendComponent({ + saveAllowEmailChange() { + const allowEmailChange = ($('input[name=allowEmailChange]:checked').val() === 'true'); + AccountSettings.update('accounts-allowEmailChange', { + $set: { 'booleanValue': allowEmailChange }, + }); + }, + + allowEmailChange() { + return AccountSettings.findOne('accounts-allowEmailChange').booleanValue; + }, + + events() { + return [{ + 'click button.js-accounts-save': this.saveAllowEmailChange, + }]; + }, +}).register('accountSettings'); diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 84ef5a09..f67f82ee 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -36,6 +36,14 @@ template(name="editProfilePopup") label | {{_ 'initials'}} input.js-profile-initials(type="text" value=profile.initials) + label + | {{_ 'email'}} + span.error.hide.email-taken + | {{_ 'error-email-taken'}} + if allowEmailChange + input.js-profile-email(type="email" value="{{emails.[0].address}}") + else + input.js-profile-email(type="email" value="{{emails.[0].address}}" readonly) input.primary.wide(type="submit" value="{{_ 'save'}}") template(name="editNotificationPopup") diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 0580092e..90205ee1 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -20,18 +20,47 @@ Template.memberMenuPopup.events({ }, }); +Template.editProfilePopup.helpers({ + allowEmailChange() { + return AccountSettings.findOne('accounts-allowEmailChange').booleanValue; + }, +}); + Template.editProfilePopup.events({ submit(evt, tpl) { evt.preventDefault(); const fullname = tpl.find('.js-profile-fullname').value.trim(); const username = tpl.find('.js-profile-username').value.trim(); const initials = tpl.find('.js-profile-initials').value.trim(); + const email = tpl.find('.js-profile-email').value.trim(); + let isChangeUserName = false; + let isChangeEmail = false; Users.update(Meteor.userId(), {$set: { 'profile.fullname': fullname, 'profile.initials': initials, }}); - - if (username !== Meteor.user().username) { + isChangeUserName = username !== Meteor.user().username; + isChangeEmail = email.toLowerCase() !== Meteor.user().emails[0].address.toLowerCase(); + if (isChangeUserName && isChangeEmail) { + Meteor.call('setUsernameAndEmail', username, email.toLowerCase(), function(error) { + const usernameMessageElement = tpl.$('.username-taken'); + const emailMessageElement = tpl.$('.email-taken'); + if (error) { + const errorElement = error.error; + if (errorElement === 'username-already-taken') { + usernameMessageElement.show(); + emailMessageElement.hide(); + } else if (errorElement === 'email-already-taken') { + usernameMessageElement.hide(); + emailMessageElement.show(); + } + } else { + usernameMessageElement.hide(); + emailMessageElement.hide(); + Popup.back(); + } + }); + } else if (isChangeUserName) { Meteor.call('setUsername', username, function(error) { const messageElement = tpl.$('.username-taken'); if (error) { @@ -41,6 +70,16 @@ Template.editProfilePopup.events({ Popup.back(); } }); + } else if (isChangeEmail) { + Meteor.call('setEmail', email.toLowerCase(), function(error) { + const messageElement = tpl.$('.email-taken'); + if (error) { + messageElement.show(); + } else { + messageElement.hide(); + Popup.back(); + } + }); } else Popup.back(); }, }); diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 2cb73ae6..2ce7cd42 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -191,6 +191,7 @@ "error-user-notAllowSelf": "You can not invite yourself", "error-user-notCreated": "This user is not created", "error-username-taken": "This username is already taken", + "error-email-taken": "Email has already been taken", "export-board": "Export board", "filter": "Filter", "filter-cards": "Filter Cards", @@ -379,5 +380,9 @@ "OS_Uptime": "OS Uptime", "hours": "hours", "minutes": "minutes", - "seconds": "seconds" + "seconds": "seconds", + "yes": "Yes", + "no": "No", + "accounts": "accounts", + "accounts-allowEmailChange": "Allow Email Change" } diff --git a/models/accountSettings.js b/models/accountSettings.js new file mode 100644 index 00000000..db4087c0 --- /dev/null +++ b/models/accountSettings.js @@ -0,0 +1,33 @@ +AccountSettings = new Mongo.Collection('accountSettings'); + +AccountSettings.attachSchema(new SimpleSchema({ + _id: { + type: String, + }, + booleanValue: { + type: Boolean, + optional: true, + }, + sort: { + type: Number, + decimal: true, + }, +})); + +AccountSettings.allow({ + update(userId) { + const user = Users.findOne(userId); + return user && user.isAdmin; + }, +}); + +if (Meteor.isServer) { + Meteor.startup(() => { + AccountSettings.upsert({ _id: 'accounts-allowEmailChange' }, { + $setOnInsert: { + booleanValue: false, + sort: 0, + }, + }); + }); +} diff --git a/models/users.js b/models/users.js index 29504aa8..c2238cde 100644 --- a/models/users.js +++ b/models/users.js @@ -334,6 +334,28 @@ Meteor.methods({ check(limit, Number); Meteor.user().setShowCardsCountAt(limit); }, + setEmail(email) { + check(email, String); + const existingUser = Users.findOne({ 'emails.address': email }, { fields: { _id: 1 } }); + if (existingUser) { + throw new Meteor.Error('email-already-taken'); + } else { + Users.update(this.userId, { + $set: { + emails: [{ + address: email, + verified: false, + }], + }, + }); + } + }, + setUsernameAndEmail(username, email) { + check(username, String); + check(email, String); + Meteor.call('setUsername', username); + Meteor.call('setEmail', email); + }, }); if (Meteor.isServer) { diff --git a/server/publications/accountSettings.js b/server/publications/accountSettings.js new file mode 100644 index 00000000..b1cacaf5 --- /dev/null +++ b/server/publications/accountSettings.js @@ -0,0 +1,3 @@ +Meteor.publish('accountSettings', function() { + return AccountSettings.find(); +}); |