Skip to content

Commit

Permalink
feat(hermes): add scalar to eventually replace swagger ui (#921)
Browse files Browse the repository at this point in the history
* feat(hermes): add scalar to eventually replace swagger ui

note: it throws a build error that we can hack around, but we should find a proper fix.
also, the issue of only client id appearing is also present here

* fix(hermes): add skipLibCheck to bypass ESM issues
refactor(router): fix security schemes when client id/secret is not active
fix(router): blocked scalar routes
  • Loading branch information
kkopanidis authored Jan 30, 2024
1 parent 38d7ab0 commit b2ee37c
Show file tree
Hide file tree
Showing 10 changed files with 1,798 additions and 24 deletions.
2 changes: 2 additions & 0 deletions libraries/hermes/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"@conduitplatform/grpc-sdk": "*",
"@grpc/grpc-js": "^1.9.7",
"@grpc/proto-loader": "^0.7.6",
"@scalar/api-reference": "^1.13.2",
"@scalar/express-api-reference": "^0.2.14",
"@socket.io/redis-adapter": "^8.2.1",
"@types/object-hash": "^3.0.6",
"body-parser": "^1.20.2",
Expand Down
10 changes: 9 additions & 1 deletion libraries/hermes/src/Rest/Rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import ConduitGrpcSdk, {
import { Cookie } from '../interfaces';
import { SwaggerRouterMetadata } from '../types';
import { ConduitRoute, TypeRegistry } from '../classes';
import { merge } from 'lodash';
import { apiReference } from '@scalar/express-api-reference';

const swaggerUi = require('swagger-ui-express');

Expand Down Expand Up @@ -313,6 +313,14 @@ export class RestController extends ConduitRouter {
this._expressRouter!.get('/swagger', (req, res, next) =>
swaggerUi.setup(self._swagger!.swaggerDoc)(req, res, next),
);
this._expressRouter!.get(
'/reference',
apiReference({
spec: {
url: '/swagger.json',
},
}),
);
this._expressRouter!.get('/swagger.json', (req, res) => {
res.send(JSON.stringify(this._swagger!.swaggerDoc));
});
Expand Down
1 change: 1 addition & 0 deletions libraries/hermes/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// "incremental": true, /* Enable incremental compilation */
"target": "es2018",
"module": "commonjs",
"skipLibCheck": true,
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
Expand Down
31 changes: 18 additions & 13 deletions modules/router/src/hermes/swaggerMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ import { ConduitRoute, SwaggerRouterMetadata } from '@conduitplatform/hermes';
export const getSwaggerMetadata: () => SwaggerRouterMetadata = () => ({
urlPrefix: '',
securitySchemes: {
clientId: {
name: 'clientId',
type: 'apiKey',
in: 'header',
description: 'A security client id, retrievable through [POST] /security/client',
},
clientSecret: {
name: 'clientSecret',
type: 'apiKey',
in: 'header',
description:
'A security client secret, retrievable through [POST] /security/client',
},
...(ConfigController.getInstance().config.security.clientValidation
? {
clientId: {
name: 'clientId',
type: 'apiKey',
in: 'header',
description:
'A security client id, retrievable through [POST] /security/client',
},
clientSecret: {
name: 'clientSecret',
type: 'apiKey',
in: 'header',
description:
'A security client secret, retrievable through [POST] /security/client',
},
}
: {}),
userToken: {
type: 'http',
scheme: 'bearer',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ export class ClientValidator {

// check gql explorer and swagger access
if (
(req.url === '/graphql' || req.url.startsWith('/swagger')) &&
(req.url === '/graphql' ||
req.url.startsWith('/swagger') ||
req.url.startsWith('/reference')) &&
req.method === 'GET'
) {
// disabled swagger and gql explorer access on production
Expand Down
4 changes: 3 additions & 1 deletion modules/router/src/security/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ export default class SecurityModule {
'helmetGqlFix',
(req: Request, res: Response, next: NextFunction) => {
if (
(req.url.startsWith('/graphql') || req.url.startsWith('/swagger')) &&
(req.url.startsWith('/graphql') ||
req.url.startsWith('/swagger') ||
req.url.startsWith('/reference')) &&
req.method === 'GET'
) {
res.removeHeader('Content-Security-Policy');
Expand Down
4 changes: 3 additions & 1 deletion packages/admin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ export default class AdminModule extends IConduitAdmin {
this._router.registerMiddleware(helmet(), false);
this._router.registerMiddleware((req: Request, res: Response, next: NextFunction) => {
if (
(req.url.startsWith('/graphql') || req.url.startsWith('/swagger')) &&
(req.url.startsWith('/graphql') ||
req.url.startsWith('/swagger') ||
req.url.startsWith('/reference')) &&
req.method === 'GET'
) {
res.removeHeader('Content-Security-Policy');
Expand Down
4 changes: 3 additions & 1 deletion packages/admin/src/middleware/Admin.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ export function getAdminMiddleware(conduit: ConduitCommons) {
const graphQlCheck =
req.originalUrl.indexOf('/graphql') === 0 && req.method === 'GET';
if (
(req.originalUrl.indexOf('/swagger') === 0 || graphQlCheck) &&
(req.originalUrl.indexOf('/swagger') === 0 ||
req.originalUrl.indexOf('/reference') === 0 ||
graphQlCheck) &&
(await isDev(conduit))
) {
return next();
Expand Down
1 change: 1 addition & 0 deletions packages/admin/src/middleware/Auth.middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ async function requestExcluded(req: ConduitRequest, conduit: ConduitCommons) {
if (await isDev(conduit)) {
if (req.originalUrl.indexOf('/graphql') === 0 && req.method === 'GET') return true;
if (req.originalUrl.indexOf('/swagger') === 0) return true;
if (req.originalUrl.indexOf('/reference') === 0) return true;
}
// REST
if (excludedRestRoutes.includes(req.path)) return true;
Expand Down
Loading

0 comments on commit b2ee37c

Please sign in to comment.