diff --git a/app/lib/server/lib/PasswordPolicyClass.js b/app/lib/server/lib/PasswordPolicyClass.js
index adee50bf7d4ab..3aed85a656e39 100644
--- a/app/lib/server/lib/PasswordPolicyClass.js
+++ b/app/lib/server/lib/PasswordPolicyClass.js
@@ -88,6 +88,41 @@ class PasswordPolicy {
return true;
}
+
+ getPasswordPolicy() {
+ const data = {
+ enabled: false,
+ policy: [],
+ };
+ if (this.enabled) {
+ data.enabled = true;
+ if (this.minLength >= 1) {
+ data.policy.push('get-password-policy-minLength', { minLength: this.minLength });
+ }
+ if (this.maxLength >= 1) {
+ data.policy.push('get-password-policy-maxLength', { maxLength: this.maxLength });
+ }
+ if (this.forbidRepeatingCharacters) {
+ data.policy.push('get-password-policy-forbidRepeatingCharacters');
+ }
+ if (this.forbidRepeatingCharactersCount) {
+ data.policy.push('get-password-policy-forbidRepeatingCharactersCount', { forbidRepeatingCharactersCount: this.forbidRepeatingCharactersCount });
+ }
+ if (this.mustContainAtLeastOneLowercase) {
+ data.policy.push('get-password-policy-mustContainAtLeastOneLowercase');
+ }
+ if (this.mustContainAtLeastOneUppercase) {
+ data.policy.push('get-password-policy-mustContainAtLeastOneUppercase');
+ }
+ if (this.mustContainAtLeastOneNumber) {
+ data.policy.push('get-password-policy-mustContainAtLeastOneNumber');
+ }
+ if (this.mustContainAtLeastOneSpecialCharacter) {
+ data.policy.push('get-password-policy-mustContainAtLeastOneSpecialCharacter');
+ }
+ }
+ return data;
+ }
}
export default PasswordPolicy;
diff --git a/app/ui-login/client/reset-password/resetPassword.html b/app/ui-login/client/reset-password/resetPassword.html
index 549d1fafb753a..733b0c8088860 100644
--- a/app/ui-login/client/reset-password/resetPassword.html
+++ b/app/ui-login/client/reset-password/resetPassword.html
@@ -26,5 +26,12 @@
+ {{#if passwordPolicyEnabled}}
+
+ {{#each passwordPolicy}}
+
* {{_ this}}
+ {{/each}}
+
+ {{/if}}
diff --git a/app/ui-login/client/reset-password/resetPassword.js b/app/ui-login/client/reset-password/resetPassword.js
index e5eaff9559fa0..f0784e60bb964 100644
--- a/app/ui-login/client/reset-password/resetPassword.js
+++ b/app/ui-login/client/reset-password/resetPassword.js
@@ -4,6 +4,7 @@ import { FlowRouter } from 'meteor/kadira:flow-router';
import { Template } from 'meteor/templating';
import toastr from 'toastr';
import { ReactiveDict } from 'meteor/reactive-dict';
+import { ReactiveVar } from 'meteor/reactive-var';
import { modal, call } from '../../../ui-utils/client';
import { t } from '../../../utils';
@@ -25,6 +26,12 @@ Template.resetPassword.helpers({
return user.requirePasswordChangeReason;
}
},
+ passwordPolicyEnabled() {
+ return Template.instance().passwordPolicyEnabled.get();
+ },
+ passwordPolicy() {
+ return Template.instance().passwordPolicyRules.get();
+ },
});
const resetPassword = (token, password) => new Promise((resolve, reject) => {
@@ -105,4 +112,12 @@ Template.resetPassword.onRendered(function() {
Template.resetPassword.onCreated(function() {
this.state = new ReactiveDict({ password: '' });
+ this.passwordPolicyEnabled = new ReactiveVar(false);
+ this.passwordPolicyRules = new ReactiveVar();
+ Meteor.call('getPasswordPolicy', (error, result) => {
+ if (result.enabled) {
+ this.passwordPolicyEnabled.set(true);
+ this.passwordPolicyRules.set(result.policy);
+ }
+ });
});
diff --git a/packages/rocketchat-i18n/i18n/en.i18n.json b/packages/rocketchat-i18n/i18n/en.i18n.json
index fb3223682d644..fbbbaa5d3f987 100644
--- a/packages/rocketchat-i18n/i18n/en.i18n.json
+++ b/packages/rocketchat-i18n/i18n/en.i18n.json
@@ -1685,6 +1685,14 @@
"Generate_new_key": "Generate a new key",
"Generating_key": "Generating key",
"Get_link": "Get Link",
+ "get-password-policy-forbidRepeatingCharacters": "The password should not contain repeating characters",
+ "get-password-policy-forbidRepeatingCharactersCount": "The password should not contain more than __forbidRepeatingCharactersCount__ repeating characters",
+ "get-password-policy-maxLength": "The password should be maximum __maxLength__ characters long",
+ "get-password-policy-minLength": "The password should be minimum __minLength__ characters long",
+ "get-password-policy-mustContainAtLeastOneLowercase": "The password should contain atleast one lowercase letter",
+ "get-password-policy-mustContainAtLeastOneNumber": "The password should contain atleast one number",
+ "get-password-policy-mustContainAtLeastOneSpecialCharacter": "The password should contain atleast one special character",
+ "get-password-policy-mustContainAtLeastOneUppercase": "The password should contain atleast one uppercase letter",
"Generate_New_Link": "Generate New Link",
"github_no_public_email": "You don't have any email as public email in your GitHub account",
"Give_a_unique_name_for_the_custom_oauth": "Give a unique name for the custom oauth",
diff --git a/server/main.js b/server/main.js
index fd0439b8d8900..faaa47169fb55 100644
--- a/server/main.js
+++ b/server/main.js
@@ -28,6 +28,7 @@ import './methods/deleteFileMessage';
import './methods/deleteUser';
import './methods/eraseRoom';
import './methods/getAvatarSuggestion';
+import './methods/getPasswordPolicy';
import './methods/getRoomById';
import './methods/getRoomIdByNameOrId';
import './methods/getRoomNameById';
diff --git a/server/methods/getPasswordPolicy.js b/server/methods/getPasswordPolicy.js
new file mode 100644
index 0000000000000..b2e2a64a4f405
--- /dev/null
+++ b/server/methods/getPasswordPolicy.js
@@ -0,0 +1,14 @@
+import { Meteor } from 'meteor/meteor';
+
+import { passwordPolicy } from '../../app/lib';
+
+Meteor.methods({
+ getPasswordPolicy() {
+ if (!Meteor.userId()) {
+ throw new Meteor.Error('error-invalid-user', 'Invalid user', {
+ method: 'getPasswordPolicy',
+ });
+ }
+ return passwordPolicy.getPasswordPolicy();
+ },
+});