@oxidezap/baileyrs 0.0.7 → 0.0.9
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 +119 -5
- package/lib/Bridge/__tests__/adapt.test.d.ts +2 -0
- package/lib/Bridge/__tests__/adapt.test.d.ts.map +1 -0
- package/lib/Bridge/__tests__/adapt.test.js +355 -0
- package/lib/Bridge/__tests__/adapt.test.js.map +1 -0
- package/lib/Bridge/__tests__/dts-drift.test.d.ts +13 -0
- package/lib/Bridge/__tests__/dts-drift.test.d.ts.map +1 -0
- package/lib/Bridge/__tests__/dts-drift.test.js +92 -0
- package/lib/Bridge/__tests__/dts-drift.test.js.map +1 -0
- package/lib/Bridge/__tests__/fixtures.d.ts +192 -0
- package/lib/Bridge/__tests__/fixtures.d.ts.map +1 -0
- package/lib/Bridge/__tests__/fixtures.js +99 -0
- package/lib/Bridge/__tests__/fixtures.js.map +1 -0
- package/lib/Bridge/adapt.d.ts +28 -0
- package/lib/Bridge/adapt.d.ts.map +1 -0
- package/lib/Bridge/adapt.js +504 -0
- package/lib/Bridge/adapt.js.map +1 -0
- package/lib/Bridge/index.d.ts +12 -0
- package/lib/Bridge/index.d.ts.map +1 -0
- package/lib/Bridge/index.js +12 -0
- package/lib/Bridge/index.js.map +1 -0
- package/lib/Bridge/primitives.d.ts +56 -0
- package/lib/Bridge/primitives.d.ts.map +1 -0
- package/lib/Bridge/primitives.js +58 -0
- package/lib/Bridge/primitives.js.map +1 -0
- package/lib/Bridge/types.d.ts +273 -0
- package/lib/Bridge/types.d.ts.map +1 -0
- package/lib/Bridge/types.js +17 -0
- package/lib/Bridge/types.js.map +1 -0
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +2 -2
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Socket/blocking.d.ts.map +1 -1
- package/lib/Socket/chat-actions.d.ts.map +1 -1
- package/lib/Socket/contacts.d.ts +9 -4
- package/lib/Socket/contacts.d.ts.map +1 -1
- package/lib/Socket/contacts.js +11 -8
- package/lib/Socket/contacts.js.map +1 -1
- package/lib/Socket/events.d.ts +7 -1
- package/lib/Socket/events.d.ts.map +1 -1
- package/lib/Socket/events.js +212 -243
- package/lib/Socket/events.js.map +1 -1
- package/lib/Socket/group-notifications.d.ts +25 -0
- package/lib/Socket/group-notifications.d.ts.map +1 -0
- package/lib/Socket/group-notifications.js +162 -0
- package/lib/Socket/group-notifications.js.map +1 -0
- package/lib/Socket/groups.d.ts +12 -1
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/groups.js +44 -1
- package/lib/Socket/groups.js.map +1 -1
- package/lib/Socket/index.d.ts +47 -13
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/index.js +158 -24
- package/lib/Socket/index.js.map +1 -1
- package/lib/Socket/messages.d.ts +5 -2
- package/lib/Socket/messages.d.ts.map +1 -1
- package/lib/Socket/messages.js +42 -21
- package/lib/Socket/messages.js.map +1 -1
- package/lib/Socket/newsletter.d.ts.map +1 -1
- package/lib/Socket/presence.d.ts.map +1 -1
- package/lib/Socket/profile.d.ts +7 -1
- package/lib/Socket/profile.d.ts.map +1 -1
- package/lib/Socket/profile.js +20 -5
- package/lib/Socket/profile.js.map +1 -1
- package/lib/Socket/transport.d.ts.map +1 -1
- package/lib/Socket/transport.js +14 -13
- package/lib/Socket/transport.js.map +1 -1
- package/lib/Socket/types.d.ts.map +1 -1
- package/lib/Types/Auth.d.ts +1 -1
- package/lib/Types/Auth.d.ts.map +1 -1
- package/lib/Types/Bussines.d.ts +1 -1
- package/lib/Types/Bussines.d.ts.map +1 -1
- package/lib/Types/Chat.d.ts +1 -1
- package/lib/Types/Chat.d.ts.map +1 -1
- package/lib/Types/Events.d.ts +12 -3
- package/lib/Types/Events.d.ts.map +1 -1
- package/lib/Types/Events.js +1 -1
- package/lib/Types/Events.js.map +1 -1
- package/lib/Types/GroupMetadata.d.ts.map +1 -1
- package/lib/Types/Message.d.ts +16 -1
- package/lib/Types/Message.d.ts.map +1 -1
- package/lib/Types/Message.js +1 -1
- package/lib/Types/Message.js.map +1 -1
- package/lib/Types/Socket.d.ts +42 -1
- package/lib/Types/Socket.d.ts.map +1 -1
- package/lib/Types/State.d.ts +1 -1
- package/lib/Types/State.d.ts.map +1 -1
- package/lib/Types/index.d.ts +1 -1
- package/lib/Types/index.d.ts.map +1 -1
- package/lib/Types/index.js +17 -12
- package/lib/Types/index.js.map +1 -1
- package/lib/Utils/__tests__/_legacy-store-fixtures.d.ts +65 -0
- package/lib/Utils/__tests__/_legacy-store-fixtures.d.ts.map +1 -0
- package/lib/Utils/__tests__/_legacy-store-fixtures.js +107 -0
- package/lib/Utils/__tests__/_legacy-store-fixtures.js.map +1 -0
- package/lib/Utils/__tests__/wrap-legacy-store-coverage.test.d.ts +10 -0
- package/lib/Utils/__tests__/wrap-legacy-store-coverage.test.d.ts.map +1 -0
- package/lib/Utils/__tests__/wrap-legacy-store-coverage.test.js +298 -0
- package/lib/Utils/__tests__/wrap-legacy-store-coverage.test.js.map +1 -0
- package/lib/Utils/__tests__/wrap-legacy-store-lid-mapping.test.d.ts +8 -0
- package/lib/Utils/__tests__/wrap-legacy-store-lid-mapping.test.d.ts.map +1 -0
- package/lib/Utils/__tests__/wrap-legacy-store-lid-mapping.test.js +91 -0
- package/lib/Utils/__tests__/wrap-legacy-store-lid-mapping.test.js.map +1 -0
- package/lib/Utils/__tests__/wrap-legacy-store-sender-key.test.d.ts +10 -0
- package/lib/Utils/__tests__/wrap-legacy-store-sender-key.test.d.ts.map +1 -0
- package/lib/Utils/__tests__/wrap-legacy-store-sender-key.test.js +126 -0
- package/lib/Utils/__tests__/wrap-legacy-store-sender-key.test.js.map +1 -0
- package/lib/Utils/__tests__/wrap-legacy-store-session.test.d.ts +14 -0
- package/lib/Utils/__tests__/wrap-legacy-store-session.test.d.ts.map +1 -0
- package/lib/Utils/__tests__/wrap-legacy-store-session.test.js +309 -0
- package/lib/Utils/__tests__/wrap-legacy-store-session.test.js.map +1 -0
- package/lib/Utils/boom.d.ts +33 -0
- package/lib/Utils/boom.d.ts.map +1 -0
- package/lib/Utils/boom.js +63 -0
- package/lib/Utils/boom.js.map +1 -0
- package/lib/Utils/browser-utils.d.ts.map +1 -1
- package/lib/Utils/event-buffer.d.ts.map +1 -1
- package/lib/Utils/generics.d.ts +37 -1
- package/lib/Utils/generics.d.ts.map +1 -1
- package/lib/Utils/generics.js +60 -2
- package/lib/Utils/generics.js.map +1 -1
- package/lib/Utils/index.d.ts +1 -0
- package/lib/Utils/index.d.ts.map +1 -1
- package/lib/Utils/index.js +10 -9
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/lid-mapping-store.d.ts +81 -0
- package/lib/Utils/lid-mapping-store.d.ts.map +1 -0
- package/lib/Utils/lid-mapping-store.js +126 -0
- package/lib/Utils/lid-mapping-store.js.map +1 -0
- package/lib/Utils/logger.d.ts.map +1 -1
- package/lib/Utils/logger.js +25 -1
- package/lib/Utils/logger.js.map +1 -1
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +1 -1
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts +30 -1
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +115 -41
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/native-crypto-provider.d.ts +18 -0
- package/lib/Utils/native-crypto-provider.d.ts.map +1 -0
- package/lib/Utils/native-crypto-provider.js +67 -0
- package/lib/Utils/native-crypto-provider.js.map +1 -0
- package/lib/Utils/use-bridge-store.d.ts.map +1 -1
- package/lib/Utils/use-memory-store.d.ts.map +1 -1
- package/lib/Utils/use-memory-store.js +1 -1
- package/lib/Utils/use-memory-store.js.map +1 -1
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -1
- package/lib/Utils/use-multi-file-auth-state.js +1 -1
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -1
- package/lib/Utils/wrap-legacy-store.d.ts.map +1 -1
- package/lib/Utils/wrap-legacy-store.js +505 -42
- package/lib/Utils/wrap-legacy-store.js.map +1 -1
- package/lib/WABinary/index.d.ts.map +1 -1
- package/lib/WABinary/index.js +1 -1
- package/lib/WABinary/index.js.map +1 -1
- package/lib/__tests__/expect.d.ts +30 -0
- package/lib/__tests__/expect.d.ts.map +1 -0
- package/lib/__tests__/expect.js +60 -0
- package/lib/__tests__/expect.js.map +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +9 -6
- package/lib/index.js.map +1 -1
- package/package.json +33 -25
- package/WAProto/index.d.ts +0 -13875
- package/WAProto/index.js +0 -175
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-impl gap for `sender_key`:
|
|
3
|
+
* • Bridge: store `sender_key`, key `{group}:{user}[:dev]@{server}.{sig}`,
|
|
4
|
+
* value = protobuf `SenderKeyRecordStructure`.
|
|
5
|
+
* • Upstream: store `sender-key`, key `{group}::{signalUser}::{deviceId}`,
|
|
6
|
+
* value = `Buffer(JSON.stringify(states, BufferJSON.replacer), 'utf-8')`.
|
|
7
|
+
* Store name, key shape AND value encoding all differ.
|
|
8
|
+
*/
|
|
9
|
+
import { Buffer } from 'node:buffer';
|
|
10
|
+
import { describe, test } from 'node:test';
|
|
11
|
+
import { SenderKeyRecord } from 'baileys/lib/Signal/Group/sender-key-record.js';
|
|
12
|
+
import { proto as bridgeProto } from 'whatsapp-rust-bridge/proto-types';
|
|
13
|
+
import { expect } from "../../__tests__/expect.js";
|
|
14
|
+
import { BRIDGE_SK_KEY_LID, BRIDGE_SK_KEY_PN_DEV, UPSTREAM_SK_KEY_LID, UPSTREAM_SK_KEY_PN_DEV, buildBridgeSenderKeyBytes, fill, makeWrapped } from "./_legacy-store-fixtures.js";
|
|
15
|
+
describe('wrap-legacy-store: sender_key key-name translation', () => {
|
|
16
|
+
test('LID, no JID device → upstream `_1` suffix + double-colon separators', async () => {
|
|
17
|
+
const { wrapped, keys } = await makeWrapped();
|
|
18
|
+
await wrapped.set('sender_key', BRIDGE_SK_KEY_LID, buildBridgeSenderKeyBytes());
|
|
19
|
+
expect(keys.raw['sender-key']?.[UPSTREAM_SK_KEY_LID]).toBeDefined();
|
|
20
|
+
// The bridge-shaped key MUST NOT leak — would mean we passthrough'd raw bytes.
|
|
21
|
+
expect(keys.raw['sender-key']?.[BRIDGE_SK_KEY_LID]).toBeUndefined();
|
|
22
|
+
});
|
|
23
|
+
test('PN with device suffix → JID device becomes upstream deviceId', async () => {
|
|
24
|
+
const { wrapped, keys } = await makeWrapped();
|
|
25
|
+
await wrapped.set('sender_key', BRIDGE_SK_KEY_PN_DEV, buildBridgeSenderKeyBytes());
|
|
26
|
+
expect(keys.raw['sender-key']?.[UPSTREAM_SK_KEY_PN_DEV]).toBeDefined();
|
|
27
|
+
});
|
|
28
|
+
test('bridge GET reads back from the upstream-formatted key', async () => {
|
|
29
|
+
const { wrapped, keys } = await makeWrapped();
|
|
30
|
+
const upstreamBytes = Buffer.from(JSON.stringify([
|
|
31
|
+
{
|
|
32
|
+
senderKeyId: 17,
|
|
33
|
+
senderChainKey: { iteration: 3, seed: Buffer.from(fill(32, 7)) },
|
|
34
|
+
senderSigningKey: { public: Buffer.from(fill(33, 11)), private: Buffer.from(fill(32, 13)) },
|
|
35
|
+
senderMessageKeys: []
|
|
36
|
+
}
|
|
37
|
+
], (_k, v) => {
|
|
38
|
+
if (Buffer.isBuffer(v) || v instanceof Uint8Array || v?.type === 'Buffer') {
|
|
39
|
+
return { type: 'Buffer', data: Buffer.from(v.data ?? v).toString('base64') };
|
|
40
|
+
}
|
|
41
|
+
return v;
|
|
42
|
+
}), 'utf-8');
|
|
43
|
+
keys.raw['sender-key'] = { [UPSTREAM_SK_KEY_LID]: upstreamBytes };
|
|
44
|
+
const out = await wrapped.get('sender_key', BRIDGE_SK_KEY_LID);
|
|
45
|
+
expect(out).not.toBe(null);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe('wrap-legacy-store: sender_key value-byte translation', () => {
|
|
49
|
+
test('bridge proto bytes load via upstream `SenderKeyRecord.deserialize`', async () => {
|
|
50
|
+
const { wrapped, keys } = await makeWrapped();
|
|
51
|
+
const keyId = 42;
|
|
52
|
+
const iteration = 9;
|
|
53
|
+
const chainSeed = Buffer.from(fill(32, 7));
|
|
54
|
+
const signPub = Buffer.from(fill(33, 11));
|
|
55
|
+
const signPriv = Buffer.from(fill(32, 13));
|
|
56
|
+
await wrapped.set('sender_key', BRIDGE_SK_KEY_LID, buildBridgeSenderKeyBytes({
|
|
57
|
+
keyId,
|
|
58
|
+
iteration,
|
|
59
|
+
chainSeed: new Uint8Array(chainSeed),
|
|
60
|
+
signingPublic: new Uint8Array(signPub),
|
|
61
|
+
signingPrivate: new Uint8Array(signPriv)
|
|
62
|
+
}));
|
|
63
|
+
const onDisk = keys.raw['sender-key']?.[UPSTREAM_SK_KEY_LID];
|
|
64
|
+
const rec = SenderKeyRecord.deserialize(onDisk);
|
|
65
|
+
expect(rec.isEmpty()).toBe(false);
|
|
66
|
+
const state = rec.getSenderKeyState();
|
|
67
|
+
expect(state.getKeyId()).toBe(keyId);
|
|
68
|
+
expect(state.getSenderChainKey().getIteration()).toBe(iteration);
|
|
69
|
+
expect(Buffer.from(state.getSenderChainKey().getSeed()).equals(chainSeed)).toBe(true);
|
|
70
|
+
expect(Buffer.from(state.getSigningKeyPublic()).equals(signPub)).toBe(true);
|
|
71
|
+
expect(Buffer.from(state.getSigningKeyPrivate()).equals(signPriv)).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
test('upstream JSON bytes round-trip to valid bridge proto', async () => {
|
|
74
|
+
const { wrapped, keys } = await makeWrapped();
|
|
75
|
+
const keyId = 99;
|
|
76
|
+
const iteration = 4;
|
|
77
|
+
const chainSeed = Buffer.alloc(32, 0xab);
|
|
78
|
+
const signPub = Buffer.alloc(33, 0xcd);
|
|
79
|
+
const signPriv = Buffer.alloc(32, 0xef);
|
|
80
|
+
const upstreamBytes = Buffer.from(JSON.stringify([
|
|
81
|
+
{
|
|
82
|
+
senderKeyId: keyId,
|
|
83
|
+
senderChainKey: { iteration, seed: chainSeed },
|
|
84
|
+
senderSigningKey: { public: signPub, private: signPriv },
|
|
85
|
+
senderMessageKeys: []
|
|
86
|
+
}
|
|
87
|
+
], (_k, v) => {
|
|
88
|
+
if (Buffer.isBuffer(v) || v instanceof Uint8Array || v?.type === 'Buffer') {
|
|
89
|
+
return { type: 'Buffer', data: Buffer.from(v.data ?? v).toString('base64') };
|
|
90
|
+
}
|
|
91
|
+
return v;
|
|
92
|
+
}), 'utf-8');
|
|
93
|
+
keys.raw['sender-key'] = { [UPSTREAM_SK_KEY_LID]: upstreamBytes };
|
|
94
|
+
const bytesOut = (await wrapped.get('sender_key', BRIDGE_SK_KEY_LID));
|
|
95
|
+
const decoded = bridgeProto.SenderKeyRecordStructure.decode(bytesOut);
|
|
96
|
+
expect(decoded.senderKeyStates.length).toBe(1);
|
|
97
|
+
const s = decoded.senderKeyStates[0];
|
|
98
|
+
expect(s.senderKeyId).toBe(keyId);
|
|
99
|
+
expect(s.senderChainKey?.iteration).toBe(iteration);
|
|
100
|
+
expect(Buffer.from(s.senderChainKey.seed).equals(chainSeed)).toBe(true);
|
|
101
|
+
expect(Buffer.from(s.senderSigningKey.public).equals(signPub)).toBe(true);
|
|
102
|
+
expect(Buffer.from(s.senderSigningKey.private).equals(signPriv)).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
test('iteration bump survives bridge SET → upstream advance → bridge GET', async () => {
|
|
105
|
+
const { wrapped, keys } = await makeWrapped();
|
|
106
|
+
await wrapped.set('sender_key', BRIDGE_SK_KEY_LID, buildBridgeSenderKeyBytes({ keyId: 5, iteration: 1 }));
|
|
107
|
+
const onDisk = keys.raw['sender-key']?.[UPSTREAM_SK_KEY_LID];
|
|
108
|
+
const rec = SenderKeyRecord.deserialize(onDisk);
|
|
109
|
+
const state = rec.getSenderKeyState();
|
|
110
|
+
const ck = state.getSenderChainKey();
|
|
111
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- SenderChainKey is structurally typed
|
|
112
|
+
const bumped = { getIteration: () => ck.getIteration() + 5, getSeed: () => ck.getSeed() };
|
|
113
|
+
state.setSenderChainKey(bumped);
|
|
114
|
+
const newJson = JSON.stringify(rec.serialize(), (_k, v) => {
|
|
115
|
+
if (Buffer.isBuffer(v) || v instanceof Uint8Array || v?.type === 'Buffer') {
|
|
116
|
+
return { type: 'Buffer', data: Buffer.from(v.data ?? v).toString('base64') };
|
|
117
|
+
}
|
|
118
|
+
return v;
|
|
119
|
+
});
|
|
120
|
+
keys.raw['sender-key'][UPSTREAM_SK_KEY_LID] = Buffer.from(newJson, 'utf-8');
|
|
121
|
+
const bytesOut = (await wrapped.get('sender_key', BRIDGE_SK_KEY_LID));
|
|
122
|
+
const decoded = bridgeProto.SenderKeyRecordStructure.decode(bytesOut);
|
|
123
|
+
expect(decoded.senderKeyStates[0].senderChainKey?.iteration).toBe(6);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
//# sourceMappingURL=wrap-legacy-store-sender-key.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrap-legacy-store-sender-key.test.js","sourceRoot":"","sources":["../../../src/Utils/__tests__/wrap-legacy-store-sender-key.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-impl gap for `session`:
|
|
3
|
+
* • Bridge: store `session`, key `{user}[:dev]@{server}.{sig}`,
|
|
4
|
+
* value = protobuf `RecordStructure` (current + previous_sessions).
|
|
5
|
+
* • Upstream: store `session`, key `{signalUser}.{deviceId}`,
|
|
6
|
+
* value = JS object `{ _sessions: { [base64BaseKey]: SessionEntry }, version: 'v1' }`.
|
|
7
|
+
*
|
|
8
|
+
* Without conversion, upstream's `loadSession` either misses the key or
|
|
9
|
+
* throws inside `SessionRecord.deserialize`, falling back to a fresh
|
|
10
|
+
* PreKey signal handshake on every cross-impl swap. These tests pin
|
|
11
|
+
* direct, no-re-handshake compatibility.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=wrap-legacy-store-session.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrap-legacy-store-session.test.d.ts","sourceRoot":"","sources":["../../../src/Utils/__tests__/wrap-legacy-store-session.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-impl gap for `session`:
|
|
3
|
+
* • Bridge: store `session`, key `{user}[:dev]@{server}.{sig}`,
|
|
4
|
+
* value = protobuf `RecordStructure` (current + previous_sessions).
|
|
5
|
+
* • Upstream: store `session`, key `{signalUser}.{deviceId}`,
|
|
6
|
+
* value = JS object `{ _sessions: { [base64BaseKey]: SessionEntry }, version: 'v1' }`.
|
|
7
|
+
*
|
|
8
|
+
* Without conversion, upstream's `loadSession` either misses the key or
|
|
9
|
+
* throws inside `SessionRecord.deserialize`, falling back to a fresh
|
|
10
|
+
* PreKey signal handshake on every cross-impl swap. These tests pin
|
|
11
|
+
* direct, no-re-handshake compatibility.
|
|
12
|
+
*/
|
|
13
|
+
import { Buffer } from 'node:buffer';
|
|
14
|
+
import { describe, test } from 'node:test';
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
16
|
+
// @ts-expect-error -- libsignal lacks .d.ts
|
|
17
|
+
import SessionRecord from 'libsignal/src/session_record.js';
|
|
18
|
+
import { proto as bridgeProto } from 'whatsapp-rust-bridge/proto-types';
|
|
19
|
+
import { expect } from "../../__tests__/expect.js";
|
|
20
|
+
import { BRIDGE_SESSION_KEY_LID, BRIDGE_SESSION_KEY_PN, BRIDGE_SESSION_KEY_PN_DEV, UPSTREAM_SESSION_KEY_LID, UPSTREAM_SESSION_KEY_PN, UPSTREAM_SESSION_KEY_PN_DEV, buildBridgeSessionBytes, fill, makeWrapped } from "./_legacy-store-fixtures.js";
|
|
21
|
+
describe('wrap-legacy-store: session key-name translation', () => {
|
|
22
|
+
test('LID → upstream `_1.deviceId`', async () => {
|
|
23
|
+
const { wrapped, keys } = await makeWrapped();
|
|
24
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_LID, buildBridgeSessionBytes());
|
|
25
|
+
expect(keys.raw['session']?.[UPSTREAM_SESSION_KEY_LID]).toBeDefined();
|
|
26
|
+
expect(keys.raw['session']?.[BRIDGE_SESSION_KEY_LID]).toBeUndefined();
|
|
27
|
+
});
|
|
28
|
+
test('PN no-device → bare `{user}.{signalDev}`', async () => {
|
|
29
|
+
const { wrapped, keys } = await makeWrapped();
|
|
30
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_PN, buildBridgeSessionBytes());
|
|
31
|
+
expect(keys.raw['session']?.[UPSTREAM_SESSION_KEY_PN]).toBeDefined();
|
|
32
|
+
});
|
|
33
|
+
test('PN with JID device → device suffix preserved', async () => {
|
|
34
|
+
const { wrapped, keys } = await makeWrapped();
|
|
35
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_PN_DEV, buildBridgeSessionBytes());
|
|
36
|
+
expect(keys.raw['session']?.[UPSTREAM_SESSION_KEY_PN_DEV]).toBeDefined();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
describe('wrap-legacy-store: session value-byte translation', () => {
|
|
40
|
+
test('bridge proto bytes load via upstream `SessionRecord.deserialize` as OPEN', async () => {
|
|
41
|
+
const { wrapped, keys } = await makeWrapped();
|
|
42
|
+
const aliceBaseKey = Buffer.from(fill(33, 100));
|
|
43
|
+
const rootKey = Buffer.from(fill(32, 11));
|
|
44
|
+
const remoteIdentity = Buffer.from(fill(33, 17));
|
|
45
|
+
const senderRatchetPub = Buffer.from(fill(33, 23));
|
|
46
|
+
const senderRatchetPriv = Buffer.from(fill(32, 29));
|
|
47
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_LID, buildBridgeSessionBytes({
|
|
48
|
+
rootKey: new Uint8Array(rootKey),
|
|
49
|
+
aliceBaseKey: new Uint8Array(aliceBaseKey),
|
|
50
|
+
remoteIdentity: new Uint8Array(remoteIdentity),
|
|
51
|
+
senderRatchetPub: new Uint8Array(senderRatchetPub),
|
|
52
|
+
senderRatchetPriv: new Uint8Array(senderRatchetPriv),
|
|
53
|
+
remoteRegistrationId: 99,
|
|
54
|
+
previousCounter: 4
|
|
55
|
+
}));
|
|
56
|
+
const stored = keys.raw['session']?.[UPSTREAM_SESSION_KEY_LID];
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
+
const rec = SessionRecord.deserialize(stored);
|
|
59
|
+
expect(rec.haveOpenSession()).toBe(true);
|
|
60
|
+
const open = rec.getOpenSession();
|
|
61
|
+
expect(open.registrationId).toBe(99);
|
|
62
|
+
expect(open.currentRatchet.previousCounter).toBe(4);
|
|
63
|
+
expect(Buffer.from(open.currentRatchet.rootKey).equals(rootKey)).toBe(true);
|
|
64
|
+
expect(Buffer.from(open.currentRatchet.ephemeralKeyPair.pubKey).equals(senderRatchetPub)).toBe(true);
|
|
65
|
+
expect(Buffer.from(open.currentRatchet.ephemeralKeyPair.privKey).equals(senderRatchetPriv)).toBe(true);
|
|
66
|
+
expect(Buffer.from(open.indexInfo.baseKey).equals(aliceBaseKey)).toBe(true);
|
|
67
|
+
expect(Buffer.from(open.indexInfo.remoteIdentityKey).equals(remoteIdentity)).toBe(true);
|
|
68
|
+
expect(open.indexInfo.closed).toBe(-1);
|
|
69
|
+
expect(Object.keys(open._chains).length).toBeGreaterThanOrEqual(1);
|
|
70
|
+
});
|
|
71
|
+
test('upstream JS object → bridge GET produces valid proto with same fields', async () => {
|
|
72
|
+
const { wrapped, keys } = await makeWrapped();
|
|
73
|
+
const baseKey = Buffer.alloc(33, 0xa0);
|
|
74
|
+
const rootKey = Buffer.alloc(32, 0xb0);
|
|
75
|
+
const remoteIdent = Buffer.alloc(33, 0xc0);
|
|
76
|
+
const ephPub = Buffer.alloc(33, 0xd0);
|
|
77
|
+
const ephPriv = Buffer.alloc(32, 0xe0);
|
|
78
|
+
const lastRemoteEph = Buffer.alloc(33, 0xf0);
|
|
79
|
+
keys.raw['session'] = {
|
|
80
|
+
[UPSTREAM_SESSION_KEY_LID]: {
|
|
81
|
+
_sessions: {
|
|
82
|
+
[baseKey.toString('base64')]: {
|
|
83
|
+
registrationId: 4242,
|
|
84
|
+
currentRatchet: {
|
|
85
|
+
ephemeralKeyPair: { pubKey: ephPub.toString('base64'), privKey: ephPriv.toString('base64') },
|
|
86
|
+
lastRemoteEphemeralKey: lastRemoteEph.toString('base64'),
|
|
87
|
+
previousCounter: 7,
|
|
88
|
+
rootKey: rootKey.toString('base64')
|
|
89
|
+
},
|
|
90
|
+
indexInfo: {
|
|
91
|
+
baseKey: baseKey.toString('base64'),
|
|
92
|
+
baseKeyType: 1,
|
|
93
|
+
closed: -1,
|
|
94
|
+
used: Date.now(),
|
|
95
|
+
created: Date.now(),
|
|
96
|
+
remoteIdentityKey: remoteIdent.toString('base64')
|
|
97
|
+
},
|
|
98
|
+
_chains: {}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
version: 'v1'
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const protoOut = (await wrapped.get('session', BRIDGE_SESSION_KEY_LID));
|
|
105
|
+
const decoded = bridgeProto.RecordStructure.decode(protoOut);
|
|
106
|
+
const cs = decoded.currentSession;
|
|
107
|
+
expect(cs.remoteRegistrationId).toBe(4242);
|
|
108
|
+
expect(cs.previousCounter).toBe(7);
|
|
109
|
+
expect(Buffer.from(cs.rootKey).equals(rootKey)).toBe(true);
|
|
110
|
+
expect(Buffer.from(cs.aliceBaseKey).equals(baseKey)).toBe(true);
|
|
111
|
+
expect(Buffer.from(cs.remoteIdentityPublic).equals(remoteIdent)).toBe(true);
|
|
112
|
+
expect(Buffer.from(cs.senderChain.senderRatchetKey).equals(ephPub)).toBe(true);
|
|
113
|
+
expect(Buffer.from(cs.senderChain.senderRatchetKeyPrivate).equals(ephPriv)).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
test('round-trip: bridge SET → upstream loadSession → still open + same identity', async () => {
|
|
116
|
+
const { wrapped, keys } = await makeWrapped();
|
|
117
|
+
const remoteIdentity = Buffer.alloc(33, 0x11);
|
|
118
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_PN, buildBridgeSessionBytes({ remoteIdentity: new Uint8Array(remoteIdentity), remoteRegistrationId: 7 }));
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
120
|
+
const rec = SessionRecord.deserialize(keys.raw['session']?.[UPSTREAM_SESSION_KEY_PN]);
|
|
121
|
+
const open = rec.getOpenSession();
|
|
122
|
+
expect(open.registrationId).toBe(7);
|
|
123
|
+
expect(Buffer.from(open.indexInfo.remoteIdentityKey).equals(remoteIdentity)).toBe(true);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
describe('wrap-legacy-store: session edge cases', () => {
|
|
127
|
+
test('lastRemoteEphemeralKey does NOT collide with senderRatchetKey when receiverChains empty', async () => {
|
|
128
|
+
// Regression: the converter previously used senderRatchetKey as a
|
|
129
|
+
// placeholder, which made upstream's `maybeStepRatchet` close the
|
|
130
|
+
// SENDER chain on the next peer ratchet (corrupting outbound
|
|
131
|
+
// encryption). Now uses aliceBaseKey (when bob) or empty buffer.
|
|
132
|
+
const { wrapped, keys } = await makeWrapped();
|
|
133
|
+
const senderRatchetPub = fill(33, 2);
|
|
134
|
+
const aliceBaseKey = fill(33, 7);
|
|
135
|
+
const protoBytes = bridgeProto.RecordStructure.encode(bridgeProto.RecordStructure.create({
|
|
136
|
+
currentSession: bridgeProto.SessionStructure.create({
|
|
137
|
+
sessionVersion: 3,
|
|
138
|
+
rootKey: fill(32, 1),
|
|
139
|
+
previousCounter: 0,
|
|
140
|
+
senderChain: {
|
|
141
|
+
senderRatchetKey: senderRatchetPub,
|
|
142
|
+
senderRatchetKeyPrivate: fill(32, 3),
|
|
143
|
+
chainKey: { index: 0, key: fill(32, 4) },
|
|
144
|
+
messageKeys: []
|
|
145
|
+
},
|
|
146
|
+
receiverChains: [],
|
|
147
|
+
remoteIdentityPublic: fill(33, 8),
|
|
148
|
+
remoteRegistrationId: 99,
|
|
149
|
+
localRegistrationId: 11,
|
|
150
|
+
aliceBaseKey,
|
|
151
|
+
pendingPreKey: { preKeyId: 42, signedPreKeyId: 7, baseKey: aliceBaseKey }
|
|
152
|
+
}),
|
|
153
|
+
previousSessions: []
|
|
154
|
+
})).finish();
|
|
155
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_LID, protoBytes);
|
|
156
|
+
const stored = keys.raw['session']?.[UPSTREAM_SESSION_KEY_LID];
|
|
157
|
+
const entry = Object.values(stored._sessions)[0];
|
|
158
|
+
expect(entry.currentRatchet.lastRemoteEphemeralKey).not.toBe(Buffer.from(senderRatchetPub).toString('base64'));
|
|
159
|
+
});
|
|
160
|
+
test('baseKeyType: pendingPreKey present → OURS (alice), absent → THEIRS (bob)', async () => {
|
|
161
|
+
// Regression: previously set OURS whenever aliceBaseKey existed
|
|
162
|
+
// (always), making upstream `getSession(byBaseKey)` throw.
|
|
163
|
+
const baseKeyTypeFor = async (withPendingPreKey) => {
|
|
164
|
+
const { wrapped, keys } = await makeWrapped();
|
|
165
|
+
const aliceBaseKey = fill(33, 7);
|
|
166
|
+
const session = bridgeProto.SessionStructure.create({
|
|
167
|
+
sessionVersion: 3,
|
|
168
|
+
rootKey: fill(32, 1),
|
|
169
|
+
previousCounter: 0,
|
|
170
|
+
senderChain: {
|
|
171
|
+
senderRatchetKey: fill(33, 2),
|
|
172
|
+
senderRatchetKeyPrivate: fill(32, 3),
|
|
173
|
+
chainKey: { index: 0, key: fill(32, 4) },
|
|
174
|
+
messageKeys: []
|
|
175
|
+
},
|
|
176
|
+
receiverChains: withPendingPreKey
|
|
177
|
+
? []
|
|
178
|
+
: [
|
|
179
|
+
{
|
|
180
|
+
senderRatchetKey: fill(33, 5),
|
|
181
|
+
chainKey: { index: 1, key: fill(32, 6) },
|
|
182
|
+
messageKeys: []
|
|
183
|
+
}
|
|
184
|
+
],
|
|
185
|
+
remoteIdentityPublic: fill(33, 8),
|
|
186
|
+
remoteRegistrationId: 1,
|
|
187
|
+
aliceBaseKey,
|
|
188
|
+
...(withPendingPreKey ? { pendingPreKey: { preKeyId: 1, signedPreKeyId: 2, baseKey: aliceBaseKey } } : {})
|
|
189
|
+
});
|
|
190
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_PN, bridgeProto.RecordStructure.encode(bridgeProto.RecordStructure.create({ currentSession: session, previousSessions: [] })).finish());
|
|
191
|
+
const stored = keys.raw['session']?.[UPSTREAM_SESSION_KEY_PN];
|
|
192
|
+
return Object.values(stored._sessions)[0].indexInfo.baseKeyType;
|
|
193
|
+
};
|
|
194
|
+
expect(await baseKeyTypeFor(true)).toBe(1); // OURS
|
|
195
|
+
expect(await baseKeyTypeFor(false)).toBe(2); // THEIRS
|
|
196
|
+
});
|
|
197
|
+
test('multi-session: currentSession + previousSessions[] all land in upstream `_sessions`', async () => {
|
|
198
|
+
const { wrapped, keys } = await makeWrapped();
|
|
199
|
+
const mkSession = (rootSeed, baseKeySeed) => bridgeProto.SessionStructure.create({
|
|
200
|
+
sessionVersion: 3,
|
|
201
|
+
rootKey: fill(32, rootSeed),
|
|
202
|
+
previousCounter: 0,
|
|
203
|
+
senderChain: {
|
|
204
|
+
senderRatchetKey: fill(33, rootSeed * 3),
|
|
205
|
+
senderRatchetKeyPrivate: fill(32, rootSeed * 5),
|
|
206
|
+
chainKey: { index: 0, key: fill(32, rootSeed * 7) },
|
|
207
|
+
messageKeys: []
|
|
208
|
+
},
|
|
209
|
+
receiverChains: [
|
|
210
|
+
{
|
|
211
|
+
senderRatchetKey: fill(33, rootSeed * 11),
|
|
212
|
+
chainKey: { index: 1, key: fill(32, rootSeed * 13) },
|
|
213
|
+
messageKeys: []
|
|
214
|
+
}
|
|
215
|
+
],
|
|
216
|
+
remoteIdentityPublic: fill(33, 8),
|
|
217
|
+
remoteRegistrationId: 1,
|
|
218
|
+
aliceBaseKey: fill(33, baseKeySeed)
|
|
219
|
+
});
|
|
220
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_LID, bridgeProto.RecordStructure.encode(bridgeProto.RecordStructure.create({
|
|
221
|
+
currentSession: mkSession(1, 100),
|
|
222
|
+
previousSessions: [mkSession(2, 200), mkSession(3, 250)]
|
|
223
|
+
})).finish());
|
|
224
|
+
const stored = keys.raw['session']?.[UPSTREAM_SESSION_KEY_LID];
|
|
225
|
+
expect(stored.version).toBe('v1');
|
|
226
|
+
expect(Object.keys(stored._sessions).length).toBe(3);
|
|
227
|
+
const open = Object.values(stored._sessions).filter(e => e.indexInfo.closed === -1);
|
|
228
|
+
expect(open.length).toBe(1);
|
|
229
|
+
expect(open[0].indexInfo.baseKey).toBe(Buffer.from(fill(33, 100)).toString('base64'));
|
|
230
|
+
// Front of Rust's previous_sessions = newest archived → must get
|
|
231
|
+
// the LARGER `closed` timestamp so upstream's removeOldSessions
|
|
232
|
+
// evicts the oldest first.
|
|
233
|
+
const closedEntries = Object.values(stored._sessions).filter(e => e.indexInfo.closed > 0);
|
|
234
|
+
const newer = closedEntries.find(e => e.indexInfo.baseKey === Buffer.from(fill(33, 200)).toString('base64'));
|
|
235
|
+
const older = closedEntries.find(e => e.indexInfo.baseKey === Buffer.from(fill(33, 250)).toString('base64'));
|
|
236
|
+
expect(newer.indexInfo.closed).toBeGreaterThan(older.indexInfo.closed);
|
|
237
|
+
});
|
|
238
|
+
test('pendingPreKey round-trips with field rename `signedPreKeyId↔signedKeyId`', async () => {
|
|
239
|
+
const { wrapped, keys } = await makeWrapped();
|
|
240
|
+
const aliceBaseKey = fill(33, 7);
|
|
241
|
+
await wrapped.set('session', BRIDGE_SESSION_KEY_LID, bridgeProto.RecordStructure.encode(bridgeProto.RecordStructure.create({
|
|
242
|
+
currentSession: bridgeProto.SessionStructure.create({
|
|
243
|
+
sessionVersion: 3,
|
|
244
|
+
rootKey: fill(32, 1),
|
|
245
|
+
previousCounter: 0,
|
|
246
|
+
senderChain: {
|
|
247
|
+
senderRatchetKey: fill(33, 2),
|
|
248
|
+
senderRatchetKeyPrivate: fill(32, 3),
|
|
249
|
+
chainKey: { index: 0, key: fill(32, 4) },
|
|
250
|
+
messageKeys: []
|
|
251
|
+
},
|
|
252
|
+
receiverChains: [],
|
|
253
|
+
remoteIdentityPublic: fill(33, 8),
|
|
254
|
+
remoteRegistrationId: 1,
|
|
255
|
+
aliceBaseKey,
|
|
256
|
+
pendingPreKey: { preKeyId: 314, signedPreKeyId: 271, baseKey: aliceBaseKey }
|
|
257
|
+
}),
|
|
258
|
+
previousSessions: []
|
|
259
|
+
})).finish());
|
|
260
|
+
const stored = keys.raw['session']?.[UPSTREAM_SESSION_KEY_LID];
|
|
261
|
+
const entry = Object.values(stored._sessions)[0];
|
|
262
|
+
expect(entry.pendingPreKey.preKeyId).toBe(314);
|
|
263
|
+
expect(entry.pendingPreKey.signedKeyId).toBe(271); // rename: signedPreKeyId → signedKeyId
|
|
264
|
+
expect(entry.pendingPreKey.baseKey).toBe(Buffer.from(aliceBaseKey).toString('base64'));
|
|
265
|
+
const protoOut = (await wrapped.get('session', BRIDGE_SESSION_KEY_LID));
|
|
266
|
+
const decoded = bridgeProto.RecordStructure.decode(protoOut);
|
|
267
|
+
expect(decoded.currentSession?.pendingPreKey?.preKeyId).toBe(314);
|
|
268
|
+
expect(decoded.currentSession?.pendingPreKey?.signedPreKeyId).toBe(271);
|
|
269
|
+
});
|
|
270
|
+
test('aliceBaseKey preserved on JS→bridge regardless of baseKeyType (bob-side restoration)', async () => {
|
|
271
|
+
// Regression: previously dropped aliceBaseKey when baseKeyType=THEIRS,
|
|
272
|
+
// breaking Rust's `find_matching_previous_session_index` lookup on
|
|
273
|
+
// subsequent PreKeySignal arrivals.
|
|
274
|
+
const { wrapped, keys } = await makeWrapped();
|
|
275
|
+
const baseKey = Buffer.alloc(33, 0xa0);
|
|
276
|
+
keys.raw['session'] = {
|
|
277
|
+
[UPSTREAM_SESSION_KEY_LID]: {
|
|
278
|
+
_sessions: {
|
|
279
|
+
[baseKey.toString('base64')]: {
|
|
280
|
+
registrationId: 4242,
|
|
281
|
+
currentRatchet: {
|
|
282
|
+
ephemeralKeyPair: {
|
|
283
|
+
pubKey: Buffer.alloc(33, 0xd0).toString('base64'),
|
|
284
|
+
privKey: Buffer.alloc(32, 0xe0).toString('base64')
|
|
285
|
+
},
|
|
286
|
+
lastRemoteEphemeralKey: Buffer.alloc(33, 0xf0).toString('base64'),
|
|
287
|
+
previousCounter: 0,
|
|
288
|
+
rootKey: Buffer.alloc(32, 0xb0).toString('base64')
|
|
289
|
+
},
|
|
290
|
+
indexInfo: {
|
|
291
|
+
baseKey: baseKey.toString('base64'),
|
|
292
|
+
baseKeyType: 2, // THEIRS — we're bob
|
|
293
|
+
closed: -1,
|
|
294
|
+
used: Date.now(),
|
|
295
|
+
created: Date.now(),
|
|
296
|
+
remoteIdentityKey: Buffer.alloc(33, 0xc0).toString('base64')
|
|
297
|
+
},
|
|
298
|
+
_chains: {}
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
version: 'v1'
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
const protoOut = (await wrapped.get('session', BRIDGE_SESSION_KEY_LID));
|
|
305
|
+
const decoded = bridgeProto.RecordStructure.decode(protoOut);
|
|
306
|
+
expect(Buffer.from(decoded.currentSession.aliceBaseKey).equals(baseKey)).toBe(true);
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
//# sourceMappingURL=wrap-legacy-store-session.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrap-legacy-store-session.test.js","sourceRoot":"","sources":["../../../src/Utils/__tests__/wrap-legacy-store-session.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface BoomPayload {
|
|
2
|
+
readonly statusCode: number;
|
|
3
|
+
readonly error: string;
|
|
4
|
+
readonly message: string;
|
|
5
|
+
}
|
|
6
|
+
export interface BoomOutput {
|
|
7
|
+
readonly statusCode: number;
|
|
8
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
9
|
+
readonly payload: BoomPayload;
|
|
10
|
+
}
|
|
11
|
+
export interface BoomOptions<TData = unknown> {
|
|
12
|
+
readonly statusCode?: number;
|
|
13
|
+
readonly data?: TData;
|
|
14
|
+
readonly cause?: unknown;
|
|
15
|
+
}
|
|
16
|
+
export declare class Boom<TData = unknown> extends Error {
|
|
17
|
+
readonly isBoom: true;
|
|
18
|
+
readonly statusCode: number;
|
|
19
|
+
readonly data?: TData;
|
|
20
|
+
constructor(message?: string | Error, options?: BoomOptions<TData>);
|
|
21
|
+
get isServer(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* `@hapi/boom`-compatible nested status info. Computed on every access
|
|
24
|
+
* (no `#private` cache) so the getter survives prototype-chain rewrites
|
|
25
|
+
* by other Boom-shaped wrappers — concretely, `new HapiBoom(ourBoom)`
|
|
26
|
+
* coerces the input to be `instanceof Boom` via `Object.setPrototypeOf`
|
|
27
|
+
* but never calls our constructor, leaving any private slot uninitialized
|
|
28
|
+
* and crashing the getter at runtime.
|
|
29
|
+
*/
|
|
30
|
+
get output(): BoomOutput;
|
|
31
|
+
static isBoom(err: unknown): err is Boom;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=boom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boom.d.ts","sourceRoot":"","sources":["../../src/Utils/boom.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAClD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAC7B;AAED,MAAM,WAAW,WAAW,CAAC,KAAK,GAAG,OAAO;IAC3C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CACxB;AA2BD,qBAAa,IAAI,CAAC,KAAK,GAAG,OAAO,CAAE,SAAQ,KAAK;IAC/C,QAAQ,CAAC,MAAM,EAAG,IAAI,CAAS;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,CAAA;gBAET,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,OAAO,GAAE,WAAW,CAAC,KAAK,CAAM;IAQtE,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED;;;;;;;OAOG;IACH,IAAI,MAAM,IAAI,UAAU,CAUvB;IAED,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,IAAI;CAGxC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const EMPTY_HEADERS = Object.freeze({});
|
|
2
|
+
const STATUS_PHRASES = Object.freeze({
|
|
3
|
+
400: 'Bad Request',
|
|
4
|
+
401: 'Unauthorized',
|
|
5
|
+
403: 'Forbidden',
|
|
6
|
+
404: 'Not Found',
|
|
7
|
+
408: 'Request Timeout',
|
|
8
|
+
411: 'Length Required',
|
|
9
|
+
428: 'Precondition Required',
|
|
10
|
+
440: 'Login Timeout',
|
|
11
|
+
499: 'Client Closed Request',
|
|
12
|
+
500: 'Internal Server Error',
|
|
13
|
+
503: 'Service Unavailable',
|
|
14
|
+
515: 'HTTP Version Not Supported'
|
|
15
|
+
});
|
|
16
|
+
function statusPhrase(code) {
|
|
17
|
+
const known = STATUS_PHRASES[code];
|
|
18
|
+
if (known !== undefined)
|
|
19
|
+
return known;
|
|
20
|
+
if (code >= 500)
|
|
21
|
+
return 'Server Error';
|
|
22
|
+
if (code >= 400)
|
|
23
|
+
return 'Client Error';
|
|
24
|
+
return 'Error';
|
|
25
|
+
}
|
|
26
|
+
export class Boom extends Error {
|
|
27
|
+
constructor(message, options = {}) {
|
|
28
|
+
const msg = message instanceof Error ? message.message : (message ?? 'Unknown error');
|
|
29
|
+
super(msg, options.cause !== undefined ? { cause: options.cause } : undefined);
|
|
30
|
+
this.isBoom = true;
|
|
31
|
+
this.statusCode = options.statusCode ?? 500;
|
|
32
|
+
if (options.data !== undefined)
|
|
33
|
+
this.data = options.data;
|
|
34
|
+
if (message instanceof Error && message.stack)
|
|
35
|
+
this.stack = message.stack;
|
|
36
|
+
}
|
|
37
|
+
get isServer() {
|
|
38
|
+
return this.statusCode >= 500;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* `@hapi/boom`-compatible nested status info. Computed on every access
|
|
42
|
+
* (no `#private` cache) so the getter survives prototype-chain rewrites
|
|
43
|
+
* by other Boom-shaped wrappers — concretely, `new HapiBoom(ourBoom)`
|
|
44
|
+
* coerces the input to be `instanceof Boom` via `Object.setPrototypeOf`
|
|
45
|
+
* but never calls our constructor, leaving any private slot uninitialized
|
|
46
|
+
* and crashing the getter at runtime.
|
|
47
|
+
*/
|
|
48
|
+
get output() {
|
|
49
|
+
return {
|
|
50
|
+
statusCode: this.statusCode,
|
|
51
|
+
headers: EMPTY_HEADERS,
|
|
52
|
+
payload: {
|
|
53
|
+
statusCode: this.statusCode,
|
|
54
|
+
error: statusPhrase(this.statusCode),
|
|
55
|
+
message: this.message
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
static isBoom(err) {
|
|
60
|
+
return typeof err === 'object' && err !== null && err.isBoom === true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=boom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boom.js","sourceRoot":"","sources":["../../src/Utils/boom.ts"],"names":[],"mappings":"AAkBA,MAAM,aAAa,GAAqC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAEzE,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IACpC,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,cAAc;IACnB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,uBAAuB;IAC5B,GAAG,EAAE,qBAAqB;IAC1B,GAAG,EAAE,4BAA4B;CACxB,CAA4C,CAAA;AAEtD,SAAS,YAAY,CAAC,IAAY;IACjC,MAAM,KAAK,GAAI,cAAmD,CAAC,IAAI,CAAC,CAAA;IACxE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IACrC,IAAI,IAAI,IAAI,GAAG;QAAE,OAAO,cAAc,CAAA;IACtC,IAAI,IAAI,IAAI,GAAG;QAAE,OAAO,cAAc,CAAA;IACtC,OAAO,OAAO,CAAA;AACf,CAAC;AAED,MAAM,OAAO,IAAsB,SAAQ,KAAK;IAK/C,YAAY,OAAwB,EAAE,UAA8B,EAAE;QACrE,MAAM,GAAG,GAAG,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,eAAe,CAAC,CAAA;QACrF,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QANtE,WAAM,GAAG,IAAa,CAAA;QAO9B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,GAAG,CAAA;QAC3C,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;QACxD,IAAI,OAAO,YAAY,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAA;IAC1E,CAAC;IAED,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,UAAU,IAAI,GAAG,CAAA;IAC9B,CAAC;IAED;;;;;;;OAOG;IACH,IAAI,MAAM;QACT,OAAO;YACN,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE;gBACR,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;gBACpC,OAAO,EAAE,IAAI,CAAC,OAAO;aACrB;SACD,CAAA;IACF,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,GAAY;QACzB,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAK,GAA4B,CAAC,MAAM,KAAK,IAAI,CAAA;IAChG,CAAC;CACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-utils.d.ts","sourceRoot":"","sources":["../../src/Utils/browser-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"browser-utils.d.ts","sourceRoot":"","sources":["../../src/Utils/browser-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAgBpD,eAAO,MAAM,QAAQ,EAAE,WAMtB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-buffer.d.ts","sourceRoot":"","sources":["../../src/Utils/event-buffer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,
|
|
1
|
+
{"version":3,"file":"event-buffer.d.ts","sourceRoot":"","sources":["../../src/Utils/event-buffer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAmB,MAAM,mBAAmB,CAAA;AAE7E;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,mBAuClC,CAAA"}
|