@webpieces/http-client-node 0.4.795 → 0.4.797
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/README.md
CHANGED
|
@@ -72,7 +72,7 @@ It is not a different kind of client. It is ONE filter:
|
|
|
72
72
|
/** @externalSystem runtime partner-webhooks */
|
|
73
73
|
@ApiPath('/ot-webhook')
|
|
74
74
|
export class PartnerWebhookApi {
|
|
75
|
-
@Endpoint('/deliver')
|
|
75
|
+
@Endpoint(POST, '/deliver', WRITE, RPC)
|
|
76
76
|
@WpAuthWebhook('partner-hmac')
|
|
77
77
|
deliver(envelope: WebhookEnvelope): Promise<DeliveryAck>;
|
|
78
78
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpieces/http-client-node",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.797",
|
|
4
4
|
"description": "Server-side HTTP client for webpieces: inversify-wired, reads RequestContext directly, mints OIDC/shared-secret delivery auth, resolves Cloud Run URLs from a service name",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@webpieces/core-context": "0.4.
|
|
26
|
-
"@webpieces/core-util": "0.4.
|
|
27
|
-
"@webpieces/gcp-identity": "0.4.
|
|
28
|
-
"@webpieces/http-client-core": "0.4.
|
|
25
|
+
"@webpieces/core-context": "0.4.797",
|
|
26
|
+
"@webpieces/core-util": "0.4.797",
|
|
27
|
+
"@webpieces/gcp-identity": "0.4.797",
|
|
28
|
+
"@webpieces/http-client-core": "0.4.797",
|
|
29
29
|
"inversify": "7.10.4",
|
|
30
30
|
"reflect-metadata": "0.2.2"
|
|
31
31
|
}
|
|
@@ -21,7 +21,7 @@ import { SsrfPolicy } from './SsrfPolicy';
|
|
|
21
21
|
* }
|
|
22
22
|
* ```
|
|
23
23
|
*
|
|
24
|
-
* The contract can therefore declare an honest path (`@ApiPath('/webhook')` + `@Endpoint('/deliver')`)
|
|
24
|
+
* The contract can therefore declare an honest path (`@ApiPath('/webhook')` + `@Endpoint(POST, '/deliver', ...)`)
|
|
25
25
|
* for documentation and the architecture graph, knowing it is replaced per call.
|
|
26
26
|
*
|
|
27
27
|
* ## Why a SEPARATE filter from ContextBaseUrlFilter
|
|
@@ -25,7 +25,7 @@ const SsrfPolicy_1 = require("./SsrfPolicy");
|
|
|
25
25
|
* }
|
|
26
26
|
* ```
|
|
27
27
|
*
|
|
28
|
-
* The contract can therefore declare an honest path (`@ApiPath('/webhook')` + `@Endpoint('/deliver')`)
|
|
28
|
+
* The contract can therefore declare an honest path (`@ApiPath('/webhook')` + `@Endpoint(POST, '/deliver', ...)`)
|
|
29
29
|
* for documentation and the architecture graph, knowing it is replaced per call.
|
|
30
30
|
*
|
|
31
31
|
* ## Why a SEPARATE filter from ContextBaseUrlFilter
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextFullUrlFilter.js","sourceRoot":"","sources":["../../../../../packages/http/http-client-node/src/ContextFullUrlFilter.ts"],"names":[],"mappings":";;;AAAA,oDAA6E;AAC7E,0DAAyD;AAEzD,6EAA0E;AAC1E,6CAA0C;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAa,oBAAqB,SAAQ,kBAA+B;IAOxD;IANb;IACI;;;;OAIG;IACM,aAAyB,IAAI,uBAAU,EAAE;QAElD,KAAK,EAAE,CAAC;QAFC,eAAU,GAAV,UAAU,CAA+B;IAGtD,CAAC;IAEQ,KAAK,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"ContextFullUrlFilter.js","sourceRoot":"","sources":["../../../../../packages/http/http-client-node/src/ContextFullUrlFilter.ts"],"names":[],"mappings":";;;AAAA,oDAA6E;AAC7E,0DAAyD;AAEzD,6EAA0E;AAC1E,6CAA0C;AAE1C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAa,oBAAqB,SAAQ,kBAA+B;IAOxD;IANb;IACI;;;;OAIG;IACM,aAAyB,IAAI,uBAAU,EAAE;QAElD,KAAK,EAAE,CAAC;QAFC,eAAU,GAAV,UAAU,CAA+B;IAGtD,CAAC;IAEQ,KAAK,CAAC,MAAM,CACjB,OAAsB,EACtB,UAA4C;QAE5C,MAAM,QAAQ,GAAG,6BAAc,CAAC,YAAY,CAAC,gCAAoB,CAAC,iBAAiB,CAAC,CAAC;QACrF,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,EAAE,CAAC;YAC5C,MAAM,IAAI,uDAA0B,CAChC,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,0CAA0C;gBACzF,iEAAiE;gBACjE,wFAAwF;gBACxF,aAAa;gBACb,yFAAyF;gBACzF,+EAA+E;gBAC/E,0FAA0F,EAC9F,GAAG,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CACxD,CAAC;QACN,CAAC;QACD,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QACjC,OAAO,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;CACJ;AAhCD,oDAgCC","sourcesContent":["import { Filter, Service, WebpiecesCoreHeaders } from '@webpieces/core-util';\nimport { RequestContext } from '@webpieces/core-context';\nimport { ClientRequest } from '@webpieces/http-client-core';\nimport { MissingRuntimeBaseUrlError } from './MissingRuntimeBaseUrlError';\nimport { SsrfPolicy } from './SsrfPolicy';\n\n/**\n * Reads {@link WebpiecesCoreHeaders.OVERRIDE_FULL_URL} out of the ambient RequestContext and sends\n * THIS ONE CALL to that url, VERBATIM — host, path and query exactly as stored, with the contract's\n * own path NOT appended. This is the filter for the common partner-webhook shape, where the partner\n * gave us one opaque url (a database row) rather than implementing our contract at their host:\n *\n * ```ts\n * const partner = factory.createRpcClient(PartnerWebhookApi, new ClientConfig('partner-webhooks'), [\n * new ClientFilterDefinition(1000, new ContextFullUrlFilter()),\n * ]);\n *\n * for (const webhook of webhooks) {\n * await RequestContext.run(() => {\n * // e.g. 'https://hooks.partner.example/in/abc?token=xyz' — sent byte for byte\n * RequestContext.putUntrusted(WebpiecesCoreHeaders.OVERRIDE_FULL_URL, webhook.url);\n * return partner.deliver(envelope);\n * });\n * }\n * ```\n *\n * The contract can therefore declare an honest path (`@ApiPath('/webhook')` + `@Endpoint(POST, '/deliver', ...)`)\n * for documentation and the architecture graph, knowing it is replaced per call.\n *\n * ## Why a SEPARATE filter from ContextBaseUrlFilter\n *\n * The two answer different questions. `ContextBaseUrlFilter` swaps the HOST and keeps this route's\n * path (a tenant running our contract at their own server); this one swaps the WHOLE url. A flag on\n * one filter would be two behaviours behind one name, and `grep -rn ContextFullUrlFilter` would no\n * longer list exactly the clients whose destination is a stored url.\n *\n * ## Everything else is ContextBaseUrlFilter's contract, unchanged\n *\n * - **Installing it is the opt-in.** A client without it ignores an ambient `OVERRIDE_FULL_URL`.\n * - **It refuses rather than falls back.** No override in scope throws\n * {@link MissingRuntimeBaseUrlError}; it never sends to the client's configured service URL,\n * which would deliver a partner's payload to one of our own services.\n * - **It cannot leak.** Only the per-call {@link ClientRequest} is mutated.\n * - **The SSRF guard is armed by the act of re-pointing.** `ClientRequest.pointAtFullUrl` flips\n * `destinationCameFromData`; this class carries only WHICH policy applies, so the one relaxation\n * (`SsrfTestingPolicy`) is named at the same construction site as the decision to be re-pointable.\n */\nexport class ContextFullUrlFilter extends Filter<ClientRequest, Response> {\n constructor(\n /**\n * What the framework's SSRF guard holds this client's re-pointed URLs to. Defaulted to the\n * strict {@link SsrfPolicy}, so the omitted argument is never the permissive one — widening\n * has to be typed out as `new ContextFullUrlFilter(new SsrfTestingPolicy('<why>'))`.\n */\n readonly ssrfPolicy: SsrfPolicy = new SsrfPolicy(),\n ) {\n super();\n }\n\n override async filter(\n request: ClientRequest,\n nextFilter: Service<ClientRequest, Response>,\n ): Promise<Response> {\n const override = RequestContext.getUntrusted(WebpiecesCoreHeaders.OVERRIDE_FULL_URL);\n if (override === undefined || override === '') {\n throw new MissingRuntimeBaseUrlError(\n `${request.contractName}.${request.route.methodName} runs behind a ContextFullUrlFilter, so ` +\n `its complete destination url must be supplied per call, but no ` +\n `WebpiecesCoreHeaders.OVERRIDE_FULL_URL was found in the RequestContext. Set it around ` +\n `the call:\\n` +\n ` RequestContext.putUntrusted(WebpiecesCoreHeaders.OVERRIDE_FULL_URL, webhook.url);\\n` +\n `Refusing rather than falling back to this client's configured service URL is ` +\n `deliberate: a silent fallback would send a partner's payload to one of our own services.`,\n `${request.contractName}.${request.route.methodName}`,\n );\n }\n request.pointAtFullUrl(override);\n return nextFilter.invoke(request);\n }\n}\n"]}
|