Add SportPath auth APIs and training content foundation
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
final class ApiAuth
|
||||
{
|
||||
public static function bearerClaims(): array
|
||||
{
|
||||
$header = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
|
||||
if (!preg_match('/^Bearer\s+([A-Za-z0-9_.-]+)$/i', $header, $matches)) {
|
||||
api_json(['error' => 'unauthorized'], 401);
|
||||
}
|
||||
$claims = JwtToken::verify($matches[1]);
|
||||
if ($claims === null) {
|
||||
api_json(['error' => 'unauthorized'], 401);
|
||||
}
|
||||
try {
|
||||
$db = Database::getInstance();
|
||||
$stmt = $db->prepare('SELECT u.id, u.account_role, u.is_active FROM auth_sessions s JOIN users u ON u.id = s.user_id WHERE s.session_uuid = ? AND s.user_id = ? AND s.revoked_at IS NULL AND s.replaced_by IS NULL AND s.expires_at > UTC_TIMESTAMP() AND u.is_active = 1 LIMIT 1');
|
||||
$userId = (int) $claims['sub'];
|
||||
$sessionId = $claims['sid'];
|
||||
$stmt->bind_param('si', $sessionId, $userId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$user = $result->fetch_assoc();
|
||||
$stmt->close();
|
||||
if (!$user) {
|
||||
api_json(['error' => 'unauthorized'], 401);
|
||||
}
|
||||
return ['user_id' => (int) $user['id'], 'role' => $user['account_role'], 'session_id' => $sessionId];
|
||||
} catch (Throwable $exception) {
|
||||
error_log('Bearer authorization check failed: ' . $exception->getMessage());
|
||||
api_json(['error' => 'service_unavailable'], 503);
|
||||
}
|
||||
}
|
||||
|
||||
public static function requireRole(array $auth, array $allowedRoles): void
|
||||
{
|
||||
if (!in_array($auth['role'] ?? null, $allowedRoles, true)) {
|
||||
api_json(['error' => 'forbidden'], 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user