Files
HIPCTF2/.kilo/plans/849.md
T

8.6 KiB
Raw Blame History

Implementation Plan: Landing Page and Login/Register Modal 1.00

1. Architectural Reconnaissance

  • Status: The landing page, login/register modal, bootstrap payload flow, and Markdown helper are present, but Job 849 is not fully implemented: the reported runtime-function string proves the welcome binding is not receiving the intended rendered HTML at runtime. Existing source currently derives welcomeHtml in frontend/src/app/features/landing/landing.component.ts:46 and binds [innerHTML]="welcomeHtml" in frontend/src/app/features/landing/landing.component.html:9; this integration needs to be corrected and covered by a focused component-level regression test.
  • Codebase style & conventions: Node.js npm workspace monorepo; Angular 17 standalone components with signals, OnPush, Angular control-flow blocks, reactive forms, and inject() services. The landing container owns bootstrap-derived state and delegates blog HTTP calls to LandingService.
  • Data Layer: No database or schema change is required. Backend SystemService.bootstrap exposes the persisted welcomeMarkdown setting, and BootstrapService stores it in its signal payload. Blog data is separately fetched from GET /api/v1/blog/posts.
  • Markdown and security path: markdown.pure.ts:9-11 converts Markdown using marked.parse and sanitizes with DOMPurify; MarkdownService.render wraps that output for Angular HTML binding. Preserve sanitization and ensure the template receives the computed signal value, not a signal/function object. Avoid introducing new CSP inline handlers or unsafe dynamic execution; the existing CSP console error should be investigated only insofar as it is caused by the rendering integration, without weakening CSP.
  • Test Framework & Structure: Root Jest 29 multi-project configuration in tests/jest.config.js; frontend tests use ts-jest and jsdom, live exclusively under tests/frontend/, and run from the root with npm test or the focused npm run test:frontend command. Existing landing-markdown.spec.ts tests the pure renderer only; no current test mounts LandingComponent or verifies its [innerHTML] output.
  • Required Tools & Dependencies: No new runtime or system dependency is expected. Existing @angular/core, @angular/platform-browser, marked, dompurify, Jest/jsdom, and ts-jest are sufficient. The implementer should use the existing setup.sh (npm ci/fallback install plus Angular and Nest builds); do not add a package solely for this fix unless repository inspection during implementation demonstrates an unavoidable Angular testing requirement.

2. Impacted Files

  • To Modify:
    • frontend/src/app/features/landing/landing.component.ts — correct the component-side value passed to the HTML binding while retaining bootstrap signal reactivity and the existing MarkdownService sanitization boundary.
    • frontend/src/app/features/landing/landing.component.html — update the binding expression if needed so Angular unwraps/consumes the computed signal value correctly and never renders the function object/source.
    • frontend/src/app/core/services/markdown.service.ts — only if needed by the confirmed root cause; keep the public render contract and sanitization behavior stable rather than bypassing Angular security.
    • tests/frontend/landing-markdown.spec.ts — extend with the smallest regression coverage if a pure helper contract is changed; retain the existing XSS/link sanitization assertions.
    • tests/frontend/landing.component.spec.ts — add a dedicated focused component test under the existing dedicated frontend test folder to mount the standalone landing component and verify the rendered welcome card.
  • To Create:
    • tests/frontend/landing.component.spec.ts — focused success-path and key safety/error regression tests, unless the implementer chooses to place equivalent coverage in an existing landing test without expanding scope.

3. Proposed Changes

Explain the exact implementation logic step-by-step:

  1. Database / Schema Migration: No migration. Confirm the existing bootstrap response contract remains welcomeMarkdown: string; use the value already loaded by BootstrapService.payload() and preserve the backend setting/default behavior.
  2. Backend Logic & APIs: No backend route or service change. Continue relying on GET /api/v1/bootstrap, which already returns the welcome Markdown, and do not alter /api/v1/blog/posts, authentication routes, login/register modal behavior, or CSP headers unless root-cause investigation proves the CSP message is independently generated by an existing Angular event-handler configuration.
  3. Frontend UI Integration:
    1. Trace Angular template expression semantics for computed() values and verify whether the current [innerHTML]="welcomeHtml" passes the computed signal object rather than its value in this Angular 17 setup. The likely correction is to consume the signal (welcomeHtml()) in the property binding, matching the components other signal accesses (pageTitle(), logo(), landing.posts(), etc.).
    2. Keep welcomeHtml as a computed value derived from bootstrap.payload()?.welcomeMarkdown ?? '', so it updates automatically after bootstrap completes and renders an empty sanitized result when the payload is unavailable.
    3. Continue routing Markdown through MarkdownService.render and renderMarkdownToHtml; do not substitute raw interpolation, unsanitized innerHTML, eval, Function, or a security bypass around untrusted content. If the current helpers return type or sanitizer wrapper must change to make Angular accept the binding, make the narrowest compatible change and preserve DOMPurifys HTML profile.
    4. Leave the existing landing title, login button, empty blog state, and modal forms unchanged except where template compilation requires a minimal adjacent adjustment. The expected welcome DOM for the supplied payload must contain an <h1> with Welcome and paragraph text Create the first admin to get started. rather than the Angular runtime helper source.
    5. Check the reported CSP error after the binding fix during automated verification. Do not weaken script-src-attr 'none'; if a separate source-level inline-handler issue is identified, replace it with Angular event bindings or document it as unrelated rather than adding an unsafe CSP exception.
  4. Test Strategy Integration: Add only minimal automated frontend logic tests: one component test that supplies a mock BootstrapService payload containing the jobs Markdown, renders the standalone component with minimal providers/mocks, and asserts the welcome element contains the heading and paragraph and does not contain the runtime-function text; one safety/error-focused assertion may verify empty/null Markdown produces no runtime source and that the existing pure renderer remains sanitized. Mock LandingService.refresh() and any unrelated auth/router dependencies as resolved stubs so the test does not perform HTTP, navigation, or UI/browser automation. Keep tests in tests/frontend/ and make them pass through the existing root npm test command.

4. Test Strategy

  • Target Unit Test File: tests/frontend/landing.component.spec.ts for the component/template regression; retain/update tests/frontend/landing-markdown.spec.ts only if the renderer contract is touched. No visual, screenshot, browser, network, database, or persistent /data fixture is needed.
  • Mocking Strategy: Configure the standalone component through Angular TestBed; provide a deterministic BootstrapService stub with a signal-backed payload, a LandingService stub whose refresh is a resolved promise and whose posts/loading/error signals represent the empty blog state, plus minimal AuthService, Router, and MarkdownService stubs or real pure Markdown service as appropriate. If HTTP providers are required by transitive dependencies, use Angulars testing providers rather than manual HTTP mocks and ensure no request is left outstanding. Assert through stable data-testid attributes or a small harness/query abstraction, not CSS classes. Verify both the expected sanitized HTML content and absence of the Angular runtime source string.
  • Verification commands for the implementer: Run the focused frontend test, then root npm test, frontend production build, lint, and typecheck using the repositorys available scripts/configuration. Since no lint/typecheck scripts are present in the inspected root or frontend package.json, inspect any project tooling before implementation; if no commands exist, record that limitation rather than inventing dependencies. setup.sh already installs dependencies and builds both packages, so no update is planned.