@openclaw/crabline 0.1.10 → 0.1.12
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 +99 -12
- package/dist/src/bin/crabline.js +3 -1
- package/dist/src/bin/crabline.js.map +1 -1
- package/dist/src/cli/program.d.ts +5 -1
- package/dist/src/cli/program.js +264 -50
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/config/load.js +39 -3
- package/dist/src/config/load.js.map +1 -1
- package/dist/src/config/schema.d.ts +20 -0
- package/dist/src/config/schema.js +163 -35
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/core/errors.d.ts +1 -0
- package/dist/src/core/errors.js +6 -3
- package/dist/src/core/errors.js.map +1 -1
- package/dist/src/core/http-path.d.ts +1 -0
- package/dist/src/core/http-path.js +14 -0
- package/dist/src/core/http-path.js.map +1 -0
- package/dist/src/core/matcher.d.ts +3 -1
- package/dist/src/core/matcher.js +58 -2
- package/dist/src/core/matcher.js.map +1 -1
- package/dist/src/core/nonces.d.ts +2 -0
- package/dist/src/core/nonces.js +11 -1
- package/dist/src/core/nonces.js.map +1 -1
- package/dist/src/core/reporters.d.ts +5 -0
- package/dist/src/core/reporters.js +26 -2
- package/dist/src/core/reporters.js.map +1 -1
- package/dist/src/core/run.d.ts +3 -1
- package/dist/src/core/run.js +178 -66
- package/dist/src/core/run.js.map +1 -1
- package/dist/src/matrix-ids.d.ts +5 -0
- package/dist/src/matrix-ids.js +83 -0
- package/dist/src/matrix-ids.js.map +1 -0
- package/dist/src/openclaw/artifact-generation.d.ts +12 -2
- package/dist/src/openclaw/artifact-generation.js +436 -15
- package/dist/src/openclaw/artifact-generation.js.map +1 -1
- package/dist/src/openclaw/bridges/matrix.js +21 -4
- package/dist/src/openclaw/bridges/matrix.js.map +1 -1
- package/dist/src/openclaw/bridges/mattermost.js +13 -8
- package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
- package/dist/src/openclaw/bridges/probe-response.d.ts +1 -0
- package/dist/src/openclaw/bridges/probe-response.js +5 -0
- package/dist/src/openclaw/bridges/probe-response.js.map +1 -0
- package/dist/src/openclaw/bridges/signal.js +15 -6
- package/dist/src/openclaw/bridges/signal.js.map +1 -1
- package/dist/src/openclaw/bridges/slack.js +116 -23
- package/dist/src/openclaw/bridges/slack.js.map +1 -1
- package/dist/src/openclaw/bridges/telegram.js +45 -19
- package/dist/src/openclaw/bridges/telegram.js.map +1 -1
- package/dist/src/openclaw/bridges/whatsapp.js +32 -16
- package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
- package/dist/src/openclaw/bridges/zalo.js +8 -3
- package/dist/src/openclaw/bridges/zalo.js.map +1 -1
- package/dist/src/openclaw/private-file.d.ts +40 -3
- package/dist/src/openclaw/private-file.js +2070 -95
- package/dist/src/openclaw/private-file.js.map +1 -1
- package/dist/src/openclaw/shared.d.ts +1 -0
- package/dist/src/openclaw/shared.js +48 -13
- package/dist/src/openclaw/shared.js.map +1 -1
- package/dist/src/openclaw/smoke-lock.d.ts +9 -0
- package/dist/src/openclaw/smoke-lock.js +696 -187
- package/dist/src/openclaw/smoke-lock.js.map +1 -1
- package/dist/src/openclaw.js +352 -29
- package/dist/src/openclaw.js.map +1 -1
- package/dist/src/platform/process-owned-lock.d.ts +11 -0
- package/dist/src/platform/process-owned-lock.js +1698 -0
- package/dist/src/platform/process-owned-lock.js.map +1 -0
- package/dist/src/platform/recorder-directory.d.ts +1 -0
- package/dist/src/platform/recorder-directory.js +14 -0
- package/dist/src/platform/recorder-directory.js.map +1 -0
- package/dist/src/platform/windows-acl.d.ts +18 -0
- package/dist/src/platform/windows-acl.js +1367 -0
- package/dist/src/platform/windows-acl.js.map +1 -0
- package/dist/src/platform/windows-lock-root.d.ts +13 -0
- package/dist/src/platform/windows-lock-root.js +98 -0
- package/dist/src/platform/windows-lock-root.js.map +1 -0
- package/dist/src/providers/builtin/discord.d.ts +4 -0
- package/dist/src/providers/builtin/discord.js +52 -9
- package/dist/src/providers/builtin/discord.js.map +1 -1
- package/dist/src/providers/builtin/external-webhook-auth.d.ts +1 -0
- package/dist/src/providers/builtin/external-webhook-auth.js +38 -1
- package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -1
- package/dist/src/providers/builtin/feishu.d.ts +1 -0
- package/dist/src/providers/builtin/feishu.js +96 -26
- package/dist/src/providers/builtin/feishu.js.map +1 -1
- package/dist/src/providers/builtin/googlechat.d.ts +1 -0
- package/dist/src/providers/builtin/googlechat.js +95 -26
- package/dist/src/providers/builtin/googlechat.js.map +1 -1
- package/dist/src/providers/builtin/imessage.js +60 -17
- package/dist/src/providers/builtin/imessage.js.map +1 -1
- package/dist/src/providers/builtin/loopback.js +88 -35
- package/dist/src/providers/builtin/loopback.js.map +1 -1
- package/dist/src/providers/builtin/matrix.d.ts +2 -2
- package/dist/src/providers/builtin/matrix.js +78 -21
- package/dist/src/providers/builtin/matrix.js.map +1 -1
- package/dist/src/providers/builtin/mattermost.d.ts +11 -7
- package/dist/src/providers/builtin/mattermost.js +138 -24
- package/dist/src/providers/builtin/mattermost.js.map +1 -1
- package/dist/src/providers/builtin/msteams.d.ts +1 -0
- package/dist/src/providers/builtin/msteams.js +118 -38
- package/dist/src/providers/builtin/msteams.js.map +1 -1
- package/dist/src/providers/builtin/native-local-mock.js +4 -4
- package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
- package/dist/src/providers/builtin/script.js +1057 -146
- package/dist/src/providers/builtin/script.js.map +1 -1
- package/dist/src/providers/builtin/slack.d.ts +8 -1
- package/dist/src/providers/builtin/slack.js +327 -24
- package/dist/src/providers/builtin/slack.js.map +1 -1
- package/dist/src/providers/builtin/telegram.d.ts +1 -1
- package/dist/src/providers/builtin/telegram.js +55 -14
- package/dist/src/providers/builtin/telegram.js.map +1 -1
- package/dist/src/providers/builtin/whatsapp.d.ts +4 -3
- package/dist/src/providers/builtin/whatsapp.js +157 -29
- package/dist/src/providers/builtin/whatsapp.js.map +1 -1
- package/dist/src/providers/builtin/zalo.d.ts +5 -2
- package/dist/src/providers/builtin/zalo.js +31 -7
- package/dist/src/providers/builtin/zalo.js.map +1 -1
- package/dist/src/providers/catalog.d.ts +1 -1
- package/dist/src/providers/catalog.js +1 -1
- package/dist/src/providers/catalog.js.map +1 -1
- package/dist/src/providers/local-mock.d.ts +4 -0
- package/dist/src/providers/local-mock.js +162 -35
- package/dist/src/providers/local-mock.js.map +1 -1
- package/dist/src/providers/native-ids.d.ts +2 -0
- package/dist/src/providers/native-ids.js +3 -0
- package/dist/src/providers/native-ids.js.map +1 -1
- package/dist/src/providers/recorder.d.ts +14 -3
- package/dist/src/providers/recorder.js +532 -42
- package/dist/src/providers/recorder.js.map +1 -1
- package/dist/src/providers/registry.d.ts +1 -0
- package/dist/src/providers/registry.js +65 -20
- package/dist/src/providers/registry.js.map +1 -1
- package/dist/src/providers/signed-jwt.d.ts +6 -1
- package/dist/src/providers/signed-jwt.js +241 -50
- package/dist/src/providers/signed-jwt.js.map +1 -1
- package/dist/src/providers/slack-ids.d.ts +1 -0
- package/dist/src/providers/slack-ids.js +5 -0
- package/dist/src/providers/slack-ids.js.map +1 -1
- package/dist/src/providers/target-normalizers.d.ts +9 -1
- package/dist/src/providers/target-normalizers.js +177 -58
- package/dist/src/providers/target-normalizers.js.map +1 -1
- package/dist/src/providers/webhook-server.d.ts +3 -0
- package/dist/src/providers/webhook-server.js +268 -47
- package/dist/src/providers/webhook-server.js.map +1 -1
- package/dist/src/servers/http.d.ts +14 -2
- package/dist/src/servers/http.js +229 -58
- package/dist/src/servers/http.js.map +1 -1
- package/dist/src/servers/matrix.d.ts +3 -0
- package/dist/src/servers/matrix.js +268 -110
- package/dist/src/servers/matrix.js.map +1 -1
- package/dist/src/servers/mattermost.d.ts +5 -0
- package/dist/src/servers/mattermost.js +389 -91
- package/dist/src/servers/mattermost.js.map +1 -1
- package/dist/src/servers/recorder.d.ts +11 -0
- package/dist/src/servers/recorder.js +1241 -22
- package/dist/src/servers/recorder.js.map +1 -1
- package/dist/src/servers/signal.d.ts +1 -0
- package/dist/src/servers/signal.js +279 -44
- package/dist/src/servers/signal.js.map +1 -1
- package/dist/src/servers/slack.d.ts +15 -0
- package/dist/src/servers/slack.js +259 -51
- package/dist/src/servers/slack.js.map +1 -1
- package/dist/src/servers/telegram-identity.d.ts +6 -0
- package/dist/src/servers/telegram-identity.js +27 -0
- package/dist/src/servers/telegram-identity.js.map +1 -0
- package/dist/src/servers/telegram.d.ts +17 -6
- package/dist/src/servers/telegram.js +1193 -118
- package/dist/src/servers/telegram.js.map +1 -1
- package/dist/src/servers/webhook-target.d.ts +12 -4
- package/dist/src/servers/webhook-target.js +226 -28
- package/dist/src/servers/webhook-target.js.map +1 -1
- package/dist/src/servers/whatsapp-baileys-websocket.d.ts +60 -1
- package/dist/src/servers/whatsapp-baileys-websocket.js +782 -112
- package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
- package/dist/src/servers/whatsapp-jid.d.ts +1 -0
- package/dist/src/servers/whatsapp-jid.js +9 -5
- package/dist/src/servers/whatsapp-jid.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/binary-node.d.ts +1 -0
- package/dist/src/servers/whatsapp-wire/binary-node.js +37 -13
- package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/crypto.d.ts +3 -0
- package/dist/src/servers/whatsapp-wire/crypto.js +23 -8
- package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/handshake.d.ts +9 -3
- package/dist/src/servers/whatsapp-wire/handshake.js +173 -12
- package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
- package/dist/src/servers/whatsapp-wire/signal.js +3 -3
- package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
- package/dist/src/servers/whatsapp.d.ts +7 -0
- package/dist/src/servers/whatsapp.js +149 -24
- package/dist/src/servers/whatsapp.js.map +1 -1
- package/dist/src/servers/zalo.d.ts +1 -0
- package/dist/src/servers/zalo.js +193 -82
- package/dist/src/servers/zalo.js.map +1 -1
- package/docs/channel-setup.md +185 -43
- package/fixtures/examples/crabline.example.yaml +3 -2
- package/package.json +18 -10
- package/fixtures/examples/openclaw-bridge.yaml +0 -125
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const WHATSAPP_USER_JID_RE = /^(\d{7,15})(?::(\d+))?@(c\.us|lid|s\.whatsapp\.net)$/iu;
|
|
1
|
+
const WHATSAPP_USER_JID_RE = /^(\d{7,15})(?:_(\d+))?(?::(\d+))?@(c\.us|lid|s\.whatsapp\.net)$/iu;
|
|
2
2
|
const WHATSAPP_GROUP_JID_RE = /^(\d{5,20}(?:-\d{5,20})?)@g\.us$/iu;
|
|
3
3
|
export function canonicalizeWhatsAppUserJid(value) {
|
|
4
4
|
const match = WHATSAPP_USER_JID_RE.exec(value.trim());
|
|
@@ -6,10 +6,11 @@ export function canonicalizeWhatsAppUserJid(value) {
|
|
|
6
6
|
return undefined;
|
|
7
7
|
}
|
|
8
8
|
const user = match[1];
|
|
9
|
-
const
|
|
10
|
-
const
|
|
9
|
+
const agent = match[2];
|
|
10
|
+
const device = match[3];
|
|
11
|
+
const rawServer = match[4].toLowerCase();
|
|
11
12
|
const server = rawServer === "c.us" ? "s.whatsapp.net" : rawServer;
|
|
12
|
-
return `${user}${device === undefined ? "" : `:${device}`}@${server}`;
|
|
13
|
+
return `${user}${agent === undefined ? "" : `_${agent}`}${device === undefined ? "" : `:${device}`}@${server}`;
|
|
13
14
|
}
|
|
14
15
|
export function canonicalizeWhatsAppUserCorrelationJid(value) {
|
|
15
16
|
const jid = canonicalizeWhatsAppUserJid(value);
|
|
@@ -17,7 +18,7 @@ export function canonicalizeWhatsAppUserCorrelationJid(value) {
|
|
|
17
18
|
return undefined;
|
|
18
19
|
}
|
|
19
20
|
const separator = jid.lastIndexOf("@");
|
|
20
|
-
return `${jid.slice(0, separator).split(
|
|
21
|
+
return `${jid.slice(0, separator).split(/[_:]/u, 1)[0]}@${jid.slice(separator + 1)}`;
|
|
21
22
|
}
|
|
22
23
|
export function canonicalizeWhatsAppGroupJid(value) {
|
|
23
24
|
const match = WHATSAPP_GROUP_JID_RE.exec(value.trim());
|
|
@@ -26,6 +27,9 @@ export function canonicalizeWhatsAppGroupJid(value) {
|
|
|
26
27
|
export function canonicalizeWhatsAppChatJid(value) {
|
|
27
28
|
return canonicalizeWhatsAppUserJid(value) ?? canonicalizeWhatsAppGroupJid(value);
|
|
28
29
|
}
|
|
30
|
+
export function canonicalizeWhatsAppChatCorrelationJid(value) {
|
|
31
|
+
return canonicalizeWhatsAppUserCorrelationJid(value) ?? canonicalizeWhatsAppGroupJid(value);
|
|
32
|
+
}
|
|
29
33
|
export function isWhatsAppGroupJid(value) {
|
|
30
34
|
return canonicalizeWhatsAppGroupJid(value) !== undefined;
|
|
31
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp-jid.js","sourceRoot":"","sources":["../../../src/servers/whatsapp-jid.ts"],"names":[],"mappings":"AAAA,MAAM,oBAAoB,GAAG,
|
|
1
|
+
{"version":3,"file":"whatsapp-jid.js","sourceRoot":"","sources":["../../../src/servers/whatsapp-jid.ts"],"names":[],"mappings":"AAAA,MAAM,oBAAoB,GAAG,mEAAmE,CAAC;AACjG,MAAM,qBAAqB,GAAG,oCAAoC,CAAC;AAEnE,MAAM,UAAU,2BAA2B,CAAC,KAAa;IACvD,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;IACvB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,OAAO,GAAG,IAAI,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,GACrD,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,EACxC,IAAI,MAAM,EAAE,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sCAAsC,CAAC,KAAa;IAClE,MAAM,GAAG,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACvC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,KAAa;IACxD,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAa;IACvD,OAAO,2BAA2B,CAAC,KAAK,CAAC,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,sCAAsC,CAAC,KAAa;IAClE,OAAO,sCAAsC,CAAC,KAAK,CAAC,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;AAC9F,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,4BAA4B,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;AAC3D,CAAC","sourcesContent":["const WHATSAPP_USER_JID_RE = /^(\\d{7,15})(?:_(\\d+))?(?::(\\d+))?@(c\\.us|lid|s\\.whatsapp\\.net)$/iu;\nconst WHATSAPP_GROUP_JID_RE = /^(\\d{5,20}(?:-\\d{5,20})?)@g\\.us$/iu;\n\nexport function canonicalizeWhatsAppUserJid(value: string): string | undefined {\n const match = WHATSAPP_USER_JID_RE.exec(value.trim());\n if (!match) {\n return undefined;\n }\n const user = match[1]!;\n const agent = match[2];\n const device = match[3];\n const rawServer = match[4]!.toLowerCase();\n const server = rawServer === \"c.us\" ? \"s.whatsapp.net\" : rawServer;\n return `${user}${agent === undefined ? \"\" : `_${agent}`}${\n device === undefined ? \"\" : `:${device}`\n }@${server}`;\n}\n\nexport function canonicalizeWhatsAppUserCorrelationJid(value: string): string | undefined {\n const jid = canonicalizeWhatsAppUserJid(value);\n if (!jid) {\n return undefined;\n }\n const separator = jid.lastIndexOf(\"@\");\n return `${jid.slice(0, separator).split(/[_:]/u, 1)[0]}@${jid.slice(separator + 1)}`;\n}\n\nexport function canonicalizeWhatsAppGroupJid(value: string): string | undefined {\n const match = WHATSAPP_GROUP_JID_RE.exec(value.trim());\n return match ? `${match[1]}@g.us` : undefined;\n}\n\nexport function canonicalizeWhatsAppChatJid(value: string): string | undefined {\n return canonicalizeWhatsAppUserJid(value) ?? canonicalizeWhatsAppGroupJid(value);\n}\n\nexport function canonicalizeWhatsAppChatCorrelationJid(value: string): string | undefined {\n return canonicalizeWhatsAppUserCorrelationJid(value) ?? canonicalizeWhatsAppGroupJid(value);\n}\n\nexport function isWhatsAppGroupJid(value: string): boolean {\n return canonicalizeWhatsAppGroupJid(value) !== undefined;\n}\n"]}
|
|
@@ -6,6 +6,7 @@ export type BinaryNode = {
|
|
|
6
6
|
};
|
|
7
7
|
export declare const WHATSAPP_BINARY_NODE_MAX_COMPRESSED_BYTES: number;
|
|
8
8
|
export declare const WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES: number;
|
|
9
|
+
export declare const WHATSAPP_BINARY_NODE_MAX_FRAME_BYTES: number;
|
|
9
10
|
export declare const WHATSAPP_BINARY_NODE_MAX_DEPTH = 128;
|
|
10
11
|
export declare const WHATSAPP_BINARY_NODE_MAX_NODES = 32768;
|
|
11
12
|
export declare const WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS = 131072;
|
|
@@ -2,6 +2,7 @@ import { Buffer } from "node:buffer";
|
|
|
2
2
|
import { inflate } from "node:zlib";
|
|
3
3
|
export const WHATSAPP_BINARY_NODE_MAX_COMPRESSED_BYTES = 1024 * 1024;
|
|
4
4
|
export const WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES = 8 * 1024 * 1024;
|
|
5
|
+
export const WHATSAPP_BINARY_NODE_MAX_FRAME_BYTES = WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES + 1;
|
|
5
6
|
export const WHATSAPP_BINARY_NODE_MAX_DEPTH = 128;
|
|
6
7
|
export const WHATSAPP_BINARY_NODE_MAX_NODES = 32_768;
|
|
7
8
|
export const WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS = 131_072;
|
|
@@ -134,7 +135,10 @@ export async function decodeBinaryNode(frame) {
|
|
|
134
135
|
return node;
|
|
135
136
|
}
|
|
136
137
|
export function encodeBinaryNode(node) {
|
|
137
|
-
return Buffer.from(encodeBinaryNodeInner(node, [0], 1
|
|
138
|
+
return Buffer.from(encodeBinaryNodeInner(node, [0], 1, {
|
|
139
|
+
listItems: 0,
|
|
140
|
+
nodes: 0,
|
|
141
|
+
}));
|
|
138
142
|
}
|
|
139
143
|
async function decompressIfRequired(buffer) {
|
|
140
144
|
if (buffer.length === 0) {
|
|
@@ -142,11 +146,11 @@ async function decompressIfRequired(buffer) {
|
|
|
142
146
|
}
|
|
143
147
|
const flag = buffer.readUInt8();
|
|
144
148
|
if ((flag & 2) !== 0) {
|
|
145
|
-
|
|
146
|
-
|
|
149
|
+
const compressed = buffer.subarray(1);
|
|
150
|
+
if (compressed.length > WHATSAPP_BINARY_NODE_MAX_COMPRESSED_BYTES) {
|
|
151
|
+
throw new Error(`Compressed WhatsApp binary node frame is too large: ${compressed.length}.`);
|
|
147
152
|
}
|
|
148
153
|
try {
|
|
149
|
-
const compressed = buffer.subarray(1);
|
|
150
154
|
const inflated = await inflateWithInfo(compressed);
|
|
151
155
|
if (inflated.engine.bytesWritten !== compressed.length) {
|
|
152
156
|
throw new Error("Compressed WhatsApp binary node frame contains trailing data.");
|
|
@@ -355,13 +359,15 @@ function decodeDecompressedBinaryNode(buffer, indexRef, depth, budget) {
|
|
|
355
359
|
const user = readString(readByte());
|
|
356
360
|
const device = readInt(2);
|
|
357
361
|
const integrator = readInt(2);
|
|
358
|
-
|
|
359
|
-
let server = "interop";
|
|
362
|
+
let server;
|
|
360
363
|
try {
|
|
361
364
|
server = readString(readByte());
|
|
362
365
|
}
|
|
363
|
-
catch {
|
|
364
|
-
|
|
366
|
+
catch (error) {
|
|
367
|
+
throw new Error("Invalid WhatsApp interop JID server.", { cause: error });
|
|
368
|
+
}
|
|
369
|
+
if (server !== "interop") {
|
|
370
|
+
throw new Error(`Invalid WhatsApp interop JID server: ${server}.`);
|
|
365
371
|
}
|
|
366
372
|
return `${integrator}-${user}:${device}@${server}`;
|
|
367
373
|
};
|
|
@@ -402,10 +408,14 @@ function decodeDecompressedBinaryNode(buffer, indexRef, depth, budget) {
|
|
|
402
408
|
}
|
|
403
409
|
return content === undefined ? { attrs, tag } : { attrs, content, tag };
|
|
404
410
|
}
|
|
405
|
-
function encodeBinaryNodeInner(node, buffer, depth) {
|
|
411
|
+
function encodeBinaryNodeInner(node, buffer, depth, budget) {
|
|
406
412
|
if (depth > WHATSAPP_BINARY_NODE_MAX_DEPTH) {
|
|
407
413
|
throw new Error(`WhatsApp binary node nesting exceeds ${WHATSAPP_BINARY_NODE_MAX_DEPTH}.`);
|
|
408
414
|
}
|
|
415
|
+
budget.nodes += 1;
|
|
416
|
+
if (budget.nodes > WHATSAPP_BINARY_NODE_MAX_NODES) {
|
|
417
|
+
throw new Error(`WhatsApp binary node count exceeds ${WHATSAPP_BINARY_NODE_MAX_NODES}.`);
|
|
418
|
+
}
|
|
409
419
|
if (!node.tag) {
|
|
410
420
|
throw new Error("Invalid WhatsApp binary node: tag is required.");
|
|
411
421
|
}
|
|
@@ -413,7 +423,7 @@ function encodeBinaryNodeInner(node, buffer, depth) {
|
|
|
413
423
|
const value = node.attrs[key];
|
|
414
424
|
return value !== undefined && value !== null;
|
|
415
425
|
});
|
|
416
|
-
|
|
426
|
+
writeBudgetedListStart(buffer, 2 * validAttributes.length + 1 + (node.content !== undefined ? 1 : 0), budget);
|
|
417
427
|
writeString(buffer, node.tag);
|
|
418
428
|
for (const key of validAttributes) {
|
|
419
429
|
writeString(buffer, key);
|
|
@@ -427,9 +437,9 @@ function encodeBinaryNodeInner(node, buffer, depth) {
|
|
|
427
437
|
pushBytes(buffer, node.content);
|
|
428
438
|
}
|
|
429
439
|
else if (Array.isArray(node.content)) {
|
|
430
|
-
|
|
440
|
+
writeBudgetedListStart(buffer, node.content.length, budget);
|
|
431
441
|
for (const child of node.content) {
|
|
432
|
-
encodeBinaryNodeInner(child, buffer, depth + 1);
|
|
442
|
+
encodeBinaryNodeInner(child, buffer, depth + 1, budget);
|
|
433
443
|
}
|
|
434
444
|
}
|
|
435
445
|
else if (node.content !== undefined) {
|
|
@@ -437,12 +447,26 @@ function encodeBinaryNodeInner(node, buffer, depth) {
|
|
|
437
447
|
}
|
|
438
448
|
return buffer;
|
|
439
449
|
}
|
|
450
|
+
function writeBudgetedListStart(buffer, size, budget) {
|
|
451
|
+
budget.listItems += size;
|
|
452
|
+
if (budget.listItems > WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS) {
|
|
453
|
+
throw new Error(`WhatsApp binary node list items exceed ${WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS}.`);
|
|
454
|
+
}
|
|
455
|
+
writeListStart(buffer, size);
|
|
456
|
+
}
|
|
440
457
|
function pushByte(buffer, value) {
|
|
458
|
+
assertEncodedCapacity(buffer, 1);
|
|
441
459
|
buffer.push(value & 0xff);
|
|
442
460
|
}
|
|
443
461
|
function pushBytes(buffer, bytes) {
|
|
462
|
+
assertEncodedCapacity(buffer, bytes.length);
|
|
444
463
|
for (const byte of bytes) {
|
|
445
|
-
|
|
464
|
+
buffer.push(byte & 0xff);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
function assertEncodedCapacity(buffer, additionalBytes) {
|
|
468
|
+
if (buffer.length + additionalBytes > WHATSAPP_BINARY_NODE_MAX_FRAME_BYTES) {
|
|
469
|
+
throw new Error(`WhatsApp binary node frame exceeds ${WHATSAPP_BINARY_NODE_MAX_FRAME_BYTES} bytes.`);
|
|
446
470
|
}
|
|
447
471
|
}
|
|
448
472
|
function pushInt(buffer, value, length) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary-node.js","sourceRoot":"","sources":["../../../../src/servers/whatsapp-wire/binary-node.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { inflate } from \"node:zlib\";\n\nexport type BinaryNode = {\n attrs: Record<string, string>;\n content?: BinaryNode[] | string | Uint8Array;\n tag: string;\n};\n\nexport const WHATSAPP_BINARY_NODE_MAX_COMPRESSED_BYTES = 1024 * 1024;\nexport const WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES = 8 * 1024 * 1024;\nexport const WHATSAPP_BINARY_NODE_MAX_DEPTH = 128;\nexport const WHATSAPP_BINARY_NODE_MAX_NODES = 32_768;\nexport const WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS = 131_072;\n\ntype DecodeBudget = {\n listItems: number;\n nodes: number;\n};\n\nfunction inflateWithInfo(\n buffer: Uint8Array,\n): Promise<{ buffer: Buffer; engine: { bytesWritten: number } }> {\n return new Promise((resolve, reject) => {\n inflate(\n buffer,\n { info: true, maxOutputLength: WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES },\n (error, result) => {\n if (error) {\n reject(error);\n } else {\n resolve(result as unknown as { buffer: Buffer; engine: { bytesWritten: number } });\n }\n },\n );\n });\n}\n\nconst TAGS = {\n AD_JID: 247,\n BINARY_8: 252,\n BINARY_20: 253,\n BINARY_32: 254,\n DICTIONARY_0: 236,\n DICTIONARY_1: 237,\n DICTIONARY_2: 238,\n DICTIONARY_3: 239,\n FB_JID: 246,\n HEX_8: 251,\n INTEROP_JID: 245,\n JID_PAIR: 250,\n LIST_8: 248,\n LIST_16: 249,\n LIST_EMPTY: 0,\n NIBBLE_8: 255,\n PACKED_MAX: 127,\n} as const;\n\n// Minimal WhatsApp binary token dictionary for the nodes this local server handles.\nconst SINGLE_BYTE_TOKENS: Readonly<Record<number, string>> = {\n 3: \"s.whatsapp.net\",\n 4: \"type\",\n 5: \"participant\",\n 6: \"from\",\n 7: \"receipt\",\n 8: \"id\",\n 12: \"jid\",\n 14: \"user\",\n 15: \"devices\",\n 17: \"to\",\n 18: \"offline\",\n 19: \"message\",\n 20: \"result\",\n 21: \"class\",\n 22: \"xmlns\",\n 25: \"iq\",\n 26: \"t\",\n 27: \"ack\",\n 28: \"g.us\",\n 29: \"enc\",\n 31: \"presence\",\n 41: \"get\",\n 45: \"0\",\n 48: \"unavailable\",\n 56: \"text\",\n 58: \"media_conn\",\n 65: \"count\",\n 69: \"2\",\n 70: \"hostname\",\n 76: \"success\",\n 79: \"prop\",\n 81: \"v\",\n 83: \"pkmsg\",\n 84: \"version\",\n 90: \"set\",\n 92: \"props\",\n 95: \"hash\",\n 97: \"last\",\n 106: \"mode\",\n 107: \"participants\",\n 108: \"value\",\n 109: \"query\",\n 113: \"list\",\n 114: \"host\",\n 118: \"lid\",\n 121: \"usync\",\n 125: \"context\",\n 137: \"name\",\n 143: \"index\",\n 155: \"true\",\n 156: \"identity\",\n 158: \"key\",\n 160: \"background\",\n 169: \"auth\",\n 173: \"registration\",\n 189: \"ttl\",\n 194: \"w:m\",\n 197: \"token\",\n 198: \"inactive\",\n 203: \"encrypt\",\n 212: \"signature\",\n 217: \"trusted_contact\",\n 226: \"privacy\",\n 230: \"device-identity\",\n};\n\nconst DOUBLE_BYTE_TOKENS: Readonly<Record<number, Readonly<Record<number, string>>>> = {\n 0: {\n 1: \"active\",\n 15: \"false\",\n 24: \"passive\",\n 45: \"skey\",\n 46: \"reason\",\n 68: \"tokens\",\n 127: \"subject\",\n 170: \"group\",\n 217: \"blocklist\",\n 238: \"s_t\",\n },\n 1: {\n 51: \"w:g2\",\n },\n};\n\nexport const S_WHATSAPP_NET = \"@s.whatsapp.net\";\n\nexport async function decodeBinaryNode(frame: Buffer): Promise<BinaryNode> {\n const buffer = await decompressIfRequired(frame);\n const indexRef = { index: 0 };\n const node = decodeDecompressedBinaryNode(buffer, indexRef, 1, {\n listItems: 0,\n nodes: 0,\n });\n if (indexRef.index !== buffer.length) {\n throw new Error(\"WhatsApp binary node frame contains trailing data.\");\n }\n return node;\n}\n\nexport function encodeBinaryNode(node: BinaryNode): Buffer {\n return Buffer.from(encodeBinaryNodeInner(node, [0], 1));\n}\n\nasync function decompressIfRequired(buffer: Buffer): Promise<Buffer> {\n if (buffer.length === 0) {\n throw new Error(\"Cannot decode an empty WhatsApp binary node.\");\n }\n const flag = buffer.readUInt8();\n if ((flag & 2) !== 0) {\n if (buffer.length > WHATSAPP_BINARY_NODE_MAX_COMPRESSED_BYTES) {\n throw new Error(`Compressed WhatsApp binary node frame is too large: ${buffer.length}.`);\n }\n try {\n const compressed = buffer.subarray(1);\n const inflated = await inflateWithInfo(compressed);\n if (inflated.engine.bytesWritten !== compressed.length) {\n throw new Error(\"Compressed WhatsApp binary node frame contains trailing data.\");\n }\n return inflated.buffer;\n } catch (error) {\n if (\n error instanceof RangeError ||\n (error instanceof Error && (error as NodeJS.ErrnoException).code === \"ERR_BUFFER_TOO_LARGE\")\n ) {\n throw new Error(\n `WhatsApp binary node expands beyond ${WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES} bytes.`,\n { cause: error },\n );\n }\n throw error;\n }\n }\n const payload = buffer.subarray(1);\n if (payload.length > WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES) {\n throw new Error(`WhatsApp binary node payload is too large: ${payload.length}.`);\n }\n return payload;\n}\n\nfunction decodeDecompressedBinaryNode(\n buffer: Buffer,\n indexRef: { index: number },\n depth: number,\n budget: DecodeBudget,\n): BinaryNode {\n if (depth > WHATSAPP_BINARY_NODE_MAX_DEPTH) {\n throw new Error(`WhatsApp binary node nesting exceeds ${WHATSAPP_BINARY_NODE_MAX_DEPTH}.`);\n }\n budget.nodes += 1;\n if (budget.nodes > WHATSAPP_BINARY_NODE_MAX_NODES) {\n throw new Error(`WhatsApp binary node count exceeds ${WHATSAPP_BINARY_NODE_MAX_NODES}.`);\n }\n const checkEOS = (length: number) => {\n if (!Number.isSafeInteger(length) || length < 0 || length > buffer.length - indexRef.index) {\n throw new Error(\"Unexpected end of WhatsApp binary node.\");\n }\n };\n const next = () => {\n const value = buffer[indexRef.index];\n indexRef.index += 1;\n if (value === undefined) {\n throw new Error(\"Unexpected end of WhatsApp binary node.\");\n }\n return value;\n };\n const readByte = () => {\n checkEOS(1);\n return next();\n };\n const readBytes = (length: number) => {\n checkEOS(length);\n const value = buffer.subarray(indexRef.index, indexRef.index + length);\n indexRef.index += length;\n return value;\n };\n const readInt = (length: number, littleEndian = false) => {\n checkEOS(length);\n let value = 0;\n for (let index = 0; index < length; index += 1) {\n const byte = next();\n value = littleEndian ? value + byte * 256 ** index : value * 256 + byte;\n }\n return value;\n };\n const readInt20 = () => {\n checkEOS(3);\n return ((next() & 15) << 16) + (next() << 8) + next();\n };\n const readStringFromChars = (length: number) => readBytes(length).toString(\"utf8\");\n const unpackHex = (value: number) => {\n if (value >= 0 && value < 16) {\n return value < 10 ? \"0\".charCodeAt(0) + value : \"A\".charCodeAt(0) + value - 10;\n }\n throw new Error(`Invalid WhatsApp hex token: ${value}.`);\n };\n const unpackNibble = (value: number) => {\n if (value >= 0 && value <= 9) {\n return \"0\".charCodeAt(0) + value;\n }\n if (value === 10) {\n return \"-\".charCodeAt(0);\n }\n if (value === 11) {\n return \".\".charCodeAt(0);\n }\n if (value === 15) {\n return \"\\0\".charCodeAt(0);\n }\n throw new Error(`Invalid WhatsApp nibble token: ${value}.`);\n };\n const unpackByte = (tag: number, value: number) => {\n if (tag === TAGS.NIBBLE_8) {\n return unpackNibble(value);\n }\n if (tag === TAGS.HEX_8) {\n return unpackHex(value);\n }\n throw new Error(`Unknown WhatsApp packed string tag: ${tag}.`);\n };\n const readPacked8 = (tag: number) => {\n const startByte = readByte();\n let value = \"\";\n for (let index = 0; index < (startByte & 127); index += 1) {\n const current = readByte();\n value += String.fromCharCode(unpackByte(tag, (current & 0xf0) >> 4));\n value += String.fromCharCode(unpackByte(tag, current & 0x0f));\n }\n return startByte >> 7 !== 0 ? value.slice(0, -1) : value;\n };\n const readListSize = (tag: number) => {\n let size: number;\n if (tag === TAGS.LIST_EMPTY) {\n size = 0;\n } else if (tag === TAGS.LIST_8) {\n size = readByte();\n } else if (tag === TAGS.LIST_16) {\n size = readInt(2);\n } else {\n throw new Error(`Invalid WhatsApp list tag: ${tag}.`);\n }\n budget.listItems += size;\n if (budget.listItems > WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS) {\n throw new Error(\n `WhatsApp binary node list items exceed ${WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS}.`,\n );\n }\n return size;\n };\n const isListTag = (tag: number) =>\n tag === TAGS.LIST_EMPTY || tag === TAGS.LIST_8 || tag === TAGS.LIST_16;\n const readString = (tag: number): string => {\n const token = SINGLE_BYTE_TOKENS[tag];\n if (token !== undefined) {\n return token;\n }\n if (tag >= 1 && tag < 236) {\n throw new Error(`Unsupported WhatsApp single-byte token: ${tag}.`);\n }\n if (\n tag === TAGS.DICTIONARY_0 ||\n tag === TAGS.DICTIONARY_1 ||\n tag === TAGS.DICTIONARY_2 ||\n tag === TAGS.DICTIONARY_3\n ) {\n return readDoubleToken(tag - TAGS.DICTIONARY_0, readByte());\n }\n if (tag === TAGS.LIST_EMPTY) {\n return \"\";\n }\n if (tag === TAGS.BINARY_8) {\n return readStringFromChars(readByte());\n }\n if (tag === TAGS.BINARY_20) {\n return readStringFromChars(readInt20());\n }\n if (tag === TAGS.BINARY_32) {\n return readStringFromChars(readInt(4));\n }\n if (tag === TAGS.JID_PAIR) {\n return readJidPair();\n }\n if (tag === TAGS.FB_JID) {\n return readFbJid();\n }\n if (tag === TAGS.INTEROP_JID) {\n return readInteropJid();\n }\n if (tag === TAGS.AD_JID) {\n return readAdJid();\n }\n if (tag === TAGS.HEX_8 || tag === TAGS.NIBBLE_8) {\n return readPacked8(tag);\n }\n throw new Error(`Invalid WhatsApp string tag: ${tag}.`);\n };\n const readList = (tag: number) => {\n const items: BinaryNode[] = [];\n const size = readListSize(tag);\n for (let index = 0; index < size; index += 1) {\n items.push(decodeDecompressedBinaryNode(buffer, indexRef, depth + 1, budget));\n }\n return items;\n };\n const readJidPair = () => {\n const user = readString(readByte());\n const server = readString(readByte());\n if (!server) {\n throw new Error(`Invalid WhatsApp JID pair: ${user}, ${server}.`);\n }\n return `${user || \"\"}@${server}`;\n };\n const readAdJid = () => {\n const domainType = readByte();\n const device = readByte();\n const user = readString(readByte());\n const server =\n domainType === 1\n ? \"lid\"\n : domainType === 128\n ? \"hosted\"\n : domainType === 129\n ? \"hosted.lid\"\n : \"s.whatsapp.net\";\n return `${user}${device ? `:${device}` : \"\"}@${server}`;\n };\n const readFbJid = () => {\n const user = readString(readByte());\n const device = readInt(2);\n const server = readString(readByte());\n return `${user}:${device}@${server}`;\n };\n const readInteropJid = () => {\n const user = readString(readByte());\n const device = readInt(2);\n const integrator = readInt(2);\n const beforeServer = indexRef.index;\n let server = \"interop\";\n try {\n server = readString(readByte());\n } catch {\n indexRef.index = beforeServer;\n }\n return `${integrator}-${user}:${device}@${server}`;\n };\n const readDoubleToken = (dictionary: number, index: number) => {\n const value = DOUBLE_BYTE_TOKENS[dictionary]?.[index];\n if (value === undefined) {\n throw new Error(`Unsupported WhatsApp dictionary token: ${dictionary}:${index}.`);\n }\n return value;\n };\n\n const listSize = readListSize(readByte());\n const tag = readString(readByte());\n if (listSize === 0 || !tag) {\n throw new Error(\"Invalid WhatsApp binary node header.\");\n }\n const attrs = Object.create(null) as Record<string, string>;\n for (let index = 0; index < (listSize - 1) >> 1; index += 1) {\n attrs[readString(readByte())] = readString(readByte());\n }\n let content: BinaryNode[\"content\"];\n if (listSize % 2 === 0) {\n const contentTag = readByte();\n if (isListTag(contentTag)) {\n content = readList(contentTag);\n } else if (contentTag === TAGS.BINARY_8) {\n content = readBytes(readByte());\n } else if (contentTag === TAGS.BINARY_20) {\n content = readBytes(readInt20());\n } else if (contentTag === TAGS.BINARY_32) {\n content = readBytes(readInt(4));\n } else {\n content = readString(contentTag);\n }\n }\n return content === undefined ? { attrs, tag } : { attrs, content, tag };\n}\n\nfunction encodeBinaryNodeInner(node: BinaryNode, buffer: number[], depth: number): number[] {\n if (depth > WHATSAPP_BINARY_NODE_MAX_DEPTH) {\n throw new Error(`WhatsApp binary node nesting exceeds ${WHATSAPP_BINARY_NODE_MAX_DEPTH}.`);\n }\n if (!node.tag) {\n throw new Error(\"Invalid WhatsApp binary node: tag is required.\");\n }\n const validAttributes = Object.keys(node.attrs ?? {}).filter((key) => {\n const value = node.attrs[key];\n return value !== undefined && value !== null;\n });\n writeListStart(buffer, 2 * validAttributes.length + 1 + (node.content !== undefined ? 1 : 0));\n writeString(buffer, node.tag);\n for (const key of validAttributes) {\n writeString(buffer, key);\n writeString(buffer, node.attrs[key] ?? \"\");\n }\n if (typeof node.content === \"string\") {\n writeString(buffer, node.content);\n } else if (node.content instanceof Uint8Array) {\n writeByteLength(buffer, node.content.length);\n pushBytes(buffer, node.content);\n } else if (Array.isArray(node.content)) {\n writeListStart(buffer, node.content.length);\n for (const child of node.content) {\n encodeBinaryNodeInner(child, buffer, depth + 1);\n }\n } else if (node.content !== undefined) {\n throw new Error(`Invalid WhatsApp binary node content for <${node.tag}>.`);\n }\n return buffer;\n}\n\nfunction pushByte(buffer: number[], value: number): void {\n buffer.push(value & 0xff);\n}\n\nfunction pushBytes(buffer: number[], bytes: Uint8Array): void {\n for (const byte of bytes) {\n pushByte(buffer, byte);\n }\n}\n\nfunction pushInt(buffer: number[], value: number, length: number): void {\n for (let index = 0; index < length; index += 1) {\n const shift = length - 1 - index;\n pushByte(buffer, value >> (shift * 8));\n }\n}\n\nfunction writeByteLength(buffer: number[], length: number): void {\n if (length >= 4294967296) {\n throw new Error(`WhatsApp binary node payload is too large: ${length}.`);\n }\n if (length >= 1 << 20) {\n pushByte(buffer, TAGS.BINARY_32);\n pushInt(buffer, length, 4);\n return;\n }\n if (length >= 256) {\n pushByte(buffer, TAGS.BINARY_20);\n pushByte(buffer, (length >> 16) & 0x0f);\n pushByte(buffer, length >> 8);\n pushByte(buffer, length);\n return;\n }\n pushByte(buffer, TAGS.BINARY_8);\n pushByte(buffer, length);\n}\n\nfunction writeString(buffer: number[], value: string): void {\n const bytes = Buffer.from(value, \"utf8\");\n writeByteLength(buffer, bytes.length);\n pushBytes(buffer, bytes);\n}\n\nfunction writeListStart(buffer: number[], size: number): void {\n if (!Number.isSafeInteger(size) || size < 0 || size > 0xffff) {\n throw new Error(`WhatsApp binary node list is too large: ${size}.`);\n }\n if (size === 0) {\n pushByte(buffer, TAGS.LIST_EMPTY);\n return;\n }\n if (size < 256) {\n pushByte(buffer, TAGS.LIST_8);\n pushByte(buffer, size);\n return;\n }\n pushByte(buffer, TAGS.LIST_16);\n pushInt(buffer, size, 2);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"binary-node.js","sourceRoot":"","sources":["../../../../src/servers/whatsapp-wire/binary-node.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport { inflate } from \"node:zlib\";\n\nexport type BinaryNode = {\n attrs: Record<string, string>;\n content?: BinaryNode[] | string | Uint8Array;\n tag: string;\n};\n\nexport const WHATSAPP_BINARY_NODE_MAX_COMPRESSED_BYTES = 1024 * 1024;\nexport const WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES = 8 * 1024 * 1024;\nexport const WHATSAPP_BINARY_NODE_MAX_FRAME_BYTES = WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES + 1;\nexport const WHATSAPP_BINARY_NODE_MAX_DEPTH = 128;\nexport const WHATSAPP_BINARY_NODE_MAX_NODES = 32_768;\nexport const WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS = 131_072;\n\ntype BinaryNodeBudget = {\n listItems: number;\n nodes: number;\n};\n\nfunction inflateWithInfo(\n buffer: Uint8Array,\n): Promise<{ buffer: Buffer; engine: { bytesWritten: number } }> {\n return new Promise((resolve, reject) => {\n inflate(\n buffer,\n { info: true, maxOutputLength: WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES },\n (error, result) => {\n if (error) {\n reject(error);\n } else {\n resolve(result as unknown as { buffer: Buffer; engine: { bytesWritten: number } });\n }\n },\n );\n });\n}\n\nconst TAGS = {\n AD_JID: 247,\n BINARY_8: 252,\n BINARY_20: 253,\n BINARY_32: 254,\n DICTIONARY_0: 236,\n DICTIONARY_1: 237,\n DICTIONARY_2: 238,\n DICTIONARY_3: 239,\n FB_JID: 246,\n HEX_8: 251,\n INTEROP_JID: 245,\n JID_PAIR: 250,\n LIST_8: 248,\n LIST_16: 249,\n LIST_EMPTY: 0,\n NIBBLE_8: 255,\n PACKED_MAX: 127,\n} as const;\n\n// Minimal WhatsApp binary token dictionary for the nodes this local server handles.\nconst SINGLE_BYTE_TOKENS: Readonly<Record<number, string>> = {\n 3: \"s.whatsapp.net\",\n 4: \"type\",\n 5: \"participant\",\n 6: \"from\",\n 7: \"receipt\",\n 8: \"id\",\n 12: \"jid\",\n 14: \"user\",\n 15: \"devices\",\n 17: \"to\",\n 18: \"offline\",\n 19: \"message\",\n 20: \"result\",\n 21: \"class\",\n 22: \"xmlns\",\n 25: \"iq\",\n 26: \"t\",\n 27: \"ack\",\n 28: \"g.us\",\n 29: \"enc\",\n 31: \"presence\",\n 41: \"get\",\n 45: \"0\",\n 48: \"unavailable\",\n 56: \"text\",\n 58: \"media_conn\",\n 65: \"count\",\n 69: \"2\",\n 70: \"hostname\",\n 76: \"success\",\n 79: \"prop\",\n 81: \"v\",\n 83: \"pkmsg\",\n 84: \"version\",\n 90: \"set\",\n 92: \"props\",\n 95: \"hash\",\n 97: \"last\",\n 106: \"mode\",\n 107: \"participants\",\n 108: \"value\",\n 109: \"query\",\n 113: \"list\",\n 114: \"host\",\n 118: \"lid\",\n 121: \"usync\",\n 125: \"context\",\n 137: \"name\",\n 143: \"index\",\n 155: \"true\",\n 156: \"identity\",\n 158: \"key\",\n 160: \"background\",\n 169: \"auth\",\n 173: \"registration\",\n 189: \"ttl\",\n 194: \"w:m\",\n 197: \"token\",\n 198: \"inactive\",\n 203: \"encrypt\",\n 212: \"signature\",\n 217: \"trusted_contact\",\n 226: \"privacy\",\n 230: \"device-identity\",\n};\n\nconst DOUBLE_BYTE_TOKENS: Readonly<Record<number, Readonly<Record<number, string>>>> = {\n 0: {\n 1: \"active\",\n 15: \"false\",\n 24: \"passive\",\n 45: \"skey\",\n 46: \"reason\",\n 68: \"tokens\",\n 127: \"subject\",\n 170: \"group\",\n 217: \"blocklist\",\n 238: \"s_t\",\n },\n 1: {\n 51: \"w:g2\",\n },\n};\n\nexport const S_WHATSAPP_NET = \"@s.whatsapp.net\";\n\nexport async function decodeBinaryNode(frame: Buffer): Promise<BinaryNode> {\n const buffer = await decompressIfRequired(frame);\n const indexRef = { index: 0 };\n const node = decodeDecompressedBinaryNode(buffer, indexRef, 1, {\n listItems: 0,\n nodes: 0,\n });\n if (indexRef.index !== buffer.length) {\n throw new Error(\"WhatsApp binary node frame contains trailing data.\");\n }\n return node;\n}\n\nexport function encodeBinaryNode(node: BinaryNode): Buffer {\n return Buffer.from(\n encodeBinaryNodeInner(node, [0], 1, {\n listItems: 0,\n nodes: 0,\n }),\n );\n}\n\nasync function decompressIfRequired(buffer: Buffer): Promise<Buffer> {\n if (buffer.length === 0) {\n throw new Error(\"Cannot decode an empty WhatsApp binary node.\");\n }\n const flag = buffer.readUInt8();\n if ((flag & 2) !== 0) {\n const compressed = buffer.subarray(1);\n if (compressed.length > WHATSAPP_BINARY_NODE_MAX_COMPRESSED_BYTES) {\n throw new Error(`Compressed WhatsApp binary node frame is too large: ${compressed.length}.`);\n }\n try {\n const inflated = await inflateWithInfo(compressed);\n if (inflated.engine.bytesWritten !== compressed.length) {\n throw new Error(\"Compressed WhatsApp binary node frame contains trailing data.\");\n }\n return inflated.buffer;\n } catch (error) {\n if (\n error instanceof RangeError ||\n (error instanceof Error && (error as NodeJS.ErrnoException).code === \"ERR_BUFFER_TOO_LARGE\")\n ) {\n throw new Error(\n `WhatsApp binary node expands beyond ${WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES} bytes.`,\n { cause: error },\n );\n }\n throw error;\n }\n }\n const payload = buffer.subarray(1);\n if (payload.length > WHATSAPP_BINARY_NODE_MAX_DECOMPRESSED_BYTES) {\n throw new Error(`WhatsApp binary node payload is too large: ${payload.length}.`);\n }\n return payload;\n}\n\nfunction decodeDecompressedBinaryNode(\n buffer: Buffer,\n indexRef: { index: number },\n depth: number,\n budget: BinaryNodeBudget,\n): BinaryNode {\n if (depth > WHATSAPP_BINARY_NODE_MAX_DEPTH) {\n throw new Error(`WhatsApp binary node nesting exceeds ${WHATSAPP_BINARY_NODE_MAX_DEPTH}.`);\n }\n budget.nodes += 1;\n if (budget.nodes > WHATSAPP_BINARY_NODE_MAX_NODES) {\n throw new Error(`WhatsApp binary node count exceeds ${WHATSAPP_BINARY_NODE_MAX_NODES}.`);\n }\n const checkEOS = (length: number) => {\n if (!Number.isSafeInteger(length) || length < 0 || length > buffer.length - indexRef.index) {\n throw new Error(\"Unexpected end of WhatsApp binary node.\");\n }\n };\n const next = () => {\n const value = buffer[indexRef.index];\n indexRef.index += 1;\n if (value === undefined) {\n throw new Error(\"Unexpected end of WhatsApp binary node.\");\n }\n return value;\n };\n const readByte = () => {\n checkEOS(1);\n return next();\n };\n const readBytes = (length: number) => {\n checkEOS(length);\n const value = buffer.subarray(indexRef.index, indexRef.index + length);\n indexRef.index += length;\n return value;\n };\n const readInt = (length: number, littleEndian = false) => {\n checkEOS(length);\n let value = 0;\n for (let index = 0; index < length; index += 1) {\n const byte = next();\n value = littleEndian ? value + byte * 256 ** index : value * 256 + byte;\n }\n return value;\n };\n const readInt20 = () => {\n checkEOS(3);\n return ((next() & 15) << 16) + (next() << 8) + next();\n };\n const readStringFromChars = (length: number) => readBytes(length).toString(\"utf8\");\n const unpackHex = (value: number) => {\n if (value >= 0 && value < 16) {\n return value < 10 ? \"0\".charCodeAt(0) + value : \"A\".charCodeAt(0) + value - 10;\n }\n throw new Error(`Invalid WhatsApp hex token: ${value}.`);\n };\n const unpackNibble = (value: number) => {\n if (value >= 0 && value <= 9) {\n return \"0\".charCodeAt(0) + value;\n }\n if (value === 10) {\n return \"-\".charCodeAt(0);\n }\n if (value === 11) {\n return \".\".charCodeAt(0);\n }\n if (value === 15) {\n return \"\\0\".charCodeAt(0);\n }\n throw new Error(`Invalid WhatsApp nibble token: ${value}.`);\n };\n const unpackByte = (tag: number, value: number) => {\n if (tag === TAGS.NIBBLE_8) {\n return unpackNibble(value);\n }\n if (tag === TAGS.HEX_8) {\n return unpackHex(value);\n }\n throw new Error(`Unknown WhatsApp packed string tag: ${tag}.`);\n };\n const readPacked8 = (tag: number) => {\n const startByte = readByte();\n let value = \"\";\n for (let index = 0; index < (startByte & 127); index += 1) {\n const current = readByte();\n value += String.fromCharCode(unpackByte(tag, (current & 0xf0) >> 4));\n value += String.fromCharCode(unpackByte(tag, current & 0x0f));\n }\n return startByte >> 7 !== 0 ? value.slice(0, -1) : value;\n };\n const readListSize = (tag: number) => {\n let size: number;\n if (tag === TAGS.LIST_EMPTY) {\n size = 0;\n } else if (tag === TAGS.LIST_8) {\n size = readByte();\n } else if (tag === TAGS.LIST_16) {\n size = readInt(2);\n } else {\n throw new Error(`Invalid WhatsApp list tag: ${tag}.`);\n }\n budget.listItems += size;\n if (budget.listItems > WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS) {\n throw new Error(\n `WhatsApp binary node list items exceed ${WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS}.`,\n );\n }\n return size;\n };\n const isListTag = (tag: number) =>\n tag === TAGS.LIST_EMPTY || tag === TAGS.LIST_8 || tag === TAGS.LIST_16;\n const readString = (tag: number): string => {\n const token = SINGLE_BYTE_TOKENS[tag];\n if (token !== undefined) {\n return token;\n }\n if (tag >= 1 && tag < 236) {\n throw new Error(`Unsupported WhatsApp single-byte token: ${tag}.`);\n }\n if (\n tag === TAGS.DICTIONARY_0 ||\n tag === TAGS.DICTIONARY_1 ||\n tag === TAGS.DICTIONARY_2 ||\n tag === TAGS.DICTIONARY_3\n ) {\n return readDoubleToken(tag - TAGS.DICTIONARY_0, readByte());\n }\n if (tag === TAGS.LIST_EMPTY) {\n return \"\";\n }\n if (tag === TAGS.BINARY_8) {\n return readStringFromChars(readByte());\n }\n if (tag === TAGS.BINARY_20) {\n return readStringFromChars(readInt20());\n }\n if (tag === TAGS.BINARY_32) {\n return readStringFromChars(readInt(4));\n }\n if (tag === TAGS.JID_PAIR) {\n return readJidPair();\n }\n if (tag === TAGS.FB_JID) {\n return readFbJid();\n }\n if (tag === TAGS.INTEROP_JID) {\n return readInteropJid();\n }\n if (tag === TAGS.AD_JID) {\n return readAdJid();\n }\n if (tag === TAGS.HEX_8 || tag === TAGS.NIBBLE_8) {\n return readPacked8(tag);\n }\n throw new Error(`Invalid WhatsApp string tag: ${tag}.`);\n };\n const readList = (tag: number) => {\n const items: BinaryNode[] = [];\n const size = readListSize(tag);\n for (let index = 0; index < size; index += 1) {\n items.push(decodeDecompressedBinaryNode(buffer, indexRef, depth + 1, budget));\n }\n return items;\n };\n const readJidPair = () => {\n const user = readString(readByte());\n const server = readString(readByte());\n if (!server) {\n throw new Error(`Invalid WhatsApp JID pair: ${user}, ${server}.`);\n }\n return `${user || \"\"}@${server}`;\n };\n const readAdJid = () => {\n const domainType = readByte();\n const device = readByte();\n const user = readString(readByte());\n const server =\n domainType === 1\n ? \"lid\"\n : domainType === 128\n ? \"hosted\"\n : domainType === 129\n ? \"hosted.lid\"\n : \"s.whatsapp.net\";\n return `${user}${device ? `:${device}` : \"\"}@${server}`;\n };\n const readFbJid = () => {\n const user = readString(readByte());\n const device = readInt(2);\n const server = readString(readByte());\n return `${user}:${device}@${server}`;\n };\n const readInteropJid = () => {\n const user = readString(readByte());\n const device = readInt(2);\n const integrator = readInt(2);\n let server: string;\n try {\n server = readString(readByte());\n } catch (error) {\n throw new Error(\"Invalid WhatsApp interop JID server.\", { cause: error });\n }\n if (server !== \"interop\") {\n throw new Error(`Invalid WhatsApp interop JID server: ${server}.`);\n }\n return `${integrator}-${user}:${device}@${server}`;\n };\n const readDoubleToken = (dictionary: number, index: number) => {\n const value = DOUBLE_BYTE_TOKENS[dictionary]?.[index];\n if (value === undefined) {\n throw new Error(`Unsupported WhatsApp dictionary token: ${dictionary}:${index}.`);\n }\n return value;\n };\n\n const listSize = readListSize(readByte());\n const tag = readString(readByte());\n if (listSize === 0 || !tag) {\n throw new Error(\"Invalid WhatsApp binary node header.\");\n }\n const attrs = Object.create(null) as Record<string, string>;\n for (let index = 0; index < (listSize - 1) >> 1; index += 1) {\n attrs[readString(readByte())] = readString(readByte());\n }\n let content: BinaryNode[\"content\"];\n if (listSize % 2 === 0) {\n const contentTag = readByte();\n if (isListTag(contentTag)) {\n content = readList(contentTag);\n } else if (contentTag === TAGS.BINARY_8) {\n content = readBytes(readByte());\n } else if (contentTag === TAGS.BINARY_20) {\n content = readBytes(readInt20());\n } else if (contentTag === TAGS.BINARY_32) {\n content = readBytes(readInt(4));\n } else {\n content = readString(contentTag);\n }\n }\n return content === undefined ? { attrs, tag } : { attrs, content, tag };\n}\n\nfunction encodeBinaryNodeInner(\n node: BinaryNode,\n buffer: number[],\n depth: number,\n budget: BinaryNodeBudget,\n): number[] {\n if (depth > WHATSAPP_BINARY_NODE_MAX_DEPTH) {\n throw new Error(`WhatsApp binary node nesting exceeds ${WHATSAPP_BINARY_NODE_MAX_DEPTH}.`);\n }\n budget.nodes += 1;\n if (budget.nodes > WHATSAPP_BINARY_NODE_MAX_NODES) {\n throw new Error(`WhatsApp binary node count exceeds ${WHATSAPP_BINARY_NODE_MAX_NODES}.`);\n }\n if (!node.tag) {\n throw new Error(\"Invalid WhatsApp binary node: tag is required.\");\n }\n const validAttributes = Object.keys(node.attrs ?? {}).filter((key) => {\n const value = node.attrs[key];\n return value !== undefined && value !== null;\n });\n writeBudgetedListStart(\n buffer,\n 2 * validAttributes.length + 1 + (node.content !== undefined ? 1 : 0),\n budget,\n );\n writeString(buffer, node.tag);\n for (const key of validAttributes) {\n writeString(buffer, key);\n writeString(buffer, node.attrs[key] ?? \"\");\n }\n if (typeof node.content === \"string\") {\n writeString(buffer, node.content);\n } else if (node.content instanceof Uint8Array) {\n writeByteLength(buffer, node.content.length);\n pushBytes(buffer, node.content);\n } else if (Array.isArray(node.content)) {\n writeBudgetedListStart(buffer, node.content.length, budget);\n for (const child of node.content) {\n encodeBinaryNodeInner(child, buffer, depth + 1, budget);\n }\n } else if (node.content !== undefined) {\n throw new Error(`Invalid WhatsApp binary node content for <${node.tag}>.`);\n }\n return buffer;\n}\n\nfunction writeBudgetedListStart(buffer: number[], size: number, budget: BinaryNodeBudget): void {\n budget.listItems += size;\n if (budget.listItems > WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS) {\n throw new Error(\n `WhatsApp binary node list items exceed ${WHATSAPP_BINARY_NODE_MAX_LIST_ITEMS}.`,\n );\n }\n writeListStart(buffer, size);\n}\n\nfunction pushByte(buffer: number[], value: number): void {\n assertEncodedCapacity(buffer, 1);\n buffer.push(value & 0xff);\n}\n\nfunction pushBytes(buffer: number[], bytes: Uint8Array): void {\n assertEncodedCapacity(buffer, bytes.length);\n for (const byte of bytes) {\n buffer.push(byte & 0xff);\n }\n}\n\nfunction assertEncodedCapacity(buffer: number[], additionalBytes: number): void {\n if (buffer.length + additionalBytes > WHATSAPP_BINARY_NODE_MAX_FRAME_BYTES) {\n throw new Error(\n `WhatsApp binary node frame exceeds ${WHATSAPP_BINARY_NODE_MAX_FRAME_BYTES} bytes.`,\n );\n }\n}\n\nfunction pushInt(buffer: number[], value: number, length: number): void {\n for (let index = 0; index < length; index += 1) {\n const shift = length - 1 - index;\n pushByte(buffer, value >> (shift * 8));\n }\n}\n\nfunction writeByteLength(buffer: number[], length: number): void {\n if (length >= 4294967296) {\n throw new Error(`WhatsApp binary node payload is too large: ${length}.`);\n }\n if (length >= 1 << 20) {\n pushByte(buffer, TAGS.BINARY_32);\n pushInt(buffer, length, 4);\n return;\n }\n if (length >= 256) {\n pushByte(buffer, TAGS.BINARY_20);\n pushByte(buffer, (length >> 16) & 0x0f);\n pushByte(buffer, length >> 8);\n pushByte(buffer, length);\n return;\n }\n pushByte(buffer, TAGS.BINARY_8);\n pushByte(buffer, length);\n}\n\nfunction writeString(buffer: number[], value: string): void {\n const bytes = Buffer.from(value, \"utf8\");\n writeByteLength(buffer, bytes.length);\n pushBytes(buffer, bytes);\n}\n\nfunction writeListStart(buffer: number[], size: number): void {\n if (!Number.isSafeInteger(size) || size < 0 || size > 0xffff) {\n throw new Error(`WhatsApp binary node list is too large: ${size}.`);\n }\n if (size === 0) {\n pushByte(buffer, TAGS.LIST_EMPTY);\n return;\n }\n if (size < 256) {\n pushByte(buffer, TAGS.LIST_8);\n pushByte(buffer, size);\n return;\n }\n pushByte(buffer, TAGS.LIST_16);\n pushInt(buffer, size, 2);\n}\n"]}
|
|
@@ -20,6 +20,7 @@ type CurveApi = NativeCurveBackend & {
|
|
|
20
20
|
};
|
|
21
21
|
export declare function createCurve(nativeBackend?: NativeCurveBackend): CurveApi;
|
|
22
22
|
export declare const Curve: CurveApi;
|
|
23
|
+
export declare function generateSignalKeyPair(): KeyPair;
|
|
23
24
|
export declare function aesEncryptGCM(plaintext: Uint8Array, key: Uint8Array, iv: Uint8Array, additionalData: Uint8Array): Buffer;
|
|
24
25
|
export declare function aesDecryptGCM(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array, additionalData: Uint8Array): Buffer;
|
|
25
26
|
export declare function encodeBigEndian(value: number, length?: number): Buffer;
|
|
@@ -29,4 +30,6 @@ export declare function hkdf(input: Uint8Array, length: number, params: {
|
|
|
29
30
|
}): Buffer<ArrayBuffer>;
|
|
30
31
|
export declare function sha256(input: Uint8Array): Buffer;
|
|
31
32
|
export declare function signedKeyPair(identityKeyPair: KeyPair, keyId: number): SignedKeyPair;
|
|
33
|
+
export declare function ensureSignalPublicKey(publicKey: Uint8Array): Buffer;
|
|
34
|
+
export declare function scrubSignalPublicKey(publicKey: Uint8Array): Buffer;
|
|
32
35
|
export {};
|
|
@@ -50,7 +50,10 @@ export function createCurve(nativeBackend = nativeCurveBackend) {
|
|
|
50
50
|
try {
|
|
51
51
|
return nativeBackend.generateKeyPair();
|
|
52
52
|
}
|
|
53
|
-
catch {
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (!isUnsupportedNativeCurveError(error)) {
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
54
57
|
nativeAvailable = false;
|
|
55
58
|
}
|
|
56
59
|
}
|
|
@@ -82,7 +85,7 @@ export function createCurve(nativeBackend = nativeCurveBackend) {
|
|
|
82
85
|
return requireValidX25519SharedKey(curve25519.sharedKey(Buffer.from(privateKey), rawPublicKey));
|
|
83
86
|
},
|
|
84
87
|
sign(privateKey, message) {
|
|
85
|
-
return Buffer.from(curve25519.sign(Buffer.from(privateKey), Buffer.from(message)));
|
|
88
|
+
return Buffer.from(curve25519.sign(Buffer.from(privateKey), Buffer.from(message), randomBytes(64)));
|
|
86
89
|
},
|
|
87
90
|
};
|
|
88
91
|
}
|
|
@@ -94,6 +97,13 @@ function requireValidX25519SharedKey(sharedKey) {
|
|
|
94
97
|
return result;
|
|
95
98
|
}
|
|
96
99
|
export const Curve = createCurve();
|
|
100
|
+
export function generateSignalKeyPair() {
|
|
101
|
+
const keyPair = Curve.generateKeyPair();
|
|
102
|
+
return {
|
|
103
|
+
private: keyPair.private,
|
|
104
|
+
public: ensureSignalPublicKey(keyPair.public),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
97
107
|
export function aesEncryptGCM(plaintext, key, iv, additionalData) {
|
|
98
108
|
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
|
99
109
|
cipher.setAAD(additionalData);
|
|
@@ -137,19 +147,24 @@ export function sha256(input) {
|
|
|
137
147
|
return createHash("sha256").update(input).digest();
|
|
138
148
|
}
|
|
139
149
|
export function signedKeyPair(identityKeyPair, keyId) {
|
|
140
|
-
const keyPair =
|
|
141
|
-
const publicKey = ensureSignalPublicKey(keyPair.public);
|
|
150
|
+
const keyPair = generateSignalKeyPair();
|
|
142
151
|
return {
|
|
143
152
|
keyId,
|
|
144
153
|
keyPair,
|
|
145
|
-
signature: Curve.sign(identityKeyPair.private,
|
|
154
|
+
signature: Curve.sign(identityKeyPair.private, keyPair.public),
|
|
146
155
|
};
|
|
147
156
|
}
|
|
148
|
-
function ensureSignalPublicKey(publicKey) {
|
|
157
|
+
export function ensureSignalPublicKey(publicKey) {
|
|
149
158
|
const buffer = Buffer.from(publicKey);
|
|
150
|
-
|
|
159
|
+
if (buffer.length === 33 && buffer[0] === KEY_BUNDLE_TYPE[0]) {
|
|
160
|
+
return buffer;
|
|
161
|
+
}
|
|
162
|
+
if (buffer.length === 32) {
|
|
163
|
+
return Buffer.concat([KEY_BUNDLE_TYPE, buffer]);
|
|
164
|
+
}
|
|
165
|
+
throw new Error(`Invalid Signal public key length or type: ${buffer.length}.`);
|
|
151
166
|
}
|
|
152
|
-
function scrubSignalPublicKey(publicKey) {
|
|
167
|
+
export function scrubSignalPublicKey(publicKey) {
|
|
153
168
|
const buffer = Buffer.from(publicKey);
|
|
154
169
|
if (buffer.length === 33 && buffer[0] === KEY_BUNDLE_TYPE[0]) {
|
|
155
170
|
return buffer.subarray(1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../../../src/servers/whatsapp-wire/crypto.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport {\n createCipheriv,\n createDecipheriv,\n createHash,\n createPrivateKey,\n createPublicKey,\n diffieHellman,\n generateKeyPairSync,\n hkdfSync,\n randomBytes,\n} from \"node:crypto\";\nimport { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\n\ntype Curve25519Module = {\n generateKeyPair(seed: Uint8Array): { private: Uint8Array; public: Uint8Array };\n sharedKey(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n sign(privateKey: Uint8Array, message: Uint8Array): Uint8Array;\n};\n\nconst curve25519 = require(\"curve25519-js\") as Curve25519Module;\n\nconst AES_GCM_TAG_LENGTH = 16;\nconst PRIVATE_KEY_DER_PREFIX = Buffer.from([\n 48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32,\n]);\nconst PUBLIC_KEY_DER_PREFIX = Buffer.from([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0]);\n\nexport const KEY_BUNDLE_TYPE = Buffer.from([5]);\nexport const NOISE_MODE = \"Noise_XX_25519_AESGCM_SHA256\\0\\0\\0\\0\";\nexport const NOISE_WA_HEADER = Buffer.from([87, 65, 6, 3]);\n\nexport type KeyPair = {\n private: Buffer;\n public: Buffer;\n};\n\nexport type SignedKeyPair = {\n keyId: number;\n keyPair: KeyPair;\n signature: Buffer;\n};\n\ntype NativeCurveBackend = {\n generateKeyPair(): KeyPair;\n sharedKey(privateKey: Uint8Array, publicKey: Uint8Array): Buffer;\n};\n\ntype CurveApi = NativeCurveBackend & {\n sign(privateKey: Uint8Array, message: Uint8Array): Buffer;\n};\n\nconst nativeCurveBackend: NativeCurveBackend = {\n generateKeyPair() {\n const { privateKey, publicKey } = generateKeyPairSync(\"x25519\", {\n privateKeyEncoding: { format: \"der\", type: \"pkcs8\" },\n publicKeyEncoding: { format: \"der\", type: \"spki\" },\n });\n return {\n private: privateKey.subarray(\n PRIVATE_KEY_DER_PREFIX.length,\n PRIVATE_KEY_DER_PREFIX.length + 32,\n ),\n public: publicKey.subarray(PUBLIC_KEY_DER_PREFIX.length, PUBLIC_KEY_DER_PREFIX.length + 32),\n };\n },\n sharedKey(privateKey, publicKey) {\n const nodePrivateKey = createPrivateKey({\n format: \"der\",\n key: Buffer.concat([PRIVATE_KEY_DER_PREFIX, Buffer.from(privateKey)]),\n type: \"pkcs8\",\n });\n const nodePublicKey = createPublicKey({\n format: \"der\",\n key: Buffer.concat([PUBLIC_KEY_DER_PREFIX, Buffer.from(publicKey)]),\n type: \"spki\",\n });\n return diffieHellman({ privateKey: nodePrivateKey, publicKey: nodePublicKey });\n },\n};\n\nfunction isUnsupportedNativeCurveError(error: unknown): boolean {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n return (\n code === \"ERR_OSSL_EVP_UNSUPPORTED\" ||\n code === \"ERR_CRYPTO_UNSUPPORTED_OPERATION\" ||\n code === \"ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE\"\n );\n}\n\nexport function createCurve(nativeBackend: NativeCurveBackend = nativeCurveBackend): CurveApi {\n let nativeAvailable = true;\n return {\n generateKeyPair(): KeyPair {\n if (nativeAvailable) {\n try {\n return nativeBackend.generateKeyPair();\n } catch {\n nativeAvailable = false;\n }\n }\n const keyPair = curve25519.generateKeyPair(randomBytes(32));\n return {\n private: Buffer.from(keyPair.private),\n public: Buffer.from(keyPair.public),\n };\n },\n\n sharedKey(privateKey: Uint8Array, publicKey: Uint8Array): Buffer {\n if (privateKey.byteLength !== 32) {\n throw new Error(`Invalid Signal private key length: ${privateKey.byteLength}.`);\n }\n const rawPublicKey = scrubSignalPublicKey(publicKey);\n if (rawPublicKey.every((byte) => byte === 0)) {\n throw new Error(\"X25519 failed during derivation for an invalid peer key.\");\n }\n if (nativeAvailable) {\n try {\n return requireValidX25519SharedKey(nativeBackend.sharedKey(privateKey, rawPublicKey));\n } catch (error) {\n if (!isUnsupportedNativeCurveError(error)) {\n throw error;\n }\n nativeAvailable = false;\n }\n }\n return requireValidX25519SharedKey(\n curve25519.sharedKey(Buffer.from(privateKey), rawPublicKey),\n );\n },\n\n sign(privateKey: Uint8Array, message: Uint8Array): Buffer {\n return Buffer.from(curve25519.sign(Buffer.from(privateKey), Buffer.from(message)));\n },\n };\n}\n\nfunction requireValidX25519SharedKey(sharedKey: Uint8Array): Buffer {\n const result = Buffer.from(sharedKey);\n if (result.every((byte) => byte === 0)) {\n throw new Error(\"X25519 failed during derivation for an invalid peer key.\");\n }\n return result;\n}\n\nexport const Curve = createCurve();\n\nexport function aesEncryptGCM(\n plaintext: Uint8Array,\n key: Uint8Array,\n iv: Uint8Array,\n additionalData: Uint8Array,\n): Buffer {\n const cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n cipher.setAAD(additionalData);\n return Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()]);\n}\n\nexport function aesDecryptGCM(\n ciphertext: Uint8Array,\n key: Uint8Array,\n iv: Uint8Array,\n additionalData: Uint8Array,\n): Buffer {\n if (ciphertext.byteLength < AES_GCM_TAG_LENGTH) {\n throw new Error(\n `AES-GCM ciphertext must include a ${AES_GCM_TAG_LENGTH}-byte authentication tag.`,\n );\n }\n const decipher = createDecipheriv(\"aes-256-gcm\", key, iv, {\n authTagLength: AES_GCM_TAG_LENGTH,\n });\n const encrypted = ciphertext.subarray(0, ciphertext.byteLength - AES_GCM_TAG_LENGTH);\n const tag = ciphertext.subarray(ciphertext.byteLength - AES_GCM_TAG_LENGTH);\n decipher.setAAD(additionalData);\n decipher.setAuthTag(tag);\n return Buffer.concat([decipher.update(encrypted), decipher.final()]);\n}\n\nexport function encodeBigEndian(value: number, length = 4): Buffer {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new Error(\"Big-endian values must be non-negative safe integers.\");\n }\n if (!Number.isSafeInteger(length) || length < 1 || length > 1024) {\n throw new Error(\"Big-endian lengths must be safe integers between 1 and 1024.\");\n }\n let remaining = BigInt(value);\n if (remaining >= 1n << BigInt(length * 8)) {\n throw new Error(`Big-endian value ${value} does not fit in ${length} bytes.`);\n }\n const bytes = Buffer.alloc(length);\n for (let index = length - 1; index >= 0; index -= 1) {\n bytes[index] = Number(remaining & 0xffn);\n remaining >>= 8n;\n }\n return bytes;\n}\n\nexport function hkdf(\n input: Uint8Array,\n length: number,\n params: { info: string; salt: Uint8Array },\n) {\n return Buffer.from(hkdfSync(\"sha256\", input, params.salt, params.info, length));\n}\n\nexport function sha256(input: Uint8Array): Buffer {\n return createHash(\"sha256\").update(input).digest();\n}\n\nexport function signedKeyPair(identityKeyPair: KeyPair, keyId: number): SignedKeyPair {\n const keyPair = Curve.generateKeyPair();\n const publicKey = ensureSignalPublicKey(keyPair.public);\n return {\n keyId,\n keyPair,\n signature: Curve.sign(identityKeyPair.private, publicKey),\n };\n}\n\nfunction ensureSignalPublicKey(publicKey: Uint8Array): Buffer {\n const buffer = Buffer.from(publicKey);\n return buffer.length === 33 ? buffer : Buffer.concat([KEY_BUNDLE_TYPE, buffer]);\n}\n\nfunction scrubSignalPublicKey(publicKey: Uint8Array): Buffer {\n const buffer = Buffer.from(publicKey);\n if (buffer.length === 33 && buffer[0] === KEY_BUNDLE_TYPE[0]) {\n return buffer.subarray(1);\n }\n if (buffer.length === 32) {\n return buffer;\n }\n throw new Error(`Invalid Signal public key length: ${buffer.length}.`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../../../src/servers/whatsapp-wire/crypto.ts"],"names":[],"mappings":"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","sourcesContent":["import { Buffer } from \"node:buffer\";\nimport {\n createCipheriv,\n createDecipheriv,\n createHash,\n createPrivateKey,\n createPublicKey,\n diffieHellman,\n generateKeyPairSync,\n hkdfSync,\n randomBytes,\n} from \"node:crypto\";\nimport { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\n\ntype Curve25519Module = {\n generateKeyPair(seed: Uint8Array): { private: Uint8Array; public: Uint8Array };\n sharedKey(privateKey: Uint8Array, publicKey: Uint8Array): Uint8Array;\n sign(privateKey: Uint8Array, message: Uint8Array, random: Uint8Array): Uint8Array;\n};\n\nconst curve25519 = require(\"curve25519-js\") as Curve25519Module;\n\nconst AES_GCM_TAG_LENGTH = 16;\nconst PRIVATE_KEY_DER_PREFIX = Buffer.from([\n 48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 110, 4, 34, 4, 32,\n]);\nconst PUBLIC_KEY_DER_PREFIX = Buffer.from([48, 42, 48, 5, 6, 3, 43, 101, 110, 3, 33, 0]);\n\nexport const KEY_BUNDLE_TYPE = Buffer.from([5]);\nexport const NOISE_MODE = \"Noise_XX_25519_AESGCM_SHA256\\0\\0\\0\\0\";\nexport const NOISE_WA_HEADER = Buffer.from([87, 65, 6, 3]);\n\nexport type KeyPair = {\n private: Buffer;\n public: Buffer;\n};\n\nexport type SignedKeyPair = {\n keyId: number;\n keyPair: KeyPair;\n signature: Buffer;\n};\n\ntype NativeCurveBackend = {\n generateKeyPair(): KeyPair;\n sharedKey(privateKey: Uint8Array, publicKey: Uint8Array): Buffer;\n};\n\ntype CurveApi = NativeCurveBackend & {\n sign(privateKey: Uint8Array, message: Uint8Array): Buffer;\n};\n\nconst nativeCurveBackend: NativeCurveBackend = {\n generateKeyPair() {\n const { privateKey, publicKey } = generateKeyPairSync(\"x25519\", {\n privateKeyEncoding: { format: \"der\", type: \"pkcs8\" },\n publicKeyEncoding: { format: \"der\", type: \"spki\" },\n });\n return {\n private: privateKey.subarray(\n PRIVATE_KEY_DER_PREFIX.length,\n PRIVATE_KEY_DER_PREFIX.length + 32,\n ),\n public: publicKey.subarray(PUBLIC_KEY_DER_PREFIX.length, PUBLIC_KEY_DER_PREFIX.length + 32),\n };\n },\n sharedKey(privateKey, publicKey) {\n const nodePrivateKey = createPrivateKey({\n format: \"der\",\n key: Buffer.concat([PRIVATE_KEY_DER_PREFIX, Buffer.from(privateKey)]),\n type: \"pkcs8\",\n });\n const nodePublicKey = createPublicKey({\n format: \"der\",\n key: Buffer.concat([PUBLIC_KEY_DER_PREFIX, Buffer.from(publicKey)]),\n type: \"spki\",\n });\n return diffieHellman({ privateKey: nodePrivateKey, publicKey: nodePublicKey });\n },\n};\n\nfunction isUnsupportedNativeCurveError(error: unknown): boolean {\n const code = (error as NodeJS.ErrnoException | undefined)?.code;\n return (\n code === \"ERR_OSSL_EVP_UNSUPPORTED\" ||\n code === \"ERR_CRYPTO_UNSUPPORTED_OPERATION\" ||\n code === \"ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE\"\n );\n}\n\nexport function createCurve(nativeBackend: NativeCurveBackend = nativeCurveBackend): CurveApi {\n let nativeAvailable = true;\n return {\n generateKeyPair(): KeyPair {\n if (nativeAvailable) {\n try {\n return nativeBackend.generateKeyPair();\n } catch (error) {\n if (!isUnsupportedNativeCurveError(error)) {\n throw error;\n }\n nativeAvailable = false;\n }\n }\n const keyPair = curve25519.generateKeyPair(randomBytes(32));\n return {\n private: Buffer.from(keyPair.private),\n public: Buffer.from(keyPair.public),\n };\n },\n\n sharedKey(privateKey: Uint8Array, publicKey: Uint8Array): Buffer {\n if (privateKey.byteLength !== 32) {\n throw new Error(`Invalid Signal private key length: ${privateKey.byteLength}.`);\n }\n const rawPublicKey = scrubSignalPublicKey(publicKey);\n if (rawPublicKey.every((byte) => byte === 0)) {\n throw new Error(\"X25519 failed during derivation for an invalid peer key.\");\n }\n if (nativeAvailable) {\n try {\n return requireValidX25519SharedKey(nativeBackend.sharedKey(privateKey, rawPublicKey));\n } catch (error) {\n if (!isUnsupportedNativeCurveError(error)) {\n throw error;\n }\n nativeAvailable = false;\n }\n }\n return requireValidX25519SharedKey(\n curve25519.sharedKey(Buffer.from(privateKey), rawPublicKey),\n );\n },\n\n sign(privateKey: Uint8Array, message: Uint8Array): Buffer {\n return Buffer.from(\n curve25519.sign(Buffer.from(privateKey), Buffer.from(message), randomBytes(64)),\n );\n },\n };\n}\n\nfunction requireValidX25519SharedKey(sharedKey: Uint8Array): Buffer {\n const result = Buffer.from(sharedKey);\n if (result.every((byte) => byte === 0)) {\n throw new Error(\"X25519 failed during derivation for an invalid peer key.\");\n }\n return result;\n}\n\nexport const Curve = createCurve();\n\nexport function generateSignalKeyPair(): KeyPair {\n const keyPair = Curve.generateKeyPair();\n return {\n private: keyPair.private,\n public: ensureSignalPublicKey(keyPair.public),\n };\n}\n\nexport function aesEncryptGCM(\n plaintext: Uint8Array,\n key: Uint8Array,\n iv: Uint8Array,\n additionalData: Uint8Array,\n): Buffer {\n const cipher = createCipheriv(\"aes-256-gcm\", key, iv);\n cipher.setAAD(additionalData);\n return Buffer.concat([cipher.update(plaintext), cipher.final(), cipher.getAuthTag()]);\n}\n\nexport function aesDecryptGCM(\n ciphertext: Uint8Array,\n key: Uint8Array,\n iv: Uint8Array,\n additionalData: Uint8Array,\n): Buffer {\n if (ciphertext.byteLength < AES_GCM_TAG_LENGTH) {\n throw new Error(\n `AES-GCM ciphertext must include a ${AES_GCM_TAG_LENGTH}-byte authentication tag.`,\n );\n }\n const decipher = createDecipheriv(\"aes-256-gcm\", key, iv, {\n authTagLength: AES_GCM_TAG_LENGTH,\n });\n const encrypted = ciphertext.subarray(0, ciphertext.byteLength - AES_GCM_TAG_LENGTH);\n const tag = ciphertext.subarray(ciphertext.byteLength - AES_GCM_TAG_LENGTH);\n decipher.setAAD(additionalData);\n decipher.setAuthTag(tag);\n return Buffer.concat([decipher.update(encrypted), decipher.final()]);\n}\n\nexport function encodeBigEndian(value: number, length = 4): Buffer {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new Error(\"Big-endian values must be non-negative safe integers.\");\n }\n if (!Number.isSafeInteger(length) || length < 1 || length > 1024) {\n throw new Error(\"Big-endian lengths must be safe integers between 1 and 1024.\");\n }\n let remaining = BigInt(value);\n if (remaining >= 1n << BigInt(length * 8)) {\n throw new Error(`Big-endian value ${value} does not fit in ${length} bytes.`);\n }\n const bytes = Buffer.alloc(length);\n for (let index = length - 1; index >= 0; index -= 1) {\n bytes[index] = Number(remaining & 0xffn);\n remaining >>= 8n;\n }\n return bytes;\n}\n\nexport function hkdf(\n input: Uint8Array,\n length: number,\n params: { info: string; salt: Uint8Array },\n) {\n return Buffer.from(hkdfSync(\"sha256\", input, params.salt, params.info, length));\n}\n\nexport function sha256(input: Uint8Array): Buffer {\n return createHash(\"sha256\").update(input).digest();\n}\n\nexport function signedKeyPair(identityKeyPair: KeyPair, keyId: number): SignedKeyPair {\n const keyPair = generateSignalKeyPair();\n return {\n keyId,\n keyPair,\n signature: Curve.sign(identityKeyPair.private, keyPair.public),\n };\n}\n\nexport function ensureSignalPublicKey(publicKey: Uint8Array): Buffer {\n const buffer = Buffer.from(publicKey);\n if (buffer.length === 33 && buffer[0] === KEY_BUNDLE_TYPE[0]) {\n return buffer;\n }\n if (buffer.length === 32) {\n return Buffer.concat([KEY_BUNDLE_TYPE, buffer]);\n }\n throw new Error(`Invalid Signal public key length or type: ${buffer.length}.`);\n}\n\nexport function scrubSignalPublicKey(publicKey: Uint8Array): Buffer {\n const buffer = Buffer.from(publicKey);\n if (buffer.length === 33 && buffer[0] === KEY_BUNDLE_TYPE[0]) {\n return buffer.subarray(1);\n }\n if (buffer.length === 32) {\n return buffer;\n }\n throw new Error(`Invalid Signal public key length: ${buffer.length}.`);\n}\n"]}
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { Buffer } from "node:buffer";
|
|
2
2
|
export type HandshakeMessage = {
|
|
3
3
|
clientFinish?: {
|
|
4
|
+
extendedCiphertext?: Buffer;
|
|
4
5
|
payload?: Buffer;
|
|
5
6
|
staticKey?: Buffer;
|
|
6
7
|
};
|
|
7
8
|
clientHello?: {
|
|
8
9
|
ephemeral?: Buffer;
|
|
10
|
+
extendedCiphertext?: Buffer;
|
|
11
|
+
payload?: Buffer;
|
|
12
|
+
staticKey?: Buffer;
|
|
13
|
+
useExtended?: boolean;
|
|
9
14
|
};
|
|
10
15
|
serverHello?: {
|
|
11
|
-
ephemeral
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
ephemeral?: Uint8Array;
|
|
17
|
+
extendedStatic?: Uint8Array;
|
|
18
|
+
payload?: Uint8Array;
|
|
19
|
+
staticKey?: Uint8Array;
|
|
14
20
|
};
|
|
15
21
|
};
|
|
16
22
|
export declare function decodeHandshakeMessage(data: Uint8Array): HandshakeMessage;
|