diff --git a/localenv/cloud-nine-wallet/docker-compose.yml b/localenv/cloud-nine-wallet/docker-compose.yml index 34654b2b1b..320baf8ded 100644 --- a/localenv/cloud-nine-wallet/docker-compose.yml +++ b/localenv/cloud-nine-wallet/docker-compose.yml @@ -22,6 +22,7 @@ services: GRAPHQL_URL: http://cloud-nine-wallet-backend:3001/graphql SIGNATURE_VERSION: 1 SIGNATURE_SECRET: iyIgCprjb9uL8wFckR+pLEkJWMB7FJhgkvqhTQR/964= + IDP_SECRET: 2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE= volumes: - ../cloud-nine-wallet/seed.yml:/workspace/seed.yml - ../cloud-nine-wallet/private-key.pem:/workspace/private-key.pem diff --git a/localenv/happy-life-bank/docker-compose.yml b/localenv/happy-life-bank/docker-compose.yml index 39faf19a95..461ba0ad58 100644 --- a/localenv/happy-life-bank/docker-compose.yml +++ b/localenv/happy-life-bank/docker-compose.yml @@ -18,6 +18,7 @@ services: GRAPHQL_URL: http://happy-life-bank-backend:3001/graphql SIGNATURE_VERSION: 1 SIGNATURE_SECRET: iyIgCprjb9uL8wFckR+pLEkJWMB7FJhgkvqhTQR/964= + IDP_SECRET: 2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE= volumes: - ../happy-life-bank/seed.yml:/workspace/seed.yml - ../happy-life-bank/private-key.pem:/workspace/private-key.pem diff --git a/localenv/mock-account-servicing-entity/app/lib/apiClient.ts b/localenv/mock-account-servicing-entity/app/lib/apiClient.ts index 647db922ec..0c4b525612 100644 --- a/localenv/mock-account-servicing-entity/app/lib/apiClient.ts +++ b/localenv/mock-account-servicing-entity/app/lib/apiClient.ts @@ -8,8 +8,6 @@ export const StepNames = { endInteraction: 3 } -const IDP_SECRET = '2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE=' - /* eslint-disable-next-line @typescript-eslint/no-explicit-any */ export type ApiResponse = ( | { @@ -34,7 +32,8 @@ export class ApiClient { */ public static async getGrant( - params: Record + params: Record, + idpSecret: string ): Promise { // get grant --> GET /grant/:id/:nonce const { interactId, nonce } = params @@ -42,7 +41,7 @@ export class ApiClient { `http://localhost:3006/grant/${interactId}/${nonce}`, { headers: { - 'x-idp-secret': IDP_SECRET + 'x-idp-secret': idpSecret } } ) @@ -65,7 +64,8 @@ export class ApiClient { public static async chooseConsent( interactId: string, nonce: string, - acceptanceDecision: boolean + acceptanceDecision: boolean, + idpSecret: string ): Promise>> { // make choice --> POST /grant/:id/:nonce/accept or /grant/:id/:nonce/reject const acceptanceSubPath = acceptanceDecision ? 'accept' : 'reject' @@ -75,7 +75,7 @@ export class ApiClient { {}, { headers: { - 'x-idp-secret': IDP_SECRET + 'x-idp-secret': idpSecret } } ) diff --git a/localenv/mock-account-servicing-entity/app/lib/parse_config.server.ts b/localenv/mock-account-servicing-entity/app/lib/parse_config.server.ts index dcba8553b2..dffdc3c378 100644 --- a/localenv/mock-account-servicing-entity/app/lib/parse_config.server.ts +++ b/localenv/mock-account-servicing-entity/app/lib/parse_config.server.ts @@ -3,6 +3,10 @@ import { readFileSync } from 'fs' import { loadOrGenerateKey } from '@interledger/http-signature-utils' import type { Config } from 'mock-account-service-lib' +if (!process.env.IDP_SECRET) { + throw new Error('environment variable IDP_SECRET is required') +} + export const CONFIG: Config = { seed: parse( readFileSync( @@ -13,5 +17,6 @@ export const CONFIG: Config = { publicHost: process.env.OPEN_PAYMENTS_URL ?? '', testnetAutoPeerUrl: process.env.TESTNET_AUTOPEER_URL ?? '', authServerDomain: process.env.AUTH_SERVER_DOMAIN || 'http://localhost:3006', - graphqlUrl: process.env.GRAPHQL_URL ?? '' + graphqlUrl: process.env.GRAPHQL_URL ?? '', + idpSecret: process.env.IDP_SECRET } diff --git a/localenv/mock-account-servicing-entity/app/routes/consent-screen.tsx b/localenv/mock-account-servicing-entity/app/routes/consent-screen.tsx index 24b6217eea..e005d60d88 100644 --- a/localenv/mock-account-servicing-entity/app/routes/consent-screen.tsx +++ b/localenv/mock-account-servicing-entity/app/routes/consent-screen.tsx @@ -213,7 +213,11 @@ function PreConsentScreen({ ) } -export default function ConsentScreen() { +type ConsentScreenProps = { + idpSecret: string +} + +export default function ConsentScreen({ idpSecret }: ConsentScreenProps) { const [ctx, setCtx] = useState({ ready: false, thirdPartyName: '', @@ -261,10 +265,13 @@ export default function ConsentScreen() { if (ctx.errors.length === 0 && ctx.ready && !ctx.accesses) { const { interactId, nonce } = ctx - ApiClient.getGrant({ - interactId, - nonce - }) + ApiClient.getGrant( + { + interactId, + nonce + }, + idpSecret + ) .then((response) => { if (response.isFailure) { setCtx({ diff --git a/localenv/mock-account-servicing-entity/app/routes/mock-idp._index.tsx b/localenv/mock-account-servicing-entity/app/routes/mock-idp._index.tsx index 90da41f13b..e5946feaa4 100644 --- a/localenv/mock-account-servicing-entity/app/routes/mock-idp._index.tsx +++ b/localenv/mock-account-servicing-entity/app/routes/mock-idp._index.tsx @@ -1,5 +1,13 @@ import ConsentScreen from '~/routes/consent-screen' +import { json } from '@remix-run/node' +import { useLoaderData } from '@remix-run/react' +import { CONFIG } from '~/lib/parse_config.server' + +export function loader() { + return json({ idpSecret: CONFIG.idpSecret }) +} export default function Index() { - return + const { idpSecret } = useLoaderData() + return } diff --git a/localenv/mock-account-servicing-entity/app/routes/shoe-shop.tsx b/localenv/mock-account-servicing-entity/app/routes/shoe-shop.tsx index 1b7fa81baf..354885c887 100644 --- a/localenv/mock-account-servicing-entity/app/routes/shoe-shop.tsx +++ b/localenv/mock-account-servicing-entity/app/routes/shoe-shop.tsx @@ -1,10 +1,13 @@ -import { useLoaderData, useLocation } from '@remix-run/react' +import { useLoaderData, useLocation, json } from '@remix-run/react' import { useEffect, useState } from 'react' import { ApiClient } from '~/lib/apiClient' import { CONFIG as config } from '~/lib/parse_config.server' export function loader() { - return config.authServerDomain + return json({ + authServerDomain: config.authServerDomain, + idpSecret: config.idpSecret + }) } function AuthorizedView({ @@ -12,15 +15,16 @@ function AuthorizedView({ currencyDisplayCode, amount, interactId, - nonce + nonce, + authServerDomain }: { thirdPartyName: string currencyDisplayCode: string amount: number interactId: string nonce: string + authServerDomain: string }) { - const authServerDomain = useLoaderData() return ( <>
@@ -53,13 +57,14 @@ function AuthorizedView({ function RejectedView({ thirdPartyName, interactId, - nonce + nonce, + authServerDomain }: { thirdPartyName: string interactId: string nonce: string + authServerDomain: string }) { - const authServerDomain = useLoaderData() return ( <>
@@ -87,6 +92,7 @@ function RejectedView({ } export default function ShoeShop() { + const { idpSecret, authServerDomain } = useLoaderData() const location = useLocation() const queryParams = new URLSearchParams(location.search) const [ctx, setCtx] = useState({ @@ -112,7 +118,12 @@ export default function ShoeShop() { if (interactId && nonce) { const acceptanceDecision = !!decision && decision.toLowerCase() === 'accept' - ApiClient.chooseConsent(interactId, nonce, acceptanceDecision) + ApiClient.chooseConsent( + interactId, + nonce, + acceptanceDecision, + idpSecret + ) .then((_consentResponse) => { setCtx({ ...ctx, @@ -180,12 +191,14 @@ export default function ShoeShop() { amount={ctx.amount} interactId={ctx.interactId} nonce={ctx.nonce} + authServerDomain={authServerDomain} /> ) : ( )}
diff --git a/packages/mock-account-service-lib/src/types.ts b/packages/mock-account-service-lib/src/types.ts index 8909f608ad..76c90bfda8 100644 --- a/packages/mock-account-service-lib/src/types.ts +++ b/packages/mock-account-service-lib/src/types.ts @@ -48,6 +48,7 @@ export interface Config { testnetAutoPeerUrl: string authServerDomain: string graphqlUrl: string + idpSecret: string } export interface Webhook { id: string diff --git a/test/integration/lib/config.ts b/test/integration/lib/config.ts index 683fa708c7..d5802e9ef0 100644 --- a/test/integration/lib/config.ts +++ b/test/integration/lib/config.ts @@ -19,6 +19,7 @@ type EnvConfig = { WALLET_ADDRESS_URL: string GRAPHQL_URL: string KEY_ID: string + IDP_SECRET: string } const REQUIRED_KEYS: (keyof EnvConfig)[] = [ 'OPEN_PAYMENTS_URL', @@ -26,7 +27,8 @@ const REQUIRED_KEYS: (keyof EnvConfig)[] = [ 'INTEGRATION_SERVER_PORT', 'WALLET_ADDRESS_URL', 'GRAPHQL_URL', - 'KEY_ID' + 'KEY_ID', + 'IDP_SECRET' ] const loadEnv = (filePath: string): EnvConfig => { @@ -62,7 +64,8 @@ const createConfig = (name: string): TestConfig => { integrationServerPort: parseInt(env.INTEGRATION_SERVER_PORT), walletAddressUrl: env.WALLET_ADDRESS_URL, graphqlUrl: env.GRAPHQL_URL, - keyId: env.KEY_ID + keyId: env.KEY_ID, + idpSecret: env.IDP_SECRET } } diff --git a/test/integration/lib/test-actions/index.ts b/test/integration/lib/test-actions/index.ts index 77c8551fd7..e975ae4fda 100644 --- a/test/integration/lib/test-actions/index.ts +++ b/test/integration/lib/test-actions/index.ts @@ -46,9 +46,11 @@ async function consentInteraction( outgoingPaymentGrant: PendingGrant, senderWalletAddress: WalletAddress ) { + const { idpSecret } = deps.sendingASE.config const { interactId, nonce, cookie } = await _startAndAcceptInteraction( outgoingPaymentGrant, - senderWalletAddress + senderWalletAddress, + idpSecret ) // Finish interacton @@ -57,7 +59,7 @@ async function consentInteraction( { method: 'GET', headers: { - 'x-idp-secret': '2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE=', + 'x-idp-secret': idpSecret, cookie } } @@ -70,9 +72,11 @@ async function consentInteractionWithInteractRef( outgoingPaymentGrant: PendingGrant, senderWalletAddress: WalletAddress ): Promise { + const { idpSecret } = deps.sendingASE.config const { interactId, nonce, cookie } = await _startAndAcceptInteraction( outgoingPaymentGrant, - senderWalletAddress + senderWalletAddress, + idpSecret ) // Finish interacton @@ -81,7 +85,7 @@ async function consentInteractionWithInteractRef( { method: 'GET', headers: { - 'x-idp-secret': '2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE=', + 'x-idp-secret': idpSecret, cookie }, redirect: 'manual' // dont follow redirects @@ -101,7 +105,8 @@ async function consentInteractionWithInteractRef( async function _startAndAcceptInteraction( outgoingPaymentGrant: PendingGrant, - senderWalletAddress: WalletAddress + senderWalletAddress: WalletAddress, + idpSecret: string ): Promise<{ nonce: string; interactId: string; cookie: string }> { const { redirect: startInteractionUrl } = outgoingPaymentGrant.interact @@ -124,7 +129,7 @@ async function _startAndAcceptInteraction( { method: 'POST', headers: { - 'x-idp-secret': '2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE=', + 'x-idp-secret': idpSecret, cookie } } diff --git a/test/integration/testenv/cloud-nine-wallet/.env b/test/integration/testenv/cloud-nine-wallet/.env index 658ee5d75b..a1c80fc105 100644 --- a/test/integration/testenv/cloud-nine-wallet/.env +++ b/test/integration/testenv/cloud-nine-wallet/.env @@ -3,5 +3,6 @@ AUTH_SERVER_DOMAIN=http://cloud-nine-wallet-test-auth:3106 INTEGRATION_SERVER_PORT=8888 WALLET_ADDRESS_URL=https://cloud-nine-wallet-test-backend:3100/.well-known/pay GRAPHQL_URL=http://cloud-nine-wallet-test-backend:3101/graphql +IDP_SECRET=2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE= # matches pfry key id KEY_ID=keyid-97a3a431-8ee1-48fc-ac85-70e2f5eba8e5 \ No newline at end of file diff --git a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml index fb45ea7fe9..8f0e47939b 100644 --- a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml +++ b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml @@ -12,7 +12,6 @@ services: - '3100:3100' - '3101:3101' - '3102:3102' - - '9229:9229' networks: - rafiki-test extra_hosts: diff --git a/test/integration/testenv/happy-life-bank/.env b/test/integration/testenv/happy-life-bank/.env index 3847999177..a2414409ec 100644 --- a/test/integration/testenv/happy-life-bank/.env +++ b/test/integration/testenv/happy-life-bank/.env @@ -3,5 +3,6 @@ AUTH_SERVER_DOMAIN=http://happy-life-bank-test-auth:4106 INTEGRATION_SERVER_PORT=8889 WALLET_ADDRESS_URL=https://happy-life-bank-test-backend:4100/accounts/pfry GRAPHQL_URL=http://happy-life-bank-test-backend:4101/graphql +IDP_SECRET=2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE= # matches pfry key id KEY_ID=keyid-97a3a431-8ee1-48fc-ac85-70e2f5eba8e5 \ No newline at end of file