UNPKG

ngo-login-client

Version:

Auth and User services for Angular v2 and up. Requires backend REST service.

166 lines 7.29 kB
import { Injectable, Inject } from '@angular/core'; import { Http, Headers, RequestOptions } from '@angular/http'; import { Observable, Subject } from 'rxjs'; import { Broadcaster } from 'ngo-base'; import { AUTH_API_URL } from '../shared/auth-api'; import { SSO_API_URL } from '../shared/sso-api'; import { REALM } from '../shared/realm-token'; var AuthenticationService = /** @class */ (function () { function AuthenticationService(broadcaster, apiUrl, ssoUrl, realm, http) { this.broadcaster = broadcaster; this.http = http; // Tokens this.google = 'google'; this.microsoft = 'microsoft'; this.refreshTokens = new Subject(); this.apiUrl = apiUrl; this.ssoUrl = ssoUrl; this.realm = realm; } AuthenticationService.prototype.logIn = function (tokenParameter) { var tokenJson = decodeURIComponent(tokenParameter); var token = this.processTokenResponse(JSON.parse(tokenJson)); this.setupRefreshTimer(token.expires_in); // kick off initial token refresh this.refreshTokens.next(token); this.onLogIn(); return true; }; AuthenticationService.prototype.onLogIn = function () { this.broadcaster.broadcast('loggedin', 1); }; AuthenticationService.prototype.logout = function () { this.clearSessionData(); this.broadcaster.broadcast('logout', 1); }; AuthenticationService.prototype.isLoggedIn = function () { var token = localStorage.getItem('auth_token'); if (token) { if (!this.clearTimeoutId) { // kick off initial token refresh this.refreshTokens.next({ "access_token": token }); this.setupRefreshTimer(15); } return true; } return false; }; AuthenticationService.prototype.getToken = function () { if (this.isLoggedIn()) return localStorage.getItem('auth_token'); }; /** * Return Google token */ AuthenticationService.prototype.getGoogleToken = function () { return this.createFederatedToken(this.google, function (response) { return response.json(); }); }; /** * Return Microsoft token */ AuthenticationService.prototype.getMicrosoftToken = function () { return this.createFederatedToken(this.microsoft, function (response) { return response.json(); }); }; AuthenticationService.prototype.setupRefreshTimer = function (refreshInSeconds) { var _this = this; if (!this.clearTimeoutId) { // refresh should be required to be less than ten minutes measured in seconds var tenMinutes = 60 * 10; if (refreshInSeconds > tenMinutes) { refreshInSeconds = tenMinutes; } var refreshInMs = Math.round(refreshInSeconds * .9) * 1000; console.log('Refreshing token in: ' + refreshInMs + ' milliseconds.'); this.refreshInterval = refreshInMs; if (process.env.ENV !== 'inmemory') { // setTimeout() uses a 32 bit int to store the delay. So the max value allowed is 2147483647 // The bigger number will cause immediate refreshing // but since we refresh in 10 minutes or in refreshInSeconds whatever is sooner we are good this.clearTimeoutId = setTimeout(function () { return _this.refreshToken(); }, refreshInMs); } } }; AuthenticationService.prototype.refreshToken = function () { var _this = this; if (this.isLoggedIn()) { var headers = new Headers({ 'Content-Type': 'application/json' }); var options = new RequestOptions({ headers: headers }); var refreshTokenUrl = this.apiUrl + 'login/refresh'; var refreshToken = localStorage.getItem('refresh_token'); var body = JSON.stringify({ 'refresh_token': refreshToken }); this.http.post(refreshTokenUrl, body, options) .map(function (response) { var responseJson = response.json(); var token = _this.processTokenResponse(responseJson.token); _this.clearTimeoutId = null; _this.setupRefreshTimer(token.expires_in); return token; }) .catch(function (response) { // Additionally catch a 400 from keycloak if (response.status === 400) { _this.broadcaster.broadcast('authenticationError', response); } return Observable.of({}); }) .subscribe(function (token) { // Refresh any federated tokens that we have _this.refreshTokens.next(token); console.log('token refreshed at:' + Date.now()); }); } }; AuthenticationService.prototype.processTokenResponse = function (response) { var token = response; localStorage.setItem('auth_token', token.access_token); localStorage.setItem('refresh_token', token.refresh_token); return token; }; AuthenticationService.prototype.createFederatedToken = function (broker, processToken) { var _this = this; var headers = new Headers({ 'Content-Type': 'application/json' }); var tokenUrl = this.ssoUrl + ("auth/realms/" + this.realm + "/broker/" + broker + "/token"); headers.set('Authorization', "Bearer " + this.getToken()); var options = new RequestOptions({ headers: headers }); return this.http.get(tokenUrl, options) .map(function (response) { return processToken(response); }) .catch(function (response) { if (response.status === 400) { _this.broadcaster.broadcast('noFederatedToken', response); } return Observable.of({}); }) .map(function (t) { return t.access_token; }); }; AuthenticationService.prototype.queryAsToken = function (query) { var vars = query.split('&'); var token = {}; for (var i = 0; i < vars.length; i++) { var pair = vars[i].split('='); var key = decodeURIComponent(pair[0]); var val = decodeURIComponent(pair[1]); token[key] = val; } return token; }; AuthenticationService.prototype.clearSessionData = function () { localStorage.removeItem('auth_token'); localStorage.removeItem('refresh_token'); clearTimeout(this.clearTimeoutId); this.refreshInterval = null; }; AuthenticationService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ AuthenticationService.ctorParameters = function () { return [ { type: Broadcaster, }, { type: undefined, decorators: [{ type: Inject, args: [AUTH_API_URL,] },] }, { type: undefined, decorators: [{ type: Inject, args: [SSO_API_URL,] },] }, { type: undefined, decorators: [{ type: Inject, args: [REALM,] },] }, { type: Http, }, ]; }; return AuthenticationService; }()); export { AuthenticationService }; //# sourceMappingURL=authentication.service.js.map