Files
api/services/nginx/app/objects/tokens_o.php
T
Jeppe Bundgaard 63c88a463d Refactor passkey and token processing for improved consistency and validation
- Update passkey data mapping to use associative arrays and handle JSON decoding for `transports`.
- Refactor token caching logic to validate database existence and clear stale entries.
- Improve 2FA handling by centralizing `token->type` and `user_id` processing for reuse.
2026-02-23 22:44:06 +01:00

106 lines
3.3 KiB
PHP

<?php
namespace objects;
use classes\db;
use classes\object_property;
use Exception;
use traits\db_object_t;
class tokens_o extends db
{
use db_object_t;
public object_property $user_id;
public object_property $type; // AUTH_TOKEN, RESET_PASSWORD, AUTH_TOKEN_SUBUSER
public object_property $token;
public function structure(): void
{
$this->setTable('tokens');
}
public function objectChanged(): void
{
// Invalidate the cache
if ($this->id > 0) {
try {
$token = $this->token->value();
redis->clear_token($token);
} catch (\Exception $e) {
// If the record is already gone or token cannot be retrieved, we can't clear by token string.
// This can happen during a hard delete where objectChanged is called after the record is deleted.
}
}
}
public function create(int $user_id, string $token, string $type = 'AUTH_TOKEN'): void
{
global $db;
// Avoid SQL injection
$token = $db->escape_string($token);
// Create a new record in the database
$sql = "INSERT INTO $this->table (user_id, token, type) VALUES ($user_id, '$token', '$type')";
$db->query($sql);
// Get the id of the new record
$this->id = $db->insert_id();
// Set the values of the object properties
$this->getObjectProperties();
}
public function getObjectProperties(): void
{
$this->user_id = new object_property($this->table, $this->id, 'user_id', 'int', true);
$this->type = new object_property($this->table, $this->id, 'type', 'string', true);
$this->token = new object_property($this->table, $this->id, 'token', 'string', true);
}
/**
* @throws Exception
*/
public function getToken(string $token): tokens_o
{
global $db;
// Check if the token is cached
$cached = redis->get_token($token);
if ($cached) {
$this->id = (int)$cached['id'];
// Verify that the token still exists in the database to avoid stale cache issues.
if ($this->exists()) {
$this->getObjectProperties();
return $this;
}
// If it doesn't exist, clear the stale cache entry and proceed to check the database.
redis->clear_token($token);
}
// Avoid SQL injection
$token = $db->escape_string($token);
// Prepare the SQL statement
$sql = "SELECT id FROM $this->table WHERE token = '$token'";
$result = $db->query($sql);
$row = $db->fetch_assoc($result);
if (!$row) {
throw new Exception("Token not found " . $token);
}
// Cache the token
redis->cache_token($token, $row);
$this->id = $row['id'];
$this->getObjectProperties();
return $this;
}
public function delete(string $token): void
{
global $db;
// Avoid SQL injection
$token = $db->escape_string($token);
// Prepare the SQL statement
$sql = "DELETE FROM $this->table WHERE token = '$token'";
$db->query($sql);
// Clear the token from the cache
redis->clear_token($token);
}
}