diff --git a/package-lock.json b/package-lock.json index 64a65bad..22f2c6aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,12 +11,10 @@ "dependencies": { "@types/jsonwebtoken": "^9", "express-unless": "^2.1.3", - "jsonwebtoken": "^9.0.0", - "lodash.set": "^4.3.2" + "jsonwebtoken": "^9.0.0" }, "devDependencies": { - "@types/lodash": "^4.14.191", - "@types/lodash.set": "^4.3.7", + "@types/express": "^4.17.16", "@types/mocha": "^9.1.0", "@typescript-eslint/eslint-plugin": "^5.15.0", "@typescript-eslint/parser": "^5.15.0", @@ -299,6 +297,48 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.16", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/express/-/express-4.17.16.tgz", + "integrity": "sha512-LkKpqRZ7zqXJuvoELakaFYuETHjZkSol8EV6cNnyishutDBCCdv6+dsKPbKkCcIk57qRphOLY5sEgClw1bO3gA==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.31", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.33", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -313,21 +353,12 @@ "@types/node": "*" } }, - "node_modules/@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "node_modules/@types/mime": { + "version": "3.0.1", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", "dev": true }, - "node_modules/@types/lodash.set": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/@types/lodash.set/-/lodash.set-4.3.7.tgz", - "integrity": "sha512-bS5Wkg/nrT82YUfkNYPSccFrNZRL+irl7Yt4iM6OTSQ0VZJED2oUIVm15NkNtUAQ8SRhCe+axqERUV6MJgkeEg==", - "dev": true, - "dependencies": { - "@types/lodash": "*" - } - }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -351,12 +382,34 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, "node_modules/@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "node_modules/@types/serve-static": { + "version": "1.15.0", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dev": true, + "dependencies": { + "@types/mime": "*", + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.47.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz", @@ -2660,11 +2713,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==" - }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -4755,6 +4803,48 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.16", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/express/-/express-4.17.16.tgz", + "integrity": "sha512-LkKpqRZ7zqXJuvoELakaFYuETHjZkSol8EV6cNnyishutDBCCdv6+dsKPbKkCcIk57qRphOLY5sEgClw1bO3gA==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.31", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.33", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz", + "integrity": "sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -4769,21 +4859,12 @@ "@types/node": "*" } }, - "@types/lodash": { - "version": "4.14.191", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz", - "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", + "@types/mime": { + "version": "3.0.1", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", "dev": true }, - "@types/lodash.set": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/@types/lodash.set/-/lodash.set-4.3.7.tgz", - "integrity": "sha512-bS5Wkg/nrT82YUfkNYPSccFrNZRL+irl7Yt4iM6OTSQ0VZJED2oUIVm15NkNtUAQ8SRhCe+axqERUV6MJgkeEg==", - "dev": true, - "requires": { - "@types/lodash": "*" - } - }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -4807,12 +4888,34 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, "@types/semver": { "version": "7.3.13", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, + "@types/serve-static": { + "version": "1.15.0", + "resolved": "https://a0us.jfrog.io/a0us/api/npm/npm/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dev": true, + "requires": { + "@types/mime": "*", + "@types/node": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "5.47.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.0.tgz", @@ -6561,11 +6664,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==" - }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", diff --git a/package.json b/package.json index 65eaba3d..9d6befa5 100644 --- a/package.json +++ b/package.json @@ -35,12 +35,10 @@ "dependencies": { "@types/jsonwebtoken": "^9", "express-unless": "^2.1.3", - "jsonwebtoken": "^9.0.0", - "lodash.set": "^4.3.2" + "jsonwebtoken": "^9.0.0" }, "devDependencies": { - "@types/lodash": "^4.14.191", - "@types/lodash.set": "^4.3.7", + "@types/express": "^4.17.16", "@types/mocha": "^9.1.0", "@typescript-eslint/eslint-plugin": "^5.15.0", "@typescript-eslint/parser": "^5.15.0", diff --git a/src/index.ts b/src/index.ts index 03f59d22..e21f91fe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -import jwt from 'jsonwebtoken'; +import * as jwt from 'jsonwebtoken'; import * as express from 'express'; import { unless } from 'express-unless'; -import set from 'lodash.set'; +import { set } from './util/set'; import { UnauthorizedError } from './errors/UnauthorizedError'; diff --git a/src/util/set.ts b/src/util/set.ts new file mode 100644 index 00000000..f2c5021d --- /dev/null +++ b/src/util/set.ts @@ -0,0 +1,26 @@ +// from https://stackoverflow.com/a/54733755 +export function set(obj: T, path: string | string[], value: unknown): T { + if (typeof obj !== 'object') { + return obj; + } + + if (typeof path === 'string') { + path = path.toString().match(/[^.[\]]+/g) || []; + } + + path.slice(0, -1).reduce((a, c, i) => // Iterate all of them except the last one + { + return Object(a[c]) === a[c] // Does the key exist and is its value an object? + + // Yes: then follow that path + ? a[c] + // No: create the key. Is the next key a potential array-index? + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + : a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] + ? [] // Yes: assign a new array object + : {}; + }, // No: assign a new plain object + obj)[path[path.length - 1]] = value; // Finally assign the value to the last key + return obj; // Return the top-level object to allow chaining +} diff --git a/test/jwt.test.ts b/test/jwt.test.ts index 177e4c2c..6fde3a11 100644 --- a/test/jwt.test.ts +++ b/test/jwt.test.ts @@ -2,7 +2,7 @@ import * as jwt from 'jsonwebtoken'; import * as express from 'express'; import { expressjwt, UnauthorizedError, Request, GetVerificationKey } from '../src'; -import assert from 'assert'; +import * as assert from 'assert'; describe('failure tests', function () { @@ -171,6 +171,7 @@ describe('failure tests', function () { onExpired: () => { }, })(req, res, function (err) { assert.ok(!err); + //@ts-ignore assert.equal(req.auth.foo, 'bar'); done(); }); @@ -284,7 +285,7 @@ describe('work tests', function () { req.headers = {}; req.headers.authorization = 'Bearer ' + token; expressjwt({ secret: secret, algorithms: ['HS256'] })(req, res, function () { - assert.equal(req.auth.foo, 'bar'); + assert.equal(req.auth?.foo, 'bar'); done(); }); }); @@ -299,7 +300,7 @@ describe('work tests', function () { req.headers = {}; req.headers.authorization = 'Bearer ' + token; expressjwt({ secret: secret, algorithms: ['HS256'], requestProperty })(req, res, function () { - assert.equal(req.auth.payload.foo, 'bar'); + assert.equal(req.auth?.payload.foo, 'bar'); done(); }); }); @@ -313,7 +314,7 @@ describe('work tests', function () { req.headers = {}; req.headers.authorization = 'Bearer ' + token; expressjwt({ secret: secret, algorithms: ['HS256'] })(req, res, function () { - assert.equal(req.auth.foo, 'bar'); + assert.equal(req.auth?.foo, 'bar'); done(); }); }); @@ -328,7 +329,7 @@ describe('work tests', function () { req.headers.Authorization = 'Bearer ' + token; expressjwt({ secret: secret, algorithms: ['HS256'] })(req, res, function (err) { if (err) { return done(err); } - assert.equal(req.auth.foo, 'bar'); + assert.equal(req.auth?.foo, 'bar'); done(); }); }); @@ -382,7 +383,7 @@ describe('work tests', function () { algorithms: ['HS256'], getToken: getTokenFromQuery })(req, res, function () { - assert.equal(req.auth.foo, 'bar'); + assert.equal(req.auth?.foo, 'bar'); done(); }); }); @@ -406,7 +407,7 @@ describe('work tests', function () { algorithms: ['HS256'], getToken: getTokenFromQuery })(req, res, function () { - assert.equal(req.auth.foo, 'bar'); + assert.equal(req.auth?.foo, 'bar'); done(); }); }); @@ -428,7 +429,7 @@ describe('work tests', function () { req.headers = {}; req.headers.authorization = 'Bearer ' + token; expressjwt({ secret: getSecret, algorithms: ['HS256'] })(req, res, function () { - assert.equal(req.auth.foo, 'bar'); + assert.equal(req.auth?.foo, 'bar'); done(); }); }); diff --git a/test/revocation.test.ts b/test/revocation.test.ts index 8ede42ae..764c3511 100644 --- a/test/revocation.test.ts +++ b/test/revocation.test.ts @@ -12,8 +12,8 @@ describe('revoked jwts', function () { secret: secret, algorithms: ['HS256'], isRevoked: async (req, token) => { - const isRevoked = typeof token.payload !== 'string' && - token.payload.jti === revoked_id; + const isRevoked = typeof token?.payload !== 'string' && + token?.payload.jti === revoked_id; return isRevoked; } }); diff --git a/tsconfig.json b/tsconfig.json index b1747c08..fdacb5ff 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "allowJs": true, "target": "es5", "declaration": true, - "esModuleInterop": true + "esModuleInterop": false }, "include": [ "./src/**/*"