From 281ca71efd4a357cbddac26f174a438d5356e4bb Mon Sep 17 00:00:00 2001 From: golobitch Date: Tue, 16 Apr 2024 23:52:35 +0200 Subject: [PATCH 01/17] feat(mase): call consent choice on different port --- localenv/mock-account-servicing-entity/app/lib/apiClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localenv/mock-account-servicing-entity/app/lib/apiClient.ts b/localenv/mock-account-servicing-entity/app/lib/apiClient.ts index b3006a1a19..50bf756c1f 100644 --- a/localenv/mock-account-servicing-entity/app/lib/apiClient.ts +++ b/localenv/mock-account-servicing-entity/app/lib/apiClient.ts @@ -69,7 +69,7 @@ export class ApiClient { const acceptanceSubPath = acceptanceDecision ? 'accept' : 'reject' const response = await axios.post( - `http://localhost:3006/grant/${interactId}/${nonce}/${acceptanceSubPath}`, + `http://localhost:3009/grant/${interactId}/${nonce}/${acceptanceSubPath}`, {}, { headers: { From 0310fac317812702002eb24262d18ab49b75cfbb Mon Sep 17 00:00:00 2001 From: golobitch Date: Tue, 16 Apr 2024 23:53:13 +0200 Subject: [PATCH 02/17] feat(localenv): expose auth choice port --- localenv/cloud-nine-wallet/docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/localenv/cloud-nine-wallet/docker-compose.yml b/localenv/cloud-nine-wallet/docker-compose.yml index 34654b2b1b..5da4472195 100644 --- a/localenv/cloud-nine-wallet/docker-compose.yml +++ b/localenv/cloud-nine-wallet/docker-compose.yml @@ -92,6 +92,7 @@ services: - '3003:3003' - '3006:3006' - "9230:9229" + - '3009:3009' environment: NODE_ENV: ${NODE_ENV:-development} TRUST_PROXY: ${TRUST_PROXY} From 075ab8d7274a6bd6e0bdcfa29af6bf87437354c1 Mon Sep 17 00:00:00 2001 From: golobitch Date: Wed, 17 Apr 2024 00:00:22 +0200 Subject: [PATCH 03/17] feat(auth)!: move interaction choice to different port Accept and reject interaction choices should not be exposed. but other routes can and must be exposed. This is why we need to move the choice routes to different port BREAKING CHANGE: Routes for accepting and rejecting choice are no longer exposed. Ideally, this must be done through ASE backend service that checks for authentication / authorization --- packages/auth/src/app.ts | 56 +++++++++++++++++++++++++++------ packages/auth/src/config/app.ts | 1 + packages/auth/src/index.ts | 3 ++ 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/packages/auth/src/app.ts b/packages/auth/src/app.ts index 2b89194c69..caaf8404a4 100644 --- a/packages/auth/src/app.ts +++ b/packages/auth/src/app.ts @@ -107,6 +107,7 @@ export type AppContainer = IocContract export class App { private authServer!: Server + private authChoiceServer!: Server private introspectionServer!: Server private adminServer!: Server private logger!: Logger @@ -338,16 +339,6 @@ export class App { interactionRoutes.details ) - // Grant accept/reject - router.post( - '/grant/:id/:nonce/:choice', - createValidatorMiddleware(openApi.idpSpec, { - path: '/grant/{id}/{nonce}/{choice}', - method: HttpMethod.POST - }), - interactionRoutes.acceptOrReject - ) - koa.use(cors()) koa.keys = [this.config.cookieKey] @@ -418,6 +409,44 @@ export class App { this.introspectionServer = koa.listen(port) } + public async startAuthChoiceServer(port: number | string): Promise { + const koa = await this.createKoaServer() + + const router = new Router() + router.use(bodyParser()) + + const openApi = await this.container.use('openApi') + const interactionRoutes = await this.container.use('interactionRoutes') + + // Grant accept/reject + router.post( + '/grant/:id/:nonce/:choice', + createValidatorMiddleware(openApi.idpSpec, { + path: '/grant/{id}/{nonce}/{choice}', + method: HttpMethod.POST + }), + interactionRoutes.acceptOrReject + ) + + koa.use(cors()) + koa.keys = [this.config.cookieKey] + koa.use( + session( + { + key: 'sessionId', + maxAge: 60 * 1000, + signed: true + }, + koa + ) + ) + + koa.use(router.middleware()) + koa.use(router.routes()) + + this.authChoiceServer = koa.listen(port) + } + private async createKoaServer(): Promise> { const koa = new Koa({ proxy: this.config.trustProxy @@ -454,6 +483,9 @@ export class App { if (this.authServer) { await this.stopServer(this.authServer) } + if (this.authChoiceServer) { + await this.stopServer(this.authChoiceServer) + } if (this.adminServer) { await this.stopServer(this.adminServer) } @@ -482,6 +514,10 @@ export class App { return this.getPort(this.authServer) } + public getAuthChoicePort(): number { + return this.getPort(this.authChoiceServer) + } + public getIntrospectionPort(): number { return this.getPort(this.introspectionServer) } diff --git a/packages/auth/src/config/app.ts b/packages/auth/src/config/app.ts index 051797db27..c477d8b70e 100644 --- a/packages/auth/src/config/app.ts +++ b/packages/auth/src/config/app.ts @@ -30,6 +30,7 @@ export const Config = { logLevel: envString('LOG_LEVEL', 'info'), adminPort: envInt('ADMIN_PORT', 3003), authPort: envInt('AUTH_PORT', 3006), + authChoiceServer: envInt('AUTH_CHOICE_SERVER', 3009), introspectionPort: envInt('INTROSPECTION_PORT', 3007), env: envString('NODE_ENV', 'development'), trustProxy: envBool('TRUST_PROXY', false), diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts index d48076efef..26ccc5ad92 100644 --- a/packages/auth/src/index.ts +++ b/packages/auth/src/index.ts @@ -299,6 +299,9 @@ export const start = async ( await app.startAuthServer(config.authPort) logger.info(`Auth server listening on ${app.getAuthPort()}`) + await app.startAuthChoiceServer(config.authChoiceServer) + logger.info(`Auth choice server listening on ${app.getAuthChoicePort()}`) + await app.startIntrospectionServer(config.introspectionPort) logger.info(`Introspection server listening on ${app.getIntrospectionPort()}`) } From c7d562ba89e403e31c06fdcac78d23d713aefff7 Mon Sep 17 00:00:00 2001 From: golobitch Date: Wed, 1 May 2024 17:59:48 +0200 Subject: [PATCH 04/17] feat(auth): change env variable name --- packages/auth/src/config/app.ts | 2 +- packages/auth/src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/auth/src/config/app.ts b/packages/auth/src/config/app.ts index c477d8b70e..bed639c6bf 100644 --- a/packages/auth/src/config/app.ts +++ b/packages/auth/src/config/app.ts @@ -30,7 +30,7 @@ export const Config = { logLevel: envString('LOG_LEVEL', 'info'), adminPort: envInt('ADMIN_PORT', 3003), authPort: envInt('AUTH_PORT', 3006), - authChoiceServer: envInt('AUTH_CHOICE_SERVER', 3009), + authChoicePort: envInt('AUTH_CHOICE_PORT', 3009), introspectionPort: envInt('INTROSPECTION_PORT', 3007), env: envString('NODE_ENV', 'development'), trustProxy: envBool('TRUST_PROXY', false), diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts index 26ccc5ad92..089865b054 100644 --- a/packages/auth/src/index.ts +++ b/packages/auth/src/index.ts @@ -299,7 +299,7 @@ export const start = async ( await app.startAuthServer(config.authPort) logger.info(`Auth server listening on ${app.getAuthPort()}`) - await app.startAuthChoiceServer(config.authChoiceServer) + await app.startAuthChoiceServer(config.authChoicePort) logger.info(`Auth choice server listening on ${app.getAuthChoicePort()}`) await app.startIntrospectionServer(config.introspectionPort) From bf4abee5793aa29447fea983b48da1de45378ced Mon Sep 17 00:00:00 2001 From: golobitch Date: Wed, 1 May 2024 18:08:25 +0200 Subject: [PATCH 05/17] test(docker): start auth choice server on specific port and expose it --- test/integration/testenv/cloud-nine-wallet/docker-compose.yml | 2 ++ test/integration/testenv/happy-life-bank/docker-compose.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml index fb45ea7fe9..4b530718b6 100644 --- a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml +++ b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml @@ -54,6 +54,7 @@ services: - '3103:3103' - '3106:3106' - '3107:3107' + - '3109:3109' environment: NODE_ENV: ${NODE_ENV:-development} AUTH_SERVER_URL: http://cloud-nine-wallet-test-auth:3106 @@ -65,6 +66,7 @@ services: IDENTITY_SERVER_URL: http://localhost:3030/mock-idp/ IDENTITY_SERVER_SECRET: 2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE= COOKIE_KEY: 42397d1f371dd4b8b7d0308a689a57c882effd4ea909d792302542af47e2cd37 + AUTH_CHOICE_PORT: 3109 depends_on: - shared-database - shared-redis \ No newline at end of file diff --git a/test/integration/testenv/happy-life-bank/docker-compose.yml b/test/integration/testenv/happy-life-bank/docker-compose.yml index fd5d86c68a..30ffdf8dec 100644 --- a/test/integration/testenv/happy-life-bank/docker-compose.yml +++ b/test/integration/testenv/happy-life-bank/docker-compose.yml @@ -53,6 +53,7 @@ services: - '4103:4103' - '4106:4106' - '4107:4107' + - '4109:4109' environment: NODE_ENV: development AUTH_DATABASE_URL: postgresql://happy_life_bank_test_auth:happy_life_bank_test_auth@shared-database/happy_life_bank_test_auth @@ -64,5 +65,6 @@ services: IDENTITY_SERVER_URL: http://localhost:3030/mock-idp/ IDENTITY_SERVER_SECRET: 2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE= COOKIE_KEY: 42397d1f371dd4b8b7d0308a689a57c882effd4ea909d792302542af47e2cd37 + AUTH_CHOICE_PORT: 4109 depends_on: - cloud-nine-wallet-test-auth \ No newline at end of file From 1e55aa7ae5cb6951b1266aca9d522a6cbc49d6fe Mon Sep 17 00:00:00 2001 From: golobitch Date: Wed, 1 May 2024 18:10:54 +0200 Subject: [PATCH 06/17] test(interactions): set auth choice port to 0 --- packages/auth/src/tests/app.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/auth/src/tests/app.ts b/packages/auth/src/tests/app.ts index 998f60fad2..2e22302cb9 100644 --- a/packages/auth/src/tests/app.ts +++ b/packages/auth/src/tests/app.ts @@ -33,6 +33,7 @@ export const createTestApp = async ( config.authPort = 0 config.introspectionPort = 0 config.adminPort = 0 + config.authChoicePort = 0 const logger = createLogger({ transport: { From ad31cfbdaa18f702d42e25b842209f683d778c25 Mon Sep 17 00:00:00 2001 From: golobitch Date: Thu, 2 May 2024 23:31:22 +0200 Subject: [PATCH 07/17] test(integration-tests): auth choice port --- test/integration/lib/config.ts | 3 +++ test/integration/lib/test-actions/index.ts | 5 ++++- test/integration/testenv/cloud-nine-wallet/.env | 1 + .../integration/testenv/cloud-nine-wallet/docker-compose.yml | 3 ++- test/integration/testenv/happy-life-bank/.env | 1 + test/integration/testenv/happy-life-bank/docker-compose.yml | 3 ++- 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/test/integration/lib/config.ts b/test/integration/lib/config.ts index 683fa708c7..db1d23e891 100644 --- a/test/integration/lib/config.ts +++ b/test/integration/lib/config.ts @@ -15,6 +15,7 @@ export type TestConfig = Config & { type EnvConfig = { OPEN_PAYMENTS_URL: string AUTH_SERVER_DOMAIN: string + AUTH_CHOICE_SERVER: string INTEGRATION_SERVER_PORT: string WALLET_ADDRESS_URL: string GRAPHQL_URL: string @@ -23,6 +24,7 @@ type EnvConfig = { const REQUIRED_KEYS: (keyof EnvConfig)[] = [ 'OPEN_PAYMENTS_URL', 'AUTH_SERVER_DOMAIN', + 'AUTH_CHOICE_SERVER', 'INTEGRATION_SERVER_PORT', 'WALLET_ADDRESS_URL', 'GRAPHQL_URL', @@ -59,6 +61,7 @@ const createConfig = (name: string): TestConfig => { publicHost: env.OPEN_PAYMENTS_URL, testnetAutoPeerUrl: '', authServerDomain: env.AUTH_SERVER_DOMAIN, + authChoiceServer: env.AUTH_CHOICE_SERVER, integrationServerPort: parseInt(env.INTEGRATION_SERVER_PORT), walletAddressUrl: env.WALLET_ADDRESS_URL, graphqlUrl: env.GRAPHQL_URL, diff --git a/test/integration/lib/test-actions/index.ts b/test/integration/lib/test-actions/index.ts index 77c8551fd7..a82248c3bf 100644 --- a/test/integration/lib/test-actions/index.ts +++ b/test/integration/lib/test-actions/index.ts @@ -119,8 +119,11 @@ async function _startAndAcceptInteraction( assert(interactId) // Accept + const url = new URL(senderWalletAddress.authServer); + url.port = "3109" + const acceptResponse = await fetch( - `${senderWalletAddress.authServer}/grant/${interactId}/${nonce}/accept`, + `${url.toString()}grant/${interactId}/${nonce}/accept`, { method: 'POST', headers: { diff --git a/test/integration/testenv/cloud-nine-wallet/.env b/test/integration/testenv/cloud-nine-wallet/.env index 658ee5d75b..8832e07700 100644 --- a/test/integration/testenv/cloud-nine-wallet/.env +++ b/test/integration/testenv/cloud-nine-wallet/.env @@ -1,5 +1,6 @@ OPEN_PAYMENTS_URL=https://cloud-nine-wallet-test-backend:3100 AUTH_SERVER_DOMAIN=http://cloud-nine-wallet-test-auth:3106 +AUTH_CHOICE_SERVER=http://cloud-nine-wallet-test-auth:3109 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 diff --git a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml index 4b530718b6..b8c790de87 100644 --- a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml +++ b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml @@ -57,7 +57,8 @@ services: - '3109:3109' environment: NODE_ENV: ${NODE_ENV:-development} - AUTH_SERVER_URL: http://cloud-nine-wallet-test-auth:3106 + AUTH_SERVER_DOMAIN: http://cloud-nine-wallet-test-auth:3106 + AUTH_CHOICE_SERVER: http://cloud-nine-wallet-test-auth:3109 AUTH_DATABASE_URL: postgresql://cloud_nine_wallet_test_auth:cloud_nine_wallet_test_auth@shared-database/cloud_nine_wallet_test_auth INTROSPECTION_PORT: 3107 AUTH_PORT: 3106 diff --git a/test/integration/testenv/happy-life-bank/.env b/test/integration/testenv/happy-life-bank/.env index 3847999177..5993cbaf31 100644 --- a/test/integration/testenv/happy-life-bank/.env +++ b/test/integration/testenv/happy-life-bank/.env @@ -1,5 +1,6 @@ OPEN_PAYMENTS_URL=https://happy-life-bank-test-backend:4100 AUTH_SERVER_DOMAIN=http://happy-life-bank-test-auth:4106 +AUTH_CHOICE_SERVER=http://happy-life-bank-test-auth:4109 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 diff --git a/test/integration/testenv/happy-life-bank/docker-compose.yml b/test/integration/testenv/happy-life-bank/docker-compose.yml index 30ffdf8dec..ed4e994064 100644 --- a/test/integration/testenv/happy-life-bank/docker-compose.yml +++ b/test/integration/testenv/happy-life-bank/docker-compose.yml @@ -57,7 +57,8 @@ services: environment: NODE_ENV: development AUTH_DATABASE_URL: postgresql://happy_life_bank_test_auth:happy_life_bank_test_auth@shared-database/happy_life_bank_test_auth - AUTH_SERVER_URL: http://happy-life-bank-test-auth:4106 + AUTH_SERVER_DOMAIN: http://happy-life-bank-test-auth:4106 + AUTH_CHOICE_SERVER: http://happy-life-bank-test-auth:4109 INTROSPECTION_PORT: 4107 ADMIN_PORT: 4103 AUTH_PORT: 4106 From 64fcf1608bbdd00088b338d9f49567c368f9b786 Mon Sep 17 00:00:00 2001 From: golobitch Date: Fri, 3 May 2024 00:25:51 +0200 Subject: [PATCH 08/17] docs(open-payments): specify port for auth choice route --- .../content/docs/concepts/open-payments/grant-interaction.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx b/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx index a2065ae86b..c9af9cd5f4 100644 --- a/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx +++ b/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx @@ -15,6 +15,7 @@ If the AS deems interaction necessary to issue a grant, there are five main endp - `GET /interact/:id/:nonce` (made by the client to the AS, establishes an interaction session, redirects browser session to IDP consent screen) - `GET /grant/:id/:nonce` (made by the IDP to the AS, secured with `x-idp-secret` header, returns grant info for the consent screen to enumerate ) - `POST /grant/:id/:nonce/(accept OR reject)` (made by the IDP to the AS, secured with `x-idp-secret` header, accepts or rejects the grant based on the user's input on the consent screen. **IDP then redirects to `GET /interact/:id/:nonce/finish`**) + - **This is served on AUTH_CHOICE_PORT and its default value is 3009** - `GET /interact/:id/:nonce/finish` (ends the interaction established by `GET /interact/:id/:nonce`, redirects browser session to client callback. Contains a query param that either indicates a failure, or on success, a `hash` parameter that the client can use to verify the successful interaction, and the `interact_ref` that identifies the interaction on the AS.) - Examples include: - `?result=grant_rejected` (if interaction was rejected) - `?result=grant_invalid` (if grant is not in a state where it may be accepted or rejected, e.g. already approved) - `?hash=p28jsq0Y2KK3WS__a42tavNC64ldGTBroywsWxT4md_jZQ1R\HZT8BOWYHcLmObM7XHPAdJzTZMtKBsaraJ64A &interact_ref=4IFWWIKYBC2PQ6U56NL1` (if interaction was accepted) - `hash` is a `sha-256` hash of values provided by the client in the body of the [grant initialization request](https://docs.openpayments.guide/reference/post-request) (`interact.finish.nonce`), values returned in the AS response for that request (`interact.finish`), the `interact_ref` provided alongside the `hash`, and the uri of the grant initialization request (`https://auth-server.com/`). From 0f96db8168154a82e9819f68e6dc76391a13f6e8 Mon Sep 17 00:00:00 2001 From: golobitch Date: Fri, 3 May 2024 00:27:18 +0200 Subject: [PATCH 09/17] chore(lint): documentation --- test/integration/lib/test-actions/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/lib/test-actions/index.ts b/test/integration/lib/test-actions/index.ts index a82248c3bf..d3d9e2e479 100644 --- a/test/integration/lib/test-actions/index.ts +++ b/test/integration/lib/test-actions/index.ts @@ -119,8 +119,8 @@ async function _startAndAcceptInteraction( assert(interactId) // Accept - const url = new URL(senderWalletAddress.authServer); - url.port = "3109" + const url = new URL(senderWalletAddress.authServer) + url.port = '3109' const acceptResponse = await fetch( `${url.toString()}grant/${interactId}/${nonce}/accept`, From 25cb61ef645d8c705620c8b29798c8bffa57c78b Mon Sep 17 00:00:00 2001 From: golobitch Date: Fri, 3 May 2024 19:29:26 +0200 Subject: [PATCH 10/17] feat: rename auth choice server to interaction server and update tests --- packages/auth/src/app.ts | 14 +++++++------- packages/auth/src/config/app.ts | 2 +- packages/auth/src/index.ts | 4 ++-- packages/auth/src/tests/app.ts | 2 +- .../concepts/open-payments/grant-interaction.mdx | 2 +- test/integration/lib/config.ts | 6 +++--- test/integration/testenv/cloud-nine-wallet/.env | 2 +- .../testenv/cloud-nine-wallet/docker-compose.yml | 2 +- test/integration/testenv/happy-life-bank/.env | 2 +- .../testenv/happy-life-bank/docker-compose.yml | 2 +- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/auth/src/app.ts b/packages/auth/src/app.ts index caaf8404a4..253013bcad 100644 --- a/packages/auth/src/app.ts +++ b/packages/auth/src/app.ts @@ -107,7 +107,7 @@ export type AppContainer = IocContract export class App { private authServer!: Server - private authChoiceServer!: Server + private interactionServer!: Server private introspectionServer!: Server private adminServer!: Server private logger!: Logger @@ -409,7 +409,7 @@ export class App { this.introspectionServer = koa.listen(port) } - public async startAuthChoiceServer(port: number | string): Promise { + public async startInteractionServer(port: number | string): Promise { const koa = await this.createKoaServer() const router = new Router() @@ -444,7 +444,7 @@ export class App { koa.use(router.middleware()) koa.use(router.routes()) - this.authChoiceServer = koa.listen(port) + this.interactionServer = koa.listen(port) } private async createKoaServer(): Promise> { @@ -483,8 +483,8 @@ export class App { if (this.authServer) { await this.stopServer(this.authServer) } - if (this.authChoiceServer) { - await this.stopServer(this.authChoiceServer) + if (this.interactionServer) { + await this.stopServer(this.interactionServer) } if (this.adminServer) { await this.stopServer(this.adminServer) @@ -514,8 +514,8 @@ export class App { return this.getPort(this.authServer) } - public getAuthChoicePort(): number { - return this.getPort(this.authChoiceServer) + public getInteractionPort(): number { + return this.getPort(this.interactionServer) } public getIntrospectionPort(): number { diff --git a/packages/auth/src/config/app.ts b/packages/auth/src/config/app.ts index bed639c6bf..d0bf03072a 100644 --- a/packages/auth/src/config/app.ts +++ b/packages/auth/src/config/app.ts @@ -30,7 +30,7 @@ export const Config = { logLevel: envString('LOG_LEVEL', 'info'), adminPort: envInt('ADMIN_PORT', 3003), authPort: envInt('AUTH_PORT', 3006), - authChoicePort: envInt('AUTH_CHOICE_PORT', 3009), + interactionPort: envInt('INTERACTION_PORT', 3009), introspectionPort: envInt('INTROSPECTION_PORT', 3007), env: envString('NODE_ENV', 'development'), trustProxy: envBool('TRUST_PROXY', false), diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts index 089865b054..4cdae32397 100644 --- a/packages/auth/src/index.ts +++ b/packages/auth/src/index.ts @@ -299,8 +299,8 @@ export const start = async ( await app.startAuthServer(config.authPort) logger.info(`Auth server listening on ${app.getAuthPort()}`) - await app.startAuthChoiceServer(config.authChoicePort) - logger.info(`Auth choice server listening on ${app.getAuthChoicePort()}`) + await app.startInteractionServer(config.interactionPort) + logger.info(`Auth choice server listening on ${app.getInteractionPort()}`) await app.startIntrospectionServer(config.introspectionPort) logger.info(`Introspection server listening on ${app.getIntrospectionPort()}`) diff --git a/packages/auth/src/tests/app.ts b/packages/auth/src/tests/app.ts index 2e22302cb9..87338ba17c 100644 --- a/packages/auth/src/tests/app.ts +++ b/packages/auth/src/tests/app.ts @@ -33,7 +33,7 @@ export const createTestApp = async ( config.authPort = 0 config.introspectionPort = 0 config.adminPort = 0 - config.authChoicePort = 0 + config.interactionPort = 0 const logger = createLogger({ transport: { diff --git a/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx b/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx index c9af9cd5f4..f36fcfee79 100644 --- a/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx +++ b/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx @@ -15,7 +15,7 @@ If the AS deems interaction necessary to issue a grant, there are five main endp - `GET /interact/:id/:nonce` (made by the client to the AS, establishes an interaction session, redirects browser session to IDP consent screen) - `GET /grant/:id/:nonce` (made by the IDP to the AS, secured with `x-idp-secret` header, returns grant info for the consent screen to enumerate ) - `POST /grant/:id/:nonce/(accept OR reject)` (made by the IDP to the AS, secured with `x-idp-secret` header, accepts or rejects the grant based on the user's input on the consent screen. **IDP then redirects to `GET /interact/:id/:nonce/finish`**) - - **This is served on AUTH_CHOICE_PORT and its default value is 3009** + - **This is served on INTERACTION_PORT and its default value is 3009** - `GET /interact/:id/:nonce/finish` (ends the interaction established by `GET /interact/:id/:nonce`, redirects browser session to client callback. Contains a query param that either indicates a failure, or on success, a `hash` parameter that the client can use to verify the successful interaction, and the `interact_ref` that identifies the interaction on the AS.) - Examples include: - `?result=grant_rejected` (if interaction was rejected) - `?result=grant_invalid` (if grant is not in a state where it may be accepted or rejected, e.g. already approved) - `?hash=p28jsq0Y2KK3WS__a42tavNC64ldGTBroywsWxT4md_jZQ1R\HZT8BOWYHcLmObM7XHPAdJzTZMtKBsaraJ64A &interact_ref=4IFWWIKYBC2PQ6U56NL1` (if interaction was accepted) - `hash` is a `sha-256` hash of values provided by the client in the body of the [grant initialization request](https://docs.openpayments.guide/reference/post-request) (`interact.finish.nonce`), values returned in the AS response for that request (`interact.finish`), the `interact_ref` provided alongside the `hash`, and the uri of the grant initialization request (`https://auth-server.com/`). diff --git a/test/integration/lib/config.ts b/test/integration/lib/config.ts index db1d23e891..b6be2bb650 100644 --- a/test/integration/lib/config.ts +++ b/test/integration/lib/config.ts @@ -15,7 +15,7 @@ export type TestConfig = Config & { type EnvConfig = { OPEN_PAYMENTS_URL: string AUTH_SERVER_DOMAIN: string - AUTH_CHOICE_SERVER: string + INTERACTION_SERVER: string INTEGRATION_SERVER_PORT: string WALLET_ADDRESS_URL: string GRAPHQL_URL: string @@ -24,7 +24,7 @@ type EnvConfig = { const REQUIRED_KEYS: (keyof EnvConfig)[] = [ 'OPEN_PAYMENTS_URL', 'AUTH_SERVER_DOMAIN', - 'AUTH_CHOICE_SERVER', + 'INTERACTION_SERVER', 'INTEGRATION_SERVER_PORT', 'WALLET_ADDRESS_URL', 'GRAPHQL_URL', @@ -61,7 +61,7 @@ const createConfig = (name: string): TestConfig => { publicHost: env.OPEN_PAYMENTS_URL, testnetAutoPeerUrl: '', authServerDomain: env.AUTH_SERVER_DOMAIN, - authChoiceServer: env.AUTH_CHOICE_SERVER, + interactionServer: env.INTERACTION_SERVER, integrationServerPort: parseInt(env.INTEGRATION_SERVER_PORT), walletAddressUrl: env.WALLET_ADDRESS_URL, graphqlUrl: env.GRAPHQL_URL, diff --git a/test/integration/testenv/cloud-nine-wallet/.env b/test/integration/testenv/cloud-nine-wallet/.env index 8832e07700..97420afd2b 100644 --- a/test/integration/testenv/cloud-nine-wallet/.env +++ b/test/integration/testenv/cloud-nine-wallet/.env @@ -1,6 +1,6 @@ OPEN_PAYMENTS_URL=https://cloud-nine-wallet-test-backend:3100 AUTH_SERVER_DOMAIN=http://cloud-nine-wallet-test-auth:3106 -AUTH_CHOICE_SERVER=http://cloud-nine-wallet-test-auth:3109 +INTERACTION_SERVER=http://cloud-nine-wallet-test-auth:3109 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 diff --git a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml index b8c790de87..8ff535a419 100644 --- a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml +++ b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml @@ -58,7 +58,7 @@ services: environment: NODE_ENV: ${NODE_ENV:-development} AUTH_SERVER_DOMAIN: http://cloud-nine-wallet-test-auth:3106 - AUTH_CHOICE_SERVER: http://cloud-nine-wallet-test-auth:3109 + INTERACTION_SERVER: http://cloud-nine-wallet-test-auth:3109 AUTH_DATABASE_URL: postgresql://cloud_nine_wallet_test_auth:cloud_nine_wallet_test_auth@shared-database/cloud_nine_wallet_test_auth INTROSPECTION_PORT: 3107 AUTH_PORT: 3106 diff --git a/test/integration/testenv/happy-life-bank/.env b/test/integration/testenv/happy-life-bank/.env index 5993cbaf31..19c527500f 100644 --- a/test/integration/testenv/happy-life-bank/.env +++ b/test/integration/testenv/happy-life-bank/.env @@ -1,6 +1,6 @@ OPEN_PAYMENTS_URL=https://happy-life-bank-test-backend:4100 AUTH_SERVER_DOMAIN=http://happy-life-bank-test-auth:4106 -AUTH_CHOICE_SERVER=http://happy-life-bank-test-auth:4109 +INTERACTION_SERVER=http://happy-life-bank-test-auth:4109 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 diff --git a/test/integration/testenv/happy-life-bank/docker-compose.yml b/test/integration/testenv/happy-life-bank/docker-compose.yml index ed4e994064..03509207b4 100644 --- a/test/integration/testenv/happy-life-bank/docker-compose.yml +++ b/test/integration/testenv/happy-life-bank/docker-compose.yml @@ -58,7 +58,7 @@ services: NODE_ENV: development AUTH_DATABASE_URL: postgresql://happy_life_bank_test_auth:happy_life_bank_test_auth@shared-database/happy_life_bank_test_auth AUTH_SERVER_DOMAIN: http://happy-life-bank-test-auth:4106 - AUTH_CHOICE_SERVER: http://happy-life-bank-test-auth:4109 + INTERACTION_SERVER: http://happy-life-bank-test-auth:4109 INTROSPECTION_PORT: 4107 ADMIN_PORT: 4103 AUTH_PORT: 4106 From 308f5e9971eeebae03f4eccb259029fcfdf9c28a Mon Sep 17 00:00:00 2001 From: golobitch Date: Fri, 3 May 2024 20:44:05 +0200 Subject: [PATCH 11/17] docs(integration): add env variable for interaction port --- .../documentation/src/content/docs/integration/deployment.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/documentation/src/content/docs/integration/deployment.md b/packages/documentation/src/content/docs/integration/deployment.md index 341160d248..a88b13fa32 100644 --- a/packages/documentation/src/content/docs/integration/deployment.md +++ b/packages/documentation/src/content/docs/integration/deployment.md @@ -123,6 +123,7 @@ Now, the Admin UI can be found on localhost:3010. | `IDENTITY_SERVER_SECRET` | auth.identityServer.secret | | API key to fetch the identity server endpoint | | `INCOMING_PAYMENT_INTERACTION` | auth.interaction.incomingPayment | `false` | flag - incoming payments grant requests are interactive or not | | `INTERACTION_EXPIRY_SECONDS` | auth.interactionExpirySeconds | `600` | time in seconds for which a user can interact with a grant request | +| `INTERACTION_PORT` | auth.port.interaction | `3009` | Port number for the interaction APIs | | `INTROSPECTION_PORT` | auth.port.introspection | `3007` | port of this Open Payments Auth - Token Introspection Server | | `LIST_ALL_ACCESS_INTERACTION` | | `true` | Specify whether grant requests including a `list-all` action should require interaction. In these requests, the client asks to list resources that they themselves did not create. | | `LOG_LEVEL` | auth.logLevel | `info` | [Pino Log Level](https://getpino.io/#/docs/api?id=levels) | From 7581bfd563e1d9fa2ace93c12d2838d0695a5a53 Mon Sep 17 00:00:00 2001 From: golobitch Date: Tue, 14 May 2024 15:10:25 +0200 Subject: [PATCH 12/17] feat(auth)!: move grant lookup to different non-exposed port --- packages/auth/src/app.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/auth/src/app.ts b/packages/auth/src/app.ts index 253013bcad..971a7ead67 100644 --- a/packages/auth/src/app.ts +++ b/packages/auth/src/app.ts @@ -329,16 +329,6 @@ export class App { interactionRoutes.finish ) - // Grant lookup - router.get( - '/grant/:id/:nonce', - createValidatorMiddleware(openApi.idpSpec, { - path: '/grant/{id}/{nonce}', - method: HttpMethod.GET - }), - interactionRoutes.details - ) - koa.use(cors()) koa.keys = [this.config.cookieKey] @@ -428,6 +418,16 @@ export class App { interactionRoutes.acceptOrReject ) + // Grant lookup + router.get( + '/grant/:id/:nonce', + createValidatorMiddleware(openApi.idpSpec, { + path: '/grant/{id}/{nonce}', + method: HttpMethod.GET + }), + interactionRoutes.details + ) + koa.use(cors()) koa.keys = [this.config.cookieKey] koa.use( From 60a32b532bf6df230657d0cfd4b954b0af03117f Mon Sep 17 00:00:00 2001 From: golobitch Date: Tue, 14 May 2024 15:10:49 +0200 Subject: [PATCH 13/17] feat(localenv): use different port for grant lookup --- localenv/mock-account-servicing-entity/app/lib/apiClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/localenv/mock-account-servicing-entity/app/lib/apiClient.ts b/localenv/mock-account-servicing-entity/app/lib/apiClient.ts index 50bf756c1f..2df7c5c40b 100644 --- a/localenv/mock-account-servicing-entity/app/lib/apiClient.ts +++ b/localenv/mock-account-servicing-entity/app/lib/apiClient.ts @@ -37,7 +37,7 @@ export class ApiClient { // get grant --> GET /grant/:id/:nonce const { interactId, nonce } = params const response = await axios.get( - `http://localhost:3006/grant/${interactId}/${nonce}`, + `http://localhost:3009/grant/${interactId}/${nonce}`, { headers: { 'x-idp-secret': 'replace-me' From b5c28a472e9d6d43d194147625014bfbdc6bc603 Mon Sep 17 00:00:00 2001 From: Tadej Golobic Date: Wed, 15 May 2024 14:42:50 +0200 Subject: [PATCH 14/17] fix(auth): interaction server start log entry Co-authored-by: Max Kurapov --- packages/auth/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts index 4cdae32397..2315fe083b 100644 --- a/packages/auth/src/index.ts +++ b/packages/auth/src/index.ts @@ -300,7 +300,7 @@ export const start = async ( logger.info(`Auth server listening on ${app.getAuthPort()}`) await app.startInteractionServer(config.interactionPort) - logger.info(`Auth choice server listening on ${app.getInteractionPort()}`) + logger.info(`Interaction server listening on ${app.getInteractionPort()}`) await app.startIntrospectionServer(config.introspectionPort) logger.info(`Introspection server listening on ${app.getIntrospectionPort()}`) From 525e54f5f530dfd7dd62e98a353e401b50420c41 Mon Sep 17 00:00:00 2001 From: golobitch Date: Wed, 15 May 2024 14:47:10 +0200 Subject: [PATCH 15/17] feat(localenv): expose auth interaction port for happy life bank --- localenv/happy-life-bank/docker-compose.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/localenv/happy-life-bank/docker-compose.yml b/localenv/happy-life-bank/docker-compose.yml index 39faf19a95..9a9ebc46cd 100644 --- a/localenv/happy-life-bank/docker-compose.yml +++ b/localenv/happy-life-bank/docker-compose.yml @@ -80,7 +80,11 @@ services: ports: - '4003:3003' - '4006:3006' +<<<<<<< HEAD - '9232:9229' +======= + - '4009:3009' +>>>>>>> d79989e4 (feat(localenv): expose auth interaction port for happy life bank) environment: NODE_ENV: development AUTH_DATABASE_URL: postgresql://happy_life_bank_auth:happy_life_bank_auth@shared-database/happy_life_bank_auth From d2414beff83faccede2679514ecedf088543af0c Mon Sep 17 00:00:00 2001 From: golobitch Date: Wed, 15 May 2024 14:48:42 +0200 Subject: [PATCH 16/17] docs(open-payments): note that grant lookup is running on interaction port --- .../content/docs/concepts/open-payments/grant-interaction.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx b/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx index f36fcfee79..02ff93d092 100644 --- a/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx +++ b/packages/documentation/src/content/docs/concepts/open-payments/grant-interaction.mdx @@ -14,6 +14,7 @@ If the AS deems interaction necessary to issue a grant, there are five main endp - `GET /interact/:id/:nonce` (made by the client to the AS, establishes an interaction session, redirects browser session to IDP consent screen) - `GET /grant/:id/:nonce` (made by the IDP to the AS, secured with `x-idp-secret` header, returns grant info for the consent screen to enumerate ) + - **This is served on INTERACTION_PORT and its default value is 3009** - `POST /grant/:id/:nonce/(accept OR reject)` (made by the IDP to the AS, secured with `x-idp-secret` header, accepts or rejects the grant based on the user's input on the consent screen. **IDP then redirects to `GET /interact/:id/:nonce/finish`**) - **This is served on INTERACTION_PORT and its default value is 3009** - `GET /interact/:id/:nonce/finish` (ends the interaction established by `GET /interact/:id/:nonce`, redirects browser session to client callback. Contains a query param that either indicates a failure, or on success, a `hash` parameter that the client can use to verify the successful interaction, and the `interact_ref` that identifies the interaction on the AS.) From 7461f680f4fd4128e8a7a0def466a1b8f1fa3f12 Mon Sep 17 00:00:00 2001 From: golobitch Date: Tue, 21 May 2024 16:25:08 +0200 Subject: [PATCH 17/17] chore(integration): accept response base url from config --- localenv/happy-life-bank/docker-compose.yml | 3 --- test/integration/integration.test.ts | 13 ++++++++++--- test/integration/lib/config.ts | 1 + test/integration/lib/test-actions/index.ts | 17 +++++++---------- .../lib/test-actions/open-payments.ts | 1 + .../cloud-nine-wallet/docker-compose.yml | 4 ++-- .../testenv/happy-life-bank/docker-compose.yml | 3 ++- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/localenv/happy-life-bank/docker-compose.yml b/localenv/happy-life-bank/docker-compose.yml index 9a9ebc46cd..6e019563f5 100644 --- a/localenv/happy-life-bank/docker-compose.yml +++ b/localenv/happy-life-bank/docker-compose.yml @@ -80,11 +80,8 @@ services: ports: - '4003:3003' - '4006:3006' -<<<<<<< HEAD - '9232:9229' -======= - '4009:3009' ->>>>>>> d79989e4 (feat(localenv): expose auth interaction port for happy life bank) environment: NODE_ENV: development AUTH_DATABASE_URL: postgresql://happy_life_bank_auth:happy_life_bank_auth@shared-database/happy_life_bank_auth diff --git a/test/integration/integration.test.ts b/test/integration/integration.test.ts index 31052fd01d..a54177bc7d 100644 --- a/test/integration/integration.test.ts +++ b/test/integration/integration.test.ts @@ -100,9 +100,16 @@ describe('Integration tests', (): void => { }) expect(senderWalletAddress.id).toBe(senderWalletAddressUrl) - const incomingPaymentGrant = await grantRequestIncomingPayment( - receiverWalletAddress - ) + let incomingPaymentGrant + try { + incomingPaymentGrant = await grantRequestIncomingPayment( + receiverWalletAddress + ) + } catch (err) { + console.log('ERROR: ', err) + throw err + } + const incomingPayment = await createIncomingPayment( receiverWalletAddress, incomingPaymentGrant.access_token.value, diff --git a/test/integration/lib/config.ts b/test/integration/lib/config.ts index b6be2bb650..2df099638f 100644 --- a/test/integration/lib/config.ts +++ b/test/integration/lib/config.ts @@ -8,6 +8,7 @@ import { resolve } from 'path' export type TestConfig = Config & { integrationServerPort: number + interactionServer: string walletAddressUrl: string keyId: string } diff --git a/test/integration/lib/test-actions/index.ts b/test/integration/lib/test-actions/index.ts index d3d9e2e479..b24820312a 100644 --- a/test/integration/lib/test-actions/index.ts +++ b/test/integration/lib/test-actions/index.ts @@ -47,8 +47,8 @@ async function consentInteraction( senderWalletAddress: WalletAddress ) { const { interactId, nonce, cookie } = await _startAndAcceptInteraction( - outgoingPaymentGrant, - senderWalletAddress + deps, + outgoingPaymentGrant ) // Finish interacton @@ -71,8 +71,8 @@ async function consentInteractionWithInteractRef( senderWalletAddress: WalletAddress ): Promise { const { interactId, nonce, cookie } = await _startAndAcceptInteraction( - outgoingPaymentGrant, - senderWalletAddress + deps, + outgoingPaymentGrant ) // Finish interacton @@ -100,8 +100,8 @@ async function consentInteractionWithInteractRef( } async function _startAndAcceptInteraction( - outgoingPaymentGrant: PendingGrant, - senderWalletAddress: WalletAddress + deps: TestActionsDeps, + outgoingPaymentGrant: PendingGrant ): Promise<{ nonce: string; interactId: string; cookie: string }> { const { redirect: startInteractionUrl } = outgoingPaymentGrant.interact @@ -119,11 +119,8 @@ async function _startAndAcceptInteraction( assert(interactId) // Accept - const url = new URL(senderWalletAddress.authServer) - url.port = '3109' - const acceptResponse = await fetch( - `${url.toString()}grant/${interactId}/${nonce}/accept`, + `${deps.sendingASE.config.interactionServer}/grant/${interactId}/${nonce}/accept`, { method: 'POST', headers: { diff --git a/test/integration/lib/test-actions/open-payments.ts b/test/integration/lib/test-actions/open-payments.ts index 007c306c65..6f54f25b68 100644 --- a/test/integration/lib/test-actions/open-payments.ts +++ b/test/integration/lib/test-actions/open-payments.ts @@ -95,6 +95,7 @@ async function grantRequestIncomingPayment( receiverWalletAddress: WalletAddress ): Promise { const { sendingASE } = deps + const grant = await sendingASE.opClient.grant.request( { url: receiverWalletAddress.authServer diff --git a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml index 8ff535a419..4d025ea643 100644 --- a/test/integration/testenv/cloud-nine-wallet/docker-compose.yml +++ b/test/integration/testenv/cloud-nine-wallet/docker-compose.yml @@ -57,17 +57,17 @@ services: - '3109:3109' environment: NODE_ENV: ${NODE_ENV:-development} - AUTH_SERVER_DOMAIN: http://cloud-nine-wallet-test-auth:3106 + AUTH_SERVER_URL: http://cloud-nine-wallet-test-auth:3106 INTERACTION_SERVER: http://cloud-nine-wallet-test-auth:3109 AUTH_DATABASE_URL: postgresql://cloud_nine_wallet_test_auth:cloud_nine_wallet_test_auth@shared-database/cloud_nine_wallet_test_auth INTROSPECTION_PORT: 3107 + INTERACTION_PORT: 3109 AUTH_PORT: 3106 ADMIN_PORT: 3103 REDIS_URL: redis://shared-redis:6379/1 IDENTITY_SERVER_URL: http://localhost:3030/mock-idp/ IDENTITY_SERVER_SECRET: 2pEcn2kkCclbOHQiGNEwhJ0rucATZhrA807HTm2rNXE= COOKIE_KEY: 42397d1f371dd4b8b7d0308a689a57c882effd4ea909d792302542af47e2cd37 - AUTH_CHOICE_PORT: 3109 depends_on: - shared-database - shared-redis \ No newline at end of file diff --git a/test/integration/testenv/happy-life-bank/docker-compose.yml b/test/integration/testenv/happy-life-bank/docker-compose.yml index 03509207b4..09121fa9b2 100644 --- a/test/integration/testenv/happy-life-bank/docker-compose.yml +++ b/test/integration/testenv/happy-life-bank/docker-compose.yml @@ -57,8 +57,9 @@ services: environment: NODE_ENV: development AUTH_DATABASE_URL: postgresql://happy_life_bank_test_auth:happy_life_bank_test_auth@shared-database/happy_life_bank_test_auth - AUTH_SERVER_DOMAIN: http://happy-life-bank-test-auth:4106 + AUTH_SERVER_URL: http://happy-life-bank-test-auth:4106 INTERACTION_SERVER: http://happy-life-bank-test-auth:4109 + INTERACTION_PORT: 4109 INTROSPECTION_PORT: 4107 ADMIN_PORT: 4103 AUTH_PORT: 4106