dbConn = $dbConn; $this->cache = new DbStatementCache($dbConn); } public static function generateCode(): string { return Base32::encode(random_bytes(6)); } public function prune(): void { $this->dbConn->execute('DELETE FROM verifications WHERE verify_created < NOW() - INTERVAL 15 MINUTE'); } public function getVerification( ?string $code = null, UuidInterface|string|null $uuid = null, IPAddress|string|null $remoteAddr = null ): VerificationInfo { $hasCode = $code !== null; $hasUuid = $uuid !== null; $hasRemoteAddr = $remoteAddr !== null; $values = []; $query = 'SELECT verify_code, verify_uuid, verify_name, INET6_NTOA(verify_addr), UNIX_TIMESTAMP(verify_created) FROM verifications'; if($hasCode) { $query .= ' WHERE verify_code = ?'; $values[] = $code; } else { $args = 0; if($hasUuid) { if($uuid instanceof UuidInterface) $uuid = $uuid->getBytes(); ++$args; $query .= ' WHERE verify_uuid = ?'; $values[] = $uuid; } if($hasRemoteAddr) { if($remoteAddr instanceof IPAddress) $remoteAddr = (string)$remoteAddr; $query .= sprintf(' %s verify_addr = INET6_ATON(?)', ++$args > 1 ? 'AND' : 'WHERE'); $values[] = $remoteAddr; } } if(empty($values)) throw new InvalidArgumentException('Not enough arguments specified.'); $args = 0; $stmt = $this->cache->get($query); foreach($values as $value) $stmt->addParameter(++$args, $value); $stmt->execute(); $result = $stmt->getResult(); if(!$result->next()) throw new RuntimeException('Verification info not found.'); return VerificationInfo::fromResult($result); } public function createVerification( UuidInterface|string $uuid, string $name, IPAddress|string $remoteAddr ): string { if($uuid instanceof UuidInterface) $uuid = $uuid->getBytes(); if($remoteAddr instanceof IPAddress) $remoteAddr = (string)$remoteAddr; $code = self::generateCode(); $stmt = $this->cache->get('REPLACE INTO verifications (verify_code, verify_uuid, verify_name, verify_addr) VALUES (?, ?, ?, INET6_ATON(?))'); $stmt->addParameter(1, $code); $stmt->addParameter(2, $uuid); $stmt->addParameter(3, $name); $stmt->addParameter(4, $remoteAddr); $stmt->execute(); return $code; } public function deleteVerification(VerificationInfo|string $code): void { if($code instanceof VerificationInfo) $code = $code->getCode(); $stmt = $this->cache->get('DELETE FROM verifications WHERE verify_code = ?'); $stmt->addParameter(1, $code); $stmt->execute(); } }