Area: Account & identity (audit phase 1) · Surface: GET /account/sessions (AccountController@activeSessions) · Dimension: dead-code · Severity: major
The dashboard layout renders an "Active Sessions ... Manage" link to /account/sessions. Clicking it navigates the browser to a route whose handler (activeSessions) emits raw JSON ({"sessions":[...]}) via $this->json(), not an HTML page. There is no JS/fetch caller of this route anywhere in the codebase, so the only consumer is this anchor click, which dumps JSON to the user. The real session-management UI (terminate one / terminate all) lives in profile/settings.php (rendered at /account/settings by showSettings), which loads its own $sessions list. The Manage link should point at /account/settings (or the route should render an HTML page).
Evidence
Route maps GET to a JSON handler:
platform/src/routes.php:1264
$router->get('/account/sessions', 'AccountController@activeSessions');
Handler returns JSON, never renders a page:
platform/src/Controllers/AccountController.php:1216-1228
public function activeSessions(): void
{
$user = $this->requireAuth();
$sessions = $this->db->fetchAll('SELECT id, ip_address, user_agent, last_active FROM sessions WHERE user_id = :uid ORDER BY last_active DESC', ['uid' => $user['id']]);
$this->json(['sessions' => $sessions]);
}
A user-facing link points a browser directly at this route:
platform/templates/layouts/dashboard.php:415
<td><?= $e($activeSessions ?? 0) ?> — <a href="/account/sessions" class="link">Manage</a></td>
No JS/fetch consumer exists for the JSON payload (proves the JSON form is not consumed programmatically):
$ grep -rn "account/sessions" platform/public/ platform/assets/ 2>/dev/null -> (zero hits)
$ grep -rn "account/sessions" platform/templates/ | grep -iE 'fetch|xhr|\.json|ajax|api' -> (zero hits)
Suggested fix. Point the dashboard "Manage" link at /account/settings#sessionsCard (the canonical session UI in profile/settings.php), or change the GET /account/sessions route to render an HTML page. If a JSON endpoint is still wanted, move it under /api/.
Filed by the automated tenant-app audit (phase 1) and adversarially evidence-verified. Status: verified. Open — not yet actioned.
Patrick Bass
@mobieus