From d4495b3459d0e82efbf2184a7cdbf5a72a877f41 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Wed, 24 May 2017 23:45:52 -0300 Subject: [PATCH 01/54] Changes for issue #976. Still need some work --- packages/rocketchat-i18n/i18n/en.i18n.json | 3 ++- server/lib/accounts.js | 26 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 0be9c641d9cf..093ec21e9127 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1106,6 +1106,7 @@ "Office_hours_updated": "Office hours updated", "Offline": "Offline", "Offline_DM_Email": "You have been direct messaged by __user__", + "User_Needs_Approval": "A new user registered and needs approval", "Offline_form": "Offline form", "Offline_form_unavailable_message": "Offline form unavailable message", "Offline_Link_Message": "GO TO MESSAGE", @@ -1724,4 +1725,4 @@ "your_message_optional": "your message (optional)", "Your_password_is_wrong": "Your password is wrong!", "Your_push_was_sent_to_s_devices": "Your push was sent to %s devices" -} \ No newline at end of file +} diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 1cffa6d39a00..9b708eee8f82 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -91,6 +91,32 @@ Accounts.onCreateUser(function(options, user = {}) { } } + if (!user.active) { + user.emails.some((email) => { + + const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); + const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + const divisorMessage = '
'; + const siteName = RocketChat.settings.get('Site_Name'); + const messageHTML = `

A user with email ${options.email} has been registered.
Please check Administration -> Users to activate or delete it.`; + + emailSubject = TAPi18n.__('User_Needs_Approval'); + + RocketChat.models.Roles.findUsersInRole('admin').forEach(function (adminUser) { + email = { + to: adminUser.emails[0].address, + from: RocketChat.settings.get('From_Email'), + subject: `[${ siteName }] ${ emailSubject }`, + html: header + messageHTML + divisorMessage + footer + }; + }); + + Meteor.defer(() => { + Email.send(email); + }); + }); + } + return user; }); From 0255a9ebef9857a19976703ffaa5483b165a8b9c Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 25 May 2017 00:02:34 -0300 Subject: [PATCH 02/54] Moved email strings to propper indexes on i18n --- packages/rocketchat-i18n/i18n/en.i18n.json | 3 ++- server/lib/accounts.js | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 093ec21e9127..aa76e5fdcc75 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -44,6 +44,8 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", + "Accounts_Enrollment_Email_Approval_Needed_Default": "

A user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Enrollment_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", "Accounts_Iframe_api_url": "API URL", @@ -1106,7 +1108,6 @@ "Office_hours_updated": "Office hours updated", "Offline": "Offline", "Offline_DM_Email": "You have been direct messaged by __user__", - "User_Needs_Approval": "A new user registered and needs approval", "Offline_form": "Offline form", "Offline_form_unavailable_message": "Offline form unavailable message", "Offline_Link_Message": "GO TO MESSAGE", diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 9b708eee8f82..31a1cda075cb 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -98,9 +98,11 @@ Accounts.onCreateUser(function(options, user = {}) { const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); const divisorMessage = '


'; const siteName = RocketChat.settings.get('Site_Name'); - const messageHTML = `

A user with email ${options.email} has been registered.
Please check Administration -> Users to activate or delete it.`; + const messageHTML = RocketChat.placeholders.replace(TAPi18n.__('Accounts_Enrollment_Email_Approval_Needed_Default'), { + email: options.email + }); - emailSubject = TAPi18n.__('User_Needs_Approval'); + emailSubject = TAPi18n.__('Accounts_Enrollment_Email_Approval_Needed_Subject_Default'); RocketChat.models.Roles.findUsersInRole('admin').forEach(function (adminUser) { email = { From b90b3b7ab78de470ce244e3f2630c1e963836430 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 25 May 2017 01:18:16 -0300 Subject: [PATCH 03/54] Created templates for subject and mail body --- packages/rocketchat-i18n/i18n/en.i18n.json | 4 +- server/lib/accounts.js | 48 ++++++++++++++-------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index aa76e5fdcc75..191acdcba41e 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -44,8 +44,8 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", - "Accounts_Enrollment_Email_Approval_Needed_Default": "

A user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", - "Accounts_Enrollment_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", + "Accounts_Admin_Email_Approval_Needed_Default": "

A user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Admin_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", "Accounts_Iframe_api_url": "API URL", diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 31a1cda075cb..b946bf60a8bc 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -9,6 +9,8 @@ Accounts.emailTemplates.siteName = RocketChat.settings.get('Site_Name'); Accounts.emailTemplates.from = `${ RocketChat.settings.get('Site_Name') } <${ RocketChat.settings.get('From_Email') }>`; +Accounts.emailTemplates.notifyAdmin = {}; + const verifyEmailHtml = Accounts.emailTemplates.verifyEmail.text; Accounts.emailTemplates.verifyEmail.html = function(user, url) { @@ -56,6 +58,31 @@ Accounts.emailTemplates.enrollAccount.html = function(user = {}/*, url*/) { return header + html + footer; }; +Accounts.emailTemplates.notifyAdmin.subject = function() { + let subject, siteName; + + subject = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Subject_Default'); + siteName = RocketChat.settings.get('Site_Name'); + + return `[${ siteName }] ${ subject }`; +}; + +Accounts.emailTemplates.notifyAdmin.html = function(user = {}) { + + let html; + + html = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Default'); + + const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); + const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + + html = RocketChat.placeholders.replace(html, { + email: user.emails[0].address + }); + + return header + html + footer; +}; + Accounts.onCreateUser(function(options, user = {}) { RocketChat.callbacks.run('beforeCreateUser', options, user); @@ -93,28 +120,17 @@ Accounts.onCreateUser(function(options, user = {}) { if (!user.active) { user.emails.some((email) => { - - const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); - const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); - const divisorMessage = '


'; - const siteName = RocketChat.settings.get('Site_Name'); - const messageHTML = RocketChat.placeholders.replace(TAPi18n.__('Accounts_Enrollment_Email_Approval_Needed_Default'), { - email: options.email - }); - - emailSubject = TAPi18n.__('Accounts_Enrollment_Email_Approval_Needed_Subject_Default'); - RocketChat.models.Roles.findUsersInRole('admin').forEach(function (adminUser) { email = { to: adminUser.emails[0].address, from: RocketChat.settings.get('From_Email'), - subject: `[${ siteName }] ${ emailSubject }`, - html: header + messageHTML + divisorMessage + footer + subject: Accounts.emailTemplates.notifyAdmin.subject(), + html: Accounts.emailTemplates.notifyAdmin.html(user) }; - }); - Meteor.defer(() => { - Email.send(email); + Meteor.defer(() => { + Email.send(email); + }); }); }); } From 7a9337901a09d5d2f73dc23831aa2032ce347965 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 25 May 2017 09:25:08 -0300 Subject: [PATCH 04/54] Fix typo and code standards --- packages/rocketchat-i18n/i18n/en.i18n.json | 2 +- server/lib/accounts.js | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 191acdcba41e..04fe30137942 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -44,7 +44,7 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", - "Accounts_Admin_Email_Approval_Needed_Default": "

A user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Admin_Email_Approval_Needed_Default": "

An user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", "Accounts_Admin_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", diff --git a/server/lib/accounts.js b/server/lib/accounts.js index b946bf60a8bc..b67a283033f2 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -59,10 +59,8 @@ Accounts.emailTemplates.enrollAccount.html = function(user = {}/*, url*/) { }; Accounts.emailTemplates.notifyAdmin.subject = function() { - let subject, siteName; - - subject = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Subject_Default'); - siteName = RocketChat.settings.get('Site_Name'); + const subject = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Subject_Default'); + const siteName = RocketChat.settings.get('Site_Name'); return `[${ siteName }] ${ subject }`; }; @@ -120,7 +118,7 @@ Accounts.onCreateUser(function(options, user = {}) { if (!user.active) { user.emails.some((email) => { - RocketChat.models.Roles.findUsersInRole('admin').forEach(function (adminUser) { + RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { email = { to: adminUser.emails[0].address, from: RocketChat.settings.get('From_Email'), From a8776038a562df4409c303542c1f6dff203f2b34 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 25 May 2017 22:29:29 -0300 Subject: [PATCH 05/54] Modified to change email to all admins at once --- server/lib/accounts.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/server/lib/accounts.js b/server/lib/accounts.js index b67a283033f2..155e15cc3651 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -118,17 +118,21 @@ Accounts.onCreateUser(function(options, user = {}) { if (!user.active) { user.emails.some((email) => { + const destinations = []; + RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { - email = { - to: adminUser.emails[0].address, - from: RocketChat.settings.get('From_Email'), - subject: Accounts.emailTemplates.notifyAdmin.subject(), - html: Accounts.emailTemplates.notifyAdmin.html(user) - }; - - Meteor.defer(() => { - Email.send(email); - }); + destinations.push(`${ adminUser.name }<${ adminUser.emails[0].address }>`); + }); + + email = { + to: destinations, + from: RocketChat.settings.get('From_Email'), + subject: Accounts.emailTemplates.notifyAdmin.subject(), + html: Accounts.emailTemplates.notifyAdmin.html(user) + }; + + Meteor.defer(() => { + Email.send(email); }); }); } From 21dcb152b4a2b5ca98e6ec46e8f1f5bfb089082f Mon Sep 17 00:00:00 2001 From: Fernando Nascimento Date: Fri, 26 May 2017 19:11:35 -0300 Subject: [PATCH 06/54] Added reason field into register screen --- packages/rocketchat-i18n/i18n/en.i18n.json | 1 + packages/rocketchat-ui-login/client/login/form.html | 9 +++++++++ packages/rocketchat-ui-login/client/login/form.js | 3 +++ 3 files changed, 13 insertions(+) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 04fe30137942..6635e40491a6 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1227,6 +1227,7 @@ "Read_only_changed_successfully": "Read only changed successfully", "Read_only_channel": "Read Only Channel", "Read_only_group": "Read Only Group", + "Reason_To_Join": "Reason to Join", "Record": "Record", "Redirect_URI": "Redirect URI", "Refresh_oauth_services": "Refresh OAuth Services", diff --git a/packages/rocketchat-ui-login/client/login/form.html b/packages/rocketchat-ui-login/client/login/form.html index c124177edc63..46f37802e5d8 100644 --- a/packages/rocketchat-ui-login/client/login/form.html +++ b/packages/rocketchat-ui-login/client/login/form.html @@ -73,6 +73,15 @@

{{{_ "Registration_Succeeded"}}}

{{/if}} + {{#if manuallyApproveNewUsers}} +
+ +
+ +
+
+
+ {{/if}} {{/if}} {{#if state 'forgot-password' 'email-verification'}}
diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index fa6d28a19a5b..cee2e76937d5 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -58,6 +58,9 @@ Template.loginForm.helpers({ }, hasOnePassword() { return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; + }, + manuallyApproveNewUsers() { + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); } }); From 8701eb09469989cccf4f387bbdc42410ac8c9a75 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 00:37:32 -0300 Subject: [PATCH 07/54] - Added error message for invalid reason - Added method to save reason into user object - Added validation to display field but setting Accounts_ManuallyApproveNewUsers is not working :( --- packages/rocketchat-i18n/i18n/en.i18n.json | 1 + packages/rocketchat-lib/server/models/Users.js | 10 ++++++++++ packages/rocketchat-ui-login/client/login/form.js | 7 ++++++- server/methods/registerUser.js | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 6635e40491a6..bfa95e070463 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -764,6 +764,7 @@ "Invalid_name": "The name must not be empty", "Invalid_notification_setting_s": "Invalid notification setting: %s", "Invalid_pass": "The password must not be empty", + "Invalid_reason": "The reason to join must not be empty", "Invalid_room_name": "%s is not a valid room name,
use only letters, numbers, hyphens and underscores", "Invalid_secret_URL_message": "The URL provided is invalid.", "Invalid_setting_s": "Invalid setting: %s", diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index 941416475c6e..a492a5b75f7a 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -313,6 +313,16 @@ class ModelUsers extends RocketChat.models._Base { return this.update(_id, update); } + setReason(_id, reason) { + const update = { + $set: { + reason + } + }; + + return this.update(_id, update); + } + setCustomFields(_id, fields) { const values = {}; Object.keys(fields).reduce(key => { diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index cee2e76937d5..ebcd82c2ba37 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -60,7 +60,9 @@ Template.loginForm.helpers({ return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; }, manuallyApproveNewUsers() { - return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); + //TODO verify why it' s not getting this setting + //return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); + return true; } }); @@ -253,6 +255,9 @@ Template.loginForm.onCreated(function() { if (RocketChat.settings.get('Accounts_RequirePasswordConfirmation') && formObj['confirm-pass'] !== formObj['pass']) { validationObj['confirm-pass'] = t('Invalid_confirm_pass'); } + if (true && !formObj['reason']) { + validationObj['reason'] = t('Invalid_reason'); + } validateCustomFields(formObj, validationObj); } $('#login-card h2').removeClass('error'); diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index 17c0ceb71b14..55c7f79ea945 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -17,6 +17,7 @@ Meteor.methods({ email: String, pass: String, name: String, + reason: String, secretURL: Match.Optional(String) })); } @@ -45,6 +46,7 @@ Meteor.methods({ } RocketChat.models.Users.setName(userId, s.trim(formData.name)); + RocketChat.models.Users.setReason(userId, s.trim(formData.reason)); RocketChat.saveCustomFields(userId, formData); From 7f5e498fa7ea703a091627933c4ca46d867f7b97 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 00:54:16 -0300 Subject: [PATCH 08/54] - Changed to use the correct setting --- packages/rocketchat-ui-login/client/login/form.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index ebcd82c2ba37..6f1fee80919f 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -60,9 +60,7 @@ Template.loginForm.helpers({ return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; }, manuallyApproveNewUsers() { - //TODO verify why it' s not getting this setting - //return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); - return true; + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); } }); @@ -255,7 +253,7 @@ Template.loginForm.onCreated(function() { if (RocketChat.settings.get('Accounts_RequirePasswordConfirmation') && formObj['confirm-pass'] !== formObj['pass']) { validationObj['confirm-pass'] = t('Invalid_confirm_pass'); } - if (true && !formObj['reason']) { + if (RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && !formObj['reason']) { validationObj['reason'] = t('Invalid_reason'); } validateCustomFields(formObj, validationObj); From c92d2b0f9cea56e215ac7fe2a733426512bd056f Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 13:43:43 -0300 Subject: [PATCH 09/54] - Modified admin message to contain reason and user name - Modified function placeholders to replace reason as well - Modified email template on accounts.js --- packages/rocketchat-i18n/i18n/en.i18n.json | 2 +- packages/rocketchat-lib/lib/placeholders.js | 1 + server/lib/accounts.js | 8 +++++--- server/methods/registerUser.js | 4 +++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index bfa95e070463..c7b2bee5b7b6 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -44,7 +44,7 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
  • [name], [fname], [lname] for the user's full name, first name or last name, respectively.
  • [email] for the user's email.
  • [Site_Name] and [Site_URL] for the Application Name and URL respectively.
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", - "Accounts_Admin_Email_Approval_Needed_Default": "

An user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Admin_Email_Approval_Needed_Default": "

The user [name] ([email]) has been registered.

Reason: [reason]

Please check Administration -> Users to activate or delete it.

", "Accounts_Admin_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", diff --git a/packages/rocketchat-lib/lib/placeholders.js b/packages/rocketchat-lib/lib/placeholders.js index 82fb613d050a..26eca737afdf 100644 --- a/packages/rocketchat-lib/lib/placeholders.js +++ b/packages/rocketchat-lib/lib/placeholders.js @@ -14,6 +14,7 @@ RocketChat.placeholders.replace = function(str, data) { str = str.replace(/\[lname\]/g, _.strRightBack(data.name, ' ') || ''); str = str.replace(/\[email\]/g, data.email || ''); str = str.replace(/\[password\]/g, data.password || ''); + str = str.replace(/\[reason\]/g, data.reason || ''); if (data.unsubscribe) { str = str.replace(/\[unsubscribe\]/g, data.unsubscribe); diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 155e15cc3651..8d69eacb8ba4 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -65,7 +65,7 @@ Accounts.emailTemplates.notifyAdmin.subject = function() { return `[${ siteName }] ${ subject }`; }; -Accounts.emailTemplates.notifyAdmin.html = function(user = {}) { +Accounts.emailTemplates.notifyAdmin.html = function(options = {}) { let html; @@ -75,7 +75,9 @@ Accounts.emailTemplates.notifyAdmin.html = function(user = {}) { const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); html = RocketChat.placeholders.replace(html, { - email: user.emails[0].address + name: options.name, + email: options.email, + reason: options.reason }); return header + html + footer; @@ -128,7 +130,7 @@ Accounts.onCreateUser(function(options, user = {}) { to: destinations, from: RocketChat.settings.get('From_Email'), subject: Accounts.emailTemplates.notifyAdmin.subject(), - html: Accounts.emailTemplates.notifyAdmin.html(user) + html: Accounts.emailTemplates.notifyAdmin.html(options) }; Meteor.defer(() => { diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index 55c7f79ea945..bd1250188028 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -32,7 +32,9 @@ Meteor.methods({ const userData = { email: s.trim(formData.email.toLowerCase()), - password: formData.pass + password: formData.pass, + name: formData.name, + reason: formData.reason }; // Check if user has already been imported and never logged in. If so, set password and let it through From eae8aa37440ccd1cbf52c468085cc420a32c09ed Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 14:56:10 -0300 Subject: [PATCH 10/54] - Added public key to use Accounts_ManuallyApproveNewUsers on frontend --- packages/rocketchat-lib/server/startup/settings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index bd77f407b7d7..b17408fc4cac 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -95,6 +95,7 @@ RocketChat.settings.addGroup('Accounts', function() { } }); this.add('Accounts_ManuallyApproveNewUsers', false, { + 'public': true, type: 'boolean' }); this.add('Accounts_AllowedDomainsList', '', { From 16a58b50155602f07f99ecddb6e732390df07d78 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 15:49:09 -0300 Subject: [PATCH 11/54] - Displaying reason on user info - Reason displayed only if setting is active and user is not active - Added reason to getFullUserData --- .../rocketchat-lib/server/functions/getFullUserData.js | 3 ++- packages/rocketchat-lib/server/models/Users.js | 1 + packages/rocketchat-ui-flextab/client/tabs/userInfo.html | 7 ++++++- packages/rocketchat-ui-flextab/client/tabs/userInfo.js | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-lib/server/functions/getFullUserData.js b/packages/rocketchat-lib/server/functions/getFullUserData.js index 0b5290b3b3e8..cbeb1e7f11c6 100644 --- a/packages/rocketchat-lib/server/functions/getFullUserData.js +++ b/packages/rocketchat-lib/server/functions/getFullUserData.js @@ -6,7 +6,8 @@ RocketChat.getFullUserData = function({userId, filter, limit}) { status: 1, utcOffset: 1, type: 1, - active: 1 + active: 1, + reason: 1 }; if (RocketChat.authz.hasPermission(userId, 'view-full-other-user-info')) { diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index a492a5b75f7a..184789c2a1cc 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -9,6 +9,7 @@ class ModelUsers extends RocketChat.models._Base { this.tryEnsureIndex({ 'active': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'statusConnection': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'type': 1 }); + this.tryEnsureIndex({ 'reason': 1 }); this.cache.ensureIndex('username', 'unique'); } diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.html b/packages/rocketchat-ui-flextab/client/tabs/userInfo.html index 4b1dfaffa3c5..6d70b7b581d7 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.html +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.html @@ -26,7 +26,7 @@

{{name}}

{{#if hasPhone}} {{#each phone}}

{{phoneNumber}}

{{/each}} {{/if}} - {{#if lastLogin}}

{{_ "Created_at"}}: {{createdAt}}

{{/if}} + {{#if createdAt}}

{{_ "Created_at"}}: {{createdAt}}

{{/if}} {{#if lastLogin}}

{{_ "Last_login"}}: {{lastLogin}}

{{/if}} {{#if services.facebook.id}}

{{services.facebook.name}}

{{/if}} {{#if services.github.id}}

{{services.github.username}}

{{/if}} @@ -37,6 +37,11 @@

{{name}}

{{#if services.twitter.id}}

{{services.twitter.screenName}}

{{/if}} {{#if services.wordpress.id}}

{{services.wordpress.user_login}}

{{/if}} {{/if}} + {{#if shouldDisplayReason}} +

+ {{_ "Reason_To_Join"}}: {{user.reason}} +

+ {{/if}}
{{/with}} diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js index e64f60b0e5fc..ede5cb950e26 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js @@ -180,6 +180,11 @@ Template.userInfo.helpers({ isBlocker() { const subscription = ChatSubscription.findOne({rid:Session.get('openedRoom'), 'u._id': Meteor.userId()}, { fields: { blocker: 1 } }); return subscription.blocker; + }, + + shouldDisplayReason() { + const user = Template.instance().user.get(); + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false; } }); From 3925e8917a4f22911dc4daa102d7cb85a76515a2 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 17:45:38 -0300 Subject: [PATCH 12/54] Added logic to remove user reason once user gets activated --- client/methods/unsetUserReason.js | 6 ++++ .../rocketchat-lib/server/models/Users.js | 30 ++++++++++++------- .../client/tabs/userInfo.js | 5 +++- server/methods/unsetUserReason.js | 27 +++++++++++++++++ 4 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 client/methods/unsetUserReason.js create mode 100644 server/methods/unsetUserReason.js diff --git a/client/methods/unsetUserReason.js b/client/methods/unsetUserReason.js new file mode 100644 index 000000000000..245eb587dfbb --- /dev/null +++ b/client/methods/unsetUserReason.js @@ -0,0 +1,6 @@ +Meteor.methods({ + unsetUserReason(userId) { + Meteor.users.update(userId, { $unset: { 'reason' : 1 } }); + return true; + } +}); diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index 184789c2a1cc..ce21729643aa 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -314,16 +314,6 @@ class ModelUsers extends RocketChat.models._Base { return this.update(_id, update); } - setReason(_id, reason) { - const update = { - $set: { - reason - } - }; - - return this.update(_id, update); - } - setCustomFields(_id, fields) { const values = {}; Object.keys(fields).reduce(key => { @@ -504,6 +494,26 @@ class ModelUsers extends RocketChat.models._Base { return this.update({ _id }, update); } + setReason(_id, reason) { + const update = { + $set: { + reason + } + }; + + return this.update(_id, update); + } + + unsetReason(_id) { + const update = { + $unset: { + 'reason' : true, + } + }; + + return this.update(_id, update); + } + // INSERT create(data) { const user = { diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js index ede5cb950e26..883751232fe7 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js @@ -184,7 +184,7 @@ Template.userInfo.helpers({ shouldDisplayReason() { const user = Template.instance().user.get(); - return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false; + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false && user.reason; } }); @@ -395,6 +395,9 @@ Template.userInfo.events({ if (user) { return Meteor.call('setUserActiveStatus', user._id, true, function(error, result) { if (result) { + + Meteor.call('unsetUserReason', user._id); + toastr.success(t('User_has_been_activated')); } if (error) { diff --git a/server/methods/unsetUserReason.js b/server/methods/unsetUserReason.js new file mode 100644 index 000000000000..b2740a145bf8 --- /dev/null +++ b/server/methods/unsetUserReason.js @@ -0,0 +1,27 @@ +Meteor.methods({ + unsetUserReason(userId) { + check(userId, String); + + if (!Meteor.userId()) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'unsetUserReason' + }); + } + + if (RocketChat.authz.hasPermission(Meteor.userId(), 'edit-other-user-active-status') !== true) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { + method: 'unsetUserReason' + }); + } + + const user = RocketChat.models.Users.findOneById(userId); + + if (user) { + RocketChat.models.Users.unsetReason(userId); + + return true; + } + + return false; + } +}); From f001a4cd373bd5329e63f79d4f17cef863bfdff0 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Fri, 26 May 2017 19:11:35 -0300 Subject: [PATCH 13/54] Added reason field into register screen --- packages/rocketchat-i18n/i18n/en.i18n.json | 1 + packages/rocketchat-ui-login/client/login/form.html | 9 +++++++++ packages/rocketchat-ui-login/client/login/form.js | 3 +++ 3 files changed, 13 insertions(+) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 04fe30137942..6635e40491a6 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1227,6 +1227,7 @@ "Read_only_changed_successfully": "Read only changed successfully", "Read_only_channel": "Read Only Channel", "Read_only_group": "Read Only Group", + "Reason_To_Join": "Reason to Join", "Record": "Record", "Redirect_URI": "Redirect URI", "Refresh_oauth_services": "Refresh OAuth Services", diff --git a/packages/rocketchat-ui-login/client/login/form.html b/packages/rocketchat-ui-login/client/login/form.html index c124177edc63..46f37802e5d8 100644 --- a/packages/rocketchat-ui-login/client/login/form.html +++ b/packages/rocketchat-ui-login/client/login/form.html @@ -73,6 +73,15 @@

{{{_ "Registration_Succeeded"}}}

{{/if}} + {{#if manuallyApproveNewUsers}} +
+ +
+ +
+
+
+ {{/if}} {{/if}} {{#if state 'forgot-password' 'email-verification'}}
diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index fa6d28a19a5b..cee2e76937d5 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -58,6 +58,9 @@ Template.loginForm.helpers({ }, hasOnePassword() { return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; + }, + manuallyApproveNewUsers() { + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); } }); From 21c6c73a976986c83caeae5c3d8afd323941944e Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 00:37:32 -0300 Subject: [PATCH 14/54] - Added error message for invalid reason - Added method to save reason into user object - Added validation to display field but setting Accounts_ManuallyApproveNewUsers is not working :( --- packages/rocketchat-i18n/i18n/en.i18n.json | 1 + packages/rocketchat-lib/server/models/Users.js | 10 ++++++++++ packages/rocketchat-ui-login/client/login/form.js | 7 ++++++- server/methods/registerUser.js | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 6635e40491a6..bfa95e070463 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -764,6 +764,7 @@ "Invalid_name": "The name must not be empty", "Invalid_notification_setting_s": "Invalid notification setting: %s", "Invalid_pass": "The password must not be empty", + "Invalid_reason": "The reason to join must not be empty", "Invalid_room_name": "%s is not a valid room name,
use only letters, numbers, hyphens and underscores", "Invalid_secret_URL_message": "The URL provided is invalid.", "Invalid_setting_s": "Invalid setting: %s", diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index 941416475c6e..a492a5b75f7a 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -313,6 +313,16 @@ class ModelUsers extends RocketChat.models._Base { return this.update(_id, update); } + setReason(_id, reason) { + const update = { + $set: { + reason + } + }; + + return this.update(_id, update); + } + setCustomFields(_id, fields) { const values = {}; Object.keys(fields).reduce(key => { diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index cee2e76937d5..ebcd82c2ba37 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -60,7 +60,9 @@ Template.loginForm.helpers({ return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; }, manuallyApproveNewUsers() { - return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); + //TODO verify why it' s not getting this setting + //return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); + return true; } }); @@ -253,6 +255,9 @@ Template.loginForm.onCreated(function() { if (RocketChat.settings.get('Accounts_RequirePasswordConfirmation') && formObj['confirm-pass'] !== formObj['pass']) { validationObj['confirm-pass'] = t('Invalid_confirm_pass'); } + if (true && !formObj['reason']) { + validationObj['reason'] = t('Invalid_reason'); + } validateCustomFields(formObj, validationObj); } $('#login-card h2').removeClass('error'); diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index 17c0ceb71b14..55c7f79ea945 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -17,6 +17,7 @@ Meteor.methods({ email: String, pass: String, name: String, + reason: String, secretURL: Match.Optional(String) })); } @@ -45,6 +46,7 @@ Meteor.methods({ } RocketChat.models.Users.setName(userId, s.trim(formData.name)); + RocketChat.models.Users.setReason(userId, s.trim(formData.reason)); RocketChat.saveCustomFields(userId, formData); From fad9497a1fb305160b6f8c937b4e181822a21692 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 00:54:16 -0300 Subject: [PATCH 15/54] - Changed to use the correct setting --- packages/rocketchat-ui-login/client/login/form.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index ebcd82c2ba37..6f1fee80919f 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -60,9 +60,7 @@ Template.loginForm.helpers({ return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; }, manuallyApproveNewUsers() { - //TODO verify why it' s not getting this setting - //return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); - return true; + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); } }); @@ -255,7 +253,7 @@ Template.loginForm.onCreated(function() { if (RocketChat.settings.get('Accounts_RequirePasswordConfirmation') && formObj['confirm-pass'] !== formObj['pass']) { validationObj['confirm-pass'] = t('Invalid_confirm_pass'); } - if (true && !formObj['reason']) { + if (RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && !formObj['reason']) { validationObj['reason'] = t('Invalid_reason'); } validateCustomFields(formObj, validationObj); From 17ad773bf8020b2b1ca9185e8d0690f89b536fdb Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 13:43:43 -0300 Subject: [PATCH 16/54] - Modified admin message to contain reason and user name - Modified function placeholders to replace reason as well - Modified email template on accounts.js --- packages/rocketchat-i18n/i18n/en.i18n.json | 2 +- packages/rocketchat-lib/lib/placeholders.js | 1 + server/lib/accounts.js | 8 +++++--- server/methods/registerUser.js | 4 +++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index bfa95e070463..c7b2bee5b7b6 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -44,7 +44,7 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
  • [name], [fname], [lname] for the user's full name, first name or last name, respectively.
  • [email] for the user's email.
  • [Site_Name] and [Site_URL] for the Application Name and URL respectively.
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", - "Accounts_Admin_Email_Approval_Needed_Default": "

An user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Admin_Email_Approval_Needed_Default": "

The user [name] ([email]) has been registered.

Reason: [reason]

Please check Administration -> Users to activate or delete it.

", "Accounts_Admin_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", diff --git a/packages/rocketchat-lib/lib/placeholders.js b/packages/rocketchat-lib/lib/placeholders.js index 82fb613d050a..26eca737afdf 100644 --- a/packages/rocketchat-lib/lib/placeholders.js +++ b/packages/rocketchat-lib/lib/placeholders.js @@ -14,6 +14,7 @@ RocketChat.placeholders.replace = function(str, data) { str = str.replace(/\[lname\]/g, _.strRightBack(data.name, ' ') || ''); str = str.replace(/\[email\]/g, data.email || ''); str = str.replace(/\[password\]/g, data.password || ''); + str = str.replace(/\[reason\]/g, data.reason || ''); if (data.unsubscribe) { str = str.replace(/\[unsubscribe\]/g, data.unsubscribe); diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 155e15cc3651..8d69eacb8ba4 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -65,7 +65,7 @@ Accounts.emailTemplates.notifyAdmin.subject = function() { return `[${ siteName }] ${ subject }`; }; -Accounts.emailTemplates.notifyAdmin.html = function(user = {}) { +Accounts.emailTemplates.notifyAdmin.html = function(options = {}) { let html; @@ -75,7 +75,9 @@ Accounts.emailTemplates.notifyAdmin.html = function(user = {}) { const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); html = RocketChat.placeholders.replace(html, { - email: user.emails[0].address + name: options.name, + email: options.email, + reason: options.reason }); return header + html + footer; @@ -128,7 +130,7 @@ Accounts.onCreateUser(function(options, user = {}) { to: destinations, from: RocketChat.settings.get('From_Email'), subject: Accounts.emailTemplates.notifyAdmin.subject(), - html: Accounts.emailTemplates.notifyAdmin.html(user) + html: Accounts.emailTemplates.notifyAdmin.html(options) }; Meteor.defer(() => { diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index 55c7f79ea945..bd1250188028 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -32,7 +32,9 @@ Meteor.methods({ const userData = { email: s.trim(formData.email.toLowerCase()), - password: formData.pass + password: formData.pass, + name: formData.name, + reason: formData.reason }; // Check if user has already been imported and never logged in. If so, set password and let it through From db7d777dbc87f0c66097c49d1acde839035cbfb0 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 14:56:10 -0300 Subject: [PATCH 17/54] - Added public key to use Accounts_ManuallyApproveNewUsers on frontend --- packages/rocketchat-lib/server/startup/settings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index bd77f407b7d7..b17408fc4cac 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -95,6 +95,7 @@ RocketChat.settings.addGroup('Accounts', function() { } }); this.add('Accounts_ManuallyApproveNewUsers', false, { + 'public': true, type: 'boolean' }); this.add('Accounts_AllowedDomainsList', '', { From 0f9962200d11cbf26e6a7bd50dcf6e25e51ce5e1 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 15:49:09 -0300 Subject: [PATCH 18/54] - Displaying reason on user info - Reason displayed only if setting is active and user is not active - Added reason to getFullUserData --- .../rocketchat-lib/server/functions/getFullUserData.js | 3 ++- packages/rocketchat-lib/server/models/Users.js | 1 + packages/rocketchat-ui-flextab/client/tabs/userInfo.html | 7 ++++++- packages/rocketchat-ui-flextab/client/tabs/userInfo.js | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-lib/server/functions/getFullUserData.js b/packages/rocketchat-lib/server/functions/getFullUserData.js index 0b5290b3b3e8..cbeb1e7f11c6 100644 --- a/packages/rocketchat-lib/server/functions/getFullUserData.js +++ b/packages/rocketchat-lib/server/functions/getFullUserData.js @@ -6,7 +6,8 @@ RocketChat.getFullUserData = function({userId, filter, limit}) { status: 1, utcOffset: 1, type: 1, - active: 1 + active: 1, + reason: 1 }; if (RocketChat.authz.hasPermission(userId, 'view-full-other-user-info')) { diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index a492a5b75f7a..184789c2a1cc 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -9,6 +9,7 @@ class ModelUsers extends RocketChat.models._Base { this.tryEnsureIndex({ 'active': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'statusConnection': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'type': 1 }); + this.tryEnsureIndex({ 'reason': 1 }); this.cache.ensureIndex('username', 'unique'); } diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.html b/packages/rocketchat-ui-flextab/client/tabs/userInfo.html index 4b1dfaffa3c5..6d70b7b581d7 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.html +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.html @@ -26,7 +26,7 @@

{{name}}

{{#if hasPhone}} {{#each phone}}

{{phoneNumber}}

{{/each}} {{/if}} - {{#if lastLogin}}

{{_ "Created_at"}}: {{createdAt}}

{{/if}} + {{#if createdAt}}

{{_ "Created_at"}}: {{createdAt}}

{{/if}} {{#if lastLogin}}

{{_ "Last_login"}}: {{lastLogin}}

{{/if}} {{#if services.facebook.id}}

{{services.facebook.name}}

{{/if}} {{#if services.github.id}}

{{services.github.username}}

{{/if}} @@ -37,6 +37,11 @@

{{name}}

{{#if services.twitter.id}}

{{services.twitter.screenName}}

{{/if}} {{#if services.wordpress.id}}

{{services.wordpress.user_login}}

{{/if}} {{/if}} + {{#if shouldDisplayReason}} +

+ {{_ "Reason_To_Join"}}: {{user.reason}} +

+ {{/if}}
{{/with}} diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js index e64f60b0e5fc..ede5cb950e26 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js @@ -180,6 +180,11 @@ Template.userInfo.helpers({ isBlocker() { const subscription = ChatSubscription.findOne({rid:Session.get('openedRoom'), 'u._id': Meteor.userId()}, { fields: { blocker: 1 } }); return subscription.blocker; + }, + + shouldDisplayReason() { + const user = Template.instance().user.get(); + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false; } }); From e6fff42c8f00cbf2afc1d1749dc51bca68f61b59 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 17:45:38 -0300 Subject: [PATCH 19/54] Added logic to remove user reason once user gets activated --- client/methods/unsetUserReason.js | 6 ++++ .../rocketchat-lib/server/models/Users.js | 30 ++++++++++++------- .../client/tabs/userInfo.js | 5 +++- server/methods/unsetUserReason.js | 27 +++++++++++++++++ 4 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 client/methods/unsetUserReason.js create mode 100644 server/methods/unsetUserReason.js diff --git a/client/methods/unsetUserReason.js b/client/methods/unsetUserReason.js new file mode 100644 index 000000000000..245eb587dfbb --- /dev/null +++ b/client/methods/unsetUserReason.js @@ -0,0 +1,6 @@ +Meteor.methods({ + unsetUserReason(userId) { + Meteor.users.update(userId, { $unset: { 'reason' : 1 } }); + return true; + } +}); diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index 184789c2a1cc..ce21729643aa 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -314,16 +314,6 @@ class ModelUsers extends RocketChat.models._Base { return this.update(_id, update); } - setReason(_id, reason) { - const update = { - $set: { - reason - } - }; - - return this.update(_id, update); - } - setCustomFields(_id, fields) { const values = {}; Object.keys(fields).reduce(key => { @@ -504,6 +494,26 @@ class ModelUsers extends RocketChat.models._Base { return this.update({ _id }, update); } + setReason(_id, reason) { + const update = { + $set: { + reason + } + }; + + return this.update(_id, update); + } + + unsetReason(_id) { + const update = { + $unset: { + 'reason' : true, + } + }; + + return this.update(_id, update); + } + // INSERT create(data) { const user = { diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js index ede5cb950e26..883751232fe7 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js @@ -184,7 +184,7 @@ Template.userInfo.helpers({ shouldDisplayReason() { const user = Template.instance().user.get(); - return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false; + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false && user.reason; } }); @@ -395,6 +395,9 @@ Template.userInfo.events({ if (user) { return Meteor.call('setUserActiveStatus', user._id, true, function(error, result) { if (result) { + + Meteor.call('unsetUserReason', user._id); + toastr.success(t('User_has_been_activated')); } if (error) { diff --git a/server/methods/unsetUserReason.js b/server/methods/unsetUserReason.js new file mode 100644 index 000000000000..b2740a145bf8 --- /dev/null +++ b/server/methods/unsetUserReason.js @@ -0,0 +1,27 @@ +Meteor.methods({ + unsetUserReason(userId) { + check(userId, String); + + if (!Meteor.userId()) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'unsetUserReason' + }); + } + + if (RocketChat.authz.hasPermission(Meteor.userId(), 'edit-other-user-active-status') !== true) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { + method: 'unsetUserReason' + }); + } + + const user = RocketChat.models.Users.findOneById(userId); + + if (user) { + RocketChat.models.Users.unsetReason(userId); + + return true; + } + + return false; + } +}); From 12988c459592637f77a4487ee505bb1f161ec57f Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 18:08:20 -0300 Subject: [PATCH 20/54] Removing unneeded comma --- packages/rocketchat-lib/server/models/Users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index ce21729643aa..1c119f79aaf1 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -507,7 +507,7 @@ class ModelUsers extends RocketChat.models._Base { unsetReason(_id) { const update = { $unset: { - 'reason' : true, + 'reason' : true } }; From 7538f007b62cbd69910b2a0edefcc43928fce175 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 20:36:41 -0300 Subject: [PATCH 21/54] Added conditionals to check and use reason field --- server/methods/registerUser.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index bd1250188028..cfe086c0bc92 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -2,6 +2,7 @@ Meteor.methods({ registerUser(formData) { const AllowAnonymousRead = RocketChat.settings.get('Accounts_AllowAnonymousRead'); const AllowAnonymousWrite = RocketChat.settings.get('Accounts_AllowAnonymousWrite'); + const manuallyApproveNewUsers = RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); if (AllowAnonymousRead === true && AllowAnonymousWrite === true && formData.email == null) { const userId = Accounts.insertUserDoc({}, { globalRoles: [ @@ -17,9 +18,14 @@ Meteor.methods({ email: String, pass: String, name: String, - reason: String, secretURL: Match.Optional(String) })); + + if (manuallyApproveNewUsers) { + check(formData, Match.ObjectIncluding({ + reason: String + })); + } } if (RocketChat.settings.get('Accounts_RegistrationForm') === 'Disabled') { @@ -33,10 +39,13 @@ Meteor.methods({ const userData = { email: s.trim(formData.email.toLowerCase()), password: formData.pass, - name: formData.name, - reason: formData.reason + name: formData.name }; + if (manuallyApproveNewUsers) { + userData.reason = formData.reason; + } + // Check if user has already been imported and never logged in. If so, set password and let it through const importedUser = RocketChat.models.Users.findOneByEmailAddress(s.trim(formData.email.toLowerCase())); let userId; @@ -48,7 +57,10 @@ Meteor.methods({ } RocketChat.models.Users.setName(userId, s.trim(formData.name)); - RocketChat.models.Users.setReason(userId, s.trim(formData.reason)); + + if (manuallyApproveNewUsers) { + RocketChat.models.Users.setReason(userId, s.trim(formData.reason)); + } RocketChat.saveCustomFields(userId, formData); From e7cd5eb599477cf7637dce423232e882c80c980e Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 21:10:03 -0300 Subject: [PATCH 22/54] Trying to fix user creation tests --- tests/data/user.js | 1 + tests/end-to-end/ui/03-user-creation.js | 4 ++-- tests/pageobjects/login.page.js | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/data/user.js b/tests/data/user.js index 92294f99dfcf..f9d51e8ba46b 100644 --- a/tests/data/user.js +++ b/tests/data/user.js @@ -1,6 +1,7 @@ export const username = `user.test.${ Date.now() }`; export const email = `${ username }@rocket.chat`; export const password = 'rocket.chat'; +export const reason = 'rocket.chat.reason'; export const adminUsername = 'rocketchat.internal.admin.test'; export const adminEmail = `${ adminUsername }@rocket.chat`; diff --git a/tests/end-to-end/ui/03-user-creation.js b/tests/end-to-end/ui/03-user-creation.js index fe93c69caa34..47b4eeb2b812 100644 --- a/tests/end-to-end/ui/03-user-creation.js +++ b/tests/end-to-end/ui/03-user-creation.js @@ -5,7 +5,7 @@ import loginPage from '../../pageobjects/login.page'; import mainContent from '../../pageobjects/main-content.page'; //test data imports -import {username, email, password} from '../../data/user.js'; +import {username, email, password, reason} from '../../data/user.js'; @@ -22,7 +22,7 @@ describe('[User Creation]', function() { it('it should create user', () => { loginPage.gotToRegister(); - loginPage.registerNewUser({username, email, password}); + loginPage.registerNewUser({username, email, password, reason}); loginPage.inputUsername.waitForExist(5000); diff --git a/tests/pageobjects/login.page.js b/tests/pageobjects/login.page.js index e0150d40a15a..15020173df95 100644 --- a/tests/pageobjects/login.page.js +++ b/tests/pageobjects/login.page.js @@ -11,6 +11,7 @@ class LoginPage extends Page { get emailField() { return browser.element('[name=email]'); } get passwordField() { return browser.element('[name=pass]'); } get confirmPasswordField() { return browser.element('[name=confirm-pass]'); } + get reasonField() { return browser.element('[reason]'); } get inputUsername() { return browser.element('form#login-card input#username'); } get emailOrUsernameInvalidText() { return browser.element('[name=emailOrUsername]~.input-error'); } @@ -18,6 +19,7 @@ class LoginPage extends Page { get emailInvalidText() { return browser.element('[name=email]~.input-error'); } get passwordInvalidText() { return browser.element('[name=pass]~.input-error'); } get confirmPasswordInvalidText() { return browser.element('[name=confirm-pass]~.input-error'); } + get reasonInvalidText() { return browser.element('[name=reason]~.input-error'); } get registrationSucceededCard() { return browser.element('#login-card h2'); } open() { @@ -38,12 +40,13 @@ class LoginPage extends Page { this.emailField.waitForVisible(15000); } - registerNewUser({username, email, password}) { + registerNewUser({username, email, password, reason}) { this.nameField.waitForVisible(5000); this.nameField.setValue(username); this.emailField.setValue(email); this.passwordField.setValue(password); this.confirmPasswordField.setValue(password); + this.reasonField.setValue(reason); this.submit(); } From 777441e7a3f2c1190c5358eb26cad721e42486cc Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 21:27:33 -0300 Subject: [PATCH 23/54] Trying to fix user creation tests(2) --- tests/pageobjects/login.page.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/pageobjects/login.page.js b/tests/pageobjects/login.page.js index 15020173df95..3f03a4c3d80d 100644 --- a/tests/pageobjects/login.page.js +++ b/tests/pageobjects/login.page.js @@ -46,7 +46,6 @@ class LoginPage extends Page { this.emailField.setValue(email); this.passwordField.setValue(password); this.confirmPasswordField.setValue(password); - this.reasonField.setValue(reason); this.submit(); } From c0edb09975e18008adc03b0f0ea59012b7e4f4e4 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Mon, 29 May 2017 23:52:52 -0300 Subject: [PATCH 24/54] Applying last suggestions --- client/methods/unsetUserReason.js | 6 ---- .../rocketchat-lib/server/models/Users.js | 1 - .../client/tabs/userInfo.js | 3 -- server/lib/accounts.js | 31 ++++++++++--------- server/methods/setUserActiveStatus.js | 2 ++ server/methods/unsetUserReason.js | 27 ---------------- 6 files changed, 18 insertions(+), 52 deletions(-) delete mode 100644 client/methods/unsetUserReason.js delete mode 100644 server/methods/unsetUserReason.js diff --git a/client/methods/unsetUserReason.js b/client/methods/unsetUserReason.js deleted file mode 100644 index 245eb587dfbb..000000000000 --- a/client/methods/unsetUserReason.js +++ /dev/null @@ -1,6 +0,0 @@ -Meteor.methods({ - unsetUserReason(userId) { - Meteor.users.update(userId, { $unset: { 'reason' : 1 } }); - return true; - } -}); diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index 1c119f79aaf1..7224cd4d2a97 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -9,7 +9,6 @@ class ModelUsers extends RocketChat.models._Base { this.tryEnsureIndex({ 'active': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'statusConnection': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'type': 1 }); - this.tryEnsureIndex({ 'reason': 1 }); this.cache.ensureIndex('username', 'unique'); } diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js index 883751232fe7..cd540249fb0f 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js @@ -395,9 +395,6 @@ Template.userInfo.events({ if (user) { return Meteor.call('setUserActiveStatus', user._id, true, function(error, result) { if (result) { - - Meteor.call('unsetUserReason', user._id); - toastr.success(t('User_has_been_activated')); } if (error) { diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 8d69eacb8ba4..c59ca905cb42 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -119,23 +119,24 @@ Accounts.onCreateUser(function(options, user = {}) { } if (!user.active) { - user.emails.some((email) => { - const destinations = []; + const destinations = []; + let email = {}; - RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { + RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { + if (adminUser.emails[0]) { destinations.push(`${ adminUser.name }<${ adminUser.emails[0].address }>`); - }); - - email = { - to: destinations, - from: RocketChat.settings.get('From_Email'), - subject: Accounts.emailTemplates.notifyAdmin.subject(), - html: Accounts.emailTemplates.notifyAdmin.html(options) - }; - - Meteor.defer(() => { - Email.send(email); - }); + } + }); + + email = { + to: destinations, + from: RocketChat.settings.get('From_Email'), + subject: Accounts.emailTemplates.notifyAdmin.subject(), + html: Accounts.emailTemplates.notifyAdmin.html(options) + }; + + Meteor.defer(() => { + Email.send(email); }); } diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index f4a2eea9d1ea..47ad26b2f68f 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -26,6 +26,8 @@ Meteor.methods({ if (active === false) { RocketChat.models.Users.unsetLoginTokens(userId); + } else { + RocketChat.models.Users.unsetReason(userId); } return true; diff --git a/server/methods/unsetUserReason.js b/server/methods/unsetUserReason.js deleted file mode 100644 index b2740a145bf8..000000000000 --- a/server/methods/unsetUserReason.js +++ /dev/null @@ -1,27 +0,0 @@ -Meteor.methods({ - unsetUserReason(userId) { - check(userId, String); - - if (!Meteor.userId()) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { - method: 'unsetUserReason' - }); - } - - if (RocketChat.authz.hasPermission(Meteor.userId(), 'edit-other-user-active-status') !== true) { - throw new Meteor.Error('error-not-allowed', 'Not allowed', { - method: 'unsetUserReason' - }); - } - - const user = RocketChat.models.Users.findOneById(userId); - - if (user) { - RocketChat.models.Users.unsetReason(userId); - - return true; - } - - return false; - } -}); From c04184849b16a9238c08112217d550c19fc486d2 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Tue, 30 May 2017 23:10:17 -0300 Subject: [PATCH 25/54] Moving reason tests to right file --- tests/end-to-end/ui/03-user-creation.js | 2 +- tests/end-to-end/ui/12-settings.js | 1 + tests/pageobjects/login.page.js | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/end-to-end/ui/03-user-creation.js b/tests/end-to-end/ui/03-user-creation.js index 47b4eeb2b812..3076b6cc4fa5 100644 --- a/tests/end-to-end/ui/03-user-creation.js +++ b/tests/end-to-end/ui/03-user-creation.js @@ -22,7 +22,7 @@ describe('[User Creation]', function() { it('it should create user', () => { loginPage.gotToRegister(); - loginPage.registerNewUser({username, email, password, reason}); + loginPage.registerNewUser({username, email, password}); loginPage.inputUsername.waitForExist(5000); diff --git a/tests/end-to-end/ui/12-settings.js b/tests/end-to-end/ui/12-settings.js index 381a305b3112..809a06f24307 100644 --- a/tests/end-to-end/ui/12-settings.js +++ b/tests/end-to-end/ui/12-settings.js @@ -458,6 +458,7 @@ describe('[Api Settings Change]', () => { loginPage.emailField.setValue(`setting${ email }`); loginPage.passwordField.setValue(password); loginPage.confirmPasswordField.setValue(password); + loginPage.reasonField.setValue(password); loginPage.submit(); diff --git a/tests/pageobjects/login.page.js b/tests/pageobjects/login.page.js index 3f03a4c3d80d..6c9ee1862983 100644 --- a/tests/pageobjects/login.page.js +++ b/tests/pageobjects/login.page.js @@ -19,7 +19,6 @@ class LoginPage extends Page { get emailInvalidText() { return browser.element('[name=email]~.input-error'); } get passwordInvalidText() { return browser.element('[name=pass]~.input-error'); } get confirmPasswordInvalidText() { return browser.element('[name=confirm-pass]~.input-error'); } - get reasonInvalidText() { return browser.element('[name=reason]~.input-error'); } get registrationSucceededCard() { return browser.element('#login-card h2'); } open() { @@ -40,7 +39,7 @@ class LoginPage extends Page { this.emailField.waitForVisible(15000); } - registerNewUser({username, email, password, reason}) { + registerNewUser({username, email, password}) { this.nameField.waitForVisible(5000); this.nameField.setValue(username); this.emailField.setValue(email); From 206c86845fcf8ea8d2ae0ac178ad1f9bd8488a65 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Tue, 30 May 2017 23:20:54 -0300 Subject: [PATCH 26/54] Moving reason tests to right file (2) --- tests/end-to-end/ui/03-user-creation.js | 2 +- tests/end-to-end/ui/12-settings.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/end-to-end/ui/03-user-creation.js b/tests/end-to-end/ui/03-user-creation.js index 3076b6cc4fa5..fe93c69caa34 100644 --- a/tests/end-to-end/ui/03-user-creation.js +++ b/tests/end-to-end/ui/03-user-creation.js @@ -5,7 +5,7 @@ import loginPage from '../../pageobjects/login.page'; import mainContent from '../../pageobjects/main-content.page'; //test data imports -import {username, email, password, reason} from '../../data/user.js'; +import {username, email, password} from '../../data/user.js'; diff --git a/tests/end-to-end/ui/12-settings.js b/tests/end-to-end/ui/12-settings.js index 809a06f24307..0bb9c19506d7 100644 --- a/tests/end-to-end/ui/12-settings.js +++ b/tests/end-to-end/ui/12-settings.js @@ -16,7 +16,7 @@ import admin from '../../pageobjects/administration.page'; import {checkIfUserIsValid, checkIfUserIsAdmin} from '../../data/checks'; import {targetUser, imgURL} from '../../data/interactions.js'; -import {adminUsername, adminEmail, adminPassword, username, email, password} from '../../data/user.js'; +import {adminUsername, adminEmail, adminPassword, username, email, password, reason} from '../../data/user.js'; function api(path) { return prefix + path; @@ -458,7 +458,7 @@ describe('[Api Settings Change]', () => { loginPage.emailField.setValue(`setting${ email }`); loginPage.passwordField.setValue(password); loginPage.confirmPasswordField.setValue(password); - loginPage.reasonField.setValue(password); + loginPage.reasonField.setValue(reason); loginPage.submit(); From 72d83355de28da6cc40d8f7daf2ac95086a393bf Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Wed, 31 May 2017 00:16:29 -0300 Subject: [PATCH 27/54] Fixing test where field was not found --- tests/pageobjects/login.page.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pageobjects/login.page.js b/tests/pageobjects/login.page.js index 6c9ee1862983..d049f31c9cac 100644 --- a/tests/pageobjects/login.page.js +++ b/tests/pageobjects/login.page.js @@ -11,7 +11,7 @@ class LoginPage extends Page { get emailField() { return browser.element('[name=email]'); } get passwordField() { return browser.element('[name=pass]'); } get confirmPasswordField() { return browser.element('[name=confirm-pass]'); } - get reasonField() { return browser.element('[reason]'); } + get reasonField() { return browser.element('[name=reason]'); } get inputUsername() { return browser.element('form#login-card input#username'); } get emailOrUsernameInvalidText() { return browser.element('[name=emailOrUsername]~.input-error'); } From 14825360cae71f9935eda38c331b911f4fc703d7 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Wed, 24 May 2017 23:45:52 -0300 Subject: [PATCH 28/54] Changes for issue #976. Still need some work --- packages/rocketchat-i18n/i18n/en.i18n.json | 1 + server/lib/accounts.js | 26 ++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 1b2888536b9a..8bd722e7a087 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1106,6 +1106,7 @@ "Office_hours_updated": "Office hours updated", "Offline": "Offline", "Offline_DM_Email": "You have been direct messaged by __user__", + "User_Needs_Approval": "A new user registered and needs approval", "Offline_form": "Offline form", "Offline_form_unavailable_message": "Offline form unavailable message", "Offline_Link_Message": "GO TO MESSAGE", diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 1cffa6d39a00..9b708eee8f82 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -91,6 +91,32 @@ Accounts.onCreateUser(function(options, user = {}) { } } + if (!user.active) { + user.emails.some((email) => { + + const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); + const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + const divisorMessage = '
'; + const siteName = RocketChat.settings.get('Site_Name'); + const messageHTML = `

A user with email ${options.email} has been registered.
Please check Administration -> Users to activate or delete it.`; + + emailSubject = TAPi18n.__('User_Needs_Approval'); + + RocketChat.models.Roles.findUsersInRole('admin').forEach(function (adminUser) { + email = { + to: adminUser.emails[0].address, + from: RocketChat.settings.get('From_Email'), + subject: `[${ siteName }] ${ emailSubject }`, + html: header + messageHTML + divisorMessage + footer + }; + }); + + Meteor.defer(() => { + Email.send(email); + }); + }); + } + return user; }); From 1ebd3712fe30962b8bdd4f71ef44facaaf264bc1 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 25 May 2017 00:02:34 -0300 Subject: [PATCH 29/54] Moved email strings to propper indexes on i18n --- packages/rocketchat-i18n/i18n/en.i18n.json | 3 ++- server/lib/accounts.js | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 8bd722e7a087..ef42f5dfac0c 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -42,6 +42,8 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
  • [name], [fname], [lname] for the user's full name, first name or last name, respectively.
  • [email] for the user's email.
  • [Site_Name] and [Site_URL] for the Application Name and URL respectively.
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", + "Accounts_Enrollment_Email_Approval_Needed_Default": "

A user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Enrollment_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", "Accounts_Iframe_api_url": "API URL", @@ -1106,7 +1108,6 @@ "Office_hours_updated": "Office hours updated", "Offline": "Offline", "Offline_DM_Email": "You have been direct messaged by __user__", - "User_Needs_Approval": "A new user registered and needs approval", "Offline_form": "Offline form", "Offline_form_unavailable_message": "Offline form unavailable message", "Offline_Link_Message": "GO TO MESSAGE", diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 9b708eee8f82..31a1cda075cb 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -98,9 +98,11 @@ Accounts.onCreateUser(function(options, user = {}) { const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); const divisorMessage = '


'; const siteName = RocketChat.settings.get('Site_Name'); - const messageHTML = `

A user with email ${options.email} has been registered.
Please check Administration -> Users to activate or delete it.`; + const messageHTML = RocketChat.placeholders.replace(TAPi18n.__('Accounts_Enrollment_Email_Approval_Needed_Default'), { + email: options.email + }); - emailSubject = TAPi18n.__('User_Needs_Approval'); + emailSubject = TAPi18n.__('Accounts_Enrollment_Email_Approval_Needed_Subject_Default'); RocketChat.models.Roles.findUsersInRole('admin').forEach(function (adminUser) { email = { From 073dd0be110ab51a94d8c615e41bc7716f8e6217 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 25 May 2017 01:18:16 -0300 Subject: [PATCH 30/54] Created templates for subject and mail body --- packages/rocketchat-i18n/i18n/en.i18n.json | 4 +- server/lib/accounts.js | 48 ++++++++++++++-------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index ef42f5dfac0c..52c2f6d3bc3d 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -42,8 +42,8 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
  • [name], [fname], [lname] for the user's full name, first name or last name, respectively.
  • [email] for the user's email.
  • [Site_Name] and [Site_URL] for the Application Name and URL respectively.
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", - "Accounts_Enrollment_Email_Approval_Needed_Default": "

A user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", - "Accounts_Enrollment_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", + "Accounts_Admin_Email_Approval_Needed_Default": "

A user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Admin_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", "Accounts_Iframe_api_url": "API URL", diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 31a1cda075cb..b946bf60a8bc 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -9,6 +9,8 @@ Accounts.emailTemplates.siteName = RocketChat.settings.get('Site_Name'); Accounts.emailTemplates.from = `${ RocketChat.settings.get('Site_Name') } <${ RocketChat.settings.get('From_Email') }>`; +Accounts.emailTemplates.notifyAdmin = {}; + const verifyEmailHtml = Accounts.emailTemplates.verifyEmail.text; Accounts.emailTemplates.verifyEmail.html = function(user, url) { @@ -56,6 +58,31 @@ Accounts.emailTemplates.enrollAccount.html = function(user = {}/*, url*/) { return header + html + footer; }; +Accounts.emailTemplates.notifyAdmin.subject = function() { + let subject, siteName; + + subject = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Subject_Default'); + siteName = RocketChat.settings.get('Site_Name'); + + return `[${ siteName }] ${ subject }`; +}; + +Accounts.emailTemplates.notifyAdmin.html = function(user = {}) { + + let html; + + html = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Default'); + + const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); + const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + + html = RocketChat.placeholders.replace(html, { + email: user.emails[0].address + }); + + return header + html + footer; +}; + Accounts.onCreateUser(function(options, user = {}) { RocketChat.callbacks.run('beforeCreateUser', options, user); @@ -93,28 +120,17 @@ Accounts.onCreateUser(function(options, user = {}) { if (!user.active) { user.emails.some((email) => { - - const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); - const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); - const divisorMessage = '


'; - const siteName = RocketChat.settings.get('Site_Name'); - const messageHTML = RocketChat.placeholders.replace(TAPi18n.__('Accounts_Enrollment_Email_Approval_Needed_Default'), { - email: options.email - }); - - emailSubject = TAPi18n.__('Accounts_Enrollment_Email_Approval_Needed_Subject_Default'); - RocketChat.models.Roles.findUsersInRole('admin').forEach(function (adminUser) { email = { to: adminUser.emails[0].address, from: RocketChat.settings.get('From_Email'), - subject: `[${ siteName }] ${ emailSubject }`, - html: header + messageHTML + divisorMessage + footer + subject: Accounts.emailTemplates.notifyAdmin.subject(), + html: Accounts.emailTemplates.notifyAdmin.html(user) }; - }); - Meteor.defer(() => { - Email.send(email); + Meteor.defer(() => { + Email.send(email); + }); }); }); } From 42201cf2c66a69b46f609bdb268dfbfb7542aa48 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 25 May 2017 09:25:08 -0300 Subject: [PATCH 31/54] Fix typo and code standards --- packages/rocketchat-i18n/i18n/en.i18n.json | 2 +- server/lib/accounts.js | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 52c2f6d3bc3d..5a368896b9ff 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -42,7 +42,7 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
  • [name], [fname], [lname] for the user's full name, first name or last name, respectively.
  • [email] for the user's email.
  • [Site_Name] and [Site_URL] for the Application Name and URL respectively.
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", - "Accounts_Admin_Email_Approval_Needed_Default": "

A user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Admin_Email_Approval_Needed_Default": "

An user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", "Accounts_Admin_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", diff --git a/server/lib/accounts.js b/server/lib/accounts.js index b946bf60a8bc..b67a283033f2 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -59,10 +59,8 @@ Accounts.emailTemplates.enrollAccount.html = function(user = {}/*, url*/) { }; Accounts.emailTemplates.notifyAdmin.subject = function() { - let subject, siteName; - - subject = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Subject_Default'); - siteName = RocketChat.settings.get('Site_Name'); + const subject = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Subject_Default'); + const siteName = RocketChat.settings.get('Site_Name'); return `[${ siteName }] ${ subject }`; }; @@ -120,7 +118,7 @@ Accounts.onCreateUser(function(options, user = {}) { if (!user.active) { user.emails.some((email) => { - RocketChat.models.Roles.findUsersInRole('admin').forEach(function (adminUser) { + RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { email = { to: adminUser.emails[0].address, from: RocketChat.settings.get('From_Email'), From 4952eb1ec8919fbcb95d11d9d6ccac99eee1ce08 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 25 May 2017 22:29:29 -0300 Subject: [PATCH 32/54] Modified to change email to all admins at once --- server/lib/accounts.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/server/lib/accounts.js b/server/lib/accounts.js index b67a283033f2..155e15cc3651 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -118,17 +118,21 @@ Accounts.onCreateUser(function(options, user = {}) { if (!user.active) { user.emails.some((email) => { + const destinations = []; + RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { - email = { - to: adminUser.emails[0].address, - from: RocketChat.settings.get('From_Email'), - subject: Accounts.emailTemplates.notifyAdmin.subject(), - html: Accounts.emailTemplates.notifyAdmin.html(user) - }; - - Meteor.defer(() => { - Email.send(email); - }); + destinations.push(`${ adminUser.name }<${ adminUser.emails[0].address }>`); + }); + + email = { + to: destinations, + from: RocketChat.settings.get('From_Email'), + subject: Accounts.emailTemplates.notifyAdmin.subject(), + html: Accounts.emailTemplates.notifyAdmin.html(user) + }; + + Meteor.defer(() => { + Email.send(email); }); }); } From b9f983a1b58476b01f7a206cb2ba07849529ed5c Mon Sep 17 00:00:00 2001 From: Fernando Nascimento Date: Fri, 26 May 2017 19:11:35 -0300 Subject: [PATCH 33/54] Added reason field into register screen --- packages/rocketchat-i18n/i18n/en.i18n.json | 1 + packages/rocketchat-ui-login/client/login/form.html | 9 +++++++++ packages/rocketchat-ui-login/client/login/form.js | 3 +++ 3 files changed, 13 insertions(+) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 5a368896b9ff..83f837a928ab 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -1227,6 +1227,7 @@ "Read_only_changed_successfully": "Read only changed successfully", "Read_only_channel": "Read Only Channel", "Read_only_group": "Read Only Group", + "Reason_To_Join": "Reason to Join", "Record": "Record", "Redirect_URI": "Redirect URI", "Refresh_oauth_services": "Refresh OAuth Services", diff --git a/packages/rocketchat-ui-login/client/login/form.html b/packages/rocketchat-ui-login/client/login/form.html index c124177edc63..46f37802e5d8 100644 --- a/packages/rocketchat-ui-login/client/login/form.html +++ b/packages/rocketchat-ui-login/client/login/form.html @@ -73,6 +73,15 @@

{{{_ "Registration_Succeeded"}}}

{{/if}} + {{#if manuallyApproveNewUsers}} +
+ +
+ +
+
+
+ {{/if}} {{/if}} {{#if state 'forgot-password' 'email-verification'}}
diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index fa6d28a19a5b..cee2e76937d5 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -58,6 +58,9 @@ Template.loginForm.helpers({ }, hasOnePassword() { return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; + }, + manuallyApproveNewUsers() { + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); } }); From dbcba5634b18285e6e8a109bd0f19368c630f438 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 00:37:32 -0300 Subject: [PATCH 34/54] - Added error message for invalid reason - Added method to save reason into user object - Added validation to display field but setting Accounts_ManuallyApproveNewUsers is not working :( --- packages/rocketchat-i18n/i18n/en.i18n.json | 1 + packages/rocketchat-lib/server/models/Users.js | 10 ++++++++++ packages/rocketchat-ui-login/client/login/form.js | 7 ++++++- server/methods/registerUser.js | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 83f837a928ab..8e275ae18a8f 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -764,6 +764,7 @@ "Invalid_name": "The name must not be empty", "Invalid_notification_setting_s": "Invalid notification setting: %s", "Invalid_pass": "The password must not be empty", + "Invalid_reason": "The reason to join must not be empty", "Invalid_room_name": "%s is not a valid room name,
use only letters, numbers, hyphens and underscores", "Invalid_secret_URL_message": "The URL provided is invalid.", "Invalid_setting_s": "Invalid setting: %s", diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index 941416475c6e..a492a5b75f7a 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -313,6 +313,16 @@ class ModelUsers extends RocketChat.models._Base { return this.update(_id, update); } + setReason(_id, reason) { + const update = { + $set: { + reason + } + }; + + return this.update(_id, update); + } + setCustomFields(_id, fields) { const values = {}; Object.keys(fields).reduce(key => { diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index cee2e76937d5..ebcd82c2ba37 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -60,7 +60,9 @@ Template.loginForm.helpers({ return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; }, manuallyApproveNewUsers() { - return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); + //TODO verify why it' s not getting this setting + //return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); + return true; } }); @@ -253,6 +255,9 @@ Template.loginForm.onCreated(function() { if (RocketChat.settings.get('Accounts_RequirePasswordConfirmation') && formObj['confirm-pass'] !== formObj['pass']) { validationObj['confirm-pass'] = t('Invalid_confirm_pass'); } + if (true && !formObj['reason']) { + validationObj['reason'] = t('Invalid_reason'); + } validateCustomFields(formObj, validationObj); } $('#login-card h2').removeClass('error'); diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index 17c0ceb71b14..55c7f79ea945 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -17,6 +17,7 @@ Meteor.methods({ email: String, pass: String, name: String, + reason: String, secretURL: Match.Optional(String) })); } @@ -45,6 +46,7 @@ Meteor.methods({ } RocketChat.models.Users.setName(userId, s.trim(formData.name)); + RocketChat.models.Users.setReason(userId, s.trim(formData.reason)); RocketChat.saveCustomFields(userId, formData); From b10b887a93acab0fb0a321a5e7dc377e75d60c20 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 00:54:16 -0300 Subject: [PATCH 35/54] - Changed to use the correct setting --- packages/rocketchat-ui-login/client/login/form.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index ebcd82c2ba37..6f1fee80919f 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -60,9 +60,7 @@ Template.loginForm.helpers({ return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; }, manuallyApproveNewUsers() { - //TODO verify why it' s not getting this setting - //return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); - return true; + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); } }); @@ -255,7 +253,7 @@ Template.loginForm.onCreated(function() { if (RocketChat.settings.get('Accounts_RequirePasswordConfirmation') && formObj['confirm-pass'] !== formObj['pass']) { validationObj['confirm-pass'] = t('Invalid_confirm_pass'); } - if (true && !formObj['reason']) { + if (RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && !formObj['reason']) { validationObj['reason'] = t('Invalid_reason'); } validateCustomFields(formObj, validationObj); From 4248273f244709e182d219b7ab5b1156deace286 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 13:43:43 -0300 Subject: [PATCH 36/54] - Modified admin message to contain reason and user name - Modified function placeholders to replace reason as well - Modified email template on accounts.js --- packages/rocketchat-i18n/i18n/en.i18n.json | 2 +- packages/rocketchat-lib/lib/placeholders.js | 1 + server/lib/accounts.js | 8 +++++--- server/methods/registerUser.js | 4 +++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 8e275ae18a8f..5a0dd4ca20ca 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -42,7 +42,7 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
  • [name], [fname], [lname] for the user's full name, first name or last name, respectively.
  • [email] for the user's email.
  • [Site_Name] and [Site_URL] for the Application Name and URL respectively.
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", - "Accounts_Admin_Email_Approval_Needed_Default": "

An user with email [email] has been registered.
Please check Administration -> Users to activate or delete it.", + "Accounts_Admin_Email_Approval_Needed_Default": "

The user [name] ([email]) has been registered.

Reason: [reason]

Please check Administration -> Users to activate or delete it.

", "Accounts_Admin_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget user session on window close", "Accounts_Iframe_api_method": "Api Method", diff --git a/packages/rocketchat-lib/lib/placeholders.js b/packages/rocketchat-lib/lib/placeholders.js index 82fb613d050a..26eca737afdf 100644 --- a/packages/rocketchat-lib/lib/placeholders.js +++ b/packages/rocketchat-lib/lib/placeholders.js @@ -14,6 +14,7 @@ RocketChat.placeholders.replace = function(str, data) { str = str.replace(/\[lname\]/g, _.strRightBack(data.name, ' ') || ''); str = str.replace(/\[email\]/g, data.email || ''); str = str.replace(/\[password\]/g, data.password || ''); + str = str.replace(/\[reason\]/g, data.reason || ''); if (data.unsubscribe) { str = str.replace(/\[unsubscribe\]/g, data.unsubscribe); diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 155e15cc3651..8d69eacb8ba4 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -65,7 +65,7 @@ Accounts.emailTemplates.notifyAdmin.subject = function() { return `[${ siteName }] ${ subject }`; }; -Accounts.emailTemplates.notifyAdmin.html = function(user = {}) { +Accounts.emailTemplates.notifyAdmin.html = function(options = {}) { let html; @@ -75,7 +75,9 @@ Accounts.emailTemplates.notifyAdmin.html = function(user = {}) { const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); html = RocketChat.placeholders.replace(html, { - email: user.emails[0].address + name: options.name, + email: options.email, + reason: options.reason }); return header + html + footer; @@ -128,7 +130,7 @@ Accounts.onCreateUser(function(options, user = {}) { to: destinations, from: RocketChat.settings.get('From_Email'), subject: Accounts.emailTemplates.notifyAdmin.subject(), - html: Accounts.emailTemplates.notifyAdmin.html(user) + html: Accounts.emailTemplates.notifyAdmin.html(options) }; Meteor.defer(() => { diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index 55c7f79ea945..bd1250188028 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -32,7 +32,9 @@ Meteor.methods({ const userData = { email: s.trim(formData.email.toLowerCase()), - password: formData.pass + password: formData.pass, + name: formData.name, + reason: formData.reason }; // Check if user has already been imported and never logged in. If so, set password and let it through From 87b51d044feca568d800d405367453ba8ca4c740 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 14:56:10 -0300 Subject: [PATCH 37/54] - Added public key to use Accounts_ManuallyApproveNewUsers on frontend --- packages/rocketchat-lib/server/startup/settings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rocketchat-lib/server/startup/settings.js b/packages/rocketchat-lib/server/startup/settings.js index 1671d5185bee..ab74bc3e7350 100644 --- a/packages/rocketchat-lib/server/startup/settings.js +++ b/packages/rocketchat-lib/server/startup/settings.js @@ -95,6 +95,7 @@ RocketChat.settings.addGroup('Accounts', function() { } }); this.add('Accounts_ManuallyApproveNewUsers', false, { + 'public': true, type: 'boolean' }); this.add('Accounts_AllowedDomainsList', '', { From 195d56bbee0a6ccd6cd81b3cbcd1de85d9bbf20c Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 15:49:09 -0300 Subject: [PATCH 38/54] - Displaying reason on user info - Reason displayed only if setting is active and user is not active - Added reason to getFullUserData --- .../rocketchat-lib/server/functions/getFullUserData.js | 3 ++- packages/rocketchat-lib/server/models/Users.js | 1 + packages/rocketchat-ui-flextab/client/tabs/userInfo.html | 7 ++++++- packages/rocketchat-ui-flextab/client/tabs/userInfo.js | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-lib/server/functions/getFullUserData.js b/packages/rocketchat-lib/server/functions/getFullUserData.js index 0b5290b3b3e8..cbeb1e7f11c6 100644 --- a/packages/rocketchat-lib/server/functions/getFullUserData.js +++ b/packages/rocketchat-lib/server/functions/getFullUserData.js @@ -6,7 +6,8 @@ RocketChat.getFullUserData = function({userId, filter, limit}) { status: 1, utcOffset: 1, type: 1, - active: 1 + active: 1, + reason: 1 }; if (RocketChat.authz.hasPermission(userId, 'view-full-other-user-info')) { diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index a492a5b75f7a..184789c2a1cc 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -9,6 +9,7 @@ class ModelUsers extends RocketChat.models._Base { this.tryEnsureIndex({ 'active': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'statusConnection': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'type': 1 }); + this.tryEnsureIndex({ 'reason': 1 }); this.cache.ensureIndex('username', 'unique'); } diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.html b/packages/rocketchat-ui-flextab/client/tabs/userInfo.html index 4b1dfaffa3c5..6d70b7b581d7 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.html +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.html @@ -26,7 +26,7 @@

{{name}}

{{#if hasPhone}} {{#each phone}}

{{phoneNumber}}

{{/each}} {{/if}} - {{#if lastLogin}}

{{_ "Created_at"}}: {{createdAt}}

{{/if}} + {{#if createdAt}}

{{_ "Created_at"}}: {{createdAt}}

{{/if}} {{#if lastLogin}}

{{_ "Last_login"}}: {{lastLogin}}

{{/if}} {{#if services.facebook.id}}

{{services.facebook.name}}

{{/if}} {{#if services.github.id}}

{{services.github.username}}

{{/if}} @@ -37,6 +37,11 @@

{{name}}

{{#if services.twitter.id}}

{{services.twitter.screenName}}

{{/if}} {{#if services.wordpress.id}}

{{services.wordpress.user_login}}

{{/if}} {{/if}} + {{#if shouldDisplayReason}} +

+ {{_ "Reason_To_Join"}}: {{user.reason}} +

+ {{/if}}
{{/with}} diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js index e64f60b0e5fc..ede5cb950e26 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js @@ -180,6 +180,11 @@ Template.userInfo.helpers({ isBlocker() { const subscription = ChatSubscription.findOne({rid:Session.get('openedRoom'), 'u._id': Meteor.userId()}, { fields: { blocker: 1 } }); return subscription.blocker; + }, + + shouldDisplayReason() { + const user = Template.instance().user.get(); + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false; } }); From 24f0618a8c4fcf8b28b91306d65b4c418e111291 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 17:45:38 -0300 Subject: [PATCH 39/54] Added logic to remove user reason once user gets activated --- client/methods/unsetUserReason.js | 6 ++++ .../rocketchat-lib/server/models/Users.js | 30 ++++++++++++------- .../client/tabs/userInfo.js | 5 +++- server/methods/unsetUserReason.js | 27 +++++++++++++++++ 4 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 client/methods/unsetUserReason.js create mode 100644 server/methods/unsetUserReason.js diff --git a/client/methods/unsetUserReason.js b/client/methods/unsetUserReason.js new file mode 100644 index 000000000000..245eb587dfbb --- /dev/null +++ b/client/methods/unsetUserReason.js @@ -0,0 +1,6 @@ +Meteor.methods({ + unsetUserReason(userId) { + Meteor.users.update(userId, { $unset: { 'reason' : 1 } }); + return true; + } +}); diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index 184789c2a1cc..ce21729643aa 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -314,16 +314,6 @@ class ModelUsers extends RocketChat.models._Base { return this.update(_id, update); } - setReason(_id, reason) { - const update = { - $set: { - reason - } - }; - - return this.update(_id, update); - } - setCustomFields(_id, fields) { const values = {}; Object.keys(fields).reduce(key => { @@ -504,6 +494,26 @@ class ModelUsers extends RocketChat.models._Base { return this.update({ _id }, update); } + setReason(_id, reason) { + const update = { + $set: { + reason + } + }; + + return this.update(_id, update); + } + + unsetReason(_id) { + const update = { + $unset: { + 'reason' : true, + } + }; + + return this.update(_id, update); + } + // INSERT create(data) { const user = { diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js index ede5cb950e26..883751232fe7 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js @@ -184,7 +184,7 @@ Template.userInfo.helpers({ shouldDisplayReason() { const user = Template.instance().user.get(); - return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false; + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers') && user.active === false && user.reason; } }); @@ -395,6 +395,9 @@ Template.userInfo.events({ if (user) { return Meteor.call('setUserActiveStatus', user._id, true, function(error, result) { if (result) { + + Meteor.call('unsetUserReason', user._id); + toastr.success(t('User_has_been_activated')); } if (error) { diff --git a/server/methods/unsetUserReason.js b/server/methods/unsetUserReason.js new file mode 100644 index 000000000000..b2740a145bf8 --- /dev/null +++ b/server/methods/unsetUserReason.js @@ -0,0 +1,27 @@ +Meteor.methods({ + unsetUserReason(userId) { + check(userId, String); + + if (!Meteor.userId()) { + throw new Meteor.Error('error-invalid-user', 'Invalid user', { + method: 'unsetUserReason' + }); + } + + if (RocketChat.authz.hasPermission(Meteor.userId(), 'edit-other-user-active-status') !== true) { + throw new Meteor.Error('error-not-allowed', 'Not allowed', { + method: 'unsetUserReason' + }); + } + + const user = RocketChat.models.Users.findOneById(userId); + + if (user) { + RocketChat.models.Users.unsetReason(userId); + + return true; + } + + return false; + } +}); From f9d736390832eb69d9870b12696c0ed911441fda Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 00:37:32 -0300 Subject: [PATCH 40/54] - Added error message for invalid reason - Added method to save reason into user object - Added validation to display field but setting Accounts_ManuallyApproveNewUsers is not working :( --- packages/rocketchat-lib/server/models/Users.js | 1 - packages/rocketchat-ui-login/client/login/form.js | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index ce21729643aa..257ae573aa2f 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -9,7 +9,6 @@ class ModelUsers extends RocketChat.models._Base { this.tryEnsureIndex({ 'active': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'statusConnection': 1 }, { sparse: 1 }); this.tryEnsureIndex({ 'type': 1 }); - this.tryEnsureIndex({ 'reason': 1 }); this.cache.ensureIndex('username', 'unique'); } diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index 6f1fee80919f..e5a8746734a5 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -60,7 +60,9 @@ Template.loginForm.helpers({ return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; }, manuallyApproveNewUsers() { - return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); + //TODO verify why it' s not getting this setting + //return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); + return true; } }); From a54af9bff514d141435d6b12d4e3d241ad424133 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sat, 27 May 2017 00:54:16 -0300 Subject: [PATCH 41/54] - Changed to use the correct setting --- packages/rocketchat-ui-login/client/login/form.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/rocketchat-ui-login/client/login/form.js b/packages/rocketchat-ui-login/client/login/form.js index e5a8746734a5..6f1fee80919f 100644 --- a/packages/rocketchat-ui-login/client/login/form.js +++ b/packages/rocketchat-ui-login/client/login/form.js @@ -60,9 +60,7 @@ Template.loginForm.helpers({ return typeof OnePassword !== 'undefined' && OnePassword.findLoginForUrl && typeof device !== 'undefined' && device.platform && device.platform.toLocaleLowerCase() === 'ios'; }, manuallyApproveNewUsers() { - //TODO verify why it' s not getting this setting - //return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); - return true; + return RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); } }); From e04387af1d8f729500f1fbde43291fe9eb4b45dc Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 18:08:20 -0300 Subject: [PATCH 42/54] Removing unneeded comma --- packages/rocketchat-lib/server/models/Users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index 257ae573aa2f..7224cd4d2a97 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -506,7 +506,7 @@ class ModelUsers extends RocketChat.models._Base { unsetReason(_id) { const update = { $unset: { - 'reason' : true, + 'reason' : true } }; From 920f928c4f36d677119cba55fd76e361ccf10311 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 20:36:41 -0300 Subject: [PATCH 43/54] Added conditionals to check and use reason field --- server/methods/registerUser.js | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index bd1250188028..cfe086c0bc92 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -2,6 +2,7 @@ Meteor.methods({ registerUser(formData) { const AllowAnonymousRead = RocketChat.settings.get('Accounts_AllowAnonymousRead'); const AllowAnonymousWrite = RocketChat.settings.get('Accounts_AllowAnonymousWrite'); + const manuallyApproveNewUsers = RocketChat.settings.get('Accounts_ManuallyApproveNewUsers'); if (AllowAnonymousRead === true && AllowAnonymousWrite === true && formData.email == null) { const userId = Accounts.insertUserDoc({}, { globalRoles: [ @@ -17,9 +18,14 @@ Meteor.methods({ email: String, pass: String, name: String, - reason: String, secretURL: Match.Optional(String) })); + + if (manuallyApproveNewUsers) { + check(formData, Match.ObjectIncluding({ + reason: String + })); + } } if (RocketChat.settings.get('Accounts_RegistrationForm') === 'Disabled') { @@ -33,10 +39,13 @@ Meteor.methods({ const userData = { email: s.trim(formData.email.toLowerCase()), password: formData.pass, - name: formData.name, - reason: formData.reason + name: formData.name }; + if (manuallyApproveNewUsers) { + userData.reason = formData.reason; + } + // Check if user has already been imported and never logged in. If so, set password and let it through const importedUser = RocketChat.models.Users.findOneByEmailAddress(s.trim(formData.email.toLowerCase())); let userId; @@ -48,7 +57,10 @@ Meteor.methods({ } RocketChat.models.Users.setName(userId, s.trim(formData.name)); - RocketChat.models.Users.setReason(userId, s.trim(formData.reason)); + + if (manuallyApproveNewUsers) { + RocketChat.models.Users.setReason(userId, s.trim(formData.reason)); + } RocketChat.saveCustomFields(userId, formData); From 6069e02f0ec5563472aa64db8f6f9d928d5cdfb7 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 21:10:03 -0300 Subject: [PATCH 44/54] Trying to fix user creation tests --- tests/data/user.js | 1 + tests/end-to-end/ui/03-user-creation.js | 4 ++-- tests/pageobjects/login.page.js | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/data/user.js b/tests/data/user.js index 92294f99dfcf..f9d51e8ba46b 100644 --- a/tests/data/user.js +++ b/tests/data/user.js @@ -1,6 +1,7 @@ export const username = `user.test.${ Date.now() }`; export const email = `${ username }@rocket.chat`; export const password = 'rocket.chat'; +export const reason = 'rocket.chat.reason'; export const adminUsername = 'rocketchat.internal.admin.test'; export const adminEmail = `${ adminUsername }@rocket.chat`; diff --git a/tests/end-to-end/ui/03-user-creation.js b/tests/end-to-end/ui/03-user-creation.js index fe93c69caa34..47b4eeb2b812 100644 --- a/tests/end-to-end/ui/03-user-creation.js +++ b/tests/end-to-end/ui/03-user-creation.js @@ -5,7 +5,7 @@ import loginPage from '../../pageobjects/login.page'; import mainContent from '../../pageobjects/main-content.page'; //test data imports -import {username, email, password} from '../../data/user.js'; +import {username, email, password, reason} from '../../data/user.js'; @@ -22,7 +22,7 @@ describe('[User Creation]', function() { it('it should create user', () => { loginPage.gotToRegister(); - loginPage.registerNewUser({username, email, password}); + loginPage.registerNewUser({username, email, password, reason}); loginPage.inputUsername.waitForExist(5000); diff --git a/tests/pageobjects/login.page.js b/tests/pageobjects/login.page.js index e0150d40a15a..15020173df95 100644 --- a/tests/pageobjects/login.page.js +++ b/tests/pageobjects/login.page.js @@ -11,6 +11,7 @@ class LoginPage extends Page { get emailField() { return browser.element('[name=email]'); } get passwordField() { return browser.element('[name=pass]'); } get confirmPasswordField() { return browser.element('[name=confirm-pass]'); } + get reasonField() { return browser.element('[reason]'); } get inputUsername() { return browser.element('form#login-card input#username'); } get emailOrUsernameInvalidText() { return browser.element('[name=emailOrUsername]~.input-error'); } @@ -18,6 +19,7 @@ class LoginPage extends Page { get emailInvalidText() { return browser.element('[name=email]~.input-error'); } get passwordInvalidText() { return browser.element('[name=pass]~.input-error'); } get confirmPasswordInvalidText() { return browser.element('[name=confirm-pass]~.input-error'); } + get reasonInvalidText() { return browser.element('[name=reason]~.input-error'); } get registrationSucceededCard() { return browser.element('#login-card h2'); } open() { @@ -38,12 +40,13 @@ class LoginPage extends Page { this.emailField.waitForVisible(15000); } - registerNewUser({username, email, password}) { + registerNewUser({username, email, password, reason}) { this.nameField.waitForVisible(5000); this.nameField.setValue(username); this.emailField.setValue(email); this.passwordField.setValue(password); this.confirmPasswordField.setValue(password); + this.reasonField.setValue(reason); this.submit(); } From 26c255ed55040d447bed9bc100f684b27603be08 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Sun, 28 May 2017 21:27:33 -0300 Subject: [PATCH 45/54] Trying to fix user creation tests(2) --- tests/pageobjects/login.page.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/pageobjects/login.page.js b/tests/pageobjects/login.page.js index 15020173df95..3f03a4c3d80d 100644 --- a/tests/pageobjects/login.page.js +++ b/tests/pageobjects/login.page.js @@ -46,7 +46,6 @@ class LoginPage extends Page { this.emailField.setValue(email); this.passwordField.setValue(password); this.confirmPasswordField.setValue(password); - this.reasonField.setValue(reason); this.submit(); } From 23219cd686c3e2adacfc5c445ffa4ced15bcefca Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Mon, 29 May 2017 23:52:52 -0300 Subject: [PATCH 46/54] Applying last suggestions --- client/methods/unsetUserReason.js | 6 ---- .../client/tabs/userInfo.js | 3 -- server/lib/accounts.js | 31 ++++++++++--------- server/methods/setUserActiveStatus.js | 2 ++ server/methods/unsetUserReason.js | 27 ---------------- 5 files changed, 18 insertions(+), 51 deletions(-) delete mode 100644 client/methods/unsetUserReason.js delete mode 100644 server/methods/unsetUserReason.js diff --git a/client/methods/unsetUserReason.js b/client/methods/unsetUserReason.js deleted file mode 100644 index 245eb587dfbb..000000000000 --- a/client/methods/unsetUserReason.js +++ /dev/null @@ -1,6 +0,0 @@ -Meteor.methods({ - unsetUserReason(userId) { - Meteor.users.update(userId, { $unset: { 'reason' : 1 } }); - return true; - } -}); diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js index 883751232fe7..cd540249fb0f 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.js +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.js @@ -395,9 +395,6 @@ Template.userInfo.events({ if (user) { return Meteor.call('setUserActiveStatus', user._id, true, function(error, result) { if (result) { - - Meteor.call('unsetUserReason', user._id); - toastr.success(t('User_has_been_activated')); } if (error) { diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 8d69eacb8ba4..c59ca905cb42 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -119,23 +119,24 @@ Accounts.onCreateUser(function(options, user = {}) { } if (!user.active) { - user.emails.some((email) => { - const destinations = []; + const destinations = []; + let email = {}; - RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { + RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { + if (adminUser.emails[0]) { destinations.push(`${ adminUser.name }<${ adminUser.emails[0].address }>`); - }); - - email = { - to: destinations, - from: RocketChat.settings.get('From_Email'), - subject: Accounts.emailTemplates.notifyAdmin.subject(), - html: Accounts.emailTemplates.notifyAdmin.html(options) - }; - - Meteor.defer(() => { - Email.send(email); - }); + } + }); + + email = { + to: destinations, + from: RocketChat.settings.get('From_Email'), + subject: Accounts.emailTemplates.notifyAdmin.subject(), + html: Accounts.emailTemplates.notifyAdmin.html(options) + }; + + Meteor.defer(() => { + Email.send(email); }); } diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index f4a2eea9d1ea..47ad26b2f68f 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -26,6 +26,8 @@ Meteor.methods({ if (active === false) { RocketChat.models.Users.unsetLoginTokens(userId); + } else { + RocketChat.models.Users.unsetReason(userId); } return true; diff --git a/server/methods/unsetUserReason.js b/server/methods/unsetUserReason.js deleted file mode 100644 index b2740a145bf8..000000000000 --- a/server/methods/unsetUserReason.js +++ /dev/null @@ -1,27 +0,0 @@ -Meteor.methods({ - unsetUserReason(userId) { - check(userId, String); - - if (!Meteor.userId()) { - throw new Meteor.Error('error-invalid-user', 'Invalid user', { - method: 'unsetUserReason' - }); - } - - if (RocketChat.authz.hasPermission(Meteor.userId(), 'edit-other-user-active-status') !== true) { - throw new Meteor.Error('error-not-allowed', 'Not allowed', { - method: 'unsetUserReason' - }); - } - - const user = RocketChat.models.Users.findOneById(userId); - - if (user) { - RocketChat.models.Users.unsetReason(userId); - - return true; - } - - return false; - } -}); From dfff89ed13218db3718af09930476b6d76aeb653 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Tue, 30 May 2017 23:10:17 -0300 Subject: [PATCH 47/54] Moving reason tests to right file --- tests/end-to-end/ui/03-user-creation.js | 2 +- tests/end-to-end/ui/12-settings.js | 1 + tests/pageobjects/login.page.js | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/end-to-end/ui/03-user-creation.js b/tests/end-to-end/ui/03-user-creation.js index 47b4eeb2b812..3076b6cc4fa5 100644 --- a/tests/end-to-end/ui/03-user-creation.js +++ b/tests/end-to-end/ui/03-user-creation.js @@ -22,7 +22,7 @@ describe('[User Creation]', function() { it('it should create user', () => { loginPage.gotToRegister(); - loginPage.registerNewUser({username, email, password, reason}); + loginPage.registerNewUser({username, email, password}); loginPage.inputUsername.waitForExist(5000); diff --git a/tests/end-to-end/ui/12-settings.js b/tests/end-to-end/ui/12-settings.js index 11e9181fd513..f2f22f4aa2b0 100644 --- a/tests/end-to-end/ui/12-settings.js +++ b/tests/end-to-end/ui/12-settings.js @@ -459,6 +459,7 @@ describe('[Api Settings Change]', () => { loginPage.emailField.setValue(`setting${ email }`); loginPage.passwordField.setValue(password); loginPage.confirmPasswordField.setValue(password); + loginPage.reasonField.setValue(password); loginPage.submit(); diff --git a/tests/pageobjects/login.page.js b/tests/pageobjects/login.page.js index 3f03a4c3d80d..6c9ee1862983 100644 --- a/tests/pageobjects/login.page.js +++ b/tests/pageobjects/login.page.js @@ -19,7 +19,6 @@ class LoginPage extends Page { get emailInvalidText() { return browser.element('[name=email]~.input-error'); } get passwordInvalidText() { return browser.element('[name=pass]~.input-error'); } get confirmPasswordInvalidText() { return browser.element('[name=confirm-pass]~.input-error'); } - get reasonInvalidText() { return browser.element('[name=reason]~.input-error'); } get registrationSucceededCard() { return browser.element('#login-card h2'); } open() { @@ -40,7 +39,7 @@ class LoginPage extends Page { this.emailField.waitForVisible(15000); } - registerNewUser({username, email, password, reason}) { + registerNewUser({username, email, password}) { this.nameField.waitForVisible(5000); this.nameField.setValue(username); this.emailField.setValue(email); From 128116db92a2ea75e48d1e153e99993388ff9a50 Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Tue, 30 May 2017 23:20:54 -0300 Subject: [PATCH 48/54] Moving reason tests to right file (2) --- tests/end-to-end/ui/03-user-creation.js | 2 +- tests/end-to-end/ui/12-settings.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/end-to-end/ui/03-user-creation.js b/tests/end-to-end/ui/03-user-creation.js index 3076b6cc4fa5..fe93c69caa34 100644 --- a/tests/end-to-end/ui/03-user-creation.js +++ b/tests/end-to-end/ui/03-user-creation.js @@ -5,7 +5,7 @@ import loginPage from '../../pageobjects/login.page'; import mainContent from '../../pageobjects/main-content.page'; //test data imports -import {username, email, password, reason} from '../../data/user.js'; +import {username, email, password} from '../../data/user.js'; diff --git a/tests/end-to-end/ui/12-settings.js b/tests/end-to-end/ui/12-settings.js index f2f22f4aa2b0..5f49dbafde6d 100644 --- a/tests/end-to-end/ui/12-settings.js +++ b/tests/end-to-end/ui/12-settings.js @@ -16,7 +16,7 @@ import admin from '../../pageobjects/administration.page'; import {checkIfUserIsValid, checkIfUserIsAdmin} from '../../data/checks'; import {targetUser, imgURL} from '../../data/interactions.js'; -import {adminUsername, adminEmail, adminPassword, username, email, password} from '../../data/user.js'; +import {adminUsername, adminEmail, adminPassword, username, email, password, reason} from '../../data/user.js'; function api(path) { return prefix + path; @@ -459,7 +459,7 @@ describe('[Api Settings Change]', () => { loginPage.emailField.setValue(`setting${ email }`); loginPage.passwordField.setValue(password); loginPage.confirmPasswordField.setValue(password); - loginPage.reasonField.setValue(password); + loginPage.reasonField.setValue(reason); loginPage.submit(); From 645943abe0d556742e055df9858061fa13fe832a Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Wed, 31 May 2017 00:16:29 -0300 Subject: [PATCH 49/54] Fixing test where field was not found --- tests/pageobjects/login.page.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pageobjects/login.page.js b/tests/pageobjects/login.page.js index 6c9ee1862983..d049f31c9cac 100644 --- a/tests/pageobjects/login.page.js +++ b/tests/pageobjects/login.page.js @@ -11,7 +11,7 @@ class LoginPage extends Page { get emailField() { return browser.element('[name=email]'); } get passwordField() { return browser.element('[name=pass]'); } get confirmPasswordField() { return browser.element('[name=confirm-pass]'); } - get reasonField() { return browser.element('[reason]'); } + get reasonField() { return browser.element('[name=reason]'); } get inputUsername() { return browser.element('form#login-card input#username'); } get emailOrUsernameInvalidText() { return browser.element('[name=emailOrUsername]~.input-error'); } From d5f141b5f71aef49d8a50165bfc752e7525991aa Mon Sep 17 00:00:00 2001 From: Luis Fernando do Nascimento Date: Thu, 1 Jun 2017 00:27:54 -0300 Subject: [PATCH 50/54] Rebasing with develop and applied code suggestion --- server/lib/accounts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/lib/accounts.js b/server/lib/accounts.js index c59ca905cb42..d3b0045ce2c8 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -123,7 +123,7 @@ Accounts.onCreateUser(function(options, user = {}) { let email = {}; RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { - if (adminUser.emails[0]) { + if (adminUser.emails && adminUser.emails[0] && adminUser.emails[0].address) { destinations.push(`${ adminUser.name }<${ adminUser.emails[0].address }>`); } }); From 1b564f409835b73af8ffbafc8afccbfba6d24e02 Mon Sep 17 00:00:00 2001 From: Martin Schoeler Date: Fri, 2 Jun 2017 11:28:51 -0300 Subject: [PATCH 51/54] Fix the tests --- tests/end-to-end/ui/12-settings.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/end-to-end/ui/12-settings.js b/tests/end-to-end/ui/12-settings.js index 5f49dbafde6d..667b749718ec 100644 --- a/tests/end-to-end/ui/12-settings.js +++ b/tests/end-to-end/ui/12-settings.js @@ -452,6 +452,7 @@ describe('[Api Settings Change]', () => { }); it('register the user', () => { + browser.refresh(); loginPage.registerButton.waitForVisible(5000); loginPage.registerButton.click(); loginPage.nameField.waitForVisible(5000); @@ -459,6 +460,7 @@ describe('[Api Settings Change]', () => { loginPage.emailField.setValue(`setting${ email }`); loginPage.passwordField.setValue(password); loginPage.confirmPasswordField.setValue(password); + loginPage.reasonField.waitForVisible(5000) loginPage.reasonField.setValue(reason); loginPage.submit(); From 244cb4cd73b34e4747bef4a8850014ee8aa800bf Mon Sep 17 00:00:00 2001 From: Martin Schoeler Date: Fri, 2 Jun 2017 11:38:24 -0300 Subject: [PATCH 52/54] fix error --- tests/end-to-end/ui/12-settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/end-to-end/ui/12-settings.js b/tests/end-to-end/ui/12-settings.js index 667b749718ec..8eba2c5da2a4 100644 --- a/tests/end-to-end/ui/12-settings.js +++ b/tests/end-to-end/ui/12-settings.js @@ -460,7 +460,7 @@ describe('[Api Settings Change]', () => { loginPage.emailField.setValue(`setting${ email }`); loginPage.passwordField.setValue(password); loginPage.confirmPasswordField.setValue(password); - loginPage.reasonField.waitForVisible(5000) + loginPage.reasonField.waitForVisible(5000); loginPage.reasonField.setValue(reason); loginPage.submit(); From a9b004c36710887b60b0da3e626a4b08703925dc Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Sat, 17 Feb 2018 15:23:56 -0200 Subject: [PATCH 53/54] Code improvements --- packages/rocketchat-i18n/i18n/en.i18n.json | 3 +- .../rocketchat-lib/server/models/Users.js | 2 +- .../client/tabs/userInfo.html | 7 ++- .../client/login/form.html | 51 ++++++++++--------- server/lib/accounts.js | 24 ++++----- server/methods/registerUser.js | 21 +++----- 6 files changed, 53 insertions(+), 55 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 21cfd39921e9..9ef9452a6163 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -52,7 +52,8 @@ "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
  • [name], [fname], [lname] for the user's full name, first name or last name, respectively.
  • [email] for the user's email.
  • [Site_Name] and [Site_URL] for the Application Name and URL respectively.
", "Accounts_Enrollment_Email_Subject_Default": "Welcome to [Site_Name]", - "Accounts_Admin_Email_Approval_Needed_Default": "

The user [name] ([email]) has been registered.

Reason: [reason]

Please check Administration -> Users to activate or delete it.

", + "Accounts_Admin_Email_Approval_Needed_Default": "

The user [name] ([email]) has been registered.

Please check \"Administration -> Users\" to activate or delete it.

", + "Accounts_Admin_Email_Approval_Needed_With_Reason_Default": "

The user [name] ([email]) has been registered.

Reason: [reason]

Please check \"Administration -> Users\" to activate or delete it.

", "Accounts_Admin_Email_Approval_Needed_Subject_Default": "A new user registered and needs approval", "Accounts_ForgetUserSessionOnWindowClose": "Forget User Session on Window Close", "Accounts_Iframe_api_method": "Api Method", diff --git a/packages/rocketchat-lib/server/models/Users.js b/packages/rocketchat-lib/server/models/Users.js index daada42180ec..e81af4599ff6 100644 --- a/packages/rocketchat-lib/server/models/Users.js +++ b/packages/rocketchat-lib/server/models/Users.js @@ -520,7 +520,7 @@ class ModelUsers extends RocketChat.models._Base { unsetReason(_id) { const update = { $unset: { - 'reason' : true + reason: true } }; diff --git a/packages/rocketchat-ui-flextab/client/tabs/userInfo.html b/packages/rocketchat-ui-flextab/client/tabs/userInfo.html index 8d9b56c04ea9..f7237d1d399e 100644 --- a/packages/rocketchat-ui-flextab/client/tabs/userInfo.html +++ b/packages/rocketchat-ui-flextab/client/tabs/userInfo.html @@ -75,6 +75,12 @@

{{{_ "Registration_Succeeded"}}}

autocapitalize="off" autocorrect="off" placeholder="{{emailOrUsernamePlaceholder}}" autofocus>
- - - {{#if hasOnePassword}} -
- {{/if}} + + + {{#if hasOnePassword}} +
+ {{/if}}
- +
+ + {{/if}} {{#if state 'register'}} @@ -58,10 +58,10 @@

{{{_ "Registration_Succeeded"}}}

+
+
+ {{#if requirePasswordConfirmation}}
@@ -86,18 +86,21 @@

{{{_ "Registration_Succeeded"}}}

-
-
- +
+ + {{/if}} {{#if manuallyApproveNewUsers}} -
- -
- -
-
+
+
{{/if}} {{/if}} diff --git a/server/lib/accounts.js b/server/lib/accounts.js index f1cde3133f63..0f2bfd761a55 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -69,15 +69,12 @@ Accounts.emailTemplates.notifyAdmin.subject = function() { }; Accounts.emailTemplates.notifyAdmin.html = function(options = {}) { - - let html; - - html = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Default'); - const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); - html = RocketChat.placeholders.replace(html, { + const email = options.reason ? 'Accounts_Admin_Email_Approval_Needed_With_Reason_Default' : 'Accounts_Admin_Email_Approval_Needed_Default'; + + const html = RocketChat.placeholders.replace(TAPi18n.__(email), { name: options.name, email: options.email, reason: options.reason @@ -123,24 +120,23 @@ Accounts.onCreateUser(function(options, user = {}) { if (!user.active) { const destinations = []; - let email = {}; - RocketChat.models.Roles.findUsersInRole('admin').forEach(function(adminUser) { - if (adminUser.emails && adminUser.emails[0] && adminUser.emails[0].address) { - destinations.push(`${ adminUser.name }<${ adminUser.emails[0].address }>`); + RocketChat.models.Roles.findUsersInRole('admin').forEach(adminUser => { + if (Array.isArray(adminUser.emails)) { + adminUser.emails.forEach(address => { + destinations.push(`${ adminUser.name }<${ address }>`); + }); } }); - email = { + const email = { to: destinations, from: RocketChat.settings.get('From_Email'), subject: Accounts.emailTemplates.notifyAdmin.subject(), html: Accounts.emailTemplates.notifyAdmin.html(options) }; - Meteor.defer(() => { - Email.send(email); - }); + Meteor.defer(() => Email.send(email)); } return user; diff --git a/server/methods/registerUser.js b/server/methods/registerUser.js index 28b189eabb70..392a2f794a5f 100644 --- a/server/methods/registerUser.js +++ b/server/methods/registerUser.js @@ -20,14 +20,9 @@ Meteor.methods({ email: String, pass: String, name: String, - secretURL: Match.Optional(String) + secretURL: Match.Optional(String), + reason: Match.Optional(String) })); - - if (manuallyApproveNewUsers) { - check(formData, Match.ObjectIncluding({ - reason: String - })); - } } if (RocketChat.settings.get('Accounts_RegistrationForm') === 'Disabled') { @@ -41,13 +36,10 @@ Meteor.methods({ const userData = { email: s.trim(formData.email.toLowerCase()), password: formData.pass, - name: formData.name + name: formData.name, + reason: formData.reason }; - if (manuallyApproveNewUsers) { - userData.reason = formData.reason; - } - // Check if user has already been imported and never logged in. If so, set password and let it through const importedUser = RocketChat.models.Users.findOneByEmailAddress(s.trim(formData.email.toLowerCase())); let userId; @@ -60,8 +52,9 @@ Meteor.methods({ RocketChat.models.Users.setName(userId, s.trim(formData.name)); - if (manuallyApproveNewUsers) { - RocketChat.models.Users.setReason(userId, s.trim(formData.reason)); + const reason = s.trim(formData.reason); + if (manuallyApproveNewUsers && reason) { + RocketChat.models.Users.setReason(userId, reason); } RocketChat.saveCustomFields(userId, formData); From b2d99d1ea7b7a4058f5d4ebb84095dc9b87d1b06 Mon Sep 17 00:00:00 2001 From: Rodrigo Nascimento Date: Sat, 17 Feb 2018 15:42:17 -0200 Subject: [PATCH 54/54] Alert by email when an account is approved/activated/deactivated --- packages/rocketchat-i18n/i18n/en.i18n.json | 6 ++ server/lib/accounts.js | 78 ++++++++++++++-------- server/methods/setUserActiveStatus.js | 13 ++++ 3 files changed, 70 insertions(+), 27 deletions(-) diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json index 9ef9452a6163..cefbcf224ac4 100644 --- a/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/packages/rocketchat-i18n/i18n/en.i18n.json @@ -48,6 +48,12 @@ "Accounts_denyUnverifiedEmail": "Deny unverified email", "Accounts_EmailVerification": "Email Verification", "Accounts_EmailVerification_Description": "Make sure you have correct SMTP settings to use this feature", + "Accounts_Email_Approved": "[name]

Your account was approved.

", + "Accounts_Email_Activated": "[name]

Your account was activated.

", + "Accounts_Email_Deactivated": "[name]

Your account was deactivated.

", + "Accounts_Email_Approved_Subject": "Account approved", + "Accounts_Email_Activated_Subject": "Account activated", + "Accounts_Email_Deactivated_Subject": "Account deactivated", "Accounts_Enrollment_Email": "Enrollment Email", "Accounts_Enrollment_Email_Default": "

Welcome to

[Site_Name]

Go to [Site_URL] and try the best open source chat solution available today!

", "Accounts_Enrollment_Email_Description": "You may use the following placeholders:
  • [name], [fname], [lname] for the user's full name, first name or last name, respectively.
  • [email] for the user's email.
  • [Site_Name] and [Site_URL] for the Application Name and URL respectively.
", diff --git a/server/lib/accounts.js b/server/lib/accounts.js index 0f2bfd761a55..946b0b0f67c1 100644 --- a/server/lib/accounts.js +++ b/server/lib/accounts.js @@ -12,7 +12,53 @@ Accounts.emailTemplates.siteName = RocketChat.settings.get('Site_Name'); Accounts.emailTemplates.from = `${ RocketChat.settings.get('Site_Name') } <${ RocketChat.settings.get('From_Email') }>`; -Accounts.emailTemplates.notifyAdmin = {}; +Accounts.emailTemplates.userToActivate = { + subject() { + const subject = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Subject_Default'); + const siteName = RocketChat.settings.get('Site_Name'); + + return `[${ siteName }] ${ subject }`; + }, + + html(options = {}) { + const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); + const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + + const email = options.reason ? 'Accounts_Admin_Email_Approval_Needed_With_Reason_Default' : 'Accounts_Admin_Email_Approval_Needed_Default'; + + const html = RocketChat.placeholders.replace(TAPi18n.__(email), { + name: options.name, + email: options.email, + reason: options.reason + }); + + return header + html + footer; + } +}; + +Accounts.emailTemplates.userActivated = { + subject({active, username}) { + const action = active ? (username ? 'Activated' : 'Approved') : 'Deactivated'; + const subject = `Accounts_Email_${ action }_Subject`; + const siteName = RocketChat.settings.get('Site_Name'); + + return `[${ siteName }] ${ TAPi18n.__(subject) }`; + }, + + html({active, name, username}) { + const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); + const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); + + const action = active ? (username ? 'Activated' : 'Approved') : 'Deactivated'; + + const html = RocketChat.placeholders.replace(TAPi18n.__(`Accounts_Email_${ action }`), { + name + }); + + return header + html + footer; + } +}; + const verifyEmailHtml = Accounts.emailTemplates.verifyEmail.text; @@ -61,28 +107,6 @@ Accounts.emailTemplates.enrollAccount.html = function(user = {}/*, url*/) { return header + html + footer; }; -Accounts.emailTemplates.notifyAdmin.subject = function() { - const subject = TAPi18n.__('Accounts_Admin_Email_Approval_Needed_Subject_Default'); - const siteName = RocketChat.settings.get('Site_Name'); - - return `[${ siteName }] ${ subject }`; -}; - -Accounts.emailTemplates.notifyAdmin.html = function(options = {}) { - const header = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Header') || ''); - const footer = RocketChat.placeholders.replace(RocketChat.settings.get('Email_Footer') || ''); - - const email = options.reason ? 'Accounts_Admin_Email_Approval_Needed_With_Reason_Default' : 'Accounts_Admin_Email_Approval_Needed_Default'; - - const html = RocketChat.placeholders.replace(TAPi18n.__(email), { - name: options.name, - email: options.email, - reason: options.reason - }); - - return header + html + footer; -}; - Accounts.onCreateUser(function(options, user = {}) { RocketChat.callbacks.run('beforeCreateUser', options, user); @@ -123,8 +147,8 @@ Accounts.onCreateUser(function(options, user = {}) { RocketChat.models.Roles.findUsersInRole('admin').forEach(adminUser => { if (Array.isArray(adminUser.emails)) { - adminUser.emails.forEach(address => { - destinations.push(`${ adminUser.name }<${ address }>`); + adminUser.emails.forEach(email => { + destinations.push(`${ adminUser.name }<${ email.address }>`); }); } }); @@ -132,8 +156,8 @@ Accounts.onCreateUser(function(options, user = {}) { const email = { to: destinations, from: RocketChat.settings.get('From_Email'), - subject: Accounts.emailTemplates.notifyAdmin.subject(), - html: Accounts.emailTemplates.notifyAdmin.html(options) + subject: Accounts.emailTemplates.userToActivate.subject(), + html: Accounts.emailTemplates.userToActivate.html(options) }; Meteor.defer(() => Email.send(email)); diff --git a/server/methods/setUserActiveStatus.js b/server/methods/setUserActiveStatus.js index 47ad26b2f68f..58607a653468 100644 --- a/server/methods/setUserActiveStatus.js +++ b/server/methods/setUserActiveStatus.js @@ -30,6 +30,19 @@ Meteor.methods({ RocketChat.models.Users.unsetReason(userId); } + const destinations = Array.isArray(user.emails) && user.emails.map(email => `${ user.name || user.username }<${ email.address }>`); + + if (destinations) { + const email = { + to: destinations, + from: RocketChat.settings.get('From_Email'), + subject: Accounts.emailTemplates.userActivated.subject({active}), + html: Accounts.emailTemplates.userActivated.html({active, name: user.name, username: user.username}) + }; + + Meteor.defer(() => Email.send(email)); + } + return true; }