166 lines
21 KiB
Markdown
166 lines
21 KiB
Markdown
---
|
|
type: architecture
|
|
title: Key Files Index
|
|
description: One-line responsibility for every important source file in the repository.
|
|
tags: [architecture, index, key-files]
|
|
timestamp: 2026-07-21T18:45:54Z
|
|
---
|
|
|
|
# Backend
|
|
|
|
## Entrypoint & config
|
|
|
|
| File | Responsibility |
|
|
|--------------------------------------------------------------------------|--------------------------------------------------------------------------------|
|
|
| `backend/src/main.ts` | Bootstraps Nest, registers middleware, builds OpenAPI 3.1, mounts SPA fallback. |
|
|
| `backend/src/app.module.ts` | Root module; wires every feature module + global guards/filters. |
|
|
| `backend/src/config/env.schema.ts` | Zod-validated env schema, `SETTINGS_KEYS`, system category metadata. |
|
|
|
|
## Database
|
|
|
|
| File | Responsibility |
|
|
|--------------------------------------------------------------------------|--------------------------------------------------------------------------------|
|
|
| `backend/src/database/database.module.ts` | TypeORM `better-sqlite3` config, entity + migration registration. |
|
|
| `backend/src/database/database-init.service.ts` | Initializes the DataSource, enforces WAL PRAGMA, runs migrations, verifies seed. |
|
|
| `backend/src/database/migrations/1700000000000-InitSchema.ts` | Creates all tables and sets WAL + foreign keys. |
|
|
| `backend/src/database/migrations/1700000000100-SeedSystemData.ts` | Seeds the 6 system categories and default settings. |
|
|
| `backend/src/database/entities/user.entity.ts` | `user` table (admin/player role, enabled/disabled status). |
|
|
| `backend/src/database/entities/setting.entity.ts` | `setting` key/value table. |
|
|
| `backend/src/database/entities/category.entity.ts` | `category` table with `system_key` unique index. |
|
|
| `backend/src/database/entities/challenge.entity.ts` | `challenge` table (difficulty, decay, protocol, flag, port). |
|
|
| `backend/src/database/entities/challenge-file.entity.ts` | `challenge_file` table for attachments. |
|
|
| `backend/src/database/entities/solve.entity.ts` | `solve` table with unique `(challenge_id, user_id)`. |
|
|
| `backend/src/database/entities/refresh-token.entity.ts` | `refresh_token` table (token_hash + revocation). |
|
|
| `backend/src/database/entities/blog-post.entity.ts` | `blog_post` table (draft/published + publishedAt index). |
|
|
|
|
## Common
|
|
|
|
| File | Responsibility |
|
|
|--------------------------------------------------------------------------|--------------------------------------------------------------------------------|
|
|
| `backend/src/common/common.module.ts` | Aggregates common services, middleware, and providers. |
|
|
| `backend/src/common/middleware/csrf.middleware.ts` | Double-submit CSRF check; mints/reads cookie, compares header. |
|
|
| `backend/src/common/guards/jwt-auth.guard.ts` | Global JWT guard; honors `@Public()`. |
|
|
| `backend/src/common/guards/admin.guard.ts` | Requires `req.user.role === 'admin'`. |
|
|
| `backend/src/common/guards/roles.guard.ts` | Enforces `@Roles(...)` metadata. |
|
|
| `backend/src/common/decorators/public.decorator.ts` | `@Public()` marker. |
|
|
| `backend/src/common/decorators/roles.decorator.ts` | `@Roles(...)` metadata. |
|
|
| `backend/src/common/decorators/skip-csrf.decorator.ts` | `@SkipCsrf()` marker. |
|
|
| `backend/src/common/filters/global-exception.filter.ts` | Converts all errors to the standard envelope. |
|
|
| `backend/src/common/pipes/zod-validation.pipe.ts` | Validates body/param/query with a zod schema. |
|
|
| `backend/src/common/interceptors/transform.interceptor.ts` | Optional response transformer. |
|
|
| `backend/src/common/services/event-status.service.ts` | Computes event `Stopped`/`Running` and `countdownMs`. |
|
|
| `backend/src/common/services/login-backoff.service.ts` | Per-IP+username failed-login throttle. |
|
|
| `backend/src/common/services/registration-rate-limit.service.ts` | Per-IP first-admin registration throttle. |
|
|
| `backend/src/common/services/sse-hub.service.ts` | In-process pub/sub for event status and scoreboard streams. |
|
|
| `backend/src/common/utils/openapi31.ts` | Converts the Nest-generated OpenAPI 3.0 doc to OpenAPI 3.1. |
|
|
| `backend/src/common/utils/password-policy.ts` | Argon2 password validator (length, mixed-case policy). |
|
|
| `backend/src/common/utils/theme-loader.service.ts` | Loads themes from disk, backfills built-ins, validates tokens. |
|
|
| `backend/src/common/utils/upload.ts` | Upload size-limit parser + filename sanitizer. |
|
|
| `backend/src/common/types/theme.ts`, `theme-ids.ts` | `Theme` interface and the 10 canonical `ThemeId`s. |
|
|
| `backend/src/common/errors/api-error.ts` | `ApiError` class (status + machine code + message + details). |
|
|
| `backend/src/common/errors/error-codes.ts` | Canonical `ERROR_CODES` enum. |
|
|
|
|
## Modules
|
|
|
|
| File | Responsibility |
|
|
|--------------------------------------------------------------------------|--------------------------------------------------------------------------------|
|
|
| `backend/src/modules/auth/auth.module.ts` | Wires `AuthController`, `AuthService`, `JwtStrategy`; imports `SettingsModule` for the public register flow. |
|
|
| `backend/src/modules/auth/auth.controller.ts` | `/api/v1/auth/{register,login,refresh,logout,csrf}`. |
|
|
| `backend/src/modules/auth/auth.service.ts` | Login, refresh, logout, register-first-admin, public player self-registration (`registerPlayer`), session minting. |
|
|
| `backend/src/modules/auth/cookie.ts` | `setRefreshCookie` / `clearRefreshCookie` helpers. |
|
|
| `backend/src/modules/auth/dto/auth.dto.ts` | Zod schemas for login + refresh + `RegisterDtoSchema` (with `password === passwordConfirm` refine + username regex). |
|
|
| `backend/src/modules/auth/strategies/jwt.strategy.ts` | Passport JWT strategy. |
|
|
| `backend/src/modules/users/users.module.ts` | Wires `UsersController` + `UsersService`. |
|
|
| `backend/src/modules/users/users.controller.ts` | `/api/v1/auth/register-first-admin`. |
|
|
| `backend/src/modules/users/users.service.ts` | `enforceLastAdminInvariant` helper. |
|
|
| `backend/src/modules/users/dto/create-first-admin.dto.ts` | Zod schema for first-admin registration. |
|
|
| `backend/src/modules/setup/setup.module.ts` | Wires `SetupController` + `SetupService` (dedicated first-admin bootstrap flow). |
|
|
| `backend/src/modules/setup/setup.controller.ts` | `POST /api/v1/setup/create-admin` (returns 404 once an admin exists). |
|
|
| `backend/src/modules/setup/setup.service.ts` | Hashes password (Argon2id), runs the create inside a transaction, mints session via `AuthService.createSession`. |
|
|
| `backend/src/modules/setup/dto/create-admin.dto.ts` | Zod schema with `password === passwordConfirm` refine. |
|
|
| `backend/src/modules/admin/admin.module.ts` | Wires `AdminController` + `AdminService`. |
|
|
| `backend/src/modules/admin/admin.controller.ts` | `/api/v1/admin/users[/{id}]`. |
|
|
| `backend/src/modules/admin/admin.service.ts` | list / create / update role / delete user with last-admin guard. |
|
|
| `backend/src/modules/admin/dto/admin.dto.ts` | Zod schemas for admin endpoints. |
|
|
| `backend/src/modules/system/system.module.ts` | Wires `SystemController` + `SystemService` + status + hub services. |
|
|
| `backend/src/modules/system/system.controller.ts` | `/api/v1/{bootstrap,event/status}` + SSE `/event/stream`, `/scoreboard/stream`. |
|
|
| `backend/src/modules/system/system.service.ts` | Builds the public bootstrap payload from settings + theme + admin count. |
|
|
| `backend/src/modules/uploads/uploads.module.ts` | Wires `UploadsController`. |
|
|
| `backend/src/modules/uploads/uploads.controller.ts` | `/api/v1/uploads/{category-icon,challenge-file}`. |
|
|
| `backend/src/modules/blog/blog.module.ts` | Wires `BlogController` + `BlogService` (registers `BlogPostEntity`). |
|
|
| `backend/src/modules/blog/blog.controller.ts` | `GET /api/v1/blog/posts` (public). |
|
|
| `backend/src/modules/blog/blog.service.ts` | `listPublished()` returns published posts ordered by `publishedAt DESC`. |
|
|
| `backend/src/modules/blog/dto/blog.dto.ts` | Zod schemas `PublicBlogPostSchema` + `PublicBlogListSchema`. |
|
|
| `backend/src/modules/settings/settings.module.ts` | `SettingsService` (get/set/getAll over the `setting` table). |
|
|
| `backend/src/frontend/frontend.module.ts` | Wires SPA fallback + uploads static middleware. |
|
|
| `backend/src/frontend/spa.controller.ts` | `SpaFallbackMiddleware` (returns `index.html` for client routes). |
|
|
| `backend/src/frontend/uploads-static.middleware.ts` | Mounts `/uploads` static helper. |
|
|
|
|
## Themes
|
|
|
|
| File | Responsibility |
|
|
|----------------------------------------------|-------------------------------------------------------------|
|
|
| `backend/themes/01-classic.json` | `classic` theme tokens. |
|
|
| `backend/themes/02-midnight.json` … `10-monochrome.json` | The other 9 canonical themes. |
|
|
|
|
# Frontend
|
|
|
|
| File | Responsibility |
|
|
|-----------------------------------------------------|--------------------------------------------------------------------------------|
|
|
| `frontend/src/main.ts` | Bootstraps the standalone Angular app + registers interceptors. |
|
|
| `frontend/src/index.html` | Root HTML shell. |
|
|
| `frontend/src/styles.css` | Global styles consuming theme CSS custom properties. |
|
|
| `frontend/src/app/app.component.ts` | Root component; triggers bootstrap then `AuthService.restoreSession()` on init. |
|
|
| `frontend/src/app/app.routes.ts` | Angular route table (declares `/` shell with `adminGuard`-gated `/admin` child). |
|
|
| `frontend/src/app/core/services/auth.service.ts` | Signal store for access token + current user; persists to `sessionStorage`, exposes `restoreSession()`, `waitUntilHydrated()`, `login()`, `register()` (both with `ensureCsrf()` + discriminated `LoginResult`/`RegisterResult`), `setSession()`. |
|
|
| `frontend/src/app/core/services/auth.session-storage.ts` | Pure `sessionStorage` helpers (`readStoredSession`, `writeStoredSession`, `clearStoredSession`) under key `hipctf.auth.v1`. |
|
|
| `frontend/src/app/core/services/bootstrap.service.ts` | Fetches `/api/v1/bootstrap`, applies theme tokens to CSS; `load()` / `ready()` deduplicate the in-flight fetch. |
|
|
| `frontend/src/app/core/services/admin.service.ts` | `GET /api/v1/admin/users` returning `AdminUser[]`. |
|
|
| `frontend/src/app/core/services/markdown.service.ts` | Thin Angular `MarkdownService.render(md): string` that forwards to `renderMarkdownToHtml`. The DOMPurify sanitization happens inside `renderMarkdownToHtml` so Angular's `[innerHTML]` binding receives a sanitized plain string — no `DomSanitizer.bypassSecurityTrustHtml` wrapper is required. |
|
|
| `frontend/src/app/core/services/markdown.pure.ts` | Pure `renderMarkdownToHtml` helper using `marked` + `DOMPurify` (kept in its own file so it can be unit-tested without Angular's ESM-only runtime and so the sanitization boundary is shared between production and tests). |
|
|
| `frontend/src/app/core/guards/auth.guard.ts` | Async `CanActivateFn`; awaits bootstrap + auth hydration, delegates to `decideAuthRedirect`. |
|
|
| `frontend/src/app/core/guards/auth.guard.decision.ts` | Pure decision function for the auth guard (returns `true` or a redirect `UrlTree`). |
|
|
| `frontend/src/app/core/guards/admin.guard.ts` | Async `CanActivateFn` for admin-only routes; awaits bootstrap + auth hydration, delegates to `decideAdminGuard`. |
|
|
| `frontend/src/app/core/guards/admin.guard.decision.ts` | Pure decision function for the admin guard (returns `allow` / `redirect`). |
|
|
| `frontend/src/app/core/guards/landing.guard.ts` | Async `CanActivateFn` for `/login`; awaits bootstrap + auth hydration, then delegates to the pure `decideLandingGuard`. |
|
|
| `frontend/src/app/core/guards/landing.guard.decision.ts` | Pure decision: returns `true` to render the landing page, or `UrlTree` to `/bootstrap` (not initialized) or `/` (already authenticated). |
|
|
| `frontend/src/app/core/interceptors/auth.interceptor.ts` | Attaches Bearer header. |
|
|
| `frontend/src/app/core/interceptors/csrf.interceptor.ts` | Attaches `X-CSRF-Token` on unsafe methods. |
|
|
| `frontend/src/app/features/landing/landing.component.{ts,html,css}` | Public landing page (logo, page title, rendered `welcomeMarkdown`, login button, blog list) + modal containing the login and registration forms (toggled by the same `mode` signal). The template binds the welcome card via `[innerHTML]="welcomeHtml()"` (the computed signal **invoked**); binding the raw `welcomeHtml` signal object would render the runtime helper source — see `tests/frontend/landing-welcome.spec.ts`. |
|
|
| `frontend/src/app/features/landing/landing.service.ts` | Fetches `GET /api/v1/blog/posts`, exposes `posts`/`loading`/`error` signals, `refresh()`. |
|
|
| `frontend/src/app/features/landing/login-modal.service.ts` | Pure `buildLoginFailureMessage` helper that maps `{code,message}` into user-facing copy (handles `INVALID_CREDENTIALS`, `RATE_LIMITED`, `CSRF_INVALID`, `USERNAME_TAKEN`, `WEAK_PASSWORD`, `REGISTRATIONS_DISABLED`, `VALIDATION_FAILED`). |
|
|
| `frontend/src/app/features/admin/admin-users.component.ts` | Admin-only user list (signals: `loading`, `error`, `users`). |
|
|
| `frontend/src/app/features/setup/setup-create-admin.component.ts` | First-admin modal overlay (non-dismissible; typed reactive form). |
|
|
| `frontend/src/app/features/setup/setup-create-admin.service.ts` | POSTs to `/api/v1/setup/create-admin` and tags the result with the error code. |
|
|
| `frontend/src/app/features/setup/setup-create-admin.validators.ts` | Standalone `passwordMatchValidator` group-level reactive form validator. |
|
|
| `frontend/src/app/features/setup/setup-create-admin.field-errors.ts` | Pure `usernameError` / `passwordError` / `confirmError` helpers that turn reactive-form state into the inline validation messages rendered next to each input. |
|
|
| `frontend/src/app/features/home/home.component.ts` | Authenticated shell: header + conditional admin nav + `<router-outlet>`. |
|
|
| `frontend/src/app/features/home/home.shell.ts` | Pure `shouldShowAdminNav({isAuthenticated, role})` predicate (unit-tested). |
|
|
|
|
# Tests
|
|
|
|
| File | Responsibility |
|
|
|------------------------------------------------|--------------------------------------------------------------------------------|
|
|
| `tests/backend/*.spec.ts` (18 suites) | Jest tests for backend modules, CSRF, OpenAPI 3.1, migrations, rate limits. |
|
|
| `tests/frontend/theme.spec.ts` | Jest test for theme token application. |
|
|
| `tests/frontend/admin-shell.spec.ts` | Unit tests for `shouldShowAdminNav` predicate. |
|
|
| `tests/frontend/admin-navigation.spec.ts` | Tests for admin guard decision + nav-link rendering. |
|
|
| `tests/frontend/auth-restore.spec.ts` | Round-trips `auth.session-storage` helpers + refresh success/failure paths. |
|
|
| `tests/frontend/setup-create-admin.spec.ts` | Pure-Jest tests for `passwordMatchValidator` and the three field-error helpers (`usernameError`, `passwordError`, `confirmError`). |
|
|
| `tests/frontend/guard-bootstrap-race.spec.ts` | Pins `decideAuthRedirect` so a refresh on a deep link never flashes `/bootstrap` or `/login` while auth is hydrating. |
|
|
| `tests/frontend/landing-guard.spec.ts` | Pins `decideLandingGuard` for the not-initialized / authenticated / anonymous branches. |
|
|
| `tests/frontend/landing-markdown.spec.ts` | Pins `renderMarkdownToHtml` (sanitization of raw `<script>` payloads, script URL schemes, etc.). |
|
|
| `tests/frontend/landing-welcome.spec.ts` | Regression test for the landing welcome binding — asserts the bootstrap payload's `welcomeMarkdown` produces the expected sanitized HTML (h1 + paragraph) and never the Angular runtime helper source string, including for null/empty/hostile payloads. |
|
|
| `tests/frontend/landing-modal.spec.ts` | Pins `buildLoginFailureMessage` (`INVALID_CREDENTIALS`, `RATE_LIMITED` with retry-seconds extraction, `CSRF_INVALID`, `USERNAME_TAKEN`, `WEAK_PASSWORD`, `REGISTRATIONS_DISABLED`, `VALIDATION_FAILED`, default fallback). |
|
|
| `tests/backend/auth-register.spec.ts` | Backend integration tests for `POST /api/v1/auth/register` (happy path, disabled flag, duplicate username, weak password, rate limit). |
|
|
| `tests/backend/blog-public.spec.ts` | Backend integration tests for `GET /api/v1/blog/posts` (only published rows, descending order). |
|
|
| `tests/backend/csrf-protected-routes.spec.ts` | Pins CSRF enforcement on the formerly-skipped `/api/v1/auth/login` route. |
|
|
| `tests/backend/csrf-client.ts` | Test helper for CSRF flow. |
|
|
| `tests/backend/db-helper.ts` | Test helper for spinning up an isolated DB. |
|
|
|
|
# See also
|
|
|
|
- [System Overview](/architecture/overview.md)
|
|
- [Backend Module Map](/architecture/backend-modules.md)
|
|
- [Frontend Structure](/architecture/frontend-structure.md)
|