enhanced token management by adding optional expiry refresh in token_get_record and updated session API documentation
Some checks failed
PHPUnit / test (push) Has been cancelled

This commit is contained in:
2026-06-24 10:23:19 +02:00
parent b02f264b23
commit 67858d34d9
4 changed files with 43 additions and 10 deletions

View File

@ -178,14 +178,29 @@ function token_add(string $token, int $ttlSeconds = 86400, array $extra = []): v
qdb_save($tmpDb, $lockFp);
}
function token_get_record(string $token): ?array {
function token_get_record(string $token, bool $refreshExpiry = true): ?array {
require_once __DIR__ . '/db_init.php';
[$pdo, $tmpDb, $lockFp] = qdb_open(false);
require_once __DIR__ . '/lib/settings.php';
[$pdo, $tmpDb, $lockFp] = qdb_open($refreshExpiry);
$now = time();
$stmt = $pdo->prepare("SELECT * FROM session WHERE token = :t AND expiresAt >= :now");
$stmt->execute([':t' => token_storage_key($token), ':now' => time()]);
$storedToken = token_storage_key($token);
$stmt->execute([':t' => $storedToken, ':now' => $now]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) {
qdb_discard($tmpDb, $lockFp);
if (!$row) return null;
return null;
}
if ($refreshExpiry) {
$settings = qdb_settings_get_on_pdo($pdo);
$newExpiry = $now + qdb_session_ttl_seconds($settings, !empty($row['temp']));
$pdo->prepare('UPDATE session SET expiresAt = :exp WHERE token = :t')
->execute([':exp' => $newExpiry, ':t' => $storedToken]);
$row['expiresAt'] = $newExpiry;
qdb_save($tmpDb, $lockFp);
} else {
qdb_discard($tmpDb, $lockFp);
}
// Map DB columns to the keys the rest of the codebase expects
return [
'token' => $row['token'],

View File

@ -1,7 +1,7 @@
<?php
/**
* GET /api/session — verify Bearer token is still active (website session check).
* GET /api/session — verify Bearer token is still active and return role metadata.
*/
if ($method !== 'GET') {
@ -19,9 +19,6 @@ if (!$rec) {
}
$role = (string)($rec['role'] ?? '');
if ($role === 'coach') {
json_error('FORBIDDEN', 'Counselor accounts can only sign in through the mobile app.', 403);
}
$username = '';
if (($rec['userID'] ?? '') !== '') {

View File

@ -255,7 +255,7 @@ function qdb_api_log_finish(): void
if ($token !== null && $token !== '') {
$auth['token_hint'] = qdb_api_log_token_hint($token);
try {
$rec = token_get_record($token);
$rec = token_get_record($token, false);
if (is_array($rec)) {
$auth['role'] = $rec['role'] ?? null;
$auth['userID'] = $rec['userID'] ?? null;

View File

@ -41,4 +41,25 @@ final class TokenTest extends QdbTestCase
$this->assertGreaterThanOrEqual(2, $n);
$this->assertNull(token_get_record($t1));
}
public function testTokenLookupRefreshesExpiry(): void
{
$token = bin2hex(random_bytes(32));
$f = $this->fixture();
token_add($token, 3600, [
'userID' => $f->adminUserId,
'role' => 'admin',
'entityID' => 'ent',
]);
[$pdo, $tmpDb, $lockFp] = qdb_open(true);
$oldExpiry = time() + 60;
$pdo->prepare('UPDATE session SET expiresAt = :exp WHERE token = :t')
->execute([':exp' => $oldExpiry, ':t' => token_storage_key($token)]);
qdb_save($tmpDb, $lockFp);
$rec = token_get_record($token);
$this->assertNotNull($rec);
$this->assertGreaterThan($oldExpiry + 3000, $rec['exp']);
}
}