angular-oauth2-oidc
Version:
Support for OAuth 2 and OpenId Connect (OIDC) in Angular.
3 lines (2 loc) • 39.4 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core"),require("@angular/common/http"),require("rxjs"),require("rxjs/operators"),require("@angular/common"),require("jsrsasign")):"function"==typeof define&&define.amd?define("angular-oauth2-oidc",["exports","@angular/core","@angular/common/http","rxjs","rxjs/operators","@angular/common","jsrsasign"],t):t(e["angular-oauth2-oidc"]={},e.ng.core,e.ng.common.http,e.rxjs,e.Rx.Observable.prototype,e.ng.common,e.jsrsasign)}(this,function(e,t,f,h,l,r,d){"use strict";var n=function(e,t){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r])})(e,t)};function s(e,t){function r(){this.constructor=e}n(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}function o(t,i,a,c){return new(a||(a=Promise))(function(e,r){function n(e){try{s(c.next(e))}catch(t){r(t)}}function o(e){try{s(c["throw"](e))}catch(t){r(t)}}function s(t){t.done?e(t.value):new a(function(e){e(t.value)}).then(n,o)}s((c=c.apply(t,i||[])).next())})}function c(n,o){var s,i,a,e,c={label:0,sent:function(){if(1&a[0])throw a[1];return a[1]},trys:[],ops:[]};return e={next:t(0),"throw":t(1),"return":t(2)},"function"==typeof Symbol&&(e[Symbol.iterator]=function(){return this}),e;function t(t){return function(e){return function r(e){if(s)throw new TypeError("Generator is already executing.");for(;c;)try{if(s=1,i&&(a=2&e[0]?i["return"]:e[0]?i["throw"]||((a=i["return"])&&a.call(i),0):i.next)&&!(a=a.call(i,e[1])).done)return a;switch(i=0,a&&(e=[2&e[0],a.value]),e[0]){case 0:case 1:a=e;break;case 4:return c.label++,{value:e[1],done:!1};case 5:c.label++,i=e[1],e=[0];continue;case 7:e=c.ops.pop(),c.trys.pop();continue;default:if(!(a=0<(a=c.trys).length&&a[a.length-1])&&(6===e[0]||2===e[0])){c=0;continue}if(3===e[0]&&(!a||e[1]>a[0]&&e[1]<a[3])){c.label=e[1];break}if(6===e[0]&&c.label<a[1]){c.label=a[1],a=e;break}if(a&&c.label<a[2]){c.label=a[2],c.ops.push(e);break}a[2]&&c.ops.pop(),c.trys.pop();continue}e=o.call(n,c)}catch(t){e=[6,t],i=0}finally{s=a=0}if(5&e[0])throw e[1];return{value:e[0]?e[1]:void 0,done:!0}}([t,e])}}}function b(e){var t="function"==typeof Symbol&&e[Symbol.iterator],r=0;return t?t.call(e):{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}}}function i(e,t){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var n,o,s=r.call(e),i=[];try{for(;(void 0===t||0<t--)&&!(n=s.next()).done;)i.push(n.value)}catch(a){o={error:a}}finally{try{n&&!n.done&&(r=s["return"])&&r.call(s)}finally{if(o)throw o.error}}return i}var a=function N(){this.preventClearHashAfterLogin=!1},u=function q(){},p=function V(){},g=function M(){},m=function J(){},v=function(){function e(){}return e.prototype.validateAtHash=function(a){return o(this,void 0,void 0,function(){var t,r,n,o,s,i;return c(this,function(e){switch(e.label){case 0:return t=this.inferHashAlgorithm(a.idTokenHeader),[4,this.calcHash(a.accessToken,t)];case 1:return r=e.sent(),n=r.substr(0,r.length/2),o=btoa(n),s=o.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,""),i=a.idTokenClaims.at_hash.replace(/=/g,""),s!==i&&(console.error("exptected at_hash: "+s),console.error("actual at_hash: "+i)),[2,s===i]}})})},e.prototype.inferHashAlgorithm=function(e){var t=e.alg;if(!t.match(/^.S[0-9]{3}$/))throw new Error("Algorithm not supported: "+t);return"sha-"+t.substr(2)},e}(),k=function(){function e(){}return e.prototype.getHashFragmentParams=function(e){var t=e||window.location.hash;if(0!==(t=decodeURIComponent(t)).indexOf("#"))return{};var r=t.indexOf("?");return t=-1<r?t.substr(r+1):t.substr(1),this.parseQueryString(t)},e.prototype.parseQueryString=function(e){var t,r,n,o,s,i,a,c={};if(null===e)return c;t=e.split("&");for(var u=0;u<t.length;u++)s=-1===(n=(r=t[u]).indexOf("="))?(o=r,null):(o=r.substr(0,n),r.substr(n+1)),i=decodeURIComponent(o),a=decodeURIComponent(s),"/"===i.substr(0,1)&&(i=i.substr(1)),c[i]=a;return c},e}();k.decorators=[{type:t.Injectable}];var y=function B(e){this.type=e},_=function(n){function e(e,t){void 0===t&&(t=null);var r=n.call(this,e)||this;return r.info=t,r}return s(e,n),e}(y),w=function(n){function e(e,t){void 0===t&&(t=null);var r=n.call(this,e)||this;return r.info=t,r}return s(e,n),e}(y),S=function(o){function e(e,t,r){void 0===r&&(r=null);var n=o.call(this,e)||this;return n.reason=t,n.params=r,n}return s(e,o),e}(y);function T(e){var t=e.replace(/\-/g,"+").replace(/\_/g,"/");return decodeURIComponent(atob(t).split("").map(function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)}).join(""))}var I=function W(e){this.clientId="",this.redirectUri="",this.postLogoutRedirectUri="",this.loginUrl="",this.scope="openid profile",this.resource="",this.rngUrl="",this.oidc=!0,this.requestAccessToken=!0,this.options=null,this.issuer="",this.logoutUrl="",this.clearHashAfterLogin=!0,this.tokenEndpoint=null,this.userinfoEndpoint=null,this.responseType="",this.showDebugInformation=!1,this.silentRefreshRedirectUri="",this.silentRefreshMessagePrefix="",this.silentRefreshShowIFrame=!1,this.siletRefreshTimeout=2e4,this.silentRefreshTimeout=2e4,this.dummyClientSecret=null,this.requireHttps="remoteOnly",this.strictDiscoveryDocumentValidation=!0,this.jwks=null,this.customQueryParams=null,this.silentRefreshIFrameName="angular-oauth-oidc-silent-refresh-iframe",this.timeoutFactor=.75,this.sessionChecksEnabled=!1,this.sessionCheckIntervall=3e3,this.sessionCheckIFrameUrl=null,this.sessionCheckIFrameName="angular-oauth-oidc-check-session-iframe",this.disableAtHashCheck=!1,this.skipSubjectCheck=!1,this.useIdTokenHintForSilentRefresh=!1,this.skipIssuerCheck=!1,this.nonceStateSeparator=";",this.useHttpBasicAuthForPasswordFlow=!1,this.openUri=function(e){location.href=e},e&&Object.assign(this,e)},C=function(){function e(){}return e.prototype.encodeKey=function(e){return encodeURIComponent(e)},e.prototype.encodeValue=function(e){return encodeURIComponent(e)},e.prototype.decodeKey=function(e){return decodeURIComponent(e)},e.prototype.decodeValue=function(e){return decodeURIComponent(e)},e}(),A=function(u){function e(e,t,r,n,o,s,i){var a=u.call(this)||this;a.ngZone=e,a.http=t,a.config=o,a.urlHelper=s,a.logger=i,a.discoveryDocumentLoaded=!1,a.state="",a.eventsSubject=new h.Subject,a.discoveryDocumentLoadedSubject=new h.Subject,a.grantTypesSupported=[],a.inImplicitFlow=!1,a.discoveryDocumentLoaded$=a.discoveryDocumentLoadedSubject.asObservable(),a.events=a.eventsSubject.asObservable(),n&&(a.tokenValidationHandler=n),o&&a.configure(o);try{r?a.setStorage(r):"undefined"!=typeof sessionStorage&&a.setStorage(sessionStorage)}catch(c){console.error("No OAuthStorage provided and cannot access default (sessionStorage).Consider providing a custom OAuthStorage implementation in your module.",c)}return a.setupRefreshTimer(),a}return s(e,u),e.prototype.configure=function(e){Object.assign(this,new I,e),this.config=Object.assign({},new I,e),this.sessionChecksEnabled&&this.setupSessionCheck(),this.configChanged()},e.prototype.configChanged=function(){},e.prototype.restartSessionChecksIfStillLoggedIn=function(){this.hasValidIdToken()&&this.initSessionCheck()},e.prototype.restartRefreshTimerIfStillLoggedIn=function(){this.setupExpirationTimers()},e.prototype.setupSessionCheck=function(){var t=this;this.events.pipe(l.filter(function(e){return"token_received"===e.type})).subscribe(function(e){t.initSessionCheck()})},e.prototype.setupAutomaticSilentRefresh=function(t){var r=this;void 0===t&&(t={}),this.events.pipe(l.filter(function(e){return"token_expires"===e.type})).subscribe(function(e){r.silentRefresh(t)["catch"](function(e){r.debug("Automatic silent refresh did not work")})}),this.restartRefreshTimerIfStillLoggedIn()},e.prototype.loadDiscoveryDocumentAndTryLogin=function(t){var r=this;return void 0===t&&(t=null),this.loadDiscoveryDocument().then(function(e){return r.tryLogin(t)})},e.prototype.loadDiscoveryDocumentAndLogin=function(e){var t=this;return void 0===e&&(e=null),this.loadDiscoveryDocumentAndTryLogin(e).then(function(e){return!(!t.hasValidIdToken()||!t.hasValidAccessToken())||(t.initImplicitFlow(),!1)})},e.prototype.debug=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];this.showDebugInformation&&this.logger.debug.apply(console,e)},e.prototype.validateUrlFromDiscoveryDocument=function(e){var t=[],r=this.validateUrlForHttps(e),n=this.validateUrlAgainstIssuer(e);return r||t.push("https for all urls required. Also for urls received by discovery."),n||t.push("Every url in discovery document has to start with the issuer url.Also see property strictDiscoveryDocumentValidation."),t},e.prototype.validateUrlForHttps=function(e){if(!e)return!0;var t=e.toLowerCase();return!1===this.requireHttps||(!(!t.match(/^http:\/\/localhost($|[:\/])/)&&!t.match(/^http:\/\/localhost($|[:\/])/)||"remoteOnly"!==this.requireHttps)||t.startsWith("https://"))},e.prototype.validateUrlAgainstIssuer=function(e){return!this.strictDiscoveryDocumentValidation||(!e||e.toLowerCase().startsWith(this.issuer.toLowerCase()))},e.prototype.setupRefreshTimer=function(){var t=this;"undefined"!=typeof window?(this.hasValidIdToken()&&(this.clearAccessTokenTimer(),this.clearIdTokenTimer(),this.setupExpirationTimers()),this.events.pipe(l.filter(function(e){return"token_received"===e.type})).subscribe(function(e){t.clearAccessTokenTimer(),t.clearIdTokenTimer(),t.setupExpirationTimers()})):this.debug("timer not supported on this plattform")},e.prototype.setupExpirationTimers=function(){var e=this.getIdTokenExpiration()||Number.MAX_VALUE,t=(this.getAccessTokenExpiration()||Number.MAX_VALUE)<=e;this.hasValidAccessToken()&&t&&this.setupAccessTokenTimer(),this.hasValidIdToken()&&!t&&this.setupIdTokenTimer()},e.prototype.setupAccessTokenTimer=function(){var t=this,e=this.getAccessTokenExpiration(),r=this.getAccessTokenStoredAt(),n=this.calcTimeout(r,e);this.ngZone.runOutsideAngular(function(){t.accessTokenTimeoutSubscription=h.of(new w("token_expires","access_token")).pipe(l.delay(n)).subscribe(function(e){t.ngZone.run(function(){t.eventsSubject.next(e)})})})},e.prototype.setupIdTokenTimer=function(){var t=this,e=this.getIdTokenExpiration(),r=this.getIdTokenStoredAt(),n=this.calcTimeout(r,e);this.ngZone.runOutsideAngular(function(){t.idTokenTimeoutSubscription=h.of(new w("token_expires","id_token")).pipe(l.delay(n)).subscribe(function(e){t.ngZone.run(function(){t.eventsSubject.next(e)})})})},e.prototype.clearAccessTokenTimer=function(){this.accessTokenTimeoutSubscription&&this.accessTokenTimeoutSubscription.unsubscribe()},e.prototype.clearIdTokenTimer=function(){this.idTokenTimeoutSubscription&&this.idTokenTimeoutSubscription.unsubscribe()},e.prototype.calcTimeout=function(e,t){return(t-e)*this.timeoutFactor},e.prototype.setStorage=function(e){this._storage=e,this.configChanged()},e.prototype.loadDiscoveryDocument=function(e){var o=this;return void 0===e&&(e=null),new Promise(function(n,t){e||((e=o.issuer||"").endsWith("/")||(e+="/"),e+=".well-known/openid-configuration"),o.validateUrlForHttps(e)?o.http.get(e).subscribe(function(r){if(!o.validateDiscoveryDocument(r))return o.eventsSubject.next(new S("discovery_document_validation_error",null)),void t("discovery_document_validation_error");o.loginUrl=r.authorization_endpoint,o.logoutUrl=r.end_session_endpoint||o.logoutUrl,o.grantTypesSupported=r.grant_types_supported,o.issuer=r.issuer,o.tokenEndpoint=r.token_endpoint,o.userinfoEndpoint=r.userinfo_endpoint,o.jwksUri=r.jwks_uri,o.sessionCheckIFrameUrl=r.check_session_iframe||o.sessionCheckIFrameUrl,o.discoveryDocumentLoaded=!0,o.discoveryDocumentLoadedSubject.next(r),o.sessionChecksEnabled&&o.restartSessionChecksIfStillLoggedIn(),o.loadJwks().then(function(e){var t=new _("discovery_document_loaded",{discoveryDocument:r,jwks:e});o.eventsSubject.next(t),n(t)})["catch"](function(e){o.eventsSubject.next(new S("discovery_document_load_error",e)),t(e)})},function(e){o.logger.error("error loading discovery document",e),o.eventsSubject.next(new S("discovery_document_load_error",e)),t(e)}):t("issuer must use https, or config value for property requireHttps must allow http")})},e.prototype.loadJwks=function(){var n=this;return new Promise(function(t,r){n.jwksUri?n.http.get(n.jwksUri).subscribe(function(e){n.jwks=e,n.eventsSubject.next(new _("discovery_document_loaded")),t(e)},function(e){n.logger.error("error loading jwks",e),n.eventsSubject.next(new S("jwks_load_error",e)),r(e)}):t(null)})},e.prototype.validateDiscoveryDocument=function(e){var t;return this.skipIssuerCheck||e.issuer===this.issuer?0<(t=this.validateUrlFromDiscoveryDocument(e.authorization_endpoint)).length?(this.logger.error("error validating authorization_endpoint in discovery document",t),!1):0<(t=this.validateUrlFromDiscoveryDocument(e.end_session_endpoint)).length?(this.logger.error("error validating end_session_endpoint in discovery document",t),!1):(0<(t=this.validateUrlFromDiscoveryDocument(e.token_endpoint)).length&&this.logger.error("error validating token_endpoint in discovery document",t),0<(t=this.validateUrlFromDiscoveryDocument(e.userinfo_endpoint)).length?(this.logger.error("error validating userinfo_endpoint in discovery document",t),!1):0<(t=this.validateUrlFromDiscoveryDocument(e.jwks_uri)).length?(this.logger.error("error validating jwks_uri in discovery document",t),!1):(this.sessionChecksEnabled&&!e.check_session_iframe&&this.logger.warn("sessionChecksEnabled is activated but discovery document does not contain a check_session_iframe field"),!0)):(this.logger.error("invalid issuer in discovery document","expected: "+this.issuer,"current: "+e.issuer),!1)},e.prototype.fetchTokenUsingPasswordFlowAndLoadUserProfile=function(e,t,r){var n=this;return void 0===r&&(r=new f.HttpHeaders),this.fetchTokenUsingPasswordFlow(e,t,r).then(function(){return n.loadUserProfile()})},e.prototype.loadUserProfile=function(){var o=this;if(!this.hasValidAccessToken())throw new Error("Can not load User Profile without access_token");if(!this.validateUrlForHttps(this.userinfoEndpoint))throw new Error("userinfoEndpoint must use http, or config value for property requireHttps must allow http");return new Promise(function(r,n){var e=(new f.HttpHeaders).set("Authorization","Bearer "+o.getAccessToken());o.http.get(o.userinfoEndpoint,{headers:e}).subscribe(function(e){o.debug("userinfo received",e);var t=o.getIdentityClaims()||{};if(o.skipSubjectCheck||!o.oidc||t.sub&&e.sub===t.sub)e=Object.assign({},t,e),o._storage.setItem("id_token_claims_obj",JSON.stringify(e)),o.eventsSubject.next(new _("user_profile_loaded")),r(e);else{n("if property oidc is true, the received user-id (sub) has to be the user-id of the user that has logged in with oidc.\nif you are not using oidc but just oauth2 password flow set oidc to false")}},function(e){o.logger.error("error loading user info",e),o.eventsSubject.next(new S("user_profile_load_error",e)),n(e)})})},e.prototype.fetchTokenUsingPasswordFlow=function(h,l,d){var p=this;if(void 0===d&&(d=new f.HttpHeaders),!this.validateUrlForHttps(this.tokenEndpoint))throw new Error("tokenEndpoint must use http, or config value for property requireHttps must allow http");return new Promise(function(t,r){var e,n,o=new f.HttpParams({encoder:new C}).set("grant_type","password").set("scope",p.scope).set("username",h).set("password",l);if(p.useHttpBasicAuthForPasswordFlow){var s=btoa(p.clientId+":"+p.dummyClientSecret);d=d.set("Authorization","Basic "+s)}if(p.useHttpBasicAuthForPasswordFlow||(o=o.set("client_id",p.clientId)),!p.useHttpBasicAuthForPasswordFlow&&p.dummyClientSecret&&(o=o.set("client_secret",p.dummyClientSecret)),p.customQueryParams)try{for(var i=b(Object.getOwnPropertyNames(p.customQueryParams)),a=i.next();!a.done;a=i.next()){var c=a.value;o=o.set(c,p.customQueryParams[c])}}catch(u){e={error:u}}finally{try{a&&!a.done&&(n=i["return"])&&n.call(i)}finally{if(e)throw e.error}}d=d.set("Content-Type","application/x-www-form-urlencoded"),p.http.post(p.tokenEndpoint,o,{headers:d}).subscribe(function(e){p.debug("tokenResponse",e),p.storeAccessTokenResponse(e.access_token,e.refresh_token,e.expires_in,e.scope),p.eventsSubject.next(new _("token_received")),t(e)},function(e){p.logger.error("Error performing password flow",e),p.eventsSubject.next(new S("token_error",e)),r(e)})})},e.prototype.refreshToken=function(){var h=this;if(!this.validateUrlForHttps(this.tokenEndpoint))throw new Error("tokenEndpoint must use http, or config value for property requireHttps must allow http");return new Promise(function(t,r){var e,n,o=(new f.HttpParams).set("grant_type","refresh_token").set("client_id",h.clientId).set("scope",h.scope).set("refresh_token",h._storage.getItem("refresh_token"));if(h.dummyClientSecret&&(o=o.set("client_secret",h.dummyClientSecret)),h.customQueryParams)try{for(var s=b(Object.getOwnPropertyNames(h.customQueryParams)),i=s.next();!i.done;i=s.next()){var a=i.value;o=o.set(a,h.customQueryParams[a])}}catch(u){e={error:u}}finally{try{i&&!i.done&&(n=s["return"])&&n.call(s)}finally{if(e)throw e.error}}var c=(new f.HttpHeaders).set("Content-Type","application/x-www-form-urlencoded");h.http.post(h.tokenEndpoint,o,{headers:c}).subscribe(function(e){h.debug("refresh tokenResponse",e),h.storeAccessTokenResponse(e.access_token,e.refresh_token,e.expires_in,e.scope),h.eventsSubject.next(new _("token_received")),h.eventsSubject.next(new _("token_refreshed")),t(e)},function(e){h.logger.error("Error performing password flow",e),h.eventsSubject.next(new S("token_refresh_error",e)),r(e)})})},e.prototype.removeSilentRefreshEventListener=function(){this.silentRefreshPostMessageEventListener&&(window.removeEventListener("message",this.silentRefreshPostMessageEventListener),this.silentRefreshPostMessageEventListener=null)},e.prototype.setupSilentRefreshEventListener=function(){var o=this;this.removeSilentRefreshEventListener(),this.silentRefreshPostMessageEventListener=function(e){var t="#";if(o.silentRefreshMessagePrefix&&(t+=o.silentRefreshMessagePrefix),e&&e.data&&"string"==typeof e.data){var r=e.data;if(r.startsWith(t)){var n="#"+r.substr(t.length);o.tryLogin({customHashFragment:n,preventClearHashAfterLogin:!0,onLoginError:function(e){o.eventsSubject.next(new S("silent_refresh_error",e))},onTokenReceived:function(){o.eventsSubject.next(new _("silently_refreshed"))}})["catch"](function(e){return o.debug("tryLogin during silent refresh failed",e)})}}},window.addEventListener("message",this.silentRefreshPostMessageEventListener)},e.prototype.silentRefresh=function(e,t){var r=this;void 0===e&&(e={}),void 0===t&&(t=!0);var n=this.getIdentityClaims()||{};if(this.useIdTokenHintForSilentRefresh&&this.hasValidIdToken()&&(e.id_token_hint=this.getIdToken()),!this.validateUrlForHttps(this.loginUrl))throw new Error("tokenEndpoint must use https, or config value for property requireHttps must allow http");if("undefined"==typeof document)throw new Error("silent refresh is not supported on this platform");var o=document.getElementById(this.silentRefreshIFrameName);o&&document.body.removeChild(o),this.silentRefreshSubject=n.sub;var s=document.createElement("iframe");s.id=this.silentRefreshIFrameName,this.setupSilentRefreshEventListener();var i=this.silentRefreshRedirectUri||this.redirectUri;this.createLoginUrl(null,null,i,t,e).then(function(e){s.setAttribute("src",e),r.silentRefreshShowIFrame||(s.style.display="none"),document.body.appendChild(s)});var a=this.events.pipe(l.filter(function(e){return e instanceof S}),l.first()),c=this.events.pipe(l.filter(function(e){return"silently_refreshed"===e.type}),l.first()),u=h.of(new S("silent_refresh_timeout",null)).pipe(l.delay(this.silentRefreshTimeout));return h.race([a,c,u]).pipe(l.tap(function(e){"silent_refresh_timeout"===e.type&&r.eventsSubject.next(e)}),l.map(function(e){if(e instanceof S)throw e;return e})).toPromise()},e.prototype.canPerformSessionCheck=function(){return!!this.sessionChecksEnabled&&(this.sessionCheckIFrameUrl?this.getSessionState()?"undefined"!=typeof document:(console.warn("sessionChecksEnabled is activated but there is no session_state"),!1):(console.warn("sessionChecksEnabled is activated but there is no sessionCheckIFrameUrl"),!1))},e.prototype.setupSessionCheckEventListener=function(){var n=this;this.removeSessionCheckEventListener(),this.sessionCheckEventListener=function(e){var t=e.origin.toLowerCase(),r=n.issuer.toLowerCase();switch(n.debug("sessionCheckEventListener"),r.startsWith(t)||n.debug("sessionCheckEventListener","wrong origin",t,"expected",r),e.data){case"unchanged":n.handleSessionUnchanged();break;case"changed":n.ngZone.run(function(){n.handleSessionChange()});break;case"error":n.ngZone.run(function(){n.handleSessionError()})}n.debug("got info from session check inframe",e)},this.ngZone.runOutsideAngular(function(){window.addEventListener("message",n.sessionCheckEventListener)})},e.prototype.handleSessionUnchanged=function(){this.debug("session check","session unchanged")},e.prototype.handleSessionChange=function(){var t=this;this.eventsSubject.next(new w("session_changed")),this.stopSessionCheckTimer(),this.silentRefreshRedirectUri?(this.silentRefresh()["catch"](function(e){return t.debug("silent refresh failed after session changed")}),this.waitForSilentRefreshAfterSessionChange()):(this.eventsSubject.next(new w("session_terminated")),this.logOut(!0))},e.prototype.waitForSilentRefreshAfterSessionChange=function(){var t=this;this.events.pipe(l.filter(function(e){return"silently_refreshed"===e.type||"silent_refresh_timeout"===e.type||"silent_refresh_error"===e.type}),l.first()).subscribe(function(e){"silently_refreshed"!==e.type&&(t.debug("silent refresh did not work after session changed"),t.eventsSubject.next(new w("session_terminated")),t.logOut(!0))})},e.prototype.handleSessionError=function(){this.stopSessionCheckTimer(),this.eventsSubject.next(new w("session_error"))},e.prototype.removeSessionCheckEventListener=function(){this.sessionCheckEventListener&&(window.removeEventListener("message",this.sessionCheckEventListener),this.sessionCheckEventListener=null)},e.prototype.initSessionCheck=function(){if(this.canPerformSessionCheck()){var e=document.getElementById(this.sessionCheckIFrameName);e&&document.body.removeChild(e);var t=document.createElement("iframe");t.id=this.sessionCheckIFrameName,this.setupSessionCheckEventListener();var r=this.sessionCheckIFrameUrl;t.setAttribute("src",r),t.style.display="none",document.body.appendChild(t),this.startSessionCheckTimer()}},e.prototype.startSessionCheckTimer=function(){var e=this;this.stopSessionCheckTimer(),this.ngZone.runOutsideAngular(function(){e.sessionCheckTimer=setInterval(e.checkSession.bind(e),e.sessionCheckIntervall)})},e.prototype.stopSessionCheckTimer=function(){this.sessionCheckTimer&&(clearInterval(this.sessionCheckTimer),this.sessionCheckTimer=null)},e.prototype.checkSession=function(){var e=document.getElementById(this.sessionCheckIFrameName);e||this.logger.warn("checkSession did not find iframe",this.sessionCheckIFrameName);var t=this.getSessionState();t||this.stopSessionCheckTimer();var r=this.clientId+" "+t;e.contentWindow.postMessage(r,this.issuer)},e.prototype.createLoginUrl=function(g,m,e,v,k){var y=this;void 0===g&&(g=""),void 0===m&&(m=""),void 0===e&&(e=""),void 0===v&&(v=!1),void 0===k&&(k={});var _,w=this;return _=e||this.redirectUri,this.createAndSaveNonce().then(function(e){var t,r,n,o;if(g=g?e+y.config.nonceStateSeparator+g:e,!y.requestAccessToken&&!y.oidc)throw new Error("Either requestAccessToken or oidc or both must be true");y.config.responseType?y.responseType=y.config.responseType:y.oidc&&y.requestAccessToken?y.responseType="id_token token":y.oidc&&!y.requestAccessToken?y.responseType="id_token":y.responseType="token";var s=-1<w.loginUrl.indexOf("?")?"&":"?",i=w.scope;y.oidc&&!i.match(/(^|\s)openid($|\s)/)&&(i="openid "+i);var a=w.loginUrl+s+"response_type="+encodeURIComponent(w.responseType)+"&client_id="+encodeURIComponent(w.clientId)+"&state="+encodeURIComponent(g)+"&redirect_uri="+encodeURIComponent(_)+"&scope="+encodeURIComponent(i);m&&(a+="&login_hint="+encodeURIComponent(m)),w.resource&&(a+="&resource="+encodeURIComponent(w.resource)),w.oidc&&(a+="&nonce="+encodeURIComponent(e)),v&&(a+="&prompt=none");try{for(var c=b(Object.keys(k)),u=c.next();!u.done;u=c.next()){var h=u.value;a+="&"+encodeURIComponent(h)+"="+encodeURIComponent(k[h])}}catch(p){t={error:p}}finally{try{u&&!u.done&&(r=c["return"])&&r.call(c)}finally{if(t)throw t.error}}if(y.customQueryParams)try{for(var l=b(Object.getOwnPropertyNames(y.customQueryParams)),d=l.next();!d.done;d=l.next()){a+="&"+(h=d.value)+"="+encodeURIComponent(y.customQueryParams[h])}}catch(f){n={error:f}}finally{try{d&&!d.done&&(o=l["return"])&&o.call(l)}finally{if(n)throw n.error}}return a})},e.prototype.initImplicitFlowInternal=function(e,t){var r=this;if(void 0===e&&(e=""),void 0===t&&(t=""),!this.inImplicitFlow){if(this.inImplicitFlow=!0,!this.validateUrlForHttps(this.loginUrl))throw new Error("loginUrl must use http, or config value for property requireHttps must allow http");var n={},o=null;"string"==typeof t?o=t:"object"==typeof t&&(n=t),this.createLoginUrl(e,o,null,!1,n).then(function(e){location.href=e})["catch"](function(e){console.error("Error in initImplicitFlow",e),r.inImplicitFlow=!1})}},e.prototype.initImplicitFlow=function(t,r){var n=this;void 0===t&&(t=""),void 0===r&&(r=""),""!==this.loginUrl?this.initImplicitFlowInternal(t,r):this.events.pipe(l.filter(function(e){return"discovery_document_loaded"===e.type})).subscribe(function(e){return n.initImplicitFlowInternal(t,r)})},e.prototype.callOnTokenReceivedIfExists=function(e){if(e.onTokenReceived){var t={idClaims:this.getIdentityClaims(),idToken:this.getIdToken(),accessToken:this.getAccessToken(),state:this.state};e.onTokenReceived(t)}},e.prototype.storeAccessTokenResponse=function(e,t,r,n){if(this._storage.setItem("access_token",e),n&&this._storage.setItem("granted_scopes",JSON.stringify(n.split("+"))),this._storage.setItem("access_token_stored_at",""+Date.now()),r){var o=1e3*r,s=(new Date).getTime()+o;this._storage.setItem("expires_at",""+s)}t&&this._storage.setItem("refresh_token",t)},e.prototype.tryLogin=function(r){var e,t=this;void 0===r&&(r=null),e=(r=r||{}).customHashFragment?this.urlHelper.getHashFragmentParams(r.customHashFragment):this.urlHelper.getHashFragmentParams(),this.debug("parsed url",e);var n=e.state,o=n;if(n){var s=n.indexOf(this.config.nonceStateSeparator);-1<s&&(o=n.substr(0,s),this.state=n.substr(s+this.config.nonceStateSeparator.length))}if(e.error){this.debug("error trying to login"),this.handleLoginError(r,e);var i=new S("token_error",{},e);return this.eventsSubject.next(i),Promise.reject(i)}var a=e.access_token,c=e.id_token,u=e.session_state,h=e.scope;if(!this.requestAccessToken&&!this.oidc)return Promise.reject("Either requestAccessToken or oidc (or both) must be true.");if(this.requestAccessToken&&!a)return Promise.resolve(!1);if(this.requestAccessToken&&!r.disableOAuth2StateCheck&&!n)return Promise.resolve(!1);if(this.oidc&&!c)return Promise.resolve(!1);if((this.sessionChecksEnabled&&!u&&this.logger.warn("session checks (Session Status Change Notification) were activated in the configuration but the id_token does not contain a session_state claim"),this.requestAccessToken&&!r.disableOAuth2StateCheck)&&!this.validateNonceForAccessToken(a,o)){var l=new S("invalid_nonce_in_state",null);return this.eventsSubject.next(l),Promise.reject(l)}return this.requestAccessToken&&this.storeAccessTokenResponse(a,null,e.expires_in||this.fallbackAccessTokenExpirationTimeInSec,h),this.oidc?this.processIdToken(c,a).then(function(t){return r.validationHandler?r.validationHandler({accessToken:a,idClaims:t.idTokenClaims,idToken:t.idToken,state:n}).then(function(e){return t}):t}).then(function(e){return t.storeIdToken(e),t.storeSessionState(u),t.clearHashAfterLogin&&(location.hash=""),t.eventsSubject.next(new _("token_received")),t.callOnTokenReceivedIfExists(r),!(t.inImplicitFlow=!1)})["catch"](function(e){return t.eventsSubject.next(new S("token_validation_error",e)),t.logger.error("Error validating tokens"),t.logger.error(e),Promise.reject(e)}):(this.eventsSubject.next(new _("token_received")),this.clearHashAfterLogin&&!r.preventClearHashAfterLogin&&(location.hash=""),this.callOnTokenReceivedIfExists(r),Promise.resolve(!0))},e.prototype.validateNonceForAccessToken=function(e,t){var r=this._storage.getItem("nonce");if(r===t)return!0;return console.error("Validating access_token failed, wrong state/nonce.",r,t),!1},e.prototype.storeIdToken=function(e){this._storage.setItem("id_token",e.idToken),this._storage.setItem("id_token_claims_obj",e.idTokenClaimsJson),this._storage.setItem("id_token_expires_at",""+e.idTokenExpiresAt),this._storage.setItem("id_token_stored_at",""+Date.now())},e.prototype.storeSessionState=function(e){this._storage.setItem("session_state",e)},e.prototype.getSessionState=function(){return this._storage.getItem("session_state")},e.prototype.handleLoginError=function(e,t){e.onLoginError&&e.onLoginError(t),this.clearHashAfterLogin&&(location.hash="")},e.prototype.processIdToken=function(r,e){var n=this,t=r.split("."),o=T(this.padBase64(t[0])),s=JSON.parse(o),i=T(this.padBase64(t[1])),a=JSON.parse(i),c=this._storage.getItem("nonce");if(Array.isArray(a.aud)){if(a.aud.every(function(e){return e!==n.clientId})){var u="Wrong audience: "+a.aud.join(",");return this.logger.warn(u),Promise.reject(u)}}else if(a.aud!==this.clientId){u="Wrong audience: "+a.aud;return this.logger.warn(u),Promise.reject(u)}if(!a.sub){u="No sub claim in id_token";return this.logger.warn(u),Promise.reject(u)}if(this.sessionChecksEnabled&&this.silentRefreshSubject&&this.silentRefreshSubject!==a.sub){u="After refreshing, we got an id_token for another user (sub). Expected sub: "+this.silentRefreshSubject+", received sub: "+a.sub;return this.logger.warn(u),Promise.reject(u)}if(!a.iat){u="No iat claim in id_token";return this.logger.warn(u),Promise.reject(u)}if(a.iss!==this.issuer){u="Wrong issuer: "+a.iss;return this.logger.warn(u),Promise.reject(u)}if(a.nonce!==c){u="Wrong nonce: "+a.nonce;return this.logger.warn(u),Promise.reject(u)}if(!this.disableAtHashCheck&&this.requestAccessToken&&!a.at_hash){u="An at_hash is needed!";return this.logger.warn(u),Promise.reject(u)}var h=Date.now(),l=1e3*a.iat,d=1e3*a.exp;if(h<=l-6e5||d+6e5<=h){u="Token has expired";return console.error(u),console.error({now:h,issuedAtMSec:l,expiresAtMSec:d}),Promise.reject(u)}var p={accessToken:e,idToken:r,jwks:this.jwks,idTokenClaims:a,idTokenHeader:s,loadKeys:function(){return n.loadJwks()}};return this.checkAtHash(p).then(function(e){if(n.disableAtHashCheck||!n.requestAccessToken||e)return n.checkSignature(p).then(function(e){return{idToken:r,idTokenClaims:a,idTokenClaimsJson:i,idTokenHeader:s,idTokenHeaderJson:o,idTokenExpiresAt:d}});var t="Wrong at_hash";return n.logger.warn(t),Promise.reject(t)})},e.prototype.getIdentityClaims=function(){var e=this._storage.getItem("id_token_claims_obj");return e?JSON.parse(e):null},e.prototype.getGrantedScopes=function(){var e=this._storage.getItem("granted_scopes");return e?JSON.parse(e):null},e.prototype.getIdToken=function(){return this._storage?this._storage.getItem("id_token"):null},e.prototype.padBase64=function(e){for(;e.length%4!=0;)e+="=";return e},e.prototype.getAccessToken=function(){return this._storage.getItem("access_token")},e.prototype.getRefreshToken=function(){return this._storage.getItem("refresh_token")},e.prototype.getAccessTokenExpiration=function(){return this._storage.getItem("expires_at")?parseInt(this._storage.getItem("expires_at"),10):null},e.prototype.getAccessTokenStoredAt=function(){return parseInt(this._storage.getItem("access_token_stored_at"),10)},e.prototype.getIdTokenStoredAt=function(){return parseInt(this._storage.getItem("id_token_stored_at"),10)},e.prototype.getIdTokenExpiration=function(){return this._storage.getItem("id_token_expires_at")?parseInt(this._storage.getItem("id_token_expires_at"),10):null},e.prototype.hasValidAccessToken=function(){if(this.getAccessToken()){var e=this._storage.getItem("expires_at"),t=new Date;return!(e&&parseInt(e,10)<t.getTime())}return!1},e.prototype.hasValidIdToken=function(){if(this.getIdToken()){var e=this._storage.getItem("id_token_expires_at"),t=new Date;return!(e&&parseInt(e,10)<t.getTime())}return!1},e.prototype.authorizationHeader=function(){return"Bearer "+this.getAccessToken()},e.prototype.logOut=function(e){void 0===e&&(e=!1);var t=this.getIdToken();if(this._storage.removeItem("access_token"),this._storage.removeItem("id_token"),this._storage.removeItem("refresh_token"),this._storage.removeItem("nonce"),this._storage.removeItem("expires_at"),this._storage.removeItem("id_token_claims_obj"),this._storage.removeItem("id_token_expires_at"),this._storage.removeItem("id_token_stored_at"),this._storage.removeItem("access_token_stored_at"),this._storage.removeItem("granted_scopes"),this._storage.removeItem("session_state"),this.silentRefreshSubject=null,this.eventsSubject.next(new w("logout")),this.logoutUrl&&!e&&(t||this.postLogoutRedirectUri)){var r;if(!this.validateUrlForHttps(this.logoutUrl))throw new Error("logoutUrl must use http, or config value for property requireHttps must allow http");if(-1<this.logoutUrl.indexOf("{{"))r=this.logoutUrl.replace(/\{\{id_token\}\}/,t).replace(/\{\{client_id\}\}/,this.clientId);else{var n=new f.HttpParams;t&&(n=n.set("id_token_hint",t));var o=this.postLogoutRedirectUri||this.redirectUri;o&&(n=n.set("post_logout_redirect_uri",o)),r=this.logoutUrl+(-1<this.logoutUrl.indexOf("?")?"&":"?")+n.toString()}location.href=r}},e.prototype.createAndSaveNonce=function(){var t=this;return this.createNonce().then(function(e){return t._storage.setItem("nonce",e),e})},e.prototype.createNonce=function(){var s=this;return new Promise(function(e,t){if(s.rngUrl)throw new Error("createNonce with rng-web-api has not been implemented so far");for(var r="",n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",o=0;o<40;o++)r+=n.charAt(Math.floor(Math.random()*n.length));e(r)})},e.prototype.checkAtHash=function(t){return o(this,void 0,void 0,function(){return c(this,function(e){return this.tokenValidationHandler?[2,this.tokenValidationHandler.validateAtHash(t)]:(this.logger.warn("No tokenValidationHandler configured. Cannot check at_hash."),[2,!0])})})},e.prototype.checkSignature=function(e){return this.tokenValidationHandler?this.tokenValidationHandler.validateSignature(e):(this.logger.warn("No tokenValidationHandler configured. Cannot check signature."),Promise.resolve(null))},e}(I);A.decorators=[{type:t.Injectable}],A.ctorParameters=function(){return[{type:t.NgZone},{type:f.HttpClient},{type:p,decorators:[{type:t.Optional}]},{type:m,decorators:[{type:t.Optional}]},{type:I,decorators:[{type:t.Optional}]},{type:k},{type:u}]};var E=function Q(){},j=function Z(){},x=function K(){},U=function(){function e(){}return e.prototype.handleError=function(e){return h.throwError(e)},e}(),H=function(){function e(e,t,r){this.authStorage=e,this.errorHandler=t,this.moduleConfig=r}return e.prototype.checkUrl=function(t){return!!this.moduleConfig.resourceServer.allowedUrls.find(function(e){return t.startsWith(e)})},e.prototype.intercept=function(e,t){var r=this,n=e.url.toLowerCase();if(!this.moduleConfig)return t.handle(e);if(!this.moduleConfig.resourceServer)return t.handle(e);if(this.moduleConfig.resourceServer.allowedUrls&&!this.checkUrl(n))return t.handle(e);if(this.moduleConfig.resourceServer.sendAccessToken&&this.authStorage.getItem("access_token")){var o="Bearer "+this.authStorage.getItem("access_token"),s=e.headers.set("Authorization",o);e=e.clone({headers:s})}return t.handle(e).pipe(l.catchError(function(e){return r.errorHandler.handleError(e)}))},e}();H.decorators=[{type:t.Injectable}],H.ctorParameters=function(){return[{type:p},{type:x},{type:E,decorators:[{type:t.Optional}]}]};var R=function(){function e(){}return e.prototype.validateSignature=function(e){return Promise.resolve(null)},e.prototype.validateAtHash=function(e){return Promise.resolve(!0)},e}();function P(){return console}function F(){return"undefined"!=typeof sessionStorage?sessionStorage:null}var L=function(){function r(){}return r.forRoot=function(e,t){return void 0===e&&(e=null),void 0===t&&(t=R),{ngModule:r,providers:[A,k,{provide:u,useFactory:P},{provide:p,useFactory:F},{provide:m,useClass:t},{provide:x,useClass:U},{provide:E,useValue:e},{provide:f.HTTP_INTERCEPTORS,useClass:H,multi:!0}]}},r}();L.decorators=[{type:t.NgModule,args:[{imports:[r.CommonModule],declarations:[],exports:[]}]}];var O=function(t){function e(){var e=t.apply(this,function r(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(i(arguments[t]));return e}(arguments))||this;return e.allowedAlgorithms=["HS256","HS384","HS512","RS256","RS384","RS512","ES256","ES384","PS256","PS384","PS512"],e.gracePeriodInSec=600,e}return s(e,t),e.prototype.validateSignature=function(t,e){var r=this;if(void 0===e&&(e=!1),!t.idToken)throw new Error("Parameter idToken expected!");if(!t.idTokenHeader)throw new Error("Parameter idTokenHandler expected.");if(!t.jwks)throw new Error("Parameter jwks expected!");if(!t.jwks.keys||!Array.isArray(t.jwks.keys)||0===t.jwks.keys.length)throw new Error("Array keys in jwks missing!");var n,o=t.idTokenHeader.kid,s=t.jwks.keys,i=t.idTokenHeader.alg;if(o)n=s.find(function(e){return e.kid===o});else{var a=this.alg2kty(i),c=s.filter(function(e){return e.kty===a&&"sig"===e.use});if(1<c.length){var u="More than one matching key found. Please specify a kid in the id_token header.";return console.error(u),Promise.reject(u)}1===c.length&&(n=c[0])}if(!n&&!e&&t.loadKeys)return t.loadKeys().then(function(e){return t.jwks=e}).then(function(e){return r.validateSignature(t,!0)});if(!n&&e&&!o){u="No matching key found.";return console.error(u),Promise.reject(u)}if(!n&&e&&o){u="expected key not found in property jwks. This property is most likely loaded with the discovery document. Expected key id (kid): "+o;return console.error(u),Promise.reject(u)}var h=d.KEYUTIL.getKey(n),l={alg:this.allowedAlgorithms,gracePeriod:this.gracePeriodInSec};return d.KJUR.jws.JWS.verifyJWT(t.idToken,h,l)?Promise.resolve():Promise.reject("Signature not valid")},e.prototype.alg2kty=function(e){switch(e.charAt(0)){case"R":return"RSA";case"E":return"EC";default:throw new Error("Cannot infer kty from alg: "+e)}},e.prototype.calcHash=function(e,t){var r=new d.KJUR.crypto.MessageDigest({alg:t}).digestString(e),n=this.toByteArrayAsString(r);return Promise.resolve(n)},e.prototype.toByteArrayAsString=function(e){for(var t="",r=0;r<e.length;r+=2){var n=e.charAt(r)+e.charAt(r+1),o=parseInt(n,16);t+=String.fromCharCode(o)}return t},e}(v),D=new t.InjectionToken("AUTH_CONFIG");e.OAuthModule=L,e.OAuthService=A,e.JwksValidationHandler=O,e.NullValidationHandler=R,e.ValidationHandler=m,e.AbstractValidationHandler=v,e.UrlHelperService=k,e.AuthConfig=I,e.LoginOptions=a,e.OAuthLogger=u,e.OAuthStorage=p,e.ReceivedTokens=g,e.AUTH_CONFIG=D,e.OAuthEvent=y,e.OAuthSuccessEvent=_,e.OAuthInfoEvent=w,e.OAuthErrorEvent=S,e.DefaultOAuthInterceptor=H,e.OAuthResourceServerErrorHandler=x,e.OAuthNoopResourceServerErrorHandler=U,e.OAuthModuleConfig=E,e.OAuthResourceServerConfig=j,e.ɵa=P,e.ɵb=F,Object.defineProperty(e,"__esModule",{value:!0})});
//# sourceMappingURL=angular-oauth2-oidc.umd.min.js.map