From 2340fc68d33058720b9aeb14d43011dc32a3c9a5 Mon Sep 17 00:00:00 2001 From: frederikprijck Date: Mon, 31 Jul 2023 19:19:53 +0200 Subject: [PATCH 1/7] Avoid using default exports --- lib/base64_url_decode.ts | 2 +- lib/index.cjs.ts | 6 ------ lib/index.standalone.ts | 3 --- lib/index.ts | 9 ++++----- rollup.config.ts | 4 ++-- 5 files changed, 7 insertions(+), 17 deletions(-) delete mode 100644 lib/index.cjs.ts delete mode 100644 lib/index.standalone.ts diff --git a/lib/base64_url_decode.ts b/lib/base64_url_decode.ts index 3328ec6..aaf3ec2 100644 --- a/lib/base64_url_decode.ts +++ b/lib/base64_url_decode.ts @@ -10,7 +10,7 @@ function b64DecodeUnicode(str: string) { ); } -export default function(str: string) { +export function base64UrlDecode(str: string) { let output = str.replace(/-/g, "+").replace(/_/g, "/"); switch (output.length % 4) { case 0: diff --git a/lib/index.cjs.ts b/lib/index.cjs.ts deleted file mode 100644 index 4d61224..0000000 --- a/lib/index.cjs.ts +++ /dev/null @@ -1,6 +0,0 @@ -import jwtDecode, { InvalidTokenError } from "./index"; - -const wrapper = jwtDecode as any; -wrapper.default = jwtDecode; -wrapper.InvalidTokenError = InvalidTokenError; -export default wrapper; diff --git a/lib/index.standalone.ts b/lib/index.standalone.ts deleted file mode 100644 index 37258be..0000000 --- a/lib/index.standalone.ts +++ /dev/null @@ -1,3 +0,0 @@ -import jwtDecode from "./index"; - -export default jwtDecode; diff --git a/lib/index.ts b/lib/index.ts index d8a279d..76c6ea4 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,6 +1,6 @@ "use strict"; -import base64_url_decode from "./base64_url_decode"; +import { base64UrlDecode } from "./base64_url_decode"; import { JwtDecodeOptions, JwtHeader, JwtPayload } from "./global"; export * from './global'; @@ -12,12 +12,12 @@ export class InvalidTokenError extends Error { InvalidTokenError.prototype.name = "InvalidTokenError"; -function jwtDecode( +export function jwtDecode( token: string, options: JwtDecodeOptions & { header: true } ): T; -function jwtDecode(token: string, options?: JwtDecodeOptions): T; -function jwtDecode( +export function jwtDecode(token: string, options?: JwtDecodeOptions): T; +export function jwtDecode( token: string, options: JwtDecodeOptions = { header: false } ) { @@ -61,4 +61,3 @@ function jwtDecode( } } -export default jwtDecode; diff --git a/rollup.config.ts b/rollup.config.ts index cf17662..89a492a 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -17,7 +17,7 @@ const plugins = [ ]; export default defineConfig([{ - input: "lib/index.standalone.ts", + input: "lib/index.ts", output: { name: "jwt_decode", file: "build/jwt-decode.js", @@ -29,7 +29,7 @@ export default defineConfig([{ ] }, { - input: "lib/index.cjs.ts", + input: "lib/index.ts", output: [{ name: EXPORT_NAME, file: "build/cjs/jwt-decode.js", From 0b247d8fb7e7751e7dbe4a4fe4cd1550c8d91fdf Mon Sep 17 00:00:00 2001 From: frederikprijck Date: Mon, 31 Jul 2023 19:25:40 +0200 Subject: [PATCH 2/7] fix --- lib/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/index.ts b/lib/index.ts index 76c6ea4..a3c410e 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -37,7 +37,7 @@ export function jwtDecode( let decoded: string; try { - decoded = base64_url_decode(part); + decoded = base64UrlDecode(part); } catch (e: any) { throw new InvalidTokenError( "Invalid token specified: invalid base64 for part #" + From 6ff06cb4e4cfba3bb0210aab11dcfef9a3b407fd Mon Sep 17 00:00:00 2001 From: frederikprijck Date: Mon, 31 Jul 2023 19:38:35 +0200 Subject: [PATCH 3/7] Update README for UMD --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 5f8e12c..8aeb910 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,12 @@ Copy the file `jwt-decode.js` from the `build/` folder to your project somewhere ```html ``` +The jwtDecode function is exposed as a property on the global `jwt_decode` property: +```javascript +const token = "eyJhsw5c"; +const decoded = jwt_decode.jwtDecode(token); +``` ## Feedback From 8e17e0ff556f18a66028017804a871ae76391071 Mon Sep 17 00:00:00 2001 From: Jon Koops Date: Mon, 31 Jul 2023 19:41:47 +0200 Subject: [PATCH 4/7] Clean up Rollup config (#176) --- rollup.config.ts | 20 +++++++++----------- test/tests.ts | 32 ++++++++++++++++---------------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/rollup.config.ts b/rollup.config.ts index 89a492a..96942b0 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -4,7 +4,6 @@ import { defineConfig } from "rollup"; import livereload from "rollup-plugin-livereload"; import serve from "rollup-plugin-serve"; -const EXPORT_NAME = "jwt-decode"; const isProduction = process.env.NODE_ENV === "production"; const tsPlugin = typescript({ rootDir: "lib", @@ -16,8 +15,10 @@ const plugins = [ isProduction && terser(), ]; +const input = "lib/index.ts"; + export default defineConfig([{ - input: "lib/index.ts", + input, output: { name: "jwt_decode", file: "build/jwt-decode.js", @@ -29,24 +30,21 @@ export default defineConfig([{ ] }, { - input: "lib/index.ts", - output: [{ - name: EXPORT_NAME, + input, + output: { file: "build/cjs/jwt-decode.js", format: "cjs", - exports: "auto", sourcemap: true, - }, ], + }, plugins, }, { - input: "lib/index.ts", - output: [{ - name: EXPORT_NAME, + input, + output: { file: "build/esm/jwt-decode.js", format: "esm", sourcemap: true, - }, ], + }, plugins: [!isProduction && serve({ contentBase: ["build", "static"], diff --git a/test/tests.ts b/test/tests.ts index 75492c8..dbd62a0 100644 --- a/test/tests.ts +++ b/test/tests.ts @@ -1,4 +1,4 @@ -import jwt_decode, { InvalidTokenError, JwtPayload } from "./../lib/index"; +import { jwtDecode, InvalidTokenError, JwtPayload } from "./../lib/index"; import { describe, expect, it } from "@jest/globals"; var token = @@ -6,14 +6,14 @@ var token = describe("jwt-decode", function () { it("should return default and custom claims", function () { - var decoded = jwt_decode(token); + var decoded = jwtDecode(token); expect(decoded.exp).toEqual(1393286893); expect(decoded.iat).toEqual(1393268893); expect(decoded.foo).toEqual("bar"); }); it("should return header information", function () { - var decoded = jwt_decode(token, { header: true }); + var decoded = jwtDecode(token, { header: true }); expect(decoded.typ).toEqual("JWT"); expect(decoded.alg).toEqual("HS256"); }); @@ -21,49 +21,49 @@ describe("jwt-decode", function () { it("should work with utf8 tokens", function () { var utf8_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSm9zw6kiLCJpYXQiOjE0MjU2NDQ5NjZ9.1CfFtdGUPs6q8kT3OGQSVlhEMdbuX0HfNSqum0023a0"; - var decoded = jwt_decode(utf8_token); + var decoded = jwtDecode(utf8_token); expect(decoded.name).toEqual("José"); }); it("should work with binary tokens", function () { var binary_token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiSm9z6SIsImlhdCI6MTQyNTY0NDk2Nn0.cpnplCBxiw7Xqz5thkqs4Mo_dymvztnI0CI4BN0d1t8"; - var decoded = jwt_decode(binary_token); + var decoded = jwtDecode(binary_token); expect(decoded.name).toEqual("José"); }); it("should work with double padding", function () { var utf8_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpvc8OpIiwiaWF0IjoxNTE2MjM5MDIyfQ.7A3F5SUH2gbBSYVon5mas_Y-KCrWojorKQg7UKGVEIA"; - var decoded = jwt_decode(utf8_token); + var decoded = jwtDecode(utf8_token); expect(decoded.name).toEqual("José"); }); it("should work with single padding", function () { var utf8_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikpvc8OpZSIsImlhdCI6MTUxNjIzOTAyMn0.tbjJzDAylkKSV0_YGR5xBJBlFK01C82nZPLIcA3JX1g"; - var decoded = jwt_decode(utf8_token); + var decoded = jwtDecode(utf8_token); expect(decoded.name).toEqual("Josée"); }); it("should throw InvalidTokenError on nonstring", function () { var bad_token = null; expect(function () { - jwt_decode(bad_token as any); + jwtDecode(bad_token as any); }).toThrow(InvalidTokenError); }); it("should throw InvalidTokenError on string that is not a token", function () { var bad_token = "fubar"; expect(function () { - jwt_decode(bad_token); + jwtDecode(bad_token); }).toThrow(InvalidTokenError); }); it("should throw InvalidTokenErrors when token is null", function () { var bad_token = null; expect(function () { - jwt_decode(bad_token as any, { header: true }); + jwtDecode(bad_token as any, { header: true }); }).toThrow( new InvalidTokenError("Invalid token specified: must be a string") ); @@ -72,28 +72,28 @@ describe("jwt-decode", function () { it("should throw InvalidTokenErrors when missing part #1", function () { var bad_token = ".FAKE_TOKEN"; expect(function () { - jwt_decode(bad_token, { header: true }); + jwtDecode(bad_token, { 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 () { - jwt_decode(bad_token, { header: true }); + jwtDecode(bad_token, { 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 () { - jwt_decode(bad_token, { header: true }); + jwtDecode(bad_token, { 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 () { - jwt_decode(bad_token); + jwtDecode(bad_token); }).toThrow( new InvalidTokenError("Invalid token specified: missing part #2") ); @@ -102,14 +102,14 @@ describe("jwt-decode", function () { it("should throw InvalidTokenErrors when part #2 is not valid base64", function () { var bad_token = "FAKE.TOKEN"; expect(function () { - jwt_decode(bad_token); + jwtDecode(bad_token); }).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 () { - jwt_decode(bad_token); + jwtDecode(bad_token); }).toThrow(/Invalid token specified: invalid json for part #2/); }); }); From d005f601044d0accb06fe6d86bee087ef752a3a0 Mon Sep 17 00:00:00 2001 From: Jon Koops Date: Mon, 31 Jul 2023 23:32:51 +0200 Subject: [PATCH 5/7] Use a default export for UMD module (#181) --- README.md | 16 +++++++++++++--- lib/index.umd.ts | 1 + rollup.config.ts | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 lib/index.umd.ts diff --git a/README.md b/README.md index 8aeb910..107c4a4 100644 --- a/README.md +++ b/README.md @@ -92,16 +92,26 @@ const jwt_decode = require('jwt-decode'); #### Include with a script tag -Copy the file `jwt-decode.js` from the `build/` folder to your project somewhere, then include it like so: +Copy the file `jwt-decode.js` from the root of the `build/` folder to your project somewhere, then include it like so: ```html ``` -The jwtDecode function is exposed as a property on the global `jwt_decode` property: + +Once this script has loaded, the `jwt_decode` function will be exposed as a global: ```javascript const token = "eyJhsw5c"; -const decoded = jwt_decode.jwtDecode(token); +const decoded = jwt_decode(token); +``` + +Alternatively, if you are using the [Asynchronous Module Definition (AMD) API](https://github.com/amdjs/amdjs-api/blob/master/AMD.md), you can load the same function as follows: + +```javascript +define(["jwt_decode"], (jwtDecode) => { + const token = "eyJhsw5c"; + const decoded = jwtDecode(token); +}); ``` ## Feedback diff --git a/lib/index.umd.ts b/lib/index.umd.ts new file mode 100644 index 0000000..4726b67 --- /dev/null +++ b/lib/index.umd.ts @@ -0,0 +1 @@ +export { jwtDecode as default } from './index'; diff --git a/rollup.config.ts b/rollup.config.ts index 96942b0..68d21fe 100644 --- a/rollup.config.ts +++ b/rollup.config.ts @@ -18,7 +18,7 @@ const plugins = [ const input = "lib/index.ts"; export default defineConfig([{ - input, + input: "lib/index.umd.ts", output: { name: "jwt_decode", file: "build/jwt-decode.js", From 15261961147e37b5cad14f8f36b4f1443f8cbdc7 Mon Sep 17 00:00:00 2001 From: Jon Koops Date: Tue, 1 Aug 2023 00:41:48 +0200 Subject: [PATCH 6/7] Update docs to use named exports (#182) --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 107c4a4..6ea672a 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,10 @@ Run `npm install jwt-decode` or `yarn add jwt-decode` to install the library. ### Usage ```js -import jwt_decode from "jwt-decode"; +import { jwtDecode } from "jwt-decode"; -var token = "eyJ0eXAiO.../// jwt token"; -var decoded = jwt_decode(token); +const token = "eyJ0eXAiO.../// jwt token"; +const decoded = jwtDecode(token); console.log(decoded); @@ -40,7 +40,7 @@ console.log(decoded); */ // decode header by passing in options (useful for when you need `kid` to verify a JWT): -var decodedHeader = jwt_decode(token, { header: true }); +const decodedHeader = jwtDecode(token, { header: true }); console.log(decodedHeader); /* prints: @@ -69,24 +69,24 @@ Not adhering to the format will result in a `InvalidTokenError` with one of the - `Invalid token specified: invalid base64 for part #` => the part could not be base64 decoded (the message should contain the error the base64 decoder gave) - `Invalid token specified: invalid json for part #` => the part was correctly base64 decoded, however, the decoded value was not valid JSON (the message should contain the error the JSON parser gave) -#### Use with typescript +#### Use with TypeScript -The return type of the `jwt_decode` function is determined by the `header` property of the object passed as the second argument. If omitted (or set to false), it'll use `JwtPayload`, when true it will use `JwtHeader`. -If needed, you can specify what the expected return type should be by passing a type argument to the `jwt_decode` function. +The return type of the `jwtDecode` function is determined by the `header` property of the object passed as the second argument. If omitted (or set to false), it'll use `JwtPayload`, when true it will use `JwtHeader`. +If needed, you can specify what the expected return type should be by passing a type argument to the `jwtDecode` function. You can extend both `JwtHeader` and `JwtPayload` to include non-standard claims or properties. ```typescript -import jwtDecode from "jwt-decode"; +import { jwtDecode } from "jwt-decode"; -const token: string = "eyJhsw5c"; +const token = "eyJhsw5c"; const decoded = jwtDecode(token); // Returns with the JwtPayload type ``` #### Use as a CommonJS package ```javascript -const jwt_decode = require('jwt-decode'); +const { jwtDecode } = require('jwt-decode'); ... ``` From 7fa15c56553d2f228581ce209d95b74566eedaaa Mon Sep 17 00:00:00 2001 From: Ewan Harris Date: Tue, 1 Aug 2023 16:28:29 +0100 Subject: [PATCH 7/7] Fix html file --- static/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/index.html b/static/index.html index bb03dda..19ca9ae 100644 --- a/static/index.html +++ b/static/index.html @@ -13,7 +13,7 @@

decoded: