adminjs-nestjs
adminjs-nestjs copied to clipboard
Broken NestJs middleware
Using NestJs Middleware Consumers is broken with this module. I'm trying to globally add middleware to the admin module with something like:
@Module({
imports: [
// whatever
AdminModule.createAdmin({
adminBroOptions: {
rootPath: 'admin',
// etc
}
})
]
})
export class AppModule implements NestModule {
confgure(consumer: MiddlewareConsumer) {
consumer.apply(passport.authenticate('jwt').forRoutes({path: 'admin*', method: RequestMethod.ALL});
}
}
But the middleware is never executed. I'm reasonably sure this is due to the middleware reordering in express.loader.ts because when I comment it out, the middleware is executed as expected.
anyone? @wojtek-krysiak ?
My solution for now is to initialize in App.module.js with:
AdminModule.createAdminAsync({
customLoader: CustomAdminJsCustomLoader,
useFactory: () => ({
adminJsOptions: {
rootPath: '/admin',
},
}),
}),
and then in CustomAdminJsCustomLoader copy ExpressLoader without the reordering
My solution for now is to initialize in App.module.js with:
AdminModule.createAdminAsync({ customLoader: CustomAdminJsCustomLoader, useFactory: () => ({ adminJsOptions: { rootPath: '/admin', }, }), }),
and then in CustomAdminJsCustomLoader copy ExpressLoader without the reordering
Hi,
I am looking for a similar solution but as soon as I did that this error happened:
{"message":"\n You probably used old body-parser middleware, which is not compatible\n with @adminjs/express. In order to make it work you will have to\n 1. move body-parser invocation after the AdminJS setup like this:\n \n const adminJs = new AdminJS()\n const router = new buildRouter(adminJs)\n app.use(adminJs.options.rootPath, router)\n \n // body parser goes after the AdminJS router\n app.use(bodyParser())\n \n 2. Upgrade body-parser to the latest version and use it like this:\n app.use(bodyParser.json())\n "}
I was looking for a way to add a middleware for mitigating session fixation...
Any inputs of how I can get add a middleware to the adminjs nestjs setup ?
Here's a modified version that inserts adminjs after any middleware applied to the rootPath. I have not tested it much but it seems to be working with nestjs applied middleware.
private reorderRoutes(app, rootPath: string) {
let jsonParser = [];
let urlencodedParser = [];
let admin = [];
// Nestjs uses bodyParser under the hood which is in conflict with adminjs setup.
// Due to adminjs-expressjs usage of formidable we have to move body parser in layer tree after adminjs init.
// Notice! This is not documented feature of express, so this may change in the future. We have to keep an eye on it.
if (app && app._router && app._router.stack) {
const jsonParserIndex = app._router.stack.findIndex(
(layer: { name: string }) => layer.name === 'jsonParser',
);
if (jsonParserIndex >= 0) {
jsonParser = app._router.stack.splice(jsonParserIndex, 1);
}
const urlencodedParserIndex = app._router.stack.findIndex(
(layer: { name: string }) => layer.name === 'urlencodedParser',
);
if (urlencodedParserIndex >= 0) {
urlencodedParser = app._router.stack.splice(urlencodedParserIndex, 1);
}
const adminIndex = app._router.stack.findIndex(
(layer: { name: string }) => layer.name === 'admin',
);
if (adminIndex >= 0) {
admin = app._router.stack.splice(adminIndex, 1);
}
// if adminjs-nestjs didn't reorder the middleware
// the body parser would have come after corsMiddleware
const corsIndex = app._router.stack.findIndex(
(layer: { name: string }) => layer.name === 'corsMiddleware',
);
// in other case if there is no corsIndex we go after expressInit, because right after that
// there are nest endpoints.
const expressInitIndex = app._router.stack.findIndex(
(layer: { name: string }) => layer.name === 'expressInit',
);
// in case there are other middleware on the rootPath
// the adminjs should go after those
let rootPathMiddlewareIndex = -1;
const matches = app._router.stack
.map((s, i) => {
return { stackIndex: i, ...s };
})
.filter((s: { regexp: RegExp; name: string }) => {
if (['query', 'corsMiddleware', 'expressInit'].includes(s.name)) {
return false;
}
return s.regexp.test(rootPath);
});
if (matches.length > 0) {
rootPathMiddlewareIndex = matches[0].stackIndex + matches.length;
}
const initIndex =
rootPathMiddlewareIndex >= 0
? rootPathMiddlewareIndex
: (corsIndex >= 0 ? corsIndex : expressInitIndex) + 1;
app._router.stack.splice(
initIndex,
0,
...admin,
...jsonParser,
...urlencodedParser,
);
}
}