0

I've hit a really strange issue, with Node & Express.

I have a middleware function, which can either be invoked in three different ways:

app.get('/', auth, handler)
app.get('/', auth('role'), handler)
app.get('/', auth('role', 'scope'), handler)

The obvious way to do this would be like this:

exports.auth = (a, b, c) => {

    let role, scope;

    switch(arguments.length) {
        case 3:
            // Called directly by express router
            handleAuth(a, b, c);
            break;

        case 2:
        case 1:
            // Called with role/scope, return handler
            // but don't execute
            role = a;
            scope = b;
            return handleAuth;
    }


    function handleAuth(req, res, next) {

        // Do some custom auth handling, can
        // check here if role/scope is set
        return next();

    }
}

However, I'm getting some very odd results for arguments.length. When called in the 2nd way, arguments.length == 5, and none of the arguments is role.

[ '0': '[object Object]',
  '1': 'function require(path) {\n    try {\n      exports.requireDepth += 1;\n      return mod.require(path);\n    } finally {\n      exports.requireDepth -= 1;\n    }\n  }',
  '2': '[object Object]',
  '3': '/Users/redacted/auth/index.js',
  '4': '/Users/redacted/auth' ]

If I log a, b, c within the function, I get a: 'role', b: undefined, c: undefined.

I've tried to reproduce it in Runkit, but haven't had any luck: https://runkit.com/benedictlewis/5a2a6538895ebe00124eb64e

2 Answers 2

1

arguments is not exposed in arrow functions (() =>). If you need them, use a regular function instead.

exports.auth = function(a, b, c) {

  let role, scope;

  switch(arguments.length) {
    ...

Side note: The arguments your refer to in that arrow function is actually picked from the wrapper function which Node.js uses while running each module / required code. That function lets you access the "magical" variables such as exports, require, module, __dirname and __filename, which is why you see 5 arguments.

Sign up to request clarification or add additional context in comments.

Comments

0

I think that case is broken.

'use strict';
let express = require('express');
let app = express();

//app.get('/', auth, handler);
app.get('/', auth('role'), handler);
//app.get('/', auth('role', 'scope'), handler);

function auth (a, b, c) {
    let role;   
    if (a == 'role') {
        role = 'user';
        return handleAuth;
    }   

    if (a != 'role')        
        return handleAuth(a, b, c);

    function handleAuth(req, res, next) {
        console.log(role || 'guest');
        next();  
    }
}

function handler (req, res, next) {
    res.send('OK');
}

app.listen(3000, () => console.log('Listening on port 3000'));

P.S. Imho, this code is knotty.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.