@altostra/core
Version:
Core library for shared types and logic
1 lines • 10.8 kB
JavaScript
;var _AuthManager_instances,_AuthManager_logger,_AuthManager_refreshToken,_AuthManager_credentials,_AuthManager_axios,_AuthManager_clientId,_AuthManager_publicKey,_AuthManager_suppressCache,_AuthManager_storeTokens,_AuthManager_storeAccessToken,_AuthManager_refreshAccessToken,_AuthManager_refreshWithRefreshToken,_AuthManager_loadCredentials,__awaiter=this&&this.__awaiter||function(e,t,a,r){return new(a||(a=Promise))((function(i,s){function n(e){try{_(r.next(e))}catch(e){s(e)}}function o(e){try{_(r.throw(e))}catch(e){s(e)}}function _(e){var t;e.done?i(e.value):(t=e.value,t instanceof a?t:new a((function(e){e(t)}))).then(n,o)}_((r=r.apply(e,t||[])).next())}))},__classPrivateFieldSet=this&&this.__classPrivateFieldSet||function(e,t,a,r,i){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!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"===r?i.call(e,a):i?i.value=a:t.set(e,a),a},__classPrivateFieldGet=this&&this.__classPrivateFieldGet||function(e,t,a,r){if("a"===a&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===a?r:"a"===a?r.call(e):r?r.value:t.get(e)},__importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.AuthManager=void 0;const fs_1=require("fs"),path_1=require("path"),AltoError_1=require("../../common/Errors/AltoError"),Logging_1=require("../../common/Logging"),FS_1=require("../../common/Utils/FS"),Url_1=require("../../common/Utils/Url"),altostra_public_key_1=__importDefault(require("../../jwt/altostra-public-key")),JwtValidator_1=require("../../jwt/JwtValidator"),type_validations_1=require("@altostra/type-validations"),primitives_1=require("@altostra/type-validations/lib/primitives"),axios_1=__importDefault(require("axios")),Defaults_1=require("./Defaults"),UnAuthenticatedError_1=require("./errors/UnAuthenticatedError"),Types_1=require("./Types"),paths_1=require("./utils/paths"),ALTO_CLAIM_PREFIX="https://altostra.com/",CURR_TEAM_CLAIM=ALTO_CLAIM_PREFIX+"organization",MEMBER_OF_CLAIM=ALTO_CLAIM_PREFIX+"member_of",ONBOARDING_COMPLETE_CLAIM=ALTO_CLAIM_PREFIX+"onboarding_complete",CREDS_MOD=384,isOptionalArrayOfStrings=(0,type_validations_1.maybe)((0,type_validations_1.arrayOf)(primitives_1.string));class AuthManager{constructor({tokensFilePath:e,clientId:t,ignoreTokenExpiration:a,skipSignatureVerification:r,publicKey:i,auth0Tenant:s,oauthUrl:n,debug:o,axios:_,cacheSuppression:l=!1}){_AuthManager_instances.add(this),_AuthManager_logger.set(this,void 0),_AuthManager_refreshToken.set(this,void 0),_AuthManager_credentials.set(this,void 0),_AuthManager_axios.set(this,void 0),_AuthManager_clientId.set(this,void 0),_AuthManager_publicKey.set(this,void 0),_AuthManager_suppressCache.set(this,void 0),this.ignoreTokenExpiration=!1,this.skipSignatureVerification=!1,this.tryGetCredentials=()=>__awaiter(this,void 0,void 0,(function*(){var e;if(!__classPrivateFieldGet(this,_AuthManager_suppressCache,"f")&&__classPrivateFieldGet(this,_AuthManager_credentials,"f")&&__classPrivateFieldGet(this,_AuthManager_credentials,"f").expires>new Date)return __classPrivateFieldGet(this,_AuthManager_credentials,"f");try{let t;const{access:a}=null!==(e=yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_loadCredentials).call(this))&&void 0!==e?e:{};if(a&&(t=this.verifyToken(a)),null!=t||(t=yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_refreshAccessToken).call(this)),!t)throw new AltoError_1.AltoError("Could not obtain user name from token.",void 0,a);return __classPrivateFieldSet(this,_AuthManager_credentials,{token:t.token,user:t.user,expires:t.expires,memberOf:t.memberOf,team:t.team},"f"),__classPrivateFieldGet(this,_AuthManager_credentials,"f")}catch(e){return __classPrivateFieldGet(this,_AuthManager_logger,"f").warn("Unable to get credentials.",e),void(yield this.tryDeleteTokensFile())}})),this.tokenLocation=(0,paths_1.resolvePathInHomeDir)(null!=e?e:(0,Defaults_1.tokenFile)()),__classPrivateFieldSet(this,_AuthManager_clientId,t,"f"),this.ignoreTokenExpiration=!!a,this.skipSignatureVerification=!!r,__classPrivateFieldSet(this,_AuthManager_logger,null!=o?o:(0,Logging_1.nullLogger)("AuthManager"),"f"),__classPrivateFieldSet(this,_AuthManager_axios,null!=_?_:axios_1.default.create(),"f"),__classPrivateFieldSet(this,_AuthManager_publicKey,null!=i?i:altostra_public_key_1.default,"f"),this.oauthProvider=s?Url_1.asUrl`https://${s}.auth0.com/`:null!=n?n:Defaults_1.oauthProvider,__classPrivateFieldSet(this,_AuthManager_suppressCache,l,"f")}validateLogin(e){return __awaiter(this,void 0,void 0,(function*(){const t=yield this.tryGetCredentials();if(!t)throw new UnAuthenticatedError_1.UnAuthenticatedError("no-login",null!=e?e:"You are not logged in. Please run 'alto login' and try again.");return t}))}storeToken(e,t){return __awaiter(this,void 0,void 0,(function*(){yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_storeTokens).call(this,t,e)}))}storeUnrefreshableToken(e){return __awaiter(this,void 0,void 0,(function*(){yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_storeAccessToken).call(this,e)}))}clearAllCredentials(){return __awaiter(this,void 0,void 0,(function*(){yield this.tryDeleteTokensFile()}))}tryDeleteTokensFile(){return __awaiter(this,void 0,void 0,(function*(){__classPrivateFieldSet(this,_AuthManager_refreshToken,void 0,"f"),__classPrivateFieldSet(this,_AuthManager_credentials,void 0,"f"),yield tryDeleteFile(this.tokenLocation,__classPrivateFieldGet(this,_AuthManager_logger,"f"))}))}verifyToken(e){var t,a,r;const i=new JwtValidator_1.JwtValidator({audience:["https://charlie-api.altostra.com"],publicKey:__classPrivateFieldGet(this,_AuthManager_publicKey,"f"),ignoreExpiration:this.ignoreTokenExpiration,skipSignatureVerification:this.skipSignatureVerification}).validate(e);if("result-success"!==i.type)return void __classPrivateFieldGet(this,_AuthManager_logger,"f").warn("Token verification failed",i);const s=null===(t=i.value.claims.altostra)||void 0===t?void 0:t[CURR_TEAM_CLAIM],n=null===(a=i.value.claims.altostra)||void 0===a?void 0:a[MEMBER_OF_CLAIM];if("string"==typeof s){if(isOptionalArrayOfStrings(n))return __classPrivateFieldGet(this,_AuthManager_logger,"f").verbose("Validated token successfully"),{user:i.value.user,expires:i.value.expires,team:s,memberOf:null!=n?n:[],token:e,onboardingComplete:!!(null===(r=i.value.claims.altostra)||void 0===r?void 0:r[ONBOARDING_COMPLETE_CLAIM])};__classPrivateFieldGet(this,_AuthManager_logger,"f").error("Member-of has invalid data")}else __classPrivateFieldGet(this,_AuthManager_logger,"f").error("Cannot get team membership")}loadCredentials(){return __awaiter(this,void 0,void 0,(function*(){let e=yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_loadCredentials).call(this);const t=(null==e?void 0:e.access)&&!this.verifyToken(e.access);return t&&!(null==e?void 0:e.refresh)?e=void 0:t&&(e=yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_refreshWithRefreshToken).call(this,e.refresh),e&&(yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_storeTokens).call(this,e.access,e.refresh))),e}))}}function tryDeleteFile(e,t){return __awaiter(this,void 0,void 0,(function*(){try{t.verbose("Deleting",{path:e}),yield fs_1.promises.unlink(e)}catch(e){t.warn("Unable to delete the credentials cache files.",{err:e})}}))}exports.AuthManager=AuthManager,_AuthManager_logger=new WeakMap,_AuthManager_refreshToken=new WeakMap,_AuthManager_credentials=new WeakMap,_AuthManager_axios=new WeakMap,_AuthManager_clientId=new WeakMap,_AuthManager_publicKey=new WeakMap,_AuthManager_suppressCache=new WeakMap,_AuthManager_instances=new WeakSet,_AuthManager_storeTokens=function(e,t){return __awaiter(this,void 0,void 0,(function*(){const a=this.verifyToken(e);if(!a)throw AltoError_1.AltoError.create("Failed to parse authentication token",{data:{token:e}});__classPrivateFieldSet(this,_AuthManager_refreshToken,t,"f");const r={access:e,refresh:t};return yield fs_1.promises.mkdir((0,path_1.dirname)(this.tokenLocation),{recursive:!0}),yield(0,FS_1.saveJsonFile)(this.tokenLocation,r,{mode:384}),a}))},_AuthManager_storeAccessToken=function(e){return __awaiter(this,void 0,void 0,(function*(){yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_storeTokens).call(this,e)}))},_AuthManager_refreshAccessToken=function(){var e;return __awaiter(this,void 0,void 0,(function*(){try{if(!__classPrivateFieldGet(this,_AuthManager_refreshToken,"f")){const{refresh:e}=yield(0,FS_1.loadJsonFile)(this.tokenLocation,Types_1.isTokensFile);__classPrivateFieldSet(this,_AuthManager_refreshToken,e,"f")}const t=__classPrivateFieldGet(this,_AuthManager_refreshToken,"f");if(!t)throw AltoError_1.AltoError.create("Could not load refresh token");const{access:a,refresh:r}=null!==(e=yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_refreshWithRefreshToken).call(this,t))&&void 0!==e?e:{};return a?yield __classPrivateFieldGet(this,_AuthManager_instances,"m",_AuthManager_storeTokens).call(this,a,r):void 0}catch(e){return __classPrivateFieldGet(this,_AuthManager_logger,"f").error("Failed to refresh the authentication token.",e),void(yield this.tryDeleteTokensFile())}}))},_AuthManager_refreshWithRefreshToken=function(e){return __awaiter(this,void 0,void 0,(function*(){try{const t={grant_type:"refresh_token",client_id:__classPrivateFieldGet(this,_AuthManager_clientId,"f"),refresh_token:e},{data:a}=yield __classPrivateFieldGet(this,_AuthManager_axios,"f").post(this.oauthProvider+"oauth/token",(0,Url_1.encodeUrlQuery)(t),{headers:{"content-type":"application/x-www-form-urlencoded"}}),r=(0,type_validations_1.arrayRejectionReasons)();if(!(0,Types_1.isBearerTokenData)(a,r))throw AltoError_1.AltoError.create("Got invalid token response",{data:{rejections:[...r]}});return Object.assign({access:a.access_token},(0,Types_1.isRefreshTokenData)(a)&&{refresh:a.refresh_token})}catch(e){return __classPrivateFieldGet(this,_AuthManager_logger,"f").error("Failed to refresh the authentication token.",e),void(yield this.tryDeleteTokensFile())}}))},_AuthManager_loadCredentials=function(){return __awaiter(this,void 0,void 0,(function*(){try{return yield(0,FS_1.loadJsonFile)(this.tokenLocation,Types_1.isTokensFile)}catch(e){return void __classPrivateFieldGet(this,_AuthManager_logger,"f").warn("Unable to load the access-token file.",e)}}))};