ngo-login-client
Version:
Auth and User services for Angular v2 and up. Requires backend REST service.
166 lines • 7.29 kB
JavaScript
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