i18n()->get($key, $default, $vars); } function current_client_id(): string { $session = app()->session(); $session->start(); return $session->ensureClientId(); } function user_theme(): string { $pdo = app()->basePdo(); if (!$pdo) { return 'light'; } $clientId = current_client_id(); $stmt = $pdo->prepare("SELECT theme FROM nexus_user_prefs WHERE client_id = :id LIMIT 1"); $stmt->execute(['id' => $clientId]); $row = $stmt->fetch(\PDO::FETCH_ASSOC); $theme = is_array($row) ? (string)($row['theme'] ?? '') : ''; return match ($theme) { 'dark', 'night' => 'night', 'light', 'day', '' => 'day', default => $theme, }; } function set_user_theme(string $theme): void { $pdo = app()->basePdo(); if (!$pdo) { return; } $clientId = current_client_id(); $stmt = $pdo->prepare( "INSERT INTO nexus_user_prefs (client_id, theme, updated_at) VALUES (:id, :theme, CURRENT_TIMESTAMP) ON CONFLICT(client_id) DO UPDATE SET theme = excluded.theme, updated_at = CURRENT_TIMESTAMP" ); $stmt->execute(['id' => $clientId, 'theme' => $theme]); } function current_module_name(): ?string { $path = app()->request()->path(); if (preg_match('~^/module/([a-zA-Z0-9_-]+)~', $path, $m)) { return $m[1]; } return null; } function auth_enabled(): bool { return app()->auth()->isEnabled(); } function auth_user(): ?array { return app()->auth()->user(); } function auth_display_name(): string { $user = auth_user(); if (!$user) { return ''; } $name = trim((string)($user['name'] ?? '')); if ($name !== '') { return $name; } $email = trim((string)($user['email'] ?? '')); return $email; } function auth_initials(): string { $name = auth_display_name(); if ($name === '') { return 'U'; } $parts = preg_split('/\s+/', $name) ?: []; $letters = ''; foreach ($parts as $p) { $p = trim($p); if ($p !== '') { $letters .= mb_strtoupper(mb_substr($p, 0, 1)); } if (mb_strlen($letters) >= 2) { break; } } return $letters !== '' ? $letters : 'U'; } function auth_groups(): array { $user = auth_user(); return is_array($user['groups'] ?? null) ? $user['groups'] : []; } function parse_group_list(string $value): array { $parts = preg_split('/[,\s]+/', $value) ?: []; $out = []; foreach ($parts as $p) { $p = trim($p); if ($p !== '') { $out[] = $p; } } return $out; } function auth_is_admin(): bool { $config = app()->config(); $groups = auth_groups(); $allowed = parse_group_list($config->oidcAdminGroup); foreach ($allowed as $g) { if (in_array($g, $groups, true)) { return true; } } return false; } function auth_is_user(): bool { $config = app()->config(); $groups = auth_groups(); $admins = parse_group_list($config->oidcAdminGroup); foreach ($admins as $g) { if (in_array($g, $groups, true)) { return true; } } $users = parse_group_list($config->oidcUserGroup); foreach ($users as $g) { if (in_array($g, $groups, true)) { return true; } } return false; } function require_auth(): void { if (!auth_enabled()) { return; } if (auth_user()) { return; } redirect('/auth/login'); } function require_admin(): void { require_auth(); if (!auth_is_admin()) { http_response_code(403); echo '
' . e($description) . '
'; } $html .= '' . e($payload) . ''; $html .= '