Skip to content

Commit

Permalink
Added verify function with some extra error handling wrapping
Browse files Browse the repository at this point in the history
  • Loading branch information
JackHumphries9 committed Jan 3, 2023
1 parent e8f335e commit 4370d2e
Show file tree
Hide file tree
Showing 6 changed files with 778 additions and 16 deletions.
621 changes: 621 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

19 changes: 16 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
{
"name": "jwter",
"version": "1.0.0",
"description": "A command line tool to decode, sign and verify JWT Tokens",
"description": "A command line tool to decode, sign and verify JWTs",
"main": "index.js",
"type": "module",
"bin": {
"jwter": "./dist/index.js"
},
"scripts": {
"prebuild": "node -p \"'export const PKG_VERSION = ' + JSON.stringify(require('./package.json').version) + ';export const PKG_DESCRIPTION = ' + JSON.stringify(require('./package.json').description) + ';'\" > src/version.ts",
"build": "npx tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"repository": {
"type": "git",
"url": "https://github.com/JackHumphries9/jwter.git"
},
"keywords": [
"cli",
"jsonwebtokens",
"jwt",
"jsonwebtoken",
"jwt-cli",
"command",
"jwter"
],
"author": "Jack Humphries",
"license": "ISC",
"license": "GNU General Public License v3.0",
"dependencies": {
"chalk": "^5.2.0",
"commander": "^9.4.1",
Expand Down
34 changes: 31 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import { Command } from "commander";
import { handleCommandError } from "./errors/handleCommandError.js";
import { jwtDecode } from "./jwtDecode.js";
import { jwtSign } from "./jwtSign.js";
import { jwtVerify } from "./jwtVerify.js";
import { error, warn } from "./utils.js";
import { PKG_DESCRIPTION, PKG_VERSION } from "./version.js";

const program = new Command();

Expand All @@ -24,9 +26,7 @@ const JWT_ALGORITHMS = [
"none",
];

program
.version("1.0.0")
.description("A CLI for decoding, verifying and signing JWTs!");
program.version(PKG_VERSION).description(PKG_DESCRIPTION);

program
.command("decode")
Expand Down Expand Up @@ -100,4 +100,32 @@ program
}
});

program
.command("verify")
.description("Checks a JWT against a secret")
.argument("<secret>", "The secret to sign the data with")
.argument("<token>", "The payload for the token")

.option("-d, --decode", "Decode the token as well", false)
.option("-ie --ignore-exp", "Ignore the expiration of the token", false)
.option("-s, --sub <sub>", "Check the subject of the token")
.option("-e, --exp <exp>", "Check the expiration of the token")
.option("-i, --iss <iss>", "Check the issuer of the token")
.option("-a, --aud <aud>", "Check the audience of the token")

.action((secret, token, options) => {
try {
if (!secret) {
error("No secret provided!");
}
if (!token) {
error("No token provided!");
}

jwtVerify(secret, token, options);
} catch (e) {
handleCommandError(e, options.debug);
}
});

program.parse(process.argv);
13 changes: 3 additions & 10 deletions src/jwtDecode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,14 @@ export const jwtDecode = (token: string, options?: DecodeOptions) => {
jwt = JSON.parse(decoded);
}

const opts = { ...defaultOptions, ...options };

console.log(chalk.blue("Your Decoded JWT:") + "\n");

const header = JSON.parse(
Buffer.from(token.split(".")[0] + "==", "base64url").toString()
);

if (opts.pretty) {
console.log(chalk.blue("* Header:"));
console.log(JSON.stringify(header, null, 2));
console.log(chalk.magenta("* Payload:"));
console.log(JSON.stringify(jwt, null, 4));
process.exit();
}

console.log(chalk.blue("* Header:"));
console.log(JSON.stringify(header, null, 2));
console.log(chalk.magenta("* Payload:"));
console.log(JSON.stringify(jwt, null, 4));
};
106 changes: 106 additions & 0 deletions src/jwtVerify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import chalk from "chalk";
import jsonwebtoken from "jsonwebtoken";
import { jwtDecode } from "./jwtDecode.js";
import { error } from "./utils.js";

export interface VerifyOptions {
ignoreExp?: boolean;
decode?: boolean;
sub?: string;
exp?: string;
iss?: string;
aud?: string;
}

const mappedOptions: { [key: string]: string } = {
ignoreExp: "ignoreExpiration",
sub: "subject",
exp: "expiresIn",
iss: "issuer",
aud: "audience",
};

export const jwtVerify = (
secret: string,
token: string,
options?: VerifyOptions
) => {
try {
let op: jsonwebtoken.VerifyOptions = {};

if (options) {
Object.keys(options).forEach((k: string) => {
if (mappedOptions[k]) {
// @ts-ignore
op = { ...op, [mappedOptions[k]]: options[k] };
}
});
}

const verifiedToken = jsonwebtoken.verify(token, secret, op);

if (verifiedToken) {
console.log(chalk.green("Your token is valid!"));
if (options?.ignoreExp) {
console.log(
chalk.yellow(
"Tip: You are ignoring the expiration of the token."
)
);
}

if (options?.decode) {
jwtDecode(token);
}

process.exit(0);
} else {
console.log(chalk.red("Your token is invalid!"));
process.exit(1);
}
} catch (e) {
if (e instanceof jsonwebtoken.JsonWebTokenError) {
if (e.message === "invalid signature") {
console.log(
chalk.red("The secret provided doesn't match the token!")
);
process.exit(1);
}
if (e.message === "jwt expired") {
console.log(chalk.red("The token provided has expired!"));
console.log(
chalk.yellow("Tip: Use --ignore-exp to ignore this error.")
);
process.exit(1);
}

if (e.message.includes("jwt audience invalid")) {
console.log(
chalk.red("The token provided has an invalid audience!")
);
process.exit(1);
}

if (e.message.includes("jwt subject invalid")) {
console.log(
chalk.red(`The token provided has an invalid subject!`)
);
process.exit(1);
}

if (e.message.includes("jwt issuer invalid")) {
console.log(
chalk.red("The token provided has an invalid issuer!")
);
process.exit(1);
}

if (e.message.includes("jwt malformed")) {
console.log(chalk.red("The token provided is malformed!"));
process.exit(1);
}

error(e.message);
}
}
};
1 change: 1 addition & 0 deletions src/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const PKG_VERSION = "1.0.0";export const PKG_DESCRIPTION = "A command line tool to decode, sign and verify JWT Tokens";

0 comments on commit 4370d2e

Please sign in to comment.