Skip to content

Commit

Permalink
Use modern JavaScript syntax (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonkoops authored Aug 5, 2023
1 parent fe9e3c5 commit 7694b50
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 75 deletions.
2 changes: 1 addition & 1 deletion lib/base64_url_decode.ts → lib/base64-url-decode.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function b64DecodeUnicode(str: string) {
return decodeURIComponent(
atob(str).replace(/(.)/g, function(m, p) {
atob(str).replace(/(.)/g, (m, p) => {
let code = p.charCodeAt(0).toString(16).toUpperCase();
if (code.length < 2) {
code = "0" + code;
Expand Down
27 changes: 8 additions & 19 deletions lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { base64UrlDecode } from "./base64_url_decode";
import { base64UrlDecode } from "./base64-url-decode";

export interface JwtDecodeOptions {
header?: boolean;
Expand All @@ -20,11 +20,7 @@ export interface JwtPayload {
jti?: string;
}

export class InvalidTokenError extends Error {
constructor(message: string) {
super(message);
}
}
export class InvalidTokenError extends Error {}

InvalidTokenError.prototype.name = "InvalidTokenError";

Expand All @@ -38,13 +34,14 @@ export function jwtDecode(token: string, options?: JwtDecodeOptions) {
throw new InvalidTokenError("Invalid token specified: must be a string");
}

options = options || {};
const pos = options.header === true ? 0 : 1;
options ||= {};

const pos = options.header === true ? 0 : 1;
const part = token.split(".")[pos];

if (typeof part !== "string") {
throw new InvalidTokenError(
"Invalid token specified: missing part #" + (pos + 1)
`Invalid token specified: missing part #${(pos + 1)}`
);
}

Expand All @@ -53,23 +50,15 @@ export function jwtDecode(token: string, options?: JwtDecodeOptions) {
decoded = base64UrlDecode(part);
} catch (e: any) {
throw new InvalidTokenError(
"Invalid token specified: invalid base64 for part #" +
(pos + 1) +
" (" +
e.message +
")"
`Invalid token specified: invalid base64 for part #${(pos + 1)} (${e.message})`
);
}

try {
return JSON.parse(decoded);
} catch (e: any) {
throw new InvalidTokenError(
"Invalid token specified: invalid json for part #" +
(pos + 1) +
" (" +
e.message +
")"
`Invalid token specified: invalid json for part #${(pos + 1)} (${e.message})`
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/index.umd.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { jwtDecode as default } from './index';
export { jwtDecode as default } from "./index";
108 changes: 54 additions & 54 deletions test/tests.ts
Original file line number Diff line number Diff line change
@@ -1,115 +1,115 @@
import { jwtDecode, InvalidTokenError, JwtPayload } from "./../lib/index";
import { describe, expect, it } from "@jest/globals";

var token =
const token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIiLCJleHAiOjEzOTMyODY4OTMsImlhdCI6MTM5MzI2ODg5M30.4-iaDojEVl0pJQMjrbM1EzUIfAZgsbK_kgnVyVxFSVo";

describe("jwt-decode", function () {
it("should return default and custom claims", function () {
var decoded = jwtDecode<JwtPayload & { foo: string }>(token);
describe("jwt-decode", () => {
it("should return default and custom claims", () => {
const decoded = jwtDecode<JwtPayload & { foo: string }>(token);
expect(decoded.exp).toEqual(1393286893);
expect(decoded.iat).toEqual(1393268893);
expect(decoded.foo).toEqual("bar");
});

it("should return header information", function () {
var decoded = jwtDecode(token, { header: true });
it("should return header information", () => {
const decoded = jwtDecode(token, { header: true });
expect(decoded.typ).toEqual("JWT");
expect(decoded.alg).toEqual("HS256");
});

it("should work with utf8 tokens", function () {
var utf8_token =
it("should work with utf8 tokens", () => {
const utf8Token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSm9zw6kiLCJpYXQiOjE0MjU2NDQ5NjZ9.1CfFtdGUPs6q8kT3OGQSVlhEMdbuX0HfNSqum0023a0";
var decoded = jwtDecode<JwtPayload & { name: string }>(utf8_token);
const decoded = jwtDecode<JwtPayload & { name: string }>(utf8Token);
expect(decoded.name).toEqual("José");
});

it("should work with binary tokens", function () {
var binary_token =
it("should work with binary tokens", () => {
const binaryToken =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSm9z6SIsImlhdCI6MTQyNTY0NDk2Nn0.cpnplCBxiw7Xqz5thkqs4Mo_dymvztnI0CI4BN0d1t8";
var decoded = jwtDecode<JwtPayload & { name: string }>(binary_token);
const decoded = jwtDecode<JwtPayload & { name: string }>(binaryToken);
expect(decoded.name).toEqual("José");
});

it("should work with double padding", function () {
var utf8_token =
it("should work with double padding", () => {
const utf8Token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpvc8OpIiwiaWF0IjoxNTE2MjM5MDIyfQ.7A3F5SUH2gbBSYVon5mas_Y-KCrWojorKQg7UKGVEIA";
var decoded = jwtDecode<JwtPayload & { name: string }>(utf8_token);
const decoded = jwtDecode<JwtPayload & { name: string }>(utf8Token);
expect(decoded.name).toEqual("José");
});

it("should work with single padding", function () {
var utf8_token =
it("should work with single padding", () => {
const utf8Token =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpvc8OpZSIsImlhdCI6MTUxNjIzOTAyMn0.tbjJzDAylkKSV0_YGR5xBJBlFK01C82nZPLIcA3JX1g";
var decoded = jwtDecode<JwtPayload & { name: string }>(utf8_token);
const decoded = jwtDecode<JwtPayload & { name: string }>(utf8Token);
expect(decoded.name).toEqual("Josée");
});

it("should throw InvalidTokenError on nonstring", function () {
var bad_token = null;
expect(function () {
jwtDecode(bad_token as any);
it("should throw InvalidTokenError on nonstring", () => {
const badToken = null;
expect(() => {
jwtDecode(badToken as any);
}).toThrow(InvalidTokenError);
});

it("should throw InvalidTokenError on string that is not a token", function () {
var bad_token = "fubar";
expect(function () {
jwtDecode(bad_token);
it("should throw InvalidTokenError on string that is not a token", () => {
const badToken = "fubar";
expect(() => {
jwtDecode(badToken);
}).toThrow(InvalidTokenError);
});

it("should throw InvalidTokenErrors when token is null", function () {
var bad_token = null;
expect(function () {
jwtDecode(bad_token as any, { header: true });
it("should throw InvalidTokenErrors when token is null", () => {
const badToken = null;
expect(() => {
jwtDecode(badToken as any, { header: true });
}).toThrow(
new InvalidTokenError("Invalid token specified: must be a string")
);
});

it("should throw InvalidTokenErrors when missing part #1", function () {
var bad_token = ".FAKE_TOKEN";
expect(function () {
jwtDecode(bad_token, { header: true });
it("should throw InvalidTokenErrors when missing part #1", () => {
const badToken = ".FAKE_TOKEN";
expect(() => {
jwtDecode(badToken, { header: true });
}).toThrow(/Invalid token specified: invalid json for part #1/);
});

it("should throw InvalidTokenErrors when part #1 is not valid base64", function () {
var bad_token = "TOKEN";
expect(function () {
jwtDecode(bad_token, { header: true });
it("should throw InvalidTokenErrors when part #1 is not valid base64", () => {
const badToken = "TOKEN";
expect(() => {
jwtDecode(badToken, { header: true });
}).toThrow(/Invalid token specified: invalid base64 for part #1/);
});

it("should throw InvalidTokenErrors when part #1 is not valid JSON", function () {
var bad_token = "FAKE.TOKEN";
expect(function () {
jwtDecode(bad_token, { header: true });
it("should throw InvalidTokenErrors when part #1 is not valid JSON", () => {
const badToken = "FAKE.TOKEN";
expect(() => {
jwtDecode(badToken, { header: true });
}).toThrow(/Invalid token specified: invalid json for part #1/);
});

it("should throw InvalidTokenErrors when missing part #2", function () {
var bad_token = "FAKE_TOKEN";
expect(function () {
jwtDecode(bad_token);
it("should throw InvalidTokenErrors when missing part #2", () => {
const badToken = "FAKE_TOKEN";
expect(() => {
jwtDecode(badToken);
}).toThrow(
new InvalidTokenError("Invalid token specified: missing part #2")
);
});

it("should throw InvalidTokenErrors when part #2 is not valid base64", function () {
var bad_token = "FAKE.TOKEN";
expect(function () {
jwtDecode(bad_token);
it("should throw InvalidTokenErrors when part #2 is not valid base64", () => {
const badToken = "FAKE.TOKEN";
expect(() => {
jwtDecode(badToken);
}).toThrow(/Invalid token specified: invalid base64 for part #2/);
});

it("should throw InvalidTokenErrors when part #2 is not valid JSON", function () {
var bad_token = "FAKE.TOKEN2";
expect(function () {
jwtDecode(bad_token);
it("should throw InvalidTokenErrors when part #2 is not valid JSON", () => {
const badToken = "FAKE.TOKEN2";
expect(() => {
jwtDecode(badToken);
}).toThrow(/Invalid token specified: invalid json for part #2/);
});
});

0 comments on commit 7694b50

Please sign in to comment.