dorfteich/apps/api/src/public/read-content.controller.ts
Claude Fable 5 d5b895ada2
Some checks failed
CI / Lint, typecheck, test (pull_request) Failing after 4m20s
CI / Auth e2e pack (pull_request) Has been skipped
CI / Import/export fidelity gate (pull_request) Has been skipped
CI / Build container images (pull_request) Has been skipped
#135 Fix: /read-Route deklariert Zugriffsregel explizit (@AuthenticatedOnly)
route-permissions.e2e.db.test.ts (#52) verlangt, dass JEDE Route ihre
Zugriffsregel explizit deklariert (PERMISSION_KEY, @Public oder
SiteAdminGuard). Der neue GET /read/:pond/:slug hatte keinen Decorator
(verließ sich auf den Default-Guard) → Coverage-Test rot in CI.
@AuthenticatedOnly() ergänzt (Session erforderlich; per-Page-Recht prüft
weiterhin der Service via resolve→canAccessPage→404).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0155v2aT8AG1kZDQEZiCLBWC
2026-07-19 06:01:45 +02:00

32 lines
1.4 KiB
TypeScript

import { Controller, Get, Param, Req } from '@nestjs/common';
import { AuthedRequest } from '../auth/auth.guard';
import { AuthenticatedOnly } from '../permissions/permission.decorators';
import { PublicPageContent, PublicService } from './public.service';
/**
* Authenticated read-rendering (issue #135). Returns a page's rendered read
* HTML — plugin fallbacks, expanded page embeds, resolved media — for a
* signed-in viewer with read access. The transclusion node view fetches this to
* show an embedded page's content inline in the authenticated read view, which
* must also work for pages that are not public and so are out of reach of the
* `/public` endpoints. NOT `@Public`: the auth guard requires a session and the
* service enforces read permission (a non-readable page 404s, no leak).
*/
@Controller('read')
export class ReadContentController {
constructor(private readonly publicPages: PublicService) {}
// Session required (explicit access rule, issue #52); per-page read
// permission is enforced in the service (resolve → canAccessPage → 404).
@Get(':pondSlug/:pageSlug')
@AuthenticatedOnly()
async content(
@Param('pondSlug') pondSlug: string,
@Param('pageSlug') pageSlug: string,
@Req() request: AuthedRequest,
): Promise<PublicPageContent> {
return this.publicPages.content(request.user ?? null, pondSlug, pageSlug);
}
}