From e5e4d47b7f8fe76094e562924121e7ca628e473f Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 24 Apr 2021 16:09:54 -0500 Subject: [PATCH 01/20] Add another badge for jsdelivr --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6fd2130..1ba6ca3 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ ![GitHub Repo stars](https://img.shields.io/github/stars/akdombrowski/jwt-authn?style=for-the-badge&logo=github) ![GitHub forks](https://img.shields.io/github/forks/akdombrowski/jwt-authn?style=for-the-badge&logo=github) ![GitHub watchers](https://img.shields.io/github/watchers/akdombrowski/jwt-authn?style=for-the-badge&logo=github) +[![](https://data.jsdelivr.com/v1/package/npm/jwt-authn/badge)](https://www.jsdelivr.com/package/npm/jwt-authn) # jwt-authn From 062514157b294b9460ebaa7b61c85d0c9537b55b Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 24 Apr 2021 16:28:20 -0500 Subject: [PATCH 02/20] minified versions --- lib/index.min.js | 1 + src/index.min.js | 1 + 2 files changed, 2 insertions(+) create mode 100644 lib/index.min.js create mode 100644 src/index.min.js diff --git a/lib/index.min.js b/lib/index.min.js new file mode 100644 index 0000000..afc6b5a --- /dev/null +++ b/lib/index.min.js @@ -0,0 +1 @@ +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.jwtEncode=exports.parseToJSON=exports.base64URLEncode=exports.createHeaderPayload=exports.hs256Verify=exports.rs256PEMVerify=exports.rs256JWKVerify=exports.rs256PEMSign=exports.rs256JWKSign=exports.hs256Sign=exports.jwtDecode=void 0;var _crypto=_interopRequireDefault(require("crypto"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}var jwtDecode=function jwtDecode(jwt){try{if(!jwt.includes("."))throw new Error("Need at least one '.'");var components=jwt.split("."),header=components[0],base64URLDecodedHeader=Buffer.from(header,"base64url").toString("utf8");if(!base64URLDecodedHeader)throw console.err("base64URLDecodedHeader"),console.err(base64URLDecodedHeader),new Error("Header isn't base64url encoded");var jsonHeader=JSON.parse(base64URLDecodedHeader),typ=jsonHeader.typ,cty=jsonHeader.cty,alg=jsonHeader.alg;if(typ&&"JWT"!==typ)throw new Error("Need to be type jwt. Received: ".concat(typ));if(cty&&"JWT"!==cty)throw new Error("Need a cty of 'JWT'. Received: ".concat(cty));if(!alg)throw new Error("Missing algorithm in JOSE header.");if(3===components.length){var payload=components[1],base64urlDecodedPayload=Buffer.from(payload,"base64url").toString("utf8"),jsonPayload;return{header:jsonHeader,payload:JSON.parse(base64urlDecodedPayload),signature:components[2]}}throw new Error("Not using compact serialization (JWS).")}catch(e){return console.error(e.message,e),{header:null,payload:null,signature:null}}};exports.jwtDecode=jwtDecode;var hs256Sign=function hs256Sign(headerPayload,key){var secret=_crypto.default.createSecretKey(key,"base64url"),hmac=_crypto.default.createHmac("sha256",secret);hmac.update(headerPayload,"ascii");var hmacked=hmac.digest(),base64URLHmacked;return Buffer.from(hmacked).toString("base64url")};exports.hs256Sign=hs256Sign;var rs256JWKSign=function rs256JWKSign(headerPayload,privateKey){var hashes,secret;if(!_crypto.default.getHashes().includes("RSA-SHA256"))throw console.error("RSA-SHA256 not found"),new Error("RSA-SHA256 isn't available in the current system.");try{try{secret=JSON.parse(privateKey)}catch(e){if(!JSON.stringify(privateKey))throw new Error("Not valid JSON.");secret=privateKey}var keyObject=_crypto.default.createPrivateKey({key:secret,format:"jwk"}),sig,sigBase64URL;return _crypto.default.sign("sha256",Buffer.from(headerPayload),{key:keyObject}).toString("base64url")}catch(e){e instanceof TypeError?secret=privateKey:console.error(e.message,e)}return null};exports.rs256JWKSign=rs256JWKSign;var rs256PEMSign=function rs256PEMSign(headerPayload,privateKey,passphrase){var hashes,pemKey,sig,sigBase64URL;if(!_crypto.default.getHashes().includes("RSA-SHA256"))return console.error("RSA-SHA256 not found"),null;try{pemKey=_crypto.default.createPrivateKey({key:privateKey,format:"pem"})}catch(e){if(e instanceof TypeError&&e.message.includes("Passphrase required for encrypted key")){if(!passphrase)throw new Error("Need a passphrase since private key is encrypted");pemKey=_crypto.default.createPrivateKey({key:privateKey,format:"pem",passphrase:passphrase})}}return _crypto.default.sign("sha256",Buffer.from(headerPayload),{key:pemKey}).toString("base64url")};exports.rs256PEMSign=rs256PEMSign;var rs256JWKVerify=function rs256JWKVerify(jwt,publicKey){var jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2],keyObject=_crypto.default.createPublicKey({key:publicKey,format:"jwk"}),isVerified;return _crypto.default.verify(null,Buffer.from(headerPayload,"ascii"),{key:keyObject},Buffer.from(signature,"base64url"))};exports.rs256JWKVerify=rs256JWKVerify;var rs256PEMVerify=function rs256PEMVerify(jwt,publicKey){var jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2],keyObject=_crypto.default.createPublicKey({key:publicKey,format:"pem"}),isVerified;return _crypto.default.verify(null,Buffer.from(headerPayload,"ascii"),{key:keyObject},Buffer.from(signature,"base64url"))};exports.rs256PEMVerify=rs256PEMVerify;var hs256Verify=function hs256Verify(jwt,passphrase,passphraseEncoding){var jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2],secret=_crypto.default.createSecretKey(passphrase,"base64url");secret=passphraseEncoding&&Buffer.isEncoding(passphraseEncoding)?_crypto.default.createSecretKey(passphrase,passphraseEncoding):_crypto.default.createSecretKey(passphrase,"base64url");var hmac=_crypto.default.createHmac("sha256",secret);hmac.update(headerPayload,"ascii");var hmacked=hmac.digest(),base64URLHmacked,isVerified;return Buffer.from(hmacked).toString("base64url")===signature};exports.hs256Verify=hs256Verify;var createHeaderPayload=function createHeaderPayload(header,payload){if(Buffer.isEncoding("base64url")){var headerBase64URL,payloadBase64URL,headerPayload;if("string"==typeof header)headerBase64URL=Buffer.from(header,"ascii").toString("base64url");else{var jsonHeader=parseToJSON(header);headerBase64URL=base64URLEncode(jsonHeader)}if("string"==typeof payload)payloadBase64URL=Buffer.from(payload,"ascii").toString("base64url");else{var jsonPayload=parseToJSON(payload);payloadBase64URL=base64URLEncode(jsonPayload)}return"".concat(headerBase64URL,".").concat(payloadBase64URL)}throw new Error("Error: Base64URL encoding isn't available.")};exports.createHeaderPayload=createHeaderPayload;var base64URLEncode=function base64URLEncode(jsonObject){if(Buffer.isEncoding("base64url")){var stringifyHeader=JSON.stringify(jsonObject),payloadBase64URL;return Buffer.from(stringifyHeader,"ascii").toString("base64url")}throw new Error("Error: Base64URL encoding isn't available")};exports.base64URLEncode=base64URLEncode;var parseToJSON=function parseToJSON(input){var json=input;if(Buffer.isEncoding("base64url"))return json=input instanceof Object?input:JSON.parse(input);throw new Error("Error: Base64URL encoding isn't available")};exports.parseToJSON=parseToJSON;var jwtEncode=function jwtEncode(header,payload,key,options){var headerBase64URL,payloadBase64URL,jsonHeader=header;if(Buffer.isEncoding("base64url")){if(header instanceof Object){jsonHeader=header;var stringifyHeader=JSON.stringify(header);headerBase64URL=Buffer.from(stringifyHeader,"ascii").toString("base64url")}else jsonHeader=JSON.parse(header),headerBase64URL=Buffer.from(header,"ascii").toString("base64url");var headerPayload=createHeaderPayload(header,payload),_jsonHeader,alg=jsonHeader.alg,sig;if(alg){switch(alg.toLowerCase()){case"hs256":sig=hs256Sign(headerPayload,key);break;case"rs256":if(!options||!options.keyFormat)throw new Error("Need to specify keyFormat in options for RS256 algorithm as either jwk or pem.");var keyFormat=options.keyFormat;"jwk"===keyFormat.toLowerCase()?sig=rs256JWKSign(headerPayload,key):"pem"===keyFormat.toLowerCase()&&(sig=options.passphrase?rs256PEMSign(headerPayload,key,options.passphrase):rs256PEMSign(headerPayload,key));break;default:throw new Error("Unsupported alg: ".concat(alg))}return headerPayload+"."+sig}throw new Error("Algorithm couldn't be determined. alg:"+alg)}throw new Error("Error: Base64URL encoding isn't available.")};exports.jwtEncode=jwtEncode;var _default=jwtDecode;exports.default=_default; \ No newline at end of file diff --git a/src/index.min.js b/src/index.min.js new file mode 100644 index 0000000..ab4b1b6 --- /dev/null +++ b/src/index.min.js @@ -0,0 +1 @@ +import crypto from"crypto";export const jwtDecode=jwt=>{try{if(!jwt.includes("."))throw new Error("Need at least one '.'");const components=jwt.split("."),header=components[0],base64URLDecodedHeader=Buffer.from(header,"base64url").toString("utf8");if(!base64URLDecodedHeader)throw console.err("base64URLDecodedHeader"),console.err(base64URLDecodedHeader),new Error("Header isn't base64url encoded");const jsonHeader=JSON.parse(base64URLDecodedHeader),{typ:typ,cty:cty,alg:alg}=jsonHeader;if(typ&&"JWT"!==typ)throw new Error(`Need to be type jwt. Received: ${typ}`);if(cty&&"JWT"!==cty)throw new Error(`Need a cty of 'JWT'. Received: ${cty}`);if(!alg)throw new Error("Missing algorithm in JOSE header.");if(3===components.length){const payload=components[1],base64urlDecodedPayload=Buffer.from(payload,"base64url").toString("utf8"),jsonPayload=JSON.parse(base64urlDecodedPayload);return{header:jsonHeader,payload:jsonPayload,signature:components[2]}}throw new Error("Not using compact serialization (JWS).")}catch(e){return console.error(e.message,e),{header:null,payload:null,signature:null}}};export const hs256Sign=(headerPayload,key)=>{const secret=crypto.createSecretKey(key,"base64url"),hmac=crypto.createHmac("sha256",secret);hmac.update(headerPayload,"ascii");const hmacked=hmac.digest(),base64URLHmacked=Buffer.from(hmacked).toString("base64url");return base64URLHmacked};export const rs256JWKSign=(headerPayload,privateKey)=>{const hashes=crypto.getHashes();if(!hashes.includes("RSA-SHA256"))throw console.error("RSA-SHA256 not found"),new Error("RSA-SHA256 isn't available in the current system.");{let secret;try{try{secret=JSON.parse(privateKey)}catch(e){if(!JSON.stringify(privateKey))throw new Error("Not valid JSON.");secret=privateKey}const keyObject=crypto.createPrivateKey({key:secret,format:"jwk"}),sig=crypto.sign("sha256",Buffer.from(headerPayload),{key:keyObject}),sigBase64URL=sig.toString("base64url");return sigBase64URL}catch(e){e instanceof TypeError?secret=privateKey:console.error(e.message,e)}}return null};export const rs256PEMSign=(headerPayload,privateKey,passphrase)=>{const hashes=crypto.getHashes();let pemKey;if(!hashes.includes("RSA-SHA256"))return console.error("RSA-SHA256 not found"),null;try{pemKey=crypto.createPrivateKey({key:privateKey,format:"pem"})}catch(e){if(e instanceof TypeError&&e.message.includes("Passphrase required for encrypted key")){if(!passphrase)throw new Error("Need a passphrase since private key is encrypted");pemKey=crypto.createPrivateKey({key:privateKey,format:"pem",passphrase:passphrase})}}const sig=crypto.sign("sha256",Buffer.from(headerPayload),{key:pemKey}),sigBase64URL=sig.toString("base64url");return sigBase64URL};export const rs256JWKVerify=(jwt,publicKey)=>{const jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2],keyObject=crypto.createPublicKey({key:publicKey,format:"jwk"}),isVerified=crypto.verify(null,Buffer.from(headerPayload,"ascii"),{key:keyObject},Buffer.from(signature,"base64url"));return isVerified};export const rs256PEMVerify=(jwt,publicKey)=>{const jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2],keyObject=crypto.createPublicKey({key:publicKey,format:"pem"}),isVerified=crypto.verify(null,Buffer.from(headerPayload,"ascii"),{key:keyObject},Buffer.from(signature,"base64url"));return isVerified};export const hs256Verify=(jwt,passphrase,passphraseEncoding)=>{const jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2];let secret=crypto.createSecretKey(passphrase,"base64url");secret=passphraseEncoding&&Buffer.isEncoding(passphraseEncoding)?crypto.createSecretKey(passphrase,passphraseEncoding):crypto.createSecretKey(passphrase,"base64url");const hmac=crypto.createHmac("sha256",secret);hmac.update(headerPayload,"ascii");const hmacked=hmac.digest(),base64URLHmacked=Buffer.from(hmacked).toString("base64url"),isVerified=base64URLHmacked===signature;return isVerified};export const createHeaderPayload=(header,payload)=>{if(Buffer.isEncoding("base64url")){let headerBase64URL,payloadBase64URL;if("string"==typeof header)headerBase64URL=Buffer.from(header,"ascii").toString("base64url");else{const jsonHeader=parseToJSON(header);headerBase64URL=base64URLEncode(jsonHeader)}if("string"==typeof payload)payloadBase64URL=Buffer.from(payload,"ascii").toString("base64url");else{const jsonPayload=parseToJSON(payload);payloadBase64URL=base64URLEncode(jsonPayload)}const headerPayload=`${headerBase64URL}.${payloadBase64URL}`;return headerPayload}throw new Error("Error: Base64URL encoding isn't available.")};export const base64URLEncode=jsonObject=>{if(Buffer.isEncoding("base64url")){const stringifyHeader=JSON.stringify(jsonObject),payloadBase64URL=Buffer.from(stringifyHeader,"ascii").toString("base64url");return payloadBase64URL}throw new Error("Error: Base64URL encoding isn't available")};export const parseToJSON=input=>{let json=input;if(Buffer.isEncoding("base64url"))return json=input instanceof Object?input:JSON.parse(input),json;throw new Error("Error: Base64URL encoding isn't available")};export const jwtEncode=(header,payload,key,options)=>{let headerBase64URL,payloadBase64URL,jsonHeader=header;if(Buffer.isEncoding("base64url")){if(header instanceof Object){jsonHeader=header;const stringifyHeader=JSON.stringify(header);headerBase64URL=Buffer.from(stringifyHeader,"ascii").toString("base64url")}else jsonHeader=JSON.parse(header),headerBase64URL=Buffer.from(header,"ascii").toString("base64url");const headerPayload=createHeaderPayload(header,payload),{alg:alg}=jsonHeader;let sig;if(alg){switch(alg.toLowerCase()){case"hs256":sig=hs256Sign(headerPayload,key);break;case"rs256":if(!options||!options.keyFormat)throw new Error("Need to specify keyFormat in options for RS256 algorithm as either jwk or pem.");{const keyFormat=options.keyFormat;"jwk"===keyFormat.toLowerCase()?sig=rs256JWKSign(headerPayload,key):"pem"===keyFormat.toLowerCase()&&(sig=options.passphrase?rs256PEMSign(headerPayload,key,options.passphrase):rs256PEMSign(headerPayload,key))}break;default:throw new Error(`Unsupported alg: ${alg}`)}return headerPayload+"."+sig}throw new Error("Algorithm couldn't be determined. alg:"+alg)}throw new Error("Error: Base64URL encoding isn't available.")};export default jwtDecode; \ No newline at end of file From 17b6cb7ff934098e4660586daf6014d1ca3aa39a Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 24 Apr 2021 16:30:43 -0500 Subject: [PATCH 03/20] added cdn to readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 1ba6ca3..a9f9f4c 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,11 @@ npm install jwt-authn yarn add jwt-authn ``` +Or from a cdn: +``` +https://cdn.jsdelivr.net/npm/jwt-authn@1.0.39/lib +``` +
--- From 6a2837a023120bf7f789b79daaf69c4cd75cc886 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 24 Apr 2021 16:35:49 -0500 Subject: [PATCH 04/20] Add minify to build script and as a dev dependency. --- lib/index.min.js | 2 +- package-lock.json | 430 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 +- 3 files changed, 430 insertions(+), 5 deletions(-) diff --git a/lib/index.min.js b/lib/index.min.js index afc6b5a..d39e479 100644 --- a/lib/index.min.js +++ b/lib/index.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.jwtEncode=exports.parseToJSON=exports.base64URLEncode=exports.createHeaderPayload=exports.hs256Verify=exports.rs256PEMVerify=exports.rs256JWKVerify=exports.rs256PEMSign=exports.rs256JWKSign=exports.hs256Sign=exports.jwtDecode=void 0;var _crypto=_interopRequireDefault(require("crypto"));function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}var jwtDecode=function jwtDecode(jwt){try{if(!jwt.includes("."))throw new Error("Need at least one '.'");var components=jwt.split("."),header=components[0],base64URLDecodedHeader=Buffer.from(header,"base64url").toString("utf8");if(!base64URLDecodedHeader)throw console.err("base64URLDecodedHeader"),console.err(base64URLDecodedHeader),new Error("Header isn't base64url encoded");var jsonHeader=JSON.parse(base64URLDecodedHeader),typ=jsonHeader.typ,cty=jsonHeader.cty,alg=jsonHeader.alg;if(typ&&"JWT"!==typ)throw new Error("Need to be type jwt. Received: ".concat(typ));if(cty&&"JWT"!==cty)throw new Error("Need a cty of 'JWT'. Received: ".concat(cty));if(!alg)throw new Error("Missing algorithm in JOSE header.");if(3===components.length){var payload=components[1],base64urlDecodedPayload=Buffer.from(payload,"base64url").toString("utf8"),jsonPayload;return{header:jsonHeader,payload:JSON.parse(base64urlDecodedPayload),signature:components[2]}}throw new Error("Not using compact serialization (JWS).")}catch(e){return console.error(e.message,e),{header:null,payload:null,signature:null}}};exports.jwtDecode=jwtDecode;var hs256Sign=function hs256Sign(headerPayload,key){var secret=_crypto.default.createSecretKey(key,"base64url"),hmac=_crypto.default.createHmac("sha256",secret);hmac.update(headerPayload,"ascii");var hmacked=hmac.digest(),base64URLHmacked;return Buffer.from(hmacked).toString("base64url")};exports.hs256Sign=hs256Sign;var rs256JWKSign=function rs256JWKSign(headerPayload,privateKey){var hashes,secret;if(!_crypto.default.getHashes().includes("RSA-SHA256"))throw console.error("RSA-SHA256 not found"),new Error("RSA-SHA256 isn't available in the current system.");try{try{secret=JSON.parse(privateKey)}catch(e){if(!JSON.stringify(privateKey))throw new Error("Not valid JSON.");secret=privateKey}var keyObject=_crypto.default.createPrivateKey({key:secret,format:"jwk"}),sig,sigBase64URL;return _crypto.default.sign("sha256",Buffer.from(headerPayload),{key:keyObject}).toString("base64url")}catch(e){e instanceof TypeError?secret=privateKey:console.error(e.message,e)}return null};exports.rs256JWKSign=rs256JWKSign;var rs256PEMSign=function rs256PEMSign(headerPayload,privateKey,passphrase){var hashes,pemKey,sig,sigBase64URL;if(!_crypto.default.getHashes().includes("RSA-SHA256"))return console.error("RSA-SHA256 not found"),null;try{pemKey=_crypto.default.createPrivateKey({key:privateKey,format:"pem"})}catch(e){if(e instanceof TypeError&&e.message.includes("Passphrase required for encrypted key")){if(!passphrase)throw new Error("Need a passphrase since private key is encrypted");pemKey=_crypto.default.createPrivateKey({key:privateKey,format:"pem",passphrase:passphrase})}}return _crypto.default.sign("sha256",Buffer.from(headerPayload),{key:pemKey}).toString("base64url")};exports.rs256PEMSign=rs256PEMSign;var rs256JWKVerify=function rs256JWKVerify(jwt,publicKey){var jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2],keyObject=_crypto.default.createPublicKey({key:publicKey,format:"jwk"}),isVerified;return _crypto.default.verify(null,Buffer.from(headerPayload,"ascii"),{key:keyObject},Buffer.from(signature,"base64url"))};exports.rs256JWKVerify=rs256JWKVerify;var rs256PEMVerify=function rs256PEMVerify(jwt,publicKey){var jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2],keyObject=_crypto.default.createPublicKey({key:publicKey,format:"pem"}),isVerified;return _crypto.default.verify(null,Buffer.from(headerPayload,"ascii"),{key:keyObject},Buffer.from(signature,"base64url"))};exports.rs256PEMVerify=rs256PEMVerify;var hs256Verify=function hs256Verify(jwt,passphrase,passphraseEncoding){var jwtComponents=jwt.split("."),headerPayload=jwtComponents[0]+"."+jwtComponents[1],signature=jwtComponents[2],secret=_crypto.default.createSecretKey(passphrase,"base64url");secret=passphraseEncoding&&Buffer.isEncoding(passphraseEncoding)?_crypto.default.createSecretKey(passphrase,passphraseEncoding):_crypto.default.createSecretKey(passphrase,"base64url");var hmac=_crypto.default.createHmac("sha256",secret);hmac.update(headerPayload,"ascii");var hmacked=hmac.digest(),base64URLHmacked,isVerified;return Buffer.from(hmacked).toString("base64url")===signature};exports.hs256Verify=hs256Verify;var createHeaderPayload=function createHeaderPayload(header,payload){if(Buffer.isEncoding("base64url")){var headerBase64URL,payloadBase64URL,headerPayload;if("string"==typeof header)headerBase64URL=Buffer.from(header,"ascii").toString("base64url");else{var jsonHeader=parseToJSON(header);headerBase64URL=base64URLEncode(jsonHeader)}if("string"==typeof payload)payloadBase64URL=Buffer.from(payload,"ascii").toString("base64url");else{var jsonPayload=parseToJSON(payload);payloadBase64URL=base64URLEncode(jsonPayload)}return"".concat(headerBase64URL,".").concat(payloadBase64URL)}throw new Error("Error: Base64URL encoding isn't available.")};exports.createHeaderPayload=createHeaderPayload;var base64URLEncode=function base64URLEncode(jsonObject){if(Buffer.isEncoding("base64url")){var stringifyHeader=JSON.stringify(jsonObject),payloadBase64URL;return Buffer.from(stringifyHeader,"ascii").toString("base64url")}throw new Error("Error: Base64URL encoding isn't available")};exports.base64URLEncode=base64URLEncode;var parseToJSON=function parseToJSON(input){var json=input;if(Buffer.isEncoding("base64url"))return json=input instanceof Object?input:JSON.parse(input);throw new Error("Error: Base64URL encoding isn't available")};exports.parseToJSON=parseToJSON;var jwtEncode=function jwtEncode(header,payload,key,options){var headerBase64URL,payloadBase64URL,jsonHeader=header;if(Buffer.isEncoding("base64url")){if(header instanceof Object){jsonHeader=header;var stringifyHeader=JSON.stringify(header);headerBase64URL=Buffer.from(stringifyHeader,"ascii").toString("base64url")}else jsonHeader=JSON.parse(header),headerBase64URL=Buffer.from(header,"ascii").toString("base64url");var headerPayload=createHeaderPayload(header,payload),_jsonHeader,alg=jsonHeader.alg,sig;if(alg){switch(alg.toLowerCase()){case"hs256":sig=hs256Sign(headerPayload,key);break;case"rs256":if(!options||!options.keyFormat)throw new Error("Need to specify keyFormat in options for RS256 algorithm as either jwk or pem.");var keyFormat=options.keyFormat;"jwk"===keyFormat.toLowerCase()?sig=rs256JWKSign(headerPayload,key):"pem"===keyFormat.toLowerCase()&&(sig=options.passphrase?rs256PEMSign(headerPayload,key,options.passphrase):rs256PEMSign(headerPayload,key));break;default:throw new Error("Unsupported alg: ".concat(alg))}return headerPayload+"."+sig}throw new Error("Algorithm couldn't be determined. alg:"+alg)}throw new Error("Error: Base64URL encoding isn't available.")};exports.jwtEncode=jwtEncode;var _default=jwtDecode;exports.default=_default; \ No newline at end of file +"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.jwtEncode=exports.parseToJSON=exports.base64URLEncode=exports.createHeaderPayload=exports.hs256Verify=exports.rs256PEMVerify=exports.rs256JWKVerify=exports.rs256PEMSign=exports.rs256JWKSign=exports.hs256Sign=exports.jwtDecode=void 0;var _crypto=_interopRequireDefault(require("crypto"));function _interopRequireDefault(r){return r&&r.__esModule?r:{default:r}}var jwtDecode=function(r){try{if(!r.includes("."))throw new Error("Need at least one '.'");var e=r.split("."),t=e[0],a=Buffer.from(t,"base64url").toString("utf8");if(!a)throw console.err("base64URLDecodedHeader"),console.err(a),new Error("Header isn't base64url encoded");var o=JSON.parse(a),s=o.typ,i=o.cty,n=o.alg;if(s&&"JWT"!==s)throw new Error("Need to be type jwt. Received: ".concat(s));if(i&&"JWT"!==i)throw new Error("Need a cty of 'JWT'. Received: ".concat(i));if(!n)throw new Error("Missing algorithm in JOSE header.");if(3===e.length){var f=e[1],c=Buffer.from(f,"base64url").toString("utf8");return{header:o,payload:JSON.parse(c),signature:e[2]}}throw new Error("Not using compact serialization (JWS).")}catch(r){return console.error(r.message,r),{header:null,payload:null,signature:null}}};exports.jwtDecode=jwtDecode;var hs256Sign=function(r,e){var t=_crypto.default.createSecretKey(e,"base64url"),a=_crypto.default.createHmac("sha256",t);a.update(r,"ascii");var o=a.digest();return Buffer.from(o).toString("base64url")};exports.hs256Sign=hs256Sign;var rs256JWKSign=function(r,e){var t;if(!_crypto.default.getHashes().includes("RSA-SHA256"))throw console.error("RSA-SHA256 not found"),new Error("RSA-SHA256 isn't available in the current system.");try{try{t=JSON.parse(e)}catch(r){if(!JSON.stringify(e))throw new Error("Not valid JSON.");t=e}var a=_crypto.default.createPrivateKey({key:t,format:"jwk"});return _crypto.default.sign("sha256",Buffer.from(r),{key:a}).toString("base64url")}catch(r){r instanceof TypeError?t=e:console.error(r.message,r)}return null};exports.rs256JWKSign=rs256JWKSign;var rs256PEMSign=function(r,e,t){var a;if(!_crypto.default.getHashes().includes("RSA-SHA256"))return console.error("RSA-SHA256 not found"),null;try{a=_crypto.default.createPrivateKey({key:e,format:"pem"})}catch(r){if(r instanceof TypeError&&r.message.includes("Passphrase required for encrypted key")){if(!t)throw new Error("Need a passphrase since private key is encrypted");a=_crypto.default.createPrivateKey({key:e,format:"pem",passphrase:t})}}return _crypto.default.sign("sha256",Buffer.from(r),{key:a}).toString("base64url")};exports.rs256PEMSign=rs256PEMSign;var rs256JWKVerify=function(r,e){var t=r.split("."),a=t[0]+"."+t[1],o=t[2],s=_crypto.default.createPublicKey({key:e,format:"jwk"});return _crypto.default.verify(null,Buffer.from(a,"ascii"),{key:s},Buffer.from(o,"base64url"))};exports.rs256JWKVerify=rs256JWKVerify;var rs256PEMVerify=function(r,e){var t=r.split("."),a=t[0]+"."+t[1],o=t[2],s=_crypto.default.createPublicKey({key:e,format:"pem"});return _crypto.default.verify(null,Buffer.from(a,"ascii"),{key:s},Buffer.from(o,"base64url"))};exports.rs256PEMVerify=rs256PEMVerify;var hs256Verify=function(r,e,t){var a=r.split("."),o=a[0]+"."+a[1],s=a[2],i=_crypto.default.createSecretKey(e,"base64url");i=t&&Buffer.isEncoding(t)?_crypto.default.createSecretKey(e,t):_crypto.default.createSecretKey(e,"base64url");var n=_crypto.default.createHmac("sha256",i);n.update(o,"ascii");var f=n.digest();return Buffer.from(f).toString("base64url")===s};exports.hs256Verify=hs256Verify;var createHeaderPayload=function(r,e){if(Buffer.isEncoding("base64url")){var t,a;if("string"==typeof r)t=Buffer.from(r,"ascii").toString("base64url");else{var o=parseToJSON(r);t=base64URLEncode(o)}if("string"==typeof e)a=Buffer.from(e,"ascii").toString("base64url");else{var s=parseToJSON(e);a=base64URLEncode(s)}return"".concat(t,".").concat(a)}throw new Error("Error: Base64URL encoding isn't available.")};exports.createHeaderPayload=createHeaderPayload;var base64URLEncode=function(r){if(Buffer.isEncoding("base64url")){var e=JSON.stringify(r);return Buffer.from(e,"ascii").toString("base64url")}throw new Error("Error: Base64URL encoding isn't available")};exports.base64URLEncode=base64URLEncode;var parseToJSON=function(r){if(Buffer.isEncoding("base64url"))return r instanceof Object?r:JSON.parse(r);throw new Error("Error: Base64URL encoding isn't available")};exports.parseToJSON=parseToJSON;var jwtEncode=function(r,e,t,a){var o=r;if(Buffer.isEncoding("base64url")){if(r instanceof Object){o=r;var s=JSON.stringify(r);Buffer.from(s,"ascii").toString("base64url")}else o=JSON.parse(r),Buffer.from(r,"ascii").toString("base64url");var i,n=createHeaderPayload(r,e),f=o.alg;if(f){switch(f.toLowerCase()){case"hs256":i=hs256Sign(n,t);break;case"rs256":if(!a||!a.keyFormat)throw new Error("Need to specify keyFormat in options for RS256 algorithm as either jwk or pem.");var c=a.keyFormat;"jwk"===c.toLowerCase()?i=rs256JWKSign(n,t):"pem"===c.toLowerCase()&&(i=a.passphrase?rs256PEMSign(n,t,a.passphrase):rs256PEMSign(n,t));break;default:throw new Error("Unsupported alg: ".concat(f))}return n+"."+i}throw new Error("Algorithm couldn't be determined. alg:"+f)}throw new Error("Error: Base64URL encoding isn't available.")};exports.jwtEncode=jwtEncode;var _default=jwtDecode;exports.default=_default; diff --git a/package-lock.json b/package-lock.json index fc3448c..bf4e11a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,13 @@ { "name": "jwt-authn", - "version": "1.0.35", + "version": "1.0.39", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "jwt-authn", - "version": "1.0.35", - "license": "GNU GPLv3", + "version": "1.0.39", + "license": "MIT-Modern-Variant", "devDependencies": { "@babel/cli": "^7.13.14", "@babel/core": "^7.13.14", @@ -19,6 +19,7 @@ "chai": "^4.3.4", "core-js": "^3.10.0", "cross-env": "^7.0.3", + "minify": "^7.0.1", "mocha": "^8.3.2", "nyc": "^15.1.0" }, @@ -1834,6 +1835,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -2074,6 +2085,27 @@ "node": ">=0.10.0" } }, + "node_modules/clean-css": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.1.2.tgz", + "integrity": "sha512-QcaGg9OuMo+0Ds933yLOY+gHPWbxhxqF0HDexmToPf8pczvmvZGYzd+QqWp9/mkucAOKViI+dSFOqoZIvXbeBw==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/clean-css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -2293,6 +2325,18 @@ "node": ">= 8" } }, + "node_modules/css-b64-images": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/css-b64-images/-/css-b64-images-0.2.5.tgz", + "integrity": "sha1-QgBdgyBLK0pdk7axpWRBM7WSegI=", + "dev": true, + "bin": { + "css-b64-images": "bin/css-b64-images" + }, + "engines": { + "node": "*" + } + }, "node_modules/debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -2388,6 +2432,16 @@ "node": ">=0.3.1" } }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/electron-to-chromium": { "version": "1.3.717", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz", @@ -3035,6 +3089,71 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "node_modules/html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/html-minifier-terser/node_modules/clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/html-minifier-terser/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/html-minifier-terser/node_modules/terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/html-minifier-terser/node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -3603,6 +3722,15 @@ "node": ">=8" } }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -3761,6 +3889,26 @@ "node": ">=0.10.0" } }, + "node_modules/minify": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/minify/-/minify-7.0.1.tgz", + "integrity": "sha512-U3CjnPKRjPu3DxZX7NsB833r2ijbw9af3fHsaChn6o7BHKvaT/zxYDQ8Q/3W7VFXGDrnkAx6XBx3ggEf5KJm7A==", + "dev": true, + "dependencies": { + "clean-css": "^5.0.1", + "css-b64-images": "~0.2.5", + "debug": "^4.1.0", + "html-minifier-terser": "^5.1.1", + "terser": "^5.3.2", + "try-to-catch": "^3.0.0" + }, + "bin": { + "minify": "bin/minify.js" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -3999,6 +4147,16 @@ "node": ">=0.10.0" } }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node_modules/node-modules-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", @@ -4480,6 +4638,26 @@ "node": ">=8" } }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "node_modules/pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -4790,6 +4968,15 @@ "jsesc": "bin/jsesc" } }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -5490,6 +5677,38 @@ "node": ">=4" } }, + "node_modules/terser": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", + "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/terser/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -5576,6 +5795,21 @@ "node": ">=0.12.0" } }, + "node_modules/try-to-catch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/try-to-catch/-/try-to-catch-3.0.0.tgz", + "integrity": "sha512-eIm6ZXwR35jVF8By/HdbbkcaCDTBI5PpCPkejRKrYp0jyf/DbCCcRhHD7/O9jtFI3ewsqo9WctFEiJTS6i+CQA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -7525,6 +7759,16 @@ "get-intrinsic": "^1.0.2" } }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -7717,6 +7961,23 @@ } } }, + "clean-css": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.1.2.tgz", + "integrity": "sha512-QcaGg9OuMo+0Ds933yLOY+gHPWbxhxqF0HDexmToPf8pczvmvZGYzd+QqWp9/mkucAOKViI+dSFOqoZIvXbeBw==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -7892,6 +8153,12 @@ "which": "^2.0.1" } }, + "css-b64-images": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/css-b64-images/-/css-b64-images-0.2.5.tgz", + "integrity": "sha1-QgBdgyBLK0pdk7axpWRBM7WSegI=", + "dev": true + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -7958,6 +8225,16 @@ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "electron-to-chromium": { "version": "1.3.717", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.717.tgz", @@ -8451,6 +8728,57 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "html-minifier-terser": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", + "dev": true, + "requires": { + "camel-case": "^4.1.1", + "clean-css": "^4.2.3", + "commander": "^4.1.1", + "he": "^1.2.0", + "param-case": "^3.0.3", + "relateurl": "^0.2.7", + "terser": "^4.6.3" + }, + "dependencies": { + "clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + } + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -8888,6 +9216,15 @@ } } }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -9021,6 +9358,20 @@ } } }, + "minify": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/minify/-/minify-7.0.1.tgz", + "integrity": "sha512-U3CjnPKRjPu3DxZX7NsB833r2ijbw9af3fHsaChn6o7BHKvaT/zxYDQ8Q/3W7VFXGDrnkAx6XBx3ggEf5KJm7A==", + "dev": true, + "requires": { + "clean-css": "^5.0.1", + "css-b64-images": "~0.2.5", + "debug": "^4.1.0", + "html-minifier-terser": "^5.1.1", + "terser": "^5.3.2", + "try-to-catch": "^3.0.0" + } + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -9193,6 +9544,16 @@ "to-regex": "^3.0.1" } }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, "node-modules-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", @@ -9566,6 +9927,26 @@ "release-zalgo": "^1.0.0" } }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", @@ -9814,6 +10195,12 @@ } } }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -10385,6 +10772,31 @@ "has-flag": "^3.0.0" } }, + "terser": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.6.1.tgz", + "integrity": "sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.19" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -10454,6 +10866,18 @@ } } }, + "try-to-catch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/try-to-catch/-/try-to-catch-3.0.0.tgz", + "integrity": "sha512-eIm6ZXwR35jVF8By/HdbbkcaCDTBI5PpCPkejRKrYp0jyf/DbCCcRhHD7/O9jtFI3ewsqo9WctFEiJTS6i+CQA==", + "dev": true + }, + "tslib": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", + "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", + "dev": true + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", diff --git a/package.json b/package.json index a7b87fb..df1b304 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "JWT decoder, encoder, and more with only Node >=15.x as a dependency.", "main": "./lib", "scripts": { - "build": "babel ./src -d ./lib", + "build": "babel ./src -d ./lib && minify ./lib/index.js > ./lib/index.min.js", "test": "cross-env NODE_ENV=test nyc mocha test", "prepublish": "npm run build" }, @@ -60,6 +60,7 @@ "chai": "^4.3.4", "core-js": "^3.10.0", "cross-env": "^7.0.3", + "minify": "^7.0.1", "mocha": "^8.3.2", "nyc": "^15.1.0" }, From fde032329b2565af1820bffb3f5d3035eb008cb8 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 24 Apr 2021 16:38:28 -0500 Subject: [PATCH 05/20] add rate this package badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a9f9f4c..d99dd83 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ ![GitHub watchers](https://img.shields.io/github/watchers/akdombrowski/jwt-authn?style=for-the-badge&logo=github) [![](https://data.jsdelivr.com/v1/package/npm/jwt-authn/badge)](https://www.jsdelivr.com/package/npm/jwt-authn) +[![Rate on Openbase](https://badges.openbase.com/js/rating/jwt-authn.svg)](https://openbase.com/js/jwt-authn?utm_source=embedded&utm_medium=badge&utm_campaign=rate-badge) + # jwt-authn jwt-authn is an npm package for dealing with JSON Web Tokens. Encoding, decoding, verifying, signing, and more coming. It includes support for the RS256 and HS256 algorithms and JWK and PEM format keys (even encrypted keys). No package dependencies! Its only dependency is NodeJS itself. From c05499472e48922e0f4f33f2aae263ade5173f99 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 24 Apr 2021 16:44:09 -0500 Subject: [PATCH 06/20] Increase time limit on test when generating keys --- test/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/index.js b/test/index.js index 32eef34..cd4afa5 100644 --- a/test/index.js +++ b/test/index.js @@ -376,7 +376,7 @@ g8W+z36ROKfkVVbmEVHY1Kg9yMo7oKYZEIa5AcAZyxxDoedT0jnlBRaWLtM=\n-----END RSA PRIVA // Check that we can verify our JWT using the public key that's paired with the private key we used to sign the JWT. expect(rs256PEMVerify(encoded, publicKey)).to.be.true; done(); - }).timeout(3000); + }).timeout(10000); }); }); }); From 3c19bbefdbff513340956e2adf4738d6d6979a93 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Thu, 29 Apr 2021 10:23:55 -0500 Subject: [PATCH 07/20] added cli support. added dependency on clipboardy --- cli/index.js | 43 ++++++ cli_lib/index.js | 43 ++++++ package-lock.json | 384 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 7 +- 4 files changed, 462 insertions(+), 15 deletions(-) create mode 100644 cli/index.js create mode 100644 cli_lib/index.js diff --git a/cli/index.js b/cli/index.js new file mode 100644 index 0000000..a85df29 --- /dev/null +++ b/cli/index.js @@ -0,0 +1,43 @@ +#!/usr/bin/env node + +import { jwtDecode } from "../lib"; +import clipboardy from "clipboardy"; + +const clipboard = clipboardy.readSync(); +const arg1 = process.argv[1]; +const arg2 = process.argv[2]; + +if (arg2 === "-c" || arg2 === "--clipboard" || !arg2) { + if (clipboard) { + try { + const decoded = jwtDecode(clipboard); + console.log("Decoding: \n" + clipboard); + console.log(decoded); + } catch (e) { + console.err( + "Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard" + ); + } + } else { + console.err( + "Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard" + ); + } +} else if (arg2) { + console.log("arg1"); + console.log(arg1); + console.log("arg1"); + console.log("arg2"); + console.log(arg2); + console.log("arg2"); + try { + console.log("Decoding: \n" + arg2); + console.log(jwtDecode(arg2)); + } catch (e) { + console.err(e, e.message); + } +} else { + console.err( + "Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard" + ); +} diff --git a/cli_lib/index.js b/cli_lib/index.js new file mode 100644 index 0000000..d5eb97f --- /dev/null +++ b/cli_lib/index.js @@ -0,0 +1,43 @@ +#!/usr/bin/env node +"use strict"; + +var _lib = require("../lib"); + +var _clipboardy = _interopRequireDefault(require("clipboardy")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + +var clipboard = _clipboardy["default"].readSync(); + +var arg1 = process.argv[1]; +var arg2 = process.argv[2]; + +if (arg2 === "-c" || arg2 === "--clipboard" || !arg2) { + if (clipboard) { + try { + var decoded = (0, _lib.jwtDecode)(clipboard); + console.log("Decoding: \n" + clipboard); + console.log(decoded); + } catch (e) { + console.err("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"); + } + } else { + console.err("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); + } +} else if (arg2) { + console.log("arg1"); + console.log(arg1); + console.log("arg1"); + console.log("arg2"); + console.log(arg2); + console.log("arg2"); + + try { + console.log("Decoding: \n" + arg2); + console.log((0, _lib.jwtDecode)(arg2)); + } catch (e) { + console.err(e, e.message); + } +} else { + console.err("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index bf4e11a..5978741 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,12 @@ "name": "jwt-authn", "version": "1.0.39", "license": "MIT-Modern-Variant", + "dependencies": { + "clipboardy": "^2.3.0" + }, + "bin": { + "jwt-authn": "cli_lib/index.js" + }, "devDependencies": { "@babel/cli": "^7.13.14", "@babel/core": "^7.13.14", @@ -1508,6 +1514,25 @@ "node": ">=8" } }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -2115,6 +2140,19 @@ "node": ">=6" } }, + "node_modules/clipboardy": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", + "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", + "dependencies": { + "arch": "^2.1.1", + "execa": "^1.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -2454,6 +2492,14 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -2500,6 +2546,92 @@ "node": ">=0.10.0" } }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/execa/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "engines": { + "node": ">=4" + } + }, + "node_modules/execa/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/execa/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -2905,6 +3037,17 @@ "node": ">=8.0.0" } }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -3261,6 +3404,20 @@ "node": ">=0.10.0" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", @@ -3376,6 +3533,17 @@ "node": ">=0.10.0" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -3386,8 +3554,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "node_modules/isobject": { "version": "3.0.1", @@ -4147,6 +4314,11 @@ "node": ">=0.10.0" } }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -4193,6 +4365,25 @@ "node": ">=0.10.0" } }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "engines": { + "node": ">=4" + } + }, "node_modules/nyc": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", @@ -4570,11 +4761,18 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "dependencies": { "wrappy": "1" } }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -4837,6 +5035,15 @@ "node": ">=8" } }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -5189,8 +5396,7 @@ "node_modules/signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "node_modules/slash": { "version": "2.0.0", @@ -5653,6 +5859,14 @@ "node": ">=8" } }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -6133,8 +6347,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/write-file-atomic": { "version": "3.0.3", @@ -7501,6 +7714,11 @@ "default-require-extensions": "^3.0.0" } }, + "arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==" + }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", @@ -7984,6 +8202,16 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, + "clipboardy": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", + "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", + "requires": { + "arch": "^2.1.1", + "execa": "^1.0.0", + "is-wsl": "^2.1.1" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -8247,6 +8475,14 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -8277,6 +8513,70 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -8588,6 +8888,14 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -8865,6 +9173,11 @@ "kind-of": "^6.0.2" } }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==" + }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", @@ -8952,6 +9265,14 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "requires": { + "is-docker": "^2.0.0" + } + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -8962,8 +9283,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isobject": { "version": "3.0.1", @@ -9544,6 +9864,11 @@ "to-regex": "^3.0.1" } }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, "no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -9581,6 +9906,21 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + } + } + }, "nyc": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", @@ -9877,11 +10217,15 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -10080,6 +10424,15 @@ "fromentries": "^1.2.0" } }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -10369,8 +10722,7 @@ "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "slash": { "version": "2.0.0", @@ -10757,6 +11109,11 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -11129,8 +11486,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-file-atomic": { "version": "3.0.3", diff --git a/package.json b/package.json index df1b304..2fa458a 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,9 @@ "description": "JWT decoder, encoder, and more with only Node >=15.x as a dependency.", "main": "./lib", "scripts": { - "build": "babel ./src -d ./lib && minify ./lib/index.js > ./lib/index.min.js", + "build": "babel ./src -d ./lib && babel ./cli -d ./cli_lib && minify ./lib/index.js > ./lib/index.min.js", "test": "cross-env NODE_ENV=test nyc mocha test", + "cli-test": "jwt-authn \"abc\"", "prepublish": "npm run build" }, "repository": { @@ -76,5 +77,9 @@ }, "engines": { "node": ">=15.0" + }, + "bin": "./cli_lib/index.js", + "dependencies": { + "clipboardy": "^2.3.0" } } From 2be6f6cd9a1107b7baf912cb630b3d94d9fa65ad Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Thu, 29 Apr 2021 15:40:34 -0500 Subject: [PATCH 08/20] cli works --- .babelrc | 13 ++-- cli/index.js | 74 ++++++++++++++--------- cli/index.min.js | 2 + cli_lib/index.js | 151 ++++++++++++++++++++++++++++++++++++---------- lib/index.js | 38 ++++++++---- lib/index.min.js | 2 +- package-lock.json | 32 ++++++++++ package.json | 7 ++- src/index.js | 27 +++++++-- 9 files changed, 256 insertions(+), 90 deletions(-) create mode 100644 cli/index.min.js diff --git a/.babelrc b/.babelrc index b3c8fbb..64f0844 100644 --- a/.babelrc +++ b/.babelrc @@ -1,12 +1,9 @@ { - "presets": [ - "@babel/preset-env" - ], + "presets": ["@babel/preset-env"], "env": { "test": { - "plugins": [ - "istanbul" - ] + "plugins": ["istanbul"] } - } -} \ No newline at end of file + }, + "plugins": ["@babel/plugin-transform-runtime"] +} diff --git a/cli/index.js b/cli/index.js index a85df29..72180b5 100644 --- a/cli/index.js +++ b/cli/index.js @@ -3,41 +3,57 @@ import { jwtDecode } from "../lib"; import clipboardy from "clipboardy"; +// read from clipboard const clipboard = clipboardy.readSync(); -const arg1 = process.argv[1]; +// read passed in argument const arg2 = process.argv[2]; -if (arg2 === "-c" || arg2 === "--clipboard" || !arg2) { - if (clipboard) { +const decode = async (jwt) => { + const decoded = await jwtDecode(jwt); + + console.log("Decoding: \n" + clipboard + "\n" + decoded); + + return decoded; +}; + +const cli = async (clipboard, arg2) => { + if (arg2 == "-h" || arg2 === "--help") { + console.log( + "use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard" + ); + console.log("or call command with JWT as first argument"); + } else if (arg2 === "-c" || arg2 === "--clipboard" || !arg2) { + if (clipboard) { + try { + await decode(clipboard); + } catch (e) { + console.error("I found an error :(."); + console.error( + "Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard" + ); + console.error("what's on your clipboard? "); + console.error(clipboard); + } + } else { + console.error("I found an error :(."); + console.error( + "Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard" + ); + } + } else if (arg2) { try { - const decoded = jwtDecode(clipboard); - console.log("Decoding: \n" + clipboard); - console.log(decoded); + console.log("Decoding: \n" + arg2); + console.log(jwtDecode(arg2)); } catch (e) { - console.err( - "Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard" - ); + console.error("I found an error :(."); + console.error(e, e.message); } } else { - console.err( - "Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard" + console.error("I found an error :(."); + console.error( + "Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard" ); } -} else if (arg2) { - console.log("arg1"); - console.log(arg1); - console.log("arg1"); - console.log("arg2"); - console.log(arg2); - console.log("arg2"); - try { - console.log("Decoding: \n" + arg2); - console.log(jwtDecode(arg2)); - } catch (e) { - console.err(e, e.message); - } -} else { - console.err( - "Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard" - ); -} +}; + +cli(clipboard, arg2); diff --git a/cli/index.min.js b/cli/index.min.js new file mode 100644 index 0000000..634d230 --- /dev/null +++ b/cli/index.min.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +import{jwtDecode}from"../lib";import clipboardy from"clipboardy";const clipboard=clipboardy.readSync(),arg2=process.argv[2],decode=async o=>{const r=await jwtDecode(o);return console.log("Decoding: \n"+clipboard+"\n"+r),r},cli=async(o,r)=>{if("-h"==r||"--help"===r)console.log("use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard"),console.log("or call command with JWT as first argument");else if("-c"!==r&&"--clipboard"!==r&&r)if(r)try{console.log("Decoding: \n"+r),console.log(jwtDecode(r))}catch(o){console.error("I found an error :(."),console.error(o,o.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard");else if(o)try{await decode(o)}catch(r){console.error("I found an error :(."),console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"),console.error("what's on your clipboard? "),console.error(o)}else console.error("I found an error :(."),console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard")};cli(clipboard,arg2); diff --git a/cli_lib/index.js b/cli_lib/index.js index d5eb97f..97503c8 100644 --- a/cli_lib/index.js +++ b/cli_lib/index.js @@ -1,43 +1,130 @@ #!/usr/bin/env node "use strict"; +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); + +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); + var _lib = require("../lib"); var _clipboardy = _interopRequireDefault(require("clipboardy")); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } +// read from clipboard +var clipboard = _clipboardy["default"].readSync(); // read passed in argument -var clipboard = _clipboardy["default"].readSync(); -var arg1 = process.argv[1]; var arg2 = process.argv[2]; -if (arg2 === "-c" || arg2 === "--clipboard" || !arg2) { - if (clipboard) { - try { - var decoded = (0, _lib.jwtDecode)(clipboard); - console.log("Decoding: \n" + clipboard); - console.log(decoded); - } catch (e) { - console.err("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"); - } - } else { - console.err("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); - } -} else if (arg2) { - console.log("arg1"); - console.log(arg1); - console.log("arg1"); - console.log("arg2"); - console.log(arg2); - console.log("arg2"); - - try { - console.log("Decoding: \n" + arg2); - console.log((0, _lib.jwtDecode)(arg2)); - } catch (e) { - console.err(e, e.message); - } -} else { - console.err("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); -} \ No newline at end of file +var decode = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(jwt) { + var decoded; + return _regenerator["default"].wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return (0, _lib.jwtDecode)(jwt); + + case 2: + decoded = _context.sent; + console.log("Decoding: \n" + clipboard + "\n" + decoded); + return _context.abrupt("return", decoded); + + case 5: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function decode(_x) { + return _ref.apply(this, arguments); + }; +}(); + +var cli = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(clipboard, arg2) { + return _regenerator["default"].wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (!(arg2 == "-h" || arg2 === "--help")) { + _context2.next = 5; + break; + } + + console.log("use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard"); + console.log("or call command with JWT as first argument"); + _context2.next = 25; + break; + + case 5: + if (!(arg2 === "-c" || arg2 === "--clipboard" || !arg2)) { + _context2.next = 24; + break; + } + + if (!clipboard) { + _context2.next = 20; + break; + } + + _context2.prev = 7; + _context2.next = 10; + return decode(clipboard); + + case 10: + _context2.next = 18; + break; + + case 12: + _context2.prev = 12; + _context2.t0 = _context2["catch"](7); + console.error("I found an error :(."); + console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"); + console.error("what's on your clipboard? "); + console.error(clipboard); + + case 18: + _context2.next = 22; + break; + + case 20: + console.error("I found an error :(."); + console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"); + + case 22: + _context2.next = 25; + break; + + case 24: + if (arg2) { + try { + console.log("Decoding: \n" + arg2); + console.log((0, _lib.jwtDecode)(arg2)); + } catch (e) { + console.error("I found an error :(."); + console.error(e, e.message); + } + } else { + console.error("I found an error :(."); + console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); + } + + case 25: + case "end": + return _context2.stop(); + } + } + }, _callee2, null, [[7, 12]]); + })); + + return function cli(_x2, _x3) { + return _ref2.apply(this, arguments); + }; +}(); + +cli(clipboard, arg2); \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index e5c0d72..744c2cd 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,5 +1,7 @@ "use strict"; +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + Object.defineProperty(exports, "__esModule", { value: true }); @@ -7,8 +9,6 @@ exports["default"] = exports.jwtEncode = exports.parseToJSON = exports.base64URL var _crypto = _interopRequireDefault(require("crypto")); -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - /** * Decodes a JWT that is in JWS format. * @@ -35,8 +35,8 @@ var jwtDecode = function jwtDecode(jwt) { var base64URLDecodedHeader = Buffer.from(header, "base64url").toString("utf8"); if (!base64URLDecodedHeader) { - console.err("base64URLDecodedHeader"); - console.err(base64URLDecodedHeader); + console.error("base64URLDecodedHeader"); + console.error(base64URLDecodedHeader); throw new Error("Header isn't base64url encoded"); } // 4. Verify that the resulting octet sequence is a UTF-8-encoded // representation of a completely valid JSON object conforming to @@ -81,16 +81,28 @@ var jwtDecode = function jwtDecode(jwt) { }; } - throw new Error("Not using compact serialization (JWS)."); + throw new SyntaxError("Not using compact serialization (JWS)."); } catch (e) { - console.error(e.message, e); - return { - header: null, - payload: null, - signature: null - }; + // debugging(e); + console.error("I found an error :(."); + throw e; } }; + +exports.jwtDecode = jwtDecode; + +var debugging = function debugging(e) { + // debugging + console.error(e.message, e); + console.error("e instanceof SyntaxError"); + console.error(e instanceof SyntaxError); + console.error(e.message); + console.error(e.name); + console.error(e.fileName); + console.error(e.lineNumber); + console.error(e.columnNumber); + console.error(e.stack); +}; /** * Uses HMAC with SHA256 to create the signature of a JWT. * @@ -102,8 +114,6 @@ var jwtDecode = function jwtDecode(jwt) { */ -exports.jwtDecode = jwtDecode; - var hs256Sign = function hs256Sign(headerPayload, key) { var secret = _crypto["default"].createSecretKey(key, "base64url"); @@ -162,10 +172,12 @@ var rs256JWKSign = function rs256JWKSign(headerPayload, privateKey) { if (e instanceof TypeError) { secret = privateKey; } else { + console.error("I found an error :(."); console.error(e.message, e); } } } else { + console.error("I found an error :(."); console.error("RSA-SHA256 not found"); throw new Error("RSA-SHA256 isn't available in the current system."); } diff --git a/lib/index.min.js b/lib/index.min.js index d39e479..9dacb08 100644 --- a/lib/index.min.js +++ b/lib/index.min.js @@ -1 +1 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.jwtEncode=exports.parseToJSON=exports.base64URLEncode=exports.createHeaderPayload=exports.hs256Verify=exports.rs256PEMVerify=exports.rs256JWKVerify=exports.rs256PEMSign=exports.rs256JWKSign=exports.hs256Sign=exports.jwtDecode=void 0;var _crypto=_interopRequireDefault(require("crypto"));function _interopRequireDefault(r){return r&&r.__esModule?r:{default:r}}var jwtDecode=function(r){try{if(!r.includes("."))throw new Error("Need at least one '.'");var e=r.split("."),t=e[0],a=Buffer.from(t,"base64url").toString("utf8");if(!a)throw console.err("base64URLDecodedHeader"),console.err(a),new Error("Header isn't base64url encoded");var o=JSON.parse(a),s=o.typ,i=o.cty,n=o.alg;if(s&&"JWT"!==s)throw new Error("Need to be type jwt. Received: ".concat(s));if(i&&"JWT"!==i)throw new Error("Need a cty of 'JWT'. Received: ".concat(i));if(!n)throw new Error("Missing algorithm in JOSE header.");if(3===e.length){var f=e[1],c=Buffer.from(f,"base64url").toString("utf8");return{header:o,payload:JSON.parse(c),signature:e[2]}}throw new Error("Not using compact serialization (JWS).")}catch(r){return console.error(r.message,r),{header:null,payload:null,signature:null}}};exports.jwtDecode=jwtDecode;var hs256Sign=function(r,e){var t=_crypto.default.createSecretKey(e,"base64url"),a=_crypto.default.createHmac("sha256",t);a.update(r,"ascii");var o=a.digest();return Buffer.from(o).toString("base64url")};exports.hs256Sign=hs256Sign;var rs256JWKSign=function(r,e){var t;if(!_crypto.default.getHashes().includes("RSA-SHA256"))throw console.error("RSA-SHA256 not found"),new Error("RSA-SHA256 isn't available in the current system.");try{try{t=JSON.parse(e)}catch(r){if(!JSON.stringify(e))throw new Error("Not valid JSON.");t=e}var a=_crypto.default.createPrivateKey({key:t,format:"jwk"});return _crypto.default.sign("sha256",Buffer.from(r),{key:a}).toString("base64url")}catch(r){r instanceof TypeError?t=e:console.error(r.message,r)}return null};exports.rs256JWKSign=rs256JWKSign;var rs256PEMSign=function(r,e,t){var a;if(!_crypto.default.getHashes().includes("RSA-SHA256"))return console.error("RSA-SHA256 not found"),null;try{a=_crypto.default.createPrivateKey({key:e,format:"pem"})}catch(r){if(r instanceof TypeError&&r.message.includes("Passphrase required for encrypted key")){if(!t)throw new Error("Need a passphrase since private key is encrypted");a=_crypto.default.createPrivateKey({key:e,format:"pem",passphrase:t})}}return _crypto.default.sign("sha256",Buffer.from(r),{key:a}).toString("base64url")};exports.rs256PEMSign=rs256PEMSign;var rs256JWKVerify=function(r,e){var t=r.split("."),a=t[0]+"."+t[1],o=t[2],s=_crypto.default.createPublicKey({key:e,format:"jwk"});return _crypto.default.verify(null,Buffer.from(a,"ascii"),{key:s},Buffer.from(o,"base64url"))};exports.rs256JWKVerify=rs256JWKVerify;var rs256PEMVerify=function(r,e){var t=r.split("."),a=t[0]+"."+t[1],o=t[2],s=_crypto.default.createPublicKey({key:e,format:"pem"});return _crypto.default.verify(null,Buffer.from(a,"ascii"),{key:s},Buffer.from(o,"base64url"))};exports.rs256PEMVerify=rs256PEMVerify;var hs256Verify=function(r,e,t){var a=r.split("."),o=a[0]+"."+a[1],s=a[2],i=_crypto.default.createSecretKey(e,"base64url");i=t&&Buffer.isEncoding(t)?_crypto.default.createSecretKey(e,t):_crypto.default.createSecretKey(e,"base64url");var n=_crypto.default.createHmac("sha256",i);n.update(o,"ascii");var f=n.digest();return Buffer.from(f).toString("base64url")===s};exports.hs256Verify=hs256Verify;var createHeaderPayload=function(r,e){if(Buffer.isEncoding("base64url")){var t,a;if("string"==typeof r)t=Buffer.from(r,"ascii").toString("base64url");else{var o=parseToJSON(r);t=base64URLEncode(o)}if("string"==typeof e)a=Buffer.from(e,"ascii").toString("base64url");else{var s=parseToJSON(e);a=base64URLEncode(s)}return"".concat(t,".").concat(a)}throw new Error("Error: Base64URL encoding isn't available.")};exports.createHeaderPayload=createHeaderPayload;var base64URLEncode=function(r){if(Buffer.isEncoding("base64url")){var e=JSON.stringify(r);return Buffer.from(e,"ascii").toString("base64url")}throw new Error("Error: Base64URL encoding isn't available")};exports.base64URLEncode=base64URLEncode;var parseToJSON=function(r){if(Buffer.isEncoding("base64url"))return r instanceof Object?r:JSON.parse(r);throw new Error("Error: Base64URL encoding isn't available")};exports.parseToJSON=parseToJSON;var jwtEncode=function(r,e,t,a){var o=r;if(Buffer.isEncoding("base64url")){if(r instanceof Object){o=r;var s=JSON.stringify(r);Buffer.from(s,"ascii").toString("base64url")}else o=JSON.parse(r),Buffer.from(r,"ascii").toString("base64url");var i,n=createHeaderPayload(r,e),f=o.alg;if(f){switch(f.toLowerCase()){case"hs256":i=hs256Sign(n,t);break;case"rs256":if(!a||!a.keyFormat)throw new Error("Need to specify keyFormat in options for RS256 algorithm as either jwk or pem.");var c=a.keyFormat;"jwk"===c.toLowerCase()?i=rs256JWKSign(n,t):"pem"===c.toLowerCase()&&(i=a.passphrase?rs256PEMSign(n,t,a.passphrase):rs256PEMSign(n,t));break;default:throw new Error("Unsupported alg: ".concat(f))}return n+"."+i}throw new Error("Algorithm couldn't be determined. alg:"+f)}throw new Error("Error: Base64URL encoding isn't available.")};exports.jwtEncode=jwtEncode;var _default=jwtDecode;exports.default=_default; +"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.jwtEncode=exports.parseToJSON=exports.base64URLEncode=exports.createHeaderPayload=exports.hs256Verify=exports.rs256PEMVerify=exports.rs256JWKVerify=exports.rs256PEMSign=exports.rs256JWKSign=exports.hs256Sign=exports.jwtDecode=void 0;var _crypto=_interopRequireDefault(require("crypto")),jwtDecode=function(r){try{if(!r.includes("."))throw new Error("Need at least one '.'");var e=r.split("."),o=e[0],t=Buffer.from(o,"base64url").toString("utf8");if(!t)throw console.error("base64URLDecodedHeader"),console.error(t),new Error("Header isn't base64url encoded");var a=JSON.parse(t),s=a.typ,n=a.cty,i=a.alg;if(s&&"JWT"!==s)throw new Error("Need to be type jwt. Received: ".concat(s));if(n&&"JWT"!==n)throw new Error("Need a cty of 'JWT'. Received: ".concat(n));if(!i)throw new Error("Missing algorithm in JOSE header.");if(3===e.length){var c=e[1],f=Buffer.from(c,"base64url").toString("utf8");return{header:a,payload:JSON.parse(f),signature:e[2]}}throw new SyntaxError("Not using compact serialization (JWS).")}catch(r){throw console.error("I found an error :(."),r}};exports.jwtDecode=jwtDecode;var debugging=function(r){console.error(r.message,r),console.error("e instanceof SyntaxError"),console.error(r instanceof SyntaxError),console.error(r.message),console.error(r.name),console.error(r.fileName),console.error(r.lineNumber),console.error(r.columnNumber),console.error(r.stack)},hs256Sign=function(r,e){var o=_crypto.default.createSecretKey(e,"base64url"),t=_crypto.default.createHmac("sha256",o);t.update(r,"ascii");var a=t.digest();return Buffer.from(a).toString("base64url")};exports.hs256Sign=hs256Sign;var rs256JWKSign=function(r,e){var o;if(!_crypto.default.getHashes().includes("RSA-SHA256"))throw console.error("I found an error :(."),console.error("RSA-SHA256 not found"),new Error("RSA-SHA256 isn't available in the current system.");try{try{o=JSON.parse(e)}catch(r){if(!JSON.stringify(e))throw new Error("Not valid JSON.");o=e}var t=_crypto.default.createPrivateKey({key:o,format:"jwk"});return _crypto.default.sign("sha256",Buffer.from(r),{key:t}).toString("base64url")}catch(r){r instanceof TypeError?o=e:(console.error("I found an error :(."),console.error(r.message,r))}return null};exports.rs256JWKSign=rs256JWKSign;var rs256PEMSign=function(r,e,o){var t;if(!_crypto.default.getHashes().includes("RSA-SHA256"))return console.error("RSA-SHA256 not found"),null;try{t=_crypto.default.createPrivateKey({key:e,format:"pem"})}catch(r){if(r instanceof TypeError&&r.message.includes("Passphrase required for encrypted key")){if(!o)throw new Error("Need a passphrase since private key is encrypted");t=_crypto.default.createPrivateKey({key:e,format:"pem",passphrase:o})}}return _crypto.default.sign("sha256",Buffer.from(r),{key:t}).toString("base64url")};exports.rs256PEMSign=rs256PEMSign;var rs256JWKVerify=function(r,e){var o=r.split("."),t=o[0]+"."+o[1],a=o[2],s=_crypto.default.createPublicKey({key:e,format:"jwk"});return _crypto.default.verify(null,Buffer.from(t,"ascii"),{key:s},Buffer.from(a,"base64url"))};exports.rs256JWKVerify=rs256JWKVerify;var rs256PEMVerify=function(r,e){var o=r.split("."),t=o[0]+"."+o[1],a=o[2],s=_crypto.default.createPublicKey({key:e,format:"pem"});return _crypto.default.verify(null,Buffer.from(t,"ascii"),{key:s},Buffer.from(a,"base64url"))};exports.rs256PEMVerify=rs256PEMVerify;var hs256Verify=function(r,e,o){var t=r.split("."),a=t[0]+"."+t[1],s=t[2],n=_crypto.default.createSecretKey(e,"base64url");n=o&&Buffer.isEncoding(o)?_crypto.default.createSecretKey(e,o):_crypto.default.createSecretKey(e,"base64url");var i=_crypto.default.createHmac("sha256",n);i.update(a,"ascii");var c=i.digest();return Buffer.from(c).toString("base64url")===s};exports.hs256Verify=hs256Verify;var createHeaderPayload=function(r,e){if(Buffer.isEncoding("base64url")){var o,t;if("string"==typeof r)o=Buffer.from(r,"ascii").toString("base64url");else{var a=parseToJSON(r);o=base64URLEncode(a)}if("string"==typeof e)t=Buffer.from(e,"ascii").toString("base64url");else{var s=parseToJSON(e);t=base64URLEncode(s)}return"".concat(o,".").concat(t)}throw new Error("Error: Base64URL encoding isn't available.")};exports.createHeaderPayload=createHeaderPayload;var base64URLEncode=function(r){if(Buffer.isEncoding("base64url")){var e=JSON.stringify(r);return Buffer.from(e,"ascii").toString("base64url")}throw new Error("Error: Base64URL encoding isn't available")};exports.base64URLEncode=base64URLEncode;var parseToJSON=function(r){if(Buffer.isEncoding("base64url"))return r instanceof Object?r:JSON.parse(r);throw new Error("Error: Base64URL encoding isn't available")};exports.parseToJSON=parseToJSON;var jwtEncode=function(r,e,o,t){var a=r;if(Buffer.isEncoding("base64url")){if(r instanceof Object){a=r;var s=JSON.stringify(r);Buffer.from(s,"ascii").toString("base64url")}else a=JSON.parse(r),Buffer.from(r,"ascii").toString("base64url");var n,i=createHeaderPayload(r,e),c=a.alg;if(c){switch(c.toLowerCase()){case"hs256":n=hs256Sign(i,o);break;case"rs256":if(!t||!t.keyFormat)throw new Error("Need to specify keyFormat in options for RS256 algorithm as either jwk or pem.");var f=t.keyFormat;"jwk"===f.toLowerCase()?n=rs256JWKSign(i,o):"pem"===f.toLowerCase()&&(n=t.passphrase?rs256PEMSign(i,o,t.passphrase):rs256PEMSign(i,o));break;default:throw new Error("Unsupported alg: ".concat(c))}return i+"."+n}throw new Error("Algorithm couldn't be determined. alg:"+c)}throw new Error("Error: Base64URL encoding isn't available.")};exports.jwtEncode=jwtEncode;var _default=jwtDecode;exports.default=_default; diff --git a/package-lock.json b/package-lock.json index 5978741..a6986a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "devDependencies": { "@babel/cli": "^7.13.14", "@babel/core": "^7.13.14", + "@babel/plugin-transform-runtime": "^7.13.15", "@babel/preset-env": "^7.13.12", "@babel/register": "^7.13.14", "@istanbuljs/nyc-config-babel": "^3.0.0", @@ -1051,6 +1052,23 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz", + "integrity": "sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-plugin-utils": "^7.13.0", + "babel-plugin-polyfill-corejs2": "^0.2.0", + "babel-plugin-polyfill-corejs3": "^0.2.0", + "babel-plugin-polyfill-regenerator": "^0.2.0", + "semver": "^6.3.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", @@ -7322,6 +7340,20 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "@babel/plugin-transform-runtime": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz", + "integrity": "sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-plugin-utils": "^7.13.0", + "babel-plugin-polyfill-corejs2": "^0.2.0", + "babel-plugin-polyfill-corejs3": "^0.2.0", + "babel-plugin-polyfill-regenerator": "^0.2.0", + "semver": "^6.3.0" + } + }, "@babel/plugin-transform-shorthand-properties": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz", diff --git a/package.json b/package.json index 2fa458a..f746f26 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,12 @@ "description": "JWT decoder, encoder, and more with only Node >=15.x as a dependency.", "main": "./lib", "scripts": { - "build": "babel ./src -d ./lib && babel ./cli -d ./cli_lib && minify ./lib/index.js > ./lib/index.min.js", + "build": "npm run babelify && npm run minify", "test": "cross-env NODE_ENV=test nyc mocha test", "cli-test": "jwt-authn \"abc\"", - "prepublish": "npm run build" + "prepublish": "npm run build", + "babelify": "babel ./src -d ./lib && babel ./cli -d ./cli_lib", + "minify": "minify ./lib/index.js > ./lib/index.min.js && minify ./cli/index.js > ./cli/index.min.js" }, "repository": { "type": "git", @@ -53,6 +55,7 @@ "devDependencies": { "@babel/cli": "^7.13.14", "@babel/core": "^7.13.14", + "@babel/plugin-transform-runtime": "^7.13.15", "@babel/preset-env": "^7.13.12", "@babel/register": "^7.13.14", "@istanbuljs/nyc-config-babel": "^3.0.0", diff --git a/src/index.js b/src/index.js index 8125590..c3d0d8a 100644 --- a/src/index.js +++ b/src/index.js @@ -28,8 +28,8 @@ export const jwtDecode = (jwt) => { "utf8" ); if (!base64URLDecodedHeader) { - console.err("base64URLDecodedHeader"); - console.err(base64URLDecodedHeader); + console.error("base64URLDecodedHeader"); + console.error(base64URLDecodedHeader); throw new Error("Header isn't base64url encoded"); } @@ -75,13 +75,28 @@ export const jwtDecode = (jwt) => { }; } - throw new Error("Not using compact serialization (JWS)."); + throw new SyntaxError("Not using compact serialization (JWS)."); } catch (e) { - console.error(e.message, e); - return { header: null, payload: null, signature: null }; + // debugging(e); + + console.error("I found an error :(."); + throw e; } }; +const debugging = (e) => { + // debugging + console.error(e.message, e); + console.error("e instanceof SyntaxError"); + console.error(e instanceof SyntaxError); + console.error(e.message); + console.error(e.name); + console.error(e.fileName); + console.error(e.lineNumber); + console.error(e.columnNumber); + console.error(e.stack); +}; + /** * Uses HMAC with SHA256 to create the signature of a JWT. * @@ -140,10 +155,12 @@ export const rs256JWKSign = (headerPayload, privateKey) => { if (e instanceof TypeError) { secret = privateKey; } else { + console.error("I found an error :(."); console.error(e.message, e); } } } else { + console.error("I found an error :(."); console.error("RSA-SHA256 not found"); throw new Error("RSA-SHA256 isn't available in the current system."); } From 8bcba1d5e71078af8335fa7c90539d12effd741d Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Thu, 29 Apr 2021 15:47:18 -0500 Subject: [PATCH 09/20] cli with clipboard works --- cli/index.js | 11 ++--- cli/index.min.js | 2 +- cli_lib/index.js | 40 ++++++++-------- cli_lib/index.min.js | 109 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 26 deletions(-) create mode 100644 cli_lib/index.min.js diff --git a/cli/index.js b/cli/index.js index 72180b5..9b1607b 100644 --- a/cli/index.js +++ b/cli/index.js @@ -9,11 +9,7 @@ const clipboard = clipboardy.readSync(); const arg2 = process.argv[2]; const decode = async (jwt) => { - const decoded = await jwtDecode(jwt); - - console.log("Decoding: \n" + clipboard + "\n" + decoded); - - return decoded; + return await jwtDecode(jwt); }; const cli = async (clipboard, arg2) => { @@ -25,7 +21,9 @@ const cli = async (clipboard, arg2) => { } else if (arg2 === "-c" || arg2 === "--clipboard" || !arg2) { if (clipboard) { try { - await decode(clipboard); + const decoded = await decode(clipboard); + console.log("Decoding: \n" + clipboard); + console.log(decoded); } catch (e) { console.error("I found an error :(."); console.error( @@ -33,6 +31,7 @@ const cli = async (clipboard, arg2) => { ); console.error("what's on your clipboard? "); console.error(clipboard); + console.error(e, e.message); } } else { console.error("I found an error :(."); diff --git a/cli/index.min.js b/cli/index.min.js index 634d230..fd107cc 100644 --- a/cli/index.min.js +++ b/cli/index.min.js @@ -1,2 +1,2 @@ #!/usr/bin/env node -import{jwtDecode}from"../lib";import clipboardy from"clipboardy";const clipboard=clipboardy.readSync(),arg2=process.argv[2],decode=async o=>{const r=await jwtDecode(o);return console.log("Decoding: \n"+clipboard+"\n"+r),r},cli=async(o,r)=>{if("-h"==r||"--help"===r)console.log("use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard"),console.log("or call command with JWT as first argument");else if("-c"!==r&&"--clipboard"!==r&&r)if(r)try{console.log("Decoding: \n"+r),console.log(jwtDecode(r))}catch(o){console.error("I found an error :(."),console.error(o,o.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard");else if(o)try{await decode(o)}catch(r){console.error("I found an error :(."),console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"),console.error("what's on your clipboard? "),console.error(o)}else console.error("I found an error :(."),console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard")};cli(clipboard,arg2); +import{jwtDecode}from"../lib";import clipboardy from"clipboardy";const clipboard=clipboardy.readSync(),arg2=process.argv[2],decode=async o=>await jwtDecode(o),cli=async(o,r)=>{if("-h"==r||"--help"===r)console.log("use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard"),console.log("or call command with JWT as first argument");else if("-c"!==r&&"--clipboard"!==r&&r)if(r)try{console.log("Decoding: \n"+r),console.log(jwtDecode(r))}catch(o){console.error("I found an error :(."),console.error(o,o.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard");else if(o)try{const r=await decode(o);console.log("Decoding: \n"+o),console.log(r)}catch(r){console.error("I found an error :(."),console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"),console.error("what's on your clipboard? "),console.error(o),console.error(r,r.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard")};cli(clipboard,arg2); diff --git a/cli_lib/index.js b/cli_lib/index.js index 97503c8..71d2f13 100644 --- a/cli_lib/index.js +++ b/cli_lib/index.js @@ -19,7 +19,6 @@ var arg2 = process.argv[2]; var decode = /*#__PURE__*/function () { var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(jwt) { - var decoded; return _regenerator["default"].wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { @@ -28,11 +27,9 @@ var decode = /*#__PURE__*/function () { return (0, _lib.jwtDecode)(jwt); case 2: - decoded = _context.sent; - console.log("Decoding: \n" + clipboard + "\n" + decoded); - return _context.abrupt("return", decoded); + return _context.abrupt("return", _context.sent); - case 5: + case 3: case "end": return _context.stop(); } @@ -47,6 +44,7 @@ var decode = /*#__PURE__*/function () { var cli = /*#__PURE__*/function () { var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(clipboard, arg2) { + var decoded; return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { @@ -58,17 +56,17 @@ var cli = /*#__PURE__*/function () { console.log("use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard"); console.log("or call command with JWT as first argument"); - _context2.next = 25; + _context2.next = 29; break; case 5: if (!(arg2 === "-c" || arg2 === "--clipboard" || !arg2)) { - _context2.next = 24; + _context2.next = 28; break; } if (!clipboard) { - _context2.next = 20; + _context2.next = 24; break; } @@ -77,30 +75,34 @@ var cli = /*#__PURE__*/function () { return decode(clipboard); case 10: - _context2.next = 18; + decoded = _context2.sent; + console.log("Decoding: \n" + clipboard); + console.log(decoded); + _context2.next = 22; break; - case 12: - _context2.prev = 12; + case 15: + _context2.prev = 15; _context2.t0 = _context2["catch"](7); console.error("I found an error :(."); console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"); console.error("what's on your clipboard? "); console.error(clipboard); + console.error(_context2.t0, _context2.t0.message); - case 18: - _context2.next = 22; + case 22: + _context2.next = 26; break; - case 20: + case 24: console.error("I found an error :(."); console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"); - case 22: - _context2.next = 25; + case 26: + _context2.next = 29; break; - case 24: + case 28: if (arg2) { try { console.log("Decoding: \n" + arg2); @@ -114,12 +116,12 @@ var cli = /*#__PURE__*/function () { console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); } - case 25: + case 29: case "end": return _context2.stop(); } } - }, _callee2, null, [[7, 12]]); + }, _callee2, null, [[7, 15]]); })); return function cli(_x2, _x3) { diff --git a/cli_lib/index.min.js b/cli_lib/index.min.js new file mode 100644 index 0000000..ee3a6d9 --- /dev/null +++ b/cli_lib/index.min.js @@ -0,0 +1,109 @@ +#!/usr/bin/env node +"use strict"; + +var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); + +var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); + +var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); + +var _lib = require("../lib"); + +var _clipboardy = _interopRequireDefault(require("clipboardy")); + +var clipboard = _clipboardy["default"].readSync(), + arg2 = process.argv[2], + decode = /*#__PURE__*/function () { + var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(o) { + return _regenerator["default"].wrap(function _callee$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + _context.next = 2; + return (0, _lib.jwtDecode)(o); + + case 2: + case "end": + return _context.stop(); + } + } + }, _callee); + })); + + return function decode(_x) { + return _ref.apply(this, arguments); + }; +}(), + cli = /*#__PURE__*/function () { + var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(o, r) { + var _r; + + return _regenerator["default"].wrap(function _callee2$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + if (!("-h" == r || "--help" === r)) { + _context2.next = 4; + break; + } + + console.log("use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard"), console.log("or call command with JWT as first argument"); + _context2.next = 22; + break; + + case 4: + if (!("-c" !== r && "--clipboard" !== r && r)) { + _context2.next = 8; + break; + } + + if (r) try { + console.log("Decoding: \n" + r), console.log((0, _lib.jwtDecode)(r)); + } catch (o) { + console.error("I found an error :(."), console.error(o, o.message); + } else console.error("I found an error :(."), console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); + _context2.next = 22; + break; + + case 8: + if (!o) { + _context2.next = 21; + break; + } + + _context2.prev = 9; + _context2.next = 12; + return decode(o); + + case 12: + _r = _context2.sent; + console.log("Decoding: \n" + o), console.log(_r); + _context2.next = 19; + break; + + case 16: + _context2.prev = 16; + _context2.t0 = _context2["catch"](9); + console.error("I found an error :(."), console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"), console.error("what's on your clipboard? "), console.error(o), console.error(_context2.t0, _context2.t0.message); + + case 19: + _context2.next = 22; + break; + + case 21: + console.error("I found an error :(."), console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"); + + case 22: + case "end": + return _context2.stop(); + } + } + }, _callee2, null, [[9, 16]]); + })); + + return function cli(_x2, _x3) { + return _ref2.apply(this, arguments); + }; +}(); + +cli(clipboard, arg2); \ No newline at end of file From 31d4c36e2597a16ea97390e545a6ca456cf1b428 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Thu, 29 Apr 2021 15:49:28 -0500 Subject: [PATCH 10/20] only babelify index.js --- cli_lib/index.min.js | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cli_lib/index.min.js b/cli_lib/index.min.js index ee3a6d9..c90bbe4 100644 --- a/cli_lib/index.min.js +++ b/cli_lib/index.min.js @@ -23,6 +23,9 @@ var clipboard = _clipboardy["default"].readSync(), return (0, _lib.jwtDecode)(o); case 2: + return _context.abrupt("return", _context.sent); + + case 3: case "end": return _context.stop(); } diff --git a/package.json b/package.json index f746f26..12a9d2b 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "test": "cross-env NODE_ENV=test nyc mocha test", "cli-test": "jwt-authn \"abc\"", "prepublish": "npm run build", - "babelify": "babel ./src -d ./lib && babel ./cli -d ./cli_lib", + "babelify": "babel ./src/index.js -d ./lib/ && babel ./cli/index.js -d ./cli_lib/", "minify": "minify ./lib/index.js > ./lib/index.min.js && minify ./cli/index.js > ./cli/index.min.js" }, "repository": { From 5ec91aaf554357d27444a0dda3c0f9b8e4e37a04 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Fri, 30 Apr 2021 13:09:29 -0500 Subject: [PATCH 11/20] writing tests for cli --- cli/index.js | 49 +++++++--- cli/index.min.js | 2 +- cli_lib/index.js | 113 ++++++++++++++-------- package-lock.json | 240 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 6 +- test/index.js | 59 ++++++++++++ 6 files changed, 412 insertions(+), 57 deletions(-) diff --git a/cli/index.js b/cli/index.js index 9b1607b..3340163 100644 --- a/cli/index.js +++ b/cli/index.js @@ -3,31 +3,38 @@ import { jwtDecode } from "../lib"; import clipboardy from "clipboardy"; -// read from clipboard -const clipboard = clipboardy.readSync(); -// read passed in argument -const arg2 = process.argv[2]; - const decode = async (jwt) => { return await jwtDecode(jwt); }; -const cli = async (clipboard, arg2) => { +export const HELP_TEXT = + "******HELP*****\n\ +use -c or --clipboard or call command with no arguments to decode the JWT in your clipboard\n\ +or call command with JWT as first argument\n\ +****************"; + +export const cli = async (clipboard, arg2) => { if (arg2 == "-h" || arg2 === "--help") { - console.log( - "use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard" - ); - console.log("or call command with JWT as first argument"); + // Help display + console.log(HELP_TEXT); + return HELP_TEXT; } else if (arg2 === "-c" || arg2 === "--clipboard" || !arg2) { + // Check for something in the clipboard. if (clipboard) { + // Great, there's something in the clipboard. Let's try to decode it as a + // JWT. try { const decoded = await decode(clipboard); - console.log("Decoding: \n" + clipboard); + // Show what we found in the clipboard + console.log("Decoding: "); + console.log(clipboard); + // Show the decoded jwt. console.log(decoded); + return decoded; } catch (e) { console.error("I found an error :(."); console.error( - "Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard" + "Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard" ); console.error("what's on your clipboard? "); console.error(clipboard); @@ -41,8 +48,10 @@ const cli = async (clipboard, arg2) => { } } else if (arg2) { try { + const decoded = jwtDecode(arg2); console.log("Decoding: \n" + arg2); - console.log(jwtDecode(arg2)); + console.log(decoded); + return decoded; } catch (e) { console.error("I found an error :(."); console.error(e, e.message); @@ -53,6 +62,20 @@ const cli = async (clipboard, arg2) => { "Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard" ); } + return 1; }; +// read from clipboard +let clipboard; +try { + clipboard = clipboardy.readSync(); +} catch (e) { + clipboard = null; +} + +// read passed in argument +const arg2 = process.argv[2]; + cli(clipboard, arg2); + +export default cli; diff --git a/cli/index.min.js b/cli/index.min.js index fd107cc..01054db 100644 --- a/cli/index.min.js +++ b/cli/index.min.js @@ -1,2 +1,2 @@ #!/usr/bin/env node -import{jwtDecode}from"../lib";import clipboardy from"clipboardy";const clipboard=clipboardy.readSync(),arg2=process.argv[2],decode=async o=>await jwtDecode(o),cli=async(o,r)=>{if("-h"==r||"--help"===r)console.log("use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard"),console.log("or call command with JWT as first argument");else if("-c"!==r&&"--clipboard"!==r&&r)if(r)try{console.log("Decoding: \n"+r),console.log(jwtDecode(r))}catch(o){console.error("I found an error :(."),console.error(o,o.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard");else if(o)try{const r=await decode(o);console.log("Decoding: \n"+o),console.log(r)}catch(r){console.error("I found an error :(."),console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"),console.error("what's on your clipboard? "),console.error(o),console.error(r,r.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard")};cli(clipboard,arg2); +import{jwtDecode}from"../lib";import clipboardy from"clipboardy";const decode=async o=>await jwtDecode(o);export const HELP_TEXT="******HELP*****\nuse -c or --clipboard or call command with no arguments to decode the JWT in your clipboard\nor call command with JWT as first argument\n****************";let clipboard;try{clipboard=clipboardy.readSync()}catch(o){clipboard=null}const arg2=process.argv[2];export const cli=async(o,r)=>{if("-h"==r||"--help"===r)return console.log(HELP_TEXT),HELP_TEXT;if("-c"!==r&&"--clipboard"!==r&&r)if(r)try{const o=jwtDecode(r);return console.log("Decoding: \n"+r),console.log(o),o}catch(o){console.error("I found an error :(."),console.error(o,o.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard");else if(o)try{const r=await decode(o);return console.log("Decoding: \n"+o),console.log(r),r}catch(r){console.error("I found an error :(."),console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"),console.error("what's on your clipboard? "),console.error(o),console.error(r,r.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard");return 1};cli(clipboard,arg2);export default cli; diff --git a/cli_lib/index.js b/cli_lib/index.js index 71d2f13..837b7b5 100644 --- a/cli_lib/index.js +++ b/cli_lib/index.js @@ -3,6 +3,11 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports["default"] = exports.cli = exports.HELP_TEXT = void 0; + var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); @@ -11,12 +16,6 @@ var _lib = require("../lib"); var _clipboardy = _interopRequireDefault(require("clipboardy")); -// read from clipboard -var clipboard = _clipboardy["default"].readSync(); // read passed in argument - - -var arg2 = process.argv[2]; - var decode = /*#__PURE__*/function () { var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(jwt) { return _regenerator["default"].wrap(function _callee$(_context) { @@ -42,9 +41,27 @@ var decode = /*#__PURE__*/function () { }; }(); +var HELP_TEXT = "******HELP*****\n\ +use -c or --clipboard or call command with no arguments to decode the JWT in your clipboard\n\ +or call command with JWT as first argument\n\ +****************"; // read from clipboard + +exports.HELP_TEXT = HELP_TEXT; +var clipboard; + +try { + clipboard = _clipboardy["default"].readSync(); +} catch (e) { + clipboard = null; +} // read passed in argument + + +var arg2 = process.argv[2]; + var cli = /*#__PURE__*/function () { var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(clipboard, arg2) { - var decoded; + var decoded, _decoded; + return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { @@ -54,19 +71,18 @@ var cli = /*#__PURE__*/function () { break; } - console.log("use -c or --clipboard or call command with no arguments to decode the JWT in you clipboard"); - console.log("or call command with JWT as first argument"); - _context2.next = 29; - break; + // Help display + console.log(HELP_TEXT); + return _context2.abrupt("return", HELP_TEXT); case 5: if (!(arg2 === "-c" || arg2 === "--clipboard" || !arg2)) { - _context2.next = 28; + _context2.next = 29; break; } if (!clipboard) { - _context2.next = 24; + _context2.next = 25; break; } @@ -76,52 +92,68 @@ var cli = /*#__PURE__*/function () { case 10: decoded = _context2.sent; - console.log("Decoding: \n" + clipboard); + // Show what we found in the clipboard + console.log("Decoding: \n" + clipboard); // Show the decoded jwt. + console.log(decoded); - _context2.next = 22; - break; + return _context2.abrupt("return", decoded); - case 15: - _context2.prev = 15; + case 16: + _context2.prev = 16; _context2.t0 = _context2["catch"](7); console.error("I found an error :(."); - console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to clipboard"); + console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"); console.error("what's on your clipboard? "); console.error(clipboard); console.error(_context2.t0, _context2.t0.message); - case 22: - _context2.next = 26; + case 23: + _context2.next = 27; break; - case 24: + case 25: console.error("I found an error :(."); console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"); - case 26: - _context2.next = 29; + case 27: + _context2.next = 45; break; - case 28: - if (arg2) { - try { - console.log("Decoding: \n" + arg2); - console.log((0, _lib.jwtDecode)(arg2)); - } catch (e) { - console.error("I found an error :(."); - console.error(e, e.message); - } - } else { - console.error("I found an error :(."); - console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); + case 29: + if (!arg2) { + _context2.next = 43; + break; } - case 29: + _context2.prev = 30; + _decoded = (0, _lib.jwtDecode)(arg2); + console.log("Decoding: \n" + arg2); + console.log(_decoded); + return _context2.abrupt("return", _decoded); + + case 37: + _context2.prev = 37; + _context2.t1 = _context2["catch"](30); + console.error("I found an error :(."); + console.error(_context2.t1, _context2.t1.message); + + case 41: + _context2.next = 45; + break; + + case 43: + console.error("I found an error :(."); + console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); + + case 45: + return _context2.abrupt("return", 1); + + case 46: case "end": return _context2.stop(); } } - }, _callee2, null, [[7, 15]]); + }, _callee2, null, [[7, 16], [30, 37]]); })); return function cli(_x2, _x3) { @@ -129,4 +161,7 @@ var cli = /*#__PURE__*/function () { }; }(); -cli(clipboard, arg2); \ No newline at end of file +exports.cli = cli; +cli(clipboard, arg2); +var _default = cli; +exports["default"] = _default; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a6986a3..3452c5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,8 @@ "cross-env": "^7.0.3", "minify": "^7.0.1", "mocha": "^8.3.2", - "nyc": "^15.1.0" + "nyc": "^15.1.0", + "sinon": "^10.0.0" }, "engines": { "node": ">=15.0" @@ -1447,6 +1448,41 @@ "node": ">=0.10.0" } }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -3785,6 +3821,12 @@ "node": ">=6" } }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -3825,6 +3867,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "node_modules/log-symbols": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", @@ -4337,6 +4385,19 @@ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, + "node_modules/nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -4924,6 +4985,21 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -5416,6 +5492,54 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, + "node_modules/sinon": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", + "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.1.0", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", @@ -7677,6 +7801,41 @@ } } }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -9474,6 +9633,12 @@ "minimist": "^1.2.5" } }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -9508,6 +9673,12 @@ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "log-symbols": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", @@ -9901,6 +10072,19 @@ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, + "nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, "no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -10361,6 +10545,23 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, "pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", @@ -10756,6 +10957,43 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, + "sinon": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", + "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", diff --git a/package.json b/package.json index 12a9d2b..7648f63 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,10 @@ "description": "JWT decoder, encoder, and more with only Node >=15.x as a dependency.", "main": "./lib", "scripts": { + "prepare": "npm run build", "build": "npm run babelify && npm run minify", "test": "cross-env NODE_ENV=test nyc mocha test", "cli-test": "jwt-authn \"abc\"", - "prepublish": "npm run build", "babelify": "babel ./src/index.js -d ./lib/ && babel ./cli/index.js -d ./cli_lib/", "minify": "minify ./lib/index.js > ./lib/index.min.js && minify ./cli/index.js > ./cli/index.min.js" }, @@ -66,9 +66,9 @@ "cross-env": "^7.0.3", "minify": "^7.0.1", "mocha": "^8.3.2", - "nyc": "^15.1.0" + "nyc": "^15.1.0", + "sinon": "^10.0.0" }, - "prepublishOnly": "npm run build", "nyc": { "require": [ "@babel/register" diff --git a/test/index.js b/test/index.js index cd4afa5..59209b4 100644 --- a/test/index.js +++ b/test/index.js @@ -11,6 +11,9 @@ import { createHeaderPayload, } from "../src/index.js"; import crypto from "crypto"; +import cli, { HELP_TEXT } from "../cli/index.js"; +import sinon from "sinon"; +import { spawn } from "child_process"; const expect = chai.expect; chai.config.includeStack = true; @@ -614,3 +617,59 @@ describe("Signing and Verification", () => { }); }); }); + +describe("#cli()", () => { + let sandbox; + before(() => { + sandbox = sinon.createSandbox(); + }); + beforeEach(() => { + sandbox.restore(); + }); + + describe("using help", () => { + context("when argument is -h or --help", () => { + it("shows the help screen", () => { + const log = sandbox.spy(console, "log"); + cli(null, "-h"); + expect(log.calledOnceWith(HELP_TEXT)).to.be.true; + }); + }); + }); + + describe("mock using clipboard", () => { + context("when 'clipboard' contains a jwt", () => { + it("decodes the jwt", async () => { + const log = sandbox.spy(console, "log"); + const myCli = cli; + const spy = sandbox.spy(myCli); + + const clipboard = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"; + const expectedOutput = { + header: { alg: "HS256", typ: "JWT" }, + payload: { sub: "1234567890", name: "John Doe", iat: 1516239022 }, + signature: "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", + }; + const cliOutput = await spy(clipboard, null); + + console.log( + spy.calledOnceWith( + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" + ) + ); + expect(log.calledWith("Decoding: ")).to.be.true; + expect( + log.calledWith( + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" + ) + ).to.be.true; + expect( + log.getCall(2).firstArg, + "decoded jwt was logged to the console" + ).to.be.deep.equal(expectedOutput); + expect(expectedOutput).to.be.deep.equal(cliOutput); + }); + }); + }); +}); From 59db00ef1d0a35ece6b83d40fc23880533b49c88 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 1 May 2021 09:35:07 -0500 Subject: [PATCH 12/20] get rid of cli-test script --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 7648f63..e4a8068 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "prepare": "npm run build", "build": "npm run babelify && npm run minify", "test": "cross-env NODE_ENV=test nyc mocha test", - "cli-test": "jwt-authn \"abc\"", "babelify": "babel ./src/index.js -d ./lib/ && babel ./cli/index.js -d ./cli_lib/", "minify": "minify ./lib/index.js > ./lib/index.min.js && minify ./cli/index.js > ./cli/index.min.js" }, From 6c0e6954913f513a5e204a76733094b2efd3b390 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 1 May 2021 13:18:32 -0500 Subject: [PATCH 13/20] cli working again --- cli/index.js | 12 +++++-- cli/index.min.js | 2 +- cli_lib/index.js | 94 +++++++++++++++++++++++++----------------------- test/index.js | 8 +++-- 4 files changed, 65 insertions(+), 51 deletions(-) diff --git a/cli/index.js b/cli/index.js index 3340163..0436389 100644 --- a/cli/index.js +++ b/cli/index.js @@ -13,7 +13,13 @@ use -c or --clipboard or call command with no arguments to decode the JWT in you or call command with JWT as first argument\n\ ****************"; -export const cli = async (clipboard, arg2) => { +export const cli = async (clipboard, argv) => { + // read passed in argument + let arg2; + if (argv) { + arg2 = argv[2]; + } + if (arg2 == "-h" || arg2 === "--help") { // Help display console.log(HELP_TEXT); @@ -74,8 +80,8 @@ try { } // read passed in argument -const arg2 = process.argv[2]; +const argv = process.argv; -cli(clipboard, arg2); +cli(clipboard, argv); export default cli; diff --git a/cli/index.min.js b/cli/index.min.js index 01054db..d66e027 100644 --- a/cli/index.min.js +++ b/cli/index.min.js @@ -1,2 +1,2 @@ #!/usr/bin/env node -import{jwtDecode}from"../lib";import clipboardy from"clipboardy";const decode=async o=>await jwtDecode(o);export const HELP_TEXT="******HELP*****\nuse -c or --clipboard or call command with no arguments to decode the JWT in your clipboard\nor call command with JWT as first argument\n****************";let clipboard;try{clipboard=clipboardy.readSync()}catch(o){clipboard=null}const arg2=process.argv[2];export const cli=async(o,r)=>{if("-h"==r||"--help"===r)return console.log(HELP_TEXT),HELP_TEXT;if("-c"!==r&&"--clipboard"!==r&&r)if(r)try{const o=jwtDecode(r);return console.log("Decoding: \n"+r),console.log(o),o}catch(o){console.error("I found an error :(."),console.error(o,o.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard");else if(o)try{const r=await decode(o);return console.log("Decoding: \n"+o),console.log(r),r}catch(r){console.error("I found an error :(."),console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"),console.error("what's on your clipboard? "),console.error(o),console.error(r,r.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard");return 1};cli(clipboard,arg2);export default cli; +import{jwtDecode}from"../lib";import clipboardy from"clipboardy";const decode=async o=>await jwtDecode(o);export const HELP_TEXT="******HELP*****\nuse -c or --clipboard or call command with no arguments to decode the JWT in your clipboard\nor call command with JWT as first argument\n****************";export const cli=async(o,r)=>{let e;if(r&&(e=r[2]),"-h"==e||"--help"===e)return console.log(HELP_TEXT),HELP_TEXT;if("-c"!==e&&"--clipboard"!==e&&e)if(e)try{const o=jwtDecode(e);return console.log("Decoding: \n"+e),console.log(o),o}catch(o){console.error("I found an error :(."),console.error(o,o.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard");else if(o)try{const r=await decode(o);return console.log("Decoding: "),console.log(o),console.log(r),r}catch(r){console.error("I found an error :(."),console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"),console.error("what's on your clipboard? "),console.error(o),console.error(r,r.message)}else console.error("I found an error :(."),console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard");return 1};let clipboard;try{clipboard=clipboardy.readSync()}catch(o){clipboard=null}const argv=process.argv;cli(clipboard,argv);export default cli; diff --git a/cli_lib/index.js b/cli_lib/index.js index 837b7b5..8816ec4 100644 --- a/cli_lib/index.js +++ b/cli_lib/index.js @@ -44,30 +44,24 @@ var decode = /*#__PURE__*/function () { var HELP_TEXT = "******HELP*****\n\ use -c or --clipboard or call command with no arguments to decode the JWT in your clipboard\n\ or call command with JWT as first argument\n\ -****************"; // read from clipboard - +****************"; exports.HELP_TEXT = HELP_TEXT; -var clipboard; - -try { - clipboard = _clipboardy["default"].readSync(); -} catch (e) { - clipboard = null; -} // read passed in argument - - -var arg2 = process.argv[2]; var cli = /*#__PURE__*/function () { - var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(clipboard, arg2) { - var decoded, _decoded; + var _ref2 = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee2(clipboard, argv) { + var arg2, decoded, _decoded; return _regenerator["default"].wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: + // read passed in argument + if (argv) { + arg2 = argv[2]; + } + if (!(arg2 == "-h" || arg2 === "--help")) { - _context2.next = 5; + _context2.next = 6; break; } @@ -75,93 +69,105 @@ var cli = /*#__PURE__*/function () { console.log(HELP_TEXT); return _context2.abrupt("return", HELP_TEXT); - case 5: + case 6: if (!(arg2 === "-c" || arg2 === "--clipboard" || !arg2)) { - _context2.next = 29; + _context2.next = 31; break; } if (!clipboard) { - _context2.next = 25; + _context2.next = 27; break; } - _context2.prev = 7; - _context2.next = 10; + _context2.prev = 8; + _context2.next = 11; return decode(clipboard); - case 10: + case 11: decoded = _context2.sent; // Show what we found in the clipboard - console.log("Decoding: \n" + clipboard); // Show the decoded jwt. + console.log("Decoding: "); + console.log(clipboard); // Show the decoded jwt. console.log(decoded); return _context2.abrupt("return", decoded); - case 16: - _context2.prev = 16; - _context2.t0 = _context2["catch"](7); + case 18: + _context2.prev = 18; + _context2.t0 = _context2["catch"](8); console.error("I found an error :(."); console.error("Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"); console.error("what's on your clipboard? "); console.error(clipboard); console.error(_context2.t0, _context2.t0.message); - case 23: - _context2.next = 27; + case 25: + _context2.next = 29; break; - case 25: + case 27: console.error("I found an error :(."); console.error("Nothing in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard"); - case 27: - _context2.next = 45; + case 29: + _context2.next = 47; break; - case 29: + case 31: if (!arg2) { - _context2.next = 43; + _context2.next = 45; break; } - _context2.prev = 30; + _context2.prev = 32; _decoded = (0, _lib.jwtDecode)(arg2); console.log("Decoding: \n" + arg2); console.log(_decoded); return _context2.abrupt("return", _decoded); - case 37: - _context2.prev = 37; - _context2.t1 = _context2["catch"](30); + case 39: + _context2.prev = 39; + _context2.t1 = _context2["catch"](32); console.error("I found an error :(."); console.error(_context2.t1, _context2.t1.message); - case 41: - _context2.next = 45; + case 43: + _context2.next = 47; break; - case 43: + case 45: console.error("I found an error :(."); console.error("Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard"); - case 45: + case 47: return _context2.abrupt("return", 1); - case 46: + case 48: case "end": return _context2.stop(); } } - }, _callee2, null, [[7, 16], [30, 37]]); + }, _callee2, null, [[8, 18], [32, 39]]); })); return function cli(_x2, _x3) { return _ref2.apply(this, arguments); }; -}(); +}(); // read from clipboard + exports.cli = cli; -cli(clipboard, arg2); +var clipboard; + +try { + clipboard = _clipboardy["default"].readSync(); +} catch (e) { + clipboard = null; +} // read passed in argument + + +var argv = process.argv; +cli(clipboard, argv); var _default = cli; exports["default"] = _default; \ No newline at end of file diff --git a/test/index.js b/test/index.js index 59209b4..034cba9 100644 --- a/test/index.js +++ b/test/index.js @@ -631,7 +631,9 @@ describe("#cli()", () => { context("when argument is -h or --help", () => { it("shows the help screen", () => { const log = sandbox.spy(console, "log"); - cli(null, "-h"); + // Mock process.argv + const processArgv = [0,0,"-h"]; + cli(null, [0,0,"-h"]); expect(log.calledOnceWith(HELP_TEXT)).to.be.true; }); }); @@ -653,11 +655,11 @@ describe("#cli()", () => { }; const cliOutput = await spy(clipboard, null); - console.log( + expect( spy.calledOnceWith( "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c" ) - ); + ).to.be.true; expect(log.calledWith("Decoding: ")).to.be.true; expect( log.calledWith( From ab510a2eec60175ab423a70fa37dd981e08afbbe Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sun, 2 May 2021 11:46:22 -0500 Subject: [PATCH 14/20] another cli test --- cli/index.js | 16 +++++++++++++--- src/index.js | 2 -- test/index.js | 40 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/cli/index.js b/cli/index.js index 0436389..bc29b8c 100644 --- a/cli/index.js +++ b/cli/index.js @@ -4,7 +4,13 @@ import { jwtDecode } from "../lib"; import clipboardy from "clipboardy"; const decode = async (jwt) => { - return await jwtDecode(jwt); + let decoded; + try { + decoded = await jwtDecode(jwt); + return decoded; + } catch (e) { + throw e; + } }; export const HELP_TEXT = @@ -38,13 +44,13 @@ export const cli = async (clipboard, argv) => { console.log(decoded); return decoded; } catch (e) { - console.error("I found an error :(."); + console.error("I found an error :("); console.error( "Couldn't decode what was in clipboard. Pass in a JWT as the first argument or copy a JWT to your clipboard" ); console.error("what's on your clipboard? "); console.error(clipboard); - console.error(e, e.message); + throw e; } } else { console.error("I found an error :(."); @@ -61,12 +67,16 @@ export const cli = async (clipboard, argv) => { } catch (e) { console.error("I found an error :(."); console.error(e, e.message); + throw e; } } else { console.error("I found an error :(."); console.error( "Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard" ); + throw new Error( + "Nothing in clipboard and no arguments given. Pass in a JWT as the first argument or copy a JWT to your clipboard" + ); } return 1; }; diff --git a/src/index.js b/src/index.js index c3d0d8a..b0989b8 100644 --- a/src/index.js +++ b/src/index.js @@ -78,8 +78,6 @@ export const jwtDecode = (jwt) => { throw new SyntaxError("Not using compact serialization (JWS)."); } catch (e) { // debugging(e); - - console.error("I found an error :(."); throw e; } }; diff --git a/test/index.js b/test/index.js index 034cba9..6f10665 100644 --- a/test/index.js +++ b/test/index.js @@ -628,12 +628,22 @@ describe("#cli()", () => { }); describe("using help", () => { - context("when argument is -h or --help", () => { + context("when argument is -h", () => { it("shows the help screen", () => { const log = sandbox.spy(console, "log"); // Mock process.argv - const processArgv = [0,0,"-h"]; - cli(null, [0,0,"-h"]); + const processArgv = [0, 0, "-h"]; + cli(null, [0, 0, "-h"]); + expect(log.calledOnceWith(HELP_TEXT)).to.be.true; + }); + }); + + context("when argument is --help", () => { + it("shows the help screen", () => { + const log = sandbox.spy(console, "log"); + // Mock process.argv + const processArgv = [0, 0, "-h"]; + cli(null, [0, 0, "-h"]); expect(log.calledOnceWith(HELP_TEXT)).to.be.true; }); }); @@ -673,5 +683,29 @@ describe("#cli()", () => { expect(expectedOutput).to.be.deep.equal(cliOutput); }); }); + + context("when 'clipboard' doesn't contain a jwt", () => { + it("decodes the jwt", async () => { + const log = sandbox.spy(console, "log"); + const err = sandbox.spy(console, "error"); + const spy = sandbox.spy(cli); + + const clipboard = "abc.abc.abc"; + + try { + await spy(clipboard, null); + } catch (e) { + try { + const syntaxErr = await spy.returnValues[0]; + } catch (ex) { + expect(ex instanceof SyntaxError).to.be.true; + } + } + + expect(err.calledWith("Need at least one '.'")); + expect(err.calledWith("I found an error :(.")); + expect(spy.called).to.be.true; + }); + }); }); }); From a9223ee46411c63c4604347fbeea5c38d795d658 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sun, 2 May 2021 18:41:52 -0500 Subject: [PATCH 15/20] cleanup --- src/index.js | 26 ++++++++++++++++++-------- test/index.js | 6 +++--- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/index.js b/src/index.js index b0989b8..4cdb4ad 100644 --- a/src/index.js +++ b/src/index.js @@ -153,12 +153,11 @@ export const rs256JWKSign = (headerPayload, privateKey) => { if (e instanceof TypeError) { secret = privateKey; } else { - console.error("I found an error :(."); console.error(e.message, e); + throw e; } } } else { - console.error("I found an error :(."); console.error("RSA-SHA256 not found"); throw new Error("RSA-SHA256 isn't available in the current system."); } @@ -384,12 +383,24 @@ export const createHeaderPayload = (header, payload) => { export const base64URLEncode = (jsonObject) => { if (Buffer.isEncoding("base64url")) { // not a string. convert to string - const stringifyHeader = JSON.stringify(jsonObject); + const stringify = JSON.stringify(jsonObject); // headerBase64URL = base64url.encode(stringifyHeader); - const payloadBase64URL = Buffer.from(stringifyHeader, "ascii").toString( - "base64url" - ); - return payloadBase64URL; + const base64URLify = Buffer.from(stringify, "ascii").toString("base64url"); + return base64URLify; + } else if (window) { + const b64c = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // base64 dictionary + const b64u = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; // base64url dictionary + const btoa = window.btoa(); + + const stringify = JSON.stringify(jsonObject); + const base64urlify = btoa(stringify); + // Remove trailing "=" + let s = base64urlify.split("=")[0]; + s = s.replace("+", "-"); + s = s.replace("/", "_"); + return s; } throw new Error("Error: Base64URL encoding isn't available"); @@ -435,7 +446,6 @@ export const parseToJSON = (input) => { */ export const jwtEncode = (header, payload, key, options) => { let headerBase64URL; - let payloadBase64URL; let jsonHeader = header; if (Buffer.isEncoding("base64url")) { diff --git a/test/index.js b/test/index.js index 6f10665..ea4104e 100644 --- a/test/index.js +++ b/test/index.js @@ -686,24 +686,24 @@ describe("#cli()", () => { context("when 'clipboard' doesn't contain a jwt", () => { it("decodes the jwt", async () => { - const log = sandbox.spy(console, "log"); const err = sandbox.spy(console, "error"); const spy = sandbox.spy(cli); const clipboard = "abc.abc.abc"; + let syntaxErr; try { await spy(clipboard, null); } catch (e) { try { - const syntaxErr = await spy.returnValues[0]; + syntaxErr = await spy.returnValues[0]; } catch (ex) { expect(ex instanceof SyntaxError).to.be.true; } } expect(err.calledWith("Need at least one '.'")); - expect(err.calledWith("I found an error :(.")); + expect(err.calledWith("I found an error :(")); expect(spy.called).to.be.true; }); }); From fc428e38df2e2622f1fadb3261530c531fe0f53f Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sun, 2 May 2021 18:53:07 -0500 Subject: [PATCH 16/20] another cli test --- cli/index.js | 3 +-- test/index.js | 55 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/cli/index.js b/cli/index.js index bc29b8c..bffd388 100644 --- a/cli/index.js +++ b/cli/index.js @@ -4,9 +4,8 @@ import { jwtDecode } from "../lib"; import clipboardy from "clipboardy"; const decode = async (jwt) => { - let decoded; try { - decoded = await jwtDecode(jwt); + const decoded = await jwtDecode(jwt); return decoded; } catch (e) { throw e; diff --git a/test/index.js b/test/index.js index ea4104e..b9f5bd6 100644 --- a/test/index.js +++ b/test/index.js @@ -685,26 +685,51 @@ describe("#cli()", () => { }); context("when 'clipboard' doesn't contain a jwt", () => { - it("decodes the jwt", async () => { - const err = sandbox.spy(console, "error"); - const spy = sandbox.spy(cli); + context("when it's not in proper JSON format", () => { + it("throws a SyntaxError", async () => { + const err = sandbox.spy(console, "error"); + const spy = sandbox.spy(cli); + + const clipboard = "abc.abc.abc"; + let syntaxErr; + + try { + await spy(clipboard, null); + } catch (e) { + try { + syntaxErr = await spy.returnValues[0]; + } catch (ex) { + expect(ex instanceof SyntaxError).to.be.true; + } + } - const clipboard = "abc.abc.abc"; - let syntaxErr; + expect(err.calledWith("I found an error :(")).to.be.true; + expect(spy.called).to.be.true; + }); + }); + + context("when it doesn't contain a '.'", () => { + it("throws an error", async () => { + const err = sandbox.spy(console, "error"); + const spy = sandbox.spy(cli); + + const clipboard = "abc"; + let dotErr; - try { - await spy(clipboard, null); - } catch (e) { try { - syntaxErr = await spy.returnValues[0]; - } catch (ex) { - expect(ex instanceof SyntaxError).to.be.true; + await spy(clipboard, null); + } catch (e) { + try { + dotErr = await spy.returnValues[0]; + } catch (ex) { + expect(ex instanceof Error).to.be.true; + expect(ex.message).to.equal("Need at least one '.'"); + } } - } - expect(err.calledWith("Need at least one '.'")); - expect(err.calledWith("I found an error :(")); - expect(spy.called).to.be.true; + expect(err.calledWith("I found an error :(")).to.be.true; + expect(spy.called).to.be.true; + }); }); }); }); From ca6c9b621ca473b06372d40f7d6678c4cbfb9f60 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Tue, 4 May 2021 16:17:30 -0500 Subject: [PATCH 17/20] readme intro --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d99dd83..7b27ab2 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ # jwt-authn -jwt-authn is an npm package for dealing with JSON Web Tokens. Encoding, decoding, verifying, signing, and more coming. It includes support for the RS256 and HS256 algorithms and JWK and PEM format keys (even encrypted keys). No package dependencies! Its only dependency is NodeJS itself. +jwt-authn is an npm package for dealing with JSON Web Tokens (JWT). Encoding, decoding, verifying, signing, and more coming. It includes support for the RS256 and HS256 algorithms and JWK and PEM format keys (even encrypted keys). *[Must be on Node >= 15.x](https://nodejs.org/en/about/releases/) From bbe840b6c16748ea84d42c1ba897f718f21c5471 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Tue, 4 May 2021 16:29:48 -0500 Subject: [PATCH 18/20] readme intro --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b27ab2..83bd0a4 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,9 @@ # jwt-authn -jwt-authn is an npm package for dealing with JSON Web Tokens (JWT). Encoding, decoding, verifying, signing, and more coming. It includes support for the RS256 and HS256 algorithms and JWK and PEM format keys (even encrypted keys). +jwt-authn is an npm package for dealing with JSON Web Tokens (JWT). Encoding, decoding, verifying, signing, and more coming. It includes support for the RS256 and HS256 algorithms and JWK and PEM format keys (even encrypted keys). Only Node >=15.x as a requirement! + +Now with command line support! *[Must be on Node >= 15.x](https://nodejs.org/en/about/releases/) @@ -61,6 +63,7 @@ Use the package manager [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg. npm install jwt-authn ``` + ```Shell yarn add jwt-authn ``` @@ -70,6 +73,17 @@ Or from a cdn: https://cdn.jsdelivr.net/npm/jwt-authn@1.0.39/lib ``` +If using for the command line support (or it'll only be available in the current directory's node_modules folder): + +```Shell +npm install -g jwt-authn +``` + +```Shell +yarn global install jwt-authn +``` + +
--- From 12ad2788935f0d149d2c74a39b92c50f48b6a6f9 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Fri, 7 May 2021 18:01:40 -0500 Subject: [PATCH 19/20] Added some text to a title and some line spacing --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 83bd0a4..0ee3496 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Now with command line support! - [⬆Usage](#usage) - [⬆Installation:](#installation) - [⬆Accepted Form of JWTs](#accepted-form-of-jwts) + - [⬆ CLI support for JWT Decoding](#-cli-support-for-jwt-decoding) - [⬆ Decoding a JWT](#-decoding-a-jwt) - [⬆ **jwtDecode(jwt)**](#-jwtdecodejwt) - [⬆ Encoding a JWT](#-encoding-a-jwt) @@ -112,6 +113,34 @@ eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTk --- +### [⬆](#index) CLI support for JWT Decoding + +
+ +Running just jwt-authn will try to decode whatever is in your clipboard. +```Shell +# Decodes what's in your clipboard. +jwt-authn +``` + +Alternatively, you can run jwt-authn with the clipboard option. +```Shell +jwt-authn -c +``` + +```Shell +jwt-authn --clipboard +``` + +or to decode the input +```Shell +jwt-authn eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk +``` + +
+ +--- + ### [⬆](#index) Decoding a JWT
From aa3eaf60a6b9baf3f36a2e04f1923f2898ac1778 Mon Sep 17 00:00:00 2001 From: akdombrowski Date: Sat, 8 May 2021 08:15:17 -0500 Subject: [PATCH 20/20] bump to 1.0.40 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e4a8068..2494fea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jwt-authn", - "version": "1.0.39", + "version": "1.0.40", "description": "JWT decoder, encoder, and more with only Node >=15.x as a dependency.", "main": "./lib", "scripts": {