UNPKG

deep-security

Version:
448 lines (360 loc) 11.3 kB
/** * Created by mgoria on 11/12/15. */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.IdentityProvider = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _MissingLoginProviderException = require('./Exception/MissingLoginProviderException'); var _IdentityProviderMismatchException = require('./Exception/IdentityProviderMismatchException'); var _InvalidProviderIdentityException = require('./Exception/InvalidProviderIdentityException'); var _MissingIdentityImplementationException = require('./Exception/MissingIdentityImplementationException'); var _UserPoolImplementation = require('./IdentityImplementation/UserPoolImplementation'); var _MissingRefreshTokenException = require('./Exception/MissingRefreshTokenException'); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * @todo: split identity providers implementations * * 3rd Party identity provider (Amazon, Facebook, Google, etc.) */ let IdentityProvider = exports.IdentityProvider = function () { /** * @param {Object} providers * @param {String} providerName * @param {Object} identityMetadata */ function IdentityProvider(providers, providerName, identityMetadata) { _classCallCheck(this, IdentityProvider); let providerDomain = this.getProviderDomain(providerName, providers); if (!providerDomain) { throw new _MissingLoginProviderException.MissingLoginProviderException(providerName); } if (identityMetadata.provider && identityMetadata.provider !== providerName && providerName !== IdentityProvider.SNAPSHOT_PROVIDER) { throw new _IdentityProviderMismatchException.IdentityProviderMismatchException(providerName, identityMetadata.provider); } let normalizedMetadata = this._normalizeIdentityMetadata(providerName, identityMetadata); this._metadata = identityMetadata; this._userToken = normalizedMetadata.token; this._tokenExpTime = new Date(normalizedMetadata.expireTime); this._userId = normalizedMetadata.userId; this._providers = providers; this._refreshToken = normalizedMetadata.refreshToken; this._domain = providerDomain; this._clientName = normalizedMetadata.clientName; this._name = providerName; } /** * @param {Object} metadata * @returns {IdentityProvider} */ _createClass(IdentityProvider, [{ key: 'getProviderDomain', /** * @param {String} providerName * @param {Object} providers * @returns {*} */ value: function getProviderDomain(providerName, providers) { let domainRegexp; switch (providerName) { case IdentityProvider.AMAZON_PROVIDER: domainRegexp = /^www\.amazon\.com$/; break; case IdentityProvider.FACEBOOK_PROVIDER: domainRegexp = /^graph\.facebook\.com$/; break; case IdentityProvider.GOOGLE_PROVIDER: domainRegexp = /^accounts\.google\.com$/; break; case IdentityProvider.AUTH0_PROVIDER: domainRegexp = /^.+\.auth0\.com$/; break; case IdentityProvider.COGNITO_USER_POOL_PROVIDER: domainRegexp = /^cognito\-idp\.[\w\d\-]+\.amazonaws\.com\/[\w\d\-]+$/; break; case IdentityProvider.SNAPSHOT_PROVIDER: return IdentityProvider.SNAPSHOT_PROVIDER; } if (!domainRegexp) { return null; } for (let providerDomain in providers) { if (!providers.hasOwnProperty(providerDomain)) { continue; } if (domainRegexp.test(providerDomain)) { return providerDomain; } } return null; } /** * @todo: Implement other identity providers * @param {String} providerName * @param {Object} identityMetadata * @returns {*} * @private */ }, { key: '_normalizeIdentityMetadata', value: function _normalizeIdentityMetadata(providerName, identityMetadata) { let token = null; let expiresIn = null; let expireTime = null; let userId = null; let refreshToken = null; let clientName = null; switch (providerName) { case IdentityProvider.FACEBOOK_PROVIDER: token = identityMetadata.accessToken; expiresIn = identityMetadata.expiresIn; userId = identityMetadata.userID; break; case IdentityProvider.COGNITO_USER_POOL_PROVIDER: let userSession = identityMetadata.getSignInUserSession(); let idTokenInstance = userSession.getIdToken(); refreshToken = userSession.getRefreshToken().getToken(); token = idTokenInstance.getJwtToken(); expireTime = idTokenInstance.getExpiration() * 1000; clientName = identityMetadata.pool.getClientId(); break; case IdentityProvider.AMAZON_PROVIDER: token = identityMetadata.access_token; userId = identityMetadata.user_id; expiresIn = identityMetadata.expires_in || 3600; break; case IdentityProvider.AUTH0_PROVIDER: expireTime = identityMetadata.tokenExpirationTime; token = identityMetadata.access_token; userId = identityMetadata.user_id; break; // backend identity provider has the same structure as normalized metadata. see `toJSON` method case IdentityProvider.SNAPSHOT_PROVIDER: return identityMetadata; } userId = userId || null; expireTime = expireTime || (expiresIn ? Date.now() + expiresIn * 1000 : null); if (!(token && expireTime)) { throw new _InvalidProviderIdentityException.InvalidProviderIdentityException(providerName); } return { token: token, userId: userId, expireTime: expireTime, refreshToken: refreshToken, clientName: clientName }; } /** * @returns {Object} */ }, { key: 'isTokenValid', /** * @returns {boolean} */ value: function isTokenValid() { if (this.userToken && this.tokenExpirationTime) { return this.tokenExpirationTime > new Date(); } return false; } /** * @param {Object} idpSnapshot * * @returns {IdentityProvider} */ }, { key: 'fillFromSnapshot', value: function fillFromSnapshot(idpSnapshot) { this._name = idpSnapshot.name; this._domain = idpSnapshot.domain; this._refreshToken = idpSnapshot.refreshToken; this._clientName = idpSnapshot.clientName; this._userToken = idpSnapshot.token; this._tokenExpTime = new Date(idpSnapshot.expireTime); return this; } /** * return normalizedMetadata compatible structure, see `_normalizeIdentityMetadata` method * @returns {*} */ }, { key: 'toJSON', value: function toJSON() { return { token: this._userToken, expireTime: this._tokenExpTime.getTime(), userId: this._userId, refreshToken: this._refreshToken, name: this._name, domain: this._domain, clientName: this._clientName }; } /** * @returns {Promise} */ }, { key: 'refresh', value: function refresh() { if (!this._refreshToken) { return Promise.reject(new _MissingRefreshTokenException.MissingRefreshTokenException()); } let implementation = null; switch (this._name) { case IdentityProvider.COGNITO_USER_POOL_PROVIDER: implementation = new _UserPoolImplementation.UserPoolImplementation(this); break; default: throw new _MissingIdentityImplementationException.MissingIdentityImplementationException(this._name); } return implementation.refreshIdentity(); } /** * @returns {String} */ }, { key: 'config', /** * @param {String} name * @returns {Object} */ value: function config(name) { if (!this.providers.hasOwnProperty(name)) { throw new _MissingLoginProviderException.MissingLoginProviderException(name); } return this.providers[name]; } /** * @returns {String} */ }, { key: 'name', /** * @param {String} name */ set: function set(name) { this._name = name; }, /** * @returns {String} */ get: function get() { return this._name; } /** * @returns {String} */ }, { key: 'providers', get: function get() { return this._providers; } }, { key: 'domain', get: function get() { return this._domain; } /** * @returns {String} */ }, { key: 'userToken', get: function get() { return this._userToken; } /** * @param {String} userToken */ , set: function set(userToken) { this._userToken = userToken; } /** * @returns {Date} */ }, { key: 'tokenExpirationTime', get: function get() { return this._tokenExpTime; } /** * @param {Date} tokenExpirationTime */ , set: function set(tokenExpirationTime) { this._tokenExpTime = tokenExpirationTime instanceof Date ? tokenExpirationTime : new Date(tokenExpirationTime); } /** * @returns {String} */ }, { key: 'refreshToken', get: function get() { return this._refreshToken; } /** * @returns {String} */ }, { key: 'clientName', get: function get() { return this._clientName; } }, { key: 'userId', get: function get() { return this._userId; } }], [{ key: 'createFromSnapshot', value: function createFromSnapshot(metadata) { let provider = new IdentityProvider(null, IdentityProvider.SNAPSHOT_PROVIDER, metadata); provider.fillFromSnapshot(metadata); return provider; } }, { key: 'COGNITO_USER_POOL_PROVIDER', get: function get() { return 'cognito-user-pool'; } /** * @returns {String} */ }, { key: 'FACEBOOK_PROVIDER', get: function get() { return 'facebook'; } /** * @returns {String} */ }, { key: 'AMAZON_PROVIDER', get: function get() { return 'amazon'; } /** * @returns {String} */ }, { key: 'GOOGLE_PROVIDER', get: function get() { return 'google'; } /** * @returns {String} */ }, { key: 'AUTH0_PROVIDER', get: function get() { return 'auth0'; } /** * @returns {String} */ }, { key: 'SNAPSHOT_PROVIDER', get: function get() { return 'snapshot'; } }]); return IdentityProvider; }();