Files
BanGUI/frontend/src/api/endpoints.ts
Lukas 29daaa9906 TASK-004: Bootstrap frontend auth state from backend session check
Validates session on app mount by calling GET /api/auth/session instead of relying
solely on cached sessionStorage. This ensures the UI state always reflects server
reality — expired or revoked sessions are detected immediately.

Changes:
- Backend: Add GET /api/auth/session endpoint (requires valid session, returns 200/401)
- Frontend: Add useSessionValidation hook for mount-time validation
- Frontend: Add SessionValidationLoading component for validation spinner
- Frontend: Update AuthProvider to call validation on mount with loading state
- Frontend: Add validateSession API function
- Docs: Update Features.md with session validation behavior
- Docs: Update Web-Development.md with session validation pattern

Handles three outcomes:
1. Valid session (200): Proceed with cached state
2. Invalid session (401): Clear sessionStorage and redirect to login
3. Network error: Don't logout (backend may be temporarily unreachable)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-26 12:00:21 +02:00

138 lines
6.4 KiB
TypeScript

/**
* API endpoint path constants.
*
* Every backend path used by the frontend is defined here.
* Components and API modules import from this file rather than
* hard-coding URL strings, so renaming an endpoint requires only one change.
*/
export const ENDPOINTS = {
// -------------------------------------------------------------------------
// Health
// -------------------------------------------------------------------------
health: "/health",
// -------------------------------------------------------------------------
// Setup wizard
// -------------------------------------------------------------------------
setup: "/setup",
setupTimezone: "/setup/timezone",
// -------------------------------------------------------------------------
// Authentication
// -------------------------------------------------------------------------
authLogin: "/auth/login",
authLogout: "/auth/logout",
authSession: "/auth/session",
// -------------------------------------------------------------------------
// Dashboard
// -------------------------------------------------------------------------
dashboardStatus: "/dashboard/status",
dashboardBans: "/dashboard/bans",
dashboardBansByCountry: "/dashboard/bans/by-country",
dashboardBansTrend: "/dashboard/bans/trend",
dashboardBansByJail: "/dashboard/bans/by-jail",
// -------------------------------------------------------------------------
// Jails
// -------------------------------------------------------------------------
jails: "/jails",
jail: (name: string): string => `/jails/${encodeURIComponent(name)}`,
jailBanned: (name: string): string => `/jails/${encodeURIComponent(name)}/banned`,
jailStart: (name: string): string => `/jails/${encodeURIComponent(name)}/start`,
jailStop: (name: string): string => `/jails/${encodeURIComponent(name)}/stop`,
jailIdle: (name: string): string => `/jails/${encodeURIComponent(name)}/idle`,
jailReload: (name: string): string => `/jails/${encodeURIComponent(name)}/reload`,
jailsReloadAll: "/jails/reload-all",
jailIgnoreIp: (name: string): string => `/jails/${encodeURIComponent(name)}/ignoreip`,
jailIgnoreSelf: (name: string): string => `/jails/${encodeURIComponent(name)}/ignoreself`,
// -------------------------------------------------------------------------
// Bans
// -------------------------------------------------------------------------
bans: "/bans",
bansActive: "/bans/active",
bansAll: "/bans/all",
// -------------------------------------------------------------------------
// Geo / IP lookup
// -------------------------------------------------------------------------
geoLookup: (ip: string): string => `/geo/lookup/${encodeURIComponent(ip)}`,
// -------------------------------------------------------------------------
// Configuration
// -------------------------------------------------------------------------
configJails: "/config/jails",
configJailsInactive: "/config/jails/inactive",
configJail: (name: string): string => `/config/jails/${encodeURIComponent(name)}`,
configJailLogPath: (name: string): string =>
`/config/jails/${encodeURIComponent(name)}/logpath`,
configJailActivate: (name: string): string =>
`/config/jails/${encodeURIComponent(name)}/activate`,
configJailDeactivate: (name: string): string =>
`/config/jails/${encodeURIComponent(name)}/deactivate`,
configJailLocalOverride: (name: string): string =>
`/config/jails/${encodeURIComponent(name)}/local`,
configJailValidate: (name: string): string =>
`/config/jails/${encodeURIComponent(name)}/validate`,
configGlobal: "/config/global",
configReload: "/config/reload",
configRestart: "/config/restart",
configRegexTest: "/config/regex-test",
configPreviewLog: "/config/preview-log",
configMapColorThresholds: "/config/map-color-thresholds",
// File-based config (jail.d, filter.d, action.d)
configJailFiles: "/config/jail-files",
configJailFile: (filename: string): string =>
`/config/jail-files/${encodeURIComponent(filename)}`,
configJailFileEnabled: (filename: string): string =>
`/config/jail-files/${encodeURIComponent(filename)}/enabled`,
configJailFileParsed: (filename: string): string =>
`/config/jail-files/${encodeURIComponent(filename)}/parsed`,
configFilters: "/config/filters",
configFiltersRaw: "/config/filters/raw",
configFilter: (name: string): string => `/config/filters/${encodeURIComponent(name)}`,
configFilterRaw: (name: string): string => `/config/filters/${encodeURIComponent(name)}/raw`,
configFilterParsed: (name: string): string =>
`/config/filters/${encodeURIComponent(name)}/parsed`,
configJailFilter: (name: string): string =>
`/config/jails/${encodeURIComponent(name)}/filter`,
configJailAction: (name: string): string =>
`/config/jails/${encodeURIComponent(name)}/action`,
configJailActionName: (jailName: string, actionName: string): string =>
`/config/jails/${encodeURIComponent(jailName)}/action/${encodeURIComponent(actionName)}`,
configActions: "/config/actions",
configAction: (name: string): string => `/config/actions/${encodeURIComponent(name)}`,
configActionRaw: (name: string): string => `/config/actions/${encodeURIComponent(name)}/raw`,
configActionParsed: (name: string): string =>
`/config/actions/${encodeURIComponent(name)}/parsed`,
// fail2ban log viewer (Task 2)
configFail2BanLog: "/config/fail2ban-log",
configServiceStatus: "/config/service-status",
// -------------------------------------------------------------------------
// Server settings
// -------------------------------------------------------------------------
serverSettings: "/server/settings",
serverFlushLogs: "/server/flush-logs",
// -------------------------------------------------------------------------
// Ban history
// -------------------------------------------------------------------------
history: "/history",
historyIp: (ip: string): string => `/history/${encodeURIComponent(ip)}`,
// -------------------------------------------------------------------------
// Blocklists
// -------------------------------------------------------------------------
blocklists: "/blocklists",
blocklist: (id: number): string => `/blocklists/${String(id)}`,
blocklistPreview: (id: number): string => `/blocklists/${String(id)}/preview`,
blocklistsImport: "/blocklists/import",
blocklistsSchedule: "/blocklists/schedule",
blocklistsLog: "/blocklists/log",
} as const;