diff --git a/packages/auth/src/auth.js b/packages/auth/src/auth.js index 2a2c18d6e05..fa498d6c038 100644 --- a/packages/auth/src/auth.js +++ b/packages/auth/src/auth.js @@ -294,30 +294,57 @@ fireauth.Auth.prototype.useDeviceLanguage = function() { /** * Sets the emulator configuration (go/firebase-emulator-connection-api). - /** - * Sets the emulator configuration (go/firebase-emulator-connection-api). - * @param {string} url The url for the Auth emulator. - */ + * @param {string} url The url for the Auth emulator. + */ fireauth.Auth.prototype.useEmulator = function(url) { - // Don't do anything if no change detected. - if (!this.emulatorConfig_ || url !== this.emulatorConfig_.url) { - console.warn("WARNING: You are using the Auth Emulator, which is" + - " intended for local testing only. Do not use with" + - " production credentials."); - this.emulatorConfig_ = { url: url }; + // Emulator config can only be set once. + if (!this.emulatorConfig_) { + // Emit a warning so dev knows we are now in test mode. + this.emitEmulatorWarning_(); + // Persist the config. + this.emulatorConfig_ = { url }; // Disable app verification. - this.settings_().setAppVerificationDisabledForTesting(true); - // Update custom Firebase locale field. + this.settings.setAppVerificationDisabledForTesting(true); + // Update RPC handler endpoints. this.rpcHandler_.updateEmulatorConfig(this.emulatorConfig_); - // Notify external language code change listeners. + // Notify external event listeners. this.notifyEmulatorConfigListeners_(); } } + +/** + * Emits a console warning and a visual banner if emulator integration is + * enabled. + */ +fireauth.Auth.prototype.emitEmulatorWarning_ = function() { + fireauth.util.consoleWarn('WARNING: You are using the Auth Emulator,' + + ' which is intended for local testing only. Do not use with' + + ' production credentials.'); + if (goog.global.document) { + const ele = goog.global.document.createElement('p'); + ele.innerText = 'Running in emulator mode. Do not use with production' + + ' credentials.'; + ele.style.position = 'fixed'; + ele.style.width = '100%'; + ele.style.backgroundColor = '#ffffff'; + ele.style.border = '.1em solid #000000'; + ele.style.color = '#ff0000'; + ele.style.bottom = '0px'; + ele.style.left = '0px'; + ele.style.margin = '0px'; + ele.style.zIndex = 10000; + ele.style.textAlign = 'center'; + ele.classList.add('firebase-emulator-warning'); + goog.global.document.body.appendChild(ele); + } +} + + /** * @return {?fireauth.constants.EmulatorSettings} */ -fireauth.Auth.prototype.getEmulatorConfig = function () { +fireauth.Auth.prototype.getEmulatorConfig = function() { return this.emulatorConfig_; } @@ -451,7 +478,7 @@ fireauth.Auth.prototype.notifyLanguageCodeListeners_ = function() { * @private */ fireauth.Auth.prototype.notifyEmulatorConfigListeners_ = function() { - // Notify external listeners on the language code change. + // Notify external listeners on the emulator config change. this.dispatchEvent( new fireauth.Auth.EmulatorConfigChangeEvent(this.emulatorConfig_)); } @@ -877,7 +904,6 @@ fireauth.Auth.prototype.updateCurrentUser = function(user) { options['apiKey'] = this.app_().options['apiKey']; options['authDomain'] = this.app_().options['authDomain']; options['appName'] = this.app_().name; - options['emulatorConfig'] = this.emulatorConfig_; var newUser = fireauth.AuthUser.copyUser(user, options, self.redirectUserStorageManager_, self.getFramework()); return this.registerPendingPromise_( @@ -922,7 +948,9 @@ fireauth.Auth.prototype.signInWithIdTokenResponse = options['apiKey'] = self.app_().options['apiKey']; options['authDomain'] = self.app_().options['authDomain']; options['appName'] = self.app_().name; - options['emulatorConfig'] = self.emulatorConfig_; + if (self.emulatorConfig_) { + options['emulatorConfig'] = self.emulatorConfig_; + } // Wait for state to be ready. // This is used internally and is also used for redirect sign in so there is // no need for waiting for redirect result to resolve since redirect result @@ -1071,7 +1099,7 @@ fireauth.Auth.prototype.initAuthState_ = function() { var p = this.initRedirectUser_().then(function() { // Override user's authDomain with app's authDomain if there is a mismatch. return /** @type {!fireauth.storage.UserManager} */ ( - self.userStorageManager_).getCurrentUser(authDomain); + self.userStorageManager_).getCurrentUser(authDomain, self.emulatorConfig_); }).then(function(user) { // Logged in user. if (user) { @@ -1765,17 +1793,6 @@ fireauth.Auth.prototype.app_ = function() { }; - -/** - * @return {!fireauth.AuthSettings} The AuthSettings object this auth object - * is connected to. - * @private - */ -fireauth.Auth.prototype.settings_ = function() { - return this['settings']; -} - - /** * @return {!fireauth.RpcHandler} The RPC handler. */ diff --git a/packages/auth/src/autheventmanager.js b/packages/auth/src/autheventmanager.js index 9e5ca22bf0b..a6bb62df6af 100644 --- a/packages/auth/src/autheventmanager.js +++ b/packages/auth/src/autheventmanager.js @@ -672,12 +672,18 @@ fireauth.AuthEventManager.KEY_SEPARATOR_ = ':'; /** * @param {string} apiKey The API key for sending backend Auth requests. * @param {string} appName The Auth instance that initiated the Auth event. - * @return {string} The key identifying the Auth event manager instance. - * @private - */ -fireauth.AuthEventManager.getKey_ = function(apiKey, appName) { - return apiKey + fireauth.AuthEventManager.KEY_SEPARATOR_ + appName; -}; + * @param {?fireauth.constants.EmulatorSettings=} emulatorConfig The emulator + * configuration. + * @return {string} The key identifying the Auth event manager instance. + * @private + */ +fireauth.AuthEventManager.getKey_ = function(apiKey, appName, emulatorConfig) { + var key = apiKey + fireauth.AuthEventManager.KEY_SEPARATOR_ + appName; + if (emulatorConfig) { + key = key + fireauth.AuthEventManager.KEY_SEPARATOR_ + emulatorConfig.url; + } + return key; +} /** @@ -690,18 +696,26 @@ fireauth.AuthEventManager.getKey_ = function(apiKey, appName) { * configuration. * @return {!fireauth.AuthEventManager} the requested manager instance. */ -fireauth.AuthEventManager.getManager = function(authDomain, apiKey, appName, emulatorConfig) { +fireauth.AuthEventManager.getManager = function (authDomain, apiKey, appName, emulatorConfig) { // Construct storage key. - var key = fireauth.AuthEventManager.getKey_(apiKey, appName); + var key = fireauth.AuthEventManager.getKey_( + apiKey, + appName, + emulatorConfig + ); if (!fireauth.AuthEventManager.manager_[key]) { fireauth.AuthEventManager.manager_[key] = - new fireauth.AuthEventManager(authDomain, apiKey, appName, emulatorConfig); + new fireauth.AuthEventManager( + authDomain, + apiKey, + appName, + emulatorConfig + ); } return fireauth.AuthEventManager.manager_[key]; }; - /** * The interface that represents a specific type of Auth event processor. * @interface diff --git a/packages/auth/src/authuser.js b/packages/auth/src/authuser.js index ac57962941e..bedde8dc345 100644 --- a/packages/auth/src/authuser.js +++ b/packages/auth/src/authuser.js @@ -351,10 +351,10 @@ fireauth.AuthUser.prototype.setLanguageCodeChangeDispatcher = /** -* Listens to emulator config changes triggered by the provided dispatcher. -* @param {?goog.events.EventTarget} dispatcher The emulator config changed -* event dispatcher. -*/ + * Listens to emulator config changes triggered by the provided dispatcher. + * @param {?goog.events.EventTarget} dispatcher The emulator config changed + * event dispatcher. + */ fireauth.AuthUser.prototype.setEmulatorConfigChangeDispatcher = function(dispatcher) { // Remove any previous listener. if (this.emulatorConfigChangeEventDispatcher_) { @@ -367,7 +367,7 @@ fireauth.AuthUser.prototype.setEmulatorConfigChangeDispatcher = function(dispatc this.emulatorConfigChangeEventDispatcher_ = dispatcher; // Using an event listener makes it easy for non-currentUsers to detect // emulator changes on the parent Auth instance. A developer could still - // call APIs that require localization on signed out user references. + // call APIs that require emulation on signed out user references. if (dispatcher) { goog.events.listen( dispatcher, fireauth.constants.AuthEventType.EMULATOR_CONFIG_CHANGED, @@ -2423,7 +2423,8 @@ fireauth.AuthUser.fromPlainObject = function(user) { var options = { 'apiKey': user['apiKey'], 'authDomain': user['authDomain'], - 'appName': user['appName'] + 'appName': user['appName'], + 'emulatorConfig': user['emulatorConfig'] }; // Convert to server response format. Constructor does not take // stsTokenManager toPlainObject as that format is different than the return diff --git a/packages/auth/src/cordovahandler.js b/packages/auth/src/cordovahandler.js index d379829b003..6646d2da821 100644 --- a/packages/auth/src/cordovahandler.js +++ b/packages/auth/src/cordovahandler.js @@ -56,18 +56,17 @@ goog.require('goog.crypt.Sha256'); * @param {string} authDomain The application authDomain. * @param {string} apiKey The API key. * @param {string} appName The App name. - * @param {?string=} opt_clientVersion The optional client version string. - * @param {number=} opt_initialTimeout Initial Auth event timeout. - * @param {number=} opt_redirectTimeout Redirect result timeout. - * @param {?string=} opt_endpointId The endpoint ID (staging, test Gaia, etc). + * @param {?string=} clientVersion The optional client version string. + * @param {number=} initialTimeout Initial Auth event timeout. + * @param {number=} redirectTimeout Redirect result timeout. + * @param {?string=} endpointId The endpoint ID (staging, test Gaia, etc). * @param {?fireauth.constants.EmulatorSettings=} emulatorConfig The emulator * configuration * @constructor * @implements {fireauth.OAuthSignInHandler} */ fireauth.CordovaHandler = function(authDomain, apiKey, appName, - opt_clientVersion, opt_initialTimeout, opt_redirectTimeout, - opt_endpointId, emulatorConfig) { + clientVersion, initialTimeout, redirectTimeout, endpointId, emulatorConfig) { /** @private {string} The application authDomain. */ this.authDomain_ = authDomain; /** @private {string} The application API key. */ @@ -75,9 +74,9 @@ fireauth.CordovaHandler = function(authDomain, apiKey, appName, /** @private {string} The application name. */ this.appName_ = appName; /** @private {?string} The client version */ - this.clientVersion_ = opt_clientVersion || null; + this.clientVersion_ = clientVersion || null; /** @private {?string} The Auth endpoint ID. */ - this.endpointId_ = opt_endpointId || null; + this.endpointId_ = endpointId || null; /** * @private @const {?fireauth.constants.EmulatorSettings|undefined} * The emulator configuration @@ -109,10 +108,10 @@ fireauth.CordovaHandler = function(authDomain, apiKey, appName, */ this.authEventListeners_ = []; /** @private {number} The initial Auth event timeout. */ - this.initialTimeout_ = opt_initialTimeout || + this.initialTimeout_ = initialTimeout || fireauth.CordovaHandler.INITIAL_TIMEOUT_MS_; /** @private {number} The return to app after redirect timeout. */ - this.redirectTimeout_ = opt_redirectTimeout || + this.redirectTimeout_ = redirectTimeout || fireauth.CordovaHandler.REDIRECT_TIMEOUT_MS_; /** * @private {?goog.Promise} The last pending redirect promise. This is null if diff --git a/packages/auth/src/iframeclient/ifchandler.js b/packages/auth/src/iframeclient/ifchandler.js index 39d32e143a1..9bf7a29a4e5 100644 --- a/packages/auth/src/iframeclient/ifchandler.js +++ b/packages/auth/src/iframeclient/ifchandler.js @@ -104,8 +104,8 @@ fireauth.iframeclient.IframeUrlBuilder = function(authDomain, apiKey, appName, e null); } /** - * @private @const {!goog.Uri} The URI object used to build the iframe URL. - */ + * @private @const {!goog.Uri} The URI object used to build the iframe URL. + */ this.uri_ = uri; this.uri_.setParameterValue('apiKey', this.apiKey_); this.uri_.setParameterValue('appName', this.appName_); @@ -774,6 +774,9 @@ fireauth.iframeclient.IfcHandler.prototype.getRpcHandler_ = function() { // Get the client Auth endpoint used. fireauth.constants.getEndpointConfig(this.endpointId_), this.fullClientVersion_); + if (this.emulatorConfig_) { + this.rpcHandler_.updateEmulatorConfig(this.emulatorConfig_); + } } return this.rpcHandler_; }; diff --git a/packages/auth/src/rpchandler.js b/packages/auth/src/rpchandler.js index 0b6147682ce..df1e287f9ce 100644 --- a/packages/auth/src/rpchandler.js +++ b/packages/auth/src/rpchandler.js @@ -437,10 +437,10 @@ fireauth.RpcHandler.prototype.updateCustomLocaleHeader = /** -* Updates the emulator configuration. -* @param {?fireauth.constants.EmulatorSettings} emulatorConfig The new -* emulator config. -*/ + * Updates the emulator configuration. + * @param {?fireauth.constants.EmulatorSettings} emulatorConfig The new + * emulator config. + */ fireauth.RpcHandler.prototype.updateEmulatorConfig = function(emulatorConfig) { if (!emulatorConfig) { return; @@ -457,24 +457,21 @@ fireauth.RpcHandler.prototype.updateEmulatorConfig = function(emulatorConfig) { fireauth.RpcHandler.IDENTITY_PLATFORM_ENDPOINT_, emulatorConfig); } - -/** - * Creates an endpoint URL intended for use by the emulator. - * - * According to go/firebase-auth-emulator-dd - * @param {string} endpoint the production endpoint URL. - * @param {?fireauth.constants.EmulatorSettings} emulatorConfig The emulator - * config. - * @return {string} The emulator endpoint URL. - * @private - */ + /** + * Creates an endpoint URL intended for use by the emulator. + * @param {string} endpoint the production endpoint URL. + * @param {?fireauth.constants.EmulatorSettings} emulatorConfig The emulator + * config. + * @return {string} The emulator endpoint URL. + * @private + */ fireauth.RpcHandler.generateEmululatorEndpointUrl_ = function(endpoint, emulatorConfig) { const uri = goog.Uri.parse(endpoint); - const endpointUri = goog.Uri.parse(emulatorConfig.url); + const emulatorUri = goog.Uri.parse(emulatorConfig.url); uri.setPath(uri.getDomain() + uri.getPath()); - uri.setScheme(endpointUri.getScheme()); - uri.setDomain(endpointUri.getDomain()); - uri.setPort(endpointUri.getPort()); + uri.setScheme(emulatorUri.getScheme()); + uri.setDomain(emulatorUri.getDomain()); + uri.setPort(emulatorUri.getPort()); return uri.toString(); } diff --git a/packages/auth/src/storageusermanager.js b/packages/auth/src/storageusermanager.js index 816664f1f6d..c3d3b28d1eb 100644 --- a/packages/auth/src/storageusermanager.js +++ b/packages/auth/src/storageusermanager.js @@ -67,6 +67,7 @@ goog.provide('fireauth.storage.UserManager'); goog.require('fireauth.AuthUser'); goog.require('fireauth.authStorage'); +goog.require('fireauth.constants'); goog.require('goog.Promise'); @@ -399,13 +400,14 @@ fireauth.storage.UserManager.prototype.removeCurrentUser = function() { /** - * @param {?string=} opt_authDomain The optional Auth domain to override if + * @param {?string=} authDomain The optional Auth domain to override if * provided. + * @param {?fireauth.constants.EmulatorSettings=} emulatorConfig The current + * emulator config to use in user requests. * @return {!goog.Promise} A promise that resolves with * the stored current user for the provided app ID. */ -fireauth.storage.UserManager.prototype.getCurrentUser = - function(opt_authDomain) { +fireauth.storage.UserManager.prototype.getCurrentUser = function(authDomain, emulatorConfig) { var self = this; // Wait for any pending persistence change to be resolved. return this.waitForReady_(function() { @@ -420,8 +422,11 @@ fireauth.storage.UserManager.prototype.getCurrentUser = // authDomain for the purpose of linking with a popup. The loaded user // (stored without the authDomain) must have this field updated with // the current authDomain. - if (response && opt_authDomain) { - response['authDomain'] = opt_authDomain; + if (response && authDomain) { + response['authDomain'] = authDomain; + } + if (response && emulatorConfig) { + response['emulatorConfig'] = emulatorConfig; } return fireauth.AuthUser.fromPlainObject(response || {}); }); diff --git a/packages/auth/test/auth_test.js b/packages/auth/test/auth_test.js index e0264f34df5..c1876a95e37 100644 --- a/packages/auth/test/auth_test.js +++ b/packages/auth/test/auth_test.js @@ -449,6 +449,12 @@ function tearDown() { fireauth.authStorage.Manager.clear(); currentUserStorageManager = null; redirectUserStorageManager = null; + if (goog.global.document) { + var el = goog.global.document.querySelector('.firebase-emulator-warning'); + if (el) { + el.parentNode.removeChild(el); + } + } } @@ -904,8 +910,16 @@ function testUseEmulator() { fireauth.RpcHandler.prototype, 'updateEmulatorConfig', goog.testing.recordFunction()); + stubs.replace( + fireauth.util, + 'consoleWarn', + goog.testing.recordFunction()); var handler = goog.testing.recordFunction(); - + stubs.replace( + fireauth.AuthSettings.prototype, + 'setAppVerificationDisabledForTesting', + goog.testing.recordFunction()); + app1 = firebase.initializeApp(config1, appId1); auth1 = app1.auth(); @@ -919,46 +933,57 @@ function testUseEmulator() { assertEquals(0, handler.getCallCount()); assertEquals( 0, fireauth.RpcHandler.prototype.updateEmulatorConfig.getCallCount()); + assertEquals(0, fireauth.util.consoleWarn.getCallCount()); + assertEquals( + 0, + fireauth.AuthSettings.prototype.setAppVerificationDisabledForTesting. + getCallCount()); // Update the emulator config. auth1.useEmulator('http://emulator.test.domain:1234'); assertObjectEquals( - auth1.getEmulatorConfig(), { - url: 'http://emulator.test.domain:1234', - }); + { + url: 'http://emulator.test.domain:1234', + }, + auth1.getEmulatorConfig()); // Should notify the RPC handler. assertEquals( 1, fireauth.RpcHandler.prototype.updateEmulatorConfig.getCallCount()); - assertObjectEquals({ - url: 'http://emulator.test.domain:1234', - }, + assertObjectEquals( + { + url: 'http://emulator.test.domain:1234', + }, fireauth.RpcHandler.prototype.updateEmulatorConfig.getLastCall() .getArgument(0) ); + // Should emit a console warning. + assertEquals(1, fireauth.util.consoleWarn.getCallCount()); + // Should disable App verification. + assertEquals( + true, + fireauth.AuthSettings.prototype.setAppVerificationDisabledForTesting. + getLastCall().getArgument(0)); // Update to the same config should not trigger event again. auth1.useEmulator('http://emulator.test.domain:1234'); assertObjectEquals( - auth1.getEmulatorConfig(), { - url: 'http://emulator.test.domain:1234', - }); + { + url: 'http://emulator.test.domain:1234', + }, + auth1.getEmulatorConfig()); assertEquals( 1, fireauth.RpcHandler.prototype.updateEmulatorConfig.getCallCount()); + assertEquals(1, fireauth.util.consoleWarn.getCallCount()); - // Updating to different config should trigger event. + // Updating to different config should still not trigger event. auth1.useEmulator('http://emulator.other.domain:9876'); assertObjectEquals( - auth1.getEmulatorConfig(), { - url: 'http://emulator.other.domain:9876' - }); + { + url: 'http://emulator.test.domain:1234', + }, + auth1.getEmulatorConfig()); assertEquals( - 2, fireauth.RpcHandler.prototype.updateEmulatorConfig.getCallCount()); - assertObjectEquals({ - url: 'http://emulator.other.domain:9876', - }, - fireauth.RpcHandler.prototype.updateEmulatorConfig.getLastCall() - .getArgument(0) - ); + 1, fireauth.RpcHandler.prototype.updateEmulatorConfig.getCallCount()); } @@ -2275,6 +2300,60 @@ function testAuth_authEventManager_withEmulator() { } +/** Asserts that AuthEventManager can pass through emulator settings. */ +function testAuth_authEventManager_withEmulator() { + // Test Auth event manager. + fireauth.AuthEventManager.ENABLED = true; + stubs.reset(); + initializeMockStorage(); + var expectedManager = { + 'subscribe': goog.testing.recordFunction(), + 'unsubscribe': goog.testing.recordFunction(), + 'clearRedirectResult': goog.testing.recordFunction() + }; + // Return stub manager. + stubs.replace( + fireauth.AuthEventManager, + 'getManager', + function (authDomain, apiKey, appName, emulatorConfig) { + assertEquals('subdomain.firebaseapp.com', authDomain); + assertEquals('API_KEY', apiKey); + assertEquals(appId1, appName); + assertObjectEquals(emulatorConfig, { + url: 'http://emulator.host:1234' + }); + return expectedManager; + }); + asyncTestCase.waitForSignals(1); + app1 = firebase.initializeApp(config3, appId1); + auth1 = app1.auth(); + auth1.useEmulator('http://emulator.host:1234'); + // Test manager initialized and Auth subscribed. + auth1.onIdTokenChanged(function (user) { + var manager = fireauth.AuthEventManager.getManager( + config3['authDomain'], config3['apiKey'], app1.name, { + url: 'http://emulator.host:1234' + }); + assertEquals(expectedManager, manager); + assertEquals(0, expectedManager.unsubscribe.getCallCount()); + assertEquals(1, expectedManager.subscribe.getCallCount()); + assertEquals( + auth1, expectedManager.subscribe.getLastCall().getArgument(0)); + assertEquals(0, expectedManager.clearRedirectResult.getCallCount()); + // Delete should trigger unsubscribe and redirect result clearing. + auth1.delete(); + // After destroy, Auth should be unsubscribed. + assertEquals(1, expectedManager.subscribe.getCallCount()); + assertEquals(1, expectedManager.unsubscribe.getCallCount()); + // Redirect result should also be cleared. + assertEquals(1, expectedManager.clearRedirectResult.getCallCount()); + assertEquals( + auth1, expectedManager.unsubscribe.getLastCall().getArgument(0)); + asyncTestCase.signal(); + }); +} + + function testAuth_signout() { // Test successful sign out. fireauth.AuthEventManager.ENABLED = true; @@ -2463,6 +2542,71 @@ function testAuth_initState_signedInStatus() { } +function testAuth_initState_signedInStatus_withEmulator() { + // Test init state with previously signed in user. + fireauth.AuthEventManager.ENABLED = true; + stubs.reset(); + // Simulate current origin is whitelisted. + simulateWhitelistedOrigin(); + stubs.replace( + goog, + 'now', + function () { + return now; + }); + initializeMockStorage(); + // Stub OAuth sign in handler. + fakeOAuthSignInHandler(); + // New loaded user should be reloaded before being set as current user. + stubs.replace( + fireauth.AuthUser.prototype, + 'reload', + function () { + // Access token unchanged, should trigger notifyAuthListeners_. + return goog.Promise.resolve(); + }); + // Listen to calls on RPC Handler. + stubs.replace( + fireauth.RpcHandler.prototype, + 'updateEmulatorConfig', + goog.testing.recordFunction( + fireauth.RpcHandler.prototype.updateEmulatorConfig)); + asyncTestCase.waitForSignals(1); + // Logged in user to be detected in initState. + var user1 = new fireauth.AuthUser( + config3, expectedTokenResponse, accountInfo); + // Save signed in user to storage. + currentUserStorageManager = new fireauth.storage.UserManager( + config3['apiKey'] + ':' + appId1); + currentUserStorageManager.setCurrentUser(user1).then(function () { + app1 = firebase.initializeApp(config3, appId1); + auth1 = app1.auth(); + // Set emulator. + auth1.useEmulator('http://emulator.test.domain:1234'); + // Before init state current user is null. + assertNull(auth1['currentUser']); + // User state change triggered with user. + auth1.onAuthStateChanged(function (user) { + // Signed in user should be detected. + assertUserEquals(user1, auth1['currentUser']); + // Emulator config should propagate to currentUser. + assertEquals( + 3, fireauth.RpcHandler.prototype.updateEmulatorConfig.getCallCount()); + assertEquals(auth1['currentUser'].getRpcHandler(), + fireauth.RpcHandler.prototype.updateEmulatorConfig.getLastCall() + .getThis()); + assertObjectEquals( + { + url: 'http://emulator.test.domain:1234' + }, + fireauth.RpcHandler.prototype.updateEmulatorConfig.getLastCall() + .getArgument(0)); + asyncTestCase.signal(); + }); + }); +} + + /** * Test that external changes on a saved user will apply after loading from * storage and reload on user is called. Confirm the updated user is saved. @@ -4280,6 +4424,57 @@ function testAuth_signInWithIdTokenResponse_newUserDifferentFromCurrent() { } +/** + * Asserts that a new signed in user gets emulator configuration set correctly. + */ +function testAuth_signInWithIdTokenResponse_withEmulator() { + // Test signInWithIdTokenResponse returning a new user. + fireauth.AuthEventManager.ENABLED = true; + stubs.reset(); + // Simulate current origin is whitelisted. + simulateWhitelistedOrigin(); + stubs.replace( + goog, + 'now', + function () { + return now; + }); + initializeMockStorage(); + // Stub OAuth sign in handler. + fakeOAuthSignInHandler(); + // Initialize from ID token response should be called and resolved with the + // new signed in user. + stubs.replace( + fireauth.AuthUser, + 'initializeFromIdTokenResponse', + function (options, idTokenResponse) { + // Confirm emulatorConfig set on user's app options. + assertObjectEquals(expectedOptions, options); + return goog.Promise.resolve(user1); + }); + asyncTestCase.waitForSignals(1); + var expectedOptions = Object.assign({}, config3); + expectedOptions['emulatorConfig'] = { + url: 'http://emulator.test.domain:1234', + }; + // The newly signed in user. + var user1 = new fireauth.AuthUser( + config3, expectedTokenResponse, accountInfo); + + app1 = firebase.initializeApp(config3, appId1); + auth1 = app1.auth(); + // Set emulator. + auth1.useEmulator('http://emulator.test.domain:1234'); + // User not logged in yet. Run sign in with ID token response. + // The user should be initialized with the emulator config. + auth1.signInWithIdTokenResponse(expectedTokenResponse).then(function () { + // Current user should be set to user1. + assertEquals(user1, auth1['currentUser']); + asyncTestCase.signal(); + }); +} + + function testAuth_getIdToken_signedInUser() { // Tests getIdToken with a signed in user. fireauth.AuthEventManager.ENABLED = true; diff --git a/packages/auth/test/autheventmanager_test.js b/packages/auth/test/autheventmanager_test.js index e36d39dd56b..3613aa3a2cd 100644 --- a/packages/auth/test/autheventmanager_test.js +++ b/packages/auth/test/autheventmanager_test.js @@ -272,6 +272,19 @@ function testGetManager() { assertEquals( fireauth.AuthEventManager.getManager(authDomain2, apiKey2, appName2), manager2); + var emulatorConfig = { + url: 'http://emulator.test.domain:1234' + }; + var managerWithEmulator = fireauth.AuthEventManager.getManager( + authDomain1, apiKey1, appName1, emulatorConfig); + assertEquals( + fireauth.AuthEventManager.manager_[ + fireauth.AuthEventManager.getKey_(apiKey1, appName1)], + manager1); + assertEquals( + fireauth.AuthEventManager.manager_[ + fireauth.AuthEventManager.getKey_(apiKey1, appName1, emulatorConfig)], + managerWithEmulator); } @@ -286,7 +299,7 @@ function testInstantiateOAuthSignInHandler_ifcHandler() { // Confirm expected endpoint used. ifcHandlerConstructor( authDomain1, apiKey1, appName1, firebase.SDK_VERSION, - fireauth.constants.Endpoint.STAGING.id).$returns(ifcHandler); + fireauth.constants.Endpoint.STAGING.id, ignoreArgument).$returns(ifcHandler); mockControl.$replayAll(); fireauth.AuthEventManager.instantiateOAuthSignInHandler( @@ -295,6 +308,31 @@ function testInstantiateOAuthSignInHandler_ifcHandler() { } +/** Asserts that emulator config is propagated to ifcHandler. */ +function testInstantiateOAuthSignInHandler_ifcHandler_withEmulator() { + // Simulate browser environment. + setOAuthSignInHandlerEnvironment(false); + // IfcHandler should be instantiated. + var ifcHandler = mockControl.createStrictMock( + fireauth.iframeclient.IfcHandler); + var ifcHandlerConstructor = mockControl.createConstructorMock( + fireauth.iframeclient, 'IfcHandler'); + var emulatorConfig = { + url: 'http://emulator.test.domain:1234' + }; + // Confirm expected endpoint used. + ifcHandlerConstructor( + authDomain1, apiKey1, appName1, firebase.SDK_VERSION, + fireauth.constants.Endpoint.STAGING.id, + emulatorConfig).$returns(ifcHandler); + mockControl.$replayAll(); + + fireauth.AuthEventManager.instantiateOAuthSignInHandler( + authDomain1, apiKey1, appName1, firebase.SDK_VERSION, + fireauth.constants.Endpoint.STAGING.id, emulatorConfig); +} + + function testInstantiateOAuthSignInHandler_cordovaHandler() { // Simulate Cordova environment setOAuthSignInHandlerEnvironment(true); @@ -306,7 +344,7 @@ function testInstantiateOAuthSignInHandler_cordovaHandler() { // Confirm expected endpoint used. cordovaHandlerConstructor( authDomain1, apiKey1, appName1, firebase.SDK_VERSION, undefined, - undefined, fireauth.constants.Endpoint.STAGING.id) + undefined, fireauth.constants.Endpoint.STAGING.id, ignoreArgument) .$returns(cordovaHandler); mockControl.$replayAll(); @@ -316,6 +354,30 @@ function testInstantiateOAuthSignInHandler_cordovaHandler() { } +/** Asserts that emulator config is propagated to cordovaHandler. */ +function testInstantiateOAuthSignInHandler_cordovaHandler_withEmulator() { + // Simulate Cordova environment + setOAuthSignInHandlerEnvironment(true); + // CordovaHandler should be instantiated. + var cordovaHandler = mockControl.createStrictMock( + fireauth.CordovaHandler); + var cordovaHandlerConstructor = mockControl.createConstructorMock( + fireauth, 'CordovaHandler'); + var emulatorConfig = { + url: 'http://emulator.test.domain:1234' + }; + // Confirm expected endpoint used. + cordovaHandlerConstructor( + authDomain1, apiKey1, appName1, firebase.SDK_VERSION, undefined, + undefined, fireauth.constants.Endpoint.STAGING.id, emulatorConfig) + .$returns(cordovaHandler); + mockControl.$replayAll(); + + fireauth.AuthEventManager.instantiateOAuthSignInHandler( + authDomain1, apiKey1, appName1, firebase.SDK_VERSION, + fireauth.constants.Endpoint.STAGING.id, emulatorConfig); +} + function testAuthEventManager_initialize_manually_withSubscriber() { var expectedAuthEvent = new fireauth.AuthEvent( @@ -396,6 +458,48 @@ function testAuthEventManager_initialize_manually_withNoSubscriber() { } +function testAuthEventManager_initialize_manually_withEmulator() { + var expectedEmulatorConfig = { + url: 'http://emulator.test.domain:1234' + }; + var expectedAuthEvent = new fireauth.AuthEvent( + 'linkViaPopup', '1234', 'http://www.example.com/#response', 'SESSION_ID'); + var isReady = false; + // This test is not environment specific. + stubs.replace( + fireauth.AuthEventManager, + 'instantiateOAuthSignInHandler', + function (authDomain, apiKey, appName, version, endpoint, emulatorConfig) { + assertEquals('subdomain1.firebaseapp.com', authDomain); + assertEquals('API_KEY1', apiKey); + assertEquals('APP1', appName); + assertEquals(firebase.SDK_VERSION, version); + assertUndefined(endpoint); + assertObjectEquals(emulatorConfig, expectedEmulatorConfig); + isReady = true; + return { + 'addAuthEventListener': function (handler) { + handler(expectedAuthEvent); + }, + 'initializeAndWait': function () { return goog.Promise.resolve(); }, + 'shouldBeInitializedEarly': function () { + return false; + }, + 'hasVolatileStorage': function () { + return false; + } + }; + }); + asyncTestCase.waitForSignals(1); + var manager = fireauth.AuthEventManager.getManager( + authDomain1, apiKey1, appName1, expectedEmulatorConfig); + manager.initialize().then(function () { + assertTrue(isReady); + asyncTestCase.signal(); + }); +} + + function testAuthEventManager_initialize_automatically_pendingRedirect() { // Test automatic initialization when pending redirect available on // subscription. diff --git a/packages/auth/test/authuser_test.js b/packages/auth/test/authuser_test.js index f72e9a01f43..33c4dbc0064 100644 --- a/packages/auth/test/authuser_test.js +++ b/packages/auth/test/authuser_test.js @@ -718,6 +718,41 @@ function testUser() { } +/** + * Asserts that a user initiated with an emulator config will propagate + * the config to the RPC handler. + */ +function tesUser_initWithEmulator() { + // Listen to emulator config calls on RpcHandler. + stubs.replace( + fireauth.RpcHandler.prototype, + 'updateEmulatorConfig', + goog.testing.recordFunction()); + + // Initialize a user. + user = new fireauth.AuthUser( + { + appName: config1.appName, + apiKey: config1.apiKey, + emulatorConfig: { + url: 'http://emulator.test.domain:1234' + } + } + ); + + // Should notify the RPC handler. + assertEquals( + 1, fireauth.RpcHandler.prototype.updateEmulatorConfig.getCallCount()); + assertObjectEquals( + { + url: 'http://emulator.test.domain:1234', + }, + fireauth.RpcHandler.prototype.updateEmulatorConfig.getLastCall() + .getArgument(0) + ); +} + + function testUser_multiFactor() { user = new fireauth.AuthUser( config1, tokenResponse, accountInfoWithEnrolledFactors); @@ -768,7 +803,7 @@ function testUser_copyUser() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -2156,7 +2191,7 @@ function testUser_getIdToken_expiredToken_reauthWithPopupAfterInvalidation() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -2469,7 +2504,7 @@ function testUser_getIdToken_expiredToken_reauthWithPopupBeforeInvalidation() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -4404,7 +4439,7 @@ function testDestroy() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); mockControl.$replayAll(); // Confirm a user is subscribed to Auth event manager. stubs.replace( @@ -5793,7 +5828,7 @@ function testUser_linkWithRedirect_success_unloadsOnRedirect() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -5881,7 +5916,7 @@ function testUser_reauthenticateWithRedirect_success_unloadsOnRedirect() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -5963,7 +5998,7 @@ function testUser_linkWithRedirect_success_unloadsOnRedirect_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6061,7 +6096,7 @@ function testUser_reauthWithRedirect_success_unloadsOnRedirect_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6146,7 +6181,7 @@ function testUser_linkWithRedirect_success_doesNotUnloadOnRedirect() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6230,7 +6265,7 @@ function testUser_reauthenticateWithRedirect_success_doesNotUnloadOnRedirect() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6307,7 +6342,7 @@ function testUser_linkWithRedirect_success_doesNotUnloadOnRedirect_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6400,7 +6435,7 @@ function testUser_reauthWithRedirect_success_doesNotUnload_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6479,7 +6514,7 @@ function testUser_linkWithRedirect_success_noStorageManager() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6561,7 +6596,7 @@ function testUser_reauthenticateWithRedirect_success_noStorageManager() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6704,7 +6739,7 @@ function testUser_linkWithRedirect_invalidProvider() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processRedirect( @@ -6828,7 +6863,7 @@ function testUser_linkWithPopup_success_slowIframeEmbed() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -6983,7 +7018,7 @@ function testUser_reauthenticateWithPopup_success_slowIframeEmbed() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -7136,7 +7171,7 @@ function testUser_linkWithPopup_error_popupClosed() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -7269,7 +7304,7 @@ function testUser_reauthenticateWithPopup_error_popupClosed() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -7390,7 +7425,7 @@ function testUser_linkWithPopup_error_iframeWebStorageNotSupported() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -7516,7 +7551,7 @@ function testUser_reauthWithPopup_error_iframeWebStorageNotSupported() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -7635,7 +7670,7 @@ function testUser_linkWithPopup_success_withoutPostBody() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -7784,7 +7819,7 @@ function testUser_linkWithPopup_success_withPostBody() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -7939,7 +7974,7 @@ function testUser_linkWithPopup_success_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -8098,7 +8133,7 @@ function testUser_reauthenticateWithPopup_success_withoutPostBody() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -8251,7 +8286,7 @@ function testUser_reauthenticateWithPopup_success_withPostBody() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -8407,7 +8442,7 @@ function testUser_linkWithPopup_emailCredentialError() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -8549,7 +8584,7 @@ function testUser_reauthenticateWithPopup_userMismatchError() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -8776,7 +8811,7 @@ function testUser_linkWithPopup_success_cannotRunInBackground() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -8957,7 +8992,7 @@ function testUser_linkWithPopup_success_cannotRunInBackground_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -9151,7 +9186,7 @@ function testUser_reauthenticateWithPopup_success_cannotRunInBackground() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -9322,7 +9357,7 @@ function testUser_reauthenticateWithPopup_success_cannotRunInBkg_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -9506,7 +9541,7 @@ function testUser_linkWithPopup_success_iframeCanRunInBackground() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -9699,7 +9734,7 @@ function testUser_reauthenticateWithPopup_success_iframeCanRunInBackground() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -9880,7 +9915,7 @@ function testUser_linkWithPopup_webStorageUnsupported_cannotRunInBackground() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -10037,7 +10072,7 @@ function testUser_reauthWithPopup_webStorageUnsupported_cantRunInBackground() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -10188,7 +10223,7 @@ function testUser_linkWithPopup_multipleUsers_success() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); @@ -10406,7 +10441,7 @@ function testUser_reauthenticateWithPopup_multipleUsers_success() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -10615,7 +10650,7 @@ function testUser_linkWithPopup_timeout() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -10802,7 +10837,7 @@ function testUser_reauthenticateWithPopup_timeout() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -10979,7 +11014,7 @@ function testUser_linkWithPopup_error() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.shouldBeInitializedEarly().$returns(false); oAuthSignInHandlerInstance.hasVolatileStorage().$returns(false); oAuthSignInHandlerInstance.processPopup( @@ -11112,7 +11147,7 @@ function testUser_reauthenticateWithPopup_error() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -11261,7 +11296,7 @@ function testUser_returnFromLinkWithRedirect_success_withoutPostBody() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -11336,7 +11371,7 @@ function testUser_returnFromLinkWithRedirect_success_withPostBody() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -11414,7 +11449,7 @@ function testUser_returnFromLinkWithRedirect_success_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -11493,7 +11528,7 @@ function testUser_returnFromReauthenticateWithRedirect_success_noPostBody() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -11568,7 +11603,7 @@ function testUser_returnFromReauthenticateWithRedirect_success_postBody() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -11646,7 +11681,7 @@ function testUser_returnFromReauthenticateWithRedirect_success_tenantId() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -11725,7 +11760,7 @@ function testUser_returnFromLinkWithRedirect_success_multipleUsers() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Both users should be subscribed. @@ -11818,7 +11853,7 @@ function testUser_returnFromReauthenticateWithRedirect_success_multipleUsers() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Both users should be subscribed. @@ -11907,7 +11942,7 @@ function testUser_returnFromLinkWithRedirect_invalidUser() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -11969,7 +12004,7 @@ function testUser_returnFromReauthenticateWithRedirect_invalidUser() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -12032,7 +12067,7 @@ function testUser_returnFromLinkWithRedirect_error() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -12096,7 +12131,7 @@ function testUser_returnFromReauthenticateWithRedirect_error() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -13173,7 +13208,7 @@ function testUser_customLocaleChanges() { function testUser_emulatorConfigChanges() { - // Listen to all custom locale header calls on RpcHandler. + // Listen to all custom emulator config change calls on RpcHandler. stubs.replace( fireauth.RpcHandler.prototype, 'updateEmulatorConfig', @@ -13203,7 +13238,7 @@ function testUser_emulatorConfigChanges() { .getArgument(0) ); - // Set dispatcher1 as language code dispatcher. + // Set dispatcher1 as emulator config change dispatcher. user.setEmulatorConfigChangeDispatcher(dispatcher1); dispatcher1.dispatchEvent( new fireauth.Auth.EmulatorConfigChangeEvent(emulatorConfig)); @@ -13941,7 +13976,7 @@ function testReauthenticateWithPopup_multiFactor_success() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -14170,7 +14205,7 @@ function testReauthenticateWithPopup_multiFactor_mismatchError() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.processPopup( ignoreArgument, ignoreArgument, @@ -14322,7 +14357,7 @@ function testReturnFromReauthenticateWithRedirect_multiFactor_success() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from @@ -14479,7 +14514,7 @@ function testReturnFromReauthenticateWithRedirect_multiFactor_mismatchError() { fireauth.AuthEventManager, 'instantiateOAuthSignInHandler'); instantiateOAuthSignInHandler( ignoreArgument, ignoreArgument, ignoreArgument, ignoreArgument, - ignoreArgument).$returns(oAuthSignInHandlerInstance); + ignoreArgument, ignoreArgument).$returns(oAuthSignInHandlerInstance); oAuthSignInHandlerInstance.addAuthEventListener(ignoreArgument) .$does(function(handler) { // Dispatch expected Auth event immediately to simulate return from diff --git a/packages/auth/test/cordovahandler_test.js b/packages/auth/test/cordovahandler_test.js index c21d35293c7..e002d434c4c 100644 --- a/packages/auth/test/cordovahandler_test.js +++ b/packages/auth/test/cordovahandler_test.js @@ -1248,6 +1248,103 @@ function testCordovaHandler_processRedirect_success_parallelCalls_tenantId() { } +function testCordovaHandler_processRedirect_success_withEmulator() { + var emulatorConfig = { + url: 'http://emulator.test.domain:1234' + }; + return installAndRunTest( + 'testCordovaHandler_processRedirect_success_withEmulator', + function () { + var provider = new fireauth.GoogleAuthProvider(); + // Construct OAuth handler URL. + var expectedUrl = + fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl( + authDomain, + apiKey, + appName, + 'linkViaRedirect', + provider, + null, + '1234', + version, + { + apn: 'com.example.app', + appDisplayName: 'Test App', + sessionId: sha256('11111111111111111111') + }, + // Confirm expected endpoint ID passed. + fireauth.constants.Endpoint.STAGING.id, + null, + emulatorConfig); + // Stub this so the session ID generated can be predictable. + stubs.replace( + Math, + 'random', + function () { + return 0; + }); + // Simulate Android environment. + stubs.replace( + fireauth.util, + 'getUserAgentString', + function () { + return androidUA; + }); + var incomingUrl = + 'http://emulator.test.domain:1234/__/auth/callback#oauthResponse'; + // Completed event. + var completeEvent = new fireauth.AuthEvent( + 'linkViaRedirect', + '1234', + incomingUrl, + '11111111111111111111'); + // Initial unknown event. + var noEvent = new fireauth.AuthEvent( + fireauth.AuthEvent.Type.UNKNOWN, + null, + null, + null, + new fireauth.AuthError(fireauth.authenum.Error.NO_AUTH_EVENT)); + var savedCb = null; + // Save the universal link callback on subscription. + universalLinks.subscribe = function (eventType, cb) { + savedCb = cb; + }; + cordova.plugins.browsertab.openUrl = function (url) { + // Confirm expected URL. + assertEquals(expectedUrl, url); + // On openUrl, simulate completion by triggering the universal link + // callback with the OAuth response. + savedCb({ url: incomingUrl }); + }; + var handler = goog.testing.recordFunction(); + cordovaHandler = new fireauth.CordovaHandler( + authDomain, apiKey, appName, version, 10, undefined, + fireauth.constants.Endpoint.STAGING.id, emulatorConfig); + cordovaHandler.addAuthEventListener(handler); + return cordovaHandler.processRedirect('linkViaRedirect', provider, '1234') + .then(function () { + // Confirm browsertab close called. + assertEquals(1, cordova.plugins.browsertab.close.getCallCount()); + // Handler triggered twice. + assertEquals(2, handler.getCallCount()); + // First with no event. + assertAuthEventEquals( + noEvent, + handler.getCalls()[0].getArgument(0)); + // Then with resolved event. + assertAuthEventEquals( + completeEvent, + handler.getLastCall().getArgument(0)); + // Confirm event deleted from storage. + return getAndDeletePartialEventManager.getAuthEvent(); + }).then(function (event) { + assertNull(event); + }); + }); +} + + function testCordovaHandler_processRedirect_success_ios() { return installAndRunTest('processRedirect_success_ios', function() { var provider = new fireauth.GoogleAuthProvider(); diff --git a/packages/auth/test/iframeclient/ifchandler_test.js b/packages/auth/test/iframeclient/ifchandler_test.js index 5b669d4b3bc..1e8ff964368 100644 --- a/packages/auth/test/iframeclient/ifchandler_test.js +++ b/packages/auth/test/iframeclient/ifchandler_test.js @@ -205,6 +205,21 @@ function testIframeUrlBuilder() { } +/** + * Asserts IframeUrlBuilder.prototype.toString handles emulator URLs. + */ +function testIframeUrlBuilder_withEmulator() { + var builder = new fireauth.iframeclient.IframeUrlBuilder( + 'example.firebaseapp.com', 'API_KEY', 'MY_APP', { + url: 'http://emulator.test.domain:1234' + }); + assertEquals( + 'http://emulator.test.domain:1234/emulator/auth/iframe?' + + 'apiKey=API_KEY&appName=MY_APP', + builder.setVersion(null).toString()); +} + + function testOAuthUrlBuilder() { var redirectUrl = 'http://www.example.com/redirect?a=b#c'; var redirectUrl2 = 'http://www.example.com/redirect2?d=e#f'; @@ -605,6 +620,25 @@ function testIfcHandler() { } +/** + * Asserts getIframeUrl handles emulator URLs. + */ +function testIfcHandler_withEmulator() { + var emulatorConfig = { + url: 'http://emulator.test.domain:1234' + }; + // The expected iframe URL. + var expectedUrl = fireauth.iframeclient.IfcHandler.getAuthIframeUrl( + authDomain, apiKey, appName, version, undefined, undefined, + emulatorConfig); + // Initialize the ifcHandler. + ifcHandler = new fireauth.iframeclient.IfcHandler( + authDomain, apiKey, appName, version, undefined, emulatorConfig); + // Confirm expected iframe URL. + assertEquals(ifcHandler.getIframeUrl(), expectedUrl); +} + + function testIfcHandler_shouldNotBeInitializedEarly() { ifcHandler = new fireauth.iframeclient.IfcHandler( authDomain, apiKey, appName, version); @@ -708,7 +742,7 @@ function testIfcHandler_initializeAndWait_success() { fireauth.iframeclient, 'IframeWrapper'); // Iframe initialized with expected endpoint ID. getAuthIframeUrl(authDomain, apiKey, appName, ignoreArgument, - fireauth.constants.Endpoint.STAGING.id, expectedFrameworks) + fireauth.constants.Endpoint.STAGING.id, expectedFrameworks, ignoreArgument) .$returns('https://url'); // Confirm iframe URL returned by getAuthIframeUrl used to initialize the // IframeWrapper. @@ -935,7 +969,7 @@ function testIfcHandler_processPopup_notAlreadyRedirected_success() { } -function testIfcHandler_processPopup_notAlreadyRedirected_tenentId_success() { +function testIfcHandler_processPopup_notAlreadyRedirected_tenantId_success() { asyncTestCase.waitForSignals(1); var popupWin = { close: goog.testing.recordFunction() @@ -993,6 +1027,77 @@ function testIfcHandler_processPopup_notAlreadyRedirected_tenentId_success() { } +/** Asserts processRedirect can handle emulator URLs. */ +function testIfcHandler_processPopup_success_withEmulator() { + var emulatorConfig = { + url: 'http:/emulator.test.domain:1234' + }; + asyncTestCase.waitForSignals(1); + var popupWin = { + close: goog.testing.recordFunction() + }; + var onInit = goog.testing.recordFunction(); + var onError = goog.testing.recordFunction(); + stubs.replace( + fireauth.util, + 'goTo', + goog.testing.recordFunction()); + // Assume origin is a valid one. + stubs.replace( + fireauth.RpcHandler.prototype, + 'getAuthorizedDomains', + function () { + var uri = goog.Uri.parse(fireauth.util.getCurrentUrl()); + var domain = uri.getDomain(); + return goog.Promise.resolve([domain]); + }); + stubs.replace( + fireauth.RpcHandler.prototype, + 'updateEmulatorConfig', + goog.testing.recordFunction()); + var provider = new fireauth.GoogleAuthProvider(); + var expectedUrl = fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl( + authDomain, + apiKey, + appName, + 'linkViaPopup', + provider, + null, + '1234', + version, + undefined, + // Check expected endpoint ID appended. + fireauth.constants.Endpoint.STAGING.id, + undefined, + emulatorConfig); + ifcHandler = new fireauth.iframeclient.IfcHandler( + authDomain, apiKey, appName, version, + fireauth.constants.Endpoint.STAGING.id, emulatorConfig); + // Should succeed. + ifcHandler.processPopup( + popupWin, 'linkViaPopup', provider, onInit, onError, '1234', false) + .then(function () { + // On init should be called as the iframe is initialized. + assertEquals(1, onInit.getCallCount()); + // No error. + assertEquals(0, onError.getCallCount()); + // Popup redirected. + assertEquals( + expectedUrl, + fireauth.util.goTo.getLastCall().getArgument(0)); + // Emulator config set on RpcHandler. + assertObjectEquals( + emulatorConfig, + fireauth.RpcHandler.prototype.updateEmulatorConfig.getLastCall() + .getArgument(0)); + assertEquals( + popupWin, + fireauth.util.goTo.getLastCall().getArgument(1)); + asyncTestCase.signal(); + }); +} + + function testIfcHandler_processPopup_redirected_iframeCanRunInBG_success() { asyncTestCase.waitForSignals(1); // Simulate that the app can run in the background but is running in an @@ -1485,6 +1590,64 @@ function testIfcHandler_processRedirect_networkError_then_success() { } +/** Asserts that processRedirects works with emulator URLs. */ +function testIfcHandler_processRedirect_success_withEmulator() { + var emulatorConfig = { + url: 'http:/emulator.test.domain:1234' + }; + var provider = new fireauth.GoogleAuthProvider(); + var expectedUrl = fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl( + authDomain, + apiKey, + appName, + 'linkViaRedirect', + provider, + fireauth.util.getCurrentUrl(), + '1234', + version, + undefined, + // Check expected endpoint ID appended. + fireauth.constants.Endpoint.STAGING.id, + null, + emulatorConfig); + asyncTestCase.waitForSignals(1); + // Assume origin is a valid one. + stubs.replace( + fireauth.RpcHandler.prototype, + 'getAuthorizedDomains', + function () { + var uri = goog.Uri.parse(fireauth.util.getCurrentUrl()); + var domain = uri.getDomain(); + return goog.Promise.resolve([domain]); + }); + stubs.replace( + fireauth.RpcHandler.prototype, + 'updateEmulatorConfig', + goog.testing.recordFunction()); + stubs.replace( + fireauth.util, + 'goTo', + goog.testing.recordFunction()); + ifcHandler = new fireauth.iframeclient.IfcHandler( + authDomain, apiKey, appName, version, + fireauth.constants.Endpoint.STAGING.id, emulatorConfig); + // Should succeed and redirect. + ifcHandler.processRedirect('linkViaRedirect', provider, '1234') + .then(function () { + /** @suppress {missingRequire} */ + assertEquals( + expectedUrl, + fireauth.util.goTo.getLastCall().getArgument(0)); + // Emulator config set on RpcHandler. + assertObjectEquals( + emulatorConfig, + fireauth.RpcHandler.prototype.updateEmulatorConfig.getLastCall() + .getArgument(0)); + asyncTestCase.signal(); + }); +} + + /** * Tests getAuthIframeUrl. */ @@ -1503,7 +1666,7 @@ function testGetAuthIframeUrl() { /** - * Tests getAuthIframeUrl with emulator. + * Asserts getAuthIframeUrl handles emulator URLs. */ function testGetAuthIframeUrl_withEmulator() { var authDomain = 'subdomain.firebaseapp.com'; @@ -1841,3 +2004,39 @@ function testGetOAuthHelperWidgetUrl_frameworksAndLanguageCode() { authDomain, apiKey, appName, authType, provider)); } + +/** + * Asserts getOAuthHelperWidgetUrl handles emulator URLs. + */ +function testGetOAuthHelperWidgetUrl_withEmulator() { + var authDomain = 'subdomain.firebaseapp.com'; + var apiKey = 'apiKey1'; + var appName = 'appName1'; + var authType = 'signInWithPopup'; + var providerId = 'facebook.com'; + var provider = new fireauth.FacebookAuthProvider(); + var emulatorConfig = { + url: 'http://emulator.test.domain:1234' + }; + var expectedWidgetUrl = 'http://emulator.test.domain:1234/' + + 'emulator/auth/handler' + + '?apiKey=' + encodeURIComponent(apiKey) + + '&appName=' + encodeURIComponent(appName) + + '&authType=' + encodeURIComponent(authType) + + '&providerId=' + encodeURIComponent(providerId); + assertEquals( + expectedWidgetUrl, + fireauth.iframeclient.IfcHandler.getOAuthHelperWidgetUrl( + authDomain, + apiKey, + appName, + authType, + provider, + null, + null, + null, + null, + null, + null, + emulatorConfig)); +} \ No newline at end of file diff --git a/packages/auth/test/rpchandler_test.js b/packages/auth/test/rpchandler_test.js index a23a4a59ff2..916ded8a37f 100644 --- a/packages/auth/test/rpchandler_test.js +++ b/packages/auth/test/rpchandler_test.js @@ -1194,7 +1194,7 @@ function testRequestStsToken_emulator() { // Set an emulator config. rpcHandler.updateEmulatorConfig( { url: 'http://emulator.test.domain:1234' }); - // Send STS token request, default config will be used. + // Send STS token request, emulator config will be used. rpcHandler .requestStsToken({ 'grant_type': 'authorization_code', 'code': 'idToken' }) .then(function (response) { diff --git a/packages/auth/test/storageusermanager_test.js b/packages/auth/test/storageusermanager_test.js index 7acc451a509..991755b8d83 100644 --- a/packages/auth/test/storageusermanager_test.js +++ b/packages/auth/test/storageusermanager_test.js @@ -190,7 +190,13 @@ function testGetSetRemoveCurrentUser() { expectedUser = new fireauth.AuthUser(config, tokenResponse, accountInfo); // Expected user with authDomain. expectedUserWithAuthDomain = - new fireauth.AuthUser(configWithAuthDomain, tokenResponse, accountInfo); + new fireauth.AuthUser(configWithAuthDomain, tokenResponse, accountInfo); + // Listen to calls on RPC Handler. + stubs.replace( + fireauth.RpcHandler.prototype, + 'updateEmulatorConfig', + goog.testing.recordFunction( + fireauth.RpcHandler.prototype.updateEmulatorConfig)); var storageKey = 'firebase:authUser:appId1'; return goog.Promise.resolve() .then(function() { @@ -210,7 +216,23 @@ function testGetSetRemoveCurrentUser() { }) .then(function(user) { fireauth.common.testHelper.assertUserEquals( - expectedUserWithAuthDomain, user); + expectedUserWithAuthDomain, user); + // Get user with authDomain & emulator config. + return userManager.getCurrentUser('project.firebaseapp.com', + { + url: 'http://emulator.test.domain:1234' + }); + }) + .then(function () { + // Verify RpcHandler was notified of config change. + assertEquals(1, + fireauth.RpcHandler.prototype.updateEmulatorConfig.getCallCount()); + assertObjectEquals( + { + url: 'http://emulator.test.domain:1234' + }, + fireauth.RpcHandler.prototype.updateEmulatorConfig.getLastCall() + .getArgument(0)); return userManager.removeCurrentUser(); }) .then(function() {