mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
⚡ Possibility to add custom middleware
This commit is contained in:
parent
4066c727b6
commit
b8f03b252e
|
@ -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",
|
||||
|
|
12
packages/cli/src/PublicApi/middlewares.ts
Normal file
12
packages/cli/src/PublicApi/middlewares.ts
Normal 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],
|
||||
};
|
|
@ -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,
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue