fix(managed): bootstrap hands the managed routes to the boot gate, so the shared kernel imports no domain

This commit is contained in:
Maurice
2026-11-09 00:09:21 +00:00
parent b3113e66b9
commit fede671f3b
3 changed files with 7 additions and 6 deletions
+4 -2
View File
@@ -6,9 +6,10 @@ import { AppModule } from './nest/app.module';
import { apiDocsEnabled } from './nest/common/api-docs.kill-switch';
import { validateBodyContracts } from './nest/common/validate-body-contracts';
import { validateManagedRoutes } from './nest/common/validate-managed-routes';
import { validateRouteGuards } from './nest/common/validate-route-guards';
import { PUBLIC_ROUTE_ALLOW_LIST, validateRouteGuards } from './nest/common/validate-route-guards';
import { DatabaseLifecycle } from './nest/database/database-lifecycle.service';
import { withRequestContext } from './nest/database/request-context';
import { MANAGED_PUBLIC_ROUTES } from './nest/managed/managed-ext.module';
import { setupApiDocs } from './nest/platform/api-docs';
import { MCP_METADATA_MIDDLEWARE } from './nest/platform/mcp-metadata.middleware';
import { applyPlatformUploads, applyPlatformStatic } from './nest/platform/platform.routes';
@@ -247,7 +248,8 @@ export async function buildApp(): Promise<INestApplication> {
// Fail closed on the anonymous surface too: a route that answers without a
// session must carry @Public() with a reason AND be on the reviewed list.
// Default-deny protects what exists; this is what keeps the exemptions honest.
validateRouteGuards(app);
// The managed attachment point declares its own anonymous routes; empty in this repository.
validateRouteGuards(app, [...PUBLIC_ROUTE_ALLOW_LIST, ...MANAGED_PUBLIC_ROUTES]);
// And on the other direction of the same question: a route that a centrally
// administered install withholds from its own admin must say why, and be on a
// list somebody reviewed. Runs in every e2e harness because they share this
@@ -2,7 +2,6 @@ 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';
@@ -182,7 +181,7 @@ export const ANONYMOUS_GUARDED_ROUTE_ALLOW_LIST: string[] = [
*/
export function validateRouteGuards(
app: INestApplication,
allowList: string[] = [...PUBLIC_ROUTE_ALLOW_LIST, ...MANAGED_PUBLIC_ROUTES],
allowList: string[] = PUBLIC_ROUTE_ALLOW_LIST,
anonymousGuardedAllowList: string[] = ANONYMOUS_GUARDED_ROUTE_ALLOW_LIST,
): void {
const entries = collectRouteGuards(app);
@@ -26,8 +26,8 @@ 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
* Empty here, like the module. bootstrap.ts adds them to the allow-list of the
* boot gate (validate-route-guards.ts), 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.
*/