Moved passwords out of the users table.

This commit is contained in:
flash 2025-02-09 00:26:12 +00:00
parent 7f85abba6e
commit f39e1230c5
13 changed files with 202 additions and 97 deletions

View file

@ -98,19 +98,26 @@ while(!empty($_POST['login']) && is_array($_POST['login'])) {
break;
}
if(!$userInfo->hasPasswordHash) {
$notices[] = 'Your password has been invalidated, please reset it.';
break;
}
if($userInfo->deleted || !$userInfo->verifyPassword($_POST['login']['password'])) {
if($userInfo->deleted) {
$msz->authCtx->loginAttempts->recordAttempt(false, $ipAddress, $countryCode, $userAgent, $clientInfo, $userInfo);
$notices[] = $loginFailedError;
break;
}
if($userInfo->passwordNeedsRehash)
$msz->usersCtx->users->updateUser($userInfo, password: $_POST['login']['password']);
$pwInfo = $msz->usersCtx->passwords->getUserPassword($userInfo);
if($pwInfo === null) {
$notices[] = 'Your password has been invalidated, please reset it.';
break;
}
if(!$pwInfo->verifyPassword($_POST['login']['password'])) {
$msz->authCtx->loginAttempts->recordAttempt(false, $ipAddress, $countryCode, $userAgent, $clientInfo, $userInfo);
$notices[] = $loginFailedError;
break;
}
if($pwInfo->needsRehash)
$msz->usersCtx->passwords->updateUserPassword($userInfo, $_POST['login']['password']);
if(!empty($loginPermCat) && $loginPermVal > 0 && !$msz->perms->checkPermissions($loginPermCat, $loginPermVal, $userInfo)) {
$notices[] = "Login succeeded, but you're not allowed to browse the site right now.";

View file

@ -2,7 +2,7 @@
namespace Misuzu;
use RuntimeException;
use Misuzu\Users\User;
use Misuzu\Users\{User,UserPasswordsData};
if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
die('Script must be called through the Misuzu route dispatcher.');
@ -63,15 +63,15 @@ while($canResetPassword) {
break;
}
$passwordValidation = $msz->usersCtx->users->validatePassword($passwordNew);
$passwordValidation = UserPasswordsData::validateUserPassword($passwordNew);
if($passwordValidation !== '') {
$notices[] = $msz->usersCtx->users->validatePasswordText($passwordValidation);
$notices[] = UserPasswordsData::validateUserPasswordText($passwordValidation);
break;
}
// also disables two factor auth to prevent getting locked out of account entirely
// this behaviour should really be replaced with recovery keys...
$msz->usersCtx->users->updateUser($userInfo, password: $passwordNew);
$msz->usersCtx->passwords->updateUserPassword($userInfo, $passwordNew);
$msz->usersCtx->totps->deleteUserTotp($userInfo);
$msz->createAuditLog('PASSWORD_RESET', [], $userInfo);

View file

@ -2,7 +2,7 @@
namespace Misuzu;
use RuntimeException;
use Misuzu\Users\User;
use Misuzu\Users\{User,UserPasswordsData};
if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
die('Script must be called through the Misuzu route dispatcher.');
@ -61,11 +61,11 @@ while(!empty($register)) {
$notices[] = $msz->usersCtx->users->validateEMailAddressText($emailValidation);
if($register['password_confirm'] !== $register['password'])
$notices[] = 'The given passwords don\'t match.';
$notices[] = "The given passwords don't match.";
$passwordValidation = $msz->usersCtx->users->validatePassword($register['password']);
$passwordValidation = UserPasswordsData::validateUserPassword($register['password']);
if($passwordValidation !== '')
$notices[] = $msz->usersCtx->users->validatePasswordText($passwordValidation);
$notices[] = UserPasswordsData::validateUserPasswordText($passwordValidation);
if(!empty($notices))
break;
@ -75,12 +75,12 @@ while(!empty($register)) {
try {
$userInfo = $msz->usersCtx->users->createUser(
$register['username'],
$register['password'],
$register['email'],
$ipAddress,
$countryCode,
$defaultRoleInfo
);
$msz->usersCtx->passwords->updateUserPassword($userInfo, $register['password']);
} catch(RuntimeException $ex) {
$notices[] = 'Something went wrong while creating your account, please alert an administrator or a developer about this!';
break;

View file

@ -5,7 +5,7 @@ use RuntimeException;
use Index\Colour\Colour;
use Misuzu\Perm;
use Misuzu\Auth\AuthTokenCookie;
use Misuzu\Users\User;
use Misuzu\Users\{User,UserPasswordsData};
if(!isset($msz) || !($msz instanceof \Misuzu\MisuzuContext))
die('Script must be called through the Misuzu route dispatcher.');
@ -190,13 +190,13 @@ if(CSRF::validateRequest() && $canEdit) {
if($passwordNewValue !== $passwordConfirmValue)
$notices[] = 'Confirm password does not match.';
else {
$passwordValidation = $msz->usersCtx->users->validatePassword($passwordNewValue);
$passwordValidation = UserPasswordsData::validateUserPassword($passwordNewValue);
if($passwordValidation !== '')
$notices[] = $msz->usersCtx->users->validatePasswordText($passwordValidation);
$notices[] = UserPasswordsData::validateUserPasswordText($passwordValidation);
}
if(empty($notices))
$msz->usersCtx->users->updateUser(userInfo: $userInfo, password: $passwordNewValue);
$msz->usersCtx->passwords->updateUserPassword($userInfo, $passwordNewValue);
}
}

View file

@ -2,7 +2,7 @@
namespace Misuzu;
use RuntimeException;
use Misuzu\Users\User;
use Misuzu\Users\{User,UserPasswordsData};
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
@ -50,7 +50,7 @@ if(!$isRestricted && $isVerifiedRequest && !empty($_POST['role'])) {
if($isVerifiedRequest && isset($_POST['tfa']['enable']) && $msz->usersCtx->totps->hasUserTotp($userInfo) !== (bool)$_POST['tfa']['enable']) {
if((bool)$_POST['tfa']['enable']) {
$totpInfo = $msz->usersCtx->totps->createUserTotp($userInfo);
$totpInfo = $msz->usersCtx->totps->updateUserTotp($userInfo);
$totpSecret = $totpInfo->encodedSecret;
$totpIssuer = $msz->siteInfo->name;
$totpQrcode = (new QRCode(new QROptions([
@ -74,7 +74,7 @@ if($isVerifiedRequest && isset($_POST['tfa']['enable']) && $msz->usersCtx->totps
}
if($isVerifiedRequest && !empty($_POST['current_password'])) {
if(!$userInfo->verifyPassword($_POST['current_password'] ?? '')) {
if(!$msz->usersCtx->passwords->getUserPassword($userInfo)?->verifyPassword($_POST['current_password'] ?? '')) {
$errors[] = 'Your password was incorrect.';
} else {
// Changing e-mail
@ -100,12 +100,12 @@ if($isVerifiedRequest && !empty($_POST['current_password'])) {
if(empty($_POST['password']['confirm']) || $_POST['password']['new'] !== $_POST['password']['confirm']) {
$errors[] = 'The new passwords you entered did not match each other.';
} else {
$checkPassword = $msz->usersCtx->users->validatePassword($_POST['password']['new']);
$checkPassword = UserPasswordsData::validateUserPassword($_POST['password']['new']);
if($checkPassword !== '') {
$errors[] = $msz->usersCtx->users->validatePasswordText($checkPassword);
$errors[] = UserPasswordsData::validateUserPasswordText($checkPassword);
} else {
$msz->usersCtx->users->updateUser(userInfo: $userInfo, password: $_POST['password']['new']);
$msz->usersCtx->passwords->updateUserPassword($userInfo, $_POST['password']['new']);
$msz->createAuditLog('PERSONAL_PASSWORD_CHANGE');
}
}

View file

@ -111,7 +111,7 @@ $userInfo = $msz->authInfo->userInfo;
if(isset($_POST['action']) && is_string($_POST['action'])) {
if(isset($_POST['password']) && is_string($_POST['password'])
&& ($userInfo->verifyPassword($_POST['password'] ?? ''))) {
&& ($msz->usersCtx->passwords->getUserPassword($userInfo)?->verifyPassword($_POST['password'] ?? ''))) {
switch($_POST['action']) {
case 'data':
$msz->createAuditLog('PERSONAL_DATA_DOWNLOAD');
@ -151,9 +151,10 @@ if(isset($_POST['action']) && is_string($_POST['action'])) {
$tmpFiles[] = db_to_zip($archive, $userInfo, 'profile_backgrounds', ['user_id:s', 'bg_attach:s', 'bg_blend:i', 'bg_slide:i']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'profile_fields_values', ['field_id:s', 'user_id:s', 'format_id:s', 'field_value:s']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'sessions', ['session_id:s', 'user_id:s', 'session_key:n', 'session_remote_addr_first:a', 'session_remote_addr_last:a:n', 'session_user_agent:s', 'session_country:s', 'session_expires:t', 'session_expires_bump:b', 'session_created:t', 'session_active:t:n']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'users', ['user_id:s', 'user_name:s', 'user_password:n', 'user_email:s', 'user_remote_addr_first:a', 'user_remote_addr_last:a', 'user_super:b', 'user_country:s', 'user_colour:i:n', 'user_title:s:n', 'user_display_role_id:s:n', 'user_created:t', 'user_active:t:n', 'user_deleted:t:n']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'users', ['user_id:s', 'user_name:s', 'user_email:s', 'user_remote_addr_first:a', 'user_remote_addr_last:a', 'user_super:b', 'user_country:s', 'user_colour:i:n', 'user_title:s:n', 'user_display_role_id:s:n', 'user_created:t', 'user_active:t:n', 'user_deleted:t:n']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'users_bans', ['ban_id:s', 'user_id:s', 'mod_id:n', 'ban_severity:i', 'ban_reason_public:s', 'ban_reason_private:s', 'ban_created:t', 'ban_expires:t:n']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'users_birthdates', ['user_id:s', 'birth_year:i:n', 'birth_month:i', 'birth_day:i']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'users_passwords', ['user_id:s', 'password_hash:n', 'password_created:t']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'users_password_resets', ['reset_id:s', 'user_id:s', 'reset_remote_addr:a', 'reset_requested:t', 'reset_code:n']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'users_roles', ['user_id:s', 'role_id:s']);
$tmpFiles[] = db_to_zip($archive, $userInfo, 'users_totp', ['user_id:s', 'totp_secret:n', 'totp_created:t']);