@curity/jwt-validation
Version:
Curity JWT Validation library
1 lines • 8.62 kB
JavaScript
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.JWTValidator=t():e.JWTValidator=t()}(this,(()=>(()=>{var e={556:e=>{"use strict";var t=function(e,t){Error.call(this,e),void 0!==Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor),this.name="JWTError",this.message=e,t&&(this.inner=t)};(t.prototype=Object.create(Error.prototype)).constructor=t,e.exports=t},113:e=>{"use strict";e.exports=require("crypto")},687:e=>{"use strict";e.exports=require("https")},156:e=>{function t(e,t,r,a,i,n,o){try{var s=e[n](o),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(a,i)}e.exports=function(e){return function(){var r=this,a=arguments;return new Promise((function(i,n){var o=e.apply(r,a);function s(e){t(o,i,n,s,u,"next",e)}function u(e){t(o,i,n,s,u,"throw",e)}s(void 0)}))}},e.exports.__esModule=!0,e.exports.default=e.exports},836:e=>{e.exports=function(e){return e&&e.__esModule?e:{default:e}},e.exports.__esModule=!0,e.exports.default=e.exports}},t={};function r(a){var i=t[a];if(void 0!==i)return i.exports;var n=t[a]={exports:{}};return e[a](n,n.exports,r),n.exports}var a={};return(()=>{"use strict";var e=a,t=r(836);Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,e.generateHash=l,e.parseJWT=h,e.strToUint8Array=p;var i=t(r(156)),n=t(r(556)),o="Signature verification failed",s={HS256:{name:"HMAC",hash:"SHA-256"},HS384:{name:"HMAC",hash:"SHA-384"},HS512:{name:"HMAC",hash:"SHA-512"},RS256:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-256"},RS384:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-384"},RS512:{name:"RSASSA-PKCS1-v1_5",hash:"SHA-512"},ES256:{name:"ECDSA",namedCurve:"P-256",hash:"SHA-256"},ES384:{name:"ECDSA",namedCurve:"P-384",hash:"SHA-384"},ES512:{name:"ECDSA",namedCurve:"P-521",hash:"SHA-512"},PS256:{name:"RSA-PSS",saltLength:32,hash:"SHA-256"},PS384:{name:"RSA-PSS",saltLength:48,hash:"SHA-384"},PS512:{name:"RSA-PSS",saltLength:64,hash:"SHA-512"}},u=["jwk","jwks_uri","pem","issuer","metadata_url","raw"];function l(e){return f.apply(this,arguments)}function f(){return f=(0,i.default)((function*(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"SHA-256",r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],a=yield b().subtle.digest(t,p(e)),i=Array.from(new Uint8Array(a));return i.length=r?i.length/2:i.length,d(i)})),f.apply(this,arguments)}function d(e){return btoa(String.fromCharCode(...new Uint8Array(e))).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_")}function c(e){return e+=Array((4-e.length%4)%4+1).join("="),g(e.replace(/-/g,"+").replace(/_/g,"/"))}function h(e){var t=e.split(".");if(3!==t.length)throw new n.default("Jwt cannot be parsed",e,null,null);var r=JSON.parse(c(t[0])),a=JSON.parse(c(t[1]));return{signature:function(e){for(var t=e.length;"="===e[t-1];)--t;var r,a,i,o=new Uint8Array(t*w.bits/8|0);r=a=i=0;for(var s=0;s<t;++s){var u=w.codes[e[s]];if(void 0===u)throw new n.default("Invalid character in signature: "+e[s]);a=a<<w.bits|u,(r+=w.bits)>=8&&(r-=8,o[i++]=255&a>>r)}if(r>=w.bits||255&a<<8-r)throw new n.default("Invalid signature, unexpected end.");return o}(t[2]),header:r,payload:a,alg:r.alg,verificationInput:p(t[0]+"."+t[1])}}function p(e){return(new TextEncoder).encode(e)}for(var w={chars:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",bits:6,codes:{}},y=0;y<w.chars.length;++y)w.codes[w.chars[y]]=y;var v,g="function"==typeof atob?atob:e=>Buffer.from(e,"base64").toString("binary");class m{constructor(e){this._data=e}json(){return Promise.resolve(JSON.parse(this._data))}}function b(){if("object"==typeof crypto)return crypto;var e=r(113);if("object"!=typeof e||"object"!=typeof e.webcrypto)throw"The library requires at least node 15.0.0 to run in non-browser environments.";return e.webcrypto}e.default=class{constructor(e,t,a,i){if(this._issuer=Array.isArray(e)?e:[e],this._audience=Array.isArray(t)?t:[t],this._algorithms=a,this._publicKey=i||{format:"issuer",value:null},1!==u.filter((e=>this._publicKey.format===e)).length)throw new n.default("public key parameter must contain one of the allowed formats : "+u.join(" or "));if(!(e&&t&&this._publicKey))throw new n.default("issuer, audience and public key must be provided");this._crypto=b(),v="function"==typeof fetch?fetch:e=>function(e){var t=r(687);return new Promise(((r,a)=>{t.get(e,(e=>{(e.statusCode<200||e.statusCode>=400)&&a(new n.default("JWKS endpoint responded with "+e.statusCode+" status code."));var t="";e.on("data",(e=>{t+=e})),e.on("end",(()=>{r(new m(t))}))})).on("error",(e=>{a(e)}))}))}(e)}verifyJWT(e,t){var r=this;return(0,i.default)((function*(){if(t||(t={}),t=Object.assign({},t),!e)throw new n.default("jwt must be provided");var a;try{a=h(e)}catch(e){throw new n.default(e.message,e)}if(!a)throw new n.default("invalid token");var i=a.header;if(r._algorithms&&r._algorithms.length>0&&!~r._algorithms.indexOf(i.alg))throw new n.default("invalid algorithm : "+i.alg);if(!s[i.alg])throw new n.default("unsupported algorithm : "+i.alg);var o=a.payload;if(!o)throw new n.default("invalid payload");if(0===r._issuer.filter((e=>e===o.iss)).length)throw new n.default("jwt issuer invalid: "+o.iss+", expected: "+r._issuer.join(" or "));yield r.verifySignature(a);var u=Math.floor(Date.now()/1e3);if(o.nbf&&!0!==t.ignoreNotBefore){if("number"!=typeof o.nbf)throw new n.default("invalid nbf value");if(o.nbf>u+(t.clockTolerance||0))throw new n.default("jwt is used before specified nbf claim.",new Date(1e3*o.nbf))}if(!0!==t.ignoreExpiration)if(o.exp){if("number"!=typeof o.exp)throw new n.default("invalid exp value");if(u>=o.exp+(t.clockTolerance||0))throw new n.default("jwt expired",new Date(1e3*o.exp))}else if(!o.exp)throw new n.default("JWT must contain exp claim");if(r._audience&&!(Array.isArray(o.aud)?o.aud:[o.aud]).some((e=>r._audience.filter((t=>t===e)).length>0)))throw new n.default("jwt audience invalid. expected: "+r._audience.join(" or "));if(t.subject&&o.sub!==t.subject)throw new n.default("jwt subject invalid. expected: "+t.subject);if(t.jti&&o.jti!==t.jti)throw new n.default("jwt jti invalid. expected: "+t.jti);if(t.accessToken&&(yield l(t.accessToken,s[i.alg].hash,!0))!==o.at_hash)throw new n.default("JWT: Failed to validate at_hash");if(t.code&&(yield l(t.code,s[i.alg].hash,!0))!==o.c_hash)throw new n.default("JWT: Failed to validate c_hash");if(t.state&&(yield l(t.state,s[i.alg].hash,!0))!==o.s_hash)throw new n.default("JWT: Failed to validate s_hash");if(t.nonce&&o.nonce!==t.nonce)throw new n.default("JWT: Invalid Nonce! Failed to validate Nonce: "+t.nonce);return o}))()}verifySignature(e){var t=this;return(0,i.default)((function*(){var r;try{var a=e.header,i=s[a.alg],u=yield t.getSigningKey(e,i);r=yield t._crypto.subtle.verify(i,u,e.signature,e.verificationInput)}catch(e){throw new n.default("Signature verification failed : "+e)}if(!r)throw new n.default(o)}))()}getSigningKey(e,t){var r=this;return(0,i.default)((function*(){if(r._signingKey)return r._signingKey;if("pem"===r._publicKey.format)r._signingKey=r.importKey(r._publicKey.value,t);else if("raw"===r._publicKey.format)r._signingKey=yield r._crypto.subtle.importKey("raw",r.str2ab(r._publicKey.value),t,!1,["verify"]);else{var a,i,n;switch(r._publicKey.format){case"issuer":a="".concat(e.payload.iss,"/.well-known/openid-configuration");break;case"metadata_url":a=r._publicKey.value;break;case"jwks_uri":i=r._publicKey.value;break;case"jwk":n=r._publicKey.value}if(a){try{i=(yield(yield v(a)).json()).jwks_uri}catch(e){throw"failed to fetch metadata"}if(!i)throw"metadata doesn't contain jwks_uri"}if(i)try{n=yield r.getJwkByJwksUri(i,e.header.kid,e.alg)}catch(e){throw"failed to fetch jwk from jwks_uri"}r._signingKey=yield r._crypto.subtle.importKey("jwk",n,t,!1,["verify"])}return r._signingKey}))()}importKey(e,t){var r=this;return(0,i.default)((function*(){try{var a="-----BEGIN PUBLIC KEY-----",i=e.indexOf(a),n=e.substring(i+a.length,e.length-"-----END PUBLIC KEY-----".length),o=g(n),s=r.str2ab(o);return yield r._crypto.subtle.importKey("spki",s,t,!1,["verify"])}catch(e){throw"Invalid pem: failed to import."}}))()}str2ab(e){for(var t=new ArrayBuffer(e.length),r=new Uint8Array(t),a=0,i=e.length;a<i;a++)r[a]=e.charCodeAt(a);return t}getJwkByJwksUri(e,t,r){return(0,i.default)((function*(){var a=yield(yield v(e)).json();if(!a||!a.hasOwnProperty("keys"))throw"failed to fetch jwk keys from : "+e;var i=a.keys.filter((e=>e.alg===r));if(i.length>1&&(i=i.filter((e=>e.kid===t))),1!==i.length)throw"failed to get jwk against kid : "+t;return i[0]}))()}}})(),a})()));