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"
|
"typescript": "~4.3.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@apidevtools/swagger-parser": "^10.0.3",
|
||||||
"@oclif/command": "^1.5.18",
|
"@oclif/command": "^1.5.18",
|
||||||
"@oclif/errors": "^1.2.2",
|
"@oclif/errors": "^1.2.2",
|
||||||
"@rudderstack/rudder-sdk-node": "1.0.6",
|
"@rudderstack/rudder-sdk-node": "1.0.6",
|
||||||
|
@ -133,6 +134,7 @@
|
||||||
"nodemailer": "^6.7.1",
|
"nodemailer": "^6.7.1",
|
||||||
"oauth-1.0a": "^2.2.6",
|
"oauth-1.0a": "^2.2.6",
|
||||||
"open": "^7.0.0",
|
"open": "^7.0.0",
|
||||||
|
"openapi-types": "^10.0.0",
|
||||||
"p-cancelable": "^2.0.0",
|
"p-cancelable": "^2.0.0",
|
||||||
"passport": "^0.5.0",
|
"passport": "^0.5.0",
|
||||||
"passport-cookie": "^1.0.9",
|
"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 { HttpError, OpenAPIV3 } from 'express-openapi-validator/dist/framework/types';
|
||||||
import * as bodyParser from 'body-parser';
|
import * as bodyParser from 'body-parser';
|
||||||
|
import * as SwaggerParser from '@apidevtools/swagger-parser';
|
||||||
// eslint-disable-next-line import/no-cycle
|
// eslint-disable-next-line import/no-cycle
|
||||||
import { Db } from '../..';
|
import { Db } from '../..';
|
||||||
import config = require('../../../config');
|
import config = require('../../../config');
|
||||||
|
|
||||||
|
import { middlewares } from '../middlewares';
|
||||||
|
|
||||||
export interface N8nApp {
|
export interface N8nApp {
|
||||||
app: Application;
|
app: Application;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OperationID = 'getUsers' | 'getUser' | undefined;
|
||||||
|
|
||||||
export const publicApiController = express.Router();
|
export const publicApiController = express.Router();
|
||||||
|
|
||||||
publicApiController.use(bodyParser.json());
|
publicApiController.use(bodyParser.json());
|
||||||
|
|
||||||
publicApiController.use(
|
void (async () => {
|
||||||
`/v1`,
|
const { paths = {} } = await SwaggerParser.parse(path.join(__dirname, 'openapi.yml'));
|
||||||
OpenApiValidator.middleware({
|
Object.entries(paths).forEach(([routePath, methods]) => {
|
||||||
apiSpec: path.join(__dirname, 'openapi.yml'),
|
Object.entries(methods).forEach(([method, data]) => {
|
||||||
operationHandlers: path.join(__dirname),
|
const operationId: OperationID = (
|
||||||
validateRequests: true,
|
data as {
|
||||||
validateApiSpec: true,
|
'x-eov-operation-id': OperationID;
|
||||||
validateSecurity: {
|
}
|
||||||
handlers: {
|
)['x-eov-operation-id'];
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
if (operationId) {
|
||||||
ApiKeyAuth: async (req, scopes, schema: OpenAPIV3.ApiKeySecurityScheme) => {
|
if (method === 'get') {
|
||||||
const apiKey = req.headers[schema.name.toLowerCase()];
|
publicApiController.get(
|
||||||
|
routePath.replace(/\{([^}]+)}/g, ':$1'),
|
||||||
|
...middlewares[operationId],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const user = await Db.collections.User?.find({
|
publicApiController.use(
|
||||||
where: {
|
'/',
|
||||||
apiKey,
|
OpenApiValidator.middleware({
|
||||||
},
|
apiSpec: path.join(__dirname, 'openapi.yml'),
|
||||||
relations: ['globalRole'],
|
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) {
|
const user = await Db.collections.User?.find({
|
||||||
return false;
|
where: {
|
||||||
}
|
apiKey,
|
||||||
|
},
|
||||||
|
relations: ['globalRole'],
|
||||||
|
});
|
||||||
|
|
||||||
if (!config.get('userManagement.isInstanceOwnerSetUp')) {
|
if (!user?.length) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
return false;
|
||||||
throw {
|
}
|
||||||
status: 400,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.get('userManagement.disabled')) {
|
if (!config.get('userManagement.isInstanceOwnerSetUp')) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
||||||
throw {
|
throw {
|
||||||
status: 400,
|
status: 400,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user[0].globalRole.name !== 'owner') {
|
if (config.get('userManagement.disabled')) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
||||||
throw {
|
throw {
|
||||||
status: 403,
|
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
|
// add error handler
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
publicApiController.use((error: HttpError, req, res: Response) => {
|
publicApiController.use((error: HttpError, req, res: Response) => {
|
||||||
res.status(error.status || 500).json({
|
res.status(error.status || 500).json({
|
||||||
message: error.message,
|
message: error.message,
|
||||||
errors: error.errors,
|
errors: error.errors,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
})();
|
||||||
|
|
|
@ -172,7 +172,7 @@ import { SharedWorkflow } from './databases/entities/SharedWorkflow';
|
||||||
import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from './constants';
|
import { AUTH_COOKIE_NAME, RESPONSE_ERROR_MESSAGES } from './constants';
|
||||||
import { credentialsController } from './api/credentials.api';
|
import { credentialsController } from './api/credentials.api';
|
||||||
import { getInstanceBaseUrl, isEmailSetUp } from './UserManagement/UserManagementHelper';
|
import { getInstanceBaseUrl, isEmailSetUp } from './UserManagement/UserManagementHelper';
|
||||||
import { publicApiController } from './PublicApi/v1';
|
import { publicApiController as publicApiControllerV1 } from './PublicApi/v1';
|
||||||
|
|
||||||
require('body-parser-xml')(bodyParser);
|
require('body-parser-xml')(bodyParser);
|
||||||
|
|
||||||
|
@ -580,7 +580,7 @@ class App {
|
||||||
return ResponseHelper.sendSuccessResponse(res, {}, true, 204);
|
return ResponseHelper.sendSuccessResponse(res, {}, true, 204);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.app.use(`/${this.publicApiEndpoint}/`, publicApiController);
|
this.app.use(`/${this.publicApiEndpoint}/v1`, publicApiControllerV1);
|
||||||
|
|
||||||
// Parse cookies for easier access
|
// Parse cookies for easier access
|
||||||
this.app.use(cookieParser());
|
this.app.use(cookieParser());
|
||||||
|
|
Loading…
Reference in a new issue