1
0
mirror of https://github.com/delight-im/PHP-Auth.git synced 2025-08-03 22:57:27 +02:00

Extract code into separate 'generateAndStoreRandomOneTimePassword'

This commit is contained in:
Marco
2024-04-04 19:09:40 +02:00
parent c21f59d4d5
commit e266178f95

View File

@@ -1320,28 +1320,7 @@ final class Auth extends UserManager {
$throttled = true; $throttled = true;
} }
// generate a one-time password $otpValue = $this->generateAndStoreRandomOneTimePassword($userId, $twoFactorMethod['mechanism']);
$otpValue = \strtoupper(\substr(\Delight\Otp\Otp::createSecret(\Delight\Otp\Otp::SHARED_SECRET_STRENGTH_LOW), 0, 6));
$otpValueSelector = self::createSelectorForOneTimePassword($otpValue, $userId);
$otpValueToken = \password_hash($otpValue, \PASSWORD_DEFAULT);
// store the generated one-time password
try {
$this->db->insert(
$this->makeTableNameComponents('users_otps'),
[
'user_id' => $userId,
'mechanism' => $twoFactorMethod['mechanism'],
'single_factor' => 0,
'selector' => $otpValueSelector,
'token' => $otpValueToken,
'expires_at' => \time() + 60 * 10,
]
);
}
catch (Error $e) {
throw new DatabaseError($e->getMessage());
}
if ($twoFactorMethod['mechanism'] === self::TWO_FACTOR_MECHANISM_SMS) { if ($twoFactorMethod['mechanism'] === self::TWO_FACTOR_MECHANISM_SMS) {
$secondFactorRequiredException->addSmsOption($twoFactorMethod['seed'], $otpValue); $secondFactorRequiredException->addSmsOption($twoFactorMethod['seed'], $otpValue);
@@ -1352,17 +1331,6 @@ final class Auth extends UserManager {
else { else {
throw new InvalidStateError(); throw new InvalidStateError();
} }
// delete any old one-time passwords for this user that have expired at least 15 minutes ago
try {
$this->db->exec(
'DELETE FROM ' . $this->makeTableName('users_otps') . ' WHERE user_id = ? AND expires_at < ?',
[ $userId, \time() - 60 * 15 ]
);
}
catch (Error $e) {
throw new DatabaseError($e->getMessage());
}
} }
// if the specific mechanism mandates that the one-time password is generated on the client side // if the specific mechanism mandates that the one-time password is generated on the client side
elseif ($twoFactorMethod['mechanism'] === self::TWO_FACTOR_MECHANISM_TOTP) { elseif ($twoFactorMethod['mechanism'] === self::TWO_FACTOR_MECHANISM_TOTP) {
@@ -1392,6 +1360,45 @@ final class Auth extends UserManager {
} }
} }
private function generateAndStoreRandomOneTimePassword($userId, $mechanism) {
// generate a random one-time password
$otpLength = 6;
$otpValue = \strtoupper(\substr(\Delight\Otp\Otp::createSecret(\Delight\Otp\Otp::SHARED_SECRET_STRENGTH_LOW), 0, $otpLength));
$otpValueSelector = self::createSelectorForOneTimePassword($otpValue, $userId);
$otpValueToken = \password_hash($otpValue, \PASSWORD_DEFAULT);
// store the generated one-time password for the user and define it to expire after ten minutes
try {
$this->db->insert(
$this->makeTableNameComponents('users_otps'),
[
'user_id' => $userId,
'mechanism' => $mechanism,
'single_factor' => 0,
'selector' => $otpValueSelector,
'token' => $otpValueToken,
'expires_at' => \time() + 60 * 10,
]
);
}
catch (Error $e) {
throw new DatabaseError($e->getMessage());
}
// delete any old one-time passwords for the user that have expired at least 15 minutes ago
try {
$this->db->exec(
'DELETE FROM ' . $this->makeTableName('users_otps') . ' WHERE user_id = ? AND expires_at < ?',
[ $userId, \time() - 60 * 15 ]
);
}
catch (Error $e) {
throw new DatabaseError($e->getMessage());
}
return $otpValue;
}
/** /**
* Returns the requested user data for the account with the specified email address (if any) * Returns the requested user data for the account with the specified email address (if any)
* *