Password recovery fixes
gitea/hedera-web/pipeline/head This commit looks good
Details
gitea/hedera-web/pipeline/head This commit looks good
Details
This commit is contained in:
parent
66875ce193
commit
f9c8cd0e83
|
@ -1,4 +1,4 @@
|
||||||
hedera-web (1.407.40) stable; urgency=low
|
hedera-web (1.407.41) stable; urgency=low
|
||||||
|
|
||||||
* Initial Release.
|
* Initial Release.
|
||||||
|
|
||||||
|
|
|
@ -1,77 +1,81 @@
|
||||||
|
|
||||||
Hedera.Conf = new Class
|
Hedera.Conf = new Class({
|
||||||
({
|
|
||||||
Extends: Hedera.Form
|
Extends: Hedera.Form
|
||||||
|
|
||||||
,activate: function ()
|
,activate: function() {
|
||||||
{
|
this.$('user-model').setInfo('c', 'myClient', 'hedera');
|
||||||
this.$('user-model').setInfo ('c', 'myClient', 'hedera');
|
|
||||||
|
console.log(this.hash.get('verificationToken'));
|
||||||
|
|
||||||
|
if (this.hash.get('verificationToken'))
|
||||||
|
this.onPassChangeClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
,onPassChangeClick: function ()
|
,onPassChangeClick: function() {
|
||||||
{
|
|
||||||
this.$('old-password').value = '';
|
this.$('old-password').value = '';
|
||||||
this.$('new-password').value = '';
|
this.$('new-password').value = '';
|
||||||
this.$('repeat-password').value = '';
|
this.$('repeat-password').value = '';
|
||||||
|
|
||||||
var recoverPass = this.$('user-form').get ('recoverPass');
|
var verificationToken = this.hash.get('verificationToken');
|
||||||
this.$('old-password').style.display = recoverPass ? 'none' : 'block';
|
this.$('old-password').style.display = verificationToken ? 'none' : 'block';
|
||||||
this.$('change-password').show ();
|
this.$('change-password').show();
|
||||||
|
|
||||||
if (recoverPass)
|
if (verificationToken)
|
||||||
this.$('new-password').focus ();
|
this.$('new-password').focus();
|
||||||
else
|
else
|
||||||
this.$('old-password').focus ();
|
this.$('old-password').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
,onPassModifyClick: function ()
|
,onPassModifyClick: function() {
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
var oldPassword = this.$('old-password').value;
|
var oldPassword = this.$('old-password').value;
|
||||||
var newPassword = this.$('new-password').value;
|
var newPassword = this.$('new-password').value;
|
||||||
var repeatedPassword = this.$('repeat-password').value;
|
var repeatedPassword = this.$('repeat-password').value;
|
||||||
|
|
||||||
if (newPassword == '' && repeatedPassword == '')
|
if (newPassword == '' && repeatedPassword == '')
|
||||||
throw new Error (_('Passwords empty'));
|
throw new Error(_('Passwords empty'));
|
||||||
if (newPassword !== repeatedPassword)
|
if (newPassword !== repeatedPassword)
|
||||||
throw new Error (_('Passwords doesn\'t match'));
|
throw new Error(_('Passwords doesn\'t match'));
|
||||||
|
|
||||||
var params = {
|
var verificationToken = this.hash.get('verificationToken');
|
||||||
oldPassword: oldPassword,
|
var params = {newPassword: newPassword};
|
||||||
newPassword: newPassword
|
|
||||||
};
|
if (verificationToken) {
|
||||||
this.conn.send ('core/change-password', params,
|
params.verificationToken = verificationToken;
|
||||||
this._onPassChange.bind (this));
|
this.conn.send('core/restore-password', params,
|
||||||
}
|
this._onPassChange.bind(this));
|
||||||
catch (e)
|
} else {
|
||||||
{
|
params.oldPassword = oldPassword;
|
||||||
Htk.Toast.showError (e.message);
|
this.conn.send('core/change-password', params,
|
||||||
|
this._onPassChange.bind(this));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Htk.Toast.showError(e.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
,_onPassChange: function (json, error)
|
,_onPassChange: function(json, error) {
|
||||||
{
|
if (json) {
|
||||||
if (json)
|
this.$('change-password').hide();
|
||||||
{
|
this.hash.unset('verificationToken');
|
||||||
this.$('change-password').hide ();
|
Htk.Toast.showMessage(_('Password changed!'));
|
||||||
Htk.Toast.showMessage (_('Password changed!'));
|
this.$('user-form').refresh();
|
||||||
this.$('user-form').refresh ();
|
} else {
|
||||||
}
|
Htk.Toast.showError(error.message);
|
||||||
else
|
|
||||||
{
|
if (this.hash.get('verificationToken'))
|
||||||
Htk.Toast.showError (error.message);
|
this.$('new-password').select();
|
||||||
this.$('old-password').select ();
|
else
|
||||||
|
this.$('old-password').select();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
,onPassInfoClick: function ()
|
,onPassInfoClick: function() {
|
||||||
{
|
this.$('password-info').show();
|
||||||
this.$('password-info').show ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
,onAddressesClick: function ()
|
,onAddressesClick: function() {
|
||||||
{
|
this.hash.set({form: 'account/address-list'});
|
||||||
this.hash.set ({form: 'account/address-list'});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@
|
||||||
<db-form id="user-form">
|
<db-form id="user-form">
|
||||||
<db-model property="model" id="user-model" updatable="true">
|
<db-model property="model" id="user-model" updatable="true">
|
||||||
<custom>
|
<custom>
|
||||||
SELECT u.id, u.name, u.email, u.recoverPass,
|
SELECT u.id, u.name, u.email, u.nickname,
|
||||||
u.nickname, u.lang, c.isToBeMailed, c.id clientFk
|
u.lang, c.isToBeMailed, c.id clientFk
|
||||||
FROM account.myUser u
|
FROM account.myUser u
|
||||||
LEFT JOIN myClient c
|
LEFT JOIN myClient c
|
||||||
ON u.id = c.id
|
ON u.id = c.id
|
||||||
|
|
|
@ -35,6 +35,15 @@ module.exports =
|
||||||
return this._hashMap[key];
|
return this._hashMap[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsets a hash key.
|
||||||
|
*
|
||||||
|
* @param {string} key The variable name
|
||||||
|
**/
|
||||||
|
,unset: function(key) {
|
||||||
|
this.add({[key]: undefined});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the hash part of the URL, respecting the current hash variables.
|
* Sets the hash part of the URL, respecting the current hash variables.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "hedera-web",
|
"name": "hedera-web",
|
||||||
"version": "1.407.40",
|
"version": "1.407.41",
|
||||||
"description": "Verdnatura web page",
|
"description": "Verdnatura web page",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -6,11 +6,11 @@ include __DIR__.'/account.php';
|
||||||
* Updates the user password.
|
* Updates the user password.
|
||||||
**/
|
**/
|
||||||
class ChangePassword extends Vn\Web\JsonRequest {
|
class ChangePassword extends Vn\Web\JsonRequest {
|
||||||
const PARAMS = ['newPassword'];
|
const PARAMS = ['oldPassword', 'newPassword'];
|
||||||
|
|
||||||
function run($db) {
|
function run($db) {
|
||||||
$newPassword = $_REQUEST['newPassword'];
|
|
||||||
$oldPassword = $_REQUEST['oldPassword'];
|
$oldPassword = $_REQUEST['oldPassword'];
|
||||||
|
$newPassword = $_REQUEST['newPassword'];
|
||||||
|
|
||||||
$db->query('CALL account.myUser_changePassword(#, #)',
|
$db->query('CALL account.myUser_changePassword(#, #)',
|
||||||
[$oldPassword, $newPassword]);
|
[$oldPassword, $newPassword]);
|
||||||
|
|
|
@ -6,61 +6,31 @@ class RecoverPassword extends Vn\Web\JsonRequest {
|
||||||
const PARAMS = ['recoverUser'];
|
const PARAMS = ['recoverUser'];
|
||||||
|
|
||||||
function run($db) {
|
function run($db) {
|
||||||
|
$recoverUser = $_REQUEST['recoverUser'];
|
||||||
|
|
||||||
$user = $db->getRow(
|
$user = $db->getRow(
|
||||||
'SELECT email, active FROM account.user WHERE name = #',
|
'SELECT email, active FROM account.user WHERE name = #',
|
||||||
[$_REQUEST['recoverUser']]
|
[$recoverUser]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!($user['active'] && $user['email']))
|
if (!($user['active'] && $user['email']))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
$verificationToken = bin2hex(random_bytes(16));
|
||||||
|
$db->query(
|
||||||
|
'UPDATE account.user SET verificationToken = #
|
||||||
|
WHERE name = #',
|
||||||
|
[$verificationToken, $recoverUser]
|
||||||
|
);
|
||||||
|
|
||||||
$service = $this->service;
|
$service = $this->service;
|
||||||
$token = $service->createToken($_REQUEST['recoverUser'], FALSE, TRUE);
|
$token = $service->createToken($recoverUser);
|
||||||
$url = $service->getUrl() ."#!form=account/conf&token=$token";
|
$url = $service->getUrl() ."#!form=account/conf&verificationToken=$verificationToken&token=$token";
|
||||||
|
|
||||||
$report = new Vn\Web\Report($db, 'recover-password', ['url' => $url]);
|
$report = new Vn\Web\Report($db, 'recover-password', ['url' => $url]);
|
||||||
$report->sendMail($user['email']);
|
$report->sendMail($user['email']);
|
||||||
|
|
||||||
return \Vn\Lib\Locale::get();
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LOWERS = 'abcdefghijklmnopqrstuvwxyz';
|
|
||||||
const UPPERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
||||||
const DIGITS = '1234567890';
|
|
||||||
const SYMBOLS = '!$%&()=.';
|
|
||||||
|
|
||||||
function genPassword($db) {
|
|
||||||
$restrictions = $db->getRow(
|
|
||||||
'SELECT length, nUpper, nDigits, nPunct FROM account.userPassword');
|
|
||||||
|
|
||||||
$pass = [];
|
|
||||||
$newPass = '';
|
|
||||||
|
|
||||||
$nAlpha = $restrictions['length'] -(
|
|
||||||
$restrictions['nUpper'] +
|
|
||||||
$restrictions['nDigits'] +
|
|
||||||
$restrictions['nPunct']);
|
|
||||||
|
|
||||||
$this->genRands($pass, self::LOWERS, $nAlpha);
|
|
||||||
$this->genRands($pass, self::UPPERS, $restrictions['nUpper']);
|
|
||||||
$this->genRands($pass, self::DIGITS, $restrictions['nDigits']);
|
|
||||||
$this->genRands($pass, self::SYMBOLS, $restrictions['nPunct']);
|
|
||||||
|
|
||||||
for ($i = count($pass) - 1; $i >= 0; $i--) {
|
|
||||||
$rand = rand(0, $i);
|
|
||||||
$newPass .= $pass[$rand];
|
|
||||||
array_splice($pass, $rand, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $newPass;
|
|
||||||
}
|
|
||||||
|
|
||||||
function genRands(&$pass, $chars, $max) {
|
|
||||||
$len = strlen($chars) - 1;
|
|
||||||
|
|
||||||
for ($i = 0; $i < $max; $i++)
|
|
||||||
$pass[] = $chars[rand(0, $len)];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Vn\Web;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the user password.
|
||||||
|
**/
|
||||||
|
class RestorePassword extends Vn\Web\JsonRequest {
|
||||||
|
const PARAMS = ['verificationToken', 'newPassword'];
|
||||||
|
|
||||||
|
function run($db) {
|
||||||
|
$verificationToken = $_REQUEST['verificationToken'];
|
||||||
|
$newPassword = $_REQUEST['newPassword'];
|
||||||
|
|
||||||
|
$db->query('CALL account.myUser_restorePassword(#, #)',
|
||||||
|
[$verificationToken, $newPassword]);
|
||||||
|
Account::sync($db, $_SESSION['user'], $newPassword);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -180,13 +180,6 @@ abstract class Service {
|
||||||
throw new SessionExpiredException();
|
throw new SessionExpiredException();
|
||||||
|
|
||||||
$user = $jwtPayload['sub'];
|
$user = $jwtPayload['sub'];
|
||||||
|
|
||||||
if (!empty($jwtPayload['recover']))
|
|
||||||
$db->query(
|
|
||||||
'UPDATE account.user SET recoverPass = TRUE
|
|
||||||
WHERE name = #',
|
|
||||||
[$user]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$user = $db->getValue('SELECT guestUser FROM config');
|
$user = $db->getValue('SELECT guestUser FROM config');
|
||||||
|
@ -263,7 +256,7 @@ abstract class Service {
|
||||||
* @param {boolean} $recover Wether to enable recovery mode on login
|
* @param {boolean} $recover Wether to enable recovery mode on login
|
||||||
* @return {string} The JWT generated token
|
* @return {string} The JWT generated token
|
||||||
*/
|
*/
|
||||||
function createToken($user, $remember = FALSE, $recover = FALSE) {
|
function createToken($user, $remember = FALSE) {
|
||||||
if ($remember)
|
if ($remember)
|
||||||
$tokenLife = WEEK;
|
$tokenLife = WEEK;
|
||||||
else
|
else
|
||||||
|
@ -274,9 +267,6 @@ abstract class Service {
|
||||||
'exp' => time() + $tokenLife
|
'exp' => time() + $tokenLife
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($recover)
|
|
||||||
$payload['recover'] = 'TRUE';
|
|
||||||
|
|
||||||
$key = $this->db->getValue('SELECT jwtKey FROM config');
|
$key = $this->db->getValue('SELECT jwtKey FROM config');
|
||||||
return Jwt::encode($payload, $key);
|
return Jwt::encode($payload, $key);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue