Reputation: 15413
I am trying to add the following configuration to my swagger.config.ts
:
const swaggerUiOptions = {
explorer: true,
swaggerOptions: {
authAction: {
JWT: {
name: 'JWT',
schema: {
type: 'apiKey',
in: 'header',
name: 'Authorization',
description: ''
},
value: 'Bearer <JWT token here>'
}
}
}
};
Then below this, I have:
app.use('/api-docs', swaggerUi.serve, swaggerUI.setup(swaggerSpec, swaggerUiOptions));
However, the Authorize button that I am expecting to see does not appear in the UI. I am not sure if there is something in the whole configuration file that may be clobbering what I added, since I did not write the whole thing, here it is:
import express from 'express';
import { Model } from "mongoose";
import swaggerJsdoc from "swagger-jsdoc";
import swaggerUi from "swagger-ui-express";
import m2s from 'mongoose-to-swagger';
import { readFileSync } from 'fs';
class SwaggerEndPointInformationDto {
readonly httpMethod: string
readonly httpPath: string
constructor(httpMethod: string, httpPath: string) {
this.httpMethod = httpMethod;
this.httpPath = httpPath
}
}
class SwaggerConfig {
// private readonly app: express.Application;
private built = false;
private static instance: SwaggerConfig;
private models = Array<Model<any>>();
public static getInstance() {
if (!this.instance) {
this.instance = new SwaggerConfig();
}
return this.instance;
}
registerModel(model: Model<any>) {
this.checkIsNotBuilt();
this.models.push(model);
}
// addPathAndMethod()
registerSwaggerPage(app: express.Application, listeners: [(entry: SwaggerEndPointInformationDto) => void]) {
// registerSwaggerPage(app: express.Application) {
this.built = true;
const packageJson = JSON.parse(readFileSync('./package.json').toString());
const swaggerOptions = {
definition: {
openapi: '3.0.0',
info: {
title: packageJson.name,
version: packageJson.version,
}
},
apis: [
'./dist/**/*.js',
],
};
// const swaggerSpec: {paths: never;} = swaggerJsdoc(swaggerOptions);
// @ts-ignore
const swaggerSpec: { paths: string; } = swaggerJsdoc(swaggerOptions);
const swaggerUiOptions = {
explorer: true,
swaggerOptions: {
authActions: {
JWT: {
name: 'JWT',
schema: {
type: 'apiKey',
in: 'header',
name: 'Authorization',
description: ''
},
value: 'Bearer <JWT Token here>'
}
}
}
};
// add to components.schemas
this.models.forEach(model => {
const swaggerModel = m2s(model)
// @ts-ignore
swaggerSpec.components.schemas.push(swaggerModel);
});
// add routes
app._router.stack.filter((e: { route: never; }) => e.route).forEach((element: any) => {
console.log(element)
// if (element?.route?.path?.startsWith('/')) {
// const httpPath: string = element.route.path
// // @ts-ignore
// if (!swaggerSpec.paths[httpPath]) {
// // @ts-ignore
// swaggerSpec.paths[httpPath] = {}
// }
// // @ts-ignore
// const pathInfo = swaggerSpec.paths[httpPath];
// for (const e in Object.keys(element.route.methods)) {
// const httpMethod = Object.keys(element.route.methods)[e]
// // console.log(element.route.methods[httpMethod])
// if (element.route.methods[httpMethod]) {
// if(!pathInfo[httpMethod]) {
// // @ts-ignore
// pathInfo[httpMethod] = {
// description: "This is a description",
// content: {
// // "application/json": {
// // "schema":
// // }
// }
// }
// }
// // const eventDto = new SwaggerEndPointInformationDto(httpMethod, httpPath)
// // listeners.forEach((fn: (entry: SwaggerEndPointInformationDto) => void) => fn(eventDto))
// }
// }
// }
});
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec, swaggerUiOptions));
console.log(JSON.stringify(swaggerSpec, null, 2))
//app._router.stack.filter(e => e.route)
}
private checkIsNotBuilt() {
if (this.built) {
throw new Error('Swagger Configuration is already built.')
}
}
public static swaggerMethod2 = (description: string) => (target: Object, propertyKey: string) => {
// Object.defineProperty(target, propertyKey, { description });
console.log(description);
console.log(Object);
console.log(propertyKey);
};
}
// const swaggerMethod = (description: string) => (target: Object, propertyKey: string) => {
// console.log(description);
// console.log(Object);
// console.log(propertyKey);
// };
/*
const swaggerMethod22 = (description: string) => (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
// console.log(key);
// Object.defineProperty(target, propertyKey, { description });
console.log("*********************************");
console.log(description);
console.log(Object);
console.log(propertyKey);
return descriptor;
};
*/
function swaggerMethod(description: string) {
return function (
target: Object,
key: string | symbol,
descriptor: PropertyDescriptor
) {
return descriptor;
};
}
export { SwaggerConfig, swaggerMethod, SwaggerEndPointInformationDto };
When I attempt to refactor to:
const swaggerSpec = {
swaggerDefinition: {}
}
I get the following complaint from TypeScript:
A class member cannot have the 'const' keyword
Also, when applying:
* security
* - Authorization: []
Where would that go in this yaml file:
/**
* @openapi
* /api/v2/patients:
* post:
* tags: [Patients]
* description: to create a new patient.
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* $ref: '#/components/schemas/NewPatientDto'
* responses:
* 201:
* description: Creates a new patient.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/NewUserDto'
* 415:
* description: Only 'application/json'. incoming content is supported..
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/BaseError415Dto'
* 500:
* description: A server error. The returned object contains the exact nature of the error.
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/BaseError500Dto'
*/
this.app.post(p().api.v2.patients.$url, [
authMiddleware.verifyJWT,
patientsMiddleware.createPatientContext,
patientsMiddleware.validateAndBuildNewPatientDto,
patientsMiddleware.validateSamePatientDoesNotExist,
patientsController.createPatient
])
Upvotes: 2
Views: 3137
Reputation: 36104
I am not sure in your implementation, but as per openapi and my implementation this is working for me,
You can add authorization in definition > components in securitySchemes,
const swaggerSpec = {
definition: {
openapi: '3.0.3',
info: {
title: packageJson.name,
version: packageJson.version
},
components: {
securitySchemes: {
Authorization: {
type: "http",
scheme: "bearer",
bearerFormat: "JWT",
value: "Bearer <JWT token here>"
}
}
}
},
apis: [
'./dist/**/*.js'
]
};
As per your implementation use,
const swaggerUiOptions = {
explorer: true
};
app.use('/api-docs', swaggerUi.serve, swaggerUI.setup(swaggerSpec, swaggerUiOptions));
One more thing, in particular api's annotation pass, security key with authorization,
/**
* @openapi
* /api/v2/patients:
* post:
* security:
* - Authorization: []
* tags: [Patients]
* description: to create a new patient.
....
It looks:
Per api there is lock icon:
After Click:
Try to update openapi version at least 3.0.3!
Upvotes: 2