Comparing version 1.0.0-dev.0 to 1.0.0
import SimpleSigner from './SimpleSigner'; | ||
import NaclSigner from './NaclSigner'; | ||
import { verifyJWT, createJWT, decodeJWT, Signer, createUnsignedJWT } from './JWT'; | ||
import { verifyJWT, createJWT, decodeJWT, Signer } from './JWT'; | ||
import { toEthereumAddress } from './Digest'; | ||
export { SimpleSigner, NaclSigner, verifyJWT, createJWT, createUnsignedJWT, decodeJWT, toEthereumAddress, Signer }; | ||
export { SimpleSigner, NaclSigner, verifyJWT, createJWT, decodeJWT, toEthereumAddress, Signer }; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,2 +0,2 @@ | ||
function r(r){return r&&"object"==typeof r&&"default"in r?r.default:r}var e=require("js-sha256"),n=require("js-sha3"),t=require("elliptic"),o=r(require("tweetnacl")),i=require("@stablelib/utf8"),a=require("buffer"),u=r(require("uport-base64url")),c=r(require("did-resolver"));function f(r){return a.Buffer.from(e.sha256.arrayBuffer(r))}function s(r){return"0x"+(e=a.Buffer.from(r.slice(2),"hex"),a.Buffer.from(n.keccak_256.arrayBuffer(e))).slice(-20).toString("hex");var e}var d=new t.ec("secp256k1");function l(r,e){return void 0===e&&(e=64),r.length===e?r:"0".repeat(e-r.length)+r}function h(r){return new Uint8Array(Array.prototype.slice.call(Buffer.from(r,"base64"),0))}var p=new t.ec("secp256k1");function v(r,e){void 0===e&&(e=!1);var n=u.toBuffer(r);if(n.length!==(e?65:64))throw new Error("wrong signature length");var t={r:n.slice(0,32).toString("hex"),s:n.slice(32,64).toString("hex")};return e&&(t.recoveryParam=n[64]),t}var w={ES256K:function(r,e,n){var t=f(r),o=v(e),i=n.find(function(r){return p.keyFromPublic(r.publicKeyHex,"hex").verify(t,o)});if(!i)throw new Error("Signature invalid for JWT");return i},"ES256K-R":function(r,e,n){var t=v(e,!0),o=f(r),i=p.recoverPubKey(o,t,t.recoveryParam),a=i.encode("hex"),u=i.encode("hex",!0),c=s(a),d=n.find(function(r){var e=r.publicKeyHex;return e===a||e===u||r.ethereumAddress===c});if(!d)throw new Error("Signature invalid for JWT");return d},Ed25519:function(r,e,n){var t=i.encode(r),a=h(u.toBase64(e)),c=n.find(function(r){return o.sign.detached.verify(t,a,h(r.publicKeyBase64))});if(!c)throw new Error("Signature invalid for JWT");return c}};function y(r){var e=w[r];if(!e)throw new Error("Unsupported algorithm "+r);return e}function g(r){return"object"==typeof r&&"r"in r&&"s"in r}function m(r){return function(e,n){try{return Promise.resolve(n(e)).then(function(e){if(g(e))return function(n){var t=e.r,o=e.s,i=e.recoveryParam,c=a.Buffer.alloc(r?65:64);if(a.Buffer.from(t,"hex").copy(c,0),a.Buffer.from(o,"hex").copy(c,32),r){if(void 0===i)throw new Error("Signer did not return a recoveryParam");c[64]=i}return u.encode(c)}();throw new Error("expected a signer function that returns a signature object instead of string")})}catch(r){return Promise.reject(r)}}}y.toSignatureObject=v;var b={ES256K:m(),"ES256K-R":m(!0),Ed25519:function(r,e){try{return Promise.resolve(e(r)).then(function(r){if(g(r))throw new Error("expected a signer function that returns a string instead of signature object");return r})}catch(r){return Promise.reject(r)}}},E={ES256K:["Secp256k1VerificationKey2018","Secp256k1SignatureVerificationKey2018","EcdsaPublicKeySecp256k1"],"ES256K-R":["Secp256k1VerificationKey2018","Secp256k1SignatureVerificationKey2018","EcdsaPublicKeySecp256k1"],Ed25519:["ED25519SignatureVerification"]};function x(r){return u.encode(JSON.stringify(r))}function S(r){return r.match(/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/)}function P(r){if(r.match(/^did:/))return r;if(S(r))return"did:uport:"+r;throw new Error("Not a valid DID '"+r+"'")}function J(r){if(!r)throw new Error("no JWT passed into decodeJWT");var e=r.match(/^([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/);if(e)return{header:JSON.parse(u.decode(e[1])),payload:JSON.parse(u.decode(e[2])),signature:e[3],data:e[1]+"."+e[2]};throw new Error("Incorrect format JWT")}exports.SimpleSigner=function(r){var e=d.keyFromPrivate(r);return function(r){try{var n=e.sign(f(r)),t=n.s,o=n.recoveryParam;return Promise.resolve({r:l(n.r.toString("hex")),s:l(t.toString("hex")),recoveryParam:o})}catch(r){return Promise.reject(r)}}},exports.NaclSigner=function(r){var e=h(r);return function(r){try{var n=i.encode(r),t=o.sign.detached(n,e),c=u.encode(a.Buffer.from(t));return Promise.resolve(c)}catch(r){return Promise.reject(r)}}},exports.verifyJWT=function(r,e){void 0===e&&(e={auth:null,audience:null,callbackUrl:null});try{var n=e.audience?P(e.audience):void 0,t=J(r),o=t.payload,i=t.header,a=t.signature,u=t.data;return Promise.resolve(function(r,e,n){try{var t=E[r];if(!t||0===t.length)throw new Error("No supported signature types for algorithm "+r);var o=P(e);return Promise.resolve(c(o)).then(function(e){if(!e)throw new Error("Unable to resolve DID document for "+o);var i=!n||(e.authentication||[]).map(function(r){return r.publicKey}),a=(e.publicKey||[]).filter(function(r){var e=r.type,o=r.id;return t.find(function(r){return r===e&&(!n||Array.isArray(i)&&i.indexOf(o)>=0)})});if(n&&(!a||0===a.length))throw new Error("DID document for "+o+" does not have public keys suitable for authenticationg user");if(!a||0===a.length)throw new Error("DID document for "+o+" does not have public keys for "+r);return{authenticators:a,issuer:o,doc:e}})}catch(r){return Promise.reject(r)}}(i.alg,o.iss,e.auth)).then(function(t){var c,f=t.doc,s=t.authenticators,d=t.issuer,l=y(i.alg)(u,a,s),h=Math.floor(Date.now()/1e3);if(l){if(o.nbf&&o.nbf>h+300)throw new Error("JWT not valid yet (issued in the future): nbf: "+o.nbf+" > now: "+h);if(o.exp&&o.exp<=h-300)throw new Error("JWT has expired: exp: "+o.exp+" < now: "+h);if(o.aud)if((c=o.aud)&&(c.match(/^did:/)||S(c))){if(!n)throw new Error("JWT audience is required but your app address has not been configured");if(n!==P(o.aud))throw new Error("JWT audience does not match your DID: aud: "+o.aud+" !== yours: "+n)}else{if(!e.callbackUrl)throw new Error("JWT audience matching your callback url is required but one wasn't passed in");if(o.aud!==e.callbackUrl)throw new Error("JWT audience does not match the callback url: aud: "+o.aud+" !== url: "+e.callbackUrl)}return{payload:o,doc:f,issuer:d,signer:l,jwt:r}}})}catch(r){return Promise.reject(r)}},exports.createJWT=function(r,e){var n=e.issuer,t=e.signer,o=e.alg,i=e.expiresIn;try{if(!t)throw new Error("No Signer functionality has been configured");var a={typ:"JWT",alg:o||"ES256K"},u={nbf:Math.floor(Date.now()/1e3),exp:void 0};if(i){if("number"!=typeof i)throw new Error("JWT expiresIn is not a number");u.exp=u.nbf+Math.floor(i)}var c=[x(a),x(Object.assign({},u,r,{iss:n}))].join("."),f=function(r){var e=b[r];if(!e)throw new Error("Unsupported algorithm "+r);return e}(a.alg);return Promise.resolve(f(c,t)).then(function(r){return[c,r].join(".")})}catch(r){return Promise.reject(r)}},exports.createUnsignedJWT=function(r){return[x({type:"JWT",alg:"none,"}),x(r),""].join(".")},exports.decodeJWT=J,exports.toEthereumAddress=s; | ||
function r(r){return r&&"object"==typeof r&&"default"in r?r.default:r}var e=require("js-sha256"),t=require("js-sha3"),n=require("elliptic"),o=r(require("tweetnacl")),i=require("@stablelib/utf8"),a=require("buffer"),u=r(require("uport-base64url")),c=r(require("did-resolver"));function f(r){return a.Buffer.from(e.sha256.arrayBuffer(r))}function s(r){return"0x"+(e=a.Buffer.from(r.slice(2),"hex"),a.Buffer.from(t.keccak_256.arrayBuffer(e))).slice(-20).toString("hex");var e}var d=new n.ec("secp256k1");function l(r,e){return void 0===e&&(e=64),r.length===e?r:"0".repeat(e-r.length)+r}function h(r){return new Uint8Array(Array.prototype.slice.call(Buffer.from(r,"base64"),0))}var v=new n.ec("secp256k1");function p(r,e){void 0===e&&(e=!1);var t=u.toBuffer(r);if(t.length!==(e?65:64))throw new Error("wrong signature length");var n={r:t.slice(0,32).toString("hex"),s:t.slice(32,64).toString("hex")};return e&&(n.recoveryParam=t[64]),n}var w={ES256K:function(r,e,t){var n=f(r),o=p(e),i=t.find(function(r){return v.keyFromPublic(r.publicKeyHex,"hex").verify(n,o)});if(!i)throw new Error("Signature invalid for JWT");return i},"ES256K-R":function(r,e,t){var n=p(e,!0),o=f(r),i=v.recoverPubKey(o,n,n.recoveryParam),a=i.encode("hex"),u=i.encode("hex",!0),c=s(a),d=t.find(function(r){var e=r.publicKeyHex;return e===a||e===u||r.ethereumAddress===c});if(!d)throw new Error("Signature invalid for JWT");return d},Ed25519:function(r,e,t){var n=i.encode(r),a=h(u.toBase64(e)),c=t.find(function(r){return o.sign.detached.verify(n,a,h(r.publicKeyBase64))});if(!c)throw new Error("Signature invalid for JWT");return c}};function y(r){var e=w[r];if(!e)throw new Error("Unsupported algorithm "+r);return e}function g(r){return"object"==typeof r&&"r"in r&&"s"in r}function m(r){return function(e,t){try{return Promise.resolve(t(e)).then(function(e){if(g(e))return function(t){var n=e.r,o=e.s,i=e.recoveryParam,c=a.Buffer.alloc(r?65:64);if(a.Buffer.from(n,"hex").copy(c,0),a.Buffer.from(o,"hex").copy(c,32),r){if(void 0===i)throw new Error("Signer did not return a recoveryParam");c[64]=i}return u.encode(c)}();throw new Error("expected a signer function that returns a signature object instead of string")})}catch(r){return Promise.reject(r)}}}y.toSignatureObject=p;var b={ES256K:m(),"ES256K-R":m(!0),Ed25519:function(r,e){try{return Promise.resolve(e(r)).then(function(r){if(g(r))throw new Error("expected a signer function that returns a string instead of signature object");return r})}catch(r){return Promise.reject(r)}}},E={ES256K:["Secp256k1VerificationKey2018","Secp256k1SignatureVerificationKey2018","EcdsaPublicKeySecp256k1"],"ES256K-R":["Secp256k1VerificationKey2018","Secp256k1SignatureVerificationKey2018","EcdsaPublicKeySecp256k1"],Ed25519:["ED25519SignatureVerification"]};function S(r){return u.encode(JSON.stringify(r))}function x(r){return r.match(/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/)}function P(r){if(r.match(/^did:/))return r;if(x(r))return"did:uport:"+r;throw new Error("Not a valid DID '"+r+"'")}function J(r){if(!r)throw new Error("no JWT passed into decodeJWT");var e=r.match(/^([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/);if(e)return{header:JSON.parse(u.decode(e[1])),payload:JSON.parse(u.decode(e[2])),signature:e[3],data:e[1]+"."+e[2]};throw new Error("Incorrect format JWT")}exports.SimpleSigner=function(r){var e=d.keyFromPrivate(r);return function(r){try{var t=e.sign(f(r)),n=t.s,o=t.recoveryParam;return Promise.resolve({r:l(t.r.toString("hex")),s:l(n.toString("hex")),recoveryParam:o})}catch(r){return Promise.reject(r)}}},exports.NaclSigner=function(r){var e=h(r);return function(r){try{var t=i.encode(r),n=o.sign.detached(t,e),c=u.encode(a.Buffer.from(n));return Promise.resolve(c)}catch(r){return Promise.reject(r)}}},exports.verifyJWT=function(r,e){void 0===e&&(e={auth:null,audience:null,callbackUrl:null});try{var t=e.audience?P(e.audience):void 0,n=J(r),o=n.payload,i=n.header,a=n.signature,u=n.data;return Promise.resolve(function(r,e,t){try{var n=E[r];if(!n||0===n.length)throw new Error("No supported signature types for algorithm "+r);var o=P(e);return Promise.resolve(c(o)).then(function(e){if(!e)throw new Error("Unable to resolve DID document for "+o);var i=!t||(e.authentication||[]).map(function(r){return r.publicKey}),a=(e.publicKey||[]).filter(function(r){var e=r.type,o=r.id;return n.find(function(r){return r===e&&(!t||Array.isArray(i)&&i.indexOf(o)>=0)})});if(t&&(!a||0===a.length))throw new Error("DID document for "+o+" does not have public keys suitable for authenticationg user");if(!a||0===a.length)throw new Error("DID document for "+o+" does not have public keys for "+r);return{authenticators:a,issuer:o,doc:e}})}catch(r){return Promise.reject(r)}}(i.alg,o.iss,e.auth)).then(function(n){var c,f=n.doc,s=n.authenticators,d=n.issuer,l=y(i.alg)(u,a,s),h=Math.floor(Date.now()/1e3);if(l){var v=h+300;if(o.nbf){if(o.nbf>v)throw new Error("JWT not valid before nbf: "+o.nbf)}else if(o.iat&&o.iat>v)throw new Error("JWT not valid yet (issued in the future) iat: "+o.iat);if(o.exp&&o.exp<=h-300)throw new Error("JWT has expired: exp: "+o.exp+" < now: "+h);if(o.aud)if((c=o.aud)&&(c.match(/^did:/)||x(c))){if(!t)throw new Error("JWT audience is required but your app address has not been configured");if(t!==P(o.aud))throw new Error("JWT audience does not match your DID: aud: "+o.aud+" !== yours: "+t)}else{if(!e.callbackUrl)throw new Error("JWT audience matching your callback url is required but one wasn't passed in");if(o.aud!==e.callbackUrl)throw new Error("JWT audience does not match the callback url: aud: "+o.aud+" !== url: "+e.callbackUrl)}return{payload:o,doc:f,issuer:d,signer:l,jwt:r}}})}catch(r){return Promise.reject(r)}},exports.createJWT=function(r,e){var t=e.issuer,n=e.signer,o=e.alg,i=e.expiresIn;try{if(!n)throw new Error("No Signer functionality has been configured");if(!t)throw new Error("No issuing DID has been configured");var a={typ:"JWT",alg:o||"ES256K"},u={iat:Math.floor(Date.now()/1e3),exp:void 0};if(i&&r.nbf){if("number"!=typeof i)throw new Error("JWT expiresIn is not a number");u.exp=r.nbf+Math.floor(i)}var c=[S(a),S(Object.assign({},u,r,{iss:t}))].join("."),f=function(r){var e=b[r];if(!e)throw new Error("Unsupported algorithm "+r);return e}(a.alg);return Promise.resolve(f(c,n)).then(function(r){return[c,r].join(".")})}catch(r){return Promise.reject(r)}},exports.decodeJWT=J,exports.toEthereumAddress=s; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,2 @@ | ||
!function(r,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("js-sha256"),require("js-sha3"),require("elliptic"),require("tweetnacl"),require("@stablelib/utf8"),require("buffer"),require("uport-base64url"),require("did-resolver")):"function"==typeof define&&define.amd?define(["exports","js-sha256","js-sha3","elliptic","tweetnacl","@stablelib/utf8","buffer","uport-base64url","did-resolver"],e):e(r.didJwt={},r.jsSha256,r.jsSha3,r.elliptic,r.tweetnacl,r.utf8,r.buffer,r.base64url,r.resolve)}(this,function(r,e,t,n,o,i,a,u,c){function f(r){return a.Buffer.from(e.sha256.arrayBuffer(r))}function s(r){return"0x"+(e=a.Buffer.from(r.slice(2),"hex"),a.Buffer.from(t.keccak_256.arrayBuffer(e))).slice(-20).toString("hex");var e}o=o&&o.hasOwnProperty("default")?o.default:o,u=u&&u.hasOwnProperty("default")?u.default:u,c=c&&c.hasOwnProperty("default")?c.default:c;var d=new n.ec("secp256k1");function l(r,e){return void 0===e&&(e=64),r.length===e?r:"0".repeat(e-r.length)+r}function h(r){return new Uint8Array(Array.prototype.slice.call(Buffer.from(r,"base64"),0))}var p=new n.ec("secp256k1");function w(r,e){void 0===e&&(e=!1);var t=u.toBuffer(r);if(t.length!==(e?65:64))throw new Error("wrong signature length");var n={r:t.slice(0,32).toString("hex"),s:t.slice(32,64).toString("hex")};return e&&(n.recoveryParam=t[64]),n}var v={ES256K:function(r,e,t){var n=f(r),o=w(e),i=t.find(function(r){return p.keyFromPublic(r.publicKeyHex,"hex").verify(n,o)});if(!i)throw new Error("Signature invalid for JWT");return i},"ES256K-R":function(r,e,t){var n=w(e,!0),o=f(r),i=p.recoverPubKey(o,n,n.recoveryParam),a=i.encode("hex"),u=i.encode("hex",!0),c=s(a),d=t.find(function(r){var e=r.publicKeyHex;return e===a||e===u||r.ethereumAddress===c});if(!d)throw new Error("Signature invalid for JWT");return d},Ed25519:function(r,e,t){var n=i.encode(r),a=h(u.toBase64(e)),c=t.find(function(r){return o.sign.detached.verify(n,a,h(r.publicKeyBase64))});if(!c)throw new Error("Signature invalid for JWT");return c}};function y(r){var e=v[r];if(!e)throw new Error("Unsupported algorithm "+r);return e}function g(r){return"object"==typeof r&&"r"in r&&"s"in r}function m(r){return function(e,t){try{return Promise.resolve(t(e)).then(function(e){if(g(e))return function(t){var n=e.r,o=e.s,i=e.recoveryParam,c=a.Buffer.alloc(r?65:64);if(a.Buffer.from(n,"hex").copy(c,0),a.Buffer.from(o,"hex").copy(c,32),r){if(void 0===i)throw new Error("Signer did not return a recoveryParam");c[64]=i}return u.encode(c)}();throw new Error("expected a signer function that returns a signature object instead of string")})}catch(r){return Promise.reject(r)}}}y.toSignatureObject=w;var b={ES256K:m(),"ES256K-R":m(!0),Ed25519:function(r,e){try{return Promise.resolve(e(r)).then(function(r){if(g(r))throw new Error("expected a signer function that returns a string instead of signature object");return r})}catch(r){return Promise.reject(r)}}},E={ES256K:["Secp256k1VerificationKey2018","Secp256k1SignatureVerificationKey2018","EcdsaPublicKeySecp256k1"],"ES256K-R":["Secp256k1VerificationKey2018","Secp256k1SignatureVerificationKey2018","EcdsaPublicKeySecp256k1"],Ed25519:["ED25519SignatureVerification"]};function S(r){return u.encode(JSON.stringify(r))}function x(r){return r.match(/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/)}function P(r){if(r.match(/^did:/))return r;if(x(r))return"did:uport:"+r;throw new Error("Not a valid DID '"+r+"'")}function j(r){if(!r)throw new Error("no JWT passed into decodeJWT");var e=r.match(/^([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/);if(e)return{header:JSON.parse(u.decode(e[1])),payload:JSON.parse(u.decode(e[2])),signature:e[3],data:e[1]+"."+e[2]};throw new Error("Incorrect format JWT")}r.SimpleSigner=function(r){var e=d.keyFromPrivate(r);return function(r){try{var t=e.sign(f(r)),n=t.s,o=t.recoveryParam;return Promise.resolve({r:l(t.r.toString("hex")),s:l(n.toString("hex")),recoveryParam:o})}catch(r){return Promise.reject(r)}}},r.NaclSigner=function(r){var e=h(r);return function(r){try{var t=i.encode(r),n=o.sign.detached(t,e),c=u.encode(a.Buffer.from(n));return Promise.resolve(c)}catch(r){return Promise.reject(r)}}},r.verifyJWT=function(r,e){void 0===e&&(e={auth:null,audience:null,callbackUrl:null});try{var t=e.audience?P(e.audience):void 0,n=j(r),o=n.payload,i=n.header,a=n.signature,u=n.data;return Promise.resolve(function(r,e,t){try{var n=E[r];if(!n||0===n.length)throw new Error("No supported signature types for algorithm "+r);var o=P(e);return Promise.resolve(c(o)).then(function(e){if(!e)throw new Error("Unable to resolve DID document for "+o);var i=!t||(e.authentication||[]).map(function(r){return r.publicKey}),a=(e.publicKey||[]).filter(function(r){var e=r.type,o=r.id;return n.find(function(r){return r===e&&(!t||Array.isArray(i)&&i.indexOf(o)>=0)})});if(t&&(!a||0===a.length))throw new Error("DID document for "+o+" does not have public keys suitable for authenticationg user");if(!a||0===a.length)throw new Error("DID document for "+o+" does not have public keys for "+r);return{authenticators:a,issuer:o,doc:e}})}catch(r){return Promise.reject(r)}}(i.alg,o.iss,e.auth)).then(function(n){var c,f=n.doc,s=n.authenticators,d=n.issuer,l=y(i.alg)(u,a,s),h=Math.floor(Date.now()/1e3);if(l){if(o.nbf&&o.nbf>h+300)throw new Error("JWT not valid yet (issued in the future): nbf: "+o.nbf+" > now: "+h);if(o.exp&&o.exp<=h-300)throw new Error("JWT has expired: exp: "+o.exp+" < now: "+h);if(o.aud)if((c=o.aud)&&(c.match(/^did:/)||x(c))){if(!t)throw new Error("JWT audience is required but your app address has not been configured");if(t!==P(o.aud))throw new Error("JWT audience does not match your DID: aud: "+o.aud+" !== yours: "+t)}else{if(!e.callbackUrl)throw new Error("JWT audience matching your callback url is required but one wasn't passed in");if(o.aud!==e.callbackUrl)throw new Error("JWT audience does not match the callback url: aud: "+o.aud+" !== url: "+e.callbackUrl)}return{payload:o,doc:f,issuer:d,signer:l,jwt:r}}})}catch(r){return Promise.reject(r)}},r.createJWT=function(r,e){var t=e.issuer,n=e.signer,o=e.alg,i=e.expiresIn;try{if(!n)throw new Error("No Signer functionality has been configured");var a={typ:"JWT",alg:o||"ES256K"},u={nbf:Math.floor(Date.now()/1e3),exp:void 0};if(i){if("number"!=typeof i)throw new Error("JWT expiresIn is not a number");u.exp=u.nbf+Math.floor(i)}var c=[S(a),S(Object.assign({},u,r,{iss:t}))].join("."),f=function(r){var e=b[r];if(!e)throw new Error("Unsupported algorithm "+r);return e}(a.alg);return Promise.resolve(f(c,n)).then(function(r){return[c,r].join(".")})}catch(r){return Promise.reject(r)}},r.createUnsignedJWT=function(r){return[S({type:"JWT",alg:"none,"}),S(r),""].join(".")},r.decodeJWT=j,r.toEthereumAddress=s}); | ||
!function(r,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("js-sha256"),require("js-sha3"),require("elliptic"),require("tweetnacl"),require("@stablelib/utf8"),require("buffer"),require("uport-base64url"),require("did-resolver")):"function"==typeof define&&define.amd?define(["exports","js-sha256","js-sha3","elliptic","tweetnacl","@stablelib/utf8","buffer","uport-base64url","did-resolver"],e):e(r.didJwt={},r.jsSha256,r.jsSha3,r.elliptic,r.tweetnacl,r.utf8,r.buffer,r.base64url,r.resolve)}(this,function(r,e,t,n,i,o,a,u,c){function f(r){return a.Buffer.from(e.sha256.arrayBuffer(r))}function s(r){return"0x"+(e=a.Buffer.from(r.slice(2),"hex"),a.Buffer.from(t.keccak_256.arrayBuffer(e))).slice(-20).toString("hex");var e}i=i&&i.hasOwnProperty("default")?i.default:i,u=u&&u.hasOwnProperty("default")?u.default:u,c=c&&c.hasOwnProperty("default")?c.default:c;var d=new n.ec("secp256k1");function l(r,e){return void 0===e&&(e=64),r.length===e?r:"0".repeat(e-r.length)+r}function h(r){return new Uint8Array(Array.prototype.slice.call(Buffer.from(r,"base64"),0))}var p=new n.ec("secp256k1");function w(r,e){void 0===e&&(e=!1);var t=u.toBuffer(r);if(t.length!==(e?65:64))throw new Error("wrong signature length");var n={r:t.slice(0,32).toString("hex"),s:t.slice(32,64).toString("hex")};return e&&(n.recoveryParam=t[64]),n}var v={ES256K:function(r,e,t){var n=f(r),i=w(e),o=t.find(function(r){return p.keyFromPublic(r.publicKeyHex,"hex").verify(n,i)});if(!o)throw new Error("Signature invalid for JWT");return o},"ES256K-R":function(r,e,t){var n=w(e,!0),i=f(r),o=p.recoverPubKey(i,n,n.recoveryParam),a=o.encode("hex"),u=o.encode("hex",!0),c=s(a),d=t.find(function(r){var e=r.publicKeyHex;return e===a||e===u||r.ethereumAddress===c});if(!d)throw new Error("Signature invalid for JWT");return d},Ed25519:function(r,e,t){var n=o.encode(r),a=h(u.toBase64(e)),c=t.find(function(r){return i.sign.detached.verify(n,a,h(r.publicKeyBase64))});if(!c)throw new Error("Signature invalid for JWT");return c}};function y(r){var e=v[r];if(!e)throw new Error("Unsupported algorithm "+r);return e}function g(r){return"object"==typeof r&&"r"in r&&"s"in r}function m(r){return function(e,t){try{return Promise.resolve(t(e)).then(function(e){if(g(e))return function(t){var n=e.r,i=e.s,o=e.recoveryParam,c=a.Buffer.alloc(r?65:64);if(a.Buffer.from(n,"hex").copy(c,0),a.Buffer.from(i,"hex").copy(c,32),r){if(void 0===o)throw new Error("Signer did not return a recoveryParam");c[64]=o}return u.encode(c)}();throw new Error("expected a signer function that returns a signature object instead of string")})}catch(r){return Promise.reject(r)}}}y.toSignatureObject=w;var b={ES256K:m(),"ES256K-R":m(!0),Ed25519:function(r,e){try{return Promise.resolve(e(r)).then(function(r){if(g(r))throw new Error("expected a signer function that returns a string instead of signature object");return r})}catch(r){return Promise.reject(r)}}},E={ES256K:["Secp256k1VerificationKey2018","Secp256k1SignatureVerificationKey2018","EcdsaPublicKeySecp256k1"],"ES256K-R":["Secp256k1VerificationKey2018","Secp256k1SignatureVerificationKey2018","EcdsaPublicKeySecp256k1"],Ed25519:["ED25519SignatureVerification"]};function S(r){return u.encode(JSON.stringify(r))}function x(r){return r.match(/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]+$/)}function P(r){if(r.match(/^did:/))return r;if(x(r))return"did:uport:"+r;throw new Error("Not a valid DID '"+r+"'")}function j(r){if(!r)throw new Error("no JWT passed into decodeJWT");var e=r.match(/^([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_-]+)$/);if(e)return{header:JSON.parse(u.decode(e[1])),payload:JSON.parse(u.decode(e[2])),signature:e[3],data:e[1]+"."+e[2]};throw new Error("Incorrect format JWT")}r.SimpleSigner=function(r){var e=d.keyFromPrivate(r);return function(r){try{var t=e.sign(f(r)),n=t.s,i=t.recoveryParam;return Promise.resolve({r:l(t.r.toString("hex")),s:l(n.toString("hex")),recoveryParam:i})}catch(r){return Promise.reject(r)}}},r.NaclSigner=function(r){var e=h(r);return function(r){try{var t=o.encode(r),n=i.sign.detached(t,e),c=u.encode(a.Buffer.from(n));return Promise.resolve(c)}catch(r){return Promise.reject(r)}}},r.verifyJWT=function(r,e){void 0===e&&(e={auth:null,audience:null,callbackUrl:null});try{var t=e.audience?P(e.audience):void 0,n=j(r),i=n.payload,o=n.header,a=n.signature,u=n.data;return Promise.resolve(function(r,e,t){try{var n=E[r];if(!n||0===n.length)throw new Error("No supported signature types for algorithm "+r);var i=P(e);return Promise.resolve(c(i)).then(function(e){if(!e)throw new Error("Unable to resolve DID document for "+i);var o=!t||(e.authentication||[]).map(function(r){return r.publicKey}),a=(e.publicKey||[]).filter(function(r){var e=r.type,i=r.id;return n.find(function(r){return r===e&&(!t||Array.isArray(o)&&o.indexOf(i)>=0)})});if(t&&(!a||0===a.length))throw new Error("DID document for "+i+" does not have public keys suitable for authenticationg user");if(!a||0===a.length)throw new Error("DID document for "+i+" does not have public keys for "+r);return{authenticators:a,issuer:i,doc:e}})}catch(r){return Promise.reject(r)}}(o.alg,i.iss,e.auth)).then(function(n){var c,f=n.doc,s=n.authenticators,d=n.issuer,l=y(o.alg)(u,a,s),h=Math.floor(Date.now()/1e3);if(l){var p=h+300;if(i.nbf){if(i.nbf>p)throw new Error("JWT not valid before nbf: "+i.nbf)}else if(i.iat&&i.iat>p)throw new Error("JWT not valid yet (issued in the future) iat: "+i.iat);if(i.exp&&i.exp<=h-300)throw new Error("JWT has expired: exp: "+i.exp+" < now: "+h);if(i.aud)if((c=i.aud)&&(c.match(/^did:/)||x(c))){if(!t)throw new Error("JWT audience is required but your app address has not been configured");if(t!==P(i.aud))throw new Error("JWT audience does not match your DID: aud: "+i.aud+" !== yours: "+t)}else{if(!e.callbackUrl)throw new Error("JWT audience matching your callback url is required but one wasn't passed in");if(i.aud!==e.callbackUrl)throw new Error("JWT audience does not match the callback url: aud: "+i.aud+" !== url: "+e.callbackUrl)}return{payload:i,doc:f,issuer:d,signer:l,jwt:r}}})}catch(r){return Promise.reject(r)}},r.createJWT=function(r,e){var t=e.issuer,n=e.signer,i=e.alg,o=e.expiresIn;try{if(!n)throw new Error("No Signer functionality has been configured");if(!t)throw new Error("No issuing DID has been configured");var a={typ:"JWT",alg:i||"ES256K"},u={iat:Math.floor(Date.now()/1e3),exp:void 0};if(o&&r.nbf){if("number"!=typeof o)throw new Error("JWT expiresIn is not a number");u.exp=r.nbf+Math.floor(o)}var c=[S(a),S(Object.assign({},u,r,{iss:t}))].join("."),f=function(r){var e=b[r];if(!e)throw new Error("Unsupported algorithm "+r);return e}(a.alg);return Promise.resolve(f(c,n)).then(function(r){return[c,r].join(".")})}catch(r){return Promise.reject(r)}},r.decodeJWT=j,r.toEthereumAddress=s}); | ||
//# sourceMappingURL=index.umd.js.map |
@@ -33,2 +33,3 @@ import { DIDDocument, PublicKey } from 'did-resolver'; | ||
aud?: string; | ||
iat?: number; | ||
nbf?: number; | ||
@@ -80,4 +81,3 @@ type?: string; | ||
*/ | ||
export declare function createJWT(payload: object, { issuer, signer, alg, expiresIn }: JWTOptions): Promise<string>; | ||
export declare function createUnsignedJWT(payload: object): string; | ||
export declare function createJWT(payload: any, { issuer, signer, alg, expiresIn }: JWTOptions): Promise<string>; | ||
/** | ||
@@ -84,0 +84,0 @@ * Verifies given JWT. If the JWT is valid, the promise returns an object including the JWT, the payload of the JWT, |
{ | ||
"name": "did-jwt", | ||
"version": "1.0.0-dev.0", | ||
"version": "1.0.0", | ||
"description": "Library for Signing and Verifying JWTs compatible uPort and DID standards", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -110,3 +110,3 @@ import { | ||
return createJWT( | ||
{ requested: ['name', 'phone'] }, | ||
{ requested: ['name', 'phone'], nbf: Math.floor(new Date().getTime() / 1000) }, | ||
{ issuer: did, signer, expiresIn: 10000 } | ||
@@ -119,2 +119,36 @@ ).then(jwt => { | ||
it('ignores expiresIn if nbf is not set', async () => { | ||
const { payload } = decodeJWT(await createJWT( | ||
{ requested: ['name', 'phone'] }, | ||
{ issuer: did, signer, expiresIn: 10000 } | ||
)) | ||
return expect(payload.exp).toBeUndefined() | ||
}) | ||
it('sets iat to the current time by default', async () => { | ||
const timestamp = Math.floor(Date.now() / 1000) | ||
const { payload } = decodeJWT(await createJWT( | ||
{ requested: ['name', 'phone'] }, | ||
{ issuer: did, signer } | ||
)) | ||
return expect(payload.iat).toEqual(timestamp) | ||
}) | ||
it('sets iat to the value passed in payload', async () => { | ||
const timestamp = 2000000 | ||
const { payload } = decodeJWT(await createJWT( | ||
{ requested: ['name', 'phone'], iat: timestamp }, | ||
{ issuer: did, signer } | ||
)) | ||
return expect(payload.iat).toEqual(timestamp) | ||
}) | ||
it('does not set iat if value in payload is undefined', async () => { | ||
const { payload } = decodeJWT(await createJWT( | ||
{ requested: ['name', 'phone'], iat: undefined }, | ||
{ issuer: did, signer } | ||
)) | ||
return expect(payload.iat).toBeUndefined() | ||
}) | ||
it('throws an error if unsupported algorithm is passed in', () => { | ||
@@ -157,3 +191,3 @@ return createJWT( | ||
return createJWT( | ||
{ requested: ['name', 'phone'] }, | ||
{ requested: ['name', 'phone'], nbf: Math.floor(new Date().getTime() / 1000) }, | ||
{ alg, issuer: did, signer, expiresIn: 10000 } | ||
@@ -269,10 +303,38 @@ ).then(jwt => { | ||
it('accepts a valid nbf', () => { | ||
return createJWT({ nbf: NOW + NBF_SKEW }, { issuer: did, signer }).then( | ||
jwt => | ||
verifyJWT(jwt).then( | ||
({ payload }) => expect(payload).toMatchSnapshot(), | ||
error => expect(error).toBeNull() | ||
) | ||
) | ||
describe('validFrom timestamp', () => { | ||
it('passes when nbf is in the past', async () => { | ||
// tslint:disable-next-line: max-line-length | ||
const jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE0ODUzMjExMzMsIm5iZiI6MTQ4NTI2MTEzMywiaXNzIjoiZGlkOnVwb3J0OjJuUXRpUUc2Q2dtMUdZVEJhYUtBZ3I3NnVZN2lTZXhVa3FYIn0.btzVz7fZsoSEDa7JyWo3cYWL63pkWTKTz8OUzepIesfSFeBozUjX2oq1xOJ2OyzuinnLGwtSqY303VoyALrafA' | ||
expect(verifyJWT(jwt)).resolves.not.toThrow() | ||
}) | ||
it('passes when nbf is in the past and iat is in the future', async () => { | ||
// tslint:disable-next-line: max-line-length | ||
const jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE0ODUzODExMzMsIm5iZiI6MTQ4NTI2MTEzMywiaXNzIjoiZGlkOnVwb3J0OjJuUXRpUUc2Q2dtMUdZVEJhYUtBZ3I3NnVZN2lTZXhVa3FYIn0.ELsPnDC_YTTkT5hxw09UCLSjWVje9mDs1n_mpvlo2Wk5VJONSy-FDAzm5TunzzCeLixU04m6dD4w6Uk3-OVkww' | ||
expect(verifyJWT(jwt)).resolves.not.toThrow() | ||
}) | ||
it('fails when nbf is in the future', async () => { | ||
// tslint:disable-next-line: max-line-length | ||
const jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE0ODUzMjExMzMsIm5iZiI6MTQ4NTM4MTEzMywiaXNzIjoiZGlkOnVwb3J0OjJuUXRpUUc2Q2dtMUdZVEJhYUtBZ3I3NnVZN2lTZXhVa3FYIn0.rcFuhVHtie3Y09pWxBSf1dnjaVh6FFQLHh-83N-uLty3M5ADJ-jVFFkyt_Eupl8Kr735-oPGn_D1Nj9rl4s_Kw' | ||
expect(verifyJWT(jwt)).rejects.toThrow() | ||
}) | ||
it('fails when nbf is in the future and iat is in the past', async () => { | ||
// tslint:disable-next-line: max-line-length | ||
const jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE0ODUyNjExMzMsIm5iZiI6MTQ4NTM4MTEzMywiaXNzIjoiZGlkOnVwb3J0OjJuUXRpUUc2Q2dtMUdZVEJhYUtBZ3I3NnVZN2lTZXhVa3FYIn0.jiVI11IcKNOvnDrJBzojKtNAGaZbEcafcqW-wfP78g6-6RucjYPBi5qvKje35IOvITWvvpXpK48IW-17Srh02w' | ||
expect(verifyJWT(jwt)).rejects.toThrow() | ||
}) | ||
it('passes when nbf is missing and iat is in the past', async () => { | ||
// tslint:disable-next-line: max-line-length | ||
const jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE0ODUyNjExMzMsImlzcyI6ImRpZDp1cG9ydDoyblF0aVFHNkNnbTFHWVRCYWFLQWdyNzZ1WTdpU2V4VWtxWCJ9.1VwGHDm7f9V-1Fa545uAwF9NfU3RI8yqRFW6XAHOg0FBeM7krC_rEf0PwqbKFO8MiIBELBwUhW_fT4oZsuggUA' | ||
expect(verifyJWT(jwt)).resolves.not.toThrow() | ||
}) | ||
it('fails when nbf is missing and iat is in the future', async () => { | ||
// tslint:disable-next-line: max-line-length | ||
const jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE0ODUzODExMzMsImlzcyI6ImRpZDp1cG9ydDoyblF0aVFHNkNnbTFHWVRCYWFLQWdyNzZ1WTdpU2V4VWtxWCJ9.jU0R8qP3aUX_3DiFt9tIONiq_P5OooFc-ypUwpqK4plGyw6WiI0FTGfZvq7pOarKrjmSojE9Sm_3ETfMpdQckg' | ||
expect(verifyJWT(jwt)).rejects.toThrow() | ||
}) | ||
it('passes when nbf and iat are both missing', async () => { | ||
// tslint:disable-next-line: max-line-length | ||
const jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpc3MiOiJkaWQ6dXBvcnQ6Mm5RdGlRRzZDZ20xR1lUQmFhS0Fncjc2dVk3aVNleFVrcVgifQ.5kGKU9ljebhTqvfVDu9MH7vGAqRH0GDTbZNGH45YmhUySgBTyI7u-MkkRit72eFvQAqBfzw6wNUbGf9FPC5AtQ' | ||
expect(verifyJWT(jwt)).resolves.not.toThrow() | ||
}) | ||
}) | ||
@@ -304,21 +366,8 @@ | ||
it('rejects an nbf in the future', () => { | ||
return createJWT({ nbf: NOW + NBF_SKEW + 1 }, { issuer: did, signer }).then( | ||
jwt => | ||
verifyJWT(jwt) | ||
.catch(error => | ||
expect(error.message).toEqual( | ||
'JWT not valid yet (issued in the future): nbf: 1485321434 > now: 1485321133' | ||
) | ||
) | ||
.then(p => expect(p).toBeFalsy()) | ||
) | ||
}) | ||
it('accepts a valid exp', () => { | ||
return createJWT( | ||
{ exp: NOW - NBF_SKEW + 1 }, | ||
{ issuer: did, signer, expiresIn: 1 } | ||
{ exp: NOW }, | ||
{ issuer: did, signer } | ||
).then(jwt => | ||
verifyJWT(jwt).then(({ payload }) => expect(payload).toMatchSnapshot()) | ||
verifyJWT(jwt).then(({ payload }) => expect(payload).toBeDefined()) | ||
) | ||
@@ -325,0 +374,0 @@ }) |
import SimpleSigner from './SimpleSigner' | ||
import NaclSigner from './NaclSigner' | ||
import { verifyJWT, createJWT, decodeJWT, Signer, createUnsignedJWT } from './JWT' | ||
import { verifyJWT, createJWT, decodeJWT, Signer } from './JWT' | ||
import { toEthereumAddress } from './Digest' | ||
@@ -11,3 +11,2 @@ | ||
createJWT, | ||
createUnsignedJWT, | ||
decodeJWT, | ||
@@ -14,0 +13,0 @@ toEthereumAddress, |
@@ -46,2 +46,3 @@ import VerifierAlgorithm from './VerifierAlgorithm' | ||
aud?: string | ||
iat?: number | ||
nbf?: number | ||
@@ -156,14 +157,15 @@ type?: string | ||
export async function createJWT( | ||
payload: object, | ||
payload: any, | ||
{ issuer, signer, alg, expiresIn }: JWTOptions | ||
): Promise<string> { | ||
if (!signer) throw new Error('No Signer functionality has been configured') | ||
if (!issuer) throw new Error('No issuing DID has been configured') | ||
const header: JWTHeader = { typ: 'JWT', alg: alg || defaultAlg } | ||
const timestamps: Partial<JWTPayload> = { | ||
nbf: Math.floor(Date.now() / 1000), | ||
iat: Math.floor(Date.now() / 1000), | ||
exp: undefined | ||
} | ||
if (expiresIn) { | ||
if (expiresIn && payload.nbf) { | ||
if (typeof expiresIn === 'number') { | ||
timestamps.exp = timestamps.nbf + Math.floor(expiresIn) | ||
timestamps.exp = payload.nbf + Math.floor(expiresIn) | ||
} else { | ||
@@ -183,13 +185,2 @@ throw new Error('JWT expiresIn is not a number') | ||
export function createUnsignedJWT(payload: object): string { | ||
return [ | ||
encodeSection({ | ||
type: 'JWT', | ||
alg: 'none,' | ||
}), | ||
encodeSection(payload), | ||
'' | ||
].join('.') | ||
} | ||
/** | ||
@@ -240,8 +231,9 @@ * Verifies given JWT. If the JWT is valid, the promise returns an object including the JWT, the payload of the JWT, | ||
if (signer) { | ||
if (payload.nbf && payload.nbf > now + NBF_SKEW) { | ||
throw new Error( | ||
`JWT not valid yet (issued in the future): nbf: ${ | ||
payload.nbf | ||
} > now: ${now}` | ||
) | ||
const nowSkewed = now + NBF_SKEW | ||
if (payload.nbf) { | ||
if (payload.nbf > nowSkewed) { | ||
throw new Error(`JWT not valid before nbf: ${payload.nbf}`) | ||
} | ||
} else if (payload.iat && payload.iat > nowSkewed) { | ||
throw new Error(`JWT not valid yet (issued in the future) iat: ${payload.iat}`) | ||
} | ||
@@ -248,0 +240,0 @@ if (payload.exp && payload.exp <= now - NBF_SKEW) { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
409661
2041
3
1