protected function processRecoveryToken(string $token)
{
if (Util::stringLength($token) < UserAccounts::RECOVERY_CHAR_LENGTH) {
\Airship\redirect($this->airship_cabin_prefix . '/login');
}
$selector = Util::subString($token, 0, 32);
$validator = Util::subString($token, 32);
$ttl = (int) $this->config('password-reset.ttl');
if (empty($ttl)) {
\Airship\redirect($this->airship_cabin_prefix . '/login');
}
$recoveryInfo = $this->acct->getRecoveryData($selector, $ttl);
if (empty($recoveryInfo)) {
\Airship\redirect($this->airship_cabin_prefix . '/login');
}
$state = State::instance();
if (Symmetric::verify($validator . $recoveryInfo['userid'], $state->keyring['auth.recovery_key'], $recoveryInfo['hashedtoken'])) {
$_SESSION['userid'] = (int) $recoveryInfo['userid'];
$_SESSION['session_canary'] = $this->acct->createSessionCanary($recoveryInfo['userid']);
$this->acct->deleteRecoveryToken($selector);
\Airship\redirect($this->airship_cabin_prefix . '/my/account');
}
\Airship\redirect($this->airship_cabin_prefix . '/login');
}