Skip to content
New issue

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

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

Already on GitHub? # 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?

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

No branches or pull requests

3 participants