Files
HIPCTF2/docs/architecture/frontend-structure.md
T
2026-07-21 14:23:48 +00:00

70 lines
4.3 KiB
Markdown

---
type: architecture
title: Frontend Structure
description: Angular routes, components, services, guards, and interceptors.
tags: [architecture, frontend, angular]
timestamp: 2026-07-21T14:18:00Z
---
# Routes
Routes live in `frontend/src/app/app.routes.ts`:
| Path | Component | Guard | Notes |
|--------------|----------------------------------|---------------|----------------------------------------|
| `/bootstrap` | `CreateAdminComponent` | — | Rendered only when `initialized === false`. |
| `/login` | `LoginComponent` | — | Standard login form. |
| `/` | `HomeComponent` | `authGuard` | Requires auth + initialized. |
| `**` | Redirect to `/` | — | Wildcard fallback. |
# Components
All components are standalone (no NgModules). Each component imports
`FormsModule` directly and uses Angular signals for state.
| Component | Path | Purpose |
|------------------------|-----------------------------------------------------------------|-------------------------------------------------|
| `AppComponent` | `frontend/src/app/app.component.ts` | Root; renders `<router-outlet>` and calls `BootstrapService.load()`. |
| `HomeComponent` | `frontend/src/app/features/home/home.component.ts` | Landing page shown after auth. |
| `LoginComponent` | `frontend/src/app/features/auth/login.component.ts` | Username/password form. |
| `CreateAdminComponent` | `frontend/src/app/features/bootstrap/create-admin.component.ts`| First-admin bootstrap form. |
# Services
| Service | Path | Purpose |
|---------------------|---------------------------------------------------------------|-----------------------------------------------------------|
| `AuthService` | `frontend/src/app/core/services/auth.service.ts` | Signal-backed access token + current user. |
| `BootstrapService` | `frontend/src/app/core/services/bootstrap.service.ts` | Fetches `/api/v1/bootstrap`, applies theme tokens to CSS. |
# Guards and interceptors
| Symbol | Path | Purpose |
|---------------------|---------------------------------------------------------------|-----------------------------------------------------------|
| `authGuard` | `frontend/src/app/core/guards/auth.guard.ts` | Redirects to `/bootstrap` when uninitialized, `/login` when not authenticated. |
| `authInterceptor` | `frontend/src/app/core/interceptors/auth.interceptor.ts` | Attaches `Authorization: Bearer <accessToken>` header. |
| `csrfInterceptor` | `frontend/src/app/core/interceptors/csrf.interceptor.ts` | Attaches `X-CSRF-Token` header on POST/PUT/PATCH/DELETE. |
Both interceptors are wired in `frontend/src/main.ts` via
`provideHttpClient(withInterceptors([csrfInterceptor, authInterceptor]))`
(notably CSRF runs first so the token is attached before the auth header).
# Bootstrap flow
1. `AppComponent.ngOnInit()``BootstrapService.load()`.
2. `BootstrapService` calls `GET /api/v1/bootstrap` (public, with
`credentials: 'include'`).
3. The payload sets `initialized` (true iff any admin user exists),
`pageTitle`, `logo`, `welcomeMarkdown`, the active `theme`, and the
default challenge IP.
4. Theme tokens are written to CSS custom properties on
`document.documentElement` (`--color-primary`, `--font-family`,
`--radius-*`, etc.) consumed by `frontend/src/styles.css`.
5. The `authGuard` reads `BootstrapService.initialized()` and either
allows navigation or redirects to `/bootstrap`.
# See also
- [System Overview](/architecture/overview.md)
- [Backend Module Map](/architecture/backend-modules.md)
- [First-Run Bootstrap](/guides/bootstrap.md)