stmts = new StatementCache($conn); } public function createLoginSession( UserInfo $userInfo, string $remoteAddr, string $countryCode, int $factors ): string { $loginId = XString::random(48); $stmt = $this->stmts->getStatement('create login', function() { return 'INSERT INTO ' . self::LOGINS_TABLE . ' (auth_login_id, user_id, auth_login_ip, auth_login_country, auth_login_factors_required)' . ' VALUES (?, ?, INET6_ATON(?), ?, ?)'; }); $stmt->addParameter(1, $loginId); $stmt->addParameter(2, $userInfo->getId()); $stmt->addParameter(3, $remoteAddr); $stmt->addParameter(4, $countryCode); $stmt->addParameter(5, $factors); $stmt->execute(); return $loginId; } public function destroyLoginSession(AuthLoginInfo $loginInfo): void { $stmt = $this->stmts->getStatement('destroy login', fn() => ('DELETE FROM ' . self::LOGINS_TABLE . ' WHERE auth_login_id = ?')); $stmt->addParameter(1, $loginInfo->getId()); $stmt->execute(); } private function fetchLoginSingle(IDbResult $result, string $exceptionText): UserInfo { if(!$result->next()) throw new AuthLoginNotFoundException($exceptionText); return new UserInfo($result); } public function getLoginSessionById(string $loginId): ?AuthLoginInfo { $stmt = $this->stmts->getStatement('get login by id', fn() => ('SELECT ' . implode(',', self::LOGINS_FIELDS) . ' FROM ' . self::LOGINS_TABLE . ' WHERE auth_login_id = ?')); $stmt->addParameter(1, $loginId); $stmt->execute(); $result = $stmt->getResult(); if(!$result->next()) return null; return new AuthLoginInfo($result); } public function incrementLoginSessionDone(AuthLoginInfo $login): void { $stmt = $this->stmts->getStatement('increment login done', fn() => ('UPDATE ' . self::LOGINS_TABLE . ' SET auth_login_factors_done = auth_login_factors_done + 1 WHERE auth_login_id = ?')); $stmt->addParameter(1, $login->getId()); $stmt->execute(); } }