Skip to content

Commit 53c51dc

Browse files
author
renkelvin
committed
Revert "Create handleRecaptchaFlow helper method"
This reverts commit 6b934c9.
1 parent 6b934c9 commit 53c51dc

File tree

6 files changed

+142
-166
lines changed

6 files changed

+142
-166
lines changed

.changeset/lucky-dragons-juggle.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/auth/src/core/credentials/email.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import { IdTokenResponse } from '../../model/id_token';
3131
import { AuthErrorCode } from '../errors';
3232
import { _fail } from '../util/assert';
3333
import { AuthCredential } from './auth_credential';
34-
import { handleRecaptchaFlow } from '../../platform_browser/recaptcha/recaptcha_enterprise_verifier';
34+
import { injectRecaptchaFields } from '../../platform_browser/recaptcha/recaptcha_enterprise_verifier';
3535
import { RecaptchaActionName, RecaptchaClientType } from '../../api';
3636
/**
3737
* Interface that represents the credentials returned by {@link EmailAuthProvider} for
@@ -123,12 +123,32 @@ export class EmailAuthCredential extends AuthCredential {
123123
password: this._password,
124124
clientType: RecaptchaClientType.WEB
125125
};
126-
return handleRecaptchaFlow(
127-
auth,
128-
request,
129-
RecaptchaActionName.SIGN_IN_WITH_PASSWORD,
130-
signInWithPassword
131-
);
126+
if (auth._getRecaptchaConfig()?.emailPasswordEnabled) {
127+
const requestWithRecaptcha = await injectRecaptchaFields(
128+
auth,
129+
request,
130+
RecaptchaActionName.SIGN_IN_WITH_PASSWORD
131+
);
132+
return signInWithPassword(auth, requestWithRecaptcha);
133+
} else {
134+
return signInWithPassword(auth, request).catch(async error => {
135+
if (
136+
error.code === `auth/${AuthErrorCode.MISSING_RECAPTCHA_TOKEN}`
137+
) {
138+
console.log(
139+
'Sign-in with email address and password is protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the sign-in flow.'
140+
);
141+
const requestWithRecaptcha = await injectRecaptchaFields(
142+
auth,
143+
request,
144+
RecaptchaActionName.SIGN_IN_WITH_PASSWORD
145+
);
146+
return signInWithPassword(auth, requestWithRecaptcha);
147+
} else {
148+
return Promise.reject(error);
149+
}
150+
});
151+
}
132152
case SignInMethod.EMAIL_LINK:
133153
return signInWithEmailLink(auth, {
134154
email: this._email,

packages/auth/src/core/strategies/email_and_password.ts

Lines changed: 81 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { _castAuth } from '../auth/auth_impl';
3636
import { AuthErrorCode } from '../errors';
3737
import { getModularInstance } from '@firebase/util';
3838
import { OperationType } from '../../model/enums';
39-
import { handleRecaptchaFlow } from '../../platform_browser/recaptcha/recaptcha_enterprise_verifier';
39+
import { injectRecaptchaFields } from '../../platform_browser/recaptcha/recaptcha_enterprise_verifier';
4040
import { IdTokenResponse } from '../../model/id_token';
4141
import { RecaptchaActionName, RecaptchaClientType } from '../../api';
4242

@@ -103,15 +103,61 @@ export async function sendPasswordResetEmail(
103103
email,
104104
clientType: RecaptchaClientType.WEB
105105
};
106-
if (actionCodeSettings) {
107-
_setActionCodeSettingsOnRequest(authInternal, request, actionCodeSettings);
106+
if (authInternal._getRecaptchaConfig()?.emailPasswordEnabled) {
107+
const requestWithRecaptcha = await injectRecaptchaFields(
108+
authInternal,
109+
request,
110+
RecaptchaActionName.GET_OOB_CODE,
111+
true
112+
);
113+
if (actionCodeSettings) {
114+
_setActionCodeSettingsOnRequest(
115+
authInternal,
116+
requestWithRecaptcha,
117+
actionCodeSettings
118+
);
119+
}
120+
await authentication.sendPasswordResetEmail(
121+
authInternal,
122+
requestWithRecaptcha
123+
);
124+
} else {
125+
if (actionCodeSettings) {
126+
_setActionCodeSettingsOnRequest(
127+
authInternal,
128+
request,
129+
actionCodeSettings
130+
);
131+
}
132+
await authentication
133+
.sendPasswordResetEmail(authInternal, request)
134+
.catch(async error => {
135+
if (error.code === `auth/${AuthErrorCode.MISSING_RECAPTCHA_TOKEN}`) {
136+
console.log(
137+
'Password resets are protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the password reset flow.'
138+
);
139+
const requestWithRecaptcha = await injectRecaptchaFields(
140+
authInternal,
141+
request,
142+
RecaptchaActionName.GET_OOB_CODE,
143+
true
144+
);
145+
if (actionCodeSettings) {
146+
_setActionCodeSettingsOnRequest(
147+
authInternal,
148+
requestWithRecaptcha,
149+
actionCodeSettings
150+
);
151+
}
152+
await authentication.sendPasswordResetEmail(
153+
authInternal,
154+
requestWithRecaptcha
155+
);
156+
} else {
157+
return Promise.reject(error);
158+
}
159+
});
108160
}
109-
await handleRecaptchaFlow(
110-
authInternal,
111-
request,
112-
RecaptchaActionName.GET_OOB_CODE,
113-
authentication.sendPasswordResetEmail
114-
);
115161
}
116162

117163
/**
@@ -272,12 +318,32 @@ export async function createUserWithEmailAndPassword(
272318
password,
273319
clientType: RecaptchaClientType.WEB
274320
};
275-
const signUpResponse: Promise<IdTokenResponse> = handleRecaptchaFlow(
276-
authInternal,
277-
request,
278-
RecaptchaActionName.SIGN_UP_PASSWORD,
279-
signUp
280-
);
321+
let signUpResponse: Promise<IdTokenResponse>;
322+
if (authInternal._getRecaptchaConfig()?.emailPasswordEnabled) {
323+
const requestWithRecaptcha = await injectRecaptchaFields(
324+
authInternal,
325+
request,
326+
RecaptchaActionName.SIGN_UP_PASSWORD
327+
);
328+
signUpResponse = signUp(authInternal, requestWithRecaptcha);
329+
} else {
330+
signUpResponse = signUp(authInternal, request).catch(async error => {
331+
if (error.code === `auth/${AuthErrorCode.MISSING_RECAPTCHA_TOKEN}`) {
332+
console.log(
333+
'Sign-up is protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the sign-up flow.'
334+
);
335+
const requestWithRecaptcha = await injectRecaptchaFields(
336+
authInternal,
337+
request,
338+
RecaptchaActionName.SIGN_UP_PASSWORD
339+
);
340+
return signUp(authInternal, requestWithRecaptcha);
341+
}
342+
343+
throw error;
344+
});
345+
}
346+
281347
const response = await signUpResponse.catch(error => {
282348
if (
283349
error.code === `auth/${AuthErrorCode.PASSWORD_DOES_NOT_MEET_REQUIREMENTS}`

packages/auth/src/core/strategies/email_link.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { AuthErrorCode } from '../errors';
3232
import { _assert } from '../util/assert';
3333
import { getModularInstance } from '@firebase/util';
3434
import { _castAuth } from '../auth/auth_impl';
35-
import { handleRecaptchaFlow } from '../../platform_browser/recaptcha/recaptcha_enterprise_verifier';
35+
import { injectRecaptchaFields } from '../../platform_browser/recaptcha/recaptcha_enterprise_verifier';
3636
import { RecaptchaActionName, RecaptchaClientType } from '../../api';
3737

3838
/**
@@ -101,13 +101,37 @@ export async function sendSignInLinkToEmail(
101101
);
102102
}
103103
}
104-
setActionCodeSettings(request, actionCodeSettings);
105-
await handleRecaptchaFlow(
106-
authInternal,
107-
request,
108-
RecaptchaActionName.GET_OOB_CODE,
109-
api.sendSignInLinkToEmail
110-
);
104+
if (authInternal._getRecaptchaConfig()?.emailPasswordEnabled) {
105+
const requestWithRecaptcha = await injectRecaptchaFields(
106+
authInternal,
107+
request,
108+
RecaptchaActionName.GET_OOB_CODE,
109+
true
110+
);
111+
setActionCodeSettings(requestWithRecaptcha, actionCodeSettings);
112+
await api.sendSignInLinkToEmail(authInternal, requestWithRecaptcha);
113+
} else {
114+
setActionCodeSettings(request, actionCodeSettings);
115+
await api
116+
.sendSignInLinkToEmail(authInternal, request)
117+
.catch(async error => {
118+
if (error.code === `auth/${AuthErrorCode.MISSING_RECAPTCHA_TOKEN}`) {
119+
console.log(
120+
'Email link sign-in is protected by reCAPTCHA for this project. Automatically triggering the reCAPTCHA flow and restarting the sign-in flow.'
121+
);
122+
const requestWithRecaptcha = await injectRecaptchaFields(
123+
authInternal,
124+
request,
125+
RecaptchaActionName.GET_OOB_CODE,
126+
true
127+
);
128+
setActionCodeSettings(requestWithRecaptcha, actionCodeSettings);
129+
await api.sendSignInLinkToEmail(authInternal, requestWithRecaptcha);
130+
} else {
131+
return Promise.reject(error);
132+
}
133+
});
134+
}
111135
}
112136

113137
/**

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

Lines changed: 2 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,16 @@ import chaiAsPromised from 'chai-as-promised';
2020
import * as sinon from 'sinon';
2121
import sinonChai from 'sinon-chai';
2222

23-
import {
24-
Endpoint,
25-
RecaptchaClientType,
26-
RecaptchaVersion,
27-
RecaptchaActionName
28-
} from '../../api';
23+
import { Endpoint, RecaptchaClientType, RecaptchaVersion } from '../../api';
2924
import { mockEndpointWithParams } from '../../../test/helpers/api/helper';
3025
import { testAuth, TestAuth } from '../../../test/helpers/mock_auth';
3126
import * as mockFetch from '../../../test/helpers/mock_fetch';
3227
import { ServerError } from '../../api/errors';
33-
import { AuthInternal } from '../../model/auth';
3428

3529
import { MockGreCAPTCHATopLevel } from './recaptcha_mock';
3630
import {
3731
RecaptchaEnterpriseVerifier,
38-
FAKE_TOKEN,
39-
handleRecaptchaFlow
32+
FAKE_TOKEN
4033
} from './recaptcha_enterprise_verifier';
4134

4235
use(chaiAsPromised);
@@ -124,86 +117,4 @@ describe('platform_browser/recaptcha/recaptcha_enterprise_verifier', () => {
124117
expect(await verifier.verify()).to.eq(FAKE_TOKEN);
125118
});
126119
});
127-
128-
context('handleRecaptchaFlow', () => {
129-
let mockAuthInstance: AuthInternal;
130-
let mockRequest: any;
131-
let mockActionMethod: sinon.SinonStub;
132-
133-
beforeEach(async () => {
134-
mockAuthInstance = await testAuth();
135-
mockRequest = {};
136-
mockActionMethod = sinon.stub();
137-
});
138-
139-
afterEach(() => {
140-
sinon.restore();
141-
});
142-
143-
it('should handle recaptcha when emailPasswordEnabled is true', async () => {
144-
if (typeof window === 'undefined') {
145-
return;
146-
}
147-
sinon.stub(mockAuthInstance, '_getRecaptchaConfig').returns({
148-
emailPasswordEnabled: true,
149-
siteKey: 'mock_site_key'
150-
});
151-
mockActionMethod.resolves('success');
152-
153-
const result = await handleRecaptchaFlow(
154-
mockAuthInstance,
155-
mockRequest,
156-
RecaptchaActionName.GET_OOB_CODE,
157-
mockActionMethod
158-
);
159-
160-
expect(result).to.equal('success');
161-
expect(mockActionMethod).to.have.been.calledOnce;
162-
});
163-
164-
it('should handle action without recaptcha when emailPasswordEnabled is false and no error', async () => {
165-
if (typeof window === 'undefined') {
166-
return;
167-
}
168-
sinon.stub(mockAuthInstance, '_getRecaptchaConfig').returns({
169-
emailPasswordEnabled: false,
170-
siteKey: 'mock_site_key'
171-
});
172-
mockActionMethod.resolves('success');
173-
174-
const result = await handleRecaptchaFlow(
175-
mockAuthInstance,
176-
mockRequest,
177-
RecaptchaActionName.GET_OOB_CODE,
178-
mockActionMethod
179-
);
180-
181-
expect(result).to.equal('success');
182-
expect(mockActionMethod).to.have.been.calledOnce;
183-
});
184-
185-
it('should handle MISSING_RECAPTCHA_TOKEN error when emailPasswordEnabled is false', async () => {
186-
if (typeof window === 'undefined') {
187-
return;
188-
}
189-
sinon.stub(mockAuthInstance, '_getRecaptchaConfig').returns({
190-
emailPasswordEnabled: false,
191-
siteKey: 'mock_site_key'
192-
});
193-
mockActionMethod.onFirstCall().rejects({
194-
code: 'auth/MISSING_RECAPTCHA_TOKEN'
195-
});
196-
mockActionMethod.onSecondCall().resolves('success-after-recaptcha');
197-
198-
const result = await handleRecaptchaFlow(
199-
mockAuthInstance,
200-
mockRequest,
201-
RecaptchaActionName.GET_OOB_CODE,
202-
mockActionMethod
203-
);
204-
205-
expect(result).to.equal('success-after-recaptcha');
206-
expect(mockActionMethod).to.have.been.calledTwice;
207-
});
208-
});
209120
});

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

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import { Auth } from '../../model/public_types';
2828
import { AuthInternal } from '../../model/auth';
2929
import { _castAuth } from '../../core/auth/auth_impl';
3030
import * as jsHelpers from '../load_js';
31-
import { AuthErrorCode } from '../../core/errors';
3231

3332
const RECAPTCHA_ENTERPRISE_URL =
3433
'https://www.google.com/recaptcha/enterprise.js?render=';
@@ -176,45 +175,6 @@ export async function injectRecaptchaFields<T>(
176175
return newRequest;
177176
}
178177

179-
type ActionMethod<TRequest, TResponse> = (
180-
auth: Auth,
181-
request: TRequest
182-
) => Promise<TResponse>;
183-
184-
export async function handleRecaptchaFlow<TRequest, TResponse>(
185-
authInstance: AuthInternal,
186-
request: TRequest,
187-
actionName: RecaptchaActionName,
188-
actionMethod: ActionMethod<TRequest, TResponse>
189-
): Promise<TResponse> {
190-
if (authInstance._getRecaptchaConfig()?.emailPasswordEnabled) {
191-
const requestWithRecaptcha = await injectRecaptchaFields(
192-
authInstance,
193-
request,
194-
actionName,
195-
actionName === RecaptchaActionName.GET_OOB_CODE
196-
);
197-
return actionMethod(authInstance, requestWithRecaptcha);
198-
} else {
199-
return actionMethod(authInstance, request).catch(async error => {
200-
if (error.code === `auth/${AuthErrorCode.MISSING_RECAPTCHA_TOKEN}`) {
201-
console.log(
202-
`${actionName} is protected by reCAPTCHA Enterprise for this project. Automatically triggering the reCAPTCHA flow and restarting the flow.`
203-
);
204-
const requestWithRecaptcha = await injectRecaptchaFields(
205-
authInstance,
206-
request,
207-
actionName,
208-
actionName === RecaptchaActionName.GET_OOB_CODE
209-
);
210-
return actionMethod(authInstance, requestWithRecaptcha);
211-
} else {
212-
return Promise.reject(error);
213-
}
214-
});
215-
}
216-
}
217-
218178
export async function _initializeRecaptchaConfig(auth: Auth): Promise<void> {
219179
const authInternal = _castAuth(auth);
220180

0 commit comments

Comments
 (0)