Files
TREK/server/tests/unit/nest/managed.guard.test.ts
Maurice 724c88c201 style: format server and shared with prettier
A mechanical prettier --write over server/src, server/tests, server/scripts
and shared/src with the workspaces' .prettierrc; nothing but layout and
import order changes, and every file keeps the same set of imports. shared
is formatted throughout and its format baseline is empty. The server
baseline keeps the 35 files that Prettier would grow past their lint:size
limit (they need a split first, which is not a formatting change), and the
generated entity files stay as their generator writes them.
2026-10-10 21:23:37 +02:00

90 lines
3.5 KiB
TypeScript

/**
* ManagedGuard — refuses the routes a centrally administered instance does not
* hand to its own admin.
*
* Two properties carry the design and both are pinned below: it is inert unless
* the route was marked (MANAGED-GUARD-002), so a self-hosted install cannot
* notice it exists, and it keys on a decorator rather than a path list
* (MANAGED-GUARD-005). The path lists MfaPolicyGuard replaced are the reason for
* the second one: they stopped being maintained, and every endpoint added after
* they were written silently fell on the wrong side.
*/
import type { RuntimeEnvService } from '../../../src/nest/app-config/runtime-env.service';
import { MANAGED_FORBIDDEN, MANAGED_FORBIDDEN_ERROR } from '../../../src/nest/common/managed';
import { ManagedGuard } from '../../../src/nest/common/managed.guard';
import { HttpException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { describe, it, expect, vi } from 'vitest';
function makeGuard(managed: boolean, marked: boolean, enforcedInHandler = false) {
const getAllAndOverride = vi.fn((key: string) =>
key === MANAGED_FORBIDDEN && marked ? { reason: 'the operator holds this', enforcedInHandler } : undefined,
);
const guard = new ManagedGuard(
{ isManaged: () => managed } as unknown as RuntimeEnvService,
{ getAllAndOverride } as unknown as Reflector,
);
return { guard, getAllAndOverride };
}
const ctx = {
getHandler: () => function handler() {},
getClass: () => class Controller {},
} as never;
const thrown = (run: () => unknown) => {
try {
run();
} catch (err) {
return err as HttpException;
}
return undefined;
};
describe('ManagedGuard', () => {
it('MANAGED-GUARD-001: lets a marked route through on a self-hosted install', () => {
const { guard } = makeGuard(false, true);
expect(guard.canActivate(ctx)).toBe(true);
});
it('MANAGED-GUARD-002: lets an unmarked route through on a managed install', () => {
const { guard } = makeGuard(true, false);
expect(guard.canActivate(ctx)).toBe(true);
});
it('MANAGED-GUARD-003: refuses a marked route on a managed install', () => {
const { guard } = makeGuard(true, true);
const err = thrown(() => guard.canActivate(ctx));
expect(err).toBeInstanceOf(HttpException);
expect(err?.getStatus()).toBe(403);
expect(err?.getResponse()).toEqual(MANAGED_FORBIDDEN_ERROR);
});
it('MANAGED-GUARD-004: does not read metadata at all while the mode is off', () => {
// The cheap check comes first because this guard runs on every request of
// every install, and all but a handful of them are self-hosted.
const { guard, getAllAndOverride } = makeGuard(false, true);
guard.canActivate(ctx);
expect(getAllAndOverride).not.toHaveBeenCalled();
});
it('MANAGED-GUARD-006: lets a handler-enforced marking through, so multipart still parses', () => {
// The route is marked and the mode is on, and it still passes: a guard that
// threw here would leave the upload body unread and the client would see an
// ECONNRESET instead of the 403 (PROFILE-015). The handler does the refusing.
const { guard } = makeGuard(true, true, true);
expect(guard.canActivate(ctx)).toBe(true);
});
it('MANAGED-GUARD-005: asks for the decorator on handler and controller, not for a path', () => {
const { guard, getAllAndOverride } = makeGuard(true, false);
guard.canActivate(ctx);
expect(getAllAndOverride).toHaveBeenCalledWith(MANAGED_FORBIDDEN, [expect.any(Function), expect.any(Function)]);
});
});