diff --git a/.env.example b/.env.example index a1c6f7dd9b..7ee1b254c6 100644 --- a/.env.example +++ b/.env.example @@ -110,4 +110,5 @@ GOV_UK_PAY_TOKEN_GLOUCESTER=👻 GOV_UK_PAY_TOKEN_MEDWAY=👻 ## End-to-end test team (borrows Lambeth's details) +GOV_UK_PAY_SECRET_E2E=👻 GOV_UK_PAY_TOKEN_E2E=👻 diff --git a/api.planx.uk/modules/pay/controller.ts b/api.planx.uk/modules/pay/controller.ts index 45aa7798ec..4b2c0266b0 100644 --- a/api.planx.uk/modules/pay/controller.ts +++ b/api.planx.uk/modules/pay/controller.ts @@ -60,6 +60,7 @@ export const makePaymentViaProxy: PaymentProxyController = async ( ), }, req, + res, )(req, res, next); }; @@ -101,6 +102,7 @@ export const makeInviteToPayPaymentViaProxy: PaymentRequestProxyController = ( }), }, req, + res, )(req, res, next); }; @@ -151,6 +153,7 @@ export function fetchPaymentViaProxyWithCallback( }), }, req, + res, )(req, res, next); }; } diff --git a/api.planx.uk/modules/pay/index.test.ts b/api.planx.uk/modules/pay/index.test.ts index 4f7b5a0e01..f2b9d5a6f4 100644 --- a/api.planx.uk/modules/pay/index.test.ts +++ b/api.planx.uk/modules/pay/index.test.ts @@ -10,6 +10,11 @@ jest.mock("@opensystemslab/planx-core", () => { session: { findDetails: jest.fn().mockImplementation(() => ({ lockedAt: null })), }, + team: { + getIntegrations: jest + .fn() + .mockImplementation(() => ({ govPayToken: "abc123" })), + }, })), }; }); diff --git a/api.planx.uk/modules/pay/middleware.ts b/api.planx.uk/modules/pay/middleware.ts index 9c2f6b1c32..e11a537714 100644 --- a/api.planx.uk/modules/pay/middleware.ts +++ b/api.planx.uk/modules/pay/middleware.ts @@ -5,19 +5,26 @@ import { ServerError } from "../../errors"; /** * Confirm that this local authority (aka team) has a pay token - * TODO: Check this against a DB value instead of env vars? */ -export const isTeamUsingGovPay: RequestHandler = (req, _res, next) => { - const isSupported = - process.env[`GOV_UK_PAY_TOKEN_${req.params.localAuthority.toUpperCase()}`]; +export const isTeamUsingGovPay: RequestHandler = async (req, res, next) => { + const env = + process.env.APP_ENVIRONMENT === "production" ? "production" : "staging"; - if (!isSupported) { + const { govPayToken } = await $api.team.getIntegrations({ + env, + slug: req.params.localAuthority, + encryptionKey: process.env.ENCRYPTION_KEY!, + }); + + if (!govPayToken) { return next({ status: 400, message: `GOV.UK Pay is not enabled for this local authority (${req.params.localAuthority})`, }); } + res.locals.govPayToken = govPayToken; + next(); }; diff --git a/api.planx.uk/modules/pay/proxy.ts b/api.planx.uk/modules/pay/proxy.ts index 66d9ee47a5..f6507fcb89 100644 --- a/api.planx.uk/modules/pay/proxy.ts +++ b/api.planx.uk/modules/pay/proxy.ts @@ -1,19 +1,19 @@ -import { Request } from "express"; +import { Response, Request } from "express"; import { fixRequestBody, Options } from "http-proxy-middleware"; import { useProxy } from "../../shared/middleware/proxy"; -export const usePayProxy = (options: Partial, req: Request) => { +export const usePayProxy = ( + options: Partial, + req: Request, + res: Response, +) => { return useProxy({ target: "https://publicapi.payments.service.gov.uk/v1/payments", onProxyReq: fixRequestBody, headers: { ...(req.headers as NodeJS.Dict), "content-type": "application/json", - Authorization: `Bearer ${ - process.env[ - `GOV_UK_PAY_TOKEN_${req.params.localAuthority}`.toUpperCase() - ] - }`, + Authorization: `Bearer ${res.locals.govPayToken}`, }, ...options, }); diff --git a/api.planx.uk/tests/serverErrorHandler.test.js b/api.planx.uk/tests/serverErrorHandler.test.js deleted file mode 100644 index f9711ac3c9..0000000000 --- a/api.planx.uk/tests/serverErrorHandler.test.js +++ /dev/null @@ -1,54 +0,0 @@ -import supertest from "supertest"; -import app from "../server"; -import nock from "nock"; - -const { get, post } = supertest(app); - -describe("bad requests", () => { - test.skip(`app.post("/bops/:localAuthority")`, async () => { - await post("/bops/wrong").expect(404); - }); - - test(`app.post("/pay/:localAuthority")`, async () => { - nock("https://publicapi.payments.service.gov.uk") - .post("/v1/payments") - .reply(400); - - await post("/pay/wrong").expect(400); - }); - - test(`app.get("/pay/:localAuthority/:paymentId")`, async () => { - nock("https://publicapi.payments.service.gov.uk") - .get("/v1/payments/1") - .reply(400, { - payment_id: 123, - amount: 0, - state: "paid", - payment_provider: "sandbox", - }); - - await get("/pay/wrong/1").expect(400); - }); - - test(`app.get("/gis")`, async () => { - await get("/gis").expect(404); - }); - - test(`app.get("/gis/wrong")`, async () => { - await get("/gis/wrong") - .expect(400) - .then((response) => { - expect(response.body).toEqual({ - error: "wrong is not a supported local authority", - }); - }); - }); - - test(`app.post("/flows/:flowId/publish")`, async () => { - await post("/flows/WRONG/publish").expect(401); - }); - - test(`app.post("/flows/:flowId/download-schema")`, async () => { - await post("/flows/WRONG/download-schema").expect(404); - }); -}); diff --git a/e2e/tests/ui-driven/src/context.ts b/e2e/tests/ui-driven/src/context.ts index 6419acec0f..ba852faaf9 100644 --- a/e2e/tests/ui-driven/src/context.ts +++ b/e2e/tests/ui-driven/src/context.ts @@ -82,6 +82,8 @@ export async function setUpTestContext( publisherId: context.user!.id!, }); } + await setupGovPaySecret($admin, context); + return context; } @@ -327,3 +329,29 @@ async function deleteTeam(adminGQLClient: GraphQLClient, context: Context) { } } } + +async function setupGovPaySecret($admin: CoreDomainClient, context: Context) { + try { + await $admin.client.request( + gql` + mutation SetupGovPaySecret( + $team_id: Int + $staging_govpay_secret: String + ) { + update_team_integrations( + where: { team_id: { _eq: $team_id } } + _set: { staging_govpay_secret: $staging_govpay_secret } + ) { + affected_rows + } + } + `, + { + team_id: context.team.id, + staging_govpay_secret: process.env.GOV_UK_PAY_SECRET_E2E, + }, + ); + } catch (error) { + throw Error("Failed to setup GovPay secret for E2E team"); + } +}