UNPKG

deep-security

Version:
370 lines (310 loc) 9.05 kB
/** * Created by mgoria on 11/12/15. */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.IdentityProvider = undefined; 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'); /** * @todo: split identity providers implementations * * 3rd Party identity provider (Amazon, Facebook, Google, etc.) */ class IdentityProvider { /** * @param {Object} providers * @param {String} providerName * @param {Object} identityMetadata */ constructor(providers, providerName, identityMetadata) { 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} */ static createFromSnapshot(metadata) { let provider = new IdentityProvider(null, IdentityProvider.SNAPSHOT_PROVIDER, metadata); provider.fillFromSnapshot(metadata); return provider; } /** * @param {String} name */ set name(name) { this._name = name; } /** * @param {String} providerName * @param {Object} providers * @returns {*} */ 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 */ _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, userId, expireTime, refreshToken, clientName }; } /** * @returns {Object} */ get providers() { return this._providers; } /** * @returns {String} */ get name() { return this._name; } /** * @returns {String} */ get domain() { return this._domain; } /** * @returns {String} */ get userToken() { return this._userToken; } /** * @param {String} userToken */ set userToken(userToken) { this._userToken = userToken; } /** * @returns {Date} */ get tokenExpirationTime() { return this._tokenExpTime; } /** * @param {Date} tokenExpirationTime */ set tokenExpirationTime(tokenExpirationTime) { this._tokenExpTime = tokenExpirationTime instanceof Date ? tokenExpirationTime : new Date(tokenExpirationTime); } /** * @returns {String} */ get refreshToken() { return this._refreshToken; } /** * @returns {String} */ get clientName() { return this._clientName; } /** * @returns {boolean} */ isTokenValid() { if (this.userToken && this.tokenExpirationTime) { return this.tokenExpirationTime > new Date(); } return false; } /** * @param {Object} idpSnapshot * * @returns {IdentityProvider} */ 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 {*} */ 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} */ 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} */ get userId() { return this._userId; } /** * @param {String} name * @returns {Object} */ config(name) { if (!this.providers.hasOwnProperty(name)) { throw new _MissingLoginProviderException.MissingLoginProviderException(name); } return this.providers[name]; } /** * @returns {String} */ static get COGNITO_USER_POOL_PROVIDER() { return 'cognito-user-pool'; } /** * @returns {String} */ static get FACEBOOK_PROVIDER() { return 'facebook'; } /** * @returns {String} */ static get AMAZON_PROVIDER() { return 'amazon'; } /** * @returns {String} */ static get GOOGLE_PROVIDER() { return 'google'; } /** * @returns {String} */ static get AUTH0_PROVIDER() { return 'auth0'; } /** * @returns {String} */ static get SNAPSHOT_PROVIDER() { return 'snapshot'; } } exports.IdentityProvider = IdentityProvider;