fix: Security upgrade jsonwebtoken to 9.0.0 (#8420)

This commit is contained in:
Daniel
2023-02-07 22:45:30 +11:00
committed by GitHub
parent 4450ecbc01
commit f5bfe4571e
8 changed files with 114 additions and 98 deletions

104
package-lock.json generated
View File

@@ -31,7 +31,7 @@
"graphql-tag": "2.12.6",
"intersect": "1.0.1",
"ip-range-check": "0.2.0",
"jsonwebtoken": "8.5.1",
"jsonwebtoken": "9.0.0",
"jwks-rsa": "2.1.5",
"ldapjs": "2.3.3",
"lodash": "4.17.21",
@@ -2863,6 +2863,35 @@
}
}
},
"node_modules/@parse/node-apn/node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/@parse/node-apn/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/@parse/node-gcm": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@parse/node-gcm/-/node-gcm-1.0.2.tgz",
@@ -10167,32 +10196,18 @@
}
},
"node_modules/jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"lodash": "^4.17.21",
"ms": "^2.1.1",
"semver": "^5.6.0"
"semver": "^7.3.8"
},
"engines": {
"node": ">=4",
"npm": ">=1.4.28"
}
},
"node_modules/jsonwebtoken/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"bin": {
"semver": "bin/semver"
"node": ">=12",
"npm": ">=6"
}
},
"node_modules/jsprim": {
@@ -22697,6 +22712,28 @@
"requires": {
"ms": "2.1.2"
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
}
},
@@ -28397,27 +28434,14 @@
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
"integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"lodash": "^4.17.21",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"dependencies": {
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
"semver": "^7.3.8"
}
},
"jsprim": {

View File

@@ -40,7 +40,7 @@
"graphql-tag": "2.12.6",
"intersect": "1.0.1",
"ip-range-check": "0.2.0",
"jsonwebtoken": "8.5.1",
"jsonwebtoken": "9.0.0",
"jwks-rsa": "2.1.5",
"ldapjs": "2.3.3",
"lodash": "4.17.21",

View File

@@ -648,6 +648,7 @@ describe('instagram auth adapter', () => {
describe('google auth adapter', () => {
const google = require('../lib/Adapters/Auth/google');
const jwt = require('jsonwebtoken');
const authUtils = require('../lib/Adapters/Auth/utils');
it('should throw error with missing id_token', async () => {
try {
@@ -670,7 +671,7 @@ describe('google auth adapter', () => {
// it('should throw error if public key used to encode token is not available', async () => {
// const fakeDecodedToken = { header: { kid: '789', alg: 'RS256' } };
// try {
// spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
// spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
// await google.validateAuthData({ id: 'the_user_id', id_token: 'the_token' }, {});
// fail();
@@ -689,7 +690,7 @@ describe('google auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
spyOn(jwt, 'verify').and.callFake(() => fakeClaim);
const result = await google.validateAuthData(
@@ -705,7 +706,7 @@ describe('google auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
spyOn(jwt, 'verify').and.callFake(() => fakeClaim);
try {
@@ -729,7 +730,7 @@ describe('google auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
spyOn(jwt, 'verify').and.callFake(() => fakeClaim);
try {
@@ -751,7 +752,7 @@ describe('google auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
spyOn(jwt, 'verify').and.callFake(() => fakeClaim);
try {
@@ -1454,6 +1455,7 @@ describe('apple signin auth adapter', () => {
const apple = require('../lib/Adapters/Auth/apple');
const jwt = require('jsonwebtoken');
const util = require('util');
const authUtils = require('../lib/Adapters/Auth/utils');
it('(using client id as string) should throw error with missing id_token', async () => {
try {
@@ -1488,7 +1490,7 @@ describe('apple signin auth adapter', () => {
it('should throw error if public key used to encode token is not available', async () => {
const fakeDecodedToken = { header: { kid: '789', alg: 'RS256' } };
try {
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header);
await apple.validateAuthData(
{ id: 'the_user_id', token: 'the_token' },
@@ -1510,7 +1512,7 @@ describe('apple signin auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header);
spyOn(jwt, 'verify').and.callFake(() => fakeClaim);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
@@ -1527,7 +1529,7 @@ describe('apple signin auth adapter', () => {
it('should not verify invalid id_token', async () => {
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
};
@@ -1564,7 +1566,7 @@ describe('apple signin auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
};
@@ -1586,7 +1588,7 @@ describe('apple signin auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
};
@@ -1608,7 +1610,7 @@ describe('apple signin auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
};
@@ -1628,7 +1630,7 @@ describe('apple signin auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
};
@@ -1656,7 +1658,7 @@ describe('apple signin auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
};
@@ -1685,7 +1687,7 @@ describe('apple signin auth adapter', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
};
@@ -1757,7 +1759,7 @@ describe('apple signin auth adapter', () => {
sub: 'a_different_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return { kid: '123', rsaPublicKey: 'the_rsa_public_key' };
};
@@ -2024,6 +2026,7 @@ describe('facebook limited auth adapter', () => {
const facebook = require('../lib/Adapters/Auth/facebook');
const jwt = require('jsonwebtoken');
const util = require('util');
const authUtils = require('../lib/Adapters/Auth/utils');
// TODO: figure out a way to run this test alongside facebook classic tests
xit('(using client id as string) should throw error with missing id_token', async () => {
@@ -2062,7 +2065,7 @@ describe('facebook limited auth adapter', () => {
header: { kid: '789', alg: 'RS256' },
};
try {
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header);
await facebook.validateAuthData(
{ id: 'the_user_id', token: 'the_token' },
@@ -2086,7 +2089,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header);
spyOn(jwt, 'verify').and.callFake(() => fakeClaim);
const fakeGetSigningKeyAsyncFunction = () => {
return {
@@ -2108,7 +2111,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return {
kid: '123',
@@ -2150,7 +2153,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return {
kid: '123',
@@ -2177,7 +2180,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return {
kid: '123',
@@ -2204,7 +2207,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return {
kid: '123',
@@ -2229,7 +2232,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return {
kid: '123',
@@ -2262,7 +2265,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return {
kid: '123',
@@ -2296,7 +2299,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return {
kid: '123',
@@ -2382,7 +2385,7 @@ describe('facebook limited auth adapter', () => {
const fakeDecodedToken = {
header: { kid: '123', alg: 'RS256' },
};
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
const fakeGetSigningKeyAsyncFunction = () => {
return {
kid: '123',

View File

@@ -587,6 +587,7 @@ describe('server', () => {
it('should not fail when Google signin is introduced without the optional clientId', done => {
const jwt = require('jsonwebtoken');
const authUtils = require('../lib/Adapters/Auth/utils');
reconfigureServer({
auth: { google: {} },
@@ -599,7 +600,7 @@ describe('server', () => {
sub: 'the_user_id',
};
const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } };
spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken);
spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken);
spyOn(jwt, 'verify').and.callFake(() => fakeClaim);
const user = new Parse.User();
user

View File

@@ -5,6 +5,7 @@ const Parse = require('parse/node').Parse;
const jwksClient = require('jwks-rsa');
const util = require('util');
const jwt = require('jsonwebtoken');
const authUtils = require('./utils');
const TOKEN_ISSUER = 'https://appleid.apple.com';
@@ -30,21 +31,12 @@ const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => {
return key;
};
const getHeaderFromToken = token => {
const decodedToken = jwt.decode(token, { complete: true });
if (!decodedToken) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`);
}
return decodedToken.header;
};
const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMaxAge }) => {
if (!token) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`);
}
const { kid: keyId, alg: algorithm } = getHeaderFromToken(token);
const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token);
const ONE_HOUR_IN_MS = 3600000;
let jwtClaims;

View File

@@ -5,6 +5,7 @@ const jwksClient = require('jwks-rsa');
const util = require('util');
const jwt = require('jsonwebtoken');
const httpsRequest = require('./httpsRequest');
const authUtils = require('./utils');
const TOKEN_ISSUER = 'https://facebook.com';
@@ -73,21 +74,12 @@ const getFacebookKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => {
return key;
};
const getHeaderFromToken = token => {
const decodedToken = jwt.decode(token, { complete: true });
if (!decodedToken) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'provided token does not decode as JWT');
}
return decodedToken.header;
};
const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMaxAge }) => {
if (!token) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'id token is invalid for this user.');
}
const { kid: keyId, alg: algorithm } = getHeaderFromToken(token);
const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token);
const ONE_HOUR_IN_MS = 3600000;
let jwtClaims;

View File

@@ -5,6 +5,7 @@ var Parse = require('parse/node').Parse;
const https = require('https');
const jwt = require('jsonwebtoken');
const authUtils = require('./utils');
const TOKEN_ISSUER = 'accounts.google.com';
const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com';
@@ -51,22 +52,12 @@ function getGoogleKeyByKeyId(keyId) {
});
}
function getHeaderFromToken(token) {
const decodedToken = jwt.decode(token, { complete: true });
if (!decodedToken) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`);
}
return decodedToken.header;
}
async function verifyIdToken({ id_token: token, id }, { clientId }) {
if (!token) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`);
}
const { kid: keyId, alg: algorithm } = getHeaderFromToken(token);
const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token);
let jwtClaims;
const googleKey = await getGoogleKeyByKeyId(keyId);

View File

@@ -0,0 +1,13 @@
const jwt = require('jsonwebtoken');
const Parse = require('parse/node').Parse;
const getHeaderFromToken = token => {
const decodedToken = jwt.decode(token, { complete: true });
if (!decodedToken) {
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`);
}
return decodedToken.header;
};
module.exports = {
getHeaderFromToken,
};