Skip to content

Commit c4e1ed3

Browse files
committed
Update injectRecaptchaFields to inject recaptcha fields into phone API requests
1 parent bebecda commit c4e1ed3

File tree

11 files changed

+350
-45
lines changed

11 files changed

+350
-45
lines changed

packages/auth/src/api/account_management/mfa.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ import chaiAsPromised from 'chai-as-promised';
2020

2121
import { FirebaseError } from '@firebase/util';
2222

23-
import { Endpoint, HttpHeader } from '../';
23+
import {
24+
Endpoint,
25+
HttpHeader,
26+
RecaptchaClientType,
27+
RecaptchaVersion
28+
} from '../';
2429
import { mockEndpoint } from '../../../test/helpers/api/helper';
2530
import { testAuth, TestAuth } from '../../../test/helpers/mock_auth';
2631
import * as mockFetch from '../../../test/helpers/mock_fetch';
@@ -40,7 +45,10 @@ describe('api/account_management/startEnrollPhoneMfa', () => {
4045
idToken: 'id-token',
4146
phoneEnrollmentInfo: {
4247
phoneNumber: 'phone-number',
43-
recaptchaToken: 'captcha-token'
48+
recaptchaToken: 'captcha-token',
49+
captchaResponse: 'captcha-response',
50+
clientType: RecaptchaClientType.WEB,
51+
recaptchaVersion: RecaptchaVersion.ENTERPRISE
4452
}
4553
};
4654

packages/auth/src/api/account_management/mfa.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import {
1919
Endpoint,
2020
HttpMethod,
21+
RecaptchaClientType,
22+
RecaptchaVersion,
2123
_addTidIfNecessary,
2224
_performApiRequest
2325
} from '../index';
@@ -55,7 +57,10 @@ export interface StartPhoneMfaEnrollmentRequest {
5557
idToken: string;
5658
phoneEnrollmentInfo: {
5759
phoneNumber: string;
58-
recaptchaToken: string;
60+
recaptchaToken?: string;
61+
captchaResponse?: string;
62+
clientType?: RecaptchaClientType;
63+
recaptchaVersion?: RecaptchaVersion;
5964
};
6065
tenantId?: string;
6166
}

packages/auth/src/api/authentication/mfa.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ import chaiAsPromised from 'chai-as-promised';
2020

2121
import { FirebaseError } from '@firebase/util';
2222

23-
import { Endpoint, HttpHeader } from '../';
23+
import {
24+
Endpoint,
25+
HttpHeader,
26+
RecaptchaClientType,
27+
RecaptchaVersion
28+
} from '../';
2429
import { mockEndpoint } from '../../../test/helpers/api/helper';
2530
import { testAuth, TestAuth } from '../../../test/helpers/mock_auth';
2631
import * as mockFetch from '../../../test/helpers/mock_fetch';
@@ -34,7 +39,10 @@ describe('api/authentication/startSignInPhoneMfa', () => {
3439
mfaPendingCredential: 'my-creds',
3540
mfaEnrollmentId: 'my-enrollment-id',
3641
phoneSignInInfo: {
37-
recaptchaToken: 'catpcha-token'
42+
recaptchaToken: 'catpcha-token',
43+
captchaResponse: 'captcha-response',
44+
clientType: RecaptchaClientType.WEB,
45+
recaptchaVersion: RecaptchaVersion.ENTERPRISE
3846
}
3947
};
4048

packages/auth/src/api/authentication/mfa.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
_performApiRequest,
2020
Endpoint,
2121
HttpMethod,
22+
RecaptchaClientType,
23+
RecaptchaVersion,
2224
_addTidIfNecessary
2325
} from '../index';
2426
import { Auth } from '../../model/public_types';
@@ -47,7 +49,10 @@ export interface StartPhoneMfaSignInRequest {
4749
mfaPendingCredential: string;
4850
mfaEnrollmentId: string;
4951
phoneSignInInfo: {
50-
recaptchaToken: string;
52+
recaptchaToken?: string;
53+
captchaResponse?: string;
54+
clientType?: RecaptchaClientType;
55+
recaptchaVersion?: RecaptchaVersion;
5156
};
5257
tenantId?: string;
5358
}

packages/auth/src/api/authentication/sms.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@ import chaiAsPromised from 'chai-as-promised';
2121
import { ProviderId } from '../../model/enums';
2222
import { FirebaseError } from '@firebase/util';
2323

24-
import { Endpoint, HttpHeader } from '../';
24+
import {
25+
Endpoint,
26+
HttpHeader,
27+
RecaptchaClientType,
28+
RecaptchaVersion
29+
} from '../';
2530
import { mockEndpoint } from '../../../test/helpers/api/helper';
2631
import { testAuth, TestAuth } from '../../../test/helpers/mock_auth';
2732
import * as mockFetch from '../../../test/helpers/mock_fetch';
@@ -38,7 +43,10 @@ use(chaiAsPromised);
3843
describe('api/authentication/sendPhoneVerificationCode', () => {
3944
const request = {
4045
phoneNumber: '123456789',
41-
recaptchaToken: 'captchad'
46+
recaptchaToken: 'captchad',
47+
captchaResponse: 'captcha-response',
48+
clientType: RecaptchaClientType.WEB,
49+
recaptchaVersion: RecaptchaVersion.ENTERPRISE
4250
};
4351

4452
let auth: TestAuth;

packages/auth/src/api/authentication/sms.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import {
1919
Endpoint,
2020
HttpMethod,
21+
RecaptchaClientType,
22+
RecaptchaVersion,
2123
_addTidIfNecessary,
2224
_makeTaggedError,
2325
_performApiRequest,
@@ -30,8 +32,11 @@ import { Auth } from '../../model/public_types';
3032

3133
export interface SendPhoneVerificationCodeRequest {
3234
phoneNumber: string;
33-
recaptchaToken: string;
35+
recaptchaToken?: string;
3436
tenantId?: string;
37+
captchaResponse?: string;
38+
clientType?: RecaptchaClientType;
39+
recaptchaVersion?: RecaptchaVersion;
3540
}
3641

3742
export interface SendPhoneVerificationCodeResponse {

packages/auth/src/api/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ export const enum RecaptchaVersion {
8686
export const enum RecaptchaActionName {
8787
SIGN_IN_WITH_PASSWORD = 'signInWithPassword',
8888
GET_OOB_CODE = 'getOobCode',
89-
SIGN_UP_PASSWORD = 'signUpPassword'
89+
SIGN_UP_PASSWORD = 'signUpPassword',
90+
SEND_VERIFICATION_CODE = 'sendVerificationCode',
91+
MFA_SMS_ENROLLMENT = 'mfaSmsEnrollment',
92+
MFA_SMS_SIGNIN = 'mfaSmsSignin'
9093
}
9194

9295
export const enum EnforcementState {
@@ -98,7 +101,8 @@ export const enum EnforcementState {
98101

99102
// Providers that have reCAPTCHA Enterprise support.
100103
export const enum RecaptchaProvider {
101-
EMAIL_PASSWORD_PROVIDER = 'EMAIL_PASSWORD_PROVIDER'
104+
EMAIL_PASSWORD_PROVIDER = 'EMAIL_PASSWORD_PROVIDER',
105+
PHONE_PROVIDER = 'PHONE_PROVIDER'
102106
}
103107

104108
export const DEFAULT_API_TIMEOUT_MS = new Delay(30_000, 60_000);

packages/auth/src/platform_browser/recaptcha/recaptcha.test.ts

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import {
2929

3030
import { isV2, isEnterprise, RecaptchaConfig } from './recaptcha';
3131
import { GetRecaptchaConfigResponse } from '../../api/authentication/recaptcha';
32-
import { EnforcementState } from '../../api/index';
32+
import { EnforcementState, RecaptchaProvider } from '../../api/index';
3333

3434
use(chaiAsPromised);
3535
use(sinonChai);
@@ -46,7 +46,14 @@ describe('platform_browser/recaptcha/recaptcha', () => {
4646
const GET_RECAPTCHA_CONFIG_RESPONSE: GetRecaptchaConfigResponse = {
4747
recaptchaKey: 'projects/testproj/keys/' + TEST_SITE_KEY,
4848
recaptchaEnforcementState: [
49-
{ provider: 'EMAIL_PASSWORD_PROVIDER', enforcementState: 'ENFORCE' }
49+
{
50+
provider: RecaptchaProvider.EMAIL_PASSWORD_PROVIDER,
51+
enforcementState: EnforcementState.ENFORCE
52+
},
53+
{
54+
provider: RecaptchaProvider.PHONE_PROVIDER,
55+
enforcementState: EnforcementState.AUDIT
56+
}
5057
]
5158
};
5259

@@ -81,23 +88,62 @@ describe('platform_browser/recaptcha/recaptcha', () => {
8188
it('should construct the recaptcha config from the backend response', () => {
8289
expect(recaptchaConfig.siteKey).to.eq(TEST_SITE_KEY);
8390
expect(recaptchaConfig.recaptchaEnforcementState[0]).to.eql({
84-
provider: 'EMAIL_PASSWORD_PROVIDER',
85-
enforcementState: 'ENFORCE'
91+
provider: RecaptchaProvider.EMAIL_PASSWORD_PROVIDER,
92+
enforcementState: EnforcementState.ENFORCE
93+
});
94+
expect(recaptchaConfig.recaptchaEnforcementState[1]).to.eql({
95+
provider: RecaptchaProvider.PHONE_PROVIDER,
96+
enforcementState: EnforcementState.AUDIT
8697
});
8798
});
8899

89100
it('#getProviderEnforcementState should return the correct enforcement state of the provider', () => {
90101
expect(
91-
recaptchaConfig.getProviderEnforcementState('EMAIL_PASSWORD_PROVIDER')
102+
recaptchaConfig.getProviderEnforcementState(
103+
RecaptchaProvider.EMAIL_PASSWORD_PROVIDER
104+
)
92105
).to.eq(EnforcementState.ENFORCE);
106+
expect(
107+
recaptchaConfig.getProviderEnforcementState(
108+
RecaptchaProvider.PHONE_PROVIDER
109+
)
110+
).to.eq(EnforcementState.AUDIT);
93111
expect(recaptchaConfig.getProviderEnforcementState('invalid-provider')).to
94112
.be.null;
95113
});
96114

97115
it('#isProviderEnabled should return the enablement state of the provider', () => {
98-
expect(recaptchaConfig.isProviderEnabled('EMAIL_PASSWORD_PROVIDER')).to.be
99-
.true;
116+
expect(
117+
recaptchaConfig.isProviderEnabled(
118+
RecaptchaProvider.EMAIL_PASSWORD_PROVIDER
119+
)
120+
).to.be.true;
121+
expect(
122+
recaptchaConfig.isProviderEnabled(RecaptchaProvider.PHONE_PROVIDER)
123+
).to.be.true;
100124
expect(recaptchaConfig.isProviderEnabled('invalid-provider')).to.be.false;
101125
});
126+
127+
it('#isAnyProviderEnabled should return true if at least one provider is enabled', () => {
128+
expect(recaptchaConfig.isAnyProviderEnabled()).to.be.true;
129+
130+
const getRecaptchaConfigResponse: GetRecaptchaConfigResponse = {
131+
recaptchaKey: 'projects/testproj/keys/' + TEST_SITE_KEY,
132+
recaptchaEnforcementState: [
133+
{
134+
provider: RecaptchaProvider.EMAIL_PASSWORD_PROVIDER,
135+
enforcementState: EnforcementState.OFF
136+
},
137+
{
138+
provider: RecaptchaProvider.PHONE_PROVIDER,
139+
enforcementState: EnforcementState.OFF
140+
}
141+
]
142+
};
143+
const configNoProviderEnabled = new RecaptchaConfig(
144+
getRecaptchaConfigResponse
145+
);
146+
expect(configNoProviderEnabled.isAnyProviderEnabled()).to.be.false;
147+
});
102148
});
103149
});

packages/auth/src/platform_browser/recaptcha/recaptcha.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ import {
2020
GetRecaptchaConfigResponse,
2121
RecaptchaEnforcementProviderState
2222
} from '../../api/authentication/recaptcha';
23-
import { EnforcementState, _parseEnforcementState } from '../../api/index';
23+
import {
24+
EnforcementState,
25+
RecaptchaProvider,
26+
_parseEnforcementState
27+
} from '../../api/index';
2428

2529
// reCAPTCHA v2 interface
2630
export interface Recaptcha {
@@ -135,4 +139,17 @@ export class RecaptchaConfig {
135139
this.getProviderEnforcementState(providerStr) === EnforcementState.AUDIT
136140
);
137141
}
142+
143+
/**
144+
* Returns true if reCAPTCHA Enterprise protection is enabled in at least one provider, otherwise
145+
* returns false.
146+
*
147+
* @returns Whether or not reCAPTCHA Enterprise protection is enabled for at least one provider.
148+
*/
149+
isAnyProviderEnabled(): boolean {
150+
return (
151+
this.isProviderEnabled(RecaptchaProvider.EMAIL_PASSWORD_PROVIDER) ||
152+
this.isProviderEnabled(RecaptchaProvider.PHONE_PROVIDER)
153+
);
154+
}
138155
}

0 commit comments

Comments
 (0)