feat(managed): the managed attachment point declares the routes it serves without a session, and the boot gate allows exactly those

Empty in this repository, as the module itself. An install that replaces the
module adds its anonymous routes in the same file, and the gate still fails on a
route missing there or an entry that went stale.
This commit is contained in:
Maurice
2026-11-08 23:33:52 +00:00
parent c0b39abe18
commit 286b0b09ec
3 changed files with 18 additions and 2 deletions
@@ -2,6 +2,7 @@ import { CookieAuthGuard } from '../auth-core/cookie-auth.guard';
import { JwtAuthGuard } from '../auth-core/jwt-auth.guard';
import { OptionalJwtGuard } from '../auth-core/optional-jwt.guard';
import { IS_PUBLIC, OPTIONAL_AUTH } from '../auth-core/public.decorator';
import { MANAGED_PUBLIC_ROUTES } from '../managed/managed-ext.module';
import { ApiTokenGuard } from '../public-api/api-token.guard';
import type { INestApplication } from '@nestjs/common';
import { METHOD_METADATA, PATH_METADATA, GUARDS_METADATA } from '@nestjs/common/constants';
@@ -181,7 +182,7 @@ export const ANONYMOUS_GUARDED_ROUTE_ALLOW_LIST: string[] = [
*/
export function validateRouteGuards(
app: INestApplication,
allowList: string[] = PUBLIC_ROUTE_ALLOW_LIST,
allowList: string[] = [...PUBLIC_ROUTE_ALLOW_LIST, ...MANAGED_PUBLIC_ROUTES],
anonymousGuardedAllowList: string[] = ANONYMOUS_GUARDED_ROUTE_ALLOW_LIST,
): void {
const entries = collectRouteGuards(app);
@@ -22,3 +22,13 @@ import { Module } from '@nestjs/common';
*/
@Module({})
export class ManagedExtModule {}
/**
* Routes of this module that answer without a session, as `Controller.handler`.
*
* Empty here, like the module. The boot gate (validate-route-guards.ts) adds
* them to its allow-list, so an install that replaces this file declares its
* anonymous surface in the same place it adds it, and the gate still fails on a
* route that is missing here or an entry that is stale.
*/
export const MANAGED_PUBLIC_ROUTES: readonly string[] = [];
+6 -1
View File
@@ -7,7 +7,7 @@
* carries none of them. A stray controller or provider slipping in would be
* invisible in review and obvious only to whoever it shipped to.
*/
import { ManagedExtModule } from '../../../src/nest/managed/managed-ext.module';
import { MANAGED_PUBLIC_ROUTES, ManagedExtModule } from '../../../src/nest/managed/managed-ext.module';
import { MODULE_METADATA } from '@nestjs/common/constants';
import { Test } from '@nestjs/testing';
@@ -25,6 +25,11 @@ describe('ManagedExtModule', () => {
}).toEqual({ controllers: [], providers: [], imports: [], exports: [] });
});
it('MANAGED-EXT-003: declares no route that answers without a session', () => {
// The boot gate adds these to its allow-list; the public build adds nothing.
expect(MANAGED_PUBLIC_ROUTES).toEqual([]);
});
it('MANAGED-EXT-002: compiles as a module, so app.module can import it unconditionally', async () => {
// Unconditionally on purpose: a conditional import would tie the module graph
// to an env var, and the graph is built once per app while TREK_MANAGED is