diff --git a/src/app.constants.ts b/src/app.constants.ts index d4ffe1e1ff..541a17632f 100644 --- a/src/app.constants.ts +++ b/src/app.constants.ts @@ -115,6 +115,7 @@ export const API_ENDPOINTS = { VERIFY_MFA_CODE: "/verify-mfa-code", ACCOUNT_RECOVERY: "/account-recovery", CHECK_REAUTH_USER: "/check-reauth-user", + CHECK_EMAIL_FRAUD_BLOCK: "/check-email-fraud-block", }; export const ERROR_MESSAGES = { diff --git a/src/components/check-email-fraud-block/checkEmailFraudBlockService.ts b/src/components/check-email-fraud-block/checkEmailFraudBlockService.ts new file mode 100644 index 0000000000..962df8f441 --- /dev/null +++ b/src/components/check-email-fraud-block/checkEmailFraudBlockService.ts @@ -0,0 +1,41 @@ +import { + createApiResponse, + getRequestConfig, + Http, + http, +} from "../../utils/http"; +import { API_ENDPOINTS } from "../../app.constants"; +import { ApiResponseResult } from "../../types"; +import { + CheckEmailFraudBlockInterface, + CheckEmailFraudBlockResponse, +} from "./types"; + +export function checkEmailFraudBlockService( + axios: Http = http +): CheckEmailFraudBlockInterface { + const checkEmailFraudBlock = async function ( + email: string, + sessionId: string, + sourceIp: string, + clientSessionId: string, + persistentSessionId: string + ): Promise> { + const response = await axios.client.post( + API_ENDPOINTS.CHECK_EMAIL_FRAUD_BLOCK, + { + email: email.toLowerCase(), + }, + getRequestConfig({ + sessionId: sessionId, + sourceIp: sourceIp, + clientSessionId: clientSessionId, + persistentSessionId: persistentSessionId, + }) + ); + return createApiResponse(response); + }; + return { + checkEmailFraudBlock, + }; +} diff --git a/src/components/check-email-fraud-block/types.ts b/src/components/check-email-fraud-block/types.ts new file mode 100644 index 0000000000..a4a4830dd0 --- /dev/null +++ b/src/components/check-email-fraud-block/types.ts @@ -0,0 +1,16 @@ +import { ApiResponseResult, DefaultApiResponse } from "../../types"; + +export interface CheckEmailFraudBlockInterface { + checkEmailFraudBlock: ( + email: string, + sessionId: string, + sourceIp: string, + clientSessionId: string, + persistentSessionId: string + ) => Promise>; +} + +export interface CheckEmailFraudBlockResponse extends DefaultApiResponse { + email: string; + isBlockedStatus: string; +} diff --git a/src/components/enter-email/tests/enter-email-controller.test.ts b/src/components/enter-email/tests/enter-email-controller.test.ts index 439c35d04b..e12a0486c9 100644 --- a/src/components/enter-email/tests/enter-email-controller.test.ts +++ b/src/components/enter-email/tests/enter-email-controller.test.ts @@ -16,6 +16,7 @@ import { SendNotificationServiceInterface } from "../../common/send-notification import { mockResponse, RequestOutput, ResponseOutput } from "mock-req-res"; import { CheckReauthServiceInterface } from "../../check-reauth-users/types"; import { createMockRequest } from "../../../../test/helpers/mock-request-helper"; +import { CheckEmailFraudBlockInterface } from "../../check-email-fraud-block/types"; describe("enter email controller", () => { let req: RequestOutput; @@ -23,6 +24,19 @@ describe("enter email controller", () => { let clock: sinon.SinonFakeTimers; const date = new Date(Date.UTC(2024, 1, 1)); + const checkReauthSuccessfulFakeService: CheckReauthServiceInterface = { + checkReauthUsers: sinon.fake.returns({ + success: true, + }), + } as unknown as CheckReauthServiceInterface; + + const checkEmailFraudFakeSuccessfulService: CheckEmailFraudBlockInterface = { + checkEmailFraudBlock: sinon.fake.returns({ + success: true, + data: { email: "test@test.com", isBlockedStatus: "Pending" }, + }), + } as unknown as CheckEmailFraudBlockInterface; + beforeEach(() => { res = mockResponse(); clock = sinon.useFakeTimers({ @@ -145,7 +159,11 @@ describe("enter email controller", () => { req.body.email = "test.test.com"; res.locals.sessionId = "dsad.dds"; - await enterEmailPost(fakeService)(req as Request, res as Response); + await enterEmailPost( + fakeService, + checkReauthSuccessfulFakeService, + checkEmailFraudFakeSuccessfulService + )(req as Request, res as Response); expect(fakeService.userExists).to.have.been.calledOnce; expect(res.redirect).to.have.calledWith(PATH_NAMES.ENTER_PASSWORD); @@ -162,7 +180,11 @@ describe("enter email controller", () => { req.body.email = "test.test.com"; res.locals.sessionId = "sadl990asdald"; - await enterEmailPost(fakeService)(req as Request, res as Response); + await enterEmailPost( + fakeService, + checkReauthSuccessfulFakeService, + checkEmailFraudFakeSuccessfulService + )(req as Request, res as Response); expect(res.redirect).to.have.calledWith(PATH_NAMES.ACCOUNT_NOT_FOUND); expect(fakeService.userExists).to.have.been.calledOnce; @@ -190,7 +212,11 @@ describe("enter email controller", () => { req.body.email = "test@test.com"; res.locals.sessionId = "sadl990asdald"; - await enterEmailPost(fakeService)(req as Request, res as Response); + await enterEmailPost( + fakeService, + checkReauthSuccessfulFakeService, + checkEmailFraudFakeSuccessfulService + )(req as Request, res as Response); const expectedLockTime = new Date( date.getTime() + lockTTlInSeconds * 1000 @@ -450,16 +476,11 @@ describe("enter email controller", () => { }), } as unknown as EnterEmailServiceInterface; - const successfulFakeService: CheckReauthServiceInterface = { - checkReauthUsers: sinon.fake.returns({ - success: true, - }), - } as unknown as CheckReauthServiceInterface; - - await enterEmailPost(fakeService, successfulFakeService)( - req as Request, - res as Response - ); + await enterEmailPost( + fakeService, + checkReauthSuccessfulFakeService, + checkEmailFraudFakeSuccessfulService + )(req as Request, res as Response); expect(res.redirect).to.have.calledWith(PATH_NAMES.ENTER_PASSWORD); }); diff --git a/src/components/enter-email/tests/enter-email-integration.test.ts b/src/components/enter-email/tests/enter-email-integration.test.ts index a863736a24..3768729b09 100644 --- a/src/components/enter-email/tests/enter-email-integration.test.ts +++ b/src/components/enter-email/tests/enter-email-integration.test.ts @@ -1,7 +1,6 @@ import request from "supertest"; import { describe } from "mocha"; import { expect, sinon } from "../../../../test/utils/test-utils"; -import nock = require("nock"); import * as cheerio from "cheerio"; import decache from "decache"; import { @@ -13,6 +12,7 @@ import { CheckReauthServiceInterface } from "../../check-reauth-users/types"; import { AxiosResponse } from "axios"; import { createApiResponse } from "../../../utils/http"; import { DefaultApiResponse } from "../../../types"; +import nock = require("nock"); describe("Integration::enter email", () => { let token: string | string[]; @@ -167,6 +167,13 @@ describe("Integration::enter email", () => { email: "test@test.com", doesUserExist: true, }); + nock(baseApi) + .post(API_ENDPOINTS.CHECK_EMAIL_FRAUD_BLOCK) + .once() + .reply(HTTP_STATUS_CODES.OK, { + email: "test@test.com", + isBlockedStatus: "Pending", + }); request(app) .post(PATH_NAMES.ENTER_EMAIL_SIGN_IN) @@ -185,6 +192,13 @@ describe("Integration::enter email", () => { email: "test@test.com", doesUserExist: false, }); + nock(baseApi) + .post(API_ENDPOINTS.CHECK_EMAIL_FRAUD_BLOCK) + .once() + .reply(HTTP_STATUS_CODES.OK, { + email: "test@test.com", + isBlockedStatus: "Pending", + }); request(app) .post(PATH_NAMES.ENTER_EMAIL_SIGN_IN) @@ -236,6 +250,14 @@ describe("Integration::enter email", () => { doesUserExist: true, }); + nock(baseApi) + .post(API_ENDPOINTS.CHECK_EMAIL_FRAUD_BLOCK) + .once() + .reply(HTTP_STATUS_CODES.OK, { + email: "test@test.com", + isBlockedStatus: "Pending", + }); + request(app) .post(PATH_NAMES.ENTER_EMAIL_SIGN_IN) .type("form")