expressJS routing: url param conventions incorrectly set?

Hi there!

I am working on a demo project and having a simple but annoying issue with one of my routers.

For the project, ids are passed as parameters of the url. The project has private areas, common areas and areas that are private but connected to the common areas.

An area that is private but linked to a common area would be like this: /group/:groupid/:userid/.

The common area for those users is like this:
/group/:grouid/profile

Additionally, I have currently simple middleware authorization code to prevent no-registered users to visit group or private user areas if they are not assigned to the group.

    authorizationFunctionGroups: function(req, res, next) {
        console.log('in middleware authorizationFunctionGroups');
        console.log('userid', req.params.userid);
     if (!_.isEmpty(registers.groups) && _.get(registers.groups, req.params.groupid)) {
            //console.log(registers.groups[req.params.groupid]);
            console.log(registers.groups[req.params.groupid]['membersuserid']);
            registers.groups[req.params.groupid]['membersuserid'].indexOf(req.params.userid) > -1 ? next() : next(new Error("userid invalid or not in the group"));

        } else {
            next(new Error('Invalid groupid'));

        }
    }

Now: notice that “profile” does NOT refer to a user: it is in fact an area where all users of that group can see common data.

However, when I call the group profile area with an html call from my front end:

$('#button1').click(() => window.location = '.../group/' + url.pathname.split('/').slice(-2)[0] + '/profile');

the routers get confused, passing my call through the authorization middleware and rejecting to go to group profile router.

The reason is that when the frontend method passes the url to the backend, expressJS cannot distinguish that “profile” or any other url parameter in THAT position as the userid param: they are NOT registered in the group (which is correct).

The hack I found to solve this is to change my current router /group/:groupid/profile into /group/:groupid/profile/profile, which I dont like.

I have to substitute the above code for:

Middleware

    authorizationFunctionGroups: function(req, res, next) {
        console.log('in middleware authorizationFunctionGroups');
        console.log('userid', req.params.userid);
        if (req.params.userid == 'profile') { ///?????????
            res.redirect('/group/' + req.params.groupid + '/profile/profile');
        } else if (!_.isEmpty(registers.groups) && _.get(registers.groups, req.params.groupid)) {
            //console.log(registers.groups[req.params.groupid]);
            console.log(registers.groups[req.params.groupid]['membersuserid']);
            registers.groups[req.params.groupid]['membersuserid'].indexOf(req.params.userid) > -1 ? next() : next(new Error("userid invalid or not in the group"));

        } else {
            next(new Error('Invalid groupid'));

        }
    },

Frontend

$('#button1').click(() => window.location = '.../group/' + url.pathname.split('/').slice(-2)[0] + '/profile/profile');

Two Questions

  • It is clearly that my main problem is a conventional one. Any advice on how to order/name my routers so the middleware doesnt run over a group/:groupid/profile call?

  • I would prefer to keep a single view for everyone (group/:groupid/profile) instead of creating individual views with same data because I think it saves memory. However: is this a good common practice in the field? If not, what is more appropriate?