Possibility to add custom middleware

This commit is contained in:
ricardo 2022-03-30 23:11:26 -04:00
parent 4066c727b6
commit b8f03b252e
4 changed files with 93 additions and 53 deletions

View file

@ -92,6 +92,7 @@
"typescript": "~4.3.5"
},
"dependencies": {
"@apidevtools/swagger-parser": "^10.0.3",
"@oclif/command": "^1.5.18",
"@oclif/errors": "^1.2.2",
"@rudderstack/rudder-sdk-node": "1.0.6",
@ -133,6 +134,7 @@
"nodemailer": "^6.7.1",
"oauth-1.0a": "^2.2.6",
"open": "^7.0.0",
"openapi-types": "^10.0.0",
"p-cancelable": "^2.0.0",
"passport": "^0.5.0",
"passport-cookie": "^1.0.9",

View file

@ -0,0 +1,12 @@
import { NextFunction, Request, Response } from 'express';
const sayHello = (req: Request, res: Response, next: NextFunction): void => {
console.log('hello');
console.log('se llamo esta vegra');
next();
};
export const middlewares = {
getUsers: [sayHello],
getUser: [sayHello],
};

View file

@ -8,77 +8,103 @@ import express = require('express');
import { HttpError, OpenAPIV3 } from 'express-openapi-validator/dist/framework/types';
import * as bodyParser from 'body-parser';
import * as SwaggerParser from '@apidevtools/swagger-parser';
// eslint-disable-next-line import/no-cycle
import { Db } from '../..';
import config = require('../../../config');
import { middlewares } from '../middlewares';
export interface N8nApp {
app: Application;
}
type OperationID = 'getUsers' | 'getUser' | undefined;
export const publicApiController = express.Router();
publicApiController.use(bodyParser.json());
publicApiController.use(
`/v1`,
OpenApiValidator.middleware({
apiSpec: path.join(__dirname, 'openapi.yml'),
operationHandlers: path.join(__dirname),
validateRequests: true,
validateApiSpec: true,
validateSecurity: {
handlers: {
// eslint-disable-next-line @typescript-eslint/naming-convention
ApiKeyAuth: async (req, scopes, schema: OpenAPIV3.ApiKeySecurityScheme) => {
const apiKey = req.headers[schema.name.toLowerCase()];
void (async () => {
const { paths = {} } = await SwaggerParser.parse(path.join(__dirname, 'openapi.yml'));
Object.entries(paths).forEach(([routePath, methods]) => {
Object.entries(methods).forEach(([method, data]) => {
const operationId: OperationID = (
data as {
'x-eov-operation-id': OperationID;
}
)['x-eov-operation-id'];
if (operationId) {
if (method === 'get') {
publicApiController.get(
routePath.replace(/\{([^}]+)}/g, ':$1'),
...middlewares[operationId],
);
}
}
});
});
const user = await Db.collections.User?.find({
where: {
apiKey,
},
relations: ['globalRole'],
});
publicApiController.use(
'/',
OpenApiValidator.middleware({
apiSpec: path.join(__dirname, 'openapi.yml'),
operationHandlers: path.join(__dirname),
validateRequests: true,
validateApiSpec: true,
validateSecurity: {
handlers: {
// eslint-disable-next-line @typescript-eslint/naming-convention
ApiKeyAuth: async (req, scopes, schema: OpenAPIV3.ApiKeySecurityScheme) => {
const apiKey = req.headers[schema.name.toLowerCase()];
if (!user?.length) {
return false;
}
const user = await Db.collections.User?.find({
where: {
apiKey,
},
relations: ['globalRole'],
});
if (!config.get('userManagement.isInstanceOwnerSetUp')) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw {
status: 400,
};
}
if (!user?.length) {
return false;
}
if (config.get('userManagement.disabled')) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw {
status: 400,
};
}
if (!config.get('userManagement.isInstanceOwnerSetUp')) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw {
status: 400,
};
}
if (user[0].globalRole.name !== 'owner') {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw {
status: 403,
};
}
if (config.get('userManagement.disabled')) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw {
status: 400,
};
}
[req.user] = user;
if (user[0].globalRole.name !== 'owner') {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw {
status: 403,
};
}
return true;
[req.user] = user;
return true;
},
},
},
},
}),
);
}),
);
// add error handler
// @ts-ignore
publicApiController.use((error: HttpError, req, res: Response) => {
res.status(error.status || 500).json({
message: error.message,
errors: error.errors,
// add error handler
// @ts-ignore
publicApiController.use((error: HttpError, req, res: Response) => {
res.status(error.status || 500).json({
message: error.message,
errors: error.errors,
});
});
});
})();

View file

@ -172,7 +172,7 @@ import { SharedWorkflow } from './databases/entities/SharedWorkflow';
import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from './constants';
import { credentialsController } from './api/credentials.api';
import { getInstanceBaseUrl, isEmailSetUp } from './UserManagement/UserManagementHelper';
import { publicApiController } from './PublicApi/v1';
import { publicApiController as publicApiControllerV1 } from './PublicApi/v1';
require('body-parser-xml')(bodyParser);
@ -580,7 +580,7 @@ class App {
return ResponseHelper.sendSuccessResponse(res, {}, true, 204);
});
this.app.use(`/${this.publicApiEndpoint}/`, publicApiController);
this.app.use(`/${this.publicApiEndpoint}/v1`, publicApiControllerV1);
// Parse cookies for easier access
this.app.use(cookieParser());