@things-factory/webhook 10.1.38 → 10.1.39
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/dist-server/service/index.d.ts +4 -2
- package/dist-server/service/index.js +8 -1
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/outbox/pump-loop.d.ts +38 -0
- package/dist-server/service/outbox/pump-loop.js +93 -0
- package/dist-server/service/outbox/pump-loop.js.map +1 -0
- package/dist-server/service/outbox/pump.d.ts +75 -0
- package/dist-server/service/outbox/pump.js +87 -0
- package/dist-server/service/outbox/pump.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
- package/dist-server/service/outbox/pump-gate.d.ts +0 -74
- package/dist-server/service/outbox/pump-gate.js +0 -90
- package/dist-server/service/outbox/pump-gate.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@things-factory/webhook",
|
|
3
|
-
"version": "10.1.
|
|
3
|
+
"version": "10.1.39",
|
|
4
4
|
"main": "dist-server/index.js",
|
|
5
5
|
"browser": "dist-client/index.js",
|
|
6
6
|
"things-factory": true,
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@operato/graphql": "^10.0.0",
|
|
31
31
|
"@operato/i18n": "^10.0.0",
|
|
32
|
-
"@operato/ops-contract": "^0.9.
|
|
33
|
-
"@things-factory/auth-base": "^10.1.
|
|
32
|
+
"@operato/ops-contract": "^0.9.35",
|
|
33
|
+
"@things-factory/auth-base": "^10.1.39",
|
|
34
34
|
"@things-factory/env": "^10.1.20",
|
|
35
|
-
"@things-factory/shell": "^10.1.
|
|
36
|
-
"@things-factory/task-lease": "^10.1.
|
|
35
|
+
"@things-factory/shell": "^10.1.39",
|
|
36
|
+
"@things-factory/task-lease": "^10.1.39"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "fe5257ad8995fe7e79275e287f36e95b5fd32d1c"
|
|
39
39
|
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* **Can this installation send at all** — a pure judgement, no imports, no environment read here.
|
|
3
|
-
*
|
|
4
|
-
* ═════════════════════════════════════════════════════════════════════════
|
|
5
|
-
* ## What used to guard this door, and why it moved
|
|
6
|
-
*
|
|
7
|
-
* The pump used to stand only if a destination was named in the configuration file. Destinations then
|
|
8
|
-
* moved to a table an administrator edits, and the door stayed where it was: a site could name its
|
|
9
|
-
* destination on the screen and **the pump still would not stand**. Rows piled up with nobody sending
|
|
10
|
-
* them, and nothing failed, so nobody knew.
|
|
11
|
-
*
|
|
12
|
-
* ## So the key is what declares a sender
|
|
13
|
-
*
|
|
14
|
-
* Destinations live in a table now, and the pump reads that table every round - a boot-time reading
|
|
15
|
-
* would not see a destination added later. What is left is the signing key. An installation with no
|
|
16
|
-
* key cannot deliver one record even with a destination: unsigned, the receiver refuses it. So the
|
|
17
|
-
* key is the declaration that this installation sends.
|
|
18
|
-
*
|
|
19
|
-
* ## The names belong to the caller, the shape belongs here
|
|
20
|
-
*
|
|
21
|
-
* This module never reads `process.env`, and it has **no default names**: a product that forgets to
|
|
22
|
-
* name its variables would otherwise sign with somebody else's key and nothing would say so. What the
|
|
23
|
-
* module does own is how a domain becomes a variable suffix - if each product wrote that rule itself,
|
|
24
|
-
* the same domain would look for different variables depending on which product asked.
|
|
25
|
-
*
|
|
26
|
-
* ```
|
|
27
|
-
* <common> one key for the installation - a single-site install
|
|
28
|
-
* <common>__MIRATEK_GUNSAN one key per domain - what a multi-tenant install should use
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* A domain's name is not known at boot, so this counts by prefix. Which domain gave the key is
|
|
32
|
-
* settled on that domain's turn, and named there.
|
|
33
|
-
*
|
|
34
|
-
* ⚠ This door answers "can we sign", not "is there anything to send". An installation with a key and
|
|
35
|
-
* no destination row still stands the pump - and says, once per domain with facts waiting, that it
|
|
36
|
-
* has nowhere to send them. That is better than not standing and saying nothing.
|
|
37
|
-
* ═════════════════════════════════════════════════════════════════════════
|
|
38
|
-
*/
|
|
39
|
-
/**
|
|
40
|
-
* The two variable name stems a product declares. **Required** - see above on why there is no default.
|
|
41
|
-
*
|
|
42
|
-
* `domainPrefix` is the stem the per-domain names are built on; `domainSecretName` makes the whole
|
|
43
|
-
* name from it.
|
|
44
|
-
*/
|
|
45
|
-
export interface SecretNames {
|
|
46
|
-
common: string;
|
|
47
|
-
domainPrefix: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* The variable a domain's own key lives in.
|
|
51
|
-
*
|
|
52
|
-
* Anything that is not a letter or a digit becomes `_`, because that is what an environment variable
|
|
53
|
-
* name may hold. Written once, here: a product that rounded this differently would look for
|
|
54
|
-
* `MIRATEK_GUNSAN` while another looked for `MIRATEK-GUNSAN`, for the same domain.
|
|
55
|
-
*/
|
|
56
|
-
export declare function domainSecretName(prefix: string, subdomain: string): string;
|
|
57
|
-
/**
|
|
58
|
-
* Does this installation hold any key to sign with?
|
|
59
|
-
*
|
|
60
|
-
* The environment arrives as an argument. Reading the process here would put this judgement out of
|
|
61
|
-
* reach of a test, and this is the judgement that decides whether anything is delivered at all.
|
|
62
|
-
*/
|
|
63
|
-
export declare function outboxCanSign(env: Record<string, string | undefined>, names: SecretNames, declaredSecret?: string): boolean;
|
|
64
|
-
/**
|
|
65
|
-
* This domain's key: its own first, then the installation's common one.
|
|
66
|
-
*
|
|
67
|
-
* **Absent is `undefined`, never an empty string.** An empty string signs, and a request signed with
|
|
68
|
-
* nothing cannot be told from a forgery. Falling back to the common key stops here; a caller with
|
|
69
|
-
* neither has to stop and name the domain it was working on.
|
|
70
|
-
*
|
|
71
|
-
* A multi-tenant installation should give per-domain keys and no common one. Then a domain nobody
|
|
72
|
-
* gave a key to is caught, rather than opening with somebody else's.
|
|
73
|
-
*/
|
|
74
|
-
export declare function outboxSecretFor(env: Record<string, string | undefined>, names: SecretNames, subdomain: string, declaredSecret?: string): string | undefined;
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* **Can this installation send at all** — a pure judgement, no imports, no environment read here.
|
|
4
|
-
*
|
|
5
|
-
* ═════════════════════════════════════════════════════════════════════════
|
|
6
|
-
* ## What used to guard this door, and why it moved
|
|
7
|
-
*
|
|
8
|
-
* The pump used to stand only if a destination was named in the configuration file. Destinations then
|
|
9
|
-
* moved to a table an administrator edits, and the door stayed where it was: a site could name its
|
|
10
|
-
* destination on the screen and **the pump still would not stand**. Rows piled up with nobody sending
|
|
11
|
-
* them, and nothing failed, so nobody knew.
|
|
12
|
-
*
|
|
13
|
-
* ## So the key is what declares a sender
|
|
14
|
-
*
|
|
15
|
-
* Destinations live in a table now, and the pump reads that table every round - a boot-time reading
|
|
16
|
-
* would not see a destination added later. What is left is the signing key. An installation with no
|
|
17
|
-
* key cannot deliver one record even with a destination: unsigned, the receiver refuses it. So the
|
|
18
|
-
* key is the declaration that this installation sends.
|
|
19
|
-
*
|
|
20
|
-
* ## The names belong to the caller, the shape belongs here
|
|
21
|
-
*
|
|
22
|
-
* This module never reads `process.env`, and it has **no default names**: a product that forgets to
|
|
23
|
-
* name its variables would otherwise sign with somebody else's key and nothing would say so. What the
|
|
24
|
-
* module does own is how a domain becomes a variable suffix - if each product wrote that rule itself,
|
|
25
|
-
* the same domain would look for different variables depending on which product asked.
|
|
26
|
-
*
|
|
27
|
-
* ```
|
|
28
|
-
* <common> one key for the installation - a single-site install
|
|
29
|
-
* <common>__MIRATEK_GUNSAN one key per domain - what a multi-tenant install should use
|
|
30
|
-
* ```
|
|
31
|
-
*
|
|
32
|
-
* A domain's name is not known at boot, so this counts by prefix. Which domain gave the key is
|
|
33
|
-
* settled on that domain's turn, and named there.
|
|
34
|
-
*
|
|
35
|
-
* ⚠ This door answers "can we sign", not "is there anything to send". An installation with a key and
|
|
36
|
-
* no destination row still stands the pump - and says, once per domain with facts waiting, that it
|
|
37
|
-
* has nowhere to send them. That is better than not standing and saying nothing.
|
|
38
|
-
* ═════════════════════════════════════════════════════════════════════════
|
|
39
|
-
*/
|
|
40
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.domainSecretName = domainSecretName;
|
|
42
|
-
exports.outboxCanSign = outboxCanSign;
|
|
43
|
-
exports.outboxSecretFor = outboxSecretFor;
|
|
44
|
-
/**
|
|
45
|
-
* The variable a domain's own key lives in.
|
|
46
|
-
*
|
|
47
|
-
* Anything that is not a letter or a digit becomes `_`, because that is what an environment variable
|
|
48
|
-
* name may hold. Written once, here: a product that rounded this differently would look for
|
|
49
|
-
* `MIRATEK_GUNSAN` while another looked for `MIRATEK-GUNSAN`, for the same domain.
|
|
50
|
-
*/
|
|
51
|
-
function domainSecretName(prefix, subdomain) {
|
|
52
|
-
return `${prefix}${subdomain.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}`;
|
|
53
|
-
}
|
|
54
|
-
/** A value that is only whitespace is no value: signing with it produces a signature that stands. */
|
|
55
|
-
function filled(value) {
|
|
56
|
-
return typeof value === 'string' && value.trim().length > 0;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Does this installation hold any key to sign with?
|
|
60
|
-
*
|
|
61
|
-
* The environment arrives as an argument. Reading the process here would put this judgement out of
|
|
62
|
-
* reach of a test, and this is the judgement that decides whether anything is delivered at all.
|
|
63
|
-
*/
|
|
64
|
-
function outboxCanSign(env, names, declaredSecret) {
|
|
65
|
-
if (filled(env[names.common]) || filled(declaredSecret)) {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
return Object.keys(env).some(name => name.startsWith(names.domainPrefix) && filled(env[name]));
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* This domain's key: its own first, then the installation's common one.
|
|
72
|
-
*
|
|
73
|
-
* **Absent is `undefined`, never an empty string.** An empty string signs, and a request signed with
|
|
74
|
-
* nothing cannot be told from a forgery. Falling back to the common key stops here; a caller with
|
|
75
|
-
* neither has to stop and name the domain it was working on.
|
|
76
|
-
*
|
|
77
|
-
* A multi-tenant installation should give per-domain keys and no common one. Then a domain nobody
|
|
78
|
-
* gave a key to is caught, rather than opening with somebody else's.
|
|
79
|
-
*/
|
|
80
|
-
function outboxSecretFor(env, names, subdomain, declaredSecret) {
|
|
81
|
-
const mine = env[domainSecretName(names.domainPrefix, subdomain)];
|
|
82
|
-
if (filled(mine)) {
|
|
83
|
-
return mine;
|
|
84
|
-
}
|
|
85
|
-
if (filled(env[names.common])) {
|
|
86
|
-
return env[names.common];
|
|
87
|
-
}
|
|
88
|
-
return filled(declaredSecret) ? declaredSecret : undefined;
|
|
89
|
-
}
|
|
90
|
-
//# sourceMappingURL=pump-gate.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pump-gate.js","sourceRoot":"","sources":["../../../server/service/outbox/pump-gate.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;;AAoBH,4CAEC;AAaD,sCAUC;AAYD,0CAiBC;AA7DD;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAAC,MAAc,EAAE,SAAiB;IAChE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,CAAA;AAC1E,CAAC;AAED,qGAAqG;AACrG,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;AAC7D,CAAC;AAED;;;;;GAKG;AACH,SAAgB,aAAa,CAC3B,GAAuC,EACvC,KAAkB,EAClB,cAAuB;IAEvB,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC;QACxD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChG,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,eAAe,CAC7B,GAAuC,EACvC,KAAkB,EAClB,SAAiB,EACjB,cAAuB;IAEvB,MAAM,IAAI,GAAG,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAA;IAEjE,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACjB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAC9B,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IAC1B,CAAC;IAED,OAAO,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5D,CAAC","sourcesContent":["/**\n * **Can this installation send at all** — a pure judgement, no imports, no environment read here.\n *\n * ═════════════════════════════════════════════════════════════════════════\n * ## What used to guard this door, and why it moved\n *\n * The pump used to stand only if a destination was named in the configuration file. Destinations then\n * moved to a table an administrator edits, and the door stayed where it was: a site could name its\n * destination on the screen and **the pump still would not stand**. Rows piled up with nobody sending\n * them, and nothing failed, so nobody knew.\n *\n * ## So the key is what declares a sender\n *\n * Destinations live in a table now, and the pump reads that table every round - a boot-time reading\n * would not see a destination added later. What is left is the signing key. An installation with no\n * key cannot deliver one record even with a destination: unsigned, the receiver refuses it. So the\n * key is the declaration that this installation sends.\n *\n * ## The names belong to the caller, the shape belongs here\n *\n * This module never reads `process.env`, and it has **no default names**: a product that forgets to\n * name its variables would otherwise sign with somebody else's key and nothing would say so. What the\n * module does own is how a domain becomes a variable suffix - if each product wrote that rule itself,\n * the same domain would look for different variables depending on which product asked.\n *\n * ```\n * <common> one key for the installation - a single-site install\n * <common>__MIRATEK_GUNSAN one key per domain - what a multi-tenant install should use\n * ```\n *\n * A domain's name is not known at boot, so this counts by prefix. Which domain gave the key is\n * settled on that domain's turn, and named there.\n *\n * ⚠ This door answers \"can we sign\", not \"is there anything to send\". An installation with a key and\n * no destination row still stands the pump - and says, once per domain with facts waiting, that it\n * has nowhere to send them. That is better than not standing and saying nothing.\n * ═════════════════════════════════════════════════════════════════════════\n */\n\n/**\n * The two variable name stems a product declares. **Required** - see above on why there is no default.\n *\n * `domainPrefix` is the stem the per-domain names are built on; `domainSecretName` makes the whole\n * name from it.\n */\nexport interface SecretNames {\n common: string\n domainPrefix: string\n}\n\n/**\n * The variable a domain's own key lives in.\n *\n * Anything that is not a letter or a digit becomes `_`, because that is what an environment variable\n * name may hold. Written once, here: a product that rounded this differently would look for\n * `MIRATEK_GUNSAN` while another looked for `MIRATEK-GUNSAN`, for the same domain.\n */\nexport function domainSecretName(prefix: string, subdomain: string): string {\n return `${prefix}${subdomain.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}`\n}\n\n/** A value that is only whitespace is no value: signing with it produces a signature that stands. */\nfunction filled(value: unknown): boolean {\n return typeof value === 'string' && value.trim().length > 0\n}\n\n/**\n * Does this installation hold any key to sign with?\n *\n * The environment arrives as an argument. Reading the process here would put this judgement out of\n * reach of a test, and this is the judgement that decides whether anything is delivered at all.\n */\nexport function outboxCanSign(\n env: Record<string, string | undefined>,\n names: SecretNames,\n declaredSecret?: string\n): boolean {\n if (filled(env[names.common]) || filled(declaredSecret)) {\n return true\n }\n\n return Object.keys(env).some(name => name.startsWith(names.domainPrefix) && filled(env[name]))\n}\n\n/**\n * This domain's key: its own first, then the installation's common one.\n *\n * **Absent is `undefined`, never an empty string.** An empty string signs, and a request signed with\n * nothing cannot be told from a forgery. Falling back to the common key stops here; a caller with\n * neither has to stop and name the domain it was working on.\n *\n * A multi-tenant installation should give per-domain keys and no common one. Then a domain nobody\n * gave a key to is caught, rather than opening with somebody else's.\n */\nexport function outboxSecretFor(\n env: Record<string, string | undefined>,\n names: SecretNames,\n subdomain: string,\n declaredSecret?: string\n): string | undefined {\n const mine = env[domainSecretName(names.domainPrefix, subdomain)]\n\n if (filled(mine)) {\n return mine\n }\n\n if (filled(env[names.common])) {\n return env[names.common]\n }\n\n return filled(declaredSecret) ? declaredSecret : undefined\n}\n"]}
|