Invalidate cached auth sessions for every active customer token and return the persisted canonical login email.
173 lines
8.3 KiB
PHP
173 lines
8.3 KiB
PHP
<?php
|
|
|
|
namespace routes;
|
|
|
|
use classes\authentication;
|
|
use objects\logs_o;
|
|
use objects\tokens_o;
|
|
use traits\route_t;
|
|
|
|
class userSecurityRoute
|
|
{
|
|
use route_t;
|
|
|
|
public function run(): void
|
|
{
|
|
$this->post('/account/security/change-email', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('user_security_change_email');
|
|
$user = (new authentication())->get_user();
|
|
if (!$user) {
|
|
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_EMAIL', 'User not logged in');
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
// Require the email, and password parameters
|
|
self::requireParameters(['email', 'password']);
|
|
// Check if the email is valid
|
|
$email = (string)self::getParameter('email');
|
|
self::requireMinLength('email', 5);
|
|
self::requireMaxLength('email', 255);
|
|
self::requireType($email, self::type_string());
|
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_CHANGE_EMAIL', 'Invalid email');
|
|
$response->error('Invalid email', 400);
|
|
}
|
|
// Validate the password
|
|
$password = (string)self::getParameter('password');
|
|
self::requireMinLength('password', 4);
|
|
self::requireMaxLength('password', 255);
|
|
self::requireType($password, self::type_string());
|
|
if (!$user->passwordMatches($password)) {
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_CHANGE_EMAIL', 'Invalid password');
|
|
$response->error('Invalid password', 400);
|
|
} else {
|
|
// Change the email
|
|
$user->setEmail($email);
|
|
$canonical_email = (string)$user->email->value();
|
|
try {
|
|
$tokenRows = (new tokens_o())->getFieldsWhere([
|
|
'user_id' => [(int)$user->id],
|
|
], ['token']);
|
|
foreach ($tokenRows as $tokenRow) {
|
|
$token = (string)($tokenRow['token'] ?? '');
|
|
if ($token !== '') {
|
|
redis->clear_auth_session($token);
|
|
}
|
|
}
|
|
} catch (\Throwable) {
|
|
// Session cache invalidation is best-effort; the persistent update above is authoritative.
|
|
}
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_CHANGE_EMAIL', 'Email changed');
|
|
$response->success([
|
|
'message' => 'Email changed',
|
|
'email' => $canonical_email,
|
|
]);
|
|
}
|
|
},
|
|
[
|
|
'user_security_change_email' => 'Change the email address of the user',
|
|
]
|
|
);
|
|
|
|
$this->post('/account/security/validate-password', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('user_security_validate_password');
|
|
$user = (new authentication())->get_user();
|
|
if (!$user) {
|
|
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_VALIDATE_PASSWORD', 'User not logged in');
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
// Require the password parameter
|
|
self::requireParameters(['password']);
|
|
// Validate the password
|
|
$password = (string)self::getParameter('password');
|
|
self::requireMinLength('password', 4);
|
|
self::requireMaxLength('password', 255);
|
|
self::requireType($password, self::type_string());
|
|
if (!$user->passwordMatches($password)) {
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_VALIDATE_PASSWORD', 'Invalid password');
|
|
$response->error('Invalid password', 400);
|
|
} else {
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_VALIDATE_PASSWORD', 'Password validated');
|
|
$response->success(['message' => 'Password validated']);
|
|
}
|
|
},
|
|
[
|
|
'user_security_validate_password' => 'Validate the password of the user',
|
|
]
|
|
);
|
|
|
|
$this->post('/account/security/change-password', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('user_security_change_password');
|
|
$user = (new authentication())->get_user();
|
|
if (!$user) {
|
|
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_PASSWORD', 'User not logged in');
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
// Require the current_password and new_password parameters
|
|
self::requireParameters(['current_password', 'new_password']);
|
|
// Validate the old password
|
|
$current_password = (string)self::getParameter('current_password');
|
|
self::requireMinLength('current_password', 4);
|
|
self::requireMaxLength('current_password', 255);
|
|
self::requireType($current_password, self::type_string());
|
|
if (!$user->passwordMatches($current_password)) {
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_CHANGE_PASSWORD', 'Invalid old password');
|
|
$response->error('Invalid old password', 400);
|
|
}
|
|
// Validate the new password
|
|
$new_password = (string)self::getParameter('new_password');
|
|
self::requireMinLength('new_password', 4);
|
|
self::requireMaxLength('new_password', 255);
|
|
self::requireType($new_password, self::type_string());
|
|
if ($current_password === $new_password) {
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_CHANGE_PASSWORD', 'New password cannot be the same as the old password');
|
|
$response->error('New password cannot be the same as the old password', 400);
|
|
} else {
|
|
// Change the password
|
|
$user->setPassword($new_password);
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_CHANGE_PASSWORD', 'Password changed');
|
|
$response->success(['message' => 'Password changed']);
|
|
}
|
|
},
|
|
[
|
|
'user_security_change_password' => 'Change the password of the user',
|
|
]
|
|
);
|
|
|
|
$this->post('/account/security/change-phone-number', function () {
|
|
// Require the user to be logged in
|
|
global $response;
|
|
self::requirePermission('user_security_change_phone_number');
|
|
$user = (new authentication())->get_user();
|
|
if (!$user) {
|
|
(new logs_o())->add('user_security', 'global', 0, 0, 'USER_SECURITY_CHANGE_PHONE_NUMBER', 'User not logged in');
|
|
$response->error('Invalid session', 400);
|
|
}
|
|
// Require the phone_number parameter
|
|
self::requireParameters(['phone_number', 'country_code']);
|
|
// Validate the phone number
|
|
$phone_number = (int)self::getParameter('phone_number');
|
|
self::requireMinLength('phone_number', 4);
|
|
self::requireMaxLength('phone_number', 20);
|
|
self::requireType($phone_number, self::type_int());
|
|
$country_code = (int)self::getParameter('country_code');
|
|
self::requireMinLength('country_code', 1);
|
|
self::requireMaxLength('country_code', 5);
|
|
self::requireType($country_code, self::type_int());
|
|
// Change the phone number
|
|
$user->setPhoneNumber($phone_number, $country_code);
|
|
(new logs_o())->add('user_security', 'global', 0, $user->id, 'USER_SECURITY_CHANGE_PHONE_NUMBER', 'Phone number changed');
|
|
$response->success(['message' => 'Phone number changed']);
|
|
},
|
|
[
|
|
'user_security_change_phone_number' => 'Change the phone number of the user',
|
|
]
|
|
);
|
|
}
|
|
}
|