Skip to content

Instantly share code, notes, and snippets.

@zishe
Created April 25, 2017 13:12
Show Gist options
  • Save zishe/e0d87a9b8b56b76caad77c7197980a0c to your computer and use it in GitHub Desktop.
Save zishe/e0d87a9b8b56b76caad77c7197980a0c to your computer and use it in GitHub Desktop.
angular2-token/lib/angular2-token.service.js
import { Injectable, Optional } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Http, Headers, Request, RequestMethod, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/share';
import 'rxjs/add/observable/interval';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/pluck';
import 'rxjs/add/operator/filter';
var Angular2TokenService = (function () {
function Angular2TokenService(http, activatedRoute, router) {
this.http = http;
this.activatedRoute = activatedRoute;
this.router = router;
}
Object.defineProperty(Angular2TokenService.prototype, "currentUserType", {
get: function () {
if (this.atCurrentUserType != null)
return this.atCurrentUserType.name;
else
return null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Angular2TokenService.prototype, "currentUserData", {
get: function () {
return this.atCurrentUserData;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Angular2TokenService.prototype, "currentAuthData", {
get: function () {
return this.atCurrentAuthData;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Angular2TokenService.prototype, "currentAuthHeaders", {
get: function () {
if (this.atCurrentAuthData != null) {
return new Headers({
'access-token': this.atCurrentAuthData.accessToken,
'client': this.atCurrentAuthData.client,
'expiry': this.atCurrentAuthData.expiry,
'token-type': this.atCurrentAuthData.tokenType,
'uid': this.atCurrentAuthData.uid
});
}
return new Headers;
},
enumerable: true,
configurable: true
});
Angular2TokenService.prototype.userSignedIn = function () {
return !!this.atCurrentAuthData;
};
Angular2TokenService.prototype.canActivate = function () {
if (this.userSignedIn())
return true;
else {
// Store current location in storage (usefull for redirection after signing in)
if (this.atOptions.signInStoredUrlStorageKey) {
localStorage.setItem(this.atOptions.signInStoredUrlStorageKey, window.location.pathname + window.location.search);
}
// Redirect user to sign in if signInRedirect is set
if (this.router && this.atOptions.signInRedirect)
this.router.navigate([this.atOptions.signInRedirect]);
return false;
}
};
// Inital configuration
Angular2TokenService.prototype.init = function (options) {
var defaultOptions = {
apiPath: null,
apiBase: null,
signInPath: 'auth/sign_in',
signInRedirect: null,
signInStoredUrlStorageKey: null,
signOutPath: 'auth/sign_out',
validateTokenPath: 'auth/validate_token',
signOutFailedValidate: false,
registerAccountPath: 'auth',
deleteAccountPath: 'auth',
registerAccountCallback: window.location.href,
updatePasswordPath: 'auth',
resetPasswordPath: 'auth/password',
resetPasswordCallback: window.location.href,
userTypes: null,
oAuthBase: window.location.origin,
oAuthPaths: {
github: 'auth/github'
},
oAuthCallbackPath: 'oauth_callback',
oAuthWindowType: 'newWindow',
oAuthWindowOptions: null,
globalOptions: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
};
this.atOptions = Object.assign(defaultOptions, options);
this.tryLoadAuthData();
};
/**
*
* Actions
*
*/
// Register request
Angular2TokenService.prototype.registerAccount = function (registerData) {
if (registerData.userType == null)
this.atCurrentUserType = null;
else {
this.atCurrentUserType = this.getUserTypeByName(registerData.userType);
delete registerData.userType;
}
registerData.password_confirmation = registerData.passwordConfirmation;
delete registerData.passwordConfirmation;
registerData.confirm_success_url = this.atOptions.registerAccountCallback;
return this.post(this.getUserPath() + this.atOptions.registerAccountPath, JSON.stringify(registerData));
};
// Delete Account
Angular2TokenService.prototype.deleteAccount = function () {
return this.delete(this.getUserPath() + this.atOptions.deleteAccountPath);
};
// Sign in request and set storage
Angular2TokenService.prototype.signIn = function (signInData) {
var _this = this;
if (signInData.userType == null)
this.atCurrentUserType = null;
else
this.atCurrentUserType = this.getUserTypeByName(signInData.userType);
var body = JSON.stringify({
email: signInData.email,
password: signInData.password
});
var observ = this.post(this.getUserPath() + this.atOptions.signInPath, body);
observ.subscribe(function (res) { return _this.atCurrentUserData = res.json().data; }, function (_error) { return null; });
return observ;
};
Angular2TokenService.prototype.signInOAuth = function (oAuthType) {
var oAuthPath = this.getOAuthPath(oAuthType);
var callbackUrl = window.location.origin + "/" + this.atOptions.oAuthCallbackPath;
var oAuthWindowType = this.atOptions.oAuthWindowType;
var authUrl = this.getOAuthUrl(oAuthPath, callbackUrl, oAuthWindowType);
if (oAuthWindowType == 'newWindow') {
var oAuthWindowOptions = this.atOptions.oAuthWindowOptions;
var windowOptions = '';
if (oAuthWindowOptions) {
for (var key in oAuthWindowOptions) {
windowOptions += "," + key + "=" + oAuthWindowOptions[key];
}
}
var popup = window.open(authUrl, '_blank', "closebuttoncaption=Cancel" + windowOptions);
return this.requestCredentialsViaPostMessage(popup);
}
else if (oAuthWindowType == 'sameWindow') {
window.location.href = authUrl;
}
else {
throw "Unsupported oAuthWindowType \"" + oAuthWindowType + "\"";
}
};
Angular2TokenService.prototype.processOAuthCallback = function () {
this.getAuthDataFromParams();
};
// Sign out request and delete storage
Angular2TokenService.prototype.signOut = function () {
var observ = this.delete(this.getUserPath() + this.atOptions.signOutPath);
localStorage.removeItem('accessToken');
localStorage.removeItem('client');
localStorage.removeItem('expiry');
localStorage.removeItem('tokenType');
localStorage.removeItem('uid');
this.atCurrentAuthData = null;
this.atCurrentUserType = null;
this.atCurrentUserData = null;
return observ;
};
// Validate token request
Angular2TokenService.prototype.validateToken = function () {
var _this = this;
var observ = this.get(this.getUserPath() + this.atOptions.validateTokenPath);
observ.subscribe(function (res) { return _this.atCurrentUserData = res.json().data; }, function (error) {
if (error.status === 401 && _this.atOptions.signOutFailedValidate) {
_this.signOut();
}
});
return observ;
};
// Update password request
Angular2TokenService.prototype.updatePassword = function (updatePasswordData) {
if (updatePasswordData.userType != null)
this.atCurrentUserType = this.getUserTypeByName(updatePasswordData.userType);
var args;
if (updatePasswordData.passwordCurrent == null) {
args = {
password: updatePasswordData.password,
password_confirmation: updatePasswordData.passwordConfirmation
};
}
else {
args = {
current_password: updatePasswordData.passwordCurrent,
password: updatePasswordData.password,
password_confirmation: updatePasswordData.passwordConfirmation
};
}
if (updatePasswordData.resetPasswordToken) {
args.reset_password_token = updatePasswordData.resetPasswordToken;
}
var body = JSON.stringify(args);
return this.put(this.getUserPath() + this.atOptions.updatePasswordPath, body);
};
// Reset password request
Angular2TokenService.prototype.resetPassword = function (resetPasswordData) {
if (resetPasswordData.userType == null)
this.atCurrentUserType = null;
else
this.atCurrentUserType = this.getUserTypeByName(resetPasswordData.userType);
var body = JSON.stringify({
email: resetPasswordData.email,
redirect_url: this.atOptions.resetPasswordCallback
});
return this.post(this.getUserPath() + this.atOptions.resetPasswordPath, body);
};
/**
*
* HTTP Wrappers
*
*/
Angular2TokenService.prototype.get = function (url, options) {
return this.request(this.mergeRequestOptionsArgs({
url: this.getApiPath() + url,
method: RequestMethod.Get
}, options));
};
Angular2TokenService.prototype.post = function (url, body, options) {
return this.request(this.mergeRequestOptionsArgs({
url: this.getApiPath() + url,
method: RequestMethod.Post,
body: body
}, options));
};
Angular2TokenService.prototype.put = function (url, body, options) {
return this.request(this.mergeRequestOptionsArgs({
url: this.getApiPath() + url,
method: RequestMethod.Put,
body: body
}, options));
};
Angular2TokenService.prototype.delete = function (url, options) {
return this.request(this.mergeRequestOptionsArgs({
url: this.getApiPath() + url,
method: RequestMethod.Delete
}, options));
};
Angular2TokenService.prototype.patch = function (url, body, options) {
return this.request(this.mergeRequestOptionsArgs({
url: this.getApiPath() + url,
method: RequestMethod.Patch,
body: body
}, options));
};
Angular2TokenService.prototype.head = function (path, options) {
return this.request({
method: RequestMethod.Head,
url: this.getApiPath() + path
});
};
Angular2TokenService.prototype.options = function (url, options) {
return this.request(this.mergeRequestOptionsArgs({
url: this.getApiPath() + url,
method: RequestMethod.Options
}, options));
};
// Construct and send Http request
Angular2TokenService.prototype.request = function (options) {
// var baseRequestOptions;
var baseHeaders = this.atOptions.globalOptions.headers;
// Merge auth headers to request if set
if (this.atCurrentAuthData != null) {
Object.assign(baseHeaders, {
'access-token': this.atCurrentAuthData.accessToken,
'client': this.atCurrentAuthData.client,
'expiry': this.atCurrentAuthData.expiry,
'token-type': this.atCurrentAuthData.tokenType,
'uid': this.atCurrentAuthData.uid
});
}
options.headers = options.headers || new Headers();
// Merge standard and custom RequestOptions
Object.keys(baseHeaders).forEach(function(name){
options.headers.set(name, baseHeaders[name]);
});
var response = this.http.request(new Request(options)).share();
this.handleResponse(response);
return response;
};
Angular2TokenService.prototype.mergeRequestOptionsArgs = function (options, addOptions) {
var returnOptions = options;
if (addOptions)
Object.assign(addOptions, returnOptions);
return addOptions || returnOptions;
};
// Check if response is complete and newer, then update storage
Angular2TokenService.prototype.handleResponse = function (response) {
var _this = this;
response.subscribe(function (res) {
_this.getAuthHeadersFromResponse(res);
}, function (error) {
_this.getAuthHeadersFromResponse(error);
});
};
/**
*
* Get Auth Data
*
*/
// Try to load auth data
Angular2TokenService.prototype.tryLoadAuthData = function () {
var userType = this.getUserTypeByName(localStorage.getItem('userType'));
if (userType)
this.atCurrentUserType = userType;
this.getAuthDataFromStorage();
if (this.activatedRoute)
this.getAuthDataFromParams();
if (this.atCurrentAuthData)
this.validateToken();
};
// Parse Auth data from response
Angular2TokenService.prototype.getAuthHeadersFromResponse = function (data) {
var headers = data.headers;
var authData = {
accessToken: headers.get('access-token'),
client: headers.get('client'),
expiry: headers.get('expiry'),
tokenType: headers.get('token-type'),
uid: headers.get('uid')
};
this.setAuthData(authData);
};
// Parse Auth data from post message
Angular2TokenService.prototype.getAuthDataFromPostMessage = function (data) {
var authData = {
accessToken: data['auth_token'],
client: data['client_id'],
expiry: data['expiry'],
tokenType: 'Bearer',
uid: data['uid']
};
this.setAuthData(authData);
};
// Try to get auth data from storage.
Angular2TokenService.prototype.getAuthDataFromStorage = function () {
var authData = {
accessToken: localStorage.getItem('accessToken'),
client: localStorage.getItem('client'),
expiry: localStorage.getItem('expiry'),
tokenType: localStorage.getItem('tokenType'),
uid: localStorage.getItem('uid')
};
if (this.checkAuthData(authData))
this.atCurrentAuthData = authData;
};
// Try to get auth data from url parameters.
Angular2TokenService.prototype.getAuthDataFromParams = function () {
var _this = this;
if (this.activatedRoute.queryParams)
this.activatedRoute.queryParams.subscribe(function (queryParams) {
var authData = {
accessToken: queryParams['token'] || queryParams['auth_token'],
client: queryParams['client_id'],
expiry: queryParams['expiry'],
tokenType: 'Bearer',
uid: queryParams['uid']
};
if (_this.checkAuthData(authData))
_this.atCurrentAuthData = authData;
});
};
/**
*
* Set Auth Data
*
*/
// Write auth data to storage
Angular2TokenService.prototype.setAuthData = function (authData) {
if (this.checkAuthData(authData)) {
this.atCurrentAuthData = authData;
localStorage.setItem('accessToken', authData.accessToken);
localStorage.setItem('client', authData.client);
localStorage.setItem('expiry', authData.expiry);
localStorage.setItem('tokenType', authData.tokenType);
localStorage.setItem('uid', authData.uid);
if (this.atCurrentUserType != null)
localStorage.setItem('userType', this.atCurrentUserType.name);
}
};
/**
*
* Validate Auth Data
*
*/
// Check if auth data complete and if response token is newer
Angular2TokenService.prototype.checkAuthData = function (authData) {
if (authData.accessToken != null &&
authData.client != null &&
authData.expiry != null &&
authData.tokenType != null &&
authData.uid != null) {
if (this.atCurrentAuthData != null)
return authData.expiry >= this.atCurrentAuthData.expiry;
else
return true;
}
else {
return false;
}
};
/**
*
* Construct Paths / Urls
*
*/
Angular2TokenService.prototype.getUserPath = function () {
if (this.atCurrentUserType == null)
return '';
else
return this.atCurrentUserType.path + '/';
};
Angular2TokenService.prototype.getApiPath = function () {
var constructedPath = '';
if (this.atOptions.apiBase != null)
constructedPath += this.atOptions.apiBase + '/';
if (this.atOptions.apiPath != null)
constructedPath += this.atOptions.apiPath + '/';
return constructedPath;
};
Angular2TokenService.prototype.getOAuthPath = function (oAuthType) {
var oAuthPath;
oAuthPath = this.atOptions.oAuthPaths[oAuthType];
if (oAuthPath == null)
oAuthPath = "/auth/" + oAuthType;
return oAuthPath;
};
Angular2TokenService.prototype.getOAuthUrl = function (oAuthPath, callbackUrl, windowType) {
var url;
url = this.atOptions.oAuthBase + "/" + oAuthPath;
url += "?omniauth_window_type=" + windowType;
url += "&auth_origin_url=" + encodeURIComponent(callbackUrl);
if (this.atCurrentUserType != null)
url += "&resource_class=" + this.atCurrentUserType.name;
return url;
};
/**
*
* OAuth
*
*/
Angular2TokenService.prototype.requestCredentialsViaPostMessage = function (authWindow) {
var pollerObserv = Observable.interval(500);
var responseObserv = Observable.fromEvent(window, 'message').pluck('data')
.filter(this.oAuthWindowResponseFilter);
var responseSubscription = responseObserv.subscribe(this.getAuthDataFromPostMessage.bind(this));
var pollerSubscription = pollerObserv.subscribe(function () {
if (authWindow.closed)
pollerSubscription.unsubscribe();
else
authWindow.postMessage('requestCredentials', '*');
});
return responseObserv;
};
Angular2TokenService.prototype.oAuthWindowResponseFilter = function (data) {
if (data.message == 'deliverCredentials' || data.message == 'authFailure')
return data;
};
/**
*
* Utilities
*
*/
// Match user config by user config name
Angular2TokenService.prototype.getUserTypeByName = function (name) {
if (name == null || this.atOptions.userTypes == null)
return null;
return this.atOptions.userTypes.find(function (userType) { return userType.name === name; });
};
return Angular2TokenService;
}());
export { Angular2TokenService };
Angular2TokenService.decorators = [
{ type: Injectable },
];
/** @nocollapse */
Angular2TokenService.ctorParameters = function () { return [
{ type: Http, },
{ type: ActivatedRoute, decorators: [{ type: Optional },] },
{ type: Router, decorators: [{ type: Optional },] },
]; };
//# sourceMappingURL=angular2-token.service.js.map
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment