@contractspec/example.openbanking-powens 3.7.24 → 3.7.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +29 -0
- package/README.md +1 -1
- package/dist/handlers/oauth-callback.js +1 -1
- package/dist/handlers/webhook-handler.js +1 -1
- package/dist/index.js +1 -1
- package/dist/node/handlers/oauth-callback.js +1 -1
- package/dist/node/handlers/webhook-handler.js +1 -1
- package/dist/node/index.js +1 -1
- package/package.json +3 -3
- package/src/handlers/oauth-callback.ts +2 -2
- package/src/handlers/webhook-handler.ts +2 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -2,27 +2,27 @@ $ contractspec-bun-build prebuild
|
|
|
2
2
|
$ bun run build:bundle && bun run build:types
|
|
3
3
|
$ contractspec-bun-build transpile
|
|
4
4
|
[contractspec-bun-build] transpile target=bun root=src entries=9 noBundle=false
|
|
5
|
-
Bundled 9 modules in
|
|
5
|
+
Bundled 9 modules in 13ms
|
|
6
6
|
|
|
7
7
|
docs/index.js 1.39 KB (entry point)
|
|
8
|
-
./index.js 6.
|
|
8
|
+
./index.js 6.93 KB (entry point)
|
|
9
9
|
./openbanking-powens.feature.js 0.56 KB (entry point)
|
|
10
10
|
docs/openbanking-powens.docblock.js 1.39 KB (entry point)
|
|
11
11
|
./example.js 0.69 KB (entry point)
|
|
12
|
-
handlers/oauth-callback.js 1.
|
|
13
|
-
handlers/webhook-handler.js 1.
|
|
12
|
+
handlers/oauth-callback.js 1.32 KB (entry point)
|
|
13
|
+
handlers/webhook-handler.js 1.88 KB (entry point)
|
|
14
14
|
jobs/index.js 1.17 KB (entry point)
|
|
15
15
|
jobs/powens-sync-dispatch.job.js 1.17 KB (entry point)
|
|
16
16
|
|
|
17
17
|
[contractspec-bun-build] transpile target=node root=src entries=9 noBundle=false
|
|
18
|
-
Bundled 9 modules in
|
|
18
|
+
Bundled 9 modules in 27ms
|
|
19
19
|
|
|
20
20
|
docs/index.js 1.37 KB (entry point)
|
|
21
|
-
./index.js 6.
|
|
21
|
+
./index.js 6.91 KB (entry point)
|
|
22
22
|
./openbanking-powens.feature.js 0.56 KB (entry point)
|
|
23
23
|
docs/openbanking-powens.docblock.js 1.37 KB (entry point)
|
|
24
24
|
./example.js 0.68 KB (entry point)
|
|
25
|
-
handlers/oauth-callback.js 1.
|
|
25
|
+
handlers/oauth-callback.js 1.31 KB (entry point)
|
|
26
26
|
handlers/webhook-handler.js 1.87 KB (entry point)
|
|
27
27
|
jobs/index.js 1.16 KB (entry point)
|
|
28
28
|
jobs/powens-sync-dispatch.job.js 1.16 KB (entry point)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @contractspec/example.openbanking-powens
|
|
2
2
|
|
|
3
|
+
## 3.7.26
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- chore: auto-bump internal dependents
|
|
8
|
+
- Updated dependencies because of chore: auto-bump internal dependents
|
|
9
|
+
- Updated dependencies because of Remove avoidable Node crypto imports from ContractSpec runtime surfaces and keep signing helpers isolated.
|
|
10
|
+
- Updated dependencies because of Improve FormSpec autocomplete rendering and resolver-backed search.
|
|
11
|
+
- Updated dependencies because of Add first-class FormSpec email fields with native renderer affordances.
|
|
12
|
+
- Updated dependencies because of Add progressive FormSpec section and step layout metadata with shared React and design-system rendering support.
|
|
13
|
+
- @contractspec/integration.provider.openbanking@0.2.1
|
|
14
|
+
- @contractspec/lib.contracts-spec@6.0.0
|
|
15
|
+
|
|
16
|
+
## 3.7.25
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Split provider implementations into targeted integration packages while preserving the legacy providers-impls facade.
|
|
21
|
+
- Packages: @contractspec/integration.providers-impls (minor), @contractspec/integration.provider.analytics (minor), @contractspec/integration.provider.calendar (minor), @contractspec/integration.provider.database (minor), @contractspec/integration.provider.email (minor), @contractspec/integration.provider.embedding (minor), @contractspec/integration.provider.health (minor), @contractspec/integration.provider.llm (minor), @contractspec/integration.provider.meeting-recorder (minor), @contractspec/integration.provider.messaging (minor), @contractspec/integration.provider.openbanking (minor), @contractspec/integration.provider.payments (minor), @contractspec/integration.provider.project-management (minor), @contractspec/integration.provider.sms (minor), @contractspec/integration.provider.storage (minor), @contractspec/integration.provider.vector-store (minor), @contractspec/integration.provider.voice (minor), @contractspec/app.api-library (patch), @contractspec/example.calendar-google (patch), @contractspec/example.email-gmail (patch), @contractspec/example.integration-posthog (patch), @contractspec/example.meeting-recorder-providers (patch), @contractspec/example.openbanking-powens (patch), @contractspec/example.product-intent (patch), @contractspec/example.project-management-sync (patch), @contractspec/example.voice-providers (patch)
|
|
22
|
+
- Migration: Replace direct provider imports such as `@contractspec/integration.providers-impls/impls/gmail-inbound` with targeted packages such as `@contractspec/integration.provider.email/impls/gmail-inbound`.; Continue importing `IntegrationProviderFactory` from `@contractspec/integration.providers-impls/impls/provider-factory` when you need broad provider routing.
|
|
23
|
+
- Updated dependencies because of Add mobile-safe FormSpec layout helpers and scoped DataView filters.
|
|
24
|
+
|
|
25
|
+
FormSpec authors can now use `responsiveFormColumns(...)` for explicit mobile-first column metadata without changing legacy numeric `layout.columns` behavior. DataView contracts can declare `filterScope.initial` and `filterScope.locked` filters so generic list/search contracts can be reused in context-restricted screens while keeping locked constraints out of user-editable URL state.
|
|
26
|
+
|
|
27
|
+
- Updated dependencies because of Add OSS harness CLI verification with deterministic Playwright, optional agent-browser visual runs, auth profile refs, visual diff evidence, replay bundles, and core scenario success semantics.
|
|
28
|
+
- Updated dependencies because of Split provider implementations into targeted integration packages while preserving the legacy providers-impls facade.
|
|
29
|
+
- @contractspec/lib.contracts-spec@5.7.0
|
|
30
|
+
- @contractspec/integration.provider.openbanking@0.2.0
|
|
31
|
+
|
|
3
32
|
## 3.7.24
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -70,4 +70,4 @@ Use `@contractspec/example.openbanking-powens` as a reference implementation, or
|
|
|
70
70
|
|
|
71
71
|
## Notes
|
|
72
72
|
|
|
73
|
-
- Works alongside `@contractspec/integration.
|
|
73
|
+
- Works alongside `@contractspec/integration.provider.openbanking`, `@contractspec/lib.contracts-spec`, `@contractspec/tool.bun`, `@contractspec/tool.typescript`.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{PowensOpenBankingProvider as K}from"@contractspec/integration.
|
|
2
|
+
import{PowensOpenBankingProvider as K}from"@contractspec/integration.provider.openbanking/impls/powens-openbanking";async function Z(j){let x=new URL(j.url),z=x.searchParams.get("code"),G=x.searchParams.get("state"),A=x.searchParams.get("user_uuid");if(!z||!G||!A)return new Response("Missing Powens OAuth params",{status:400});let h=await L(G);if(!h)return new Response("Unknown Powens OAuth state",{status:404});let E=await M(h.meta.id),H=await new K({clientId:E.clientId,clientSecret:E.clientSecret,apiKey:E.apiKey,environment:h.config.environment,baseUrl:h.config.baseUrl}).listAccounts({tenantId:h.meta.tenantId,connectionId:h.meta.id,userId:A});await h.storePowensUser({tenantUserId:h.meta.tenantUserId,powensUserUuid:A,authCode:z}),await N("pfo.workflow.sync-openbanking-accounts",{tenantId:h.meta.tenantId,userUuid:A,connectionId:h.meta.id,previewAccounts:H.accounts});let J=process.env.APP_DASHBOARD_URL??"";return Response.redirect(`${J}/banking/linked?tenant=${h.meta.tenantId}`,302)}async function L(j){return R.connections.find((z)=>z.state===j)??null}async function M(j){let x=T[j];if(!x)throw Error(`Missing Powens secrets for ${j}`);return x}async function N(j,x){await V.enqueue({name:j,input:x})}var R={connections:[]},T={},V={enqueue:async(j)=>{}};export{Z as powensOAuthCallbackHandler};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{PowensOpenBankingProvider as N}from"@contractspec/integration.
|
|
2
|
+
import{PowensOpenBankingProvider as N}from"@contractspec/integration.provider.openbanking/impls/powens-openbanking";import{createHmac as R,timingSafeEqual as V}from"crypto";async function T(h){let x=h.headers.get("x-powens-signature"),G=h.headers.get("x-powens-state"),J=await h.text();if(!x||!G)return new Response("Missing Powens signature headers",{status:400});let j=await Y(G);if(!j)return new Response("Unknown Powens state header",{status:404});let z=await Z(j.meta.id);if(!X(J,x,z.webhookSecret))return new Response("Invalid Powens webhook signature",{status:401});let A=JSON.parse(J),M=new N({clientId:z.clientId,clientSecret:z.clientSecret,apiKey:z.apiKey,environment:j.config.environment,baseUrl:j.config.baseUrl});switch(A.type){case"connection.updated":case"user.sync.completed":{await K("pfo.workflow.sync-openbanking-accounts",{tenantId:j.meta.tenantId,connectionId:j.meta.id,userUuid:A.user_uuid});break}case"transactions.created":case"transactions.updated":{await K("pfo.workflow.sync-openbanking-transactions",{tenantId:j.meta.tenantId,connectionId:j.meta.id,userUuid:A.user_uuid,accountId:A.account_uuid});break}default:await _(A)}if(A.account_uuid)await M.getBalances({tenantId:j.meta.tenantId,connectionId:j.meta.id,accountId:A.account_uuid});return new Response("OK",{status:200})}function X(h,x,G){let J=R("sha256",G).update(h).digest("hex"),j=Buffer.from(J,"hex"),z=Buffer.from(x,"hex");return j.length===z.length&&V(j,z)}async function Y(h){return $.connections.find((x)=>x.state===h)??null}async function Z(h){let x=D[h];if(!x)throw Error(`Missing Powens secrets for ${h}`);return x}async function K(h,x){await F.enqueue({name:h,input:x})}async function _(h){await L.record({event:"openbanking.webhook.unmapped",payload:"redacted"})}var $={connections:[]},D={},F={enqueue:async(h)=>{}},L={record:async(h)=>{}};export{T as powensWebhookHandler};
|
package/dist/index.js
CHANGED
|
@@ -12,4 +12,4 @@ import{registerDocBlocks as _}from"@contractspec/lib.contracts-spec/docs";var $=
|
|
|
12
12
|
|
|
13
13
|
## Notes
|
|
14
14
|
- Replace the fake stores with your app-layer persistence.
|
|
15
|
-
- Enqueue ContractSpec workflows for canonical upserts and telemetry.`}];_($);import{defineExample as J}from"@contractspec/lib.contracts-spec/examples";var L=J({meta:{key:"examples.openbanking-powens",version:"1.0.0",title:"Openbanking Powens",description:"OpenBanking Powens example: OAuth callback + webhook handler patterns (provider + workflows).",kind:"template",visibility:"experimental",stability:"experimental",owners:["@contractspec-core"],tags:["package","examples","openbanking-powens"]},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["playground","specs"]},studio:{enabled:!1,installable:!1},mcp:{enabled:!1}},entrypoints:{packageName:"@contractspec/example.openbanking-powens"}}),M=L;import{PowensOpenBankingProvider as Q}from"@contractspec/integration.
|
|
15
|
+
- Enqueue ContractSpec workflows for canonical upserts and telemetry.`}];_($);import{defineExample as J}from"@contractspec/lib.contracts-spec/examples";var L=J({meta:{key:"examples.openbanking-powens",version:"1.0.0",title:"Openbanking Powens",description:"OpenBanking Powens example: OAuth callback + webhook handler patterns (provider + workflows).",kind:"template",visibility:"experimental",stability:"experimental",owners:["@contractspec-core"],tags:["package","examples","openbanking-powens"]},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["playground","specs"]},studio:{enabled:!1,installable:!1},mcp:{enabled:!1}},entrypoints:{packageName:"@contractspec/example.openbanking-powens"}}),M=L;import{PowensOpenBankingProvider as Q}from"@contractspec/integration.provider.openbanking/impls/powens-openbanking";async function s(x){let j=new URL(x.url),K=j.searchParams.get("code"),N=j.searchParams.get("state"),A=j.searchParams.get("user_uuid");if(!K||!N||!A)return new Response("Missing Powens OAuth params",{status:400});let z=await F(N);if(!z)return new Response("Unknown Powens OAuth state",{status:404});let G=await H(z.meta.id),Y=await new Q({clientId:G.clientId,clientSecret:G.clientSecret,apiKey:G.apiKey,environment:z.config.environment,baseUrl:z.config.baseUrl}).listAccounts({tenantId:z.meta.tenantId,connectionId:z.meta.id,userId:A});await z.storePowensUser({tenantUserId:z.meta.tenantUserId,powensUserUuid:A,authCode:K}),await h("pfo.workflow.sync-openbanking-accounts",{tenantId:z.meta.tenantId,userUuid:A,connectionId:z.meta.id,previewAccounts:Y.accounts});let Z=process.env.APP_DASHBOARD_URL??"";return Response.redirect(`${Z}/banking/linked?tenant=${z.meta.tenantId}`,302)}async function F(x){return C.connections.find((K)=>K.state===x)??null}async function H(x){let j=D[x];if(!j)throw Error(`Missing Powens secrets for ${x}`);return j}async function h(x,j){await O.enqueue({name:x,input:j})}var C={connections:[]},D={},O={enqueue:async(x)=>{}};import{PowensOpenBankingProvider as U}from"@contractspec/integration.provider.openbanking/impls/powens-openbanking";import{createHmac as W,timingSafeEqual as B}from"crypto";async function t(x){let j=x.headers.get("x-powens-signature"),K=x.headers.get("x-powens-state"),N=await x.text();if(!j||!K)return new Response("Missing Powens signature headers",{status:400});let A=await I(K);if(!A)return new Response("Unknown Powens state header",{status:404});let z=await f(A.meta.id);if(!T(N,j,z.webhookSecret))return new Response("Invalid Powens webhook signature",{status:401});let G=JSON.parse(N),V=new U({clientId:z.clientId,clientSecret:z.clientSecret,apiKey:z.apiKey,environment:A.config.environment,baseUrl:A.config.baseUrl});switch(G.type){case"connection.updated":case"user.sync.completed":{await X("pfo.workflow.sync-openbanking-accounts",{tenantId:A.meta.tenantId,connectionId:A.meta.id,userUuid:G.user_uuid});break}case"transactions.created":case"transactions.updated":{await X("pfo.workflow.sync-openbanking-transactions",{tenantId:A.meta.tenantId,connectionId:A.meta.id,userUuid:G.user_uuid,accountId:G.account_uuid});break}default:await P(G)}if(G.account_uuid)await V.getBalances({tenantId:A.meta.tenantId,connectionId:A.meta.id,accountId:G.account_uuid});return new Response("OK",{status:200})}function T(x,j,K){let N=W("sha256",K).update(x).digest("hex"),A=Buffer.from(N,"hex"),z=Buffer.from(j,"hex");return A.length===z.length&&B(A,z)}async function I(x){return q.connections.find((j)=>j.state===x)??null}async function f(x){let j=m[x];if(!j)throw Error(`Missing Powens secrets for ${x}`);return j}async function X(x,j){await E.enqueue({name:x,input:j})}async function P(x){await v.record({event:"openbanking.webhook.unmapped",payload:"redacted"})}var q={connections:[]},m={},E={enqueue:async(x)=>{}},v={record:async(x)=>{}};import{defineJob as b}from"@contractspec/lib.contracts-spec/jobs/spec";import{OwnersEnum as w,StabilityEnum as y}from"@contractspec/lib.contracts-spec/ownership";import{defineSchemaModel as S,ScalarTypeEnum as R}from"@contractspec/lib.schema";var k=S({name:"PowensSyncDispatchPayload",description:"Payload enqueued from Powens OAuth callbacks or webhooks before dispatching sync workflows.",fields:{tenantId:{type:R.String_unsecure(),isOptional:!1},connectionId:{type:R.String_unsecure(),isOptional:!1},eventType:{type:R.String_unsecure(),isOptional:!1},userUuid:{type:R.String_unsecure(),isOptional:!1},accountUuid:{type:R.String_unsecure(),isOptional:!0}}}),jx=b({meta:{key:"openbanking-powens.job.sync-dispatch",version:"1.0.0",title:"Powens Sync Dispatch Job",description:"Queues the canonical open banking sync workflows after Powens callbacks and webhooks are verified.",domain:"open-banking",owners:[w.PlatformFinance],tags:["openbanking","powens","job","webhook"],stability:y.Experimental},payload:{schema:k},retry:{maxRetries:5,initialBackoffMs:30000,maxBackoffMs:300000,multiplier:2,jitter:!0},timeoutMs:60000});import{defineFeature as g}from"@contractspec/lib.contracts-spec/features";var Nx=g({meta:{key:"openbanking-powens",version:"1.0.0",title:"Open Banking - Powens",description:"Powens open banking OAuth callback and webhook handler patterns",domain:"integration",owners:["@examples"],tags:["openbanking","powens","oauth","webhooks"],stability:"experimental"},integrations:[{key:"openbanking-powens.integration.powens",version:"1.0.0"}],docs:["docs.examples.openbanking-powens","docs.examples.openbanking-powens.usage"]});export{t as powensWebhookHandler,s as powensOAuthCallbackHandler,M as example,jx as PowensSyncDispatchJob,Nx as OpenbankingPowensFeature,L as ExamplesOpenbankingPowensExample};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PowensOpenBankingProvider as K}from"@contractspec/integration.
|
|
1
|
+
import{PowensOpenBankingProvider as K}from"@contractspec/integration.provider.openbanking/impls/powens-openbanking";async function Z(j){let x=new URL(j.url),z=x.searchParams.get("code"),G=x.searchParams.get("state"),A=x.searchParams.get("user_uuid");if(!z||!G||!A)return new Response("Missing Powens OAuth params",{status:400});let h=await L(G);if(!h)return new Response("Unknown Powens OAuth state",{status:404});let E=await M(h.meta.id),H=await new K({clientId:E.clientId,clientSecret:E.clientSecret,apiKey:E.apiKey,environment:h.config.environment,baseUrl:h.config.baseUrl}).listAccounts({tenantId:h.meta.tenantId,connectionId:h.meta.id,userId:A});await h.storePowensUser({tenantUserId:h.meta.tenantUserId,powensUserUuid:A,authCode:z}),await N("pfo.workflow.sync-openbanking-accounts",{tenantId:h.meta.tenantId,userUuid:A,connectionId:h.meta.id,previewAccounts:H.accounts});let J=process.env.APP_DASHBOARD_URL??"";return Response.redirect(`${J}/banking/linked?tenant=${h.meta.tenantId}`,302)}async function L(j){return R.connections.find((z)=>z.state===j)??null}async function M(j){let x=T[j];if(!x)throw Error(`Missing Powens secrets for ${j}`);return x}async function N(j,x){await V.enqueue({name:j,input:x})}var R={connections:[]},T={},V={enqueue:async(j)=>{}};export{Z as powensOAuthCallbackHandler};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PowensOpenBankingProvider as N}from"@contractspec/integration.
|
|
1
|
+
import{PowensOpenBankingProvider as N}from"@contractspec/integration.provider.openbanking/impls/powens-openbanking";import{createHmac as R,timingSafeEqual as V}from"crypto";async function T(h){let x=h.headers.get("x-powens-signature"),G=h.headers.get("x-powens-state"),J=await h.text();if(!x||!G)return new Response("Missing Powens signature headers",{status:400});let j=await Y(G);if(!j)return new Response("Unknown Powens state header",{status:404});let z=await Z(j.meta.id);if(!X(J,x,z.webhookSecret))return new Response("Invalid Powens webhook signature",{status:401});let A=JSON.parse(J),M=new N({clientId:z.clientId,clientSecret:z.clientSecret,apiKey:z.apiKey,environment:j.config.environment,baseUrl:j.config.baseUrl});switch(A.type){case"connection.updated":case"user.sync.completed":{await K("pfo.workflow.sync-openbanking-accounts",{tenantId:j.meta.tenantId,connectionId:j.meta.id,userUuid:A.user_uuid});break}case"transactions.created":case"transactions.updated":{await K("pfo.workflow.sync-openbanking-transactions",{tenantId:j.meta.tenantId,connectionId:j.meta.id,userUuid:A.user_uuid,accountId:A.account_uuid});break}default:await _(A)}if(A.account_uuid)await M.getBalances({tenantId:j.meta.tenantId,connectionId:j.meta.id,accountId:A.account_uuid});return new Response("OK",{status:200})}function X(h,x,G){let J=R("sha256",G).update(h).digest("hex"),j=Buffer.from(J,"hex"),z=Buffer.from(x,"hex");return j.length===z.length&&V(j,z)}async function Y(h){return $.connections.find((x)=>x.state===h)??null}async function Z(h){let x=D[h];if(!x)throw Error(`Missing Powens secrets for ${h}`);return x}async function K(h,x){await F.enqueue({name:h,input:x})}async function _(h){await L.record({event:"openbanking.webhook.unmapped",payload:"redacted"})}var $={connections:[]},D={},F={enqueue:async(h)=>{}},L={record:async(h)=>{}};export{T as powensWebhookHandler};
|
package/dist/node/index.js
CHANGED
|
@@ -11,4 +11,4 @@ import{registerDocBlocks as _}from"@contractspec/lib.contracts-spec/docs";var $=
|
|
|
11
11
|
|
|
12
12
|
## Notes
|
|
13
13
|
- Replace the fake stores with your app-layer persistence.
|
|
14
|
-
- Enqueue ContractSpec workflows for canonical upserts and telemetry.`}];_($);import{defineExample as J}from"@contractspec/lib.contracts-spec/examples";var L=J({meta:{key:"examples.openbanking-powens",version:"1.0.0",title:"Openbanking Powens",description:"OpenBanking Powens example: OAuth callback + webhook handler patterns (provider + workflows).",kind:"template",visibility:"experimental",stability:"experimental",owners:["@contractspec-core"],tags:["package","examples","openbanking-powens"]},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["playground","specs"]},studio:{enabled:!1,installable:!1},mcp:{enabled:!1}},entrypoints:{packageName:"@contractspec/example.openbanking-powens"}}),M=L;import{PowensOpenBankingProvider as Q}from"@contractspec/integration.
|
|
14
|
+
- Enqueue ContractSpec workflows for canonical upserts and telemetry.`}];_($);import{defineExample as J}from"@contractspec/lib.contracts-spec/examples";var L=J({meta:{key:"examples.openbanking-powens",version:"1.0.0",title:"Openbanking Powens",description:"OpenBanking Powens example: OAuth callback + webhook handler patterns (provider + workflows).",kind:"template",visibility:"experimental",stability:"experimental",owners:["@contractspec-core"],tags:["package","examples","openbanking-powens"]},surfaces:{templates:!0,sandbox:{enabled:!0,modes:["playground","specs"]},studio:{enabled:!1,installable:!1},mcp:{enabled:!1}},entrypoints:{packageName:"@contractspec/example.openbanking-powens"}}),M=L;import{PowensOpenBankingProvider as Q}from"@contractspec/integration.provider.openbanking/impls/powens-openbanking";async function s(x){let j=new URL(x.url),K=j.searchParams.get("code"),N=j.searchParams.get("state"),A=j.searchParams.get("user_uuid");if(!K||!N||!A)return new Response("Missing Powens OAuth params",{status:400});let z=await F(N);if(!z)return new Response("Unknown Powens OAuth state",{status:404});let G=await H(z.meta.id),Y=await new Q({clientId:G.clientId,clientSecret:G.clientSecret,apiKey:G.apiKey,environment:z.config.environment,baseUrl:z.config.baseUrl}).listAccounts({tenantId:z.meta.tenantId,connectionId:z.meta.id,userId:A});await z.storePowensUser({tenantUserId:z.meta.tenantUserId,powensUserUuid:A,authCode:K}),await h("pfo.workflow.sync-openbanking-accounts",{tenantId:z.meta.tenantId,userUuid:A,connectionId:z.meta.id,previewAccounts:Y.accounts});let Z=process.env.APP_DASHBOARD_URL??"";return Response.redirect(`${Z}/banking/linked?tenant=${z.meta.tenantId}`,302)}async function F(x){return C.connections.find((K)=>K.state===x)??null}async function H(x){let j=D[x];if(!j)throw Error(`Missing Powens secrets for ${x}`);return j}async function h(x,j){await O.enqueue({name:x,input:j})}var C={connections:[]},D={},O={enqueue:async(x)=>{}};import{PowensOpenBankingProvider as U}from"@contractspec/integration.provider.openbanking/impls/powens-openbanking";import{createHmac as W,timingSafeEqual as B}from"crypto";async function t(x){let j=x.headers.get("x-powens-signature"),K=x.headers.get("x-powens-state"),N=await x.text();if(!j||!K)return new Response("Missing Powens signature headers",{status:400});let A=await I(K);if(!A)return new Response("Unknown Powens state header",{status:404});let z=await f(A.meta.id);if(!T(N,j,z.webhookSecret))return new Response("Invalid Powens webhook signature",{status:401});let G=JSON.parse(N),V=new U({clientId:z.clientId,clientSecret:z.clientSecret,apiKey:z.apiKey,environment:A.config.environment,baseUrl:A.config.baseUrl});switch(G.type){case"connection.updated":case"user.sync.completed":{await X("pfo.workflow.sync-openbanking-accounts",{tenantId:A.meta.tenantId,connectionId:A.meta.id,userUuid:G.user_uuid});break}case"transactions.created":case"transactions.updated":{await X("pfo.workflow.sync-openbanking-transactions",{tenantId:A.meta.tenantId,connectionId:A.meta.id,userUuid:G.user_uuid,accountId:G.account_uuid});break}default:await P(G)}if(G.account_uuid)await V.getBalances({tenantId:A.meta.tenantId,connectionId:A.meta.id,accountId:G.account_uuid});return new Response("OK",{status:200})}function T(x,j,K){let N=W("sha256",K).update(x).digest("hex"),A=Buffer.from(N,"hex"),z=Buffer.from(j,"hex");return A.length===z.length&&B(A,z)}async function I(x){return q.connections.find((j)=>j.state===x)??null}async function f(x){let j=m[x];if(!j)throw Error(`Missing Powens secrets for ${x}`);return j}async function X(x,j){await E.enqueue({name:x,input:j})}async function P(x){await v.record({event:"openbanking.webhook.unmapped",payload:"redacted"})}var q={connections:[]},m={},E={enqueue:async(x)=>{}},v={record:async(x)=>{}};import{defineJob as b}from"@contractspec/lib.contracts-spec/jobs/spec";import{OwnersEnum as w,StabilityEnum as y}from"@contractspec/lib.contracts-spec/ownership";import{defineSchemaModel as S,ScalarTypeEnum as R}from"@contractspec/lib.schema";var k=S({name:"PowensSyncDispatchPayload",description:"Payload enqueued from Powens OAuth callbacks or webhooks before dispatching sync workflows.",fields:{tenantId:{type:R.String_unsecure(),isOptional:!1},connectionId:{type:R.String_unsecure(),isOptional:!1},eventType:{type:R.String_unsecure(),isOptional:!1},userUuid:{type:R.String_unsecure(),isOptional:!1},accountUuid:{type:R.String_unsecure(),isOptional:!0}}}),jx=b({meta:{key:"openbanking-powens.job.sync-dispatch",version:"1.0.0",title:"Powens Sync Dispatch Job",description:"Queues the canonical open banking sync workflows after Powens callbacks and webhooks are verified.",domain:"open-banking",owners:[w.PlatformFinance],tags:["openbanking","powens","job","webhook"],stability:y.Experimental},payload:{schema:k},retry:{maxRetries:5,initialBackoffMs:30000,maxBackoffMs:300000,multiplier:2,jitter:!0},timeoutMs:60000});import{defineFeature as g}from"@contractspec/lib.contracts-spec/features";var Nx=g({meta:{key:"openbanking-powens",version:"1.0.0",title:"Open Banking - Powens",description:"Powens open banking OAuth callback and webhook handler patterns",domain:"integration",owners:["@examples"],tags:["openbanking","powens","oauth","webhooks"],stability:"experimental"},integrations:[{key:"openbanking-powens.integration.powens",version:"1.0.0"}],docs:["docs.examples.openbanking-powens","docs.examples.openbanking-powens.usage"]});export{t as powensWebhookHandler,s as powensOAuthCallbackHandler,M as example,jx as PowensSyncDispatchJob,Nx as OpenbankingPowensFeature,L as ExamplesOpenbankingPowensExample};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractspec/example.openbanking-powens",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.26",
|
|
4
4
|
"description": "OpenBanking Powens example: OAuth callback + webhook handler patterns (provider + workflows).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
"typecheck": "tsc --noEmit"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@contractspec/integration.
|
|
80
|
-
"@contractspec/lib.contracts-spec": "
|
|
79
|
+
"@contractspec/integration.provider.openbanking": "0.2.1",
|
|
80
|
+
"@contractspec/lib.contracts-spec": "6.0.0"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@contractspec/tool.typescript": "3.7.13",
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* type so it can be used in Next.js, Elysia, or any fetch-compatible runtime.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { PowensEnvironment } from '@contractspec/integration.
|
|
9
|
-
import { PowensOpenBankingProvider } from '@contractspec/integration.
|
|
8
|
+
import type { PowensEnvironment } from '@contractspec/integration.provider.openbanking/impls/powens-client';
|
|
9
|
+
import { PowensOpenBankingProvider } from '@contractspec/integration.provider.openbanking/impls/powens-openbanking';
|
|
10
10
|
|
|
11
11
|
export async function powensOAuthCallbackHandler(req: Request) {
|
|
12
12
|
const url = new URL(req.url);
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* in sync. Unknown events are ignored (or can be recorded by the app layer).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { PowensEnvironment } from '@contractspec/integration.
|
|
9
|
-
import { PowensOpenBankingProvider } from '@contractspec/integration.
|
|
8
|
+
import type { PowensEnvironment } from '@contractspec/integration.provider.openbanking/impls/powens-client';
|
|
9
|
+
import { PowensOpenBankingProvider } from '@contractspec/integration.provider.openbanking/impls/powens-openbanking';
|
|
10
10
|
import { createHmac, timingSafeEqual } from 'crypto';
|
|
11
11
|
|
|
12
12
|
export async function powensWebhookHandler(req: Request) {
|