mirror of
https://github.com/getnamingo/registry.git
synced 2025-05-13 16:16:59 +02:00
Added ability to have password policy and password expiration
This commit is contained in:
parent
e0eeaed83c
commit
2620dfd7f3
5 changed files with 51 additions and 3 deletions
|
@ -93,6 +93,13 @@ class AuthController extends Controller
|
|||
unset($_SESSION['2fa_email'], $_SESSION['2fa_password'], $_SESSION['is2FAEnabled']);
|
||||
|
||||
if ($login===true) {
|
||||
// Check if password renewal is needed
|
||||
$passwordLastChanged = $_SESSION['password_last_changed'][$_SESSION['auth_user_id']] ?? 0;
|
||||
if (checkPasswordRenewal($passwordLastChanged)) {
|
||||
Auth::logout();
|
||||
redirect()->route('forgot.password')->with('error','Your password is expired. Please change it');
|
||||
}
|
||||
|
||||
$db = $container->get('db');
|
||||
$currentDateTime = new \DateTime();
|
||||
$currentDate = $currentDateTime->format('Y-m-d H:i:s.v'); // Current timestamp
|
||||
|
|
|
@ -69,7 +69,13 @@ class PasswordController extends Controller
|
|||
* @throws \Pinga\Auth\AuthError
|
||||
*/
|
||||
public function updatePassword(Request $request, Response $response){
|
||||
global $container;
|
||||
$data = $request->getParsedBody();
|
||||
$db = $container->get('db');
|
||||
$userId = $db->selectValue(
|
||||
'SELECT user_id FROM users_resets WHERE selector = ? AND expires > ? ORDER BY expires DESC LIMIT 1',
|
||||
[ $data['selector'], time() ]
|
||||
);
|
||||
$validation = $this->validator->validate($request, [
|
||||
'password' => v::notEmpty()->stringType()->length(8),
|
||||
'password2' => v::notEmpty(),
|
||||
|
@ -78,10 +84,13 @@ class PasswordController extends Controller
|
|||
if ($validation->failed()) {
|
||||
redirect()->route('update.password',[],['selector'=>urlencode($data['selector']),'token'=>urlencode($data['token'])]);
|
||||
}
|
||||
|
||||
elseif (!v::equals($data['password'])->validate($data['password2'])) {
|
||||
redirect()->route('update.password',[],['selector'=>urlencode($data['selector']),'token'=>urlencode($data['token'])])->with('error','The password do not match.');
|
||||
}
|
||||
if (!checkPasswordComplexity($data['password2'])) {
|
||||
redirect()->route('update.password',[],['selector'=>urlencode($data['selector']),'token'=>urlencode($data['token'])])->with('error','Password too weak. Use a stronger password.');
|
||||
}
|
||||
$_SESSION['password_last_changed'][$userId] = time();
|
||||
Auth::resetPasswordUpdate($data['selector'], $data['token'], $data['password']);
|
||||
}
|
||||
|
||||
|
@ -91,6 +100,7 @@ class PasswordController extends Controller
|
|||
* @throws \Pinga\Auth\AuthError
|
||||
*/
|
||||
public function changePassword(Request $request, Response $response){
|
||||
global $container;
|
||||
$data = $request->getParsedBody();
|
||||
$validation = $this->validator->validate($request, [
|
||||
'old_password' => v::notEmpty(),
|
||||
|
@ -99,6 +109,11 @@ class PasswordController extends Controller
|
|||
if ($validation->failed()) {
|
||||
redirect()->route('profile');
|
||||
}
|
||||
if (!checkPasswordComplexity($data['new_password'])) {
|
||||
redirect()->route('profile')->with('error','Password too weak. Use a stronger password.');
|
||||
}
|
||||
$userId = $container->get('auth')->user()['id'];
|
||||
$_SESSION['password_last_changed'][$userId] = time();
|
||||
Auth::changeCurrentPassword($data['old_password'], $data['new_password']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,11 @@ class RegistrarsController extends Controller
|
|||
return $response->withHeader('Location', '/registrar/create')->withStatus(302);
|
||||
}
|
||||
|
||||
if (!checkPasswordComplexity($data['panelPassword'])) {
|
||||
$this->container->get('flash')->addMessage('error', 'Password too weak. Use a stronger password');
|
||||
return $response->withHeader('Location', '/registrar/create')->withStatus(302);
|
||||
}
|
||||
|
||||
$db->beginTransaction();
|
||||
|
||||
try {
|
||||
|
@ -651,6 +656,11 @@ class RegistrarsController extends Controller
|
|||
return $response->withHeader('Location', '/registrar/update/'.$registrar)->withStatus(302);
|
||||
}
|
||||
|
||||
if (!checkPasswordComplexity($data['panelPassword'])) {
|
||||
$this->container->get('flash')->addMessage('error', 'Password too weak. Use a stronger password');
|
||||
return $response->withHeader('Location', '/registrar/update/'.$registrar)->withStatus(302);
|
||||
}
|
||||
|
||||
if (!empty($_SESSION['registrars_user_email'])) {
|
||||
$regEmail = $_SESSION['registrars_user_email'][0];
|
||||
} else {
|
||||
|
|
|
@ -83,6 +83,11 @@ class UsersController extends Controller
|
|||
return $response->withHeader('Location', '/user/create')->withStatus(302);
|
||||
}
|
||||
|
||||
if (!checkPasswordComplexity($password)) {
|
||||
$this->container->get('flash')->addMessage('error', 'Password too weak. Use a stronger password');
|
||||
return $response->withHeader('Location', '/user/create')->withStatus(302);
|
||||
}
|
||||
|
||||
$registrars = $db->select("SELECT id, clid, name FROM registrar");
|
||||
if ($_SESSION["auth_roles"] != 0) {
|
||||
$registrar = true;
|
||||
|
@ -146,6 +151,7 @@ class UsersController extends Controller
|
|||
'registered' => \time()
|
||||
]
|
||||
);
|
||||
$userId = $db->getlastInsertId();
|
||||
|
||||
$db->commit();
|
||||
} catch (Exception $e) {
|
||||
|
@ -154,6 +160,7 @@ class UsersController extends Controller
|
|||
return $response->withHeader('Location', '/user/create')->withStatus(302);
|
||||
}
|
||||
|
||||
$_SESSION['password_last_changed'][$userId] = time();
|
||||
$this->container->get('flash')->addMessage('success', 'User ' . $email . ' has been created successfully');
|
||||
return $response->withHeader('Location', '/users')->withStatus(302);
|
||||
}
|
||||
|
@ -305,6 +312,11 @@ class UsersController extends Controller
|
|||
return $response->withHeader('Location', '/user/update/'.$old_username)->withStatus(302);
|
||||
}
|
||||
|
||||
if (!checkPasswordComplexity($password)) {
|
||||
$this->container->get('flash')->addMessage('error', 'Password too weak. Use a stronger password');
|
||||
return $response->withHeader('Location', '/user/update/'.$old_username)->withStatus(302);
|
||||
}
|
||||
|
||||
// Check if username already exists (excluding the current user)
|
||||
if ($username && $username !== $old_username) {
|
||||
$existingUsername = $db->selectValue('SELECT COUNT(*) FROM users WHERE username = ? AND username != ?', [$username, $old_username]);
|
||||
|
@ -395,7 +407,9 @@ class UsersController extends Controller
|
|||
return $response->withHeader('Location', '/user/update/'.$old_username)->withStatus(302);
|
||||
}
|
||||
|
||||
$userId = $db->selectValue('SELECT id from users WHERE username = ?', [ $username ]);
|
||||
unset($_SESSION['user_to_update']);
|
||||
$_SESSION['password_last_changed'][$userId] = time();
|
||||
$this->container->get('flash')->addMessage('success', 'User ' . $username . ' has been updated successfully on ' . $update);
|
||||
return $response->withHeader('Location', '/user/update/'.$username)->withStatus(302);
|
||||
}
|
||||
|
|
|
@ -693,8 +693,10 @@ function checkPasswordComplexity($password) {
|
|||
$score = $zxcvbn->passwordStrength($password)['score'];
|
||||
|
||||
if ($score < $requiredScore) { // Score ranges from 0 (weak) to 4 (strong)
|
||||
throw new Exception('Password too weak. Use a stronger password.');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkPasswordRenewal($lastPasswordUpdateTimestamp) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue