From 5149ade9343358200c2b918376f4fc8a6de9dd71 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Thu, 16 Apr 2020 11:08:29 -0700 Subject: [PATCH 1/4] Add fetchSignInMethodsForEmail to auth-next --- .../src/core/strategies/email.test.ts | 87 +++++++++++++++++++ .../auth-exp/src/core/strategies/email.ts | 38 ++++++++ .../auth-exp/src/core/util/location.ts | 28 ++++++ 3 files changed, 153 insertions(+) create mode 100644 packages-exp/auth-exp/src/core/strategies/email.test.ts create mode 100644 packages-exp/auth-exp/src/core/strategies/email.ts create mode 100644 packages-exp/auth-exp/src/core/util/location.ts diff --git a/packages-exp/auth-exp/src/core/strategies/email.test.ts b/packages-exp/auth-exp/src/core/strategies/email.test.ts new file mode 100644 index 00000000000..cbac9be95c9 --- /dev/null +++ b/packages-exp/auth-exp/src/core/strategies/email.test.ts @@ -0,0 +1,87 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FirebaseError } from '@firebase/util'; +import { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { SinonStub, stub } from 'sinon'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; +import * as mockFetch from '../../../test/mock_fetch'; +import { Endpoint } from '../../api'; +import { ServerError } from '../../api/errors'; +import { ProviderId } from '../providers'; +import * as location from '../util/location'; +import { fetchSignInMethodsForEmail } from './email'; + +use(chaiAsPromised); + +describe('fetchSignInMethodsForEmail', () => { + const email = 'foo@bar.com'; + const expectedSignInMethods = [ProviderId.PASSWORD, ProviderId.GOOGLE]; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should return the sign in methods', async () => { + const mock = mockEndpoint(Endpoint.CREATE_AUTH_URI, { + signinMethods: expectedSignInMethods + }); + const response = await fetchSignInMethodsForEmail(mockAuth, email); + expect(response).to.eql(expectedSignInMethods); + expect(mock.calls[0].request).to.eql({ + identifier: email, + continueUri: location.getCurrentUrl() + }); + }); + + context('on non standard platforms', () => { + let locationStub: SinonStub; + + beforeEach(() => { + locationStub = stub(location, 'isHttpOrHttps'); + locationStub.callsFake(() => false); + }); + + afterEach(() => { + locationStub.restore(); + }); + + it('should use localhost for the continueUri', async () => { + const mock = mockEndpoint(Endpoint.CREATE_AUTH_URI, { + signinMethods: expectedSignInMethods + }); + const response = await fetchSignInMethodsForEmail(mockAuth, email); + expect(response).to.eql(expectedSignInMethods); + expect(mock.calls[0].request).to.eql({ + identifier: email, + continueUri: 'http://localhost' + }); + }); + }); + + it('should surface errors', async () => { + const mock = mockEndpoint(Endpoint.CREATE_AUTH_URI, { + error: { + code: 400, + message: ServerError.INVALID_EMAIL + } + }, 400); + await expect(fetchSignInMethodsForEmail(mockAuth, email)).to.be.rejectedWith(FirebaseError, 'Firebase: The email address is badly formatted. (auth/invalid-email).'); + expect(mock.calls.length).to.eq(1); + }); +}); diff --git a/packages-exp/auth-exp/src/core/strategies/email.ts b/packages-exp/auth-exp/src/core/strategies/email.ts new file mode 100644 index 00000000000..038fee6b0de --- /dev/null +++ b/packages-exp/auth-exp/src/core/strategies/email.ts @@ -0,0 +1,38 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createAuthUri, CreateAuthUriRequest } from '../../api/authentication/create_auth_uri'; +import { Auth } from '../../model/auth'; +import { getCurrentUrl, isHttpOrHttps } from '../util/location'; + +export async function fetchSignInMethodsForEmail( + auth: Auth, + email: string +): Promise { + // createAuthUri returns an error if continue URI is not http or https. + // For environments like Cordova, Chrome extensions, native frameworks, file + // systems, etc, use http://localhost as continue URL. + const continueUri = isHttpOrHttps() ? getCurrentUrl() : 'http://localhost'; + const request: CreateAuthUriRequest = { + identifier: email, + continueUri + }; + + const response = await createAuthUri(auth, request); + + return response.signinMethods || []; +} \ No newline at end of file diff --git a/packages-exp/auth-exp/src/core/util/location.ts b/packages-exp/auth-exp/src/core/util/location.ts new file mode 100644 index 00000000000..89044084786 --- /dev/null +++ b/packages-exp/auth-exp/src/core/util/location.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function getCurrentUrl(): string { + return window?.location?.href || self?.location?.href || ''; +} + +export function isHttpOrHttps(): boolean { + return getCurrentScheme() === 'http:' || getCurrentScheme() === 'https:'; +} + +export function getCurrentScheme(): string | null { + return location?.protocol || null; +} \ No newline at end of file From 88ecc5cf081c18e3fa5d4ca164e9a959a22b6210 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Thu, 16 Apr 2020 11:21:51 -0700 Subject: [PATCH 2/4] [AUTOMATED]: Prettier Code Styling --- .../src/core/strategies/email.test.ts | 23 +++++++++++++------ .../auth-exp/src/core/strategies/email.ts | 7 ++++-- .../auth-exp/src/core/util/location.ts | 2 +- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages-exp/auth-exp/src/core/strategies/email.test.ts b/packages-exp/auth-exp/src/core/strategies/email.test.ts index cbac9be95c9..960e0ffc497 100644 --- a/packages-exp/auth-exp/src/core/strategies/email.test.ts +++ b/packages-exp/auth-exp/src/core/strategies/email.test.ts @@ -75,13 +75,22 @@ describe('fetchSignInMethodsForEmail', () => { }); it('should surface errors', async () => { - const mock = mockEndpoint(Endpoint.CREATE_AUTH_URI, { - error: { - code: 400, - message: ServerError.INVALID_EMAIL - } - }, 400); - await expect(fetchSignInMethodsForEmail(mockAuth, email)).to.be.rejectedWith(FirebaseError, 'Firebase: The email address is badly formatted. (auth/invalid-email).'); + const mock = mockEndpoint( + Endpoint.CREATE_AUTH_URI, + { + error: { + code: 400, + message: ServerError.INVALID_EMAIL + } + }, + 400 + ); + await expect( + fetchSignInMethodsForEmail(mockAuth, email) + ).to.be.rejectedWith( + FirebaseError, + 'Firebase: The email address is badly formatted. (auth/invalid-email).' + ); expect(mock.calls.length).to.eq(1); }); }); diff --git a/packages-exp/auth-exp/src/core/strategies/email.ts b/packages-exp/auth-exp/src/core/strategies/email.ts index 038fee6b0de..e604da2fbf5 100644 --- a/packages-exp/auth-exp/src/core/strategies/email.ts +++ b/packages-exp/auth-exp/src/core/strategies/email.ts @@ -15,7 +15,10 @@ * limitations under the License. */ -import { createAuthUri, CreateAuthUriRequest } from '../../api/authentication/create_auth_uri'; +import { + createAuthUri, + CreateAuthUriRequest +} from '../../api/authentication/create_auth_uri'; import { Auth } from '../../model/auth'; import { getCurrentUrl, isHttpOrHttps } from '../util/location'; @@ -35,4 +38,4 @@ export async function fetchSignInMethodsForEmail( const response = await createAuthUri(auth, request); return response.signinMethods || []; -} \ No newline at end of file +} diff --git a/packages-exp/auth-exp/src/core/util/location.ts b/packages-exp/auth-exp/src/core/util/location.ts index 89044084786..52c399e3cdb 100644 --- a/packages-exp/auth-exp/src/core/util/location.ts +++ b/packages-exp/auth-exp/src/core/util/location.ts @@ -25,4 +25,4 @@ export function isHttpOrHttps(): boolean { export function getCurrentScheme(): string | null { return location?.protocol || null; -} \ No newline at end of file +} From 5e1aedc6d456ca01739d1e72cf643017100631aa Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Thu, 16 Apr 2020 11:46:30 -0700 Subject: [PATCH 3/4] PR Feedback --- packages-exp/auth-exp/src/core/strategies/email.ts | 6 +++--- packages-exp/auth-exp/src/core/util/location.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages-exp/auth-exp/src/core/strategies/email.ts b/packages-exp/auth-exp/src/core/strategies/email.ts index e604da2fbf5..1b4b3b471f2 100644 --- a/packages-exp/auth-exp/src/core/strategies/email.ts +++ b/packages-exp/auth-exp/src/core/strategies/email.ts @@ -35,7 +35,7 @@ export async function fetchSignInMethodsForEmail( continueUri }; - const response = await createAuthUri(auth, request); + const { signinMethods } = await createAuthUri(auth, request); - return response.signinMethods || []; -} + return signinMethods || []; +} \ No newline at end of file diff --git a/packages-exp/auth-exp/src/core/util/location.ts b/packages-exp/auth-exp/src/core/util/location.ts index 52c399e3cdb..8c487ce76ea 100644 --- a/packages-exp/auth-exp/src/core/util/location.ts +++ b/packages-exp/auth-exp/src/core/util/location.ts @@ -16,7 +16,7 @@ */ export function getCurrentUrl(): string { - return window?.location?.href || self?.location?.href || ''; + return self?.location?.href || ''; } export function isHttpOrHttps(): boolean { @@ -24,5 +24,5 @@ export function isHttpOrHttps(): boolean { } export function getCurrentScheme(): string | null { - return location?.protocol || null; -} + return self?.location?.protocol || null; +} \ No newline at end of file From 1114dfcaf8d72d815ff860637fec8891a36f06ff Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Thu, 16 Apr 2020 11:46:44 -0700 Subject: [PATCH 4/4] [AUTOMATED]: Prettier Code Styling --- packages-exp/auth-exp/src/core/strategies/email.ts | 2 +- packages-exp/auth-exp/src/core/util/location.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages-exp/auth-exp/src/core/strategies/email.ts b/packages-exp/auth-exp/src/core/strategies/email.ts index 1b4b3b471f2..265f109ba4d 100644 --- a/packages-exp/auth-exp/src/core/strategies/email.ts +++ b/packages-exp/auth-exp/src/core/strategies/email.ts @@ -38,4 +38,4 @@ export async function fetchSignInMethodsForEmail( const { signinMethods } = await createAuthUri(auth, request); return signinMethods || []; -} \ No newline at end of file +} diff --git a/packages-exp/auth-exp/src/core/util/location.ts b/packages-exp/auth-exp/src/core/util/location.ts index 8c487ce76ea..f44363bd70f 100644 --- a/packages-exp/auth-exp/src/core/util/location.ts +++ b/packages-exp/auth-exp/src/core/util/location.ts @@ -25,4 +25,4 @@ export function isHttpOrHttps(): boolean { export function getCurrentScheme(): string | null { return self?.location?.protocol || null; -} \ No newline at end of file +}