From 73cf3af48ba70920353c724b877ae8663ee574ed Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Thu, 9 Apr 2020 13:03:10 -0700 Subject: [PATCH 01/14] User should be an interface for now we can make an implementation class later From 902c43e743bb3f91774af98959b3e43f2ac2a1a3 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Thu, 9 Apr 2020 15:17:50 -0700 Subject: [PATCH 02/14] Add API call to signUp --- packages-exp/auth-exp/src/core/errors.ts | 2 +- packages-exp/auth-exp/src/model/auth.d.ts | 2 +- .../test/api/authentication/sign_up.test.ts | 69 +++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 packages-exp/auth-exp/test/api/authentication/sign_up.test.ts diff --git a/packages-exp/auth-exp/src/core/errors.ts b/packages-exp/auth-exp/src/core/errors.ts index f894217720d..cf087a7ce5a 100644 --- a/packages-exp/auth-exp/src/core/errors.ts +++ b/packages-exp/auth-exp/src/core/errors.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2019 Google LLC + * 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. diff --git a/packages-exp/auth-exp/src/model/auth.d.ts b/packages-exp/auth-exp/src/model/auth.d.ts index 7ff4ef617f6..9fa9570feaf 100644 --- a/packages-exp/auth-exp/src/model/auth.d.ts +++ b/packages-exp/auth-exp/src/model/auth.d.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2019 Google LLC + * 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. diff --git a/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts b/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts new file mode 100644 index 00000000000..77221353655 --- /dev/null +++ b/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts @@ -0,0 +1,69 @@ +/** + * @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 * as mockFetch from '../../mock_fetch'; +import { signUp, SignUpRequest } from '../../../src/api/authentication/sign_up'; +import { expect } from 'chai'; +import { Endpoint } from '../../../src/api'; +import { ServerError } from '../../../src/api/errors'; +import { mockEndpoint, mockAuth } from '../helper'; + +describe('signUp', () => { + const request: SignUpRequest = { + returnSecureToken: true, + email: 'test@foo.com', + password: 'my-password' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SIGN_UP, { displayName: 'my-name', email: 'test@foo.com' }); + + const response = await signUp(mockAuth, request); + expect(response.displayName).to.eq('my-name'); + expect(response.email).to.eq('test@foo.com'); + expect(mock.calls[0]).to.eql({ + request + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint(Endpoint.SIGN_UP, { + error: { + code: 400, + message: ServerError.EMAIL_EXISTS, + errors: [ + { + message: ServerError.EMAIL_EXISTS, + } + ] + } + }, 400); + + try { + await signUp(mockAuth, request); + } catch (e) { + expect(e.name).to.eq('FirebaseError'); + expect(e.message).to.eq('Firebase: The email address is already in use by another account. (auth/email-already-in-use).'); + expect(mock.calls[0]).to.eql({ + request + }); + } + }); +}); \ No newline at end of file From ba33f0eeb5af00dbacb7e4ac7c9e159c77988c07 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Thu, 9 Apr 2020 15:18:15 -0700 Subject: [PATCH 03/14] [AUTOMATED]: Prettier Code Styling --- .../test/api/authentication/sign_up.test.ts | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts b/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts index 77221353655..0c296077117 100644 --- a/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts +++ b/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts @@ -33,7 +33,10 @@ describe('signUp', () => { afterEach(mockFetch.tearDown); it('should POST to the correct endpoint', async () => { - const mock = mockEndpoint(Endpoint.SIGN_UP, { displayName: 'my-name', email: 'test@foo.com' }); + const mock = mockEndpoint(Endpoint.SIGN_UP, { + displayName: 'my-name', + email: 'test@foo.com' + }); const response = await signUp(mockAuth, request); expect(response.displayName).to.eq('my-name'); @@ -44,26 +47,32 @@ describe('signUp', () => { }); it('should handle errors', async () => { - const mock = mockEndpoint(Endpoint.SIGN_UP, { - error: { - code: 400, - message: ServerError.EMAIL_EXISTS, - errors: [ - { - message: ServerError.EMAIL_EXISTS, - } - ] - } - }, 400); + const mock = mockEndpoint( + Endpoint.SIGN_UP, + { + error: { + code: 400, + message: ServerError.EMAIL_EXISTS, + errors: [ + { + message: ServerError.EMAIL_EXISTS + } + ] + } + }, + 400 + ); try { await signUp(mockAuth, request); } catch (e) { expect(e.name).to.eq('FirebaseError'); - expect(e.message).to.eq('Firebase: The email address is already in use by another account. (auth/email-already-in-use).'); + expect(e.message).to.eq( + 'Firebase: The email address is already in use by another account. (auth/email-already-in-use).' + ); expect(mock.calls[0]).to.eql({ request }); } }); -}); \ No newline at end of file +}); From ddf9e694584020125387008616e12fda3feca70a Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Fri, 10 Apr 2020 13:48:37 -0700 Subject: [PATCH 04/14] Update tests to test a little more --- .../test/api/authentication/sign_up.test.ts | 78 ------------------- 1 file changed, 78 deletions(-) delete mode 100644 packages-exp/auth-exp/test/api/authentication/sign_up.test.ts diff --git a/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts b/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts deleted file mode 100644 index 0c296077117..00000000000 --- a/packages-exp/auth-exp/test/api/authentication/sign_up.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @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 * as mockFetch from '../../mock_fetch'; -import { signUp, SignUpRequest } from '../../../src/api/authentication/sign_up'; -import { expect } from 'chai'; -import { Endpoint } from '../../../src/api'; -import { ServerError } from '../../../src/api/errors'; -import { mockEndpoint, mockAuth } from '../helper'; - -describe('signUp', () => { - const request: SignUpRequest = { - returnSecureToken: true, - email: 'test@foo.com', - password: 'my-password' - }; - - beforeEach(mockFetch.setUp); - afterEach(mockFetch.tearDown); - - it('should POST to the correct endpoint', async () => { - const mock = mockEndpoint(Endpoint.SIGN_UP, { - displayName: 'my-name', - email: 'test@foo.com' - }); - - const response = await signUp(mockAuth, request); - expect(response.displayName).to.eq('my-name'); - expect(response.email).to.eq('test@foo.com'); - expect(mock.calls[0]).to.eql({ - request - }); - }); - - it('should handle errors', async () => { - const mock = mockEndpoint( - Endpoint.SIGN_UP, - { - error: { - code: 400, - message: ServerError.EMAIL_EXISTS, - errors: [ - { - message: ServerError.EMAIL_EXISTS - } - ] - } - }, - 400 - ); - - try { - await signUp(mockAuth, request); - } catch (e) { - expect(e.name).to.eq('FirebaseError'); - expect(e.message).to.eq( - 'Firebase: The email address is already in use by another account. (auth/email-already-in-use).' - ); - expect(mock.calls[0]).to.eql({ - request - }); - } - }); -}); From 6d939662522e565cd275b6bf40974c3db1d83f1c Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Mon, 13 Apr 2020 15:17:59 -0700 Subject: [PATCH 05/14] Add remaining API methods to auth-next --- .../src/api/account_management/account.ts | 99 +++++++ .../account_management/email_and_password.ts | 45 ++++ .../src/api/account_management/mfa.ts | 64 +++++ .../src/api/account_management/profile.ts | 26 ++ .../authentication/create_auth_uri.test.ts | 75 ++++++ .../src/api/authentication/create_auth_uri.ts | 23 ++ .../api/authentication/custom_token.test.ts | 81 ++++++ .../src/api/authentication/custom_token.ts | 19 ++ .../authentication/email_and_password.test.ts | 224 ++++++++++++++++ .../api/authentication/email_and_password.ts | 96 +++++++ .../src/api/authentication/email_link.test.ts | 77 ++++++ .../src/api/authentication/email_link.ts | 23 ++ .../src/api/authentication/idp.test.ts | 78 ++++++ .../auth-exp/src/api/authentication/idp.ts | 34 +++ .../src/api/authentication/mfa.test.ts | 136 ++++++++++ .../auth-exp/src/api/authentication/mfa.ts | 51 ++++ .../src/api/authentication/recaptcha.test.ts | 70 +++++ .../src/api/authentication/recaptcha.ts | 18 ++ .../src/api/authentication/sign_up.test.ts | 4 +- .../src/api/authentication/sms.test.ts | 251 ++++++++++++++++++ .../auth-exp/src/api/authentication/sms.ts | 92 +++++++ 21 files changed, 1584 insertions(+), 2 deletions(-) create mode 100644 packages-exp/auth-exp/src/api/account_management/account.ts create mode 100644 packages-exp/auth-exp/src/api/account_management/email_and_password.ts create mode 100644 packages-exp/auth-exp/src/api/account_management/mfa.ts create mode 100644 packages-exp/auth-exp/src/api/account_management/profile.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/create_auth_uri.test.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/custom_token.test.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/custom_token.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/email_and_password.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/email_link.test.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/email_link.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/idp.test.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/idp.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/mfa.test.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/mfa.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/recaptcha.test.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/recaptcha.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/sms.test.ts create mode 100644 packages-exp/auth-exp/src/api/authentication/sms.ts diff --git a/packages-exp/auth-exp/src/api/account_management/account.ts b/packages-exp/auth-exp/src/api/account_management/account.ts new file mode 100644 index 00000000000..44a40c69fad --- /dev/null +++ b/packages-exp/auth-exp/src/api/account_management/account.ts @@ -0,0 +1,99 @@ +/** + * @license + * Copyright 2020 Google Inc. + * + * 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 { Auth } from '../../model/auth'; +import { performApiRequest, HttpMethod, Endpoint } from '..'; +import { APIMFAInfo } from '../../model/id_token'; + +export interface DeleteAccountRequest { + idToken: string; +} + +export async function deleteAccount( + auth: Auth, + request: DeleteAccountRequest +): Promise { + return performApiRequest( + auth, + HttpMethod.POST, + Endpoint.DELETE_ACCOUNT, + request + ); +} + +export interface DeleteLinkedAccountsRequest { + idToken: string; + deleteProvider: string[]; +} + +export interface DeleteLinkedAccountsResponse { + providerUserInfo: ProviderUserInfo[]; +} + +export async function deleteLinkedAccounts( + auth: Auth, + request: DeleteLinkedAccountsRequest +): Promise { + return performApiRequest< + DeleteLinkedAccountsRequest, + DeleteLinkedAccountsResponse + >(auth, HttpMethod.POST, Endpoint.SET_ACCOUNT_INFO, request); +} + +export interface APIUserInfo { + localId?: string; + displayName?: string; + photoUrl?: string; + email?: string; + emailVerified?: boolean; + phoneNumber?: string; + lastLoginAt?: number; + createdAt?: number; + tenantId?: string; + passwordHash?: string; + providerUserInfo: ProviderUserInfo[]; + mfaInfo?: APIMFAInfo[]; +} + +export interface ProviderUserInfo { + rawId?: string; + providerId?: string; + email?: string; + displayName?: string; + photoUrl?: string; + phoneNumber?: string; +} + +export interface GetAccountInfoRequest { + idToken: string; +} + +export interface GetAccountInfoResponse { + users: APIUserInfo[]; +} + +export async function getAccountInfo( + auth: Auth, + request: GetAccountInfoRequest +): Promise { + return performApiRequest( + auth, + HttpMethod.POST, + Endpoint.GET_ACCOUNT_INFO, + request + ); +} diff --git a/packages-exp/auth-exp/src/api/account_management/email_and_password.ts b/packages-exp/auth-exp/src/api/account_management/email_and_password.ts new file mode 100644 index 00000000000..8334d0d75d0 --- /dev/null +++ b/packages-exp/auth-exp/src/api/account_management/email_and_password.ts @@ -0,0 +1,45 @@ +import { performApiRequest, Endpoint, HttpMethod } from '..'; +import { Auth } from '../../model/auth'; +import { IdTokenResponse } from '../../model/id_token'; +import { Operation } from '../../model/action_code_info'; + +export interface ResetPasswordRequest { + oobCode: string; + newPassword?: string; +} + +export interface ResetPasswordResponse { + email: string; + newEmail?: string; + requestType?: Operation; +} + +export async function resetPassword( + auth: Auth, + request: ResetPasswordRequest +): Promise { + return performApiRequest( + auth, + HttpMethod.POST, + Endpoint.RESET_PASSWORD, + request + ); +} +export interface UpdateEmailPasswordRequest { + idToken: string; + returnSecureToken?: boolean; + email?: string; + password?: string; +} + +export interface UpdateEmailPasswordResponse extends IdTokenResponse { } + +export async function updateEmailPassword( + auth: Auth, + request: UpdateEmailPasswordRequest +): Promise { + return performApiRequest< + UpdateEmailPasswordRequest, + UpdateEmailPasswordResponse + >(auth, HttpMethod.POST, Endpoint.SET_ACCOUNT_INFO, request); +} diff --git a/packages-exp/auth-exp/src/api/account_management/mfa.ts b/packages-exp/auth-exp/src/api/account_management/mfa.ts new file mode 100644 index 00000000000..e775ff5ed19 --- /dev/null +++ b/packages-exp/auth-exp/src/api/account_management/mfa.ts @@ -0,0 +1,64 @@ +import { Endpoint, HttpMethod, performApiRequest } from '..'; +import { SignInWithPhoneNumberRequest } from '../authentication/sms'; +import { IdTokenResponse } from '../../model/id_token'; +import { Auth } from '../../model/auth'; + +export interface StartPhoneMfaEnrollmentRequest { + idToken: string; + + phoneEnrollmentInfo: { + phoneNumber: string; + recaptchaToken: string; + }; +} + +export interface StartPhoneMfaEnrollmentResponse { + phoneSessionInfo: { + sessionInfo: string; + }; +} + +export function startEnrollPhoneMfa( + auth: Auth, + request: StartPhoneMfaEnrollmentRequest +): Promise { + return performApiRequest< + StartPhoneMfaEnrollmentRequest, + StartPhoneMfaEnrollmentResponse + >(auth, HttpMethod.POST, Endpoint.START_PHONE_MFA_ENROLLMENT, request); +} + +export interface PhoneMfaEnrollmentRequest { + phoneVerificationInfo: SignInWithPhoneNumberRequest; +} + +export interface PhoneMfaEnrollmentResponse extends IdTokenResponse { } + +export function enrollPhoneMfa( + auth: Auth, + request: PhoneMfaEnrollmentRequest +): Promise { + return performApiRequest< + PhoneMfaEnrollmentRequest, + PhoneMfaEnrollmentResponse + >(auth, HttpMethod.POST, Endpoint.FINALIZE_PHONE_MFA_ENROLLMENT, request); +} + +export interface WithdrawMfaRequest { + idToken: string; + mfaEnrollmentId: string; +} + +export interface WithdrawMfaResponse extends IdTokenResponse { } + +export function withdrawMfa( + auth: Auth, + request: WithdrawMfaRequest +): Promise { + return performApiRequest( + auth, + HttpMethod.POST, + Endpoint.WITHDRAW_MFA, + request + ); +} \ No newline at end of file diff --git a/packages-exp/auth-exp/src/api/account_management/profile.ts b/packages-exp/auth-exp/src/api/account_management/profile.ts new file mode 100644 index 00000000000..5feb6999b83 --- /dev/null +++ b/packages-exp/auth-exp/src/api/account_management/profile.ts @@ -0,0 +1,26 @@ +import { IdTokenResponse } from '../../model/id_token'; +import { Auth } from '../../model/auth'; +import { performApiRequest, HttpMethod, Endpoint } from '..'; + +export interface UpdateProfileRequest { + idToken: string; + displayName?: string | null; + photoUrl?: string | null; +} + +export interface UpdateProfileResponse extends IdTokenResponse { + displayName?: string | null; + photoUrl?: string | null; +} + +export async function updateProfile( + auth: Auth, + request: UpdateProfileRequest +): Promise { + return performApiRequest( + auth, + HttpMethod.POST, + Endpoint.SET_ACCOUNT_INFO, + request + ); +} diff --git a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.test.ts b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.test.ts new file mode 100644 index 00000000000..ac0957daba9 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.test.ts @@ -0,0 +1,75 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { createAuthUri } from './create_auth_uri'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('createAuthUri', () => { + const request = { + identifier: 'my-id', + continueUri: 'example.com/redirectUri' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.CREATE_AUTH_URI, { + signinMethods: ['email'] + }); + + const response = await createAuthUri(mockAuth, request); + expect(response.signinMethods).to.include('email'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.CREATE_AUTH_URI, + { + error: { + code: 400, + message: ServerError.INVALID_PROVIDER_ID, + errors: [ + { + message: ServerError.INVALID_PROVIDER_ID + } + ] + } + }, + 400 + ); + + await expect(createAuthUri(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The specified provider ID is invalid. (auth/invalid-provider-id).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); diff --git a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts new file mode 100644 index 00000000000..09433bfefc8 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts @@ -0,0 +1,23 @@ +import { Auth } from '../../model/auth'; +import { performApiRequest, HttpMethod, Endpoint } from '..'; + +export interface CreateAuthUriRequest { + identifier: string; + continueUri: string; +} + +export interface CreateAuthUriResponse { + signinMethods: string[]; +} + +export async function createAuthUri( + auth: Auth, + request: CreateAuthUriRequest +): Promise { + return performApiRequest( + auth, + HttpMethod.POST, + Endpoint.CREATE_AUTH_URI, + request + ); +} \ No newline at end of file diff --git a/packages-exp/auth-exp/src/api/authentication/custom_token.test.ts b/packages-exp/auth-exp/src/api/authentication/custom_token.test.ts new file mode 100644 index 00000000000..57d9ca643a5 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/custom_token.test.ts @@ -0,0 +1,81 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { signInWithCustomToken } from './custom_token'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ProviderId } from '../../core/providers'; + +use(chaiAsPromised); + +describe('signInWithCustomToken', () => { + const request = { + token: 'my-token' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SIGN_IN_WITH_CUSTOM_TOKEN, { + providerId: ProviderId.CUSTOM, + idToken: 'id-token', + expiresIn: '1000', + localId: '1234' + }); + + const response = await signInWithCustomToken(mockAuth, request); + expect(response.providerId).to.eq(ProviderId.CUSTOM); + expect(response.idToken).to.eq('id-token'); + expect(response.expiresIn).to.eq('1000'); + expect(response.localId).to.eq('1234'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SIGN_IN_WITH_CUSTOM_TOKEN, + { + error: { + code: 400, + message: ServerError.INVALID_CUSTOM_TOKEN, + errors: [ + { + message: ServerError.INVALID_CUSTOM_TOKEN + } + ] + } + }, + 400 + ); + + await expect(signInWithCustomToken(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The custom token format is incorrect. Please check the documentation. (auth/invalid-custom-token).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); diff --git a/packages-exp/auth-exp/src/api/authentication/custom_token.ts b/packages-exp/auth-exp/src/api/authentication/custom_token.ts new file mode 100644 index 00000000000..4b5211d5148 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/custom_token.ts @@ -0,0 +1,19 @@ +import { Auth } from '../../model/auth'; +import { IdTokenResponse } from '../../model/id_token'; +import { performSignInRequest, HttpMethod, Endpoint } from '..'; + +export interface SignInWithCustomTokenRequest { + token: string; +} + +export interface SignInWithCustomTokenResponse extends IdTokenResponse {} + +export async function signInWithCustomToken( + auth: Auth, + request: SignInWithCustomTokenRequest +): Promise { + return performSignInRequest< + SignInWithCustomTokenRequest, + SignInWithCustomTokenResponse + >(auth, HttpMethod.POST, Endpoint.SIGN_IN_WITH_CUSTOM_TOKEN, request); +} \ No newline at end of file diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts new file mode 100644 index 00000000000..576fe206cab --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts @@ -0,0 +1,224 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { signInWithPassword, sendPasswordResetEmail, sendEmailVerification, sendSignInLinkToEmail, GetOobCodeRequestType, VerifyEmailRequest, PasswordResetRequest, EmailSignInRequest } from './email_and_password'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('signInWithPassword', () => { + const request = { + returnSecureToken: true, + email: 'test@foo.com', + password: 'my-password' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SIGN_IN_WITH_PASSWORD, { + displayName: 'my-name', + email: 'test@foo.com' + }); + + const response = await signInWithPassword(mockAuth, request); + expect(response.displayName).to.eq('my-name'); + expect(response.email).to.eq('test@foo.com'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SIGN_IN_WITH_PASSWORD, + { + error: { + code: 400, + message: ServerError.INVALID_PASSWORD, + errors: [ + { + message: ServerError.INVALID_PASSWORD + } + ] + } + }, + 400 + ); + + await expect(signInWithPassword(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The password is invalid or the user does not have a password. (auth/wrong-password).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('sendOobCode', () => { + context('VERIFY_EMAIL', () => { + const request: VerifyEmailRequest = { + requestType: GetOobCodeRequestType.VERIFY_EMAIL, + idToken: 'my-token' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SEND_OOB_CODE, { + email: 'test@foo.com' + }); + + const response = await sendEmailVerification(mockAuth, request); + expect(response.email).to.eq('test@foo.com'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SEND_OOB_CODE, + { + error: { + code: 400, + message: ServerError.INVALID_EMAIL, + errors: [ + { + message: ServerError.INVALID_EMAIL + } + ] + } + }, + 400 + ); + + await expect(sendEmailVerification(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The email address is badly formatted. (auth/invalid-email).' + ); + expect(mock.calls[0].request).to.eql(request); + }); + }); + + context('PASSWORD_RESET', () => { + const request: PasswordResetRequest = { + requestType: GetOobCodeRequestType.PASSWORD_RESET, + email: 'test@foo.com' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SEND_OOB_CODE, { + email: 'test@foo.com' + }); + + const response = await sendPasswordResetEmail(mockAuth, request); + expect(response.email).to.eq('test@foo.com'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SEND_OOB_CODE, + { + error: { + code: 400, + message: ServerError.INVALID_EMAIL, + errors: [ + { + message: ServerError.INVALID_EMAIL + } + ] + } + }, + 400 + ); + + await expect(sendPasswordResetEmail(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The email address is badly formatted. (auth/invalid-email).' + ); + expect(mock.calls[0].request).to.eql(request); + }); + }); + + context('EMAIL_SIGNIN', () => { + const request: EmailSignInRequest = { + requestType: GetOobCodeRequestType.EMAIL_SIGNIN, + email: 'test@foo.com' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SEND_OOB_CODE, { + email: 'test@foo.com' + }); + + const response = await sendSignInLinkToEmail(mockAuth, request); + expect(response.email).to.eq('test@foo.com'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SEND_OOB_CODE, + { + error: { + code: 400, + message: ServerError.INVALID_EMAIL, + errors: [ + { + message: ServerError.INVALID_EMAIL + } + ] + } + }, + 400 + ); + + await expect(sendSignInLinkToEmail(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The email address is badly formatted. (auth/invalid-email).' + ); + expect(mock.calls[0].request).to.eql(request); + }); + }); +}); \ No newline at end of file diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts new file mode 100644 index 00000000000..6c0bb79c432 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts @@ -0,0 +1,96 @@ +import { Auth } from '../../model/auth'; +import { IdTokenResponse, IdToken } from '../../model/id_token'; +import { performSignInRequest, HttpMethod, Endpoint, performApiRequest } from '..'; + +export interface SignInWithPasswordRequest { + returnSecureToken?: boolean; + email: string; + password: string; +} + +export interface SignInWithPasswordResponse extends IdTokenResponse { + email: string; + displayName: string; +} + +export async function signInWithPassword( + auth: Auth, + request: SignInWithPasswordRequest +): Promise { + return performSignInRequest< + SignInWithPasswordRequest, + SignInWithPasswordResponse + >(auth, HttpMethod.POST, Endpoint.SIGN_IN_WITH_PASSWORD, request); +} + +export enum GetOobCodeRequestType { + PASSWORD_RESET = 'PASSWORD_RESET', + EMAIL_SIGNIN = 'EMAIL_SIGNIN', + VERIFY_EMAIL = 'VERIFY_EMAIL', + VERIFY_AND_CHANGE_EMAIL = 'VERIFY_AND_CHANGE_EMAIL' +} + +interface GetOobCodeRequest { + email?: string; // Everything except VERIFY_AND_CHANGE_EMAIL + // captchaResp?: string, // RESET_PASSWORD + // userIp?: string, // RESET_PASSWORD, + // newEmail?: string, // VERIFY_AND_CHANGE_EMAIL, + idToken?: IdToken; // VERIFY_EMAIL, VERIFY_AND_CHANGE_EMAIL + continueUrl?: string; + iosBundleId?: string; + iosAppStoreId?: string; + androidPackageName?: string; + androidInstallApp?: boolean; + androidMinimumVersionCode?: string; + canHandleCodeInApp?: boolean; + dynamicLinkDomain?: string; + // tenantId?: string, + // targetProjectid?: string, +} + +export interface VerifyEmailRequest extends GetOobCodeRequest { + requestType: GetOobCodeRequestType.VERIFY_EMAIL; + idToken: IdToken; +} + +export interface PasswordResetRequest extends GetOobCodeRequest { + requestType: GetOobCodeRequestType.PASSWORD_RESET; + email: string; +} + +export interface EmailSignInRequest extends GetOobCodeRequest { + requestType: GetOobCodeRequestType.EMAIL_SIGNIN; + email: string; +} + +interface GetOobCodeResponse { + email: string; +} + +export interface VerifyEmailResponse extends GetOobCodeResponse {}; +export interface PasswordResetResponse extends GetOobCodeResponse { }; +export interface EmailSignInResponse extends GetOobCodeResponse { }; + +async function sendOobCode( + auth: Auth, + request: GetOobCodeRequest +): Promise { + return performApiRequest( + auth, + HttpMethod.POST, + Endpoint.SEND_OOB_CODE, + request + ); +} + +export async function sendEmailVerification(auth: Auth, request: VerifyEmailRequest): Promise { + return sendOobCode(auth, request); +} + +export async function sendPasswordResetEmail(auth: Auth, request: PasswordResetRequest): Promise { + return sendOobCode(auth, request); +} + +export async function sendSignInLinkToEmail(auth: Auth, request: EmailSignInRequest): Promise { + return sendOobCode(auth, request); +} \ No newline at end of file diff --git a/packages-exp/auth-exp/src/api/authentication/email_link.test.ts b/packages-exp/auth-exp/src/api/authentication/email_link.test.ts new file mode 100644 index 00000000000..934dc7adf7b --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/email_link.test.ts @@ -0,0 +1,77 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { signInWithEmailLink } from './email_link'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('signInWithEmailLink', () => { + const request = { + email: 'foo@bar.com', + oobCode: 'my-code' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SIGN_IN_WITH_EMAIL_LINK, { + displayName: 'my-name', + email: 'test@foo.com' + }); + + const response = await signInWithEmailLink(mockAuth, request); + expect(response.displayName).to.eq('my-name'); + expect(response.email).to.eq('test@foo.com'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SIGN_IN_WITH_EMAIL_LINK, + { + error: { + code: 400, + message: ServerError.INVALID_EMAIL, + errors: [ + { + message: ServerError.INVALID_EMAIL + } + ] + } + }, + 400 + ); + + await expect(signInWithEmailLink(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The email address is badly formatted. (auth/invalid-email).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); diff --git a/packages-exp/auth-exp/src/api/authentication/email_link.ts b/packages-exp/auth-exp/src/api/authentication/email_link.ts new file mode 100644 index 00000000000..fbec634db41 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/email_link.ts @@ -0,0 +1,23 @@ +import { Auth } from '../../model/auth'; +import { IdTokenResponse } from '../../model/id_token'; +import { performSignInRequest, HttpMethod, Endpoint } from '..'; + +export interface SignInWithEmailLinkRequest { + email: string; + oobCode: string; +} + +export interface SignInWithEmailLinkResponse extends IdTokenResponse { + email: string; + isNewUser: boolean; +} + +export async function signInWithEmailLink( + auth: Auth, + request: SignInWithEmailLinkRequest +): Promise { + return performSignInRequest< + SignInWithEmailLinkRequest, + SignInWithEmailLinkResponse + >(auth, HttpMethod.POST, Endpoint.SIGN_IN_WITH_EMAIL_LINK, request); +} diff --git a/packages-exp/auth-exp/src/api/authentication/idp.test.ts b/packages-exp/auth-exp/src/api/authentication/idp.test.ts new file mode 100644 index 00000000000..ff671ee3b5e --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/idp.test.ts @@ -0,0 +1,78 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { signInWithIdp } from './idp'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('signInWithIdp', () => { + const request = { + returnSecureToken: true, + requestUri: 'request-uri', + postBody: null + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SIGN_IN_WITH_IDP, { + displayName: 'my-name', + idToken: 'id-token' + }); + + const response = await signInWithIdp(mockAuth, request); + expect(response.displayName).to.eq('my-name'); + expect(response.idToken).to.eq('id-token'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SIGN_IN_WITH_IDP, + { + error: { + code: 400, + message: ServerError.INVALID_IDP_RESPONSE, + errors: [ + { + message: ServerError.INVALID_IDP_RESPONSE + } + ] + } + }, + 400 + ); + + await expect(signInWithIdp(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The supplied auth credential is malformed or has expired. (auth/invalid-credential).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); diff --git a/packages-exp/auth-exp/src/api/authentication/idp.ts b/packages-exp/auth-exp/src/api/authentication/idp.ts new file mode 100644 index 00000000000..54941530dd5 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/idp.ts @@ -0,0 +1,34 @@ +import { Auth } from '../../model/auth'; +import { IdToken, IdTokenResponse } from '../../model/id_token'; +import { performSignInRequest, HttpMethod, Endpoint } from '..'; + +export interface SignInWithIdpRequest { + requestUri: string; + postBody: string | null; + sessionId?: string; + tenantId?: string; + returnSecureToken: boolean; + idToken?: IdToken; + autoCreate?: boolean; + pendingToken?: string; +} + +export interface SignInWithIdpResponse extends IdTokenResponse { + oauthAccessToken?: string; + oauthTokenSecret?: string; + nonce?: string; + oauthIdToken?: string; + pendingToken?: string; +} + +export async function signInWithIdp( + auth: Auth, + request: SignInWithIdpRequest +): Promise { + return performSignInRequest( + auth, + HttpMethod.POST, + Endpoint.SIGN_IN_WITH_IDP, + request + ); +} \ No newline at end of file diff --git a/packages-exp/auth-exp/src/api/authentication/mfa.test.ts b/packages-exp/auth-exp/src/api/authentication/mfa.test.ts new file mode 100644 index 00000000000..84cd9495419 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/mfa.test.ts @@ -0,0 +1,136 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { startSignInPhoneMfa, finalizeSignInPhoneMfa } from './mfa'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('startSignInPhoneMfa', () => { + const request = { + mfaPendingCredential: 'my-creds', + mfaEnrollmentId: 'my-enrollment-id', + phoneSignInInfo: { + recaptchaToken: 'catpcha-token' + } + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.START_PHONE_MFA_SIGN_IN, { + phoneResponseInfo: { + sessionInfo: 'session-info' + } + }); + + const response = await startSignInPhoneMfa(mockAuth, request); + expect(response.phoneResponseInfo.sessionInfo).to.eq('session-info'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.START_PHONE_MFA_SIGN_IN, + { + error: { + code: 400, + message: ServerError.INVALID_PENDING_TOKEN, + errors: [ + { + message: ServerError.INVALID_PENDING_TOKEN + } + ] + } + }, + 400 + ); + + await expect(startSignInPhoneMfa(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The supplied auth credential is malformed or has expired. (auth/invalid-credential).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('finalizeSignInPhoneMfa', () => { + const request = { + mfaPendingCredential: 'pending-cred', + phoneVerificationInfo: { + temporaryProof: 'proof', + phoneNumber: '123456789', + sessionInfo: 'session-info', + code: 'my-code' + } + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.FINALIZE_PHONE_MFA_SIGN_IN, { + displayName: 'my-name', + idToken: 'id-token' + }); + + const response = await finalizeSignInPhoneMfa(mockAuth, request); + expect(response.displayName).to.eq('my-name'); + expect(response.idToken).to.eq('id-token'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.FINALIZE_PHONE_MFA_SIGN_IN, + { + error: { + code: 400, + message: ServerError.INVALID_CODE, + errors: [ + { + message: ServerError.INVALID_CODE + } + ] + } + }, + 400 + ); + + await expect(finalizeSignInPhoneMfa(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The SMS verification code used to create the phone auth credential is invalid. Please resend the verification code sms and be sure use the verification code provided by the user. (auth/invalid-verification-code).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + diff --git a/packages-exp/auth-exp/src/api/authentication/mfa.ts b/packages-exp/auth-exp/src/api/authentication/mfa.ts new file mode 100644 index 00000000000..baa4ac4bb7a --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/mfa.ts @@ -0,0 +1,51 @@ +import { Auth } from '../../model/auth'; +import { IdTokenResponse } from '../../model/id_token'; +import { HttpMethod, Endpoint, performApiRequest } from '..'; +import { SignInWithPhoneNumberRequest, SignInWithPhoneNumberResponse } from './sms'; +import { SignInWithIdpResponse } from './idp'; + +export interface StartPhoneMfaSignInRequest { + mfaPendingCredential: string; + mfaEnrollmentId: string; + phoneSignInInfo: { + recaptchaToken: string; + }; +} + +export interface StartPhoneMfaSignInResponse { + phoneResponseInfo: { + sessionInfo: string; + }; +} + +export function startSignInPhoneMfa( + auth: Auth, + request: StartPhoneMfaSignInRequest +): Promise { + return performApiRequest< + StartPhoneMfaSignInRequest, + StartPhoneMfaSignInResponse + >(auth, HttpMethod.POST, Endpoint.START_PHONE_MFA_SIGN_IN, request); +} + +export interface FinalizePhoneMfaSignInRequest { + mfaPendingCredential: string; + phoneVerificationInfo: SignInWithPhoneNumberRequest; +} + +export interface FinalizePhoneMfaSignInResponse extends IdTokenResponse {} + +export function finalizeSignInPhoneMfa( + auth: Auth, + request: FinalizePhoneMfaSignInRequest +): Promise { + return performApiRequest< + FinalizePhoneMfaSignInRequest, + FinalizePhoneMfaSignInResponse + >(auth, HttpMethod.POST, Endpoint.FINALIZE_PHONE_MFA_SIGN_IN, request); +} + +export type PhoneOrOauthTokenResponse = + | SignInWithPhoneNumberResponse + | SignInWithIdpResponse + | IdTokenResponse; diff --git a/packages-exp/auth-exp/src/api/authentication/recaptcha.test.ts b/packages-exp/auth-exp/src/api/authentication/recaptcha.test.ts new file mode 100644 index 00000000000..40c120d1d51 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/recaptcha.test.ts @@ -0,0 +1,70 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { getRecaptchaParams } from './recaptcha'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('getRecaptchaParams', () => { + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should GET to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.GET_RECAPTCHA_PARAM, { + recaptchaSiteKey: 'site-key' + }); + + const response = await getRecaptchaParams(mockAuth); + expect(response).to.eq('site-key'); + expect(mock.calls[0].request).to.be.undefined; + expect(mock.calls[0].method).to.eq('GET'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.GET_RECAPTCHA_PARAM, + { + error: { + code: 400, + message: ServerError.TOO_MANY_ATTEMPTS_TRY_LATER, + errors: [ + { + message: ServerError.TOO_MANY_ATTEMPTS_TRY_LATER + } + ] + } + }, + 400 + ); + + await expect(getRecaptchaParams(mockAuth)).to.be.rejectedWith( + FirebaseError, + 'Firebase: We have blocked all requests from this device due to unusual activity. Try again later. (auth/too-many-requests).' + ); + expect(mock.calls[0].request).to.be.undefined; + }); +}); diff --git a/packages-exp/auth-exp/src/api/authentication/recaptcha.ts b/packages-exp/auth-exp/src/api/authentication/recaptcha.ts new file mode 100644 index 00000000000..325a8827318 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/recaptcha.ts @@ -0,0 +1,18 @@ +import { Auth } from '../../model/auth'; +import { HttpMethod, Endpoint, performApiRequest } from '..'; + +interface GetRecaptchaParamResponse { + recaptchaSiteKey?: string; +} + +export async function getRecaptchaParams(auth: Auth): Promise { + return ( + ( + await performApiRequest( + auth, + HttpMethod.GET, + Endpoint.GET_RECAPTCHA_PARAM + ) + ).recaptchaSiteKey || '' + ); +} \ No newline at end of file diff --git a/packages-exp/auth-exp/src/api/authentication/sign_up.test.ts b/packages-exp/auth-exp/src/api/authentication/sign_up.test.ts index 6b7b258f30d..7f1acac36a7 100644 --- a/packages-exp/auth-exp/src/api/authentication/sign_up.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/sign_up.test.ts @@ -17,7 +17,7 @@ import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { signUp, SignUpRequest } from './sign_up'; +import { signUp } from './sign_up'; import { Endpoint } from '..'; import { ServerError } from '../errors'; import { FirebaseError } from '@firebase/util'; @@ -28,7 +28,7 @@ import { mockAuth } from '../../../test/mock_auth'; use(chaiAsPromised); describe('signUp', () => { - const request: SignUpRequest = { + const request = { returnSecureToken: true, email: 'test@foo.com', password: 'my-password' diff --git a/packages-exp/auth-exp/src/api/authentication/sms.test.ts b/packages-exp/auth-exp/src/api/authentication/sms.test.ts new file mode 100644 index 00000000000..032d25c2192 --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/sms.test.ts @@ -0,0 +1,251 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { sendPhoneVerificationCode, signInWithPhoneNumber, linkWithPhoneNumber, verifyPhoneNumberForExisting } from './sms'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ProviderId } from '../../core/providers'; + +use(chaiAsPromised); + +describe('sendPhoneVerificationCode', () => { + const request = { + phoneNumber: '123456789', + recaptchaToken: 'captchad' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SEND_VERIFICATION_CODE, { + sessionInfo: 'my-session' + }); + + const response = await sendPhoneVerificationCode(mockAuth, request); + expect(response.sessionInfo).to.eq('my-session'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SEND_VERIFICATION_CODE, + { + error: { + code: 400, + message: ServerError.INVALID_PHONE_NUMBER, + errors: [ + { + message: ServerError.INVALID_PHONE_NUMBER + } + ] + } + }, + 400 + ); + + await expect(sendPhoneVerificationCode(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The format of the phone number provided is incorrect. Please enter the phone number in a format that can be parsed into E.164 format. E.164 phone numbers are written in the format [+,[country code,[subscriber number including area code,. (auth/invalid-phone-number).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('signInWithPhoneNumber', () => { + const request = { + temporaryProof: 'my-proof', + phoneNumber: '1234567', + sessionInfo: 'my-session', + code: 'my-code' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SIGN_IN_WITH_PHONE_NUMBER, { + providerId: ProviderId.PHONE, + idToken: 'id-token', + refreshToken: 'refresh-token', + expiresIn: '1000', + localId: '1234' + }); + + const response = await signInWithPhoneNumber(mockAuth, request); + expect(response.providerId).to.eq(ProviderId.PHONE); + expect(response.idToken).to.eq('id-token'); + expect(response.expiresIn).to.eq('1000'); + expect(response.localId).to.eq('1234'); expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SIGN_IN_WITH_PHONE_NUMBER, + { + error: { + code: 400, + message: ServerError.INVALID_CODE, + errors: [ + { + message: ServerError.INVALID_CODE + } + ] + } + }, + 400 + ); + + await expect(signInWithPhoneNumber(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The SMS verification code used to create the phone auth credential is invalid. Please resend the verification code sms and be sure use the verification code provided by the user. (auth/invalid-verification-code).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('linkWithPhoneNumber', () => { + const request = { + idToken: 'id-token', + temporaryProof: 'my-proof', + phoneNumber: '1234567', + sessionInfo: 'my-session', + code: 'my-code' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SIGN_IN_WITH_PHONE_NUMBER, { + providerId: ProviderId.PHONE, + idToken: 'id-token', + refreshToken: 'refresh-token', + expiresIn: '1000', + localId: '1234' + }); + + const response = await linkWithPhoneNumber(mockAuth, request); + expect(response.providerId).to.eq(ProviderId.PHONE); + expect(response.idToken).to.eq('id-token'); + expect(response.expiresIn).to.eq('1000'); + expect(response.localId).to.eq('1234'); expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SIGN_IN_WITH_PHONE_NUMBER, + { + error: { + code: 400, + message: ServerError.INVALID_CODE, + errors: [ + { + message: ServerError.INVALID_CODE + } + ] + } + }, + 400 + ); + + await expect(linkWithPhoneNumber(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The SMS verification code used to create the phone auth credential is invalid. Please resend the verification code sms and be sure use the verification code provided by the user. (auth/invalid-verification-code).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('verifyPhoneNumberForExisting', () => { + const request = { + temporaryProof: 'my-proof', + phoneNumber: '1234567', + sessionInfo: 'my-session', + code: 'my-code' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SIGN_IN_WITH_PHONE_NUMBER, { + providerId: ProviderId.PHONE, + idToken: 'id-token', + refreshToken: 'refresh-token', + expiresIn: '1000', + localId: '1234' + }); + + const response = await verifyPhoneNumberForExisting(mockAuth, request); + expect(response.providerId).to.eq(ProviderId.PHONE); + expect(response.idToken).to.eq('id-token'); + expect(response.expiresIn).to.eq('1000'); + expect(response.localId).to.eq('1234'); expect(mock.calls[0].request).to.eql({ + ...request, + operation: 'REAUTH' + }); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle custom errors', async () => { + const mock = mockEndpoint( + Endpoint.SIGN_IN_WITH_PHONE_NUMBER, + { + error: { + code: 400, + message: ServerError.USER_NOT_FOUND, + errors: [ + { + message: ServerError.USER_NOT_FOUND + } + ] + } + }, + 400 + ); + + await expect(verifyPhoneNumberForExisting(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: There is no user record corresponding to this identifier. The user may have been deleted. (auth/user-not-found).' + ); + expect(mock.calls[0].request).to.eql({ + ...request, + operation: 'REAUTH' + }); + }); +}); diff --git a/packages-exp/auth-exp/src/api/authentication/sms.ts b/packages-exp/auth-exp/src/api/authentication/sms.ts new file mode 100644 index 00000000000..bdc8782405f --- /dev/null +++ b/packages-exp/auth-exp/src/api/authentication/sms.ts @@ -0,0 +1,92 @@ +import { Auth } from '../../model/auth'; +import { IdTokenResponse } from '../../model/id_token'; +import { performSignInRequest, HttpMethod, Endpoint, performApiRequest } from '..'; +import { ServerErrorMap, ServerError } from '../errors'; +import { AuthErrorCode } from '../../core/errors'; + +export interface SendPhoneVerificationCodeRequest { + phoneNumber: string; + recaptchaToken: string; +} + +export interface SendPhoneVerificationCodeResponse { + sessionInfo: string; +} + +export async function sendPhoneVerificationCode( + auth: Auth, + request: SendPhoneVerificationCodeRequest +): Promise { + return performApiRequest< + SendPhoneVerificationCodeRequest, + SendPhoneVerificationCodeResponse + >(auth, HttpMethod.POST, Endpoint.SEND_VERIFICATION_CODE, request); +} + +export interface SignInWithPhoneNumberRequest { + temporaryProof?: string; + phoneNumber?: string; + sessionInfo?: string; + code?: string; +} + +export interface LinkWithPhoneNumberRequest + extends SignInWithPhoneNumberRequest { + idToken: string; +} + +export interface SignInWithPhoneNumberResponse extends IdTokenResponse { + temporaryProof?: string; + phoneNumber?: string; +} + +export async function signInWithPhoneNumber( + auth: Auth, + request: SignInWithPhoneNumberRequest +): Promise { + return performSignInRequest< + SignInWithPhoneNumberRequest, + SignInWithPhoneNumberResponse + >(auth, HttpMethod.POST, Endpoint.SIGN_IN_WITH_PHONE_NUMBER, request); +} + +export async function linkWithPhoneNumber( + auth: Auth, + request: LinkWithPhoneNumberRequest +): Promise { + return performSignInRequest< + LinkWithPhoneNumberRequest, + SignInWithPhoneNumberResponse + >(auth, HttpMethod.POST, Endpoint.SIGN_IN_WITH_PHONE_NUMBER, request); +} + +interface VerifyPhoneNumberForExistingRequest + extends SignInWithPhoneNumberRequest { + operation: 'REAUTH'; +} + +const VERIFY_PHONE_NUMBER_FOR_EXISTING_ERROR_MAP_: Partial> = { + [ServerError.USER_NOT_FOUND]: AuthErrorCode.USER_DELETED +}; + +export async function verifyPhoneNumberForExisting( + auth: Auth, + request: SignInWithPhoneNumberRequest +): Promise { + const apiRequest: VerifyPhoneNumberForExistingRequest = { + ...request, + operation: 'REAUTH' + }; + return performSignInRequest< + VerifyPhoneNumberForExistingRequest, + SignInWithPhoneNumberResponse + >( + auth, + HttpMethod.POST, + Endpoint.SIGN_IN_WITH_PHONE_NUMBER, + apiRequest, + VERIFY_PHONE_NUMBER_FOR_EXISTING_ERROR_MAP_ + ); +} From b1d5664009b3a39ece383e5ef067b322b24c378e Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Mon, 13 Apr 2020 15:18:17 -0700 Subject: [PATCH 06/14] [AUTOMATED]: Prettier Code Styling --- .../account_management/email_and_password.ts | 2 +- .../src/api/account_management/mfa.ts | 6 ++-- .../src/api/authentication/create_auth_uri.ts | 2 +- .../src/api/authentication/custom_token.ts | 2 +- .../authentication/email_and_password.test.ts | 17 +++++++++-- .../api/authentication/email_and_password.ts | 30 ++++++++++++++----- .../auth-exp/src/api/authentication/idp.ts | 2 +- .../src/api/authentication/mfa.test.ts | 1 - .../auth-exp/src/api/authentication/mfa.ts | 5 +++- .../src/api/authentication/recaptcha.ts | 2 +- .../src/api/authentication/sms.test.ts | 24 +++++++++++---- .../auth-exp/src/api/authentication/sms.ts | 7 ++++- 12 files changed, 72 insertions(+), 28 deletions(-) diff --git a/packages-exp/auth-exp/src/api/account_management/email_and_password.ts b/packages-exp/auth-exp/src/api/account_management/email_and_password.ts index 8334d0d75d0..edf826439df 100644 --- a/packages-exp/auth-exp/src/api/account_management/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/account_management/email_and_password.ts @@ -32,7 +32,7 @@ export interface UpdateEmailPasswordRequest { password?: string; } -export interface UpdateEmailPasswordResponse extends IdTokenResponse { } +export interface UpdateEmailPasswordResponse extends IdTokenResponse {} export async function updateEmailPassword( auth: Auth, diff --git a/packages-exp/auth-exp/src/api/account_management/mfa.ts b/packages-exp/auth-exp/src/api/account_management/mfa.ts index e775ff5ed19..0a00d52136d 100644 --- a/packages-exp/auth-exp/src/api/account_management/mfa.ts +++ b/packages-exp/auth-exp/src/api/account_management/mfa.ts @@ -32,7 +32,7 @@ export interface PhoneMfaEnrollmentRequest { phoneVerificationInfo: SignInWithPhoneNumberRequest; } -export interface PhoneMfaEnrollmentResponse extends IdTokenResponse { } +export interface PhoneMfaEnrollmentResponse extends IdTokenResponse {} export function enrollPhoneMfa( auth: Auth, @@ -49,7 +49,7 @@ export interface WithdrawMfaRequest { mfaEnrollmentId: string; } -export interface WithdrawMfaResponse extends IdTokenResponse { } +export interface WithdrawMfaResponse extends IdTokenResponse {} export function withdrawMfa( auth: Auth, @@ -61,4 +61,4 @@ export function withdrawMfa( Endpoint.WITHDRAW_MFA, request ); -} \ No newline at end of file +} diff --git a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts index 09433bfefc8..060284dabd2 100644 --- a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts +++ b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts @@ -20,4 +20,4 @@ export async function createAuthUri( Endpoint.CREATE_AUTH_URI, request ); -} \ No newline at end of file +} diff --git a/packages-exp/auth-exp/src/api/authentication/custom_token.ts b/packages-exp/auth-exp/src/api/authentication/custom_token.ts index 4b5211d5148..2866ec12d83 100644 --- a/packages-exp/auth-exp/src/api/authentication/custom_token.ts +++ b/packages-exp/auth-exp/src/api/authentication/custom_token.ts @@ -16,4 +16,4 @@ export async function signInWithCustomToken( SignInWithCustomTokenRequest, SignInWithCustomTokenResponse >(auth, HttpMethod.POST, Endpoint.SIGN_IN_WITH_CUSTOM_TOKEN, request); -} \ No newline at end of file +} diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts index 576fe206cab..a300170985c 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts @@ -17,7 +17,16 @@ import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { signInWithPassword, sendPasswordResetEmail, sendEmailVerification, sendSignInLinkToEmail, GetOobCodeRequestType, VerifyEmailRequest, PasswordResetRequest, EmailSignInRequest } from './email_and_password'; +import { + signInWithPassword, + sendPasswordResetEmail, + sendEmailVerification, + sendSignInLinkToEmail, + GetOobCodeRequestType, + VerifyEmailRequest, + PasswordResetRequest, + EmailSignInRequest +} from './email_and_password'; import { Endpoint } from '..'; import { ServerError } from '../errors'; import { FirebaseError } from '@firebase/util'; @@ -166,7 +175,9 @@ describe('sendOobCode', () => { 400 ); - await expect(sendPasswordResetEmail(mockAuth, request)).to.be.rejectedWith( + await expect( + sendPasswordResetEmail(mockAuth, request) + ).to.be.rejectedWith( FirebaseError, 'Firebase: The email address is badly formatted. (auth/invalid-email).' ); @@ -221,4 +232,4 @@ describe('sendOobCode', () => { expect(mock.calls[0].request).to.eql(request); }); }); -}); \ No newline at end of file +}); diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts index 6c0bb79c432..f0097cd589b 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts @@ -1,6 +1,11 @@ import { Auth } from '../../model/auth'; import { IdTokenResponse, IdToken } from '../../model/id_token'; -import { performSignInRequest, HttpMethod, Endpoint, performApiRequest } from '..'; +import { + performSignInRequest, + HttpMethod, + Endpoint, + performApiRequest +} from '..'; export interface SignInWithPasswordRequest { returnSecureToken?: boolean; @@ -67,9 +72,9 @@ interface GetOobCodeResponse { email: string; } -export interface VerifyEmailResponse extends GetOobCodeResponse {}; -export interface PasswordResetResponse extends GetOobCodeResponse { }; -export interface EmailSignInResponse extends GetOobCodeResponse { }; +export interface VerifyEmailResponse extends GetOobCodeResponse {} +export interface PasswordResetResponse extends GetOobCodeResponse {} +export interface EmailSignInResponse extends GetOobCodeResponse {} async function sendOobCode( auth: Auth, @@ -83,14 +88,23 @@ async function sendOobCode( ); } -export async function sendEmailVerification(auth: Auth, request: VerifyEmailRequest): Promise { +export async function sendEmailVerification( + auth: Auth, + request: VerifyEmailRequest +): Promise { return sendOobCode(auth, request); } -export async function sendPasswordResetEmail(auth: Auth, request: PasswordResetRequest): Promise { +export async function sendPasswordResetEmail( + auth: Auth, + request: PasswordResetRequest +): Promise { return sendOobCode(auth, request); } -export async function sendSignInLinkToEmail(auth: Auth, request: EmailSignInRequest): Promise { +export async function sendSignInLinkToEmail( + auth: Auth, + request: EmailSignInRequest +): Promise { return sendOobCode(auth, request); -} \ No newline at end of file +} diff --git a/packages-exp/auth-exp/src/api/authentication/idp.ts b/packages-exp/auth-exp/src/api/authentication/idp.ts index 54941530dd5..b3d870c1e6d 100644 --- a/packages-exp/auth-exp/src/api/authentication/idp.ts +++ b/packages-exp/auth-exp/src/api/authentication/idp.ts @@ -31,4 +31,4 @@ export async function signInWithIdp( Endpoint.SIGN_IN_WITH_IDP, request ); -} \ No newline at end of file +} diff --git a/packages-exp/auth-exp/src/api/authentication/mfa.test.ts b/packages-exp/auth-exp/src/api/authentication/mfa.test.ts index 84cd9495419..5ab192a2c31 100644 --- a/packages-exp/auth-exp/src/api/authentication/mfa.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/mfa.test.ts @@ -133,4 +133,3 @@ describe('finalizeSignInPhoneMfa', () => { expect(mock.calls[0].request).to.eql(request); }); }); - diff --git a/packages-exp/auth-exp/src/api/authentication/mfa.ts b/packages-exp/auth-exp/src/api/authentication/mfa.ts index baa4ac4bb7a..7f68f04b591 100644 --- a/packages-exp/auth-exp/src/api/authentication/mfa.ts +++ b/packages-exp/auth-exp/src/api/authentication/mfa.ts @@ -1,7 +1,10 @@ import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; import { HttpMethod, Endpoint, performApiRequest } from '..'; -import { SignInWithPhoneNumberRequest, SignInWithPhoneNumberResponse } from './sms'; +import { + SignInWithPhoneNumberRequest, + SignInWithPhoneNumberResponse +} from './sms'; import { SignInWithIdpResponse } from './idp'; export interface StartPhoneMfaSignInRequest { diff --git a/packages-exp/auth-exp/src/api/authentication/recaptcha.ts b/packages-exp/auth-exp/src/api/authentication/recaptcha.ts index 325a8827318..7e5695b9e56 100644 --- a/packages-exp/auth-exp/src/api/authentication/recaptcha.ts +++ b/packages-exp/auth-exp/src/api/authentication/recaptcha.ts @@ -15,4 +15,4 @@ export async function getRecaptchaParams(auth: Auth): Promise { ) ).recaptchaSiteKey || '' ); -} \ No newline at end of file +} diff --git a/packages-exp/auth-exp/src/api/authentication/sms.test.ts b/packages-exp/auth-exp/src/api/authentication/sms.test.ts index 032d25c2192..9297cb82ddf 100644 --- a/packages-exp/auth-exp/src/api/authentication/sms.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/sms.test.ts @@ -17,7 +17,12 @@ import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { sendPhoneVerificationCode, signInWithPhoneNumber, linkWithPhoneNumber, verifyPhoneNumberForExisting } from './sms'; +import { + sendPhoneVerificationCode, + signInWithPhoneNumber, + linkWithPhoneNumber, + verifyPhoneNumberForExisting +} from './sms'; import { Endpoint } from '..'; import { ServerError } from '../errors'; import { FirebaseError } from '@firebase/util'; @@ -67,7 +72,9 @@ describe('sendPhoneVerificationCode', () => { 400 ); - await expect(sendPhoneVerificationCode(mockAuth, request)).to.be.rejectedWith( + await expect( + sendPhoneVerificationCode(mockAuth, request) + ).to.be.rejectedWith( FirebaseError, 'Firebase: The format of the phone number provided is incorrect. Please enter the phone number in a format that can be parsed into E.164 format. E.164 phone numbers are written in the format [+,[country code,[subscriber number including area code,. (auth/invalid-phone-number).' ); @@ -99,7 +106,8 @@ describe('signInWithPhoneNumber', () => { expect(response.providerId).to.eq(ProviderId.PHONE); expect(response.idToken).to.eq('id-token'); expect(response.expiresIn).to.eq('1000'); - expect(response.localId).to.eq('1234'); expect(mock.calls[0].request).to.eql(request); + expect(response.localId).to.eq('1234'); + expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ 'Content-Type': 'application/json' @@ -156,7 +164,8 @@ describe('linkWithPhoneNumber', () => { expect(response.providerId).to.eq(ProviderId.PHONE); expect(response.idToken).to.eq('id-token'); expect(response.expiresIn).to.eq('1000'); - expect(response.localId).to.eq('1234'); expect(mock.calls[0].request).to.eql(request); + expect(response.localId).to.eq('1234'); + expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ 'Content-Type': 'application/json' @@ -212,7 +221,8 @@ describe('verifyPhoneNumberForExisting', () => { expect(response.providerId).to.eq(ProviderId.PHONE); expect(response.idToken).to.eq('id-token'); expect(response.expiresIn).to.eq('1000'); - expect(response.localId).to.eq('1234'); expect(mock.calls[0].request).to.eql({ + expect(response.localId).to.eq('1234'); + expect(mock.calls[0].request).to.eql({ ...request, operation: 'REAUTH' }); @@ -239,7 +249,9 @@ describe('verifyPhoneNumberForExisting', () => { 400 ); - await expect(verifyPhoneNumberForExisting(mockAuth, request)).to.be.rejectedWith( + await expect( + verifyPhoneNumberForExisting(mockAuth, request) + ).to.be.rejectedWith( FirebaseError, 'Firebase: There is no user record corresponding to this identifier. The user may have been deleted. (auth/user-not-found).' ); diff --git a/packages-exp/auth-exp/src/api/authentication/sms.ts b/packages-exp/auth-exp/src/api/authentication/sms.ts index bdc8782405f..6af24fdde1d 100644 --- a/packages-exp/auth-exp/src/api/authentication/sms.ts +++ b/packages-exp/auth-exp/src/api/authentication/sms.ts @@ -1,6 +1,11 @@ import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; -import { performSignInRequest, HttpMethod, Endpoint, performApiRequest } from '..'; +import { + performSignInRequest, + HttpMethod, + Endpoint, + performApiRequest +} from '..'; import { ServerErrorMap, ServerError } from '../errors'; import { AuthErrorCode } from '../../core/errors'; From 1ac918f4617796f10705bdac3de960909d504c9f Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Mon, 13 Apr 2020 15:18:18 -0700 Subject: [PATCH 07/14] [AUTOMATED]: License Headers --- .../src/api/account_management/account.ts | 2 +- .../account_management/email_and_password.ts | 17 +++++++++++++++++ .../auth-exp/src/api/account_management/mfa.ts | 17 +++++++++++++++++ .../src/api/account_management/profile.ts | 17 +++++++++++++++++ .../src/api/authentication/create_auth_uri.ts | 17 +++++++++++++++++ .../src/api/authentication/custom_token.ts | 17 +++++++++++++++++ .../api/authentication/email_and_password.ts | 17 +++++++++++++++++ .../src/api/authentication/email_link.ts | 17 +++++++++++++++++ .../auth-exp/src/api/authentication/idp.ts | 17 +++++++++++++++++ .../auth-exp/src/api/authentication/mfa.ts | 17 +++++++++++++++++ .../src/api/authentication/recaptcha.ts | 17 +++++++++++++++++ .../auth-exp/src/api/authentication/sms.ts | 17 +++++++++++++++++ 12 files changed, 188 insertions(+), 1 deletion(-) diff --git a/packages-exp/auth-exp/src/api/account_management/account.ts b/packages-exp/auth-exp/src/api/account_management/account.ts index 44a40c69fad..ddde7dd003e 100644 --- a/packages-exp/auth-exp/src/api/account_management/account.ts +++ b/packages-exp/auth-exp/src/api/account_management/account.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2020 Google Inc. + * 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. diff --git a/packages-exp/auth-exp/src/api/account_management/email_and_password.ts b/packages-exp/auth-exp/src/api/account_management/email_and_password.ts index edf826439df..cf65b061ae8 100644 --- a/packages-exp/auth-exp/src/api/account_management/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/account_management/email_and_password.ts @@ -1,3 +1,20 @@ +/** + * @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 { performApiRequest, Endpoint, HttpMethod } from '..'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; diff --git a/packages-exp/auth-exp/src/api/account_management/mfa.ts b/packages-exp/auth-exp/src/api/account_management/mfa.ts index 0a00d52136d..ad28d3da696 100644 --- a/packages-exp/auth-exp/src/api/account_management/mfa.ts +++ b/packages-exp/auth-exp/src/api/account_management/mfa.ts @@ -1,3 +1,20 @@ +/** + * @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 { Endpoint, HttpMethod, performApiRequest } from '..'; import { SignInWithPhoneNumberRequest } from '../authentication/sms'; import { IdTokenResponse } from '../../model/id_token'; diff --git a/packages-exp/auth-exp/src/api/account_management/profile.ts b/packages-exp/auth-exp/src/api/account_management/profile.ts index 5feb6999b83..46948ddd251 100644 --- a/packages-exp/auth-exp/src/api/account_management/profile.ts +++ b/packages-exp/auth-exp/src/api/account_management/profile.ts @@ -1,3 +1,20 @@ +/** + * @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 { IdTokenResponse } from '../../model/id_token'; import { Auth } from '../../model/auth'; import { performApiRequest, HttpMethod, Endpoint } from '..'; diff --git a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts index 060284dabd2..1d156176beb 100644 --- a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts +++ b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts @@ -1,3 +1,20 @@ +/** + * @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 { Auth } from '../../model/auth'; import { performApiRequest, HttpMethod, Endpoint } from '..'; diff --git a/packages-exp/auth-exp/src/api/authentication/custom_token.ts b/packages-exp/auth-exp/src/api/authentication/custom_token.ts index 2866ec12d83..389ef2f1b1b 100644 --- a/packages-exp/auth-exp/src/api/authentication/custom_token.ts +++ b/packages-exp/auth-exp/src/api/authentication/custom_token.ts @@ -1,3 +1,20 @@ +/** + * @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 { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; import { performSignInRequest, HttpMethod, Endpoint } from '..'; diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts index f0097cd589b..733958d47c8 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts @@ -1,3 +1,20 @@ +/** + * @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 { Auth } from '../../model/auth'; import { IdTokenResponse, IdToken } from '../../model/id_token'; import { diff --git a/packages-exp/auth-exp/src/api/authentication/email_link.ts b/packages-exp/auth-exp/src/api/authentication/email_link.ts index fbec634db41..e358e791171 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_link.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_link.ts @@ -1,3 +1,20 @@ +/** + * @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 { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; import { performSignInRequest, HttpMethod, Endpoint } from '..'; diff --git a/packages-exp/auth-exp/src/api/authentication/idp.ts b/packages-exp/auth-exp/src/api/authentication/idp.ts index b3d870c1e6d..d9e7138aa91 100644 --- a/packages-exp/auth-exp/src/api/authentication/idp.ts +++ b/packages-exp/auth-exp/src/api/authentication/idp.ts @@ -1,3 +1,20 @@ +/** + * @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 { Auth } from '../../model/auth'; import { IdToken, IdTokenResponse } from '../../model/id_token'; import { performSignInRequest, HttpMethod, Endpoint } from '..'; diff --git a/packages-exp/auth-exp/src/api/authentication/mfa.ts b/packages-exp/auth-exp/src/api/authentication/mfa.ts index 7f68f04b591..f83341da87f 100644 --- a/packages-exp/auth-exp/src/api/authentication/mfa.ts +++ b/packages-exp/auth-exp/src/api/authentication/mfa.ts @@ -1,3 +1,20 @@ +/** + * @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 { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; import { HttpMethod, Endpoint, performApiRequest } from '..'; diff --git a/packages-exp/auth-exp/src/api/authentication/recaptcha.ts b/packages-exp/auth-exp/src/api/authentication/recaptcha.ts index 7e5695b9e56..25e172663da 100644 --- a/packages-exp/auth-exp/src/api/authentication/recaptcha.ts +++ b/packages-exp/auth-exp/src/api/authentication/recaptcha.ts @@ -1,3 +1,20 @@ +/** + * @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 { Auth } from '../../model/auth'; import { HttpMethod, Endpoint, performApiRequest } from '..'; diff --git a/packages-exp/auth-exp/src/api/authentication/sms.ts b/packages-exp/auth-exp/src/api/authentication/sms.ts index 6af24fdde1d..5e0fd545492 100644 --- a/packages-exp/auth-exp/src/api/authentication/sms.ts +++ b/packages-exp/auth-exp/src/api/authentication/sms.ts @@ -1,3 +1,20 @@ +/** + * @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 { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; import { From 97114a946d6471e5f8d2a1e289c9876e497c3bf4 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Tue, 14 Apr 2020 12:09:45 -0700 Subject: [PATCH 08/14] Add more tests to account API methods --- .../api/account_management/account.test.ts | 175 +++++++++++++++++ .../src/api/account_management/account.ts | 18 +- .../email_and_password.test.ts | 127 ++++++++++++ .../src/api/account_management/mfa.test.ts | 184 ++++++++++++++++++ .../api/account_management/profile.test.ts | 77 ++++++++ .../api/authentication/email_and_password.ts | 10 +- 6 files changed, 576 insertions(+), 15 deletions(-) create mode 100644 packages-exp/auth-exp/src/api/account_management/account.test.ts create mode 100644 packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts create mode 100644 packages-exp/auth-exp/src/api/account_management/mfa.test.ts create mode 100644 packages-exp/auth-exp/src/api/account_management/profile.test.ts diff --git a/packages-exp/auth-exp/src/api/account_management/account.test.ts b/packages-exp/auth-exp/src/api/account_management/account.test.ts new file mode 100644 index 00000000000..58aea550772 --- /dev/null +++ b/packages-exp/auth-exp/src/api/account_management/account.test.ts @@ -0,0 +1,175 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { deleteAccount, deleteLinkedAccounts, getAccountInfo } from './account'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ProviderId } from '../../core/providers'; + +use(chaiAsPromised); + +describe('deleteAccount', () => { + const request = { + idToken: 'id-token' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.DELETE_ACCOUNT, {}); + + await deleteAccount(mockAuth, request); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.DELETE_ACCOUNT, + { + error: { + code: 400, + message: ServerError.INVALID_ID_TOKEN, + errors: [ + { + message: ServerError.INVALID_ID_TOKEN + } + ] + } + }, + 400 + ); + + await expect(deleteAccount(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: This user\'s credential isn\'t valid for this project. This can happen if the user\'s token has been tampered with]: or if the user isn\'t for the project associated with this API key. (auth/invalid-user-token).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('deleteLinkedAccounts', () => { + const request = { + idToken: 'id-token', + deleteProvider: [ProviderId.GOOGLE] + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SET_ACCOUNT_INFO, { + providerUserInfo: [{ + providerId: ProviderId.GOOGLE, + email: 'test@foo.com' + }] + }); + + const response = await deleteLinkedAccounts(mockAuth, request); + expect(response.providerUserInfo[0].providerId).to.eq('google.com'); + expect(response.providerUserInfo[0].email).to.eq('test@foo.com'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SET_ACCOUNT_INFO, + { + error: { + code: 400, + message: ServerError.INVALID_PROVIDER_ID, + errors: [ + { + message: ServerError.INVALID_PROVIDER_ID + } + ] + } + }, + 400 + ); + + await expect(deleteLinkedAccounts(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The specified provider ID is invalid. (auth/invalid-provider-id).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('getAccountInfo', () => { + const request = { + idToken: 'id-token' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.GET_ACCOUNT_INFO, { + users: [{ + displayName: 'my-name', + email: 'test@foo.com' + }] + }); + + const response = await getAccountInfo(mockAuth, request); + expect(response.users[0].displayName).to.eq('my-name'); + expect(response.users[0].email).to.eq('test@foo.com'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.GET_ACCOUNT_INFO, + { + error: { + code: 400, + message: ServerError.INVALID_ID_TOKEN, + errors: [ + { + message: ServerError.INVALID_ID_TOKEN + } + ] + } + }, + 400 + ); + + await expect(getAccountInfo(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: This user\'s credential isn\'t valid for this project. This can happen if the user\'s token has been tampered with]: or if the user isn\'t for the project associated with this API key. (auth/invalid-user-token).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); diff --git a/packages-exp/auth-exp/src/api/account_management/account.ts b/packages-exp/auth-exp/src/api/account_management/account.ts index ddde7dd003e..ab790ceba90 100644 --- a/packages-exp/auth-exp/src/api/account_management/account.ts +++ b/packages-exp/auth-exp/src/api/account_management/account.ts @@ -35,6 +35,15 @@ export async function deleteAccount( ); } +export interface ProviderUserInfo { + rawId?: string; + providerId?: string; + email?: string; + displayName?: string; + photoUrl?: string; + phoneNumber?: string; +} + export interface DeleteLinkedAccountsRequest { idToken: string; deleteProvider: string[]; @@ -69,15 +78,6 @@ export interface APIUserInfo { mfaInfo?: APIMFAInfo[]; } -export interface ProviderUserInfo { - rawId?: string; - providerId?: string; - email?: string; - displayName?: string; - photoUrl?: string; - phoneNumber?: string; -} - export interface GetAccountInfoRequest { idToken: string; } diff --git a/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts b/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts new file mode 100644 index 00000000000..3eacf7fa9b9 --- /dev/null +++ b/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts @@ -0,0 +1,127 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { resetPassword, updateEmailPassword } from './email_and_password'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('resetPassword', () => { + const request = { + oobCode: 'oob-code', + newPassword: 'new-password' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.RESET_PASSWORD, { + email: 'test@foo.com' + }); + + const response = await resetPassword(mockAuth, request); + expect(response.email).to.eq('test@foo.com'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.RESET_PASSWORD, + { + error: { + code: 400, + message: ServerError.RESET_PASSWORD_EXCEED_LIMIT, + errors: [ + { + message: ServerError.RESET_PASSWORD_EXCEED_LIMIT + } + ] + } + }, + 400 + ); + + await expect(resetPassword(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: We have blocked all requests from this device due to unusual activity. Try again later. (auth/too-many-requests).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + + +describe('updateEmailPassword', () => { + const request = { + idToken: 'id-token', + returnSecureToken: true, + email: 'test@foo.com', + password: 'new-password' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SET_ACCOUNT_INFO, { + idToken: 'id-token' + }); + + const response = await updateEmailPassword(mockAuth, request); + expect(response.idToken).to.eq('id-token'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SET_ACCOUNT_INFO, + { + error: { + code: 400, + message: ServerError.INVALID_EMAIL, + errors: [ + { + message: ServerError.INVALID_EMAIL + } + ] + } + }, + 400 + ); + + await expect(updateEmailPassword(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The email address is badly formatted. (auth/invalid-email).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + diff --git a/packages-exp/auth-exp/src/api/account_management/mfa.test.ts b/packages-exp/auth-exp/src/api/account_management/mfa.test.ts new file mode 100644 index 00000000000..4f2b828734c --- /dev/null +++ b/packages-exp/auth-exp/src/api/account_management/mfa.test.ts @@ -0,0 +1,184 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { startEnrollPhoneMfa, enrollPhoneMfa, withdrawMfa } from './mfa'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('startEnrollPhoneMfa', () => { + const request = { + idToken: 'id-token', + phoneEnrollmentInfo: { + phoneNumber: 'phone-number', + recaptchaToken: 'captcha-token' + } + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.START_PHONE_MFA_ENROLLMENT, { + phoneSessionInfo: { + sessionInfo: 'session-info' + } + }); + + const response = await startEnrollPhoneMfa(mockAuth, request); + expect(response.phoneSessionInfo.sessionInfo).to.eq('session-info'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.START_PHONE_MFA_ENROLLMENT, + { + error: { + code: 400, + message: ServerError.INVALID_ID_TOKEN, + errors: [ + { + message: ServerError.INVALID_ID_TOKEN + } + ] + } + }, + 400 + ); + + await expect(startEnrollPhoneMfa(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: This user\'s credential isn\'t valid for this project. This can happen if the user\'s token has been tampered with]: or if the user isn\'t for the project associated with this API key. (auth/invalid-user-token).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('enrollPhoneMfa', () => { + const request = { + phoneVerificationInfo: { + temporaryProof: 'temporary-proof', + phoneNumber: 'phone-number', + sessionInfo: 'session-info', + code: 'code' + } + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.FINALIZE_PHONE_MFA_ENROLLMENT, { + displayName: 'my-name', + idToken: 'id-token' + }); + + const response = await enrollPhoneMfa(mockAuth, request); + expect(response.displayName).to.eq('my-name'); + expect(response.idToken).to.eq('id-token'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.FINALIZE_PHONE_MFA_ENROLLMENT, + { + error: { + code: 400, + message: ServerError.INVALID_SESSION_INFO, + errors: [ + { + message: ServerError.INVALID_SESSION_INFO + } + ] + } + }, + 400 + ); + + await expect(enrollPhoneMfa(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The verification ID used to create the phone auth credential is invalid. (auth/invalid-verification-id).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); + +describe('withdrawMfa', () => { + const request = { + idToken: 'id-token', + mfaEnrollmentId: 'mfa-enrollment-id' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.WITHDRAW_MFA, { + displayName: 'my-name', + idToken: 'id-token' + }); + + const response = await withdrawMfa(mockAuth, request); + expect(response.displayName).to.eq('my-name'); + expect(response.idToken).to.eq('id-token'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.WITHDRAW_MFA, + { + error: { + code: 400, + message: ServerError.INVALID_ID_TOKEN, + errors: [ + { + message: ServerError.INVALID_ID_TOKEN + } + ] + } + }, + 400 + ); + + await expect(withdrawMfa(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: This user\'s credential isn\'t valid for this project. This can happen if the user\'s token has been tampered with]: or if the user isn\'t for the project associated with this API key. (auth/invalid-user-token).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); diff --git a/packages-exp/auth-exp/src/api/account_management/profile.test.ts b/packages-exp/auth-exp/src/api/account_management/profile.test.ts new file mode 100644 index 00000000000..855f4c153f1 --- /dev/null +++ b/packages-exp/auth-exp/src/api/account_management/profile.test.ts @@ -0,0 +1,77 @@ +/** + * @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 { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import { updateProfile } from './profile'; +import { Endpoint } from '..'; +import { ServerError } from '../errors'; +import { FirebaseError } from '@firebase/util'; +import * as mockFetch from '../../../test/mock_fetch'; +import { mockEndpoint, mockAuth } from '../../../test/api/helper'; + +use(chaiAsPromised); + +describe('updateProfile', () => { + const request = { + idToken: 'my-token', + email: 'test@foo.com', + password: 'my-password' + }; + + beforeEach(mockFetch.setUp); + afterEach(mockFetch.tearDown); + + it('should POST to the correct endpoint', async () => { + const mock = mockEndpoint(Endpoint.SET_ACCOUNT_INFO, { + displayName: 'my-name', + email: 'test@foo.com' + }); + + const response = await updateProfile(mockAuth, request); + expect(response.displayName).to.eq('my-name'); + expect(mock.calls[0].request).to.eql(request); + expect(mock.calls[0].method).to.eq('POST'); + expect(mock.calls[0].headers).to.eql({ + 'Content-Type': 'application/json' + }); + }); + + it('should handle errors', async () => { + const mock = mockEndpoint( + Endpoint.SET_ACCOUNT_INFO, + { + error: { + code: 400, + message: ServerError.EMAIL_EXISTS, + errors: [ + { + message: ServerError.EMAIL_EXISTS + } + ] + } + }, + 400 + ); + + await expect(updateProfile(mockAuth, request)).to.be.rejectedWith( + FirebaseError, + 'Firebase: The email address is already in use by another account. (auth/email-already-in-use).' + ); + expect(mock.calls[0].request).to.eql(request); + }); +}); diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts index 733958d47c8..2be7c833d2d 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts @@ -54,10 +54,6 @@ export enum GetOobCodeRequestType { interface GetOobCodeRequest { email?: string; // Everything except VERIFY_AND_CHANGE_EMAIL - // captchaResp?: string, // RESET_PASSWORD - // userIp?: string, // RESET_PASSWORD, - // newEmail?: string, // VERIFY_AND_CHANGE_EMAIL, - idToken?: IdToken; // VERIFY_EMAIL, VERIFY_AND_CHANGE_EMAIL continueUrl?: string; iosBundleId?: string; iosAppStoreId?: string; @@ -66,8 +62,8 @@ interface GetOobCodeRequest { androidMinimumVersionCode?: string; canHandleCodeInApp?: boolean; dynamicLinkDomain?: string; - // tenantId?: string, - // targetProjectid?: string, + tenantId?: string, + targetProjectid?: string, } export interface VerifyEmailRequest extends GetOobCodeRequest { @@ -78,6 +74,8 @@ export interface VerifyEmailRequest extends GetOobCodeRequest { export interface PasswordResetRequest extends GetOobCodeRequest { requestType: GetOobCodeRequestType.PASSWORD_RESET; email: string; + captchaResp?: string; + userIp?: string; } export interface EmailSignInRequest extends GetOobCodeRequest { From 12f439e8a1c41d7a9e8ebb6bd6ccd70059c0be7c Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Tue, 14 Apr 2020 13:09:05 -0700 Subject: [PATCH 09/14] Pass in SDK version & correctly send GET request params --- .../api/account_management/account.test.ts | 18 ++++++---- .../src/api/account_management/account.ts | 2 +- .../email_and_password.test.ts | 15 ++++---- .../account_management/email_and_password.ts | 4 +-- .../src/api/account_management/mfa.test.ts | 18 ++++++---- .../src/api/account_management/mfa.ts | 4 +-- .../api/account_management/profile.test.ts | 12 ++++--- .../src/api/account_management/profile.ts | 4 +-- .../authentication/create_auth_uri.test.ts | 12 ++++--- .../src/api/authentication/create_auth_uri.ts | 2 +- .../api/authentication/custom_token.test.ts | 12 ++++--- .../src/api/authentication/custom_token.ts | 2 +- .../authentication/email_and_password.test.ts | 30 +++++++--------- .../api/authentication/email_and_password.ts | 9 ++--- .../src/api/authentication/email_link.test.ts | 12 ++++--- .../src/api/authentication/email_link.ts | 2 +- .../src/api/authentication/idp.test.ts | 12 ++++--- .../auth-exp/src/api/authentication/idp.ts | 2 +- .../src/api/authentication/mfa.test.ts | 15 ++++---- .../auth-exp/src/api/authentication/mfa.ts | 7 ++-- .../src/api/authentication/recaptcha.test.ts | 12 ++++--- .../src/api/authentication/recaptcha.ts | 2 +- .../src/api/authentication/sign_up.test.ts | 11 +++--- .../src/api/authentication/sign_up.ts | 2 +- .../src/api/authentication/sms.test.ts | 26 +++++++------- .../auth-exp/src/api/authentication/sms.ts | 11 ++---- packages-exp/auth-exp/src/api/index.ts | 35 +++++++++++-------- .../src/core/user/token_manager.test.ts | 4 +-- packages-exp/auth-exp/src/model/auth.d.ts | 1 + packages-exp/auth-exp/test/mock_auth.ts | 3 +- 30 files changed, 160 insertions(+), 141 deletions(-) diff --git a/packages-exp/auth-exp/src/api/account_management/account.test.ts b/packages-exp/auth-exp/src/api/account_management/account.test.ts index 58aea550772..9860bf20036 100644 --- a/packages-exp/auth-exp/src/api/account_management/account.test.ts +++ b/packages-exp/auth-exp/src/api/account_management/account.test.ts @@ -15,15 +15,16 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { deleteAccount, deleteLinkedAccounts, getAccountInfo } from './account'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; import { ProviderId } from '../../core/providers'; +import { ServerError } from '../errors'; +import { deleteAccount, deleteLinkedAccounts, getAccountInfo } from './account'; use(chaiAsPromised); @@ -42,7 +43,8 @@ describe('deleteAccount', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -94,7 +96,8 @@ describe('deleteLinkedAccounts', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -145,7 +148,8 @@ describe('getAccountInfo', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/account_management/account.ts b/packages-exp/auth-exp/src/api/account_management/account.ts index ab790ceba90..6df5a679f6f 100644 --- a/packages-exp/auth-exp/src/api/account_management/account.ts +++ b/packages-exp/auth-exp/src/api/account_management/account.ts @@ -15,8 +15,8 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performApiRequest } from '..'; import { Auth } from '../../model/auth'; -import { performApiRequest, HttpMethod, Endpoint } from '..'; import { APIMFAInfo } from '../../model/id_token'; export interface DeleteAccountRequest { diff --git a/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts b/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts index 3eacf7fa9b9..a29adf5c6f0 100644 --- a/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts +++ b/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { resetPassword, updateEmailPassword } from './email_and_password'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { resetPassword, updateEmailPassword } from './email_and_password'; use(chaiAsPromised); @@ -45,7 +46,8 @@ describe('resetPassword', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -96,7 +98,8 @@ describe('updateEmailPassword', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/account_management/email_and_password.ts b/packages-exp/auth-exp/src/api/account_management/email_and_password.ts index cf65b061ae8..f38cf91d904 100644 --- a/packages-exp/auth-exp/src/api/account_management/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/account_management/email_and_password.ts @@ -15,10 +15,10 @@ * limitations under the License. */ -import { performApiRequest, Endpoint, HttpMethod } from '..'; +import { Endpoint, HttpMethod, performApiRequest } from '..'; +import { Operation } from '../../model/action_code_info'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; -import { Operation } from '../../model/action_code_info'; export interface ResetPasswordRequest { oobCode: string; diff --git a/packages-exp/auth-exp/src/api/account_management/mfa.test.ts b/packages-exp/auth-exp/src/api/account_management/mfa.test.ts index 4f2b828734c..13b9eb35d22 100644 --- a/packages-exp/auth-exp/src/api/account_management/mfa.test.ts +++ b/packages-exp/auth-exp/src/api/account_management/mfa.test.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { startEnrollPhoneMfa, enrollPhoneMfa, withdrawMfa } from './mfa'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { enrollPhoneMfa, startEnrollPhoneMfa, withdrawMfa } from './mfa'; use(chaiAsPromised); @@ -50,7 +51,8 @@ describe('startEnrollPhoneMfa', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -104,7 +106,8 @@ describe('enrollPhoneMfa', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -154,7 +157,8 @@ describe('withdrawMfa', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/account_management/mfa.ts b/packages-exp/auth-exp/src/api/account_management/mfa.ts index ad28d3da696..7cc6505add5 100644 --- a/packages-exp/auth-exp/src/api/account_management/mfa.ts +++ b/packages-exp/auth-exp/src/api/account_management/mfa.ts @@ -16,9 +16,9 @@ */ import { Endpoint, HttpMethod, performApiRequest } from '..'; -import { SignInWithPhoneNumberRequest } from '../authentication/sms'; -import { IdTokenResponse } from '../../model/id_token'; import { Auth } from '../../model/auth'; +import { IdTokenResponse } from '../../model/id_token'; +import { SignInWithPhoneNumberRequest } from '../authentication/sms'; export interface StartPhoneMfaEnrollmentRequest { idToken: string; diff --git a/packages-exp/auth-exp/src/api/account_management/profile.test.ts b/packages-exp/auth-exp/src/api/account_management/profile.test.ts index 855f4c153f1..171a5c9f175 100644 --- a/packages-exp/auth-exp/src/api/account_management/profile.test.ts +++ b/packages-exp/auth-exp/src/api/account_management/profile.test.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { updateProfile } from './profile'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { updateProfile } from './profile'; use(chaiAsPromised); @@ -47,7 +48,8 @@ describe('updateProfile', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/account_management/profile.ts b/packages-exp/auth-exp/src/api/account_management/profile.ts index 46948ddd251..5dfef1b9f16 100644 --- a/packages-exp/auth-exp/src/api/account_management/profile.ts +++ b/packages-exp/auth-exp/src/api/account_management/profile.ts @@ -15,9 +15,9 @@ * limitations under the License. */ -import { IdTokenResponse } from '../../model/id_token'; +import { Endpoint, HttpMethod, performApiRequest } from '..'; import { Auth } from '../../model/auth'; -import { performApiRequest, HttpMethod, Endpoint } from '..'; +import { IdTokenResponse } from '../../model/id_token'; export interface UpdateProfileRequest { idToken: string; diff --git a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.test.ts b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.test.ts index ac0957daba9..14d982ea57e 100644 --- a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.test.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { createAuthUri } from './create_auth_uri'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { createAuthUri } from './create_auth_uri'; use(chaiAsPromised); @@ -45,7 +46,8 @@ describe('createAuthUri', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts index 1d156176beb..935bbe1b4c6 100644 --- a/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts +++ b/packages-exp/auth-exp/src/api/authentication/create_auth_uri.ts @@ -15,8 +15,8 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performApiRequest } from '..'; import { Auth } from '../../model/auth'; -import { performApiRequest, HttpMethod, Endpoint } from '..'; export interface CreateAuthUriRequest { identifier: string; diff --git a/packages-exp/auth-exp/src/api/authentication/custom_token.test.ts b/packages-exp/auth-exp/src/api/authentication/custom_token.test.ts index 57d9ca643a5..5b29ab3531a 100644 --- a/packages-exp/auth-exp/src/api/authentication/custom_token.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/custom_token.test.ts @@ -15,15 +15,16 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { signInWithCustomToken } from './custom_token'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; import { ProviderId } from '../../core/providers'; +import { ServerError } from '../errors'; +import { signInWithCustomToken } from './custom_token'; use(chaiAsPromised); @@ -51,7 +52,8 @@ describe('signInWithCustomToken', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/custom_token.ts b/packages-exp/auth-exp/src/api/authentication/custom_token.ts index 389ef2f1b1b..02993302d4a 100644 --- a/packages-exp/auth-exp/src/api/authentication/custom_token.ts +++ b/packages-exp/auth-exp/src/api/authentication/custom_token.ts @@ -15,9 +15,9 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performSignInRequest } from '..'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; -import { performSignInRequest, HttpMethod, Endpoint } from '..'; export interface SignInWithCustomTokenRequest { token: string; diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts index a300170985c..b0d6edf9349 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts @@ -15,23 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { - signInWithPassword, - sendPasswordResetEmail, - sendEmailVerification, - sendSignInLinkToEmail, - GetOobCodeRequestType, - VerifyEmailRequest, - PasswordResetRequest, - EmailSignInRequest -} from './email_and_password'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { EmailSignInRequest, GetOobCodeRequestType, PasswordResetRequest, sendEmailVerification, sendPasswordResetEmail, sendSignInLinkToEmail, signInWithPassword, VerifyEmailRequest } from './email_and_password'; use(chaiAsPromised); @@ -57,7 +49,8 @@ describe('signInWithPassword', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -106,7 +99,8 @@ describe('sendOobCode', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -154,7 +148,8 @@ describe('sendOobCode', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -204,7 +199,8 @@ describe('sendOobCode', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts index 2be7c833d2d..643ac220fc8 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts @@ -15,14 +15,9 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performApiRequest, performSignInRequest } from '..'; import { Auth } from '../../model/auth'; -import { IdTokenResponse, IdToken } from '../../model/id_token'; -import { - performSignInRequest, - HttpMethod, - Endpoint, - performApiRequest -} from '..'; +import { IdToken, IdTokenResponse } from '../../model/id_token'; export interface SignInWithPasswordRequest { returnSecureToken?: boolean; diff --git a/packages-exp/auth-exp/src/api/authentication/email_link.test.ts b/packages-exp/auth-exp/src/api/authentication/email_link.test.ts index 934dc7adf7b..de3d0a9725b 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_link.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_link.test.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { signInWithEmailLink } from './email_link'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { signInWithEmailLink } from './email_link'; use(chaiAsPromised); @@ -47,7 +48,8 @@ describe('signInWithEmailLink', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/email_link.ts b/packages-exp/auth-exp/src/api/authentication/email_link.ts index e358e791171..ae91349b84a 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_link.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_link.ts @@ -15,9 +15,9 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performSignInRequest } from '..'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; -import { performSignInRequest, HttpMethod, Endpoint } from '..'; export interface SignInWithEmailLinkRequest { email: string; diff --git a/packages-exp/auth-exp/src/api/authentication/idp.test.ts b/packages-exp/auth-exp/src/api/authentication/idp.test.ts index ff671ee3b5e..db5685e7c8a 100644 --- a/packages-exp/auth-exp/src/api/authentication/idp.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/idp.test.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { signInWithIdp } from './idp'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { signInWithIdp } from './idp'; use(chaiAsPromised); @@ -48,7 +49,8 @@ describe('signInWithIdp', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/idp.ts b/packages-exp/auth-exp/src/api/authentication/idp.ts index d9e7138aa91..8aab144e94a 100644 --- a/packages-exp/auth-exp/src/api/authentication/idp.ts +++ b/packages-exp/auth-exp/src/api/authentication/idp.ts @@ -15,9 +15,9 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performSignInRequest } from '..'; import { Auth } from '../../model/auth'; import { IdToken, IdTokenResponse } from '../../model/id_token'; -import { performSignInRequest, HttpMethod, Endpoint } from '..'; export interface SignInWithIdpRequest { requestUri: string; diff --git a/packages-exp/auth-exp/src/api/authentication/mfa.test.ts b/packages-exp/auth-exp/src/api/authentication/mfa.test.ts index 5ab192a2c31..eef32fa3f93 100644 --- a/packages-exp/auth-exp/src/api/authentication/mfa.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/mfa.test.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { startSignInPhoneMfa, finalizeSignInPhoneMfa } from './mfa'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { finalizeSignInPhoneMfa, startSignInPhoneMfa } from './mfa'; use(chaiAsPromised); @@ -50,7 +51,8 @@ describe('startSignInPhoneMfa', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -105,7 +107,8 @@ describe('finalizeSignInPhoneMfa', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/mfa.ts b/packages-exp/auth-exp/src/api/authentication/mfa.ts index f83341da87f..801e2152ff5 100644 --- a/packages-exp/auth-exp/src/api/authentication/mfa.ts +++ b/packages-exp/auth-exp/src/api/authentication/mfa.ts @@ -15,14 +15,11 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performApiRequest } from '..'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; -import { HttpMethod, Endpoint, performApiRequest } from '..'; -import { - SignInWithPhoneNumberRequest, - SignInWithPhoneNumberResponse -} from './sms'; import { SignInWithIdpResponse } from './idp'; +import { SignInWithPhoneNumberRequest, SignInWithPhoneNumberResponse } from './sms'; export interface StartPhoneMfaSignInRequest { mfaPendingCredential: string; diff --git a/packages-exp/auth-exp/src/api/authentication/recaptcha.test.ts b/packages-exp/auth-exp/src/api/authentication/recaptcha.test.ts index 40c120d1d51..5d1637b151f 100644 --- a/packages-exp/auth-exp/src/api/authentication/recaptcha.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/recaptcha.test.ts @@ -15,14 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { getRecaptchaParams } from './recaptcha'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; +import { ServerError } from '../errors'; +import { getRecaptchaParams } from './recaptcha'; use(chaiAsPromised); @@ -40,7 +41,8 @@ describe('getRecaptchaParams', () => { expect(mock.calls[0].request).to.be.undefined; expect(mock.calls[0].method).to.eq('GET'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/recaptcha.ts b/packages-exp/auth-exp/src/api/authentication/recaptcha.ts index 25e172663da..27babbe639a 100644 --- a/packages-exp/auth-exp/src/api/authentication/recaptcha.ts +++ b/packages-exp/auth-exp/src/api/authentication/recaptcha.ts @@ -15,8 +15,8 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performApiRequest } from '..'; import { Auth } from '../../model/auth'; -import { HttpMethod, Endpoint, performApiRequest } from '..'; interface GetRecaptchaParamResponse { recaptchaSiteKey?: string; diff --git a/packages-exp/auth-exp/src/api/authentication/sign_up.test.ts b/packages-exp/auth-exp/src/api/authentication/sign_up.test.ts index 7f1acac36a7..c83f5297fab 100644 --- a/packages-exp/auth-exp/src/api/authentication/sign_up.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/sign_up.test.ts @@ -15,15 +15,15 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { signUp } from './sign_up'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; -import * as mockFetch from '../../../test/mock_fetch'; import { mockEndpoint } from '../../../test/api/helper'; import { mockAuth } from '../../../test/mock_auth'; +import * as mockFetch from '../../../test/mock_fetch'; +import { ServerError } from '../errors'; +import { signUp } from './sign_up'; use(chaiAsPromised); @@ -49,7 +49,8 @@ describe('signUp', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/sign_up.ts b/packages-exp/auth-exp/src/api/authentication/sign_up.ts index b58361d666a..99498395a95 100644 --- a/packages-exp/auth-exp/src/api/authentication/sign_up.ts +++ b/packages-exp/auth-exp/src/api/authentication/sign_up.ts @@ -15,9 +15,9 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performSignInRequest } from '..'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; -import { performSignInRequest, HttpMethod, Endpoint } from '..'; export interface SignUpRequest { returnSecureToken?: boolean; diff --git a/packages-exp/auth-exp/src/api/authentication/sms.test.ts b/packages-exp/auth-exp/src/api/authentication/sms.test.ts index 9297cb82ddf..fd25a5c7ca2 100644 --- a/packages-exp/auth-exp/src/api/authentication/sms.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/sms.test.ts @@ -15,20 +15,16 @@ * limitations under the License. */ +import { FirebaseError } from '@firebase/util'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { - sendPhoneVerificationCode, - signInWithPhoneNumber, - linkWithPhoneNumber, - verifyPhoneNumberForExisting -} from './sms'; import { Endpoint } from '..'; -import { ServerError } from '../errors'; -import { FirebaseError } from '@firebase/util'; +import { mockEndpoint } from '../../../test/api/helper'; +import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; -import { mockEndpoint, mockAuth } from '../../../test/api/helper'; import { ProviderId } from '../../core/providers'; +import { ServerError } from '../errors'; +import { linkWithPhoneNumber, sendPhoneVerificationCode, signInWithPhoneNumber, verifyPhoneNumberForExisting } from './sms'; use(chaiAsPromised); @@ -51,7 +47,8 @@ describe('sendPhoneVerificationCode', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -110,7 +107,8 @@ describe('signInWithPhoneNumber', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -168,7 +166,8 @@ describe('linkWithPhoneNumber', () => { expect(mock.calls[0].request).to.eql(request); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); @@ -228,7 +227,8 @@ describe('verifyPhoneNumberForExisting', () => { }); expect(mock.calls[0].method).to.eq('POST'); expect(mock.calls[0].headers).to.eql({ - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': 'testSDK/0.0.0' }); }); diff --git a/packages-exp/auth-exp/src/api/authentication/sms.ts b/packages-exp/auth-exp/src/api/authentication/sms.ts index 5e0fd545492..3fb969fbf03 100644 --- a/packages-exp/auth-exp/src/api/authentication/sms.ts +++ b/packages-exp/auth-exp/src/api/authentication/sms.ts @@ -15,16 +15,11 @@ * limitations under the License. */ +import { Endpoint, HttpMethod, performApiRequest, performSignInRequest } from '..'; +import { AuthErrorCode } from '../../core/errors'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; -import { - performSignInRequest, - HttpMethod, - Endpoint, - performApiRequest -} from '..'; -import { ServerErrorMap, ServerError } from '../errors'; -import { AuthErrorCode } from '../../core/errors'; +import { ServerError, ServerErrorMap } from '../errors'; export interface SendPhoneVerificationCodeRequest { phoneNumber: string; diff --git a/packages-exp/auth-exp/src/api/index.ts b/packages-exp/auth-exp/src/api/index.ts index 5c9545f7db9..afe5b9307e6 100644 --- a/packages-exp/auth-exp/src/api/index.ts +++ b/packages-exp/auth-exp/src/api/index.ts @@ -15,16 +15,11 @@ * limitations under the License. */ -import { Auth } from '../model/auth'; -import { - JsonError, - SERVER_ERROR_MAP, - ServerErrorMap, - ServerError -} from './errors'; -import { AUTH_ERROR_FACTORY, AuthErrorCode } from '../core/errors'; import { FirebaseError } from '@firebase/util'; +import { AuthErrorCode, AUTH_ERROR_FACTORY } from '../core/errors'; +import { Auth } from '../model/auth'; import { IdTokenResponse } from '../model/id_token'; +import { JsonError, ServerError, ServerErrorMap, SERVER_ERROR_MAP } from './errors'; export enum HttpMethod { POST = 'POST', @@ -62,17 +57,29 @@ export async function performApiRequest( ): Promise { const errorMap = { ...SERVER_ERROR_MAP, ...customErrorMap }; try { - const body = request - ? { + let body = {}; + const params: { [key: string]: string } = { + key: auth.config.apiKey + }; + if (request) { + if (method === HttpMethod.GET) { + Object.assign(params, request); + } else { + body = { body: JSON.stringify(request) - } - : {}; + }; + } + } + + const queryString = Object.keys(params).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&'); + const response = await fetch( - `${auth.config.apiScheme}://${auth.config.apiHost}${path}?key=${auth.config.apiKey}`, + `${auth.config.apiScheme}://${auth.config.apiHost}${path}?${queryString}`, { method, headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', + 'X-Client-Version': auth.config.sdkClientVersion }, referrerPolicy: 'no-referrer', ...body diff --git a/packages-exp/auth-exp/src/core/user/token_manager.test.ts b/packages-exp/auth-exp/src/core/user/token_manager.test.ts index c6a943a62ed..d15420d99b1 100644 --- a/packages-exp/auth-exp/src/core/user/token_manager.test.ts +++ b/packages-exp/auth-exp/src/core/user/token_manager.test.ts @@ -17,9 +17,9 @@ import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { StsTokenManager, TOKEN_REFRESH_BUFFER_MS } from './token_manager'; -import { IdTokenResponse } from '../../model/id_token'; import { createSandbox } from 'sinon'; +import { IdTokenResponse } from '../../model/id_token'; +import { StsTokenManager, TOKEN_REFRESH_BUFFER_MS } from './token_manager'; use(chaiAsPromised); diff --git a/packages-exp/auth-exp/src/model/auth.d.ts b/packages-exp/auth-exp/src/model/auth.d.ts index 9fa9570feaf..9d06ed06df9 100644 --- a/packages-exp/auth-exp/src/model/auth.d.ts +++ b/packages-exp/auth-exp/src/model/auth.d.ts @@ -26,6 +26,7 @@ export interface Config { apiKey: ApiKey; apiHost: string; apiScheme: string; + sdkClientVersion: string; authDomain?: AuthDomain; } diff --git a/packages-exp/auth-exp/test/mock_auth.ts b/packages-exp/auth-exp/test/mock_auth.ts index a5304ecba7f..659bdebe270 100644 --- a/packages-exp/auth-exp/test/mock_auth.ts +++ b/packages-exp/auth-exp/test/mock_auth.ts @@ -29,7 +29,8 @@ export const mockAuth: Auth = { config: { apiKey: TEST_KEY, apiHost: TEST_HOST, - apiScheme: TEST_SCHEME + apiScheme: TEST_SCHEME, + sdkClientVersion: 'testSDK/0.0.0' } }; From c896cbf41ed4e1563bf146893aec3506790bc6c9 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Tue, 14 Apr 2020 13:09:29 -0700 Subject: [PATCH 10/14] [AUTOMATED]: Prettier Code Styling --- .../api/account_management/account.test.ts | 24 +++++++++++-------- .../email_and_password.test.ts | 2 -- .../src/api/account_management/mfa.test.ts | 4 ++-- .../api/authentication/email_and_password.ts | 4 ++-- packages-exp/auth-exp/src/api/index.ts | 10 +++++--- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/packages-exp/auth-exp/src/api/account_management/account.test.ts b/packages-exp/auth-exp/src/api/account_management/account.test.ts index 9860bf20036..877e33ecdae 100644 --- a/packages-exp/auth-exp/src/api/account_management/account.test.ts +++ b/packages-exp/auth-exp/src/api/account_management/account.test.ts @@ -67,7 +67,7 @@ describe('deleteAccount', () => { await expect(deleteAccount(mockAuth, request)).to.be.rejectedWith( FirebaseError, - 'Firebase: This user\'s credential isn\'t valid for this project. This can happen if the user\'s token has been tampered with]: or if the user isn\'t for the project associated with this API key. (auth/invalid-user-token).' + "Firebase: This user's credential isn't valid for this project. This can happen if the user's token has been tampered with]: or if the user isn't for the project associated with this API key. (auth/invalid-user-token)." ); expect(mock.calls[0].request).to.eql(request); }); @@ -84,10 +84,12 @@ describe('deleteLinkedAccounts', () => { it('should POST to the correct endpoint', async () => { const mock = mockEndpoint(Endpoint.SET_ACCOUNT_INFO, { - providerUserInfo: [{ - providerId: ProviderId.GOOGLE, - email: 'test@foo.com' - }] + providerUserInfo: [ + { + providerId: ProviderId.GOOGLE, + email: 'test@foo.com' + } + ] }); const response = await deleteLinkedAccounts(mockAuth, request); @@ -136,10 +138,12 @@ describe('getAccountInfo', () => { it('should POST to the correct endpoint', async () => { const mock = mockEndpoint(Endpoint.GET_ACCOUNT_INFO, { - users: [{ - displayName: 'my-name', - email: 'test@foo.com' - }] + users: [ + { + displayName: 'my-name', + email: 'test@foo.com' + } + ] }); const response = await getAccountInfo(mockAuth, request); @@ -172,7 +176,7 @@ describe('getAccountInfo', () => { await expect(getAccountInfo(mockAuth, request)).to.be.rejectedWith( FirebaseError, - 'Firebase: This user\'s credential isn\'t valid for this project. This can happen if the user\'s token has been tampered with]: or if the user isn\'t for the project associated with this API key. (auth/invalid-user-token).' + "Firebase: This user's credential isn't valid for this project. This can happen if the user's token has been tampered with]: or if the user isn't for the project associated with this API key. (auth/invalid-user-token)." ); expect(mock.calls[0].request).to.eql(request); }); diff --git a/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts b/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts index a29adf5c6f0..308108ab336 100644 --- a/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts +++ b/packages-exp/auth-exp/src/api/account_management/email_and_password.test.ts @@ -76,7 +76,6 @@ describe('resetPassword', () => { }); }); - describe('updateEmailPassword', () => { const request = { idToken: 'id-token', @@ -127,4 +126,3 @@ describe('updateEmailPassword', () => { expect(mock.calls[0].request).to.eql(request); }); }); - diff --git a/packages-exp/auth-exp/src/api/account_management/mfa.test.ts b/packages-exp/auth-exp/src/api/account_management/mfa.test.ts index 13b9eb35d22..27ed7f78ddd 100644 --- a/packages-exp/auth-exp/src/api/account_management/mfa.test.ts +++ b/packages-exp/auth-exp/src/api/account_management/mfa.test.ts @@ -75,7 +75,7 @@ describe('startEnrollPhoneMfa', () => { await expect(startEnrollPhoneMfa(mockAuth, request)).to.be.rejectedWith( FirebaseError, - 'Firebase: This user\'s credential isn\'t valid for this project. This can happen if the user\'s token has been tampered with]: or if the user isn\'t for the project associated with this API key. (auth/invalid-user-token).' + "Firebase: This user's credential isn't valid for this project. This can happen if the user's token has been tampered with]: or if the user isn't for the project associated with this API key. (auth/invalid-user-token)." ); expect(mock.calls[0].request).to.eql(request); }); @@ -181,7 +181,7 @@ describe('withdrawMfa', () => { await expect(withdrawMfa(mockAuth, request)).to.be.rejectedWith( FirebaseError, - 'Firebase: This user\'s credential isn\'t valid for this project. This can happen if the user\'s token has been tampered with]: or if the user isn\'t for the project associated with this API key. (auth/invalid-user-token).' + "Firebase: This user's credential isn't valid for this project. This can happen if the user's token has been tampered with]: or if the user isn't for the project associated with this API key. (auth/invalid-user-token)." ); expect(mock.calls[0].request).to.eql(request); }); diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts index 643ac220fc8..143e3d62e94 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts @@ -57,8 +57,8 @@ interface GetOobCodeRequest { androidMinimumVersionCode?: string; canHandleCodeInApp?: boolean; dynamicLinkDomain?: string; - tenantId?: string, - targetProjectid?: string, + tenantId?: string; + targetProjectid?: string; } export interface VerifyEmailRequest extends GetOobCodeRequest { diff --git a/packages-exp/auth-exp/src/api/index.ts b/packages-exp/auth-exp/src/api/index.ts index afe5b9307e6..e3ada355851 100644 --- a/packages-exp/auth-exp/src/api/index.ts +++ b/packages-exp/auth-exp/src/api/index.ts @@ -63,7 +63,7 @@ export async function performApiRequest( }; if (request) { if (method === HttpMethod.GET) { - Object.assign(params, request); + Object.assign(params, request); } else { body = { body: JSON.stringify(request) @@ -71,8 +71,12 @@ export async function performApiRequest( } } - const queryString = Object.keys(params).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&'); - + const queryString = Object.keys(params) + .map( + key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}` + ) + .join('&'); + const response = await fetch( `${auth.config.apiScheme}://${auth.config.apiHost}${path}?${queryString}`, { From 9304b96703dde9f97e80cd546d7958eb2044d7b7 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Tue, 14 Apr 2020 14:28:02 -0700 Subject: [PATCH 11/14] [AUTOMATED]: Prettier Code Styling --- .../src/api/authentication/email_and_password.test.ts | 11 ++++++++++- .../src/api/authentication/email_and_password.ts | 7 ++++++- packages-exp/auth-exp/src/api/authentication/mfa.ts | 5 ++++- .../auth-exp/src/api/authentication/sms.test.ts | 7 ++++++- packages-exp/auth-exp/src/api/authentication/sms.ts | 7 ++++++- packages-exp/auth-exp/src/api/index.ts | 7 ++++++- 6 files changed, 38 insertions(+), 6 deletions(-) diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts index b0d6edf9349..ae9efb84137 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.test.ts @@ -23,7 +23,16 @@ import { mockEndpoint } from '../../../test/api/helper'; import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; import { ServerError } from '../errors'; -import { EmailSignInRequest, GetOobCodeRequestType, PasswordResetRequest, sendEmailVerification, sendPasswordResetEmail, sendSignInLinkToEmail, signInWithPassword, VerifyEmailRequest } from './email_and_password'; +import { + EmailSignInRequest, + GetOobCodeRequestType, + PasswordResetRequest, + sendEmailVerification, + sendPasswordResetEmail, + sendSignInLinkToEmail, + signInWithPassword, + VerifyEmailRequest +} from './email_and_password'; use(chaiAsPromised); diff --git a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts index 143e3d62e94..ca801baeaea 100644 --- a/packages-exp/auth-exp/src/api/authentication/email_and_password.ts +++ b/packages-exp/auth-exp/src/api/authentication/email_and_password.ts @@ -15,7 +15,12 @@ * limitations under the License. */ -import { Endpoint, HttpMethod, performApiRequest, performSignInRequest } from '..'; +import { + Endpoint, + HttpMethod, + performApiRequest, + performSignInRequest +} from '..'; import { Auth } from '../../model/auth'; import { IdToken, IdTokenResponse } from '../../model/id_token'; diff --git a/packages-exp/auth-exp/src/api/authentication/mfa.ts b/packages-exp/auth-exp/src/api/authentication/mfa.ts index 801e2152ff5..a93464eb63c 100644 --- a/packages-exp/auth-exp/src/api/authentication/mfa.ts +++ b/packages-exp/auth-exp/src/api/authentication/mfa.ts @@ -19,7 +19,10 @@ import { Endpoint, HttpMethod, performApiRequest } from '..'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; import { SignInWithIdpResponse } from './idp'; -import { SignInWithPhoneNumberRequest, SignInWithPhoneNumberResponse } from './sms'; +import { + SignInWithPhoneNumberRequest, + SignInWithPhoneNumberResponse +} from './sms'; export interface StartPhoneMfaSignInRequest { mfaPendingCredential: string; diff --git a/packages-exp/auth-exp/src/api/authentication/sms.test.ts b/packages-exp/auth-exp/src/api/authentication/sms.test.ts index fd25a5c7ca2..067d789a7be 100644 --- a/packages-exp/auth-exp/src/api/authentication/sms.test.ts +++ b/packages-exp/auth-exp/src/api/authentication/sms.test.ts @@ -24,7 +24,12 @@ import { mockAuth } from '../../../test/mock_auth'; import * as mockFetch from '../../../test/mock_fetch'; import { ProviderId } from '../../core/providers'; import { ServerError } from '../errors'; -import { linkWithPhoneNumber, sendPhoneVerificationCode, signInWithPhoneNumber, verifyPhoneNumberForExisting } from './sms'; +import { + linkWithPhoneNumber, + sendPhoneVerificationCode, + signInWithPhoneNumber, + verifyPhoneNumberForExisting +} from './sms'; use(chaiAsPromised); diff --git a/packages-exp/auth-exp/src/api/authentication/sms.ts b/packages-exp/auth-exp/src/api/authentication/sms.ts index 3fb969fbf03..80192375616 100644 --- a/packages-exp/auth-exp/src/api/authentication/sms.ts +++ b/packages-exp/auth-exp/src/api/authentication/sms.ts @@ -15,7 +15,12 @@ * limitations under the License. */ -import { Endpoint, HttpMethod, performApiRequest, performSignInRequest } from '..'; +import { + Endpoint, + HttpMethod, + performApiRequest, + performSignInRequest +} from '..'; import { AuthErrorCode } from '../../core/errors'; import { Auth } from '../../model/auth'; import { IdTokenResponse } from '../../model/id_token'; diff --git a/packages-exp/auth-exp/src/api/index.ts b/packages-exp/auth-exp/src/api/index.ts index e3ada355851..65efe5779b4 100644 --- a/packages-exp/auth-exp/src/api/index.ts +++ b/packages-exp/auth-exp/src/api/index.ts @@ -19,7 +19,12 @@ import { FirebaseError } from '@firebase/util'; import { AuthErrorCode, AUTH_ERROR_FACTORY } from '../core/errors'; import { Auth } from '../model/auth'; import { IdTokenResponse } from '../model/id_token'; -import { JsonError, ServerError, ServerErrorMap, SERVER_ERROR_MAP } from './errors'; +import { + JsonError, + ServerError, + ServerErrorMap, + SERVER_ERROR_MAP +} from './errors'; export enum HttpMethod { POST = 'POST', From 3410d1bae9ddb482e75ca1e8a1580d05d371a835 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Tue, 14 Apr 2020 14:30:35 -0700 Subject: [PATCH 12/14] Fix import ordering --- packages-exp/auth-exp/src/core/errors.test.ts | 2 +- packages-exp/auth-exp/src/core/user/user_impl.test.ts | 6 +++--- packages-exp/auth-exp/src/core/user/user_impl.ts | 2 +- packages-exp/auth-exp/src/model/user.d.ts | 2 +- packages-exp/auth-exp/test/api/helper.ts | 2 +- packages-exp/auth-exp/test/mock_auth.ts | 4 ++-- packages-exp/auth-exp/test/mock_fetch.ts | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages-exp/auth-exp/src/core/errors.test.ts b/packages-exp/auth-exp/src/core/errors.test.ts index 7dfb0d07184..87eed7f0590 100644 --- a/packages-exp/auth-exp/src/core/errors.test.ts +++ b/packages-exp/auth-exp/src/core/errors.test.ts @@ -16,7 +16,7 @@ */ import { expect } from 'chai'; -import { AUTH_ERROR_FACTORY, AuthErrorCode } from './errors'; +import { AuthErrorCode, AUTH_ERROR_FACTORY } from './errors'; describe('AUTH_ERROR_FACTORY', () => { it('should create an Auth namespaced FirebaseError', () => { diff --git a/packages-exp/auth-exp/src/core/user/user_impl.test.ts b/packages-exp/auth-exp/src/core/user/user_impl.test.ts index c84ccea513f..26fbe161dc6 100644 --- a/packages-exp/auth-exp/src/core/user/user_impl.test.ts +++ b/packages-exp/auth-exp/src/core/user/user_impl.test.ts @@ -17,10 +17,10 @@ import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import { UserImpl } from './user_impl'; -import { StsTokenManager } from './token_manager'; -import { IdTokenResponse } from '../../model/id_token'; import { mockAuth } from '../../../test/mock_auth'; +import { IdTokenResponse } from '../../model/id_token'; +import { StsTokenManager } from './token_manager'; +import { UserImpl } from './user_impl'; use(chaiAsPromised); diff --git a/packages-exp/auth-exp/src/core/user/user_impl.ts b/packages-exp/auth-exp/src/core/user/user_impl.ts index 1e535299ca4..c3d676716e3 100644 --- a/packages-exp/auth-exp/src/core/user/user_impl.ts +++ b/packages-exp/auth-exp/src/core/user/user_impl.ts @@ -15,9 +15,9 @@ * limitations under the License. */ -import { User } from '../../model/user'; import { Auth } from '../../model/auth'; import { IdTokenResult } from '../../model/id_token'; +import { User } from '../../model/user'; import { ProviderId } from '../providers'; import { StsTokenManager } from './token_manager'; diff --git a/packages-exp/auth-exp/src/model/user.d.ts b/packages-exp/auth-exp/src/model/user.d.ts index d21eae226d8..75820154392 100644 --- a/packages-exp/auth-exp/src/model/user.d.ts +++ b/packages-exp/auth-exp/src/model/user.d.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -import { IdTokenResult } from './id_token'; import { ProviderId } from '../core/providers'; +import { IdTokenResult } from './id_token'; export interface UserInfo { readonly uid: string; diff --git a/packages-exp/auth-exp/test/api/helper.ts b/packages-exp/auth-exp/test/api/helper.ts index 002d5f017cf..68118d8d418 100644 --- a/packages-exp/auth-exp/test/api/helper.ts +++ b/packages-exp/auth-exp/test/api/helper.ts @@ -16,8 +16,8 @@ */ import { Endpoint } from '../../src/api'; +import { TEST_HOST, TEST_KEY, TEST_SCHEME } from '../mock_auth'; import { mock, Route } from '../mock_fetch'; -import { TEST_SCHEME, TEST_HOST, TEST_KEY } from '../mock_auth'; export function mockEndpoint( endpoint: Endpoint, diff --git a/packages-exp/auth-exp/test/mock_auth.ts b/packages-exp/auth-exp/test/mock_auth.ts index 659bdebe270..9928047a616 100644 --- a/packages-exp/auth-exp/test/mock_auth.ts +++ b/packages-exp/auth-exp/test/mock_auth.ts @@ -15,10 +15,10 @@ * limitations under the License. */ +import { StsTokenManager } from '../src/core/user/token_manager'; +import { UserImpl } from '../src/core/user/user_impl'; import { Auth } from '../src/model/auth'; import { User } from '../src/model/user'; -import { UserImpl } from '../src/core/user/user_impl'; -import { StsTokenManager } from '../src/core/user/token_manager'; export const TEST_HOST = 'localhost'; export const TEST_SCHEME = 'mock'; diff --git a/packages-exp/auth-exp/test/mock_fetch.ts b/packages-exp/auth-exp/test/mock_fetch.ts index d70376fe3e3..2d1cafb71ab 100644 --- a/packages-exp/auth-exp/test/mock_fetch.ts +++ b/packages-exp/auth-exp/test/mock_fetch.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { stub, SinonStub } from 'sinon'; +import { SinonStub, stub } from 'sinon'; export interface Call { request?: object; From cd05f2ba8ea01c9c1b472df9b99cfdef08717a09 Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Wed, 15 Apr 2020 10:23:36 -0700 Subject: [PATCH 13/14] Minor formatting change --- packages-exp/auth-exp/src/api/index.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages-exp/auth-exp/src/api/index.ts b/packages-exp/auth-exp/src/api/index.ts index 65efe5779b4..aa7403b0681 100644 --- a/packages-exp/auth-exp/src/api/index.ts +++ b/packages-exp/auth-exp/src/api/index.ts @@ -63,7 +63,7 @@ export async function performApiRequest( const errorMap = { ...SERVER_ERROR_MAP, ...customErrorMap }; try { let body = {}; - const params: { [key: string]: string } = { + const params: { [key: string]: string; } = { key: auth.config.apiKey }; if (request) { @@ -77,10 +77,9 @@ export async function performApiRequest( } const queryString = Object.keys(params) - .map( - key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}` - ) - .join('&'); + .map(key => { + return `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`; + }).join('&'); const response = await fetch( `${auth.config.apiScheme}://${auth.config.apiHost}${path}?${queryString}`, From a5794787c6dc71625a861d60f2aa7e87ae6086bb Mon Sep 17 00:00:00 2001 From: Alex Volkovitsky Date: Wed, 15 Apr 2020 10:23:57 -0700 Subject: [PATCH 14/14] [AUTOMATED]: Prettier Code Styling --- packages-exp/auth-exp/src/api/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages-exp/auth-exp/src/api/index.ts b/packages-exp/auth-exp/src/api/index.ts index aa7403b0681..788e2886558 100644 --- a/packages-exp/auth-exp/src/api/index.ts +++ b/packages-exp/auth-exp/src/api/index.ts @@ -63,7 +63,7 @@ export async function performApiRequest( const errorMap = { ...SERVER_ERROR_MAP, ...customErrorMap }; try { let body = {}; - const params: { [key: string]: string; } = { + const params: { [key: string]: string } = { key: auth.config.apiKey }; if (request) { @@ -79,7 +79,8 @@ export async function performApiRequest( const queryString = Object.keys(params) .map(key => { return `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`; - }).join('&'); + }) + .join('&'); const response = await fetch( `${auth.config.apiScheme}://${auth.config.apiHost}${path}?${queryString}`,