diff --git a/README.md b/README.md index 3e81099..9d80f08 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,7 @@ app.run(); // Open http://localhost:3030/api/docs | `enabled` | `true` | Convenience flag—skip calling `registerRoutes` if you want to hide docs. | | `path` | `'/api/docs'` | Mount path for Swagger UI; value is used as-is. | | `swaggerJsonPath` | `undefined` | Path relative to mount path where OpenAPI schema is served as JSON. When set, Swagger UI loads the schema from this endpoint instead of embedding it directly. | +| `authPolicy` | `AuthPolicy.disabled` | Controls authentication for the Swagger UI page itself. | Usage example: diff --git a/src/openapi-registry.ts b/src/openapi-registry.ts index a34c09d..8ebcb93 100644 --- a/src/openapi-registry.ts +++ b/src/openapi-registry.ts @@ -403,6 +403,7 @@ export function createOpenApiRegistry(config: OpenApiRegistryConfig) { return { ...routes, [`MOUNT ${mountPath}`]: { + authPolicy: config.authPolicy ?? AuthPolicy.disabled, handler: ({router}: Parameters[0]) => { const schema = getOpenApiSchema(); diff --git a/src/tests/openapi-registry.test.ts b/src/tests/openapi-registry.test.ts index b73b7fb..81d21a1 100644 --- a/src/tests/openapi-registry.test.ts +++ b/src/tests/openapi-registry.test.ts @@ -1,6 +1,12 @@ import {createOpenApiRegistry} from '../openapi-registry'; import {apiKeyAuth, bearerAuth} from '../security-schemas'; -import {AppRoutes, AuthPolicy, RouteContract, withContract} from '@gravity-ui/expresskit'; +import { + AppMountDescription, + AppRoutes, + AuthPolicy, + RouteContract, + withContract, +} from '@gravity-ui/expresskit'; import {NodeKit} from '@gravity-ui/nodekit'; import {z} from 'zod'; @@ -669,6 +675,33 @@ describe('openapi-registry', () => { const registeredRoutes = registerRoutes(routes, nodekit); expect(registeredRoutes).toHaveProperty('MOUNT /api/docs'); + const mountRoute = registeredRoutes['MOUNT /api/docs'] as AppMountDescription; + expect(mountRoute).toBeDefined(); + expect(mountRoute.authPolicy).toBe(AuthPolicy.disabled); + }); + + it('should apply configured authPolicy to MOUNT route', () => { + const {registerRoutes} = createOpenApiRegistry({ + title: 'Test API', + authPolicy: AuthPolicy.required, + }); + + const routes = { + 'GET /test': { + handler: withContract({ + request: {}, + response: {content: {200: z.object({})}}, + })(async (_req, res) => { + res.sendTyped(200, {}); + }), + }, + }; + + const registeredRoutes = registerRoutes(routes, nodekit); + const mountRoute = registeredRoutes['MOUNT /api/docs'] as AppMountDescription; + + expect(mountRoute).toBeDefined(); + expect(mountRoute.authPolicy).toBe(AuthPolicy.required); }); it('should handle routes with tags and description', () => { diff --git a/src/types.ts b/src/types.ts index f91473f..1f5ddf6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,5 @@ import type {SwaggerUiOptions} from 'swagger-ui-express'; -import type {AppRouteDescription} from '@gravity-ui/expresskit'; +import type {AppRouteDescription, AuthPolicy} from '@gravity-ui/expresskit'; // OpenAPI Security Scheme Object types export interface SecuritySchemeObject { @@ -64,6 +64,7 @@ export interface OpenApiRegistryConfig { }[]; swaggerUi?: SwaggerUiOptions; swaggerJsonPath?: string; + authPolicy?: AuthPolicy; transformOperation?: ( operation: OpenApiOperation, context: {