mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Revamp Issue #51 to make the whole "change password" thing a plugin
This commit is contained in:
parent
3426921c9d
commit
fb03687528
17 changed files with 207 additions and 297 deletions
20
plugins/change-password/LICENSE
Normal file
20
plugins/change-password/LICENSE
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 RainLoop Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
76
plugins/change-password/index.php
Normal file
76
plugins/change-password/index.php
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
use \RainLoop\Exceptions\ClientException;
|
||||
|
||||
class ChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
const
|
||||
NAME = 'Change Password',
|
||||
CATEGORY = 'Security',
|
||||
DESCRIPTION = '';
|
||||
|
||||
// \RainLoop\Notifications\
|
||||
const CouldNotSaveNewPassword = 130;
|
||||
const CurrentPasswordIncorrect = 131;
|
||||
const NewPasswordShort = 132;
|
||||
const NewPasswordWeak = 133;
|
||||
|
||||
public function Init() : void
|
||||
{
|
||||
$this->UseLangs(true); // start use langs folder
|
||||
|
||||
$this->addJs('js/ChangePasswordUserSettings.js'); // add js file
|
||||
$this->addJsonHook('ChangePassword', 'ChangePassword');
|
||||
$this->addTemplate('templates/SettingsChangePassword.html');
|
||||
|
||||
/**
|
||||
* Admin
|
||||
*/
|
||||
/*
|
||||
$this->addJs('js/ChangePasswordAdminSettings.js', true); // add js file
|
||||
$this->addJsonHook('AdminChangePassword', 'AdminChangePassword');
|
||||
$this->addTemplate('templates/ChangePasswordAdminSettings.html', true);
|
||||
*/
|
||||
}
|
||||
|
||||
public function ChangePassword()
|
||||
{
|
||||
$sPrevPassword = $this->jsonParam('PrevPassword');
|
||||
$sNewPassword = $this->jsonParam('NewPassword');
|
||||
|
||||
$oActions = $this->Manager()->Actions();
|
||||
$oAccount = $oActions->GetAccount();
|
||||
/*
|
||||
if (!$this->isPossible($oAccount)) {
|
||||
throw new ClientException(static::CouldNotSaveNewPassword);
|
||||
}
|
||||
*/
|
||||
if ($sPrevPassword !== $oAccount->Password()) {
|
||||
throw new ClientException(static::CurrentPasswordIncorrect, null, $oActions->StaticI18N('NOTIFICATIONS/CURRENT_PASSWORD_INCORRECT'));
|
||||
}
|
||||
|
||||
$sPasswordForCheck = \trim($sNewPassword);
|
||||
if (10 > \strlen($sPasswordForCheck)) {
|
||||
throw new ClientException(static::NewPasswordShort, null, $oActions->StaticI18N('NOTIFICATIONS/NEW_PASSWORD_SHORT'));
|
||||
}
|
||||
|
||||
if (!\MailSo\Base\Utils::PasswordWeaknessCheck($sPasswordForCheck)) {
|
||||
throw new ClientException(static::NewPasswordWeak, null, $oActions->StaticI18N('NOTIFICATIONS/NEW_PASSWORD_WEAK'));
|
||||
}
|
||||
/*
|
||||
if (!$this->oDriver->ChangePassword($oAccount, $sPrevPassword, $sNewPassword)) {
|
||||
throw new ClientException(static::CouldNotSaveNewPassword);
|
||||
}
|
||||
|
||||
$oAccount->SetPassword($sNewPassword);
|
||||
$oActions->SetAuthToken($oAccount);
|
||||
*/
|
||||
return $oActions->GetSpecAuthToken();
|
||||
// return $this->jsonResponse(__FUNCTION__, $oActions->GetSpecAuthToken());
|
||||
}
|
||||
|
||||
public function AdminChangePassword()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
110
plugins/change-password/js/ChangePasswordUserSettings.js
Normal file
110
plugins/change-password/js/ChangePasswordUserSettings.js
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
|
||||
(rl => {
|
||||
|
||||
if (!rl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
class ChangePasswordUserSettings
|
||||
{
|
||||
constructor() {
|
||||
ko.addObservablesTo(this, {
|
||||
changeProcess: false,
|
||||
|
||||
errorDescription: '',
|
||||
passwordMismatch: false,
|
||||
passwordUpdateError: false,
|
||||
passwordUpdateSuccess: false,
|
||||
|
||||
currentPassword: '',
|
||||
currentPasswordError: false,
|
||||
newPassword: '',
|
||||
newPassword2: '',
|
||||
});
|
||||
|
||||
this.currentPassword.subscribe(() => this.resetUpdate(true));
|
||||
this.newPassword.subscribe(() => this.resetUpdate());
|
||||
this.newPassword2.subscribe(() => this.resetUpdate());
|
||||
|
||||
ko.decorateCommands(this, {
|
||||
saveNewPasswordCommand: self => !self.changeProcess()
|
||||
&& '' !== self.currentPassword()
|
||||
&& '' !== self.newPassword()
|
||||
&& '' !== self.newPassword2()
|
||||
});
|
||||
}
|
||||
|
||||
saveNewPasswordCommand() {
|
||||
if (this.newPassword() !== this.newPassword2()) {
|
||||
this.passwordMismatch(true);
|
||||
this.errorDescription(rl.i18n('SETTINGS_CHANGE_PASSWORD/ERROR_PASSWORD_MISMATCH'));
|
||||
} else {
|
||||
this.reset(true);
|
||||
rl.pluginRemoteRequest(
|
||||
(...args) => {
|
||||
console.dir(...args);
|
||||
this.onChangePasswordResponse(...args);
|
||||
},
|
||||
'ChangePassword',
|
||||
{
|
||||
'PrevPassword': this.currentPassword(),
|
||||
'NewPassword': this.newPassword()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
reset(change) {
|
||||
this.changeProcess(change);
|
||||
this.resetUpdate();
|
||||
this.currentPasswordError(false);
|
||||
this.errorDescription('');
|
||||
}
|
||||
|
||||
resetUpdate(current) {
|
||||
this.passwordUpdateError(false);
|
||||
this.passwordUpdateSuccess(false);
|
||||
current ? this.currentPasswordError(false) : this.passwordMismatch(false);
|
||||
}
|
||||
|
||||
onHide() {
|
||||
this.reset(false);
|
||||
this.currentPassword('');
|
||||
this.newPassword('');
|
||||
this.newPassword2('');
|
||||
}
|
||||
|
||||
onChangePasswordResponse(result, data) {
|
||||
this.reset(false);
|
||||
if (rl.Enums.StorageResultType.Success === result && data && data.Result) {
|
||||
this.currentPassword('');
|
||||
this.newPassword('');
|
||||
this.newPassword2('');
|
||||
this.passwordUpdateSuccess(true);
|
||||
rl.hash.set();
|
||||
rl.settings.set('AuthAccountHash', data.Result);
|
||||
} else {
|
||||
this.passwordUpdateError(true);
|
||||
this.errorDescription(rl.i18n('NOTIFICATIONS/COULD_NOT_SAVE_NEW_PASSWORD'));
|
||||
if (data) {
|
||||
if (131 === data.ErrorCode) {
|
||||
// Notification.CurrentPasswordIncorrect
|
||||
this.currentPasswordError(true);
|
||||
}
|
||||
if (data.ErrorMessageAdditional) {
|
||||
this.errorDescription(data.ErrorMessageAdditional);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rl.addSettingsViewModel(
|
||||
ChangePasswordUserSettings,
|
||||
'SettingsChangePassword',
|
||||
'GLOBAL/PASSWORD',
|
||||
'change-password'
|
||||
);
|
||||
|
||||
})(window.rl);
|
||||
12
plugins/change-password/langs/en.ini
Normal file
12
plugins/change-password/langs/en.ini
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[SETTINGS_CHANGE_PASSWORD]
|
||||
LEGEND_CHANGE_PASSWORD = "Change Password"
|
||||
LABEL_CURRENT_PASSWORD = "Current password"
|
||||
LABEL_NEW_PASSWORD = "New password"
|
||||
LABEL_REPEAT_PASSWORD = "Confirm New Password"
|
||||
BUTTON_UPDATE_PASSWORD = "Set New Password"
|
||||
ERROR_PASSWORD_MISMATCH = "Passwords do not match, please try again"
|
||||
[NOTIFICATIONS]
|
||||
COULD_NOT_SAVE_NEW_PASSWORD = "Could not save new password"
|
||||
CURRENT_PASSWORD_INCORRECT = "Current password incorrect"
|
||||
NEW_PASSWORD_SHORT = "Password is too short"
|
||||
NEW_PASSWORD_WEAK = "Password is too easy"
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<div class="b-settings-general g-ui-user-select-none">
|
||||
<div class="form-horizontal long-label">
|
||||
<div class="legend" data-i18n="SETTINGS_CHANGE_PASSWORD/LEGEND_CHANGE_PASSWORD"></div>
|
||||
<div class="row">
|
||||
<div class="span6">
|
||||
<div class="control-group" data-bind="css: {'error': currentPasswordError}">
|
||||
<label class="control-label" data-i18n="SETTINGS_CHANGE_PASSWORD/LABEL_CURRENT_PASSWORD"></label>
|
||||
<div class="controls">
|
||||
<input type="password" autocomplete="current-password" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: currentPassword" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" data-bind="css: {'error': passwordMismatch}">
|
||||
<label class="control-label" data-i18n="SETTINGS_CHANGE_PASSWORD/LABEL_NEW_PASSWORD"></label>
|
||||
<div class="controls">
|
||||
<input type="password" autocomplete="new-password" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
minlength="10"
|
||||
data-bind="textInput: newPassword" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group" data-bind="css: {'error': passwordMismatch}">
|
||||
<label class="control-label" data-i18n="SETTINGS_CHANGE_PASSWORD/LABEL_REPEAT_PASSWORD"></label>
|
||||
<div class="controls">
|
||||
<input type="password" autocomplete="new-password" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||
data-bind="textInput: newPassword2" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<a class="btn" data-bind="command: saveNewPasswordCommand, css: { 'btn-success': passwordUpdateSuccess, 'btn-danger': passwordUpdateError }">
|
||||
<i class="fontastic" data-bind="css: {'icon-spinner': changeProcess()}">🔑</i>
|
||||
<span class="i18n" data-i18n="SETTINGS_CHANGE_PASSWORD/BUTTON_UPDATE_PASSWORD"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span4 alert alert-error alert-null-left-margin" data-bind="visible: '' !== errorDescription(), text: errorDescription"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue