Skip to content

Commit bd820ed

Browse files
chore(deps): update dependency eslint to v9 (#340)
* chore(deps): update dependency eslint to v9 * chore: migrate to eslint v9 - Updated ESLint configuration for v9 compatibility - Adjusted rules and plugins as needed - Removed deprecated configurations * refactor: modernize codebase --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Francisco Buceta <frbuceta@gmail.com>
1 parent 8db3ff8 commit bd820ed

File tree

10 files changed

+741
-629
lines changed

10 files changed

+741
-629
lines changed

.eslintignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

.eslintrc.json

Lines changed: 0 additions & 21 deletions
This file was deleted.

eslint.config.mjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import globals from "globals";
2+
import pluginJs from "@eslint/js";
3+
import jest from "eslint-plugin-jest";
4+
5+
export default [
6+
{files: ["**/*.js"], languageOptions: {sourceType: "commonjs"}},
7+
{languageOptions: { globals: globals.node }},
8+
{
9+
files: ["test/**"],
10+
...jest.configs['flat/recommended'],
11+
rules: {
12+
...jest.configs['flat/recommended'].rules,
13+
},
14+
},
15+
pluginJs.configs.recommended,
16+
];

lib/index.js

Lines changed: 62 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -8,160 +8,106 @@
88
const async = require('async');
99
const errors = require('restify-errors');
1010
const jwt = require('jsonwebtoken');
11-
const {unless} = require('express-unless');
11+
const { unless } = require('express-unless');
1212

13-
const DEFAULT_REVOKED_FUNCTION = (_, __, cb) => {
14-
return cb(null, false);
15-
};
13+
const DEFAULT_REVOKED_FUNCTION = (_, __, cb) => cb(null, false);
1614

17-
/**
18-
* @param {any} object
19-
* @return {boolean}
20-
*/
21-
function isFunction(object) {
22-
return Object.prototype.toString.call(object) === '[object Function]';
23-
}
15+
const isFunction = (object) => typeof object === 'function';
2416

25-
/**
26-
* @param {string} secret
27-
* @return {function(*, *, *): *}
28-
*/
29-
function wrapStaticSecretInCallback(secret) {
30-
return (_, __, cb) => {
31-
return cb(null, secret);
32-
};
33-
}
17+
const wrapStaticSecretInCallback = (secret) => (_, __, cb) => cb(null, secret);
3418

3519
module.exports = (options) => {
36-
if (!options || !options.secret) throw new Error('secret should be set');
37-
38-
let secretCallback = options.secret;
39-
40-
if (!isFunction(secretCallback)) {
41-
secretCallback = wrapStaticSecretInCallback(secretCallback);
20+
if (!options || !options.secret) {
21+
throw new Error('secret should be set');
4222
}
4323

44-
const isRevokedCallback = options.isRevoked || DEFAULT_REVOKED_FUNCTION;
24+
const secretCallback = isFunction(options.secret)
25+
? options.secret
26+
: wrapStaticSecretInCallback(options.secret);
4527

46-
const _requestProperty = options.userProperty ||
47-
options.requestProperty ||
48-
'user';
49-
50-
// eslint-disable-next-line max-len
51-
const credentialsRequired = typeof options.credentialsRequired === 'undefined' ?
52-
true :
53-
options.credentialsRequired;
28+
const isRevokedCallback = options.isRevoked || DEFAULT_REVOKED_FUNCTION;
29+
const requestProperty = options.userProperty || options.requestProperty || 'user';
30+
const credentialsRequired = options.credentialsRequired !== false;
5431

5532
const middleware = (req, res, next) => {
5633
let token;
5734

58-
if (
59-
req.method === 'OPTIONS' &&
60-
req.headers.hasOwnProperty('access-control-request-headers')
61-
) {
62-
const hasAuthInAccessControl = !!~req.headers[
63-
'access-control-request-headers'
64-
]
35+
// Handle CORS preflight requests
36+
if (req.method === 'OPTIONS' && req.headers['access-control-request-headers']) {
37+
const hasAuthInAccessControl = req.headers['access-control-request-headers']
6538
.split(',')
66-
.map((header) => {
67-
return header.trim();
68-
})
69-
.indexOf('authorization');
39+
.map(header => header.trim())
40+
.includes('authorization');
7041

71-
if (hasAuthInAccessControl) {
72-
return next();
73-
}
42+
if (hasAuthInAccessControl) return next();
7443
}
7544

76-
if (options.getToken && typeof options.getToken === 'function') {
77-
try {
78-
token = options.getToken(req);
79-
} catch (e) {
80-
return next(e);
81-
}
82-
} else if (req.headers && req.headers.authorization) {
83-
const parts = req.headers.authorization.split(' ');
84-
if (parts.length === 2) {
85-
const scheme = parts[0];
86-
const credentials = parts[1];
87-
88-
if (/^(?:Bearer|JWT)$/i.test(scheme)) {
89-
token = credentials;
90-
} else {
91-
return next(
92-
new errors.InvalidCredentialsError(
93-
'Format is Authorization: Bearer [token] or Jwt [token]',
94-
),
95-
);
96-
}
97-
} else {
98-
return next(
99-
new errors.InvalidCredentialsError(
100-
'Format is Authorization: Bearer [token] or Jwt [token]',
101-
),
102-
);
103-
}
45+
// Get the token from the request
46+
try {
47+
token = options.getToken ? options.getToken(req) : extractToken(req);
48+
} catch (e) {
49+
return next(e);
10450
}
10551

52+
// Check if token is required
10653
if (!token) {
10754
if (credentialsRequired) {
108-
return next(
109-
new errors.InvalidCredentialsError(
110-
'No authorization token was found',
111-
),
112-
);
113-
} else {
114-
return next();
55+
return next(new errors.InvalidCredentialsError('No authorization token was found'));
11556
}
57+
return next();
11658
}
11759

118-
let dToken;
119-
60+
let decodedToken;
12061
try {
121-
dToken = jwt.decode(token, {complete: true}) || {};
122-
} catch (e) {
62+
decodedToken = jwt.decode(token, { complete: true }) || {};
63+
} catch {
12364
return next(new errors.InvalidCredentialsError('The token is corrupted'));
12465
}
12566

12667
async.parallel([
127-
(callback) => { // getSecret
128-
const arity = secretCallback.length;
129-
if (arity === 4) {
130-
secretCallback(req, dToken.header, dToken.payload, callback);
131-
} else { // arity == 3
132-
secretCallback(req, dToken.payload, callback);
133-
}
134-
},
135-
(callback) => { // checkRevoked
136-
isRevokedCallback(req, dToken.payload, callback);
137-
},
138-
], (err, results) => {
139-
if (err) {
140-
return next(err);
141-
}
142-
const revoked = results[1];
68+
(callback) => getSecret(secretCallback, req, decodedToken, callback),
69+
(callback) => checkRevoked(isRevokedCallback, req, decodedToken, callback),
70+
], (err, [secret, revoked]) => {
71+
if (err) return next(err);
72+
14373
if (revoked) {
144-
return next(
145-
new errors.UnauthorizedError(
146-
'The token has been revoked.',
147-
),
148-
);
74+
return next(new errors.UnauthorizedError('The token has been revoked.'));
14975
}
15076

151-
const secret = results[0];
152-
77+
// Verify the token
15378
jwt.verify(token, secret, options, (err, decoded) => {
15479
if (err && credentialsRequired) {
155-
return (err.name === 'TokenExpiredError') ?
156-
next(new errors.UnauthorizedError('The token has expired')) :
157-
next(new errors.InvalidCredentialsError(err));
80+
return next(err.name === 'TokenExpiredError'
81+
? new errors.UnauthorizedError('The token has expired')
82+
: new errors.InvalidCredentialsError(err));
15883
}
159-
req[_requestProperty] = decoded;
84+
req[requestProperty] = decoded;
16085
next();
16186
});
16287
});
16388
};
16489

90+
const extractToken = (req) => {
91+
const authHeader = req.headers?.authorization;
92+
if (!authHeader) return null;
93+
94+
const parts = authHeader.split(' ');
95+
if (parts.length === 2 && /^(Bearer|JWT)$/i.test(parts[0])) {
96+
return parts[1];
97+
}
98+
99+
throw new errors.InvalidCredentialsError('Format is Authorization: Bearer [token] or Jwt [token]');
100+
};
101+
102+
const getSecret = (callback, req, token, done) => {
103+
const arity = callback.length;
104+
return arity === 4
105+
? callback(req, token.header, token.payload, done)
106+
: callback(req, token.payload, done);
107+
};
108+
109+
const checkRevoked = (callback, req, token, done) => callback(req, token.payload, done);
110+
165111
middleware.unless = unless;
166112
return middleware;
167-
};
113+
};

0 commit comments

Comments
 (0)