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
Some checks failed
PHPUnit / test (push) Has been cancelled
This commit is contained in:
23
common.php
23
common.php
@ -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'],
|
||||
|
||||
@ -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'] ?? '') !== '') {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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']);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user