Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing additional data to Middleware #372

Open
josezone opened this issue Aug 12, 2019 · 2 comments
Open

Passing additional data to Middleware #372

josezone opened this issue Aug 12, 2019 · 2 comments

Comments

@josezone
Copy link

I am using

  • inversify 5.0.1
  • inversify-binding-decorators 4.0.0
  • inversify-express-utils 6.3.2
    The code I am working on can be seen at this Link
    The Problem
    I need to pass an additional parameter to the Middleware so that it will act as a factory,
    Example, I need to pass a role onto a middleware so that the system can check if the user has permission to access the API
    an example we need to create a middleware as follows
@provide("roles")
class RoleValidator extends BaseMiddleware {
    role(role){
        return handler(req: Request, res: Response, next: NextFunction) {
            if(req.user.role === role){
                next();
            } else {
                res.end();
            }
        }
    }
}

And the middleware is called by a controller

@controller('/test')
class UserController extends BaseHttpController {
    @httpPost('/', "roles=>'currentRole'")
    private test(
        @requestParam('param') param: string,
        res: Response,
        next: NextFunction
      ){
        //code
      }
}

How can this be achieved, this is a common scenario, that has to be used. Is it that, the feature is not supported.

@PodaruDragos PodaruDragos transferred this issue from inversify/InversifyJS Jan 28, 2022
@hazeos
Copy link

hazeos commented Feb 18, 2022

You can implement it like this:

  1. Pass functions to endpoint decorator
    @httpPost('/', authenticateToken(), authorizeUser(['administrator']))

  2. Function example

export const authenticateToken = (/* PARAMS HERE */) => {
  return async (req: Request, res: Response, next: NextFunction) => {
    const authHeader = req.headers.authorization;
    const token = authHeader && authHeader.split(' ')[1];

    if (!token) {
      return next(new AppError(HttpStatusCode.UNAUTHORIZED, 'error', 'No token'));
    }

    verify(token, process.env.ACCESS_TOKEN_SECRET, (error, user) => {
      if (error) {
        console.error(error);
        next(new AppError(HttpStatusCode.FORBIDDEN, 'error', 'Invalid or expired token'));
      }

      req.body.user = user?.user as IJwtUserPayload;
      next();
    });
  };
};

@talfreds
Copy link

You can implement it like this:

  1. Pass functions to endpoint decorator
    @httpPost('/', authenticateToken(), authorizeUser(['administrator']))
  2. Function example
export const authenticateToken = (/* PARAMS HERE */) => {
  return async (req: Request, res: Response, next: NextFunction) => {
    const authHeader = req.headers.authorization;
    const token = authHeader && authHeader.split(' ')[1];

    if (!token) {
      return next(new AppError(HttpStatusCode.UNAUTHORIZED, 'error', 'No token'));
    }

    verify(token, process.env.ACCESS_TOKEN_SECRET, (error, user) => {
      if (error) {
        console.error(error);
        next(new AppError(HttpStatusCode.FORBIDDEN, 'error', 'Invalid or expired token'));
      }

      req.body.user = user?.user as IJwtUserPayload;
      next();
    });
  };
};

I don't think it's possible with BaseMiddleware, so that you have access to http context, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants