@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.
Files changed (366) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -0
  3. package/dist/builder/transaction-builder.d.ts +53 -0
  4. package/dist/builder/transaction-builder.d.ts.map +1 -0
  5. package/dist/builder/transaction-builder.js +159 -0
  6. package/dist/builder/transaction-builder.js.map +1 -0
  7. package/dist/catalogue/default-catalogue.d.ts +18 -0
  8. package/dist/catalogue/default-catalogue.d.ts.map +1 -0
  9. package/dist/catalogue/default-catalogue.js +21 -0
  10. package/dist/catalogue/default-catalogue.js.map +1 -0
  11. package/dist/catalogue/endpoints.d.ts +22 -0
  12. package/dist/catalogue/endpoints.d.ts.map +1 -0
  13. package/dist/catalogue/endpoints.js +24 -0
  14. package/dist/catalogue/endpoints.js.map +1 -0
  15. package/dist/catalogue/flows.d.ts +32 -0
  16. package/dist/catalogue/flows.d.ts.map +1 -0
  17. package/dist/catalogue/flows.js +64 -0
  18. package/dist/catalogue/flows.js.map +1 -0
  19. package/dist/catalogue/hash-options.d.ts +112 -0
  20. package/dist/catalogue/hash-options.d.ts.map +1 -0
  21. package/dist/catalogue/hash-options.js +151 -0
  22. package/dist/catalogue/hash-options.js.map +1 -0
  23. package/dist/catalogue/types.d.ts +279 -0
  24. package/dist/catalogue/types.d.ts.map +1 -0
  25. package/dist/catalogue/types.js +360 -0
  26. package/dist/catalogue/types.js.map +1 -0
  27. package/dist/codegen/generate.d.ts +14 -0
  28. package/dist/codegen/generate.d.ts.map +1 -0
  29. package/dist/codegen/generate.js +490 -0
  30. package/dist/codegen/generate.js.map +1 -0
  31. package/dist/codegen/languages/node.d.ts +3 -0
  32. package/dist/codegen/languages/node.d.ts.map +1 -0
  33. package/dist/codegen/languages/node.js +32 -0
  34. package/dist/codegen/languages/node.js.map +1 -0
  35. package/dist/codegen/languages/php.d.ts +3 -0
  36. package/dist/codegen/languages/php.d.ts.map +1 -0
  37. package/dist/codegen/languages/php.js +27 -0
  38. package/dist/codegen/languages/php.js.map +1 -0
  39. package/dist/codegen/languages/python.d.ts +3 -0
  40. package/dist/codegen/languages/python.d.ts.map +1 -0
  41. package/dist/codegen/languages/python.js +27 -0
  42. package/dist/codegen/languages/python.js.map +1 -0
  43. package/dist/codegen/renderer.d.ts +24 -0
  44. package/dist/codegen/renderer.d.ts.map +1 -0
  45. package/dist/codegen/renderer.js +59 -0
  46. package/dist/codegen/renderer.js.map +1 -0
  47. package/dist/codegen/types.d.ts +50 -0
  48. package/dist/codegen/types.d.ts.map +1 -0
  49. package/dist/codegen/types.js +5 -0
  50. package/dist/codegen/types.js.map +1 -0
  51. package/dist/config/credentials.d.ts +64 -0
  52. package/dist/config/credentials.d.ts.map +1 -0
  53. package/dist/config/credentials.js +216 -0
  54. package/dist/config/credentials.js.map +1 -0
  55. package/dist/config/environment.d.ts +23 -0
  56. package/dist/config/environment.d.ts.map +1 -0
  57. package/dist/config/environment.js +54 -0
  58. package/dist/config/environment.js.map +1 -0
  59. package/dist/core/dependencies.d.ts +43 -0
  60. package/dist/core/dependencies.d.ts.map +1 -0
  61. package/dist/core/dependencies.js +2 -0
  62. package/dist/core/dependencies.js.map +1 -0
  63. package/dist/core/registry.d.ts +33 -0
  64. package/dist/core/registry.d.ts.map +1 -0
  65. package/dist/core/registry.js +13 -0
  66. package/dist/core/registry.js.map +1 -0
  67. package/dist/core/server.d.ts +61 -0
  68. package/dist/core/server.d.ts.map +1 -0
  69. package/dist/core/server.js +90 -0
  70. package/dist/core/server.js.map +1 -0
  71. package/dist/dependencies.d.ts +28 -0
  72. package/dist/dependencies.d.ts.map +1 -0
  73. package/dist/dependencies.js +2 -0
  74. package/dist/dependencies.js.map +1 -0
  75. package/dist/diagnostics/diagnose.d.ts +43 -0
  76. package/dist/diagnostics/diagnose.d.ts.map +1 -0
  77. package/dist/diagnostics/diagnose.js +121 -0
  78. package/dist/diagnostics/diagnose.js.map +1 -0
  79. package/dist/domain/amount.d.ts +157 -0
  80. package/dist/domain/amount.d.ts.map +1 -0
  81. package/dist/domain/amount.js +275 -0
  82. package/dist/domain/amount.js.map +1 -0
  83. package/dist/domain/datetime.d.ts +95 -0
  84. package/dist/domain/datetime.d.ts.map +1 -0
  85. package/dist/domain/datetime.js +211 -0
  86. package/dist/domain/datetime.js.map +1 -0
  87. package/dist/domain/response-codes.d.ts +116 -0
  88. package/dist/domain/response-codes.d.ts.map +1 -0
  89. package/dist/domain/response-codes.js +380 -0
  90. package/dist/domain/response-codes.js.map +1 -0
  91. package/dist/domain/secure-hash.d.ts +78 -0
  92. package/dist/domain/secure-hash.d.ts.map +1 -0
  93. package/dist/domain/secure-hash.js +69 -0
  94. package/dist/domain/secure-hash.js.map +1 -0
  95. package/dist/domain/signature/jazzcash.d.ts +56 -0
  96. package/dist/domain/signature/jazzcash.d.ts.map +1 -0
  97. package/dist/domain/signature/jazzcash.js +214 -0
  98. package/dist/domain/signature/jazzcash.js.map +1 -0
  99. package/dist/domain/signature/registry.d.ts +69 -0
  100. package/dist/domain/signature/registry.d.ts.map +1 -0
  101. package/dist/domain/signature/registry.js +92 -0
  102. package/dist/domain/signature/registry.js.map +1 -0
  103. package/dist/domain/signature/scheme.d.ts +349 -0
  104. package/dist/domain/signature/scheme.d.ts.map +1 -0
  105. package/dist/domain/signature/scheme.js +398 -0
  106. package/dist/domain/signature/scheme.js.map +1 -0
  107. package/dist/domain/txn-ref.d.ts +76 -0
  108. package/dist/domain/txn-ref.d.ts.map +1 -0
  109. package/dist/domain/txn-ref.js +126 -0
  110. package/dist/domain/txn-ref.js.map +1 -0
  111. package/dist/domain/types.d.ts +45 -0
  112. package/dist/domain/types.d.ts.map +1 -0
  113. package/dist/domain/types.js +70 -0
  114. package/dist/domain/types.js.map +1 -0
  115. package/dist/errors.d.ts +84 -0
  116. package/dist/errors.d.ts.map +1 -0
  117. package/dist/errors.js +87 -0
  118. package/dist/errors.js.map +1 -0
  119. package/dist/gateway/checkout-form.d.ts +16 -0
  120. package/dist/gateway/checkout-form.d.ts.map +1 -0
  121. package/dist/gateway/checkout-form.js +103 -0
  122. package/dist/gateway/checkout-form.js.map +1 -0
  123. package/dist/gateway/checkout-output.d.ts +70 -0
  124. package/dist/gateway/checkout-output.d.ts.map +1 -0
  125. package/dist/gateway/checkout-output.js +199 -0
  126. package/dist/gateway/checkout-output.js.map +1 -0
  127. package/dist/gateway/guards.d.ts +37 -0
  128. package/dist/gateway/guards.d.ts.map +1 -0
  129. package/dist/gateway/guards.js +44 -0
  130. package/dist/gateway/guards.js.map +1 -0
  131. package/dist/gateway/http-client.d.ts +42 -0
  132. package/dist/gateway/http-client.d.ts.map +1 -0
  133. package/dist/gateway/http-client.js +153 -0
  134. package/dist/gateway/http-client.js.map +1 -0
  135. package/dist/gateway/rest-client.d.ts +42 -0
  136. package/dist/gateway/rest-client.d.ts.map +1 -0
  137. package/dist/gateway/rest-client.js +241 -0
  138. package/dist/gateway/rest-client.js.map +1 -0
  139. package/dist/gateway/transport.d.ts +31 -0
  140. package/dist/gateway/transport.d.ts.map +1 -0
  141. package/dist/gateway/transport.js +73 -0
  142. package/dist/gateway/transport.js.map +1 -0
  143. package/dist/index.d.ts +3 -0
  144. package/dist/index.d.ts.map +1 -0
  145. package/dist/index.js +75 -0
  146. package/dist/index.js.map +1 -0
  147. package/dist/install/cli.d.ts +38 -0
  148. package/dist/install/cli.d.ts.map +1 -0
  149. package/dist/install/cli.js +274 -0
  150. package/dist/install/cli.js.map +1 -0
  151. package/dist/install/harnesses.d.ts +74 -0
  152. package/dist/install/harnesses.d.ts.map +1 -0
  153. package/dist/install/harnesses.js +263 -0
  154. package/dist/install/harnesses.js.map +1 -0
  155. package/dist/knowledge/corpus.d.ts +15 -0
  156. package/dist/knowledge/corpus.d.ts.map +1 -0
  157. package/dist/knowledge/corpus.js +129 -0
  158. package/dist/knowledge/corpus.js.map +1 -0
  159. package/dist/knowledge/search.d.ts +29 -0
  160. package/dist/knowledge/search.d.ts.map +1 -0
  161. package/dist/knowledge/search.js +181 -0
  162. package/dist/knowledge/search.js.map +1 -0
  163. package/dist/knowledge/source.d.ts +60 -0
  164. package/dist/knowledge/source.d.ts.map +1 -0
  165. package/dist/knowledge/source.js +91 -0
  166. package/dist/knowledge/source.js.map +1 -0
  167. package/dist/knowledge/types.d.ts +40 -0
  168. package/dist/knowledge/types.d.ts.map +1 -0
  169. package/dist/knowledge/types.js +19 -0
  170. package/dist/knowledge/types.js.map +1 -0
  171. package/dist/paths.d.ts +26 -0
  172. package/dist/paths.d.ts.map +1 -0
  173. package/dist/paths.js +106 -0
  174. package/dist/paths.js.map +1 -0
  175. package/dist/prompts/integration-walkthrough.d.ts +11 -0
  176. package/dist/prompts/integration-walkthrough.d.ts.map +1 -0
  177. package/dist/prompts/integration-walkthrough.js +52 -0
  178. package/dist/prompts/integration-walkthrough.js.map +1 -0
  179. package/dist/prompts/register.d.ts +4 -0
  180. package/dist/prompts/register.d.ts.map +1 -0
  181. package/dist/prompts/register.js +4 -0
  182. package/dist/prompts/register.js.map +1 -0
  183. package/dist/registry.d.ts +14 -0
  184. package/dist/registry.d.ts.map +1 -0
  185. package/dist/registry.js +2 -0
  186. package/dist/registry.js.map +1 -0
  187. package/dist/resources/knowledge-resources.d.ts +5 -0
  188. package/dist/resources/knowledge-resources.d.ts.map +1 -0
  189. package/dist/resources/knowledge-resources.js +121 -0
  190. package/dist/resources/knowledge-resources.js.map +1 -0
  191. package/dist/resources/register.d.ts +4 -0
  192. package/dist/resources/register.d.ts.map +1 -0
  193. package/dist/resources/register.js +8 -0
  194. package/dist/resources/register.js.map +1 -0
  195. package/dist/server.d.ts +40 -0
  196. package/dist/server.d.ts.map +1 -0
  197. package/dist/server.js +56 -0
  198. package/dist/server.js.map +1 -0
  199. package/dist/telemetry/logger.d.ts +31 -0
  200. package/dist/telemetry/logger.d.ts.map +1 -0
  201. package/dist/telemetry/logger.js +67 -0
  202. package/dist/telemetry/logger.js.map +1 -0
  203. package/dist/telemetry/redaction.d.ts +88 -0
  204. package/dist/telemetry/redaction.d.ts.map +1 -0
  205. package/dist/telemetry/redaction.js +238 -0
  206. package/dist/telemetry/redaction.js.map +1 -0
  207. package/dist/tools/build-transaction-parameters.d.ts +10 -0
  208. package/dist/tools/build-transaction-parameters.d.ts.map +1 -0
  209. package/dist/tools/build-transaction-parameters.js +154 -0
  210. package/dist/tools/build-transaction-parameters.js.map +1 -0
  211. package/dist/tools/call-context.d.ts +47 -0
  212. package/dist/tools/call-context.d.ts.map +1 -0
  213. package/dist/tools/call-context.js +15 -0
  214. package/dist/tools/call-context.js.map +1 -0
  215. package/dist/tools/codegen-tools.d.ts +4 -0
  216. package/dist/tools/codegen-tools.d.ts.map +1 -0
  217. package/dist/tools/codegen-tools.js +131 -0
  218. package/dist/tools/codegen-tools.js.map +1 -0
  219. package/dist/tools/credential-tools.d.ts +32 -0
  220. package/dist/tools/credential-tools.d.ts.map +1 -0
  221. package/dist/tools/credential-tools.js +65 -0
  222. package/dist/tools/credential-tools.js.map +1 -0
  223. package/dist/tools/descriptor.d.ts +52 -0
  224. package/dist/tools/descriptor.d.ts.map +1 -0
  225. package/dist/tools/descriptor.js +2 -0
  226. package/dist/tools/descriptor.js.map +1 -0
  227. package/dist/tools/diagnostic-tools.d.ts +3 -0
  228. package/dist/tools/diagnostic-tools.d.ts.map +1 -0
  229. package/dist/tools/diagnostic-tools.js +128 -0
  230. package/dist/tools/diagnostic-tools.js.map +1 -0
  231. package/dist/tools/gateway-tools.d.ts +6 -0
  232. package/dist/tools/gateway-tools.d.ts.map +1 -0
  233. package/dist/tools/gateway-tools.js +381 -0
  234. package/dist/tools/gateway-tools.js.map +1 -0
  235. package/dist/tools/hash-tools.d.ts +5 -0
  236. package/dist/tools/hash-tools.d.ts.map +1 -0
  237. package/dist/tools/hash-tools.js +238 -0
  238. package/dist/tools/hash-tools.js.map +1 -0
  239. package/dist/tools/knowledge-tools.d.ts +7 -0
  240. package/dist/tools/knowledge-tools.d.ts.map +1 -0
  241. package/dist/tools/knowledge-tools.js +247 -0
  242. package/dist/tools/knowledge-tools.js.map +1 -0
  243. package/dist/tools/onboarding-checklist.d.ts +3 -0
  244. package/dist/tools/onboarding-checklist.d.ts.map +1 -0
  245. package/dist/tools/onboarding-checklist.js +141 -0
  246. package/dist/tools/onboarding-checklist.js.map +1 -0
  247. package/dist/tools/register.d.ts +60 -0
  248. package/dist/tools/register.d.ts.map +1 -0
  249. package/dist/tools/register.js +145 -0
  250. package/dist/tools/register.js.map +1 -0
  251. package/dist/tools/tool-kit.d.ts +88 -0
  252. package/dist/tools/tool-kit.d.ts.map +1 -0
  253. package/dist/tools/tool-kit.js +297 -0
  254. package/dist/tools/tool-kit.js.map +1 -0
  255. package/dist/validation/payload-validator.d.ts +29 -0
  256. package/dist/validation/payload-validator.d.ts.map +1 -0
  257. package/dist/validation/payload-validator.js +79 -0
  258. package/dist/validation/payload-validator.js.map +1 -0
  259. package/dist/validation/rules/amount.d.ts +3 -0
  260. package/dist/validation/rules/amount.d.ts.map +1 -0
  261. package/dist/validation/rules/amount.js +77 -0
  262. package/dist/validation/rules/amount.js.map +1 -0
  263. package/dist/validation/rules/bill-reference.d.ts +10 -0
  264. package/dist/validation/rules/bill-reference.d.ts.map +1 -0
  265. package/dist/validation/rules/bill-reference.js +34 -0
  266. package/dist/validation/rules/bill-reference.js.map +1 -0
  267. package/dist/validation/rules/cnic.d.ts +3 -0
  268. package/dist/validation/rules/cnic.d.ts.map +1 -0
  269. package/dist/validation/rules/cnic.js +42 -0
  270. package/dist/validation/rules/cnic.js.map +1 -0
  271. package/dist/validation/rules/constants.d.ts +9 -0
  272. package/dist/validation/rules/constants.d.ts.map +1 -0
  273. package/dist/validation/rules/constants.js +28 -0
  274. package/dist/validation/rules/constants.js.map +1 -0
  275. package/dist/validation/rules/constraints.d.ts +3 -0
  276. package/dist/validation/rules/constraints.d.ts.map +1 -0
  277. package/dist/validation/rules/constraints.js +113 -0
  278. package/dist/validation/rules/constraints.js.map +1 -0
  279. package/dist/validation/rules/datetime.d.ts +3 -0
  280. package/dist/validation/rules/datetime.d.ts.map +1 -0
  281. package/dist/validation/rules/datetime.js +49 -0
  282. package/dist/validation/rules/datetime.js.map +1 -0
  283. package/dist/validation/rules/empty-string.d.ts +13 -0
  284. package/dist/validation/rules/empty-string.d.ts.map +1 -0
  285. package/dist/validation/rules/empty-string.js +32 -0
  286. package/dist/validation/rules/empty-string.js.map +1 -0
  287. package/dist/validation/rules/expiry.d.ts +3 -0
  288. package/dist/validation/rules/expiry.d.ts.map +1 -0
  289. package/dist/validation/rules/expiry.js +52 -0
  290. package/dist/validation/rules/expiry.js.map +1 -0
  291. package/dist/validation/rules/msisdn.d.ts +3 -0
  292. package/dist/validation/rules/msisdn.d.ts.map +1 -0
  293. package/dist/validation/rules/msisdn.js +45 -0
  294. package/dist/validation/rules/msisdn.js.map +1 -0
  295. package/dist/validation/rules/presence.d.ts +3 -0
  296. package/dist/validation/rules/presence.d.ts.map +1 -0
  297. package/dist/validation/rules/presence.js +90 -0
  298. package/dist/validation/rules/presence.js.map +1 -0
  299. package/dist/validation/rules/return-url.d.ts +14 -0
  300. package/dist/validation/rules/return-url.d.ts.map +1 -0
  301. package/dist/validation/rules/return-url.js +58 -0
  302. package/dist/validation/rules/return-url.js.map +1 -0
  303. package/dist/validation/rules/tool-argument.d.ts +16 -0
  304. package/dist/validation/rules/tool-argument.d.ts.map +1 -0
  305. package/dist/validation/rules/tool-argument.js +38 -0
  306. package/dist/validation/rules/tool-argument.js.map +1 -0
  307. package/dist/validation/rules/txn-ref.d.ts +3 -0
  308. package/dist/validation/rules/txn-ref.d.ts.map +1 -0
  309. package/dist/validation/rules/txn-ref.js +47 -0
  310. package/dist/validation/rules/txn-ref.js.map +1 -0
  311. package/dist/validation/rules/unknown-fields.d.ts +10 -0
  312. package/dist/validation/rules/unknown-fields.d.ts.map +1 -0
  313. package/dist/validation/rules/unknown-fields.js +29 -0
  314. package/dist/validation/rules/unknown-fields.js.map +1 -0
  315. package/dist/validation/types.d.ts +36 -0
  316. package/dist/validation/types.d.ts.map +1 -0
  317. package/dist/validation/types.js +12 -0
  318. package/dist/validation/types.js.map +1 -0
  319. package/dist/version.d.ts +23 -0
  320. package/dist/version.d.ts.map +1 -0
  321. package/dist/version.js +23 -0
  322. package/dist/version.js.map +1 -0
  323. package/knowledge/diagnostics/symptoms.json +321 -0
  324. package/knowledge/docs/bnpl-guide.md +77 -0
  325. package/knowledge/docs/card-page-redirection.md +67 -0
  326. package/knowledge/docs/card-refund.md +91 -0
  327. package/knowledge/docs/hmac-sha256-calculation.md +72 -0
  328. package/knowledge/docs/index.json +189 -0
  329. package/knowledge/docs/ipn-implementation.md +89 -0
  330. package/knowledge/docs/mwallet-recurring.md +117 -0
  331. package/knowledge/docs/mwallet-refund.md +65 -0
  332. package/knowledge/docs/mwallet-rest-v1-1.md +126 -0
  333. package/knowledge/docs/mwallet-rest-v2-0-cnic.md +113 -0
  334. package/knowledge/docs/portal-guide.md +45 -0
  335. package/knowledge/docs/shopify-guide.md +74 -0
  336. package/knowledge/docs/status-inquiry-2025-26.md +32 -0
  337. package/knowledge/docs/status-inquiry.md +111 -0
  338. package/knowledge/docs/wordpress-guide.md +49 -0
  339. package/knowledge/flow.schema.json +390 -0
  340. package/knowledge/flows/bnpl-page-redirection-v1.1.json +211 -0
  341. package/knowledge/flows/card-page-redirection-v1.1.json +211 -0
  342. package/knowledge/flows/mwallet-rest-v1.1.json +187 -0
  343. package/knowledge/flows/mwallet-rest-v2.0-cnic.json +197 -0
  344. package/knowledge/flows/mwallet-token-pay-v4.0.json +130 -0
  345. package/knowledge/flows/refund-bnpl.json +105 -0
  346. package/knowledge/flows/refund-card-v1.1.json +112 -0
  347. package/knowledge/flows/refund-card-v2.0.json +121 -0
  348. package/knowledge/flows/refund-mwallet-v1.1.json +106 -0
  349. package/knowledge/flows/status-inquiry-v1.1.json +102 -0
  350. package/knowledge/flows/status-inquiry-v2.0.json +103 -0
  351. package/knowledge/flows/token-delete-v1.json +85 -0
  352. package/knowledge/flows/token-inquiry-v1.json +85 -0
  353. package/knowledge/flows/wallet-linking-portal.json +103 -0
  354. package/knowledge/templates/node/checkout-redirect.tmpl +166 -0
  355. package/knowledge/templates/node/ipn-handler.tmpl +108 -0
  356. package/knowledge/templates/node/rest-client.tmpl +197 -0
  357. package/knowledge/templates/node/wallet-linking.tmpl +147 -0
  358. package/knowledge/templates/php/checkout-redirect.tmpl +149 -0
  359. package/knowledge/templates/php/ipn-handler.tmpl +105 -0
  360. package/knowledge/templates/php/rest-client.tmpl +191 -0
  361. package/knowledge/templates/php/wallet-linking.tmpl +137 -0
  362. package/knowledge/templates/python/checkout-redirect.tmpl +148 -0
  363. package/knowledge/templates/python/ipn-handler.tmpl +110 -0
  364. package/knowledge/templates/python/rest-client.tmpl +179 -0
  365. package/knowledge/templates/python/wallet-linking.tmpl +133 -0
  366. 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"}