UNPKG

@altostra/core

Version:

Core library for shared types and logic

1 lines 5.78 kB
"use strict";var _JwtValidator_config,__classPrivateFieldSet=this&&this.__classPrivateFieldSet||function(e,t,r,a,i){if("m"===a)throw new TypeError("Private method is not writable");if("a"===a&&!i)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!i:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===a?i.call(e,r):i?i.value=r:t.set(e,r),r},__classPrivateFieldGet=this&&this.__classPrivateFieldGet||function(e,t,r,a){if("a"===r&&!a)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!a:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?a:"a"===r?a.call(e):a?a.value:t.get(e)},__rest=this&&this.__rest||function(e,t){var r={};for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&t.indexOf(a)<0&&(r[a]=e[a]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(a=Object.getOwnPropertySymbols(e);i<a.length;i++)t.indexOf(a[i])<0&&Object.prototype.propertyIsEnumerable.call(e,a[i])&&(r[a[i]]=e[a[i]])}return r},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.JwtValidator=exports.AltostraClaimNamespace=exports.ErrorCodes=void 0;const NonEmptyString_1=require("../common/CustomTypes/NonEmptyString"),Result_1=require("../common/Result"),Date_1=require("../common/Utils/Date"),type_validations_1=require("@altostra/type-validations"),primitives_1=require("@altostra/type-validations/lib/primitives"),iterable_1=require("@reactivex/ix-es2015-cjs/iterable"),map_1=require("@reactivex/ix-es2015-cjs/iterable/operators/map"),jsonwebtoken_1=__importDefault(require("jsonwebtoken")),isJwtValidatorConfigMultipleKeys=(0,type_validations_1.objectOf)({audience:(0,type_validations_1.arrayOf)(primitives_1.string),ignoreExpiration:primitives_1.maybeBoolean,publicKeys:(0,type_validations_1.arrayOf)(primitives_1.string),skipSignatureVerification:primitives_1.maybeBoolean});var ErrorCodes;!function(e){e[e.MissingToken=400]="MissingToken",e[e.InvalidToken=401]="InvalidToken",e[e.MalformedPayload=500]="MalformedPayload",e[e.MissingUserPayload=501]="MissingUserPayload",e[e.WrongPayloadType=502]="WrongPayloadType"}(ErrorCodes=exports.ErrorCodes||(exports.ErrorCodes={})),exports.AltostraClaimNamespace="https://altostra.com";class JwtValidator{constructor(e){if(_JwtValidator_config.set(this,void 0),isJwtValidatorConfigMultipleKeys(e))__classPrivateFieldSet(this,_JwtValidator_config,e,"f");else{const{publicKey:t}=e,r=__rest(e,["publicKey"]);__classPrivateFieldSet(this,_JwtValidator_config,Object.assign(Object.assign({},r),{publicKeys:[t]}),"f")}}validate(e){if(!(0,NonEmptyString_1.isNonEmptyString)(e))return(0,Result_1.failure)({code:ErrorCodes.MissingToken,message:"Expected token value was missing or a string value.",data:e});const t=e.replace(/^Bearer /,""),r=this;if(!__classPrivateFieldGet(this,_JwtValidator_config,"f").skipSignatureVerification){const e=[],a=(0,iterable_1.from)(__classPrivateFieldGet(this,_JwtValidator_config,"f").publicKeys).pipe((0,map_1.map)(e=>function(e){try{return jsonwebtoken_1.default.verify(t,e,{algorithms:["RS256"],audience:__classPrivateFieldGet(r,_JwtValidator_config,"f").audience,ignoreExpiration:!!__classPrivateFieldGet(r,_JwtValidator_config,"f").ignoreExpiration}),{isValid:!0}}catch(e){return{isValid:!1,err:e}}}(e)),(0,map_1.map)(t=>(e.push(t.err),t)));if(!(0,iterable_1.find)(a,e=>e.isValid))return(0,Result_1.failure)({code:ErrorCodes.InvalidToken,message:"Token validation failed.",data:{errors:e}})}return JwtValidator.decodeUnverified(e,__classPrivateFieldGet(this,_JwtValidator_config,"f"))}static decodeUnverified(e,t){try{const r=jsonwebtoken_1.default.decode(e,{complete:!1});return"string"==typeof r?(0,Result_1.failure)({code:ErrorCodes.WrongPayloadType,message:"Expected payload to be JWT but it was a string."}):r&&"object"==typeof r?"string"!=typeof r.sub?(0,Result_1.failure)({code:ErrorCodes.MalformedPayload,message:"Unable to find 'sub' property in the token payload or it is of wrong type.",data:r}):void 0===r.exp||isNaN(r.exp)?(0,Result_1.failure)({code:ErrorCodes.MalformedPayload,message:"Unable to parse 'exp' property in the token payload or it is of wrong type.",data:r}):t.skipSignatureVerification&&!t.ignoreExpiration&&Number(r.exp)<Date.now()/1e3?(0,Result_1.failure)({code:ErrorCodes.InvalidToken,message:"Token has expired.",data:r}):void 0===r.iat||isNaN(r.iat)?(0,Result_1.failure)({code:ErrorCodes.MalformedPayload,message:"Unable to parse 'iat' property in the token payload or it is of wrong type.",data:r}):r.scope&&"string"!=typeof r.scope?(0,Result_1.failure)({code:ErrorCodes.MalformedPayload,message:"Type of 'scope' property is of wrong type.",data:r}):"string"!=typeof r.iss?(0,Result_1.failure)({code:ErrorCodes.MalformedPayload,message:"Unable to find 'iss' property in the token payload or it is of wrong type.",data:r}):(0,Result_1.success)({user:r.sub,expires:(0,Date_1.fromEpoch)(r.exp),claims:Object.assign({iss:r.iss,iat:r.iat,exp:r.exp,sub:r.sub,scope:r.scope,permissions:r.permissions},getAltostraClaims(r))}):(0,Result_1.failure)({code:ErrorCodes.MalformedPayload,message:"Unable to decode the payload as an object.",data:r})}catch(e){return(0,Result_1.failure)({code:ErrorCodes.MalformedPayload,message:"Unable to decode the JWT token.",inner:e})}}}function getAltostraClaims(e){return{altostra:Object.keys(e).filter(e=>e.startsWith(exports.AltostraClaimNamespace)).reduce((t,r)=>(r.startsWith(exports.AltostraClaimNamespace)&&(t[r]=e[r]),t),{})}}exports.JwtValidator=JwtValidator,_JwtValidator_config=new WeakMap;