86 lines
3.3 KiB
PHP
86 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace com\fwdekker\deathnotifier\user;
|
|
|
|
use com\fwdekker\deathnotifier\Action;
|
|
use com\fwdekker\deathnotifier\Util;
|
|
use com\fwdekker\deathnotifier\validation\InvalidTypeException;
|
|
use com\fwdekker\deathnotifier\validation\InvalidValueException;
|
|
use com\fwdekker\deathnotifier\validation\IsEmailRule;
|
|
use com\fwdekker\deathnotifier\validation\IsStringRule;
|
|
use com\fwdekker\deathnotifier\validation\IsValidCsrfTokenRule;
|
|
use com\fwdekker\deathnotifier\validation\RuleSet;
|
|
|
|
|
|
/**
|
|
* Verifies the user's email address.
|
|
*/
|
|
class VerifyEmailAction extends Action
|
|
{
|
|
/**
|
|
* @var UserList the list to verify the email address in
|
|
*/
|
|
private readonly UserList $user_list;
|
|
|
|
|
|
/**
|
|
* Constructs a new `VerifyEmailAction`.
|
|
*
|
|
* @param UserList $user_list the list to verify the email address in
|
|
*/
|
|
public function __construct(UserList $user_list)
|
|
{
|
|
$this->user_list = $user_list;
|
|
}
|
|
|
|
|
|
/**
|
|
* Verifies the user's email address.
|
|
*
|
|
* Requires that a valid CSRF token is present. Does not require the user to be logged in or out.
|
|
*
|
|
* @param array<int|string, mixed> $inputs `"token": string`: a valid CSRF token, `"email"`: the email address to
|
|
* verify, `"verify_token": string`: the token to verify the email address with
|
|
* @return null
|
|
* @throws InvalidTypeException if any of the inputs has the incorrect type
|
|
* @throws InvalidValueException if no valid CSRF token is present, if no account with the given email address
|
|
* exists, if the reset token is invalid, or if the reset token has expired
|
|
*/
|
|
public function handle(array $inputs): mixed
|
|
{
|
|
(new RuleSet([
|
|
"token" => [new IsValidCsrfTokenRule()],
|
|
"email" => [new IsEmailRule()],
|
|
"verify_token" => [new IsStringRule()],
|
|
]))->check($inputs);
|
|
|
|
$this->user_list->transaction(function () use ($inputs) {
|
|
$user_data = $this->user_list->get_user_by_email($inputs["email"]);
|
|
if ($user_data === null)
|
|
throw new InvalidValueException("No user with that email address has been registered.");
|
|
if ($user_data["email_verification_token"] === null)
|
|
throw new InvalidValueException("Your email address is already verified. You can close this page.");
|
|
if ($inputs["verify_token"] !== $user_data["email_verification_token"])
|
|
throw new InvalidValueException(
|
|
"This verification link is invalid. " .
|
|
"This may happen if you recently changed your email address or you requested another " .
|
|
"verification link, in which case a new verification link should arrive in your inbox soon. " .
|
|
"If this does not happen, log in and request a new verification email."
|
|
);
|
|
|
|
$minutes_left = Util::minutes_until_interval_elapsed(
|
|
$user_data["email_verification_token_timestamp"],
|
|
UserList::MINUTES_VALID_VERIFICATION
|
|
);
|
|
if ($minutes_left < 0)
|
|
throw new InvalidValueException(
|
|
"This email verification link has expired. Log in and request a new verification email."
|
|
);
|
|
|
|
$this->user_list->set_email_verified($_SESSION["uuid"]);
|
|
});
|
|
|
|
return null;
|
|
}
|
|
}
|