Added: Change Password extension use pass_min_length and pass_min_strength in JavaScript

This commit is contained in:
the-djmaze 2022-11-09 15:28:12 +01:00
parent fbabf0a283
commit eb34fd64d1
3 changed files with 22 additions and 10 deletions

View file

@ -6,8 +6,8 @@ class ChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
{ {
const const
NAME = 'Change Password', NAME = 'Change Password',
VERSION = '2.16.3', VERSION = '2.16.4',
RELEASE = '2022-10-14', RELEASE = '2022-11-09',
REQUIRED = '2.12.0', REQUIRED = '2.12.0',
CATEGORY = 'Security', CATEGORY = 'Security',
DESCRIPTION = 'Extension to allow users to change their passwords'; DESCRIPTION = 'Extension to allow users to change their passwords';
@ -106,12 +106,14 @@ class ChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
->SetLabel('Password minimum length') ->SetLabel('Password minimum length')
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT) ->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
->SetDescription('Minimum length of the password') ->SetDescription('Minimum length of the password')
->SetDefaultValue(10), ->SetDefaultValue(10)
->SetAllowedInJs(true),
\RainLoop\Plugins\Property::NewInstance("pass_min_strength") \RainLoop\Plugins\Property::NewInstance("pass_min_strength")
->SetLabel('Password minimum strength') ->SetLabel('Password minimum strength')
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT) ->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
->SetDescription('Minimum strength of the password in %') ->SetDescription('Minimum strength of the password in %')
->SetDefaultValue(70), ->SetDefaultValue(70)
->SetAllowedInJs(true),
]; ];
foreach ($this->getSupportedDrivers(true) as $name => $class) { foreach ($this->getSupportedDrivers(true) as $name => $class) {
$group = new \RainLoop\Plugins\PropertyCollection($name); $group = new \RainLoop\Plugins\PropertyCollection($name);

View file

@ -34,6 +34,9 @@
class ChangePasswordUserSettings class ChangePasswordUserSettings
{ {
constructor() { constructor() {
let minLength = rl.pluginSettingsGet('change-password', 'pass_min_length');
let minStrength = rl.pluginSettingsGet('change-password', 'pass_min_strength');
this.changeProcess = ko.observable(false); this.changeProcess = ko.observable(false);
this.errorDescription = ko.observable(''); this.errorDescription = ko.observable('');
this.passwordMismatch = ko.observable(false); this.passwordMismatch = ko.observable(false);
@ -43,6 +46,7 @@
this.currentPasswordError = ko.observable(false); this.currentPasswordError = ko.observable(false);
this.newPassword = ko.observable(''); this.newPassword = ko.observable('');
this.newPassword2 = ko.observable(''); this.newPassword2 = ko.observable('');
this.pass_min_length = minLength;
this.currentPassword.subscribe(() => this.resetUpdate(true)); this.currentPassword.subscribe(() => this.resetUpdate(true));
this.newPassword.subscribe(() => this.resetUpdate()); this.newPassword.subscribe(() => this.resetUpdate());
@ -51,11 +55,16 @@
ko.decorateCommands(this, { ko.decorateCommands(this, {
saveNewPasswordCommand: self => !self.changeProcess() saveNewPasswordCommand: self => !self.changeProcess()
&& '' !== self.currentPassword() && '' !== self.currentPassword()
&& '' !== self.newPassword() && self.newPassword().length >= minLength
&& '' !== self.newPassword2() && self.newPassword2() == self.newPassword()
&& (!this.meter || this.meter.value >= minStrength)
}); });
} }
submitForm(form) {
form.reportValidity() && this.saveNewPasswordCommand();
}
saveNewPasswordCommand() { saveNewPasswordCommand() {
if (this.newPassword() !== this.newPassword2()) { if (this.newPassword() !== this.newPassword2()) {
this.passwordMismatch(true); this.passwordMismatch(true);
@ -111,6 +120,7 @@
onBuild(dom) { onBuild(dom) {
let meter = dom.querySelector('.new-password-meter'); let meter = dom.querySelector('.new-password-meter');
meter && this.newPassword.subscribe(value => meter.value = getPassStrength(value)); meter && this.newPassword.subscribe(value => meter.value = getPassStrength(value));
this.meter = meter;
} }
onHide() { onHide() {

View file

@ -1,5 +1,5 @@
<div class="b-settings-general g-ui-user-select-none"> <div class="b-settings-general g-ui-user-select-none">
<form class="form-horizontal change-password" spellcheck="false"> <form action="" spellcheck="false" data-bind="submit: submitForm" class="form-horizontal change-password">
<div class="legend" data-i18n="SETTINGS_CHANGE_PASSWORD/LEGEND_CHANGE_PASSWORD"></div> <div class="legend" data-i18n="SETTINGS_CHANGE_PASSWORD/LEGEND_CHANGE_PASSWORD"></div>
<div class="row"> <div class="row">
<div class="span6"> <div class="span6">
@ -14,7 +14,7 @@
<label class="control-label" data-i18n="SETTINGS_CHANGE_PASSWORD/LABEL_NEW_PASSWORD"></label> <label class="control-label" data-i18n="SETTINGS_CHANGE_PASSWORD/LABEL_NEW_PASSWORD"></label>
<div class="controls"> <div class="controls">
<input style="margin:0" class="new-password" type="password" autocomplete="new-password" autocorrect="off" autocapitalize="off" <input style="margin:0" class="new-password" type="password" autocomplete="new-password" autocorrect="off" autocapitalize="off"
data-bind="textInput: newPassword" /> data-bind="textInput: newPassword, attr:{minlength:pass_min_length}" />
<br/> <br/>
<meter style="width:210px" class="new-password-meter" min="0" low="35" optimum="85" high="70" max="100" value="0"></meter> <meter style="width:210px" class="new-password-meter" min="0" low="35" optimum="85" high="70" max="100" value="0"></meter>
</div> </div>
@ -28,10 +28,10 @@
</div> </div>
<div class="control-group"> <div class="control-group">
<div class="controls"> <div class="controls">
<a class="btn" data-bind="command: saveNewPasswordCommand, css: { 'btn-success': passwordUpdateSuccess, 'btn-danger': passwordUpdateError }"> <button class="btn" data-bind="command: saveNewPasswordCommand, css: { 'btn-success': passwordUpdateSuccess, 'btn-danger': passwordUpdateError }">
<i class="fontastic" data-bind="css: {'icon-spinner': changeProcess()}">🔑</i> <i class="fontastic" data-bind="css: {'icon-spinner': changeProcess()}">🔑</i>
<span class="i18n" data-i18n="SETTINGS_CHANGE_PASSWORD/BUTTON_UPDATE_PASSWORD"></span> <span class="i18n" data-i18n="SETTINGS_CHANGE_PASSWORD/BUTTON_UPDATE_PASSWORD"></span>
</a> </button>
</div> </div>
</div> </div>
</div> </div>