From ac4dac3a037683089b9f16e5a0881edd45426738 Mon Sep 17 00:00:00 2001 From: wti806 <32399754+wti806@users.noreply.github.com> Date: Wed, 28 Mar 2018 15:48:29 -0700 Subject: [PATCH] Paring FDL link in getActionCodeFromSignInEmailLink to support deep link (#604) --- packages/auth/src/authcredential.js | 2 + packages/auth/test/auth_test.js | 87 +++++++++++++++++++++++ packages/auth/test/authcredential_test.js | 67 +++++++++++++++++ 3 files changed, 156 insertions(+) diff --git a/packages/auth/src/authcredential.js b/packages/auth/src/authcredential.js index c5cffb50fa6..b5afddcbc59 100644 --- a/packages/auth/src/authcredential.js +++ b/packages/auth/src/authcredential.js @@ -35,6 +35,7 @@ goog.provide('fireauth.TwitterAuthProvider'); goog.require('fireauth.ActionCodeUrl'); goog.require('fireauth.AuthError'); +goog.require('fireauth.DynamicLink'); goog.require('fireauth.IdToken'); goog.require('fireauth.authenum.Error'); goog.require('fireauth.idp'); @@ -750,6 +751,7 @@ fireauth.EmailAuthProvider.credentialWithLink = function(email, emailLink) { */ fireauth.EmailAuthProvider.getActionCodeFromSignInEmailLink = function(emailLink) { + emailLink = fireauth.DynamicLink.parseDeepLink(emailLink); var actionCodeUrl = new fireauth.ActionCodeUrl(emailLink); var code = actionCodeUrl.getCode(); if (actionCodeUrl.getMode() === fireauth.ActionCodeUrl.Mode.SIGN_IN && code) { diff --git a/packages/auth/test/auth_test.js b/packages/auth/test/auth_test.js index 28a73f20e19..dc2c5e4659b 100644 --- a/packages/auth/test/auth_test.js +++ b/packages/auth/test/auth_test.js @@ -1411,6 +1411,30 @@ function testIsSignInWithEmailLink() { } +function testIsSignInWithEmailLink_deepLink() { + var deepLink1 = 'https://www.example.com/action?mode=signIn&oobCode=oobCode'; + var deepLink2 = 'https://www.example.com/action?mode=verifyEmail&' + + 'oobCode=oobCode'; + var deepLink3 = 'https://www.example.com/action?mode=signIn'; + + var emailLink1 = 'https://example.app.goo.gl/?link=' + + encodeURIComponent(deepLink1); + var emailLink2= 'https://example.app.goo.gl/?link=' + + encodeURIComponent(deepLink2); + var emailLink3 = 'https://example.app.goo.gl/?link=' + + encodeURIComponent(deepLink3); + var emailLink4 = 'comexampleiosurl://google/link?deep_link_id=' + + encodeURIComponent(deepLink1); + + app1 = firebase.initializeApp(config1, appId1); + auth1 = app1.auth(); + assertEquals(true, auth1.isSignInWithEmailLink(emailLink1)); + assertEquals(false, auth1.isSignInWithEmailLink(emailLink2)); + assertEquals(false, auth1.isSignInWithEmailLink(emailLink3)); + assertEquals(true, auth1.isSignInWithEmailLink(emailLink4)); +} + + function testAuth_pendingPromises() { asyncTestCase.waitForSignals(1); // Simulate available token. @@ -3955,6 +3979,69 @@ function testAuth_signInWithEmailLink_success() { } +function testAuth_signInWithEmailLink_deepLink_success() { + // Tests successful signInWithEmailLink where the URL provided is the entire + // FDL link, instead of the deep link. + fireauth.AuthEventManager.ENABLED = true; + // Expected email and link. + var expectedEmail = 'user@example.com'; + var deepLink = 'https://www.example.com?mode=signIn&oobCode=code'; + var expectedLink = 'https://example.app.goo.gl/?link=' + + encodeURIComponent(deepLink); + var expectedOobCode = 'code'; + + // Stub OAuth sign in handler. + fakeOAuthSignInHandler(); + // signInWithIdTokenResponse should initialize a user using the expected + // token response generated by RPC response. + stubs.replace( + fireauth.Auth.prototype, + 'signInWithIdTokenResponse', + function(tokenResponse) { + // Token response should match rpcHandler response. + assertObjectEquals(expectedTokenResponse4, tokenResponse); + // Simulate user sign in completed and returned. + auth1.setCurrentUser_(user1); + asyncTestCase.signal(); + return goog.Promise.resolve(); + }); + // emailLinkSignIn should be called with expected parameters and resolved + // with expected token response. + stubs.replace( + fireauth.RpcHandler.prototype, + 'emailLinkSignIn', + function(email, oobCode) { + assertEquals(expectedEmail, email); + assertEquals(expectedOobCode, oobCode); + asyncTestCase.signal(); + return goog.Promise.resolve(expectedTokenResponse4); + }); + asyncTestCase.waitForSignals(3); + // Initialize expected user. + var user1 = new fireauth.AuthUser( + config3, expectedTokenResponse4, accountInfo); + var expectedResult = { + 'user': user1, + 'credential': null, + 'additionalUserInfo': {'providerId': 'password', 'isNewUser': false}, + 'operationType': fireauth.constants.OperationType.SIGN_IN + }; + app1 = firebase.initializeApp(config3, appId1); + auth1 = app1.auth(); + // Sign in with email and password. + auth1.signInWithEmailLink(expectedEmail, expectedLink) + .then(function(result) { + fireauth.common.testHelper.assertUserCredentialResponse( + expectedResult['user'], + expectedResult['credential'], + expectedResult['additionalUserInfo'], + expectedResult['operationType'], + result); + asyncTestCase.signal(); + }); +} + + function testAuth_signInWithEmailLink_error() { // Tests successful signInWithEmailLink. fireauth.AuthEventManager.ENABLED = true; diff --git a/packages/auth/test/authcredential_test.js b/packages/auth/test/authcredential_test.js index 2a1d53a8707..2f3d8c2dbd6 100644 --- a/packages/auth/test/authcredential_test.js +++ b/packages/auth/test/authcredential_test.js @@ -1510,6 +1510,43 @@ function testEmailAuthCredentialWithLink() { } +function testEmailAuthCredentialWithLink_deepLink() { + assertEquals( + fireauth.idp.ProviderId.PASSWORD, + fireauth.EmailAuthProvider['PROVIDER_ID']); + assertEquals( + fireauth.idp.SignInMethod.EMAIL_LINK, + fireauth.EmailAuthProvider['EMAIL_LINK_SIGN_IN_METHOD']); + var deepLink = 'https://www.example.com?mode=signIn&oobCode=code'; + var emailLink = 'https://example.app.goo.gl/?link=' + + encodeURIComponent(deepLink); + var authCredential = fireauth.EmailAuthProvider.credentialWithLink( + 'user@example.com', emailLink); + assertObjectEquals( + { + 'email': 'user@example.com', + 'password': 'code', + 'signInMethod': 'emailLink' + }, + authCredential.toPlainObject()); + assertEquals(fireauth.idp.ProviderId.PASSWORD, authCredential['providerId']); + assertEquals( + fireauth.idp.SignInMethod.EMAIL_LINK, authCredential['signInMethod']); + authCredential.getIdTokenProvider(rpcHandler); + assertRpcHandlerEmailLinkSignIn('user@example.com', 'code'); + var provider = new fireauth.EmailAuthProvider(); + // Should throw an invalid OAuth provider error. + var error = assertThrows(function() { + fireauth.AuthProvider.checkIfOAuthSupported(provider); + }); + var expectedError = + new fireauth.AuthError(fireauth.authenum.Error.INVALID_OAUTH_PROVIDER); + fireauth.common.testHelper.assertErrorEquals(expectedError, error); + assertEquals(fireauth.idp.ProviderId.PASSWORD, provider['providerId']); + assertFalse(provider['isOAuthProvider']); +} + + function testEmailAuthCredentialWithLink_invalidLink_error() { var expectedError = new fireauth.AuthError( fireauth.authenum.Error.ARGUMENT_ERROR, 'Invalid email link!'); @@ -1538,6 +1575,36 @@ function testEmailAuthProvider_getActionCodeFromSignInEmailLink() { } +function testEmailAuthProvider_getActionCodeFromSignInEmailLink_deepLink() { + var deepLink1 = 'https://www.example.com/action?mode=signIn&oobCode=oobCode'; + var deepLink2 = 'https://www.example.com/action?mode=verifyEmail&' + + 'oobCode=oobCode'; + var deepLink3 = 'https://www.example.com/action?mode=signIn'; + + var emailLink1 = 'https://example.app.goo.gl/?link=' + + encodeURIComponent(deepLink1); + var emailLink2 = 'https://example.app.goo.gl/?link=' + + encodeURIComponent(deepLink2); + var emailLink3 = 'https://example.app.goo.gl/?link=' + + encodeURIComponent(deepLink3); + var emailLink4 = 'comexampleiosurl://google/link?deep_link_id=' + + encodeURIComponent(deepLink1); + + var oobCode1 = fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink1); + assertEquals('oobCode', oobCode1); + var oobCode2 = fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink2); + assertNull(oobCode2); + var oobCode3 = fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink3); + assertNull(oobCode3); + var oobCode4 = fireauth.EmailAuthProvider + .getActionCodeFromSignInEmailLink(emailLink4); + assertEquals('oobCode', oobCode4); +} + + function testPhoneAuthProvider() { assertEquals(fireauth.PhoneAuthProvider['PROVIDER_ID'], fireauth.idp.ProviderId.PHONE);