@peers-app/peers-sdk 0.1.4

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.
Files changed (234) hide show
  1. package/README.md +1 -0
  2. package/dist/context/data-context.d.ts +31 -0
  3. package/dist/context/data-context.js +56 -0
  4. package/dist/context/index.d.ts +3 -0
  5. package/dist/context/index.js +19 -0
  6. package/dist/context/user-context-singleton.d.ts +11 -0
  7. package/dist/context/user-context-singleton.js +121 -0
  8. package/dist/context/user-context.d.ts +55 -0
  9. package/dist/context/user-context.js +205 -0
  10. package/dist/data/assistants.d.ts +68 -0
  11. package/dist/data/assistants.js +64 -0
  12. package/dist/data/change-tracking.d.ts +219 -0
  13. package/dist/data/change-tracking.js +119 -0
  14. package/dist/data/channels.d.ts +29 -0
  15. package/dist/data/channels.js +25 -0
  16. package/dist/data/data-locks.d.ts +37 -0
  17. package/dist/data/data-locks.js +180 -0
  18. package/dist/data/data-locks.test.d.ts +1 -0
  19. package/dist/data/data-locks.test.js +456 -0
  20. package/dist/data/device-sync-info.d.ts +19 -0
  21. package/dist/data/device-sync-info.js +24 -0
  22. package/dist/data/devices.d.ts +51 -0
  23. package/dist/data/devices.js +36 -0
  24. package/dist/data/embeddings.d.ts +47 -0
  25. package/dist/data/embeddings.js +36 -0
  26. package/dist/data/files/file-read-stream.d.ts +27 -0
  27. package/dist/data/files/file-read-stream.js +195 -0
  28. package/dist/data/files/file-write-stream.d.ts +20 -0
  29. package/dist/data/files/file-write-stream.js +113 -0
  30. package/dist/data/files/file.types.d.ts +47 -0
  31. package/dist/data/files/file.types.js +55 -0
  32. package/dist/data/files/files.d.ts +28 -0
  33. package/dist/data/files/files.js +127 -0
  34. package/dist/data/files/files.test.d.ts +1 -0
  35. package/dist/data/files/files.test.js +728 -0
  36. package/dist/data/files/index.d.ts +4 -0
  37. package/dist/data/files/index.js +23 -0
  38. package/dist/data/group-member-roles.d.ts +9 -0
  39. package/dist/data/group-member-roles.js +25 -0
  40. package/dist/data/group-members.d.ts +39 -0
  41. package/dist/data/group-members.js +68 -0
  42. package/dist/data/group-members.test.d.ts +1 -0
  43. package/dist/data/group-members.test.js +287 -0
  44. package/dist/data/group-permissions.d.ts +8 -0
  45. package/dist/data/group-permissions.js +73 -0
  46. package/dist/data/group-share.d.ts +50 -0
  47. package/dist/data/group-share.js +196 -0
  48. package/dist/data/groups.d.ts +50 -0
  49. package/dist/data/groups.js +73 -0
  50. package/dist/data/groups.test.d.ts +1 -0
  51. package/dist/data/groups.test.js +153 -0
  52. package/dist/data/index.d.ts +31 -0
  53. package/dist/data/index.js +47 -0
  54. package/dist/data/knowledge/knowledge-frames.d.ts +34 -0
  55. package/dist/data/knowledge/knowledge-frames.js +34 -0
  56. package/dist/data/knowledge/knowledge-links.d.ts +30 -0
  57. package/dist/data/knowledge/knowledge-links.js +25 -0
  58. package/dist/data/knowledge/knowledge-values.d.ts +35 -0
  59. package/dist/data/knowledge/knowledge-values.js +35 -0
  60. package/dist/data/knowledge/peer-types.d.ts +112 -0
  61. package/dist/data/knowledge/peer-types.js +27 -0
  62. package/dist/data/knowledge/predicates.d.ts +34 -0
  63. package/dist/data/knowledge/predicates.js +27 -0
  64. package/dist/data/messages.d.ts +57 -0
  65. package/dist/data/messages.js +97 -0
  66. package/dist/data/orm/client-proxy.data-source.d.ts +27 -0
  67. package/dist/data/orm/client-proxy.data-source.js +65 -0
  68. package/dist/data/orm/cursor.d.ts +25 -0
  69. package/dist/data/orm/cursor.js +47 -0
  70. package/dist/data/orm/cursor.test.d.ts +1 -0
  71. package/dist/data/orm/cursor.test.js +315 -0
  72. package/dist/data/orm/data-query.d.ts +96 -0
  73. package/dist/data/orm/data-query.js +208 -0
  74. package/dist/data/orm/data-query.mongo.d.ts +17 -0
  75. package/dist/data/orm/data-query.mongo.js +267 -0
  76. package/dist/data/orm/data-query.mongo.test.d.ts +1 -0
  77. package/dist/data/orm/data-query.mongo.test.js +398 -0
  78. package/dist/data/orm/data-query.sqlite.d.ts +14 -0
  79. package/dist/data/orm/data-query.sqlite.js +297 -0
  80. package/dist/data/orm/data-query.sqlite.test.d.ts +1 -0
  81. package/dist/data/orm/data-query.sqlite.test.js +377 -0
  82. package/dist/data/orm/data-query.test.d.ts +1 -0
  83. package/dist/data/orm/data-query.test.js +553 -0
  84. package/dist/data/orm/decorators.d.ts +6 -0
  85. package/dist/data/orm/decorators.js +21 -0
  86. package/dist/data/orm/dependency-injection.test.d.ts +1 -0
  87. package/dist/data/orm/dependency-injection.test.js +171 -0
  88. package/dist/data/orm/doc.d.ts +26 -0
  89. package/dist/data/orm/doc.js +124 -0
  90. package/dist/data/orm/event-registry.d.ts +24 -0
  91. package/dist/data/orm/event-registry.js +40 -0
  92. package/dist/data/orm/event-registry.test.d.ts +1 -0
  93. package/dist/data/orm/event-registry.test.js +44 -0
  94. package/dist/data/orm/factory.d.ts +8 -0
  95. package/dist/data/orm/factory.js +147 -0
  96. package/dist/data/orm/index.d.ts +16 -0
  97. package/dist/data/orm/index.js +32 -0
  98. package/dist/data/orm/multi-cursors.d.ts +11 -0
  99. package/dist/data/orm/multi-cursors.js +146 -0
  100. package/dist/data/orm/multi-cursors.test.d.ts +1 -0
  101. package/dist/data/orm/multi-cursors.test.js +455 -0
  102. package/dist/data/orm/sql-db.d.ts +6 -0
  103. package/dist/data/orm/sql-db.js +2 -0
  104. package/dist/data/orm/sql.data-source.d.ts +38 -0
  105. package/dist/data/orm/sql.data-source.js +379 -0
  106. package/dist/data/orm/sql.data-source.test.d.ts +1 -0
  107. package/dist/data/orm/sql.data-source.test.js +406 -0
  108. package/dist/data/orm/subscribable.data-source.d.ts +25 -0
  109. package/dist/data/orm/subscribable.data-source.js +72 -0
  110. package/dist/data/orm/table-container-events.test.d.ts +1 -0
  111. package/dist/data/orm/table-container-events.test.js +93 -0
  112. package/dist/data/orm/table-container.d.ts +39 -0
  113. package/dist/data/orm/table-container.js +96 -0
  114. package/dist/data/orm/table-definitions.system.d.ts +9 -0
  115. package/dist/data/orm/table-definitions.system.js +29 -0
  116. package/dist/data/orm/table-definitions.type.d.ts +19 -0
  117. package/dist/data/orm/table-definitions.type.js +2 -0
  118. package/dist/data/orm/table-dependencies.d.ts +32 -0
  119. package/dist/data/orm/table-dependencies.js +2 -0
  120. package/dist/data/orm/table.d.ts +42 -0
  121. package/dist/data/orm/table.event-source.test.d.ts +1 -0
  122. package/dist/data/orm/table.event-source.test.js +341 -0
  123. package/dist/data/orm/table.js +244 -0
  124. package/dist/data/orm/types.d.ts +20 -0
  125. package/dist/data/orm/types.js +115 -0
  126. package/dist/data/orm/types.test.d.ts +1 -0
  127. package/dist/data/orm/types.test.js +71 -0
  128. package/dist/data/package-permissions.d.ts +7 -0
  129. package/dist/data/package-permissions.js +18 -0
  130. package/dist/data/packages.d.ts +92 -0
  131. package/dist/data/packages.js +90 -0
  132. package/dist/data/peer-events/peer-event-handlers.d.ts +21 -0
  133. package/dist/data/peer-events/peer-event-handlers.js +28 -0
  134. package/dist/data/peer-events/peer-event-types.d.ts +119 -0
  135. package/dist/data/peer-events/peer-event-types.js +29 -0
  136. package/dist/data/peer-events/peer-events.d.ts +41 -0
  137. package/dist/data/peer-events/peer-events.js +102 -0
  138. package/dist/data/persistent-vars.d.ts +87 -0
  139. package/dist/data/persistent-vars.js +230 -0
  140. package/dist/data/tool-tests.d.ts +37 -0
  141. package/dist/data/tool-tests.js +27 -0
  142. package/dist/data/tools.d.ts +358 -0
  143. package/dist/data/tools.js +48 -0
  144. package/dist/data/user-permissions.d.ts +15 -0
  145. package/dist/data/user-permissions.js +39 -0
  146. package/dist/data/user-permissions.test.d.ts +1 -0
  147. package/dist/data/user-permissions.test.js +252 -0
  148. package/dist/data/users.d.ts +38 -0
  149. package/dist/data/users.js +73 -0
  150. package/dist/data/workflow-logs.d.ts +106 -0
  151. package/dist/data/workflow-logs.js +67 -0
  152. package/dist/data/workflow-runs.d.ts +103 -0
  153. package/dist/data/workflow-runs.js +313 -0
  154. package/dist/data/workflows.d.ts +16 -0
  155. package/dist/data/workflows.js +21 -0
  156. package/dist/device/connection.d.ts +41 -0
  157. package/dist/device/connection.js +249 -0
  158. package/dist/device/connection.test.d.ts +1 -0
  159. package/dist/device/connection.test.js +292 -0
  160. package/dist/device/device-election.d.ts +36 -0
  161. package/dist/device/device-election.js +137 -0
  162. package/dist/device/device.d.ts +22 -0
  163. package/dist/device/device.js +110 -0
  164. package/dist/device/device.test.d.ts +1 -0
  165. package/dist/device/device.test.js +203 -0
  166. package/dist/device/get-trust-level.d.ts +3 -0
  167. package/dist/device/get-trust-level.js +87 -0
  168. package/dist/device/socket.type.d.ts +20 -0
  169. package/dist/device/socket.type.js +15 -0
  170. package/dist/device/streamed-socket.d.ts +27 -0
  171. package/dist/device/streamed-socket.js +154 -0
  172. package/dist/device/streamed-socket.test.d.ts +1 -0
  173. package/dist/device/streamed-socket.test.js +44 -0
  174. package/dist/events.d.ts +35 -0
  175. package/dist/events.js +128 -0
  176. package/dist/index.d.ts +33 -0
  177. package/dist/index.js +50 -0
  178. package/dist/keys.d.ts +51 -0
  179. package/dist/keys.js +234 -0
  180. package/dist/keys.test.d.ts +1 -0
  181. package/dist/keys.test.js +215 -0
  182. package/dist/mentions.d.ts +9 -0
  183. package/dist/mentions.js +46 -0
  184. package/dist/observable.d.ts +19 -0
  185. package/dist/observable.js +112 -0
  186. package/dist/observable.test.d.ts +1 -0
  187. package/dist/observable.test.js +183 -0
  188. package/dist/package-loader/get-require.d.ts +10 -0
  189. package/dist/package-loader/get-require.js +31 -0
  190. package/dist/package-loader/index.d.ts +1 -0
  191. package/dist/package-loader/index.js +17 -0
  192. package/dist/package-loader/package-loader.d.ts +16 -0
  193. package/dist/package-loader/package-loader.js +102 -0
  194. package/dist/peers-ui/peers-ui.d.ts +15 -0
  195. package/dist/peers-ui/peers-ui.js +23 -0
  196. package/dist/peers-ui/peers-ui.types.d.ts +35 -0
  197. package/dist/peers-ui/peers-ui.types.js +3 -0
  198. package/dist/rpc-types.d.ts +45 -0
  199. package/dist/rpc-types.js +47 -0
  200. package/dist/serial-json.d.ts +5 -0
  201. package/dist/serial-json.js +186 -0
  202. package/dist/serial-json.test.d.ts +1 -0
  203. package/dist/serial-json.test.js +86 -0
  204. package/dist/system-ids.d.ts +6 -0
  205. package/dist/system-ids.js +10 -0
  206. package/dist/tools/index.d.ts +1 -0
  207. package/dist/tools/index.js +17 -0
  208. package/dist/tools/tools-factory.d.ts +5 -0
  209. package/dist/tools/tools-factory.js +34 -0
  210. package/dist/types/app-nav.d.ts +18 -0
  211. package/dist/types/app-nav.js +10 -0
  212. package/dist/types/assistant-runner-args.d.ts +9 -0
  213. package/dist/types/assistant-runner-args.js +2 -0
  214. package/dist/types/field-type.d.ts +37 -0
  215. package/dist/types/field-type.js +26 -0
  216. package/dist/types/peer-device.d.ts +40 -0
  217. package/dist/types/peer-device.js +14 -0
  218. package/dist/types/peers-package.d.ts +23 -0
  219. package/dist/types/peers-package.js +2 -0
  220. package/dist/types/workflow-logger.d.ts +2 -0
  221. package/dist/types/workflow-logger.js +2 -0
  222. package/dist/types/workflow-run-context.d.ts +12 -0
  223. package/dist/types/workflow-run-context.js +2 -0
  224. package/dist/types/workflow.d.ts +72 -0
  225. package/dist/types/workflow.js +24 -0
  226. package/dist/types/zod-types.d.ts +7 -0
  227. package/dist/types/zod-types.js +12 -0
  228. package/dist/users.query.d.ts +13 -0
  229. package/dist/users.query.js +134 -0
  230. package/dist/utils.d.ts +39 -0
  231. package/dist/utils.js +240 -0
  232. package/dist/utils.test.d.ts +1 -0
  233. package/dist/utils.test.js +140 -0
  234. package/package.json +50 -0
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("../utils");
4
+ const keys_1 = require("../keys");
5
+ const device_1 = require("./device");
6
+ describe(device_1.Device, () => {
7
+ it("should create a new device with valid keys", async () => {
8
+ const userId = (0, utils_1.newid)();
9
+ const device = new device_1.Device(userId);
10
+ expect(device.userId).toBe(userId);
11
+ expect(device.deviceId).toBeTruthy();
12
+ expect(device.publicKey).toBeTruthy();
13
+ expect(device.publicBoxKey).toBeTruthy();
14
+ const msg = "Hello, World!";
15
+ const signedMsg = device.signMessageWithSecretKey(msg);
16
+ expect(signedMsg).toBeTruthy();
17
+ const openedMsg = (0, keys_1.openMessageWithPublicKey)(signedMsg, device.publicKey);
18
+ expect(openedMsg).toBe(msg);
19
+ const obj = { msg };
20
+ const signedObj = device.signObjectWithSecretKey(obj);
21
+ expect(signedObj.contents).toEqual(obj);
22
+ const openedObj = (0, keys_1.openSignedObject)(signedObj);
23
+ expect(openedObj).toEqual(obj);
24
+ const userId2 = (0, utils_1.newid)();
25
+ const device2 = new device_1.Device(userId2);
26
+ {
27
+ const box = device.boxDataWithKeys(obj, device2.publicBoxKey);
28
+ expect(box).toBeTruthy();
29
+ const openedBox = device2.openBoxWithSecretKey(box);
30
+ expect(openedBox).toEqual(obj);
31
+ }
32
+ {
33
+ const box = device.boxDataForDevice(obj, device2);
34
+ expect(box).toBeTruthy();
35
+ const openedBox = device2.openBoxWithSecretKey(box);
36
+ expect(openedBox).toEqual(obj);
37
+ }
38
+ });
39
+ describe("handshakes", () => {
40
+ const userId1 = (0, utils_1.newid)();
41
+ const client = new device_1.Device(userId1);
42
+ const userId2 = (0, utils_1.newid)();
43
+ const server = new device_1.Device(userId2);
44
+ describe("getHandshake", () => {
45
+ it("should return a valid and correct handshake object", async () => {
46
+ const connectionId = (0, utils_1.newid)();
47
+ const handshake = client.getHandshake(connectionId, 'localhost');
48
+ expect(handshake.publicKey).toBe(client.publicKey);
49
+ expect(handshake.contents.userId).toBe(userId1);
50
+ expect(handshake.contents.publicKey).toBe(client.publicKey);
51
+ expect(handshake.contents.publicBoxKey).toBe(client.publicBoxKey);
52
+ expect(handshake.contents.connectionId).toBe(connectionId);
53
+ });
54
+ });
55
+ describe("handshakeResponse", () => {
56
+ it("should return a valid and correct handshake response object", async () => {
57
+ const connectionId = (0, utils_1.newid)();
58
+ const handshake = client.getHandshake(connectionId, 'localhost');
59
+ const handshakeResponse = server.handshakeResponse(handshake, connectionId, 'localhost');
60
+ expect(handshakeResponse.userId).toBe(userId2);
61
+ expect(handshakeResponse.deviceId).toBe(server.deviceId);
62
+ expect(handshakeResponse.publicKey).toBe(server.publicKey);
63
+ expect(handshakeResponse.publicBoxKey).toBe(server.publicBoxKey);
64
+ expect(handshakeResponse.connectionId).toBe(connectionId);
65
+ });
66
+ it("should detect when requests and responses are being forwarded through a different connection", async () => {
67
+ const c1 = {
68
+ connectionId: (0, utils_1.newid)(),
69
+ };
70
+ const c2 = {
71
+ connectionId: (0, utils_1.newid)(),
72
+ };
73
+ const handshake = client.getHandshake(c1.connectionId, 'localhost');
74
+ expect(() => server.handshakeResponse(handshake, c2.connectionId, 'localhost')).toThrow(/Invalid connectionId/);
75
+ });
76
+ it("should throw when the client can't unbox the data", async () => {
77
+ const c1 = {
78
+ connectionId: (0, utils_1.newid)(),
79
+ };
80
+ const c2 = {
81
+ connectionId: c1.connectionId,
82
+ };
83
+ const clientImposter = new device_1.Device(userId1, client.deviceId, {
84
+ secretKey: (0, keys_1.newKeys)().secretKey,
85
+ publicKey: client.publicKey,
86
+ publicBoxKey: client.publicBoxKey
87
+ });
88
+ const handshake = clientImposter.getHandshake(c1.connectionId, 'localhost');
89
+ const response = server.handshakeResponse(handshake, c2.connectionId, 'localhost');
90
+ // expect(() => clientImposter.openBoxWithSecretKey(response)).toThrow(/Message was null or verification failed/);
91
+ });
92
+ it("should detect when requests and responses are being forwarded through a different address", async () => {
93
+ const connToServer = {
94
+ connectionId: (0, utils_1.newid)(),
95
+ };
96
+ const connToClient = {
97
+ connectionId: connToServer.connectionId,
98
+ };
99
+ const manInTheMiddle = new device_1.Device(userId2);
100
+ // const mitmAddress = manInTheMiddle.publicAddress || manInTheMiddle.localAddress;
101
+ // const connToManInTheMiddle = {
102
+ // connectionId: connToServer.connectionId,
103
+ // remoteAddress: mitmAddress
104
+ // };
105
+ // // client is being intercepted
106
+ // {
107
+ // expect(() => {
108
+ // doHandshake(client, connToManInTheMiddle, server, connToClient);
109
+ // }).toThrow(/Invalid client address/);
110
+ // }
111
+ // // server is being intercepted
112
+ // {
113
+ // expect(() => {
114
+ // doHandshake(client, connToServer, server, connToManInTheMiddle);
115
+ // }).toThrow(/Invalid server address/);
116
+ // }
117
+ });
118
+ });
119
+ });
120
+ });
121
+ /*
122
+ describe(ServerDevice, () => {
123
+ describe("newConnection", () => {
124
+ it("should create a new connection with a valid server device and valid client device", async () => {
125
+ const serverDevice = new Device();
126
+ const server = new ServerDevice(serverDevice);
127
+
128
+ const clientDevice = new Device();
129
+
130
+ let conn = await server.newConnection(clientDevice.address);
131
+
132
+ // don't allow RPC calls to the server before the handshake is complete
133
+ {
134
+ const result: any = await conn.rpcCall('ping', {}).catch((err) => err);
135
+ expect(result?.message).toMatch(/Connection not verified/);
136
+ }
137
+
138
+ const handshakeSigned = clientDevice.getHandshake({ connectionId: conn.connectionId, remoteAddress: serverDevice.address });
139
+ const handshakeBoxed = clientDevice.boxDataForDevice(handshakeSigned, serverDevice);
140
+ const responseBox = await conn.completeHandshake(handshakeBoxed);
141
+ const responseSigned = clientDevice.openBoxWithSecretKey(responseBox);
142
+ const response = openSignedObject(responseSigned) as IDeviceHandshake;
143
+ expect(response.userId).toBe(serverDevice.userId);
144
+ expect(response.deviceId).toBe(serverDevice.deviceId);
145
+ expect(response.publicKey).toBe(serverDevice.publicKey);
146
+ expect(response.publicBoxKey).toBe(serverDevice.publicBoxKey);
147
+ expect(response.localAddress).toBe(serverDevice.localAddress);
148
+ expect(response.publicAddress).toBe(serverDevice.publicAddress);
149
+ expect(response.connectionId).toBe(conn.connectionId);
150
+ expect(response.remoteAddress).toBe(clientDevice.address);
151
+
152
+ conn = await server.getConnection(conn.connectionId);
153
+
154
+ expect(conn.server).toEqual({
155
+ userId: serverDevice.userId,
156
+ deviceId: serverDevice.deviceId,
157
+ publicKey: serverDevice.publicKey,
158
+ publicBoxKey: serverDevice.publicBoxKey
159
+ });
160
+ expect(conn.client).toEqual({
161
+ userId: clientDevice.userId,
162
+ deviceId: clientDevice.deviceId,
163
+ publicKey: clientDevice.publicKey,
164
+ publicBoxKey: clientDevice.publicBoxKey
165
+ });
166
+ expect(conn.clientAddress).toBe(clientDevice.address);
167
+ expect(conn.secure).toBe(true);
168
+ expect(conn.verified).toBe(true);
169
+
170
+ // allow RPC calls to the server after the handshake is complete
171
+ {
172
+ const result: any = await conn.rpcCall('ping', {}).catch((err) => err);
173
+ expect(result).toBe('pong');
174
+ }
175
+ });
176
+
177
+ it("should leave connections as insecure if the remoteAddress doesn't match", async () => {
178
+ const serverDevice = new Device();
179
+ const server = new ServerDevice(serverDevice);
180
+
181
+ const clientDevice = new Device();
182
+
183
+ let conn = await server.newConnection(clientDevice.address);
184
+
185
+ const handshakeSigned = clientDevice.getHandshake({ connectionId: conn.connectionId, remoteAddress: 'using proxy' });
186
+ const handshakeBoxed = clientDevice.boxDataForDevice(handshakeSigned, serverDevice);
187
+ const responseBox = await conn.completeHandshake(handshakeBoxed);
188
+ const response = clientDevice.openBoxedAndSignedData(responseBox) as IDeviceHandshake;
189
+ expect(response.userId).toBe(serverDevice.userId);
190
+
191
+ conn = await server.getConnection(conn.connectionId);
192
+
193
+ expect(conn.verified).toBe(true);
194
+ expect(conn.secure).toBe(false);
195
+
196
+ // confirm responses are signed and boxed
197
+ const resultBox = await conn.rpcCall('ping', {}).catch((err) => err) as IDataBox;
198
+ const result = clientDevice.openBoxedAndSignedData(resultBox);
199
+ expect(result).toBe('pong');
200
+ });
201
+ });
202
+ })
203
+ */
@@ -0,0 +1,3 @@
1
+ import { IDeviceInfo, IUser } from "../data";
2
+ import { TrustLevel } from "./socket.type";
3
+ export declare function getTrustLevelFn(me: IUser, serverUrl?: string): (deviceInfo: IDeviceInfo, registerNew?: boolean) => Promise<TrustLevel>;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTrustLevelFn = getTrustLevelFn;
4
+ const data_1 = require("../data");
5
+ const socket_type_1 = require("./socket.type");
6
+ function getTrustLevelFn(me, serverUrl) {
7
+ return async function getTrustLevel(deviceInfo, registerNew) {
8
+ if (deviceInfo.userId === me.userId && deviceInfo.publicKey === me.publicKey && deviceInfo.publicBoxKey === me.publicBoxKey) {
9
+ if (deviceInfo.deviceId === (0, data_1.thisDeviceId)()) {
10
+ // return TrustLevel.Untrusted;
11
+ }
12
+ return socket_type_1.TrustLevel.Trusted;
13
+ }
14
+ // await Devices().delete(deviceInfo.deviceId);
15
+ let [user, device] = await Promise.all([
16
+ (0, data_1.Users)().get(deviceInfo.userId),
17
+ (0, data_1.Devices)().get(deviceInfo.deviceId),
18
+ ]);
19
+ if (user && device && !(deviceInfo.userId === device.userId && deviceInfo.userId === user.userId && deviceInfo.publicKey === user.publicKey && deviceInfo.publicBoxKey === user.publicBoxKey)) {
20
+ console.error(new Date().toISOString(), 'deviceInfo does not align with local info about user and device', { deviceInfo, user, device });
21
+ // TODO check if user has changed their public keys
22
+ return socket_type_1.TrustLevel.Untrusted;
23
+ }
24
+ if (user?.trustLevel && user.trustLevel >= socket_type_1.TrustLevel.Trusted && device?.trustLevel && device.trustLevel >= socket_type_1.TrustLevel.Trusted) {
25
+ device.lastSeen = new Date();
26
+ await (0, data_1.Devices)().update(device);
27
+ return socket_type_1.TrustLevel.Trusted;
28
+ }
29
+ let trustLevel = device?.trustLevel ?? socket_type_1.TrustLevel.Known;
30
+ if (!device) {
31
+ device = {
32
+ deviceId: deviceInfo.deviceId,
33
+ userId: deviceInfo.userId,
34
+ firstSeen: new Date(),
35
+ lastSeen: new Date(),
36
+ serverUrl,
37
+ trustLevel: socket_type_1.TrustLevel.Unknown,
38
+ };
39
+ trustLevel = socket_type_1.TrustLevel.NewDevice;
40
+ }
41
+ else {
42
+ device.lastSeen = new Date();
43
+ }
44
+ let newUser = false;
45
+ if (!user) {
46
+ user = {
47
+ userId: deviceInfo.userId,
48
+ publicKey: deviceInfo.publicKey,
49
+ publicBoxKey: deviceInfo.publicBoxKey,
50
+ name: serverUrl || deviceInfo.userId,
51
+ };
52
+ trustLevel = socket_type_1.TrustLevel.NewUser;
53
+ newUser = true;
54
+ }
55
+ let remoteTrustLevel = socket_type_1.TrustLevel.Unknown;
56
+ // TODO - reimplement this, checks with peers to see if this is an untrusted device
57
+ // for (const [serverUrl, conn] of Object.entries(getActiveConnections())) {
58
+ // if (conn.trustLevel >= TrustLevel.Trusted) {
59
+ // const _remoteTrustLevel: TrustLevel = await conn.emit('getTrustLevel', deviceInfo).catch(err => {
60
+ // console.error(new Date().toISOString(), 'Error getting trust level from server', serverUrl, err);
61
+ // return TrustLevel.Unknown;
62
+ // });
63
+ // console.log(new Date().toISOString(), 'Remote trust level', { _remoteTrustLevel, serverUrl, remoteUrlBeingChecked: serverUrl });
64
+ // if (_remoteTrustLevel < TrustLevel.Unknown) {
65
+ // console.error(new Date().toISOString(), 'Unverified user failed trust check', { user, remoteTrustLevel });
66
+ // device.trustLevel = _remoteTrustLevel;
67
+ // await Devices().save(device);
68
+ // return device.trustLevel;
69
+ // }
70
+ // if (_remoteTrustLevel > TrustLevel.Unknown) {
71
+ // remoteTrustLevel = Math.min(_remoteTrustLevel, device.trustLevel);
72
+ // break;
73
+ // }
74
+ // }
75
+ // }
76
+ if (remoteTrustLevel > socket_type_1.TrustLevel.Unknown && !user.trustLevel) {
77
+ user.trustLevel = socket_type_1.TrustLevel.Known;
78
+ await (0, data_1.Users)().save(user);
79
+ }
80
+ else if (newUser) {
81
+ await (0, data_1.Users)().insert(user);
82
+ }
83
+ device.trustLevel = remoteTrustLevel || trustLevel;
84
+ await (0, data_1.Devices)().save(device);
85
+ return device.trustLevel;
86
+ };
87
+ }
@@ -0,0 +1,20 @@
1
+ export declare const DEFAULT_MAX_CHUNK_SIZE: number;
2
+ export type RPCCallback = (error?: any, result?: any) => void;
3
+ export interface ISocket {
4
+ id?: string;
5
+ connected?: boolean;
6
+ emit(eventName: string, args: any, callback: RPCCallback): void;
7
+ on(eventName: string, handler: ((...args: any[]) => void)): void;
8
+ removeAllListeners(eventName: string): void;
9
+ disconnect(): void;
10
+ }
11
+ export declare enum TrustLevel {
12
+ Malicious = -20,
13
+ Untrusted = -10,
14
+ Unknown = 0,
15
+ NewUser = 10,
16
+ NewDevice = 20,
17
+ Known = 30,
18
+ Trusted = 50,
19
+ Self = 100
20
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TrustLevel = exports.DEFAULT_MAX_CHUNK_SIZE = void 0;
4
+ exports.DEFAULT_MAX_CHUNK_SIZE = 1024 * 1024; // 1MB
5
+ var TrustLevel;
6
+ (function (TrustLevel) {
7
+ TrustLevel[TrustLevel["Malicious"] = -20] = "Malicious";
8
+ TrustLevel[TrustLevel["Untrusted"] = -10] = "Untrusted";
9
+ TrustLevel[TrustLevel["Unknown"] = 0] = "Unknown";
10
+ TrustLevel[TrustLevel["NewUser"] = 10] = "NewUser";
11
+ TrustLevel[TrustLevel["NewDevice"] = 20] = "NewDevice";
12
+ TrustLevel[TrustLevel["Known"] = 30] = "Known";
13
+ TrustLevel[TrustLevel["Trusted"] = 50] = "Trusted";
14
+ TrustLevel[TrustLevel["Self"] = 100] = "Self";
15
+ })(TrustLevel || (exports.TrustLevel = TrustLevel = {}));
@@ -0,0 +1,27 @@
1
+ import { ISocket, RPCCallback } from "./socket.type";
2
+ export interface IMessageChunk {
3
+ messageId: string;
4
+ chunkIndex: number;
5
+ totalChunks?: number;
6
+ eventName?: string;
7
+ data: string;
8
+ }
9
+ export declare class StreamedSocket implements ISocket {
10
+ readonly socket: ISocket;
11
+ maxChunkSize: number;
12
+ readonly safeSocketChunkEventName = "__streamed-socket-chunk";
13
+ readonly safeSocketResponseEventName = "__streamed-socket-response";
14
+ constructor(socket: ISocket, maxChunkSize?: number);
15
+ get id(): string | undefined;
16
+ get connected(): boolean | undefined;
17
+ disconnect(): void;
18
+ private readonly callbacks;
19
+ emit(eventName: string, args: any, callback: RPCCallback): void;
20
+ private handlers;
21
+ on(eventName: string, handler: ((...args: any[]) => void)): void;
22
+ removeAllListeners(eventName: string): void;
23
+ private readonly chunkBuffers;
24
+ private handleChunk;
25
+ private processChunks;
26
+ private handleResponse;
27
+ }
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StreamedSocket = void 0;
4
+ const lodash_1 = require("lodash");
5
+ const serial_json_1 = require("../serial-json");
6
+ const utils_1 = require("../utils");
7
+ const socket_type_1 = require("./socket.type");
8
+ class StreamedSocket {
9
+ socket;
10
+ maxChunkSize;
11
+ safeSocketChunkEventName = '__streamed-socket-chunk';
12
+ safeSocketResponseEventName = '__streamed-socket-response';
13
+ constructor(socket, maxChunkSize = socket_type_1.DEFAULT_MAX_CHUNK_SIZE) {
14
+ this.socket = socket;
15
+ this.maxChunkSize = maxChunkSize;
16
+ socket.on(this.safeSocketChunkEventName, (chunk) => this.handleChunk(chunk));
17
+ }
18
+ get id() {
19
+ return this.socket.id;
20
+ }
21
+ get connected() {
22
+ return this.socket.connected;
23
+ }
24
+ disconnect() {
25
+ this.socket.disconnect();
26
+ }
27
+ callbacks = {};
28
+ emit(eventName, args, callback) {
29
+ const strArgs = (0, serial_json_1.toJSONString)(args);
30
+ // if (strArgs.length < this.maxChunkSize) {
31
+ // // If the data is small enough, send it directly
32
+ // this.socket.emit(eventName, args, callback);
33
+ // return;
34
+ // }
35
+ const messageId = (0, utils_1.newid)();
36
+ if (callback !== lodash_1.noop) {
37
+ this.callbacks[messageId] = callback;
38
+ }
39
+ const chunks = [];
40
+ for (let i = 0; i < strArgs.length; i += this.maxChunkSize) {
41
+ const chunkData = strArgs.slice(i, i + this.maxChunkSize);
42
+ chunks.push({
43
+ messageId,
44
+ chunkIndex: Math.floor(i / this.maxChunkSize),
45
+ data: chunkData
46
+ });
47
+ if (i === 0) {
48
+ // The first chunk contains metadata about the chunks
49
+ chunks[0].eventName = eventName;
50
+ chunks[0].totalChunks = Math.ceil(strArgs.length / this.maxChunkSize);
51
+ }
52
+ }
53
+ if (chunks.length > 1) {
54
+ console.debug(`Sending ${chunks.length} chunks for event ${eventName} with messageId ${messageId}`);
55
+ }
56
+ for (const chunk of chunks) {
57
+ // TODO on error or timeout retry
58
+ this.socket.emit(this.safeSocketChunkEventName, chunk, lodash_1.noop);
59
+ }
60
+ }
61
+ handlers = {};
62
+ on(eventName, handler) {
63
+ this.handlers[eventName] = handler;
64
+ // TODO I think this needs to come back to a handleResult method on this class
65
+ this.socket.on(eventName, handler);
66
+ }
67
+ removeAllListeners(eventName) {
68
+ this.socket.removeAllListeners(eventName);
69
+ delete this.handlers[eventName];
70
+ }
71
+ chunkBuffers = {};
72
+ async handleChunk(chunk) {
73
+ if (!this.chunkBuffers[chunk.messageId]) {
74
+ // TODO handle timeout for chunks and cleanup data to prevent memory leaks
75
+ this.chunkBuffers[chunk.messageId] = [];
76
+ }
77
+ const chunks = this.chunkBuffers[chunk.messageId];
78
+ const chunkIndex = chunk.chunkIndex;
79
+ if (chunkIndex < 0) {
80
+ console.warn(`Received chunk with negative index ${chunk.chunkIndex} for messageId: ${chunk.messageId}`, chunk);
81
+ return;
82
+ }
83
+ chunks[chunkIndex] = chunk;
84
+ const chunkZero = chunks[0];
85
+ if (!chunkZero && chunks.length > 100) {
86
+ console.error(`Received over 100 chunks without a chunkZero for messageId: ${chunk.messageId}. This could indicate a memory attack`, chunk);
87
+ }
88
+ if (chunkZero) {
89
+ if (chunkZero?.totalChunks <= chunkIndex) {
90
+ console.warn(`Received chunk with index ${chunk.chunkIndex} which is greater than totalChunks ${chunkZero.totalChunks} for messageId: ${chunk.messageId}`, chunk);
91
+ return;
92
+ }
93
+ if (chunks.length >= chunkZero.totalChunks) {
94
+ this.processChunks(chunks);
95
+ }
96
+ }
97
+ }
98
+ async processChunks(chunks) {
99
+ try {
100
+ const chunkZero = chunks[0];
101
+ const strData = chunks.map(c => c.data).join('');
102
+ delete this.chunkBuffers[chunkZero.messageId];
103
+ const eventName = chunkZero.eventName;
104
+ const args = (0, serial_json_1.fromJSONString)(strData);
105
+ if (eventName === this.safeSocketResponseEventName) {
106
+ this.handleResponse(args.messageId, args.error, args.result);
107
+ return;
108
+ }
109
+ const handler = this.handlers[eventName];
110
+ if (!handler) {
111
+ throw new Error(`No handler registered for event ${eventName}`);
112
+ }
113
+ let error = undefined;
114
+ let result = undefined;
115
+ try {
116
+ await new Promise((resolve) => {
117
+ handler(args, (...params) => {
118
+ [error, result] = params;
119
+ resolve();
120
+ });
121
+ });
122
+ }
123
+ catch (err) {
124
+ error = err;
125
+ }
126
+ this.emit(this.safeSocketResponseEventName, {
127
+ messageId: chunkZero.messageId,
128
+ error,
129
+ result
130
+ }, lodash_1.noop);
131
+ }
132
+ catch (error) {
133
+ console.error(`Error handling chunked request:`, error);
134
+ return;
135
+ }
136
+ }
137
+ async handleResponse(messageId, error, result) {
138
+ const callback = this.callbacks[messageId];
139
+ if (!callback) {
140
+ console.warn(`No callback found for messageId ${messageId}`);
141
+ }
142
+ delete this.callbacks[messageId];
143
+ if (error) {
144
+ console.error(`Error in SafeSocket response for messageId ${messageId}:`, error);
145
+ }
146
+ try {
147
+ await callback(error, result);
148
+ }
149
+ catch (err) {
150
+ console.error(`Error in SafeSocket callback for messageId ${messageId}:`, err);
151
+ }
152
+ }
153
+ }
154
+ exports.StreamedSocket = StreamedSocket;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const streamed_socket_1 = require("./streamed-socket");
4
+ const utils_1 = require("../utils");
5
+ function createMockSocket() {
6
+ const emittedEvents = [];
7
+ const socket = {
8
+ id: (0, utils_1.newid)(),
9
+ emit(eventName, args, callback) {
10
+ emittedEvents.push({ eventName, args, callback });
11
+ },
12
+ on(eventName, handler) {
13
+ // Simple mock - we'll manually trigger events in tests
14
+ },
15
+ removeAllListeners(eventName) {
16
+ // Simple mock
17
+ },
18
+ disconnect() {
19
+ // Simple mock - we'll assume the socket is disconnected
20
+ },
21
+ };
22
+ return {
23
+ socket,
24
+ getEmittedEvents: () => emittedEvents
25
+ };
26
+ }
27
+ describe('StreamedSocket', () => {
28
+ it('should emit a single chunk for small messages', () => {
29
+ const mock = createMockSocket();
30
+ const streamedSocket = new streamed_socket_1.StreamedSocket(mock.socket, 1000); // Large chunk size
31
+ const testData = { message: 'hello' };
32
+ streamedSocket.emit('test-event', testData, () => { });
33
+ // Should emit a single chunk
34
+ const emittedEvents = mock.getEmittedEvents();
35
+ expect(emittedEvents).toHaveLength(1);
36
+ const chunkEvent = emittedEvents[0];
37
+ expect(chunkEvent.eventName).toBe('__streamed-socket-chunk');
38
+ expect(chunkEvent.args.messageId).toBeTruthy();
39
+ expect(chunkEvent.args.chunkIndex).toBe(0);
40
+ expect(chunkEvent.args.totalChunks).toBe(1);
41
+ expect(chunkEvent.args.eventName).toBe('test-event');
42
+ expect(JSON.parse(chunkEvent.args.data)).toEqual(testData);
43
+ });
44
+ });
@@ -0,0 +1,35 @@
1
+ import { IEventData } from "./rpc-types";
2
+ export type IEventFilter = (event: IEventData) => boolean;
3
+ export type IEventHandler<T = any> = (eventData: IEventData<T>) => boolean | void | Promise<boolean> | Promise<void>;
4
+ export interface ISubscription {
5
+ filter: IEventFilter;
6
+ handler: IEventHandler;
7
+ }
8
+ export interface ISubscriptionResult {
9
+ unsubscribe: () => boolean;
10
+ }
11
+ export declare function subscribe<T = any>(nameOrFilter: string | IEventFilter, handler: IEventHandler<T>): ISubscriptionResult;
12
+ export declare function subscribeDebounce<T = any>(nameOrFilter: string | IEventFilter, handler: IEventHandler<T>, debounceMs: number): ISubscriptionResult;
13
+ export declare function emit(event: IEventData, dontPropagate?: boolean): Promise<boolean>;
14
+ export type IHandler<T> = (data: T) => boolean | void | Promise<boolean> | Promise<void>;
15
+ export interface IEvent<T> {
16
+ eventName: () => string;
17
+ subscribe: (handler: IHandler<T>) => ISubscriptionResult;
18
+ next: () => Promise<T>;
19
+ union: <U>(event: IEvent<U>) => IEvent<T | U>;
20
+ }
21
+ export declare class Event<T> implements IEvent<T> {
22
+ private _eventName;
23
+ constructor(_eventName: string);
24
+ eventName: () => string;
25
+ subscribe: (handler: IHandler<T>, debounceMs?: number) => ISubscriptionResult;
26
+ next: () => Promise<T>;
27
+ union: <U>(event: IEvent<U>) => IEvent<T | U>;
28
+ }
29
+ export declare class Emitter<T> {
30
+ readonly eventName: string;
31
+ constructor(eventName: string);
32
+ readonly event: Event<T>;
33
+ emit(data: T): Promise<boolean>;
34
+ }
35
+ export declare function unionEvents(...events: IEvent<any>[]): IEvent<any>;