@atbas/m-mcp 0.1.0
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/LICENSE +21 -0
- package/README.md +364 -0
- package/dist/builder/transaction-builder.d.ts +53 -0
- package/dist/builder/transaction-builder.d.ts.map +1 -0
- package/dist/builder/transaction-builder.js +159 -0
- package/dist/builder/transaction-builder.js.map +1 -0
- package/dist/catalogue/default-catalogue.d.ts +18 -0
- package/dist/catalogue/default-catalogue.d.ts.map +1 -0
- package/dist/catalogue/default-catalogue.js +21 -0
- package/dist/catalogue/default-catalogue.js.map +1 -0
- package/dist/catalogue/endpoints.d.ts +22 -0
- package/dist/catalogue/endpoints.d.ts.map +1 -0
- package/dist/catalogue/endpoints.js +24 -0
- package/dist/catalogue/endpoints.js.map +1 -0
- package/dist/catalogue/flows.d.ts +32 -0
- package/dist/catalogue/flows.d.ts.map +1 -0
- package/dist/catalogue/flows.js +64 -0
- package/dist/catalogue/flows.js.map +1 -0
- package/dist/catalogue/hash-options.d.ts +112 -0
- package/dist/catalogue/hash-options.d.ts.map +1 -0
- package/dist/catalogue/hash-options.js +151 -0
- package/dist/catalogue/hash-options.js.map +1 -0
- package/dist/catalogue/types.d.ts +279 -0
- package/dist/catalogue/types.d.ts.map +1 -0
- package/dist/catalogue/types.js +360 -0
- package/dist/catalogue/types.js.map +1 -0
- package/dist/codegen/generate.d.ts +14 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/generate.js +490 -0
- package/dist/codegen/generate.js.map +1 -0
- package/dist/codegen/languages/node.d.ts +3 -0
- package/dist/codegen/languages/node.d.ts.map +1 -0
- package/dist/codegen/languages/node.js +32 -0
- package/dist/codegen/languages/node.js.map +1 -0
- package/dist/codegen/languages/php.d.ts +3 -0
- package/dist/codegen/languages/php.d.ts.map +1 -0
- package/dist/codegen/languages/php.js +27 -0
- package/dist/codegen/languages/php.js.map +1 -0
- package/dist/codegen/languages/python.d.ts +3 -0
- package/dist/codegen/languages/python.d.ts.map +1 -0
- package/dist/codegen/languages/python.js +27 -0
- package/dist/codegen/languages/python.js.map +1 -0
- package/dist/codegen/renderer.d.ts +24 -0
- package/dist/codegen/renderer.d.ts.map +1 -0
- package/dist/codegen/renderer.js +59 -0
- package/dist/codegen/renderer.js.map +1 -0
- package/dist/codegen/types.d.ts +50 -0
- package/dist/codegen/types.d.ts.map +1 -0
- package/dist/codegen/types.js +5 -0
- package/dist/codegen/types.js.map +1 -0
- package/dist/config/credentials.d.ts +64 -0
- package/dist/config/credentials.d.ts.map +1 -0
- package/dist/config/credentials.js +216 -0
- package/dist/config/credentials.js.map +1 -0
- package/dist/config/environment.d.ts +23 -0
- package/dist/config/environment.d.ts.map +1 -0
- package/dist/config/environment.js +54 -0
- package/dist/config/environment.js.map +1 -0
- package/dist/core/dependencies.d.ts +43 -0
- package/dist/core/dependencies.d.ts.map +1 -0
- package/dist/core/dependencies.js +2 -0
- package/dist/core/dependencies.js.map +1 -0
- package/dist/core/registry.d.ts +33 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +13 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/server.d.ts +61 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +90 -0
- package/dist/core/server.js.map +1 -0
- package/dist/dependencies.d.ts +28 -0
- package/dist/dependencies.d.ts.map +1 -0
- package/dist/dependencies.js +2 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/diagnostics/diagnose.d.ts +43 -0
- package/dist/diagnostics/diagnose.d.ts.map +1 -0
- package/dist/diagnostics/diagnose.js +121 -0
- package/dist/diagnostics/diagnose.js.map +1 -0
- package/dist/domain/amount.d.ts +157 -0
- package/dist/domain/amount.d.ts.map +1 -0
- package/dist/domain/amount.js +275 -0
- package/dist/domain/amount.js.map +1 -0
- package/dist/domain/datetime.d.ts +95 -0
- package/dist/domain/datetime.d.ts.map +1 -0
- package/dist/domain/datetime.js +211 -0
- package/dist/domain/datetime.js.map +1 -0
- package/dist/domain/response-codes.d.ts +116 -0
- package/dist/domain/response-codes.d.ts.map +1 -0
- package/dist/domain/response-codes.js +380 -0
- package/dist/domain/response-codes.js.map +1 -0
- package/dist/domain/secure-hash.d.ts +78 -0
- package/dist/domain/secure-hash.d.ts.map +1 -0
- package/dist/domain/secure-hash.js +69 -0
- package/dist/domain/secure-hash.js.map +1 -0
- package/dist/domain/signature/jazzcash.d.ts +56 -0
- package/dist/domain/signature/jazzcash.d.ts.map +1 -0
- package/dist/domain/signature/jazzcash.js +214 -0
- package/dist/domain/signature/jazzcash.js.map +1 -0
- package/dist/domain/signature/registry.d.ts +69 -0
- package/dist/domain/signature/registry.d.ts.map +1 -0
- package/dist/domain/signature/registry.js +92 -0
- package/dist/domain/signature/registry.js.map +1 -0
- package/dist/domain/signature/scheme.d.ts +349 -0
- package/dist/domain/signature/scheme.d.ts.map +1 -0
- package/dist/domain/signature/scheme.js +398 -0
- package/dist/domain/signature/scheme.js.map +1 -0
- package/dist/domain/txn-ref.d.ts +76 -0
- package/dist/domain/txn-ref.d.ts.map +1 -0
- package/dist/domain/txn-ref.js +126 -0
- package/dist/domain/txn-ref.js.map +1 -0
- package/dist/domain/types.d.ts +45 -0
- package/dist/domain/types.d.ts.map +1 -0
- package/dist/domain/types.js +70 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/errors.d.ts +84 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +87 -0
- package/dist/errors.js.map +1 -0
- package/dist/gateway/checkout-form.d.ts +16 -0
- package/dist/gateway/checkout-form.d.ts.map +1 -0
- package/dist/gateway/checkout-form.js +103 -0
- package/dist/gateway/checkout-form.js.map +1 -0
- package/dist/gateway/checkout-output.d.ts +70 -0
- package/dist/gateway/checkout-output.d.ts.map +1 -0
- package/dist/gateway/checkout-output.js +199 -0
- package/dist/gateway/checkout-output.js.map +1 -0
- package/dist/gateway/guards.d.ts +37 -0
- package/dist/gateway/guards.d.ts.map +1 -0
- package/dist/gateway/guards.js +44 -0
- package/dist/gateway/guards.js.map +1 -0
- package/dist/gateway/http-client.d.ts +42 -0
- package/dist/gateway/http-client.d.ts.map +1 -0
- package/dist/gateway/http-client.js +153 -0
- package/dist/gateway/http-client.js.map +1 -0
- package/dist/gateway/rest-client.d.ts +42 -0
- package/dist/gateway/rest-client.d.ts.map +1 -0
- package/dist/gateway/rest-client.js +241 -0
- package/dist/gateway/rest-client.js.map +1 -0
- package/dist/gateway/transport.d.ts +31 -0
- package/dist/gateway/transport.d.ts.map +1 -0
- package/dist/gateway/transport.js +73 -0
- package/dist/gateway/transport.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/install/cli.d.ts +38 -0
- package/dist/install/cli.d.ts.map +1 -0
- package/dist/install/cli.js +274 -0
- package/dist/install/cli.js.map +1 -0
- package/dist/install/harnesses.d.ts +74 -0
- package/dist/install/harnesses.d.ts.map +1 -0
- package/dist/install/harnesses.js +263 -0
- package/dist/install/harnesses.js.map +1 -0
- package/dist/knowledge/corpus.d.ts +15 -0
- package/dist/knowledge/corpus.d.ts.map +1 -0
- package/dist/knowledge/corpus.js +129 -0
- package/dist/knowledge/corpus.js.map +1 -0
- package/dist/knowledge/search.d.ts +29 -0
- package/dist/knowledge/search.d.ts.map +1 -0
- package/dist/knowledge/search.js +181 -0
- package/dist/knowledge/search.js.map +1 -0
- package/dist/knowledge/source.d.ts +60 -0
- package/dist/knowledge/source.d.ts.map +1 -0
- package/dist/knowledge/source.js +91 -0
- package/dist/knowledge/source.js.map +1 -0
- package/dist/knowledge/types.d.ts +40 -0
- package/dist/knowledge/types.d.ts.map +1 -0
- package/dist/knowledge/types.js +19 -0
- package/dist/knowledge/types.js.map +1 -0
- package/dist/paths.d.ts +26 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +106 -0
- package/dist/paths.js.map +1 -0
- package/dist/prompts/integration-walkthrough.d.ts +11 -0
- package/dist/prompts/integration-walkthrough.d.ts.map +1 -0
- package/dist/prompts/integration-walkthrough.js +52 -0
- package/dist/prompts/integration-walkthrough.js.map +1 -0
- package/dist/prompts/register.d.ts +4 -0
- package/dist/prompts/register.d.ts.map +1 -0
- package/dist/prompts/register.js +4 -0
- package/dist/prompts/register.js.map +1 -0
- package/dist/registry.d.ts +14 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +2 -0
- package/dist/registry.js.map +1 -0
- package/dist/resources/knowledge-resources.d.ts +5 -0
- package/dist/resources/knowledge-resources.d.ts.map +1 -0
- package/dist/resources/knowledge-resources.js +121 -0
- package/dist/resources/knowledge-resources.js.map +1 -0
- package/dist/resources/register.d.ts +4 -0
- package/dist/resources/register.d.ts.map +1 -0
- package/dist/resources/register.js +8 -0
- package/dist/resources/register.js.map +1 -0
- package/dist/server.d.ts +40 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +56 -0
- package/dist/server.js.map +1 -0
- package/dist/telemetry/logger.d.ts +31 -0
- package/dist/telemetry/logger.d.ts.map +1 -0
- package/dist/telemetry/logger.js +67 -0
- package/dist/telemetry/logger.js.map +1 -0
- package/dist/telemetry/redaction.d.ts +88 -0
- package/dist/telemetry/redaction.d.ts.map +1 -0
- package/dist/telemetry/redaction.js +238 -0
- package/dist/telemetry/redaction.js.map +1 -0
- package/dist/tools/build-transaction-parameters.d.ts +10 -0
- package/dist/tools/build-transaction-parameters.d.ts.map +1 -0
- package/dist/tools/build-transaction-parameters.js +154 -0
- package/dist/tools/build-transaction-parameters.js.map +1 -0
- package/dist/tools/call-context.d.ts +47 -0
- package/dist/tools/call-context.d.ts.map +1 -0
- package/dist/tools/call-context.js +15 -0
- package/dist/tools/call-context.js.map +1 -0
- package/dist/tools/codegen-tools.d.ts +4 -0
- package/dist/tools/codegen-tools.d.ts.map +1 -0
- package/dist/tools/codegen-tools.js +131 -0
- package/dist/tools/codegen-tools.js.map +1 -0
- package/dist/tools/credential-tools.d.ts +32 -0
- package/dist/tools/credential-tools.d.ts.map +1 -0
- package/dist/tools/credential-tools.js +65 -0
- package/dist/tools/credential-tools.js.map +1 -0
- package/dist/tools/descriptor.d.ts +52 -0
- package/dist/tools/descriptor.d.ts.map +1 -0
- package/dist/tools/descriptor.js +2 -0
- package/dist/tools/descriptor.js.map +1 -0
- package/dist/tools/diagnostic-tools.d.ts +3 -0
- package/dist/tools/diagnostic-tools.d.ts.map +1 -0
- package/dist/tools/diagnostic-tools.js +128 -0
- package/dist/tools/diagnostic-tools.js.map +1 -0
- package/dist/tools/gateway-tools.d.ts +6 -0
- package/dist/tools/gateway-tools.d.ts.map +1 -0
- package/dist/tools/gateway-tools.js +381 -0
- package/dist/tools/gateway-tools.js.map +1 -0
- package/dist/tools/hash-tools.d.ts +5 -0
- package/dist/tools/hash-tools.d.ts.map +1 -0
- package/dist/tools/hash-tools.js +238 -0
- package/dist/tools/hash-tools.js.map +1 -0
- package/dist/tools/knowledge-tools.d.ts +7 -0
- package/dist/tools/knowledge-tools.d.ts.map +1 -0
- package/dist/tools/knowledge-tools.js +247 -0
- package/dist/tools/knowledge-tools.js.map +1 -0
- package/dist/tools/onboarding-checklist.d.ts +3 -0
- package/dist/tools/onboarding-checklist.d.ts.map +1 -0
- package/dist/tools/onboarding-checklist.js +141 -0
- package/dist/tools/onboarding-checklist.js.map +1 -0
- package/dist/tools/register.d.ts +60 -0
- package/dist/tools/register.d.ts.map +1 -0
- package/dist/tools/register.js +145 -0
- package/dist/tools/register.js.map +1 -0
- package/dist/tools/tool-kit.d.ts +88 -0
- package/dist/tools/tool-kit.d.ts.map +1 -0
- package/dist/tools/tool-kit.js +297 -0
- package/dist/tools/tool-kit.js.map +1 -0
- package/dist/validation/payload-validator.d.ts +29 -0
- package/dist/validation/payload-validator.d.ts.map +1 -0
- package/dist/validation/payload-validator.js +79 -0
- package/dist/validation/payload-validator.js.map +1 -0
- package/dist/validation/rules/amount.d.ts +3 -0
- package/dist/validation/rules/amount.d.ts.map +1 -0
- package/dist/validation/rules/amount.js +77 -0
- package/dist/validation/rules/amount.js.map +1 -0
- package/dist/validation/rules/bill-reference.d.ts +10 -0
- package/dist/validation/rules/bill-reference.d.ts.map +1 -0
- package/dist/validation/rules/bill-reference.js +34 -0
- package/dist/validation/rules/bill-reference.js.map +1 -0
- package/dist/validation/rules/cnic.d.ts +3 -0
- package/dist/validation/rules/cnic.d.ts.map +1 -0
- package/dist/validation/rules/cnic.js +42 -0
- package/dist/validation/rules/cnic.js.map +1 -0
- package/dist/validation/rules/constants.d.ts +9 -0
- package/dist/validation/rules/constants.d.ts.map +1 -0
- package/dist/validation/rules/constants.js +28 -0
- package/dist/validation/rules/constants.js.map +1 -0
- package/dist/validation/rules/constraints.d.ts +3 -0
- package/dist/validation/rules/constraints.d.ts.map +1 -0
- package/dist/validation/rules/constraints.js +113 -0
- package/dist/validation/rules/constraints.js.map +1 -0
- package/dist/validation/rules/datetime.d.ts +3 -0
- package/dist/validation/rules/datetime.d.ts.map +1 -0
- package/dist/validation/rules/datetime.js +49 -0
- package/dist/validation/rules/datetime.js.map +1 -0
- package/dist/validation/rules/empty-string.d.ts +13 -0
- package/dist/validation/rules/empty-string.d.ts.map +1 -0
- package/dist/validation/rules/empty-string.js +32 -0
- package/dist/validation/rules/empty-string.js.map +1 -0
- package/dist/validation/rules/expiry.d.ts +3 -0
- package/dist/validation/rules/expiry.d.ts.map +1 -0
- package/dist/validation/rules/expiry.js +52 -0
- package/dist/validation/rules/expiry.js.map +1 -0
- package/dist/validation/rules/msisdn.d.ts +3 -0
- package/dist/validation/rules/msisdn.d.ts.map +1 -0
- package/dist/validation/rules/msisdn.js +45 -0
- package/dist/validation/rules/msisdn.js.map +1 -0
- package/dist/validation/rules/presence.d.ts +3 -0
- package/dist/validation/rules/presence.d.ts.map +1 -0
- package/dist/validation/rules/presence.js +90 -0
- package/dist/validation/rules/presence.js.map +1 -0
- package/dist/validation/rules/return-url.d.ts +14 -0
- package/dist/validation/rules/return-url.d.ts.map +1 -0
- package/dist/validation/rules/return-url.js +58 -0
- package/dist/validation/rules/return-url.js.map +1 -0
- package/dist/validation/rules/tool-argument.d.ts +16 -0
- package/dist/validation/rules/tool-argument.d.ts.map +1 -0
- package/dist/validation/rules/tool-argument.js +38 -0
- package/dist/validation/rules/tool-argument.js.map +1 -0
- package/dist/validation/rules/txn-ref.d.ts +3 -0
- package/dist/validation/rules/txn-ref.d.ts.map +1 -0
- package/dist/validation/rules/txn-ref.js +47 -0
- package/dist/validation/rules/txn-ref.js.map +1 -0
- package/dist/validation/rules/unknown-fields.d.ts +10 -0
- package/dist/validation/rules/unknown-fields.d.ts.map +1 -0
- package/dist/validation/rules/unknown-fields.js +29 -0
- package/dist/validation/rules/unknown-fields.js.map +1 -0
- package/dist/validation/types.d.ts +36 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +12 -0
- package/dist/validation/types.js.map +1 -0
- package/dist/version.d.ts +23 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +23 -0
- package/dist/version.js.map +1 -0
- package/knowledge/diagnostics/symptoms.json +321 -0
- package/knowledge/docs/bnpl-guide.md +77 -0
- package/knowledge/docs/card-page-redirection.md +67 -0
- package/knowledge/docs/card-refund.md +91 -0
- package/knowledge/docs/hmac-sha256-calculation.md +72 -0
- package/knowledge/docs/index.json +189 -0
- package/knowledge/docs/ipn-implementation.md +89 -0
- package/knowledge/docs/mwallet-recurring.md +117 -0
- package/knowledge/docs/mwallet-refund.md +65 -0
- package/knowledge/docs/mwallet-rest-v1-1.md +126 -0
- package/knowledge/docs/mwallet-rest-v2-0-cnic.md +113 -0
- package/knowledge/docs/portal-guide.md +45 -0
- package/knowledge/docs/shopify-guide.md +74 -0
- package/knowledge/docs/status-inquiry-2025-26.md +32 -0
- package/knowledge/docs/status-inquiry.md +111 -0
- package/knowledge/docs/wordpress-guide.md +49 -0
- package/knowledge/flow.schema.json +390 -0
- package/knowledge/flows/bnpl-page-redirection-v1.1.json +211 -0
- package/knowledge/flows/card-page-redirection-v1.1.json +211 -0
- package/knowledge/flows/mwallet-rest-v1.1.json +187 -0
- package/knowledge/flows/mwallet-rest-v2.0-cnic.json +197 -0
- package/knowledge/flows/mwallet-token-pay-v4.0.json +130 -0
- package/knowledge/flows/refund-bnpl.json +105 -0
- package/knowledge/flows/refund-card-v1.1.json +112 -0
- package/knowledge/flows/refund-card-v2.0.json +121 -0
- package/knowledge/flows/refund-mwallet-v1.1.json +106 -0
- package/knowledge/flows/status-inquiry-v1.1.json +102 -0
- package/knowledge/flows/status-inquiry-v2.0.json +103 -0
- package/knowledge/flows/token-delete-v1.json +85 -0
- package/knowledge/flows/token-inquiry-v1.json +85 -0
- package/knowledge/flows/wallet-linking-portal.json +103 -0
- package/knowledge/templates/node/checkout-redirect.tmpl +166 -0
- package/knowledge/templates/node/ipn-handler.tmpl +108 -0
- package/knowledge/templates/node/rest-client.tmpl +197 -0
- package/knowledge/templates/node/wallet-linking.tmpl +147 -0
- package/knowledge/templates/php/checkout-redirect.tmpl +149 -0
- package/knowledge/templates/php/ipn-handler.tmpl +105 -0
- package/knowledge/templates/php/rest-client.tmpl +191 -0
- package/knowledge/templates/php/wallet-linking.tmpl +137 -0
- package/knowledge/templates/python/checkout-redirect.tmpl +148 -0
- package/knowledge/templates/python/ipn-handler.tmpl +110 -0
- package/knowledge/templates/python/rest-client.tmpl +179 -0
- package/knowledge/templates/python/wallet-linking.tmpl +133 -0
- package/package.json +84 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locate the flow catalogue that ships beside the code.
|
|
3
|
+
*
|
|
4
|
+
* Split from `loadFlowCatalogue` so that the loader itself carries no import of
|
|
5
|
+
* `../paths.js`. That module resolves the corpus directory by walking up from
|
|
6
|
+
* `import.meta.url`, which is correct for a checkout and for an npm install of
|
|
7
|
+
* this package and wrong inside a bundle — and the loader is bundled into the
|
|
8
|
+
* published connector, which ships no corpus directory and reads its
|
|
9
|
+
* specifications from generated source instead. Keeping the walk here means the
|
|
10
|
+
* connector never carries it, and `scripts/closure.mjs` enforces that.
|
|
11
|
+
*
|
|
12
|
+
* Only the *location* lives here. Loading a catalogue from it is a caller's
|
|
13
|
+
* decision — `createServerDependencies` makes it once, and the tests that want
|
|
14
|
+
* the shipped catalogue use `tests/helpers/catalogue.ts` rather than a
|
|
15
|
+
* convenience wrapper shipped in production code for their benefit.
|
|
16
|
+
*/
|
|
17
|
+
export declare function defaultFlowSource(): string;
|
|
18
|
+
//# sourceMappingURL=default-catalogue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-catalogue.d.ts","sourceRoot":"","sources":["../../src/catalogue/default-catalogue.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { knowledgePath } from '../paths.js';
|
|
2
|
+
/**
|
|
3
|
+
* Locate the flow catalogue that ships beside the code.
|
|
4
|
+
*
|
|
5
|
+
* Split from `loadFlowCatalogue` so that the loader itself carries no import of
|
|
6
|
+
* `../paths.js`. That module resolves the corpus directory by walking up from
|
|
7
|
+
* `import.meta.url`, which is correct for a checkout and for an npm install of
|
|
8
|
+
* this package and wrong inside a bundle — and the loader is bundled into the
|
|
9
|
+
* published connector, which ships no corpus directory and reads its
|
|
10
|
+
* specifications from generated source instead. Keeping the walk here means the
|
|
11
|
+
* connector never carries it, and `scripts/closure.mjs` enforces that.
|
|
12
|
+
*
|
|
13
|
+
* Only the *location* lives here. Loading a catalogue from it is a caller's
|
|
14
|
+
* decision — `createServerDependencies` makes it once, and the tests that want
|
|
15
|
+
* the shipped catalogue use `tests/helpers/catalogue.ts` rather than a
|
|
16
|
+
* convenience wrapper shipped in production code for their benefit.
|
|
17
|
+
*/
|
|
18
|
+
export function defaultFlowSource() {
|
|
19
|
+
return knowledgePath('flows');
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=default-catalogue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-catalogue.js","sourceRoot":"","sources":["../../src/catalogue/default-catalogue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { JazzCashEnvironment } from '../config/environment.js';
|
|
2
|
+
import type { IntegrationFlow } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Endpoint resolution and the portal URLs merchants need during onboarding.
|
|
5
|
+
*/
|
|
6
|
+
export declare const JAZZCASH_BASE_URL = "https://onlinepayments.jazzcash.com.pk";
|
|
7
|
+
/** URLs that are not flow endpoints but are part of every onboarding conversation. */
|
|
8
|
+
export declare const PORTAL_URLS: {
|
|
9
|
+
readonly sandboxSignup: "https://onlinepayments.jazzcash.com.pk/sandbox-frontend/";
|
|
10
|
+
readonly merchantPortalLogin: "https://onlinepayments.jazzcash.com.pk/merchant-frontend/login";
|
|
11
|
+
readonly shopifyAppListing: "https://apps.shopify.com/jazzcash";
|
|
12
|
+
};
|
|
13
|
+
/** Resolve the endpoint for a flow in a given environment. */
|
|
14
|
+
export declare function resolveEndpoint(flow: IntegrationFlow, environment: JazzCashEnvironment): string;
|
|
15
|
+
/**
|
|
16
|
+
* True when the endpoint alone cannot distinguish sandbox from production.
|
|
17
|
+
*
|
|
18
|
+
* This holds for every documented flow, which is why `environment` is a required
|
|
19
|
+
* argument on every network tool rather than something inferred from a URL.
|
|
20
|
+
*/
|
|
21
|
+
export declare function endpointIsAmbiguous(flow: IntegrationFlow): boolean;
|
|
22
|
+
//# sourceMappingURL=endpoints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/catalogue/endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AAEH,eAAO,MAAM,iBAAiB,2CAA2C,CAAC;AAE1E,sFAAsF;AACtF,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAEX,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,mBAAmB,GAAG,MAAM,CAE/F;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAElE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Endpoint resolution and the portal URLs merchants need during onboarding.
|
|
3
|
+
*/
|
|
4
|
+
export const JAZZCASH_BASE_URL = 'https://onlinepayments.jazzcash.com.pk';
|
|
5
|
+
/** URLs that are not flow endpoints but are part of every onboarding conversation. */
|
|
6
|
+
export const PORTAL_URLS = {
|
|
7
|
+
sandboxSignup: `${JAZZCASH_BASE_URL}/sandbox-frontend/`,
|
|
8
|
+
merchantPortalLogin: `${JAZZCASH_BASE_URL}/merchant-frontend/login`,
|
|
9
|
+
shopifyAppListing: 'https://apps.shopify.com/jazzcash',
|
|
10
|
+
};
|
|
11
|
+
/** Resolve the endpoint for a flow in a given environment. */
|
|
12
|
+
export function resolveEndpoint(flow, environment) {
|
|
13
|
+
return environment === 'sandbox' ? flow.endpoints.sandbox : flow.endpoints.production;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* True when the endpoint alone cannot distinguish sandbox from production.
|
|
17
|
+
*
|
|
18
|
+
* This holds for every documented flow, which is why `environment` is a required
|
|
19
|
+
* argument on every network tool rather than something inferred from a URL.
|
|
20
|
+
*/
|
|
21
|
+
export function endpointIsAmbiguous(flow) {
|
|
22
|
+
return flow.endpoints.sandbox === flow.endpoints.production;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=endpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/catalogue/endpoints.ts"],"names":[],"mappings":"AAGA;;GAEG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,wCAAwC,CAAC;AAE1E,sFAAsF;AACtF,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,aAAa,EAAE,GAAG,iBAAiB,oBAAoB;IACvD,mBAAmB,EAAE,GAAG,iBAAiB,0BAA0B;IACnE,iBAAiB,EAAE,mCAAmC;CAC9C,CAAC;AAEX,8DAA8D;AAC9D,MAAM,UAAU,eAAe,CAAC,IAAqB,EAAE,WAAgC;IACrF,OAAO,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;AACxF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAqB;IACvD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type CorpusSource } from '../knowledge/source.js';
|
|
2
|
+
import { type IntegrationFlow, type Product } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Loader for the flow catalogue in `knowledge/flows/`.
|
|
5
|
+
*
|
|
6
|
+
* Specifications are parsed and validated once at start-up. A malformed file is
|
|
7
|
+
* a fatal configuration error rather than a runtime surprise: a flow with a
|
|
8
|
+
* missing parameter would silently generate an invalid payload.
|
|
9
|
+
*
|
|
10
|
+
* Files arrive through a `CorpusSource`, so the same loader serves a catalogue
|
|
11
|
+
* that is not a directory on this machine.
|
|
12
|
+
*/
|
|
13
|
+
export interface FlowCatalogue {
|
|
14
|
+
list(): readonly IntegrationFlow[];
|
|
15
|
+
ids(): readonly string[];
|
|
16
|
+
get(id: string): IntegrationFlow;
|
|
17
|
+
find(id: string): IntegrationFlow | undefined;
|
|
18
|
+
byProduct(product: Product): readonly IntegrationFlow[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Load and index every flow specification. Throws if any file is malformed.
|
|
22
|
+
*
|
|
23
|
+
* The source is required rather than defaulted to the corpus directory beside
|
|
24
|
+
* the code. A default would mean a static import of `../paths.js`, whose
|
|
25
|
+
* package-root walk resolves from `import.meta.url` — and this module is bundled
|
|
26
|
+
* into the published connector, where that walk answers wrongly and where no
|
|
27
|
+
* corpus directory exists at all. `loadDefaultFlowCatalogue` in
|
|
28
|
+
* `./default-catalogue.js` supplies the on-disk source for every caller that
|
|
29
|
+
* wants it, and keeps that import out of the connector's module graph.
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadFlowCatalogue(source: CorpusSource | string): FlowCatalogue;
|
|
32
|
+
//# sourceMappingURL=flows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/catalogue/flows.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAc,KAAK,eAAe,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5E;;;;;;;;;GASG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,IAAI,SAAS,eAAe,EAAE,CAAC;IACnC,GAAG,IAAI,SAAS,MAAM,EAAE,CAAC;IACzB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,CAAC;IACjC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IAC9C,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,eAAe,EAAE,CAAC;CACzD;AA2BD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,GAAG,aAAa,CAiC9E"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
import { JazzCashConfigError, JazzCashNotFoundError } from '../errors.js';
|
|
3
|
+
import { toCorpusSource } from '../knowledge/source.js';
|
|
4
|
+
import { flowSchema } from './types.js';
|
|
5
|
+
function readFlowFile(files, name) {
|
|
6
|
+
let parsedJson;
|
|
7
|
+
try {
|
|
8
|
+
parsedJson = JSON.parse(files.readText(name));
|
|
9
|
+
}
|
|
10
|
+
catch (cause) {
|
|
11
|
+
throw new JazzCashConfigError(`Flow specification ${name} is not readable JSON.`, { cause });
|
|
12
|
+
}
|
|
13
|
+
const parsed = flowSchema.safeParse(parsedJson);
|
|
14
|
+
if (!parsed.success) {
|
|
15
|
+
const issues = parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; ');
|
|
16
|
+
throw new JazzCashConfigError(`Flow specification ${name} is invalid. ${issues}`);
|
|
17
|
+
}
|
|
18
|
+
const flow = parsed.data;
|
|
19
|
+
const expectedId = basename(name, '.json');
|
|
20
|
+
if (flow.id !== expectedId) {
|
|
21
|
+
throw new JazzCashConfigError(`Flow specification ${name} declares id "${flow.id}". The file name and the id must match so that citations resolve.`);
|
|
22
|
+
}
|
|
23
|
+
return flow;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Load and index every flow specification. Throws if any file is malformed.
|
|
27
|
+
*
|
|
28
|
+
* The source is required rather than defaulted to the corpus directory beside
|
|
29
|
+
* the code. A default would mean a static import of `../paths.js`, whose
|
|
30
|
+
* package-root walk resolves from `import.meta.url` — and this module is bundled
|
|
31
|
+
* into the published connector, where that walk answers wrongly and where no
|
|
32
|
+
* corpus directory exists at all. `loadDefaultFlowCatalogue` in
|
|
33
|
+
* `./default-catalogue.js` supplies the on-disk source for every caller that
|
|
34
|
+
* wants it, and keeps that import out of the connector's module graph.
|
|
35
|
+
*/
|
|
36
|
+
export function loadFlowCatalogue(source) {
|
|
37
|
+
const files = toCorpusSource(source);
|
|
38
|
+
let fileNames;
|
|
39
|
+
try {
|
|
40
|
+
fileNames = files.entryNames().filter((name) => name.endsWith('.json'));
|
|
41
|
+
}
|
|
42
|
+
catch (cause) {
|
|
43
|
+
throw new JazzCashConfigError(`Unable to read the flow catalogue directory at ${files.location}.`, { cause });
|
|
44
|
+
}
|
|
45
|
+
if (fileNames.length === 0) {
|
|
46
|
+
throw new JazzCashConfigError(`No flow specifications found in ${files.location}.`);
|
|
47
|
+
}
|
|
48
|
+
const flows = fileNames.map((name) => readFlowFile(files, name)).sort((left, right) => (left.id < right.id ? -1 : 1));
|
|
49
|
+
const byId = new Map(flows.map((flow) => [flow.id, flow]));
|
|
50
|
+
return {
|
|
51
|
+
list: () => flows,
|
|
52
|
+
ids: () => flows.map((flow) => flow.id),
|
|
53
|
+
find: (id) => byId.get(id),
|
|
54
|
+
get(id) {
|
|
55
|
+
const flow = byId.get(id);
|
|
56
|
+
if (flow === undefined) {
|
|
57
|
+
throw new JazzCashNotFoundError(`No integration flow with id "${id}". Available flows: ${flows.map((entry) => entry.id).join(', ')}.`);
|
|
58
|
+
}
|
|
59
|
+
return flow;
|
|
60
|
+
},
|
|
61
|
+
byProduct: (product) => flows.filter((flow) => flow.product === product),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=flows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flows.js","sourceRoot":"","sources":["../../src/catalogue/flows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { SignatureOptions } from '../domain/signature/registry.js';
|
|
2
|
+
import type { SchemeProvenance } from '../domain/signature/scheme.js';
|
|
3
|
+
import type { IntegrationFlow } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Hash options derived from a flow specification.
|
|
6
|
+
*
|
|
7
|
+
* Requests and responses do NOT share a field-selection rule, and conflating
|
|
8
|
+
* them is a security defect rather than a tidiness problem:
|
|
9
|
+
*
|
|
10
|
+
* - Requests are prefix-filtered (`pp_`, `ppmpf_`), because a merchant payload
|
|
11
|
+
* may legitimately carry application fields that must not be hashed.
|
|
12
|
+
* - Responses are NOT prefix-filtered. Card refund v1.1, card refund v2.0 and
|
|
13
|
+
* BNPL refund return `ResponseCode`, `ResponseMessage`, `RefundAmount`,
|
|
14
|
+
* `TotalRefundAmount` and `SecureHash` with no prefix at all. Applying the
|
|
15
|
+
* request filter to those responses removes every field, collapsing the hash
|
|
16
|
+
* input to the bare Integrity Salt — which produces the same digest for any
|
|
17
|
+
* response body, so a forged response verifies successfully.
|
|
18
|
+
*
|
|
19
|
+
* Both derivations live here, named for their direction, so a call site cannot
|
|
20
|
+
* reach for the wrong one by spreading `flow.hash` into a response check.
|
|
21
|
+
*
|
|
22
|
+
* Each derivation also names the signature SCHEME it selects, rather than
|
|
23
|
+
* returning `flow.hash` directly. A hash specification is structurally
|
|
24
|
+
* assignable to the JazzCash options whatever construction it describes, so a
|
|
25
|
+
* direct return compiles for a second scheme and signs it the wrong way, with
|
|
26
|
+
* no error until the gateway rejects the transaction.
|
|
27
|
+
*/
|
|
28
|
+
/** Field selection and construction for signing and verifying a REQUEST. */
|
|
29
|
+
export declare function requestHashOptions(flow: IntegrationFlow): SignatureOptions;
|
|
30
|
+
/**
|
|
31
|
+
* Field selection for verifying a RESPONSE.
|
|
32
|
+
*
|
|
33
|
+
* The JazzCash spellings are excluded alongside the flow's own field name,
|
|
34
|
+
* because a flow's field name is not always the one present in a hand-pasted
|
|
35
|
+
* payload. A flow that declares no response signature contributes no name of
|
|
36
|
+
* its own, and the two spellings still have to go: this function is also called
|
|
37
|
+
* for payloads that arrive without a flow.
|
|
38
|
+
*
|
|
39
|
+
* JazzCash-scoped, which is every flow the corpus ships. A gateway whose
|
|
40
|
+
* responses are signed by some other construction would need that construction
|
|
41
|
+
* derivable from the response spec — which declares no ordered component list,
|
|
42
|
+
* and inventing one produces a confident digest computed over the wrong string.
|
|
43
|
+
* Such a gateway must declare what its responses sign, and this function must
|
|
44
|
+
* then select the scheme the way `requestHashOptions` does.
|
|
45
|
+
*/
|
|
46
|
+
export declare function responseHashOptions(flow: IntegrationFlow): SignatureOptions;
|
|
47
|
+
/**
|
|
48
|
+
* JazzCash response field selection when the flow is unknown.
|
|
49
|
+
*
|
|
50
|
+
* Used by tools that accept a payload without a `flowId`, and by IPN
|
|
51
|
+
* verification, which has no flow. No prefix filter: an unfiltered hash may be
|
|
52
|
+
* wrong for a given flow, but a filtered one is silently vacuous for the three
|
|
53
|
+
* refund flows, and a wrong answer is safer than a vacuous one.
|
|
54
|
+
*
|
|
55
|
+
* The scheme is named rather than left to default, because the exclusions below
|
|
56
|
+
* are JazzCash field names. Another gateway's callback verified with these would
|
|
57
|
+
* feed its own signature back into its own input and could only ever come back
|
|
58
|
+
* unverified — a result that must not be read as evidence of a broken
|
|
59
|
+
* integration.
|
|
60
|
+
*
|
|
61
|
+
* That argument covers verification and nothing else, and this constant also
|
|
62
|
+
* reaches DIAGNOSIS, where "wrong is safer than vacuous" inverts: a wrong
|
|
63
|
+
* construction replayed through a forensic table reproduces a foreign gateway's
|
|
64
|
+
* CORRECT signature and reports it as a proven defect. Measured on shipping
|
|
65
|
+
* code, a gateway signing `SHA256(secret&sorted-values)` was told "Reproduced
|
|
66
|
+
* your hash exactly by applying a known construction error: Plain SHA-256 used
|
|
67
|
+
* instead of HMAC-SHA256". `forensicProvenance` is what stops it.
|
|
68
|
+
*/
|
|
69
|
+
export declare const UNKNOWN_FLOW_RESPONSE_HASH_OPTIONS: SignatureOptions;
|
|
70
|
+
/**
|
|
71
|
+
* Whether a mismatch under the derivation above may be reported as a proven cause.
|
|
72
|
+
*
|
|
73
|
+
* A `confirmed` hypothesis says a known wrong construction reproduced the
|
|
74
|
+
* merchant's signature exactly. That is evidence only where the construction it
|
|
75
|
+
* varies is the one the payload was signed under, and the three derivations
|
|
76
|
+
* above differ in whether it is:
|
|
77
|
+
*
|
|
78
|
+
* - REQUEST — `requestHashOptions` reads the construction from the flow's own
|
|
79
|
+
* `hash` specification, so it is declared. With no flow the JazzCash default
|
|
80
|
+
* applies, and that default selects `pp_`/`ppmpf_` fields only: a payload
|
|
81
|
+
* from another gateway contributes nothing to it, so no variant can
|
|
82
|
+
* reproduce that gateway's signature. Both are evidence.
|
|
83
|
+
* - RESPONSE — both response derivations select the JazzCash construction with
|
|
84
|
+
* NO prefix filter, so they will happily hash a foreign payload's fields
|
|
85
|
+
* under JazzCash rules. For a flow the corpus knows that is the gateway's own
|
|
86
|
+
* construction and the reproduction stands. For a payload arriving without
|
|
87
|
+
* one it is this server's guess, and a guess cannot demonstrate what a
|
|
88
|
+
* merchant's code did.
|
|
89
|
+
*
|
|
90
|
+
* Named for the decision rather than folded into the options, because the
|
|
91
|
+
* options are also passed to `computeSecureHash`, where the same assumption is
|
|
92
|
+
* survivable: an unverified response is reported as unverified (assumption A2),
|
|
93
|
+
* while an unfounded `confirmed` sends a merchant to break working code.
|
|
94
|
+
*/
|
|
95
|
+
export declare function forensicProvenance(flow: IntegrationFlow | undefined, direction: 'request' | 'response'): SchemeProvenance;
|
|
96
|
+
/**
|
|
97
|
+
* The parameter a flow writes its request signature into.
|
|
98
|
+
*
|
|
99
|
+
* Read from the flow rather than spelled `pp_SecureHash` at the call site: that
|
|
100
|
+
* is JazzCash's name for it, and a payload built for a gateway that spells it
|
|
101
|
+
* otherwise carries a correct digest in a field that gateway never reads — a
|
|
102
|
+
* rejected transaction with nothing in the response to explain it. The flow already
|
|
103
|
+
* carries the answer as the parameter whose `valueType` is `secure-hash`, and
|
|
104
|
+
* `tests/catalogue/flows.test.ts` asserts every flow declares exactly one, so
|
|
105
|
+
* no new schema field is needed to derive it.
|
|
106
|
+
*
|
|
107
|
+
* Returns `undefined` for a flow that declares none, because a flow that does
|
|
108
|
+
* not sign has no field to name and inventing one would be the same defect
|
|
109
|
+
* pointed the other way.
|
|
110
|
+
*/
|
|
111
|
+
export declare function signatureFieldName(flow: IntegrationFlow): string | undefined;
|
|
112
|
+
//# sourceMappingURL=hash-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash-options.d.ts","sourceRoot":"","sources":["../../src/catalogue/hash-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,gBAAgB,CAwB1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,gBAAgB,CAQ3E;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,kCAAkC,EAAE,gBAIhD,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,eAAe,GAAG,SAAS,EACjC,SAAS,EAAE,SAAS,GAAG,UAAU,GAChC,gBAAgB,CAOlB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAE5E"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hash options derived from a flow specification.
|
|
3
|
+
*
|
|
4
|
+
* Requests and responses do NOT share a field-selection rule, and conflating
|
|
5
|
+
* them is a security defect rather than a tidiness problem:
|
|
6
|
+
*
|
|
7
|
+
* - Requests are prefix-filtered (`pp_`, `ppmpf_`), because a merchant payload
|
|
8
|
+
* may legitimately carry application fields that must not be hashed.
|
|
9
|
+
* - Responses are NOT prefix-filtered. Card refund v1.1, card refund v2.0 and
|
|
10
|
+
* BNPL refund return `ResponseCode`, `ResponseMessage`, `RefundAmount`,
|
|
11
|
+
* `TotalRefundAmount` and `SecureHash` with no prefix at all. Applying the
|
|
12
|
+
* request filter to those responses removes every field, collapsing the hash
|
|
13
|
+
* input to the bare Integrity Salt — which produces the same digest for any
|
|
14
|
+
* response body, so a forged response verifies successfully.
|
|
15
|
+
*
|
|
16
|
+
* Both derivations live here, named for their direction, so a call site cannot
|
|
17
|
+
* reach for the wrong one by spreading `flow.hash` into a response check.
|
|
18
|
+
*
|
|
19
|
+
* Each derivation also names the signature SCHEME it selects, rather than
|
|
20
|
+
* returning `flow.hash` directly. A hash specification is structurally
|
|
21
|
+
* assignable to the JazzCash options whatever construction it describes, so a
|
|
22
|
+
* direct return compiles for a second scheme and signs it the wrong way, with
|
|
23
|
+
* no error until the gateway rejects the transaction.
|
|
24
|
+
*/
|
|
25
|
+
/** Field selection and construction for signing and verifying a REQUEST. */
|
|
26
|
+
export function requestHashOptions(flow) {
|
|
27
|
+
const hash = flow.hash;
|
|
28
|
+
// Exhaustive by construction: a second algorithm added to the flow schema
|
|
29
|
+
// fails to compile here rather than silently inheriting this one.
|
|
30
|
+
switch (hash.algorithm) {
|
|
31
|
+
case 'hmac-sha256':
|
|
32
|
+
return {
|
|
33
|
+
scheme: 'jazzcash',
|
|
34
|
+
includeFieldPrefixes: hash.includeFieldPrefixes,
|
|
35
|
+
excludeFields: hash.excludeFields,
|
|
36
|
+
outputEncoding: hash.outputEncoding,
|
|
37
|
+
comparison: hash.comparison,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// A second algorithm fails on this line, naming itself. Left to TypeScript's
|
|
41
|
+
// "lacks ending return statement" the error is about this function rather than
|
|
42
|
+
// about the member nobody handled, and the obvious way to silence it is a
|
|
43
|
+
// `default:` — which signs the new construction as the one above.
|
|
44
|
+
/* c8 ignore start -- unreachable: the switch above is exhaustive, and the assignment below is what proves it */
|
|
45
|
+
const _exhaustive = hash.algorithm;
|
|
46
|
+
return _exhaustive;
|
|
47
|
+
/* c8 ignore stop */
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Field selection for verifying a RESPONSE.
|
|
51
|
+
*
|
|
52
|
+
* The JazzCash spellings are excluded alongside the flow's own field name,
|
|
53
|
+
* because a flow's field name is not always the one present in a hand-pasted
|
|
54
|
+
* payload. A flow that declares no response signature contributes no name of
|
|
55
|
+
* its own, and the two spellings still have to go: this function is also called
|
|
56
|
+
* for payloads that arrive without a flow.
|
|
57
|
+
*
|
|
58
|
+
* JazzCash-scoped, which is every flow the corpus ships. A gateway whose
|
|
59
|
+
* responses are signed by some other construction would need that construction
|
|
60
|
+
* derivable from the response spec — which declares no ordered component list,
|
|
61
|
+
* and inventing one produces a confident digest computed over the wrong string.
|
|
62
|
+
* Such a gateway must declare what its responses sign, and this function must
|
|
63
|
+
* then select the scheme the way `requestHashOptions` does.
|
|
64
|
+
*/
|
|
65
|
+
export function responseHashOptions(flow) {
|
|
66
|
+
const declaredField = flow.response.hashField;
|
|
67
|
+
return {
|
|
68
|
+
scheme: 'jazzcash',
|
|
69
|
+
includeFieldPrefixes: flow.response.hashFieldPrefixes,
|
|
70
|
+
excludeFields: [...(declaredField === undefined ? [] : [declaredField]), 'pp_SecureHash', 'SecureHash'],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* JazzCash response field selection when the flow is unknown.
|
|
75
|
+
*
|
|
76
|
+
* Used by tools that accept a payload without a `flowId`, and by IPN
|
|
77
|
+
* verification, which has no flow. No prefix filter: an unfiltered hash may be
|
|
78
|
+
* wrong for a given flow, but a filtered one is silently vacuous for the three
|
|
79
|
+
* refund flows, and a wrong answer is safer than a vacuous one.
|
|
80
|
+
*
|
|
81
|
+
* The scheme is named rather than left to default, because the exclusions below
|
|
82
|
+
* are JazzCash field names. Another gateway's callback verified with these would
|
|
83
|
+
* feed its own signature back into its own input and could only ever come back
|
|
84
|
+
* unverified — a result that must not be read as evidence of a broken
|
|
85
|
+
* integration.
|
|
86
|
+
*
|
|
87
|
+
* That argument covers verification and nothing else, and this constant also
|
|
88
|
+
* reaches DIAGNOSIS, where "wrong is safer than vacuous" inverts: a wrong
|
|
89
|
+
* construction replayed through a forensic table reproduces a foreign gateway's
|
|
90
|
+
* CORRECT signature and reports it as a proven defect. Measured on shipping
|
|
91
|
+
* code, a gateway signing `SHA256(secret&sorted-values)` was told "Reproduced
|
|
92
|
+
* your hash exactly by applying a known construction error: Plain SHA-256 used
|
|
93
|
+
* instead of HMAC-SHA256". `forensicProvenance` is what stops it.
|
|
94
|
+
*/
|
|
95
|
+
export const UNKNOWN_FLOW_RESPONSE_HASH_OPTIONS = {
|
|
96
|
+
scheme: 'jazzcash',
|
|
97
|
+
includeFieldPrefixes: [],
|
|
98
|
+
excludeFields: ['pp_SecureHash', 'SecureHash'],
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Whether a mismatch under the derivation above may be reported as a proven cause.
|
|
102
|
+
*
|
|
103
|
+
* A `confirmed` hypothesis says a known wrong construction reproduced the
|
|
104
|
+
* merchant's signature exactly. That is evidence only where the construction it
|
|
105
|
+
* varies is the one the payload was signed under, and the three derivations
|
|
106
|
+
* above differ in whether it is:
|
|
107
|
+
*
|
|
108
|
+
* - REQUEST — `requestHashOptions` reads the construction from the flow's own
|
|
109
|
+
* `hash` specification, so it is declared. With no flow the JazzCash default
|
|
110
|
+
* applies, and that default selects `pp_`/`ppmpf_` fields only: a payload
|
|
111
|
+
* from another gateway contributes nothing to it, so no variant can
|
|
112
|
+
* reproduce that gateway's signature. Both are evidence.
|
|
113
|
+
* - RESPONSE — both response derivations select the JazzCash construction with
|
|
114
|
+
* NO prefix filter, so they will happily hash a foreign payload's fields
|
|
115
|
+
* under JazzCash rules. For a flow the corpus knows that is the gateway's own
|
|
116
|
+
* construction and the reproduction stands. For a payload arriving without
|
|
117
|
+
* one it is this server's guess, and a guess cannot demonstrate what a
|
|
118
|
+
* merchant's code did.
|
|
119
|
+
*
|
|
120
|
+
* Named for the decision rather than folded into the options, because the
|
|
121
|
+
* options are also passed to `computeSecureHash`, where the same assumption is
|
|
122
|
+
* survivable: an unverified response is reported as unverified (assumption A2),
|
|
123
|
+
* while an unfounded `confirmed` sends a merchant to break working code.
|
|
124
|
+
*/
|
|
125
|
+
export function forensicProvenance(flow, direction) {
|
|
126
|
+
if (direction === 'request') {
|
|
127
|
+
return 'declared';
|
|
128
|
+
}
|
|
129
|
+
// With a flow, the response construction above IS that flow's own. Without
|
|
130
|
+
// one, it is this server's assumption and may not be reported as proof.
|
|
131
|
+
return flow === undefined ? 'assumed' : 'declared';
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The parameter a flow writes its request signature into.
|
|
135
|
+
*
|
|
136
|
+
* Read from the flow rather than spelled `pp_SecureHash` at the call site: that
|
|
137
|
+
* is JazzCash's name for it, and a payload built for a gateway that spells it
|
|
138
|
+
* otherwise carries a correct digest in a field that gateway never reads — a
|
|
139
|
+
* rejected transaction with nothing in the response to explain it. The flow already
|
|
140
|
+
* carries the answer as the parameter whose `valueType` is `secure-hash`, and
|
|
141
|
+
* `tests/catalogue/flows.test.ts` asserts every flow declares exactly one, so
|
|
142
|
+
* no new schema field is needed to derive it.
|
|
143
|
+
*
|
|
144
|
+
* Returns `undefined` for a flow that declares none, because a flow that does
|
|
145
|
+
* not sign has no field to name and inventing one would be the same defect
|
|
146
|
+
* pointed the other way.
|
|
147
|
+
*/
|
|
148
|
+
export function signatureFieldName(flow) {
|
|
149
|
+
return flow.parameters.find((parameter) => parameter.valueType === 'secure-hash')?.name;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=hash-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash-options.js","sourceRoot":"","sources":["../../src/catalogue/hash-options.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,4EAA4E;AAC5E,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAEvB,0EAA0E;IAC1E,kEAAkE;IAClE,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QACvB,KAAK,aAAa;YAChB,OAAO;gBACL,MAAM,EAAE,UAAU;gBAClB,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;gBAC/C,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,UAAU,EAAE,IAAI,CAAC,UAAU;aAC5B,CAAC;IACN,CAAC;IAED,6EAA6E;IAC7E,+EAA+E;IAC/E,0EAA0E;IAC1E,kEAAkE;IAClE,gHAAgH;IAChH,MAAM,WAAW,GAAU,IAAI,CAAC,SAAS,CAAC;IAC1C,OAAO,WAAW,CAAC;IACnB,oBAAoB;AACtB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAqB;IACvD,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;IAE9C,OAAO;QACL,MAAM,EAAE,UAAU;QAClB,oBAAoB,EAAE,IAAI,CAAC,QAAQ,CAAC,iBAAiB;QACrD,aAAa,EAAE,CAAC,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,EAAE,eAAe,EAAE,YAAY,CAAC;KACxG,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAqB;IAClE,MAAM,EAAE,UAAU;IAClB,oBAAoB,EAAE,EAAE;IACxB,aAAa,EAAE,CAAC,eAAe,EAAE,YAAY,CAAC;CAC/C,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAiC,EACjC,SAAiC;IAEjC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,2EAA2E;IAC3E,wEAAwE;IACxE,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAqB;IACtD,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,SAAS,KAAK,aAAa,CAAC,EAAE,IAAI,CAAC;AAC1F,CAAC"}
|