@cello-protocol/gateway 0.0.12 → 0.0.14
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/bin/cello-gateway.js +74 -17
- package/dist/bin/cello-gateway.js.map +1 -1
- package/dist/client.d.ts +12 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +30 -0
- package/dist/client.js.map +1 -1
- package/dist/config/config-store.d.ts +24 -1
- package/dist/config/config-store.d.ts.map +1 -1
- package/dist/config/config-store.js +9 -2
- package/dist/config/config-store.js.map +1 -1
- package/dist/detect/index.d.ts +9 -5
- package/dist/detect/index.d.ts.map +1 -1
- package/dist/detect/index.js +9 -5
- package/dist/detect/index.js.map +1 -1
- package/dist/detect/pii.d.ts.map +1 -1
- package/dist/detect/pii.js +43 -1
- package/dist/detect/pii.js.map +1 -1
- package/dist/detect/rate-limit.d.ts +0 -12
- package/dist/detect/rate-limit.d.ts.map +1 -1
- package/dist/detect/rate-limit.js +16 -1
- package/dist/detect/rate-limit.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/passthrough.d.ts +11 -6
- package/dist/passthrough.d.ts.map +1 -1
- package/dist/passthrough.js +10 -5
- package/dist/passthrough.js.map +1 -1
- package/dist/records/record-store.d.ts +26 -1
- package/dist/records/record-store.d.ts.map +1 -1
- package/dist/records/record-store.js +9 -2
- package/dist/records/record-store.js.map +1 -1
- package/dist/screen/affordance.d.ts +32 -0
- package/dist/screen/affordance.d.ts.map +1 -0
- package/dist/screen/affordance.js +37 -0
- package/dist/screen/affordance.js.map +1 -0
- package/dist/screen/inbound.d.ts.map +1 -1
- package/dist/screen/inbound.js +6 -2
- package/dist/screen/inbound.js.map +1 -1
- package/dist/screen/outbound.d.ts.map +1 -1
- package/dist/screen/outbound.js +15 -4
- package/dist/screen/outbound.js.map +1 -1
- package/dist/spawn.d.ts.map +1 -1
- package/dist/spawn.js +33 -5
- package/dist/spawn.js.map +1 -1
- package/dist/store/encrypted-db.d.ts +12 -2
- package/dist/store/encrypted-db.d.ts.map +1 -1
- package/dist/store/encrypted-db.js +73 -10
- package/dist/store/encrypted-db.js.map +1 -1
- package/dist/testing.d.ts +14 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +14 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +6 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type GatewayStoreErrorCode = "store_key_unavailable" | "store_key_mismatch" | "store_engine_unavailable" | "store_open_failed";
|
|
1
|
+
export type GatewayStoreErrorCode = "store_key_unavailable" | "store_key_mismatch" | "store_plaintext_file" | "store_locked" | "store_engine_unavailable" | "store_open_failed";
|
|
2
2
|
export declare class GatewayStoreError extends Error {
|
|
3
3
|
readonly code: GatewayStoreErrorCode;
|
|
4
4
|
/** Actionable next step for the operator — never contains key material. */
|
|
@@ -18,10 +18,20 @@ export interface StoreDb {
|
|
|
18
18
|
prepare(sql: string): StoreStatement;
|
|
19
19
|
close(): void;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Where this module's events go. INJECTED, because the store now has two callers with opposite
|
|
23
|
+
* needs: the gateway BIN is a composition root with no logger, whose stdout is reserved for the
|
|
24
|
+
* READY handshake the spawner parses — so its events go to stderr, which the spawner drains and
|
|
25
|
+
* surfaces. The DAEMON has an injected logger and a hard rule against writing anywhere else
|
|
26
|
+
* (INV-7), so it passes one in. Defaulting to stderr would have put raw writes in daemon code.
|
|
27
|
+
*/
|
|
28
|
+
export type StoreEventSink = (event: string, context: Record<string, unknown>) => void;
|
|
29
|
+
/** The gateway bin's sink: one structured line on stderr, never stdout. */
|
|
30
|
+
export declare const stderrStoreEventSink: StoreEventSink;
|
|
21
31
|
/**
|
|
22
32
|
* Open (creating if absent) the gateway's encrypted store file, keyed by the raw 32-byte key in
|
|
23
33
|
* `keyFilePath`. Verifies the key by reading sqlite_master; enables WAL only after verification.
|
|
24
34
|
* Throws GatewayStoreError on every failure path — never returns a plaintext handle.
|
|
25
35
|
*/
|
|
26
|
-
export declare function openEncryptedStoreDb(dbPath: string, keyFilePath: string): StoreDb;
|
|
36
|
+
export declare function openEncryptedStoreDb(dbPath: string, keyFilePath: string, onEvent?: StoreEventSink): StoreDb;
|
|
27
37
|
//# sourceMappingURL=encrypted-db.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypted-db.d.ts","sourceRoot":"","sources":["../../src/store/encrypted-db.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"encrypted-db.d.ts","sourceRoot":"","sources":["../../src/store/encrypted-db.ts"],"names":[],"mappings":"AA8CA,MAAM,MAAM,qBAAqB,GAC7B,uBAAuB,GACvB,oBAAoB,GACpB,sBAAsB,GACtB,cAAc,GACd,0BAA0B,GAC1B,mBAAmB,CAAC;AAExB,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBACd,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAM3E;AA0BD,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG;QAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC1F,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACnC,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC;IACrC,KAAK,IAAI,IAAI,CAAC;CACf;AAkCD;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAEvF,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,EAAE,cAElC,CAAC;AAsCF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAwF3G"}
|
|
@@ -17,8 +17,33 @@
|
|
|
17
17
|
* writes config and reads records).
|
|
18
18
|
*/
|
|
19
19
|
import { createRequire } from "node:module";
|
|
20
|
-
import { readFileSync } from "node:fs";
|
|
20
|
+
import { readFileSync, existsSync, openSync, readSync, closeSync } from "node:fs";
|
|
21
21
|
const STORE_KEY_BYTES = 32; // AES-256 — the daemon's key size
|
|
22
|
+
/**
|
|
23
|
+
* A plaintext SQLite file begins with these bytes; a SQLCipher file encrypts its header, so its
|
|
24
|
+
* first bytes are ciphertext and never match. Used to tell "someone left a plaintext store here"
|
|
25
|
+
* apart from "wrong key" — two very different operator actions.
|
|
26
|
+
*/
|
|
27
|
+
const SQLITE_PLAINTEXT_MAGIC = Buffer.concat([Buffer.from("SQLite format 3", "latin1"), Buffer.from([0x00])]);
|
|
28
|
+
function isPlaintextSqliteFile(dbPath) {
|
|
29
|
+
if (!existsSync(dbPath))
|
|
30
|
+
return false;
|
|
31
|
+
const head = Buffer.alloc(SQLITE_PLAINTEXT_MAGIC.length);
|
|
32
|
+
try {
|
|
33
|
+
const fd = openSync(dbPath, "r");
|
|
34
|
+
try {
|
|
35
|
+
if (readSync(fd, head, 0, head.length, 0) < head.length)
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
closeSync(fd);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
return head.equals(SQLITE_PLAINTEXT_MAGIC);
|
|
46
|
+
}
|
|
22
47
|
export class GatewayStoreError extends Error {
|
|
23
48
|
code;
|
|
24
49
|
/** Actionable next step for the operator — never contains key material. */
|
|
@@ -60,6 +85,10 @@ class AdaptedDb {
|
|
|
60
85
|
this.#inner.close();
|
|
61
86
|
}
|
|
62
87
|
}
|
|
88
|
+
/** The gateway bin's sink: one structured line on stderr, never stdout. */
|
|
89
|
+
export const stderrStoreEventSink = (event, context) => {
|
|
90
|
+
process.stderr.write(`${JSON.stringify({ level: "info", event, ...context })}\n`);
|
|
91
|
+
};
|
|
63
92
|
function loadEngine() {
|
|
64
93
|
const require = createRequire(import.meta.url);
|
|
65
94
|
try {
|
|
@@ -89,8 +118,18 @@ function readStoreKey(keyFilePath) {
|
|
|
89
118
|
* `keyFilePath`. Verifies the key by reading sqlite_master; enables WAL only after verification.
|
|
90
119
|
* Throws GatewayStoreError on every failure path — never returns a plaintext handle.
|
|
91
120
|
*/
|
|
92
|
-
export function openEncryptedStoreDb(dbPath, keyFilePath) {
|
|
121
|
+
export function openEncryptedStoreDb(dbPath, keyFilePath, onEvent) {
|
|
122
|
+
const emit = (event, context) => onEvent?.(event, context);
|
|
93
123
|
const key = readStoreKey(keyFilePath);
|
|
124
|
+
// Distinguish "a plaintext store was left here" from "wrong key" BEFORE trying to decrypt.
|
|
125
|
+
// Both surface as an unreadable header, and they call for opposite operator actions: one is
|
|
126
|
+
// "delete this stale file", the other is "restore your key from backup" — advice that destroys
|
|
127
|
+
// data if given for the wrong cause.
|
|
128
|
+
if (isPlaintextSqliteFile(dbPath)) {
|
|
129
|
+
throw new GatewayStoreError("store_plaintext_file", `the file at ${dbPath} is an UNENCRYPTED SQLite database`, "The gateway store must be encrypted. This is a leftover plaintext store from before the " +
|
|
130
|
+
"store was encrypted; it is not migrated and not read. Move or delete it and restart — a " +
|
|
131
|
+
"fresh encrypted store is created automatically.");
|
|
132
|
+
}
|
|
94
133
|
const mod = loadEngine();
|
|
95
134
|
const Ctor = mod.Database ?? mod.default;
|
|
96
135
|
let inner;
|
|
@@ -104,28 +143,52 @@ export function openEncryptedStoreDb(dbPath, keyFilePath) {
|
|
|
104
143
|
// Key set outside the message-bearing try: key hex must never reach an error string.
|
|
105
144
|
const keyHex = Buffer.from(key).toString("hex");
|
|
106
145
|
inner.pragma(`key = "x'${keyHex}'"`);
|
|
146
|
+
// busy_timeout FIRST — before the verify read and before the WAL pragma, both of which take
|
|
147
|
+
// locks. This file is shared with the daemon (M9C-D9), so a contended startup is ordinary, and
|
|
148
|
+
// with the SQLite default timeout of 0 the very first contended open returns SQLITE_BUSY
|
|
149
|
+
// instantly — which the verify-read catch below would then report as a wrong key. Setting it
|
|
150
|
+
// last (as this did) turns lock contention into "your key is wrong. Restore it from backup."
|
|
151
|
+
inner.pragma("busy_timeout = 3000");
|
|
107
152
|
try {
|
|
108
153
|
inner.prepare("SELECT count(*) AS c FROM sqlite_master").get([]);
|
|
109
154
|
}
|
|
110
|
-
catch {
|
|
155
|
+
catch (err) {
|
|
111
156
|
try {
|
|
112
157
|
inner.close();
|
|
113
158
|
}
|
|
114
159
|
catch {
|
|
115
160
|
/* ignore */
|
|
116
161
|
}
|
|
117
|
-
|
|
162
|
+
// The upstream reason MUST survive. A wrong key, a locked file, a truncated file and an I/O
|
|
163
|
+
// error all surface here, and a label that names only the exit point sends the operator to
|
|
164
|
+
// the wrong subsystem. No key material can appear in this string — the key is only ever in
|
|
165
|
+
// the pragma above, which is not part of the thrown error. (The daemon's opener does the
|
|
166
|
+
// same at sqlcipher-db.ts; this copy dropped it, which is the defect being fixed.)
|
|
167
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
168
|
+
const locked = /SQLITE_BUSY|database is locked/i.test(reason);
|
|
169
|
+
if (locked) {
|
|
170
|
+
throw new GatewayStoreError("store_locked", `gateway store is locked by another process (${reason})`, "Another process holds the gateway store's write lock — usually an orphaned gateway from " +
|
|
171
|
+
"a previous daemon. Stop it and restart the daemon. The key is not the problem.");
|
|
172
|
+
}
|
|
173
|
+
throw new GatewayStoreError("store_key_mismatch", `gateway store did not decrypt with the supplied key (${reason})`, "The daemon's key does not match this gateway store file. Restore the matching key file; " +
|
|
118
174
|
"the gateway will not fall back to a plaintext store.");
|
|
119
175
|
}
|
|
120
|
-
// WAL after verification so WAL/SHM are ciphertext
|
|
121
|
-
//
|
|
176
|
+
// WAL after verification so WAL/SHM are ciphertext. CHECK the result rather than assuming it:
|
|
177
|
+
// the file is shared with the daemon, and a silent fall back to rollback-journal mode means a
|
|
178
|
+
// daemon write blocks gateway reads, which surfaces to the user as messages fail-closed with a
|
|
179
|
+
// generic screen error. Not fatal — SQLCipher encrypts the rollback journal too, so custody
|
|
180
|
+
// holds either way — but never silent.
|
|
122
181
|
try {
|
|
123
|
-
inner.pragma("journal_mode=WAL", { simple: true });
|
|
182
|
+
const mode = inner.pragma("journal_mode=WAL", { simple: true });
|
|
183
|
+
if (mode !== "wal")
|
|
184
|
+
emit("gateway.store.wal_unavailable", { mode: String(mode) });
|
|
124
185
|
}
|
|
125
|
-
catch {
|
|
126
|
-
|
|
186
|
+
catch (err) {
|
|
187
|
+
emit("gateway.store.wal_unavailable", { error: err instanceof Error ? err.message : String(err) });
|
|
127
188
|
}
|
|
128
|
-
|
|
189
|
+
// The store is open and encrypted. Structured, on stderr: stdout carries the READY handshake the
|
|
190
|
+
// parent parses, so nothing else may go there. Never the key, and never the key file's contents.
|
|
191
|
+
emit("gateway.store.opened", { encrypted: true, path: dbPath });
|
|
129
192
|
return new AdaptedDb(inner);
|
|
130
193
|
}
|
|
131
194
|
//# sourceMappingURL=encrypted-db.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypted-db.js","sourceRoot":"","sources":["../../src/store/encrypted-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"encrypted-db.js","sourceRoot":"","sources":["../../src/store/encrypted-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAElF,MAAM,eAAe,GAAG,EAAE,CAAC,CAAC,kCAAkC;AAE9D;;;;GAIG;AACH,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9G,SAAS,qBAAqB,CAAC,MAAc;IAC3C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IACtC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,IAAI,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAC;QACxE,CAAC;gBAAS,CAAC;YACT,SAAS,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAC7C,CAAC;AAUD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAwB;IACrC,2EAA2E;IAClE,QAAQ,CAAS;IAC1B,YAAY,IAA2B,EAAE,OAAe,EAAE,QAAgB;QACxE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAsCD,MAAM,gBAAgB;IACX,MAAM,CAAkB;IACjC,YAAY,KAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,GAAG,CAAC,GAAG,MAAiB;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACD,GAAG,CAAC,GAAG,MAAiB;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACD,GAAG,CAAC,GAAG,MAAiB;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;CACF;AAED,MAAM,SAAS;IACJ,MAAM,CAAiB;IAChC,YAAY,KAAqB;QAC/B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,IAAI,CAAC,GAAW;QACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,GAAW;QACjB,OAAO,IAAI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACF;AAWD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,oBAAoB,GAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACrE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;AACpF,CAAC,CAAC;AAEF,SAAS,UAAU;IACjB,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/C,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,sBAAsB,CAAiB,CAAC;IACzD,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,IAAI,iBAAiB,CACzB,0BAA0B,EAC1B,wCAAwC,MAAM,EAAE,EAChD,iGAAiG,CAClG,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,WAAmB;IACvC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,iBAAiB,CACzB,uBAAuB,EACvB,uCAAuC,WAAW,EAAE,EACpD,8FAA8F;YAC5F,sFAAsF,CACzF,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,eAAe,EAAE,CAAC;QACnC,MAAM,IAAI,iBAAiB,CACzB,uBAAuB,EACvB,6BAA6B,GAAG,CAAC,MAAM,oBAAoB,eAAe,EAAE,EAC5E,mBAAmB,WAAW,wCAAwC,CACvE,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,WAAmB,EAAE,OAAwB;IAChG,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,OAAgC,EAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAClG,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAEtC,2FAA2F;IAC3F,4FAA4F;IAC5F,+FAA+F;IAC/F,qCAAqC;IACrC,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,iBAAiB,CACzB,sBAAsB,EACtB,eAAe,MAAM,oCAAoC,EACzD,0FAA0F;YACxF,0FAA0F;YAC1F,iDAAiD,CACpD,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC;IAEzC,IAAI,KAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,IAAI,iBAAiB,CAAC,mBAAmB,EAAE,MAAM,EAAE,uCAAuC,MAAM,GAAG,CAAC,CAAC;IAC7G,CAAC;IAED,qFAAqF;IACrF,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,KAAK,CAAC,MAAM,CAAC,YAAY,MAAM,IAAI,CAAC,CAAC;IAErC,4FAA4F;IAC5F,+FAA+F;IAC/F,yFAAyF;IACzF,6FAA6F;IAC7F,6FAA6F;IAC7F,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,KAAK,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC;YACP,YAAY;QACd,CAAC;QACD,4FAA4F;QAC5F,2FAA2F;QAC3F,2FAA2F;QAC3F,yFAAyF;QACzF,mFAAmF;QACnF,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,iCAAiC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9D,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,iBAAiB,CACzB,cAAc,EACd,+CAA+C,MAAM,GAAG,EACxD,0FAA0F;gBACxF,gFAAgF,CACnF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,iBAAiB,CACzB,oBAAoB,EACpB,wDAAwD,MAAM,GAAG,EACjE,0FAA0F;YACxF,sDAAsD,CACzD,CAAC;IACJ,CAAC;IAED,8FAA8F;IAC9F,8FAA8F;IAC9F,+FAA+F;IAC/F,4FAA4F;IAC5F,uCAAuC;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,IAAI,IAAI,KAAK,KAAK;YAAE,IAAI,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,CAAC,+BAA+B,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrG,CAAC;IAED,iGAAiG;IACjG,iGAAiG;IACjG,IAAI,CAAC,sBAAsB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAEhE,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TEST-ONLY exports. Reachable as `@cello-protocol/gateway/testing`, deliberately NOT from the
|
|
3
|
+
* package barrel (DOD-M9C-WIRE-1: "the stub moves to test-only visibility").
|
|
4
|
+
*
|
|
5
|
+
* `PassthroughGatewayClient` screens nothing and allows everything. It was the daemon's DEFAULT
|
|
6
|
+
* once, and because no production caller ever overrode it, the entire security layer shipped inert
|
|
7
|
+
* while the daemon logged that its gateway was connected. It still has to EXIST — tests are
|
|
8
|
+
* out-of-tree consumers and need a way to satisfy the now-required `securityGateway` field — but
|
|
9
|
+
* putting it on the main barrel leaves an always-allow client one ordinary import away from any
|
|
10
|
+
* production file. A separate entry point makes reaching for it a deliberate act that shows up in
|
|
11
|
+
* a diff.
|
|
12
|
+
*/
|
|
13
|
+
export { PassthroughGatewayClient } from "./passthrough.js";
|
|
14
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TEST-ONLY exports. Reachable as `@cello-protocol/gateway/testing`, deliberately NOT from the
|
|
3
|
+
* package barrel (DOD-M9C-WIRE-1: "the stub moves to test-only visibility").
|
|
4
|
+
*
|
|
5
|
+
* `PassthroughGatewayClient` screens nothing and allows everything. It was the daemon's DEFAULT
|
|
6
|
+
* once, and because no production caller ever overrode it, the entire security layer shipped inert
|
|
7
|
+
* while the daemon logged that its gateway was connected. It still has to EXIST — tests are
|
|
8
|
+
* out-of-tree consumers and need a way to satisfy the now-required `securityGateway` field — but
|
|
9
|
+
* putting it on the main barrel leaves an always-allow client one ordinary import away from any
|
|
10
|
+
* production file. A separate entry point makes reaching for it a deliberate act that shows up in
|
|
11
|
+
* a diff.
|
|
12
|
+
*/
|
|
13
|
+
export { PassthroughGatewayClient } from "./passthrough.js";
|
|
14
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -102,7 +102,17 @@ export interface ScreenVerdict {
|
|
|
102
102
|
* deadline. A timeout or unreachable gateway resolves to a fail-closed `block`
|
|
103
103
|
* (`gateway_unavailable`), never a rejected/never-settling promise (INV-6 / SI-001).
|
|
104
104
|
*/
|
|
105
|
+
/** What a client actually does to content. `enforcing` screens; `passthrough` allows everything. */
|
|
106
|
+
export type GatewayMode = "enforcing" | "passthrough";
|
|
105
107
|
export interface SecurityGatewayClient {
|
|
108
|
+
/**
|
|
109
|
+
* Declared by the implementation, never computed by the caller (M9C-D11). The daemon announces
|
|
110
|
+
* this at boot, and it is the field an operator greps to know whether their agent is screened —
|
|
111
|
+
* so it must come from the object that will actually do (or not do) the screening. The defect
|
|
112
|
+
* this closes: the daemon used to announce `config.securityGateway ? "sidecar" : "passthrough"`,
|
|
113
|
+
* so the boot line described the caller's intent rather than the object's behavior.
|
|
114
|
+
*/
|
|
115
|
+
readonly mode: GatewayMode;
|
|
106
116
|
screenOutbound(content: Uint8Array, ctx: ScreenContext): Promise<ScreenVerdict>;
|
|
107
117
|
screenInbound(content: Uint8Array, ctx: ScreenContext): Promise<ScreenVerdict>;
|
|
108
118
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtE,yGAAyG;AACzG,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5E;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,YAAY,GAAG,cAAc,CAAC;AAE1E;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,qBAAqB,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC1D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAChF,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAChF;AAED,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AACzD;0EAC0E;AAC1E,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,eAAe,EAAE,MAAM,GAAE,MAA4B,GAAG,aAAa,CAcjH"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEtE,yGAAyG;AACzG,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5E;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,YAAY,GAAG,cAAc,CAAC;AAE1E;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,qBAAqB,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,kGAAkG;AAClG,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gGAAgG;IAChG,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC1D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,oGAAoG;AACpG,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,aAAa,CAAC;AAEtD,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAChF,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CAChF;AAED,wFAAwF;AACxF,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AACzD;0EAC0E;AAC1E,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAEvD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,eAAe,EAAE,MAAM,GAAE,MAA4B,GAAG,aAAa,CAcjH"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAoHH,wFAAwF;AACxF,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AACzD;0EAC0E;AAC1E,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAA0B,EAAE,SAAiB,mBAAmB;IAChG,MAAM,KAAK,GAAG,MAAM,KAAK,kBAAkB;QACzC,CAAC,CAAC,6EAA6E;QAC/E,CAAC,CAAC,2CAA2C,CAAC;IAChD,OAAO;QACL,WAAW,EAAE,OAAO;QACpB,MAAM;QACN,QAAQ,EACN,SAAS,KAAK,UAAU;YACtB,CAAC,CAAC,gBAAgB,KAAK,4DAA4D;gBACjF,wDAAwD;YAC1D,CAAC,CAAC,gBAAgB,KAAK,mEAAmE;gBACxF,sGAAsG;KAC7G,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cello-protocol/gateway",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
"import": "./dist/index.js",
|
|
17
17
|
"types": "./dist/index.d.ts"
|
|
18
18
|
},
|
|
19
|
+
"./testing": {
|
|
20
|
+
"import": "./dist/testing.js",
|
|
21
|
+
"types": "./dist/testing.d.ts"
|
|
22
|
+
},
|
|
19
23
|
"./detect": {
|
|
20
24
|
"import": "./dist/detect/index.js",
|
|
21
25
|
"types": "./dist/detect/index.d.ts"
|
|
@@ -30,10 +34,10 @@
|
|
|
30
34
|
"package.json"
|
|
31
35
|
],
|
|
32
36
|
"dependencies": {
|
|
33
|
-
"@signalapp/sqlcipher": "^3.3.5",
|
|
34
37
|
"re2-wasm": "^1.0.2"
|
|
35
38
|
},
|
|
36
39
|
"optionalDependencies": {
|
|
40
|
+
"@signalapp/sqlcipher": "^3.3.5",
|
|
37
41
|
"re2": "^1.25.0"
|
|
38
42
|
},
|
|
39
43
|
"devDependencies": {
|