@seriousme/opifex 1.11.3 → 2.0.3

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 (531) hide show
  1. package/README.md +99 -40
  2. package/bin/conformanceServer.ts +45 -13
  3. package/bin/demoServer.ts +38 -13
  4. package/bin/mqtt.ts +2 -2
  5. package/client/ConnectionState.ts +2 -0
  6. package/client/client.ts +51 -41
  7. package/client/context.ts +75 -21
  8. package/client/deps.ts +4 -0
  9. package/client/handlers/handleAuth.test.ts +193 -0
  10. package/client/handlers/handleAuth.ts +89 -0
  11. package/client/handlers/handleConnack.test.ts +173 -0
  12. package/client/handlers/handleConnack.ts +16 -6
  13. package/client/handlers/handleDisconnect.test.ts +22 -0
  14. package/client/handlers/handleDisconnect.ts +17 -0
  15. package/client/handlers/handlePacket.test.ts +242 -0
  16. package/client/handlers/handlePacket.ts +19 -5
  17. package/client/handlers/handlePuback.test.ts +99 -0
  18. package/client/handlers/handlePuback.ts +6 -0
  19. package/client/handlers/handlePubcomp.test.ts +112 -0
  20. package/client/handlers/handlePubcomp.ts +5 -0
  21. package/client/handlers/handlePublish.test.ts +188 -0
  22. package/client/handlers/handlePubrec.test.ts +119 -0
  23. package/client/handlers/handlePubrec.ts +5 -1
  24. package/client/handlers/handlePubrel.test.ts +136 -0
  25. package/client/handlers/handleSuback.test.ts +122 -0
  26. package/client/handlers/handleSuback.ts +3 -0
  27. package/client/handlers/handleUnsuback.test.ts +101 -0
  28. package/client/mod.ts +1 -1
  29. package/client/store/memoryStore.ts +2 -2
  30. package/client/store/store.ts +3 -1
  31. package/deno/README.md +1 -2
  32. package/deno/tcpClient.test.ts +75 -0
  33. package/deno/tcpClient.ts +16 -11
  34. package/deno/tcpServer.test.ts +22 -21
  35. package/deno/tcpServer.ts +5 -0
  36. package/deno/tlsServer.test.ts +97 -0
  37. package/deno/tlsServer.ts +42 -0
  38. package/deno/wsServer.test.ts +93 -0
  39. package/deno/wsServer.ts +73 -0
  40. package/dev_utils/generateCert.ts +95 -0
  41. package/dev_utils/mockConn.ts +36 -0
  42. package/dev_utils/mockServer.ts +28 -0
  43. package/dev_utils/mod.ts +30 -3
  44. package/dev_utils/packetHelpers.ts +404 -0
  45. package/dev_utils/test-handlers.ts +98 -0
  46. package/dev_utils/timers.ts +14 -0
  47. package/dev_utils/webStreamPair.test.ts +171 -0
  48. package/dev_utils/webStreamPair.ts +143 -0
  49. package/dist/bin/conformanceServer.js +17 -12
  50. package/dist/bin/conformanceServer.js.map +1 -1
  51. package/dist/bin/demoServer.js +16 -12
  52. package/dist/bin/demoServer.js.map +1 -1
  53. package/dist/bin/mqtt.js +2 -2
  54. package/dist/bin/mqtt.js.map +1 -1
  55. package/dist/client/ConnectionState.d.ts +2 -0
  56. package/dist/client/ConnectionState.d.ts.map +1 -1
  57. package/dist/client/ConnectionState.js +2 -0
  58. package/dist/client/ConnectionState.js.map +1 -1
  59. package/dist/client/client.d.ts +13 -16
  60. package/dist/client/client.d.ts.map +1 -1
  61. package/dist/client/client.js +34 -20
  62. package/dist/client/client.js.map +1 -1
  63. package/dist/client/context.d.ts +11 -3
  64. package/dist/client/context.d.ts.map +1 -1
  65. package/dist/client/context.js +44 -12
  66. package/dist/client/context.js.map +1 -1
  67. package/dist/client/deps.d.ts +3 -2
  68. package/dist/client/deps.d.ts.map +1 -1
  69. package/dist/client/deps.js +1 -1
  70. package/dist/client/deps.js.map +1 -1
  71. package/dist/client/handlers/handleAuth.d.ts +9 -0
  72. package/dist/client/handlers/handleAuth.d.ts.map +1 -0
  73. package/dist/client/handlers/handleAuth.js +66 -0
  74. package/dist/client/handlers/handleAuth.js.map +1 -0
  75. package/dist/client/handlers/handleConnack.d.ts +2 -2
  76. package/dist/client/handlers/handleConnack.d.ts.map +1 -1
  77. package/dist/client/handlers/handleConnack.js +16 -6
  78. package/dist/client/handlers/handleConnack.js.map +1 -1
  79. package/dist/client/handlers/handleDisconnect.d.ts +11 -0
  80. package/dist/client/handlers/handleDisconnect.d.ts.map +1 -0
  81. package/dist/client/handlers/handleDisconnect.js +15 -0
  82. package/dist/client/handlers/handleDisconnect.js.map +1 -0
  83. package/dist/client/handlers/handlePacket.d.ts.map +1 -1
  84. package/dist/client/handlers/handlePacket.js +14 -3
  85. package/dist/client/handlers/handlePacket.js.map +1 -1
  86. package/dist/client/handlers/handlePuback.d.ts.map +1 -1
  87. package/dist/client/handlers/handlePuback.js +5 -0
  88. package/dist/client/handlers/handlePuback.js.map +1 -1
  89. package/dist/client/handlers/handlePubcomp.d.ts.map +1 -1
  90. package/dist/client/handlers/handlePubcomp.js +5 -0
  91. package/dist/client/handlers/handlePubcomp.js.map +1 -1
  92. package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
  93. package/dist/client/handlers/handlePubrec.js +5 -1
  94. package/dist/client/handlers/handlePubrec.js.map +1 -1
  95. package/dist/client/handlers/handleSuback.d.ts +1 -0
  96. package/dist/client/handlers/handleSuback.d.ts.map +1 -1
  97. package/dist/client/handlers/handleSuback.js +3 -0
  98. package/dist/client/handlers/handleSuback.js.map +1 -1
  99. package/dist/client/mod.d.ts +1 -1
  100. package/dist/client/mod.d.ts.map +1 -1
  101. package/dist/client/mod.js +1 -1
  102. package/dist/client/mod.js.map +1 -1
  103. package/dist/client/store/memoryStore.d.ts.map +1 -1
  104. package/dist/client/store/memoryStore.js +2 -2
  105. package/dist/client/store/memoryStore.js.map +1 -1
  106. package/dist/client/store/store.d.ts +2 -1
  107. package/dist/client/store/store.d.ts.map +1 -1
  108. package/dist/client/store/store.js +1 -1
  109. package/dist/client/store/store.js.map +1 -1
  110. package/dist/dev_utils/generateCert.d.ts +11 -0
  111. package/dist/dev_utils/generateCert.d.ts.map +1 -0
  112. package/dist/dev_utils/generateCert.js +76 -0
  113. package/dist/dev_utils/generateCert.js.map +1 -0
  114. package/dist/examples/authHandler.test.d.ts +2 -0
  115. package/dist/examples/authHandler.test.d.ts.map +1 -0
  116. package/dist/examples/authHandler.test.js +123 -0
  117. package/dist/examples/authHandler.test.js.map +1 -0
  118. package/dist/examples/mqtt.test.d.ts +2 -0
  119. package/dist/examples/mqtt.test.d.ts.map +1 -0
  120. package/dist/examples/mqtt.test.js +70 -0
  121. package/dist/examples/mqtt.test.js.map +1 -0
  122. package/dist/examples/mqtts.test.d.ts +2 -0
  123. package/dist/examples/mqtts.test.d.ts.map +1 -0
  124. package/dist/examples/mqtts.test.js +81 -0
  125. package/dist/examples/mqtts.test.js.map +1 -0
  126. package/dist/mqttConn/mqttConn.d.ts +23 -15
  127. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  128. package/dist/mqttConn/mqttConn.js +56 -35
  129. package/dist/mqttConn/mqttConn.js.map +1 -1
  130. package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
  131. package/dist/mqttPacket/BitMask.d.ts.map +1 -1
  132. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  133. package/dist/mqttPacket/Properties.d.ts +2 -2
  134. package/dist/mqttPacket/Properties.d.ts.map +1 -1
  135. package/dist/mqttPacket/Properties.js.map +1 -1
  136. package/dist/mqttPacket/ReasonCode.d.ts +1 -0
  137. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -1
  138. package/dist/mqttPacket/ReasonCode.js +1 -0
  139. package/dist/mqttPacket/ReasonCode.js.map +1 -1
  140. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
  141. package/dist/mqttPacket/auth.d.ts +3 -5
  142. package/dist/mqttPacket/auth.d.ts.map +1 -1
  143. package/dist/mqttPacket/auth.js +31 -30
  144. package/dist/mqttPacket/auth.js.map +1 -1
  145. package/dist/mqttPacket/codec.d.ts +48 -0
  146. package/dist/mqttPacket/codec.d.ts.map +1 -0
  147. package/dist/mqttPacket/codec.js +93 -0
  148. package/dist/mqttPacket/codec.js.map +1 -0
  149. package/dist/mqttPacket/connack.d.ts +4 -5
  150. package/dist/mqttPacket/connack.d.ts.map +1 -1
  151. package/dist/mqttPacket/connack.js +43 -45
  152. package/dist/mqttPacket/connack.js.map +1 -1
  153. package/dist/mqttPacket/connect.d.ts +4 -5
  154. package/dist/mqttPacket/connect.d.ts.map +1 -1
  155. package/dist/mqttPacket/connect.js +156 -157
  156. package/dist/mqttPacket/connect.js.map +1 -1
  157. package/dist/mqttPacket/decoder.d.ts +1 -13
  158. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  159. package/dist/mqttPacket/decoder.js +6 -27
  160. package/dist/mqttPacket/decoder.js.map +1 -1
  161. package/dist/mqttPacket/disconnect.d.ts +4 -5
  162. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  163. package/dist/mqttPacket/disconnect.js +41 -43
  164. package/dist/mqttPacket/disconnect.js.map +1 -1
  165. package/dist/mqttPacket/encoder.d.ts +1 -15
  166. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  167. package/dist/mqttPacket/encoder.js +4 -27
  168. package/dist/mqttPacket/encoder.js.map +1 -1
  169. package/dist/mqttPacket/mod.d.ts +21 -103
  170. package/dist/mqttPacket/mod.d.ts.map +1 -1
  171. package/dist/mqttPacket/mod.js +5 -94
  172. package/dist/mqttPacket/mod.js.map +1 -1
  173. package/dist/mqttPacket/pingreq.d.ts +4 -5
  174. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  175. package/dist/mqttPacket/pingreq.js +11 -13
  176. package/dist/mqttPacket/pingreq.js.map +1 -1
  177. package/dist/mqttPacket/pingres.d.ts +4 -5
  178. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  179. package/dist/mqttPacket/pingres.js +11 -13
  180. package/dist/mqttPacket/pingres.js.map +1 -1
  181. package/dist/mqttPacket/protocolLevels.d.ts +11 -6
  182. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
  183. package/dist/mqttPacket/protocolLevels.js +5 -1
  184. package/dist/mqttPacket/protocolLevels.js.map +1 -1
  185. package/dist/mqttPacket/pubblishAcks.d.ts +4 -5
  186. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
  187. package/dist/mqttPacket/pubblishAcks.js +43 -45
  188. package/dist/mqttPacket/pubblishAcks.js.map +1 -1
  189. package/dist/mqttPacket/publish.d.ts +5 -5
  190. package/dist/mqttPacket/publish.d.ts.map +1 -1
  191. package/dist/mqttPacket/publish.js +53 -55
  192. package/dist/mqttPacket/publish.js.map +1 -1
  193. package/dist/mqttPacket/suback.d.ts +4 -5
  194. package/dist/mqttPacket/suback.d.ts.map +1 -1
  195. package/dist/mqttPacket/suback.js +38 -40
  196. package/dist/mqttPacket/suback.js.map +1 -1
  197. package/dist/mqttPacket/subscribe.d.ts +36 -7
  198. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  199. package/dist/mqttPacket/subscribe.js +90 -89
  200. package/dist/mqttPacket/subscribe.js.map +1 -1
  201. package/dist/mqttPacket/types.d.ts +1 -8
  202. package/dist/mqttPacket/types.d.ts.map +1 -1
  203. package/dist/mqttPacket/unsuback.d.ts +4 -5
  204. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  205. package/dist/mqttPacket/unsuback.js +32 -34
  206. package/dist/mqttPacket/unsuback.js.map +1 -1
  207. package/dist/mqttPacket/unsubscribe.d.ts +23 -6
  208. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  209. package/dist/mqttPacket/unsubscribe.js +45 -44
  210. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  211. package/dist/mqttPacket/validators.d.ts +4 -16
  212. package/dist/mqttPacket/validators.d.ts.map +1 -1
  213. package/dist/mqttPacket/validators.js +5 -26
  214. package/dist/mqttPacket/validators.js.map +1 -1
  215. package/dist/node/tcpClient.d.ts +1 -1
  216. package/dist/node/tcpClient.d.ts.map +1 -1
  217. package/dist/node/tcpClient.js +12 -7
  218. package/dist/node/tcpClient.js.map +1 -1
  219. package/dist/node/tcpServer.d.ts.map +1 -1
  220. package/dist/node/tcpServer.js +4 -0
  221. package/dist/node/tcpServer.js.map +1 -1
  222. package/dist/node/tlsServer.d.ts +19 -0
  223. package/dist/node/tlsServer.d.ts.map +1 -0
  224. package/dist/node/tlsServer.js +58 -0
  225. package/dist/node/tlsServer.js.map +1 -0
  226. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  227. package/dist/node/wrapNodeSocket.js +6 -28
  228. package/dist/node/wrapNodeSocket.js.map +1 -1
  229. package/dist/persistence/basicPersistence.d.ts +36 -0
  230. package/dist/persistence/basicPersistence.d.ts.map +1 -0
  231. package/dist/persistence/basicPersistence.js +306 -0
  232. package/dist/persistence/basicPersistence.js.map +1 -0
  233. package/dist/persistence/deps.d.ts +3 -2
  234. package/dist/persistence/deps.d.ts.map +1 -1
  235. package/dist/persistence/deps.js +2 -1
  236. package/dist/persistence/deps.js.map +1 -1
  237. package/dist/persistence/memory/memoryPersistence.d.ts +6 -23
  238. package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
  239. package/dist/persistence/memory/memoryPersistence.js +12 -115
  240. package/dist/persistence/memory/memoryPersistence.js.map +1 -1
  241. package/dist/persistence/memory/memoryStorage.d.ts +45 -0
  242. package/dist/persistence/memory/memoryStorage.d.ts.map +1 -0
  243. package/dist/persistence/memory/memoryStorage.js +143 -0
  244. package/dist/persistence/memory/memoryStorage.js.map +1 -0
  245. package/dist/persistence/mod.d.ts +3 -3
  246. package/dist/persistence/mod.d.ts.map +1 -1
  247. package/dist/persistence/mod.js +6 -1
  248. package/dist/persistence/mod.js.map +1 -1
  249. package/dist/persistence/persistence.d.ts +44 -69
  250. package/dist/persistence/persistence.d.ts.map +1 -1
  251. package/dist/persistence/persistence.js +1 -2
  252. package/dist/persistence/persistence.js.map +1 -1
  253. package/dist/persistence/sqlite/sqliteDatabase.d.ts +46 -0
  254. package/dist/persistence/sqlite/sqliteDatabase.d.ts.map +1 -0
  255. package/dist/persistence/sqlite/sqliteDatabase.js +215 -0
  256. package/dist/persistence/sqlite/sqliteDatabase.js.map +1 -0
  257. package/dist/persistence/sqlite/sqlitePersistence.d.ts +16 -0
  258. package/dist/persistence/sqlite/sqlitePersistence.d.ts.map +1 -0
  259. package/dist/persistence/sqlite/sqlitePersistence.js +29 -0
  260. package/dist/persistence/sqlite/sqlitePersistence.js.map +1 -0
  261. package/dist/persistence/sqlite/sqliteStorage.d.ts +36 -0
  262. package/dist/persistence/sqlite/sqliteStorage.d.ts.map +1 -0
  263. package/dist/persistence/sqlite/sqliteStorage.js +194 -0
  264. package/dist/persistence/sqlite/sqliteStorage.js.map +1 -0
  265. package/dist/persistence/storage.d.ts +38 -0
  266. package/dist/persistence/storage.d.ts.map +1 -0
  267. package/dist/persistence/storage.js +5 -0
  268. package/dist/persistence/storage.js.map +1 -0
  269. package/dist/server/config.d.ts +47 -0
  270. package/dist/server/config.d.ts.map +1 -0
  271. package/dist/server/config.js +41 -0
  272. package/dist/server/config.js.map +1 -0
  273. package/dist/server/context.d.ts +198 -24
  274. package/dist/server/context.d.ts.map +1 -1
  275. package/dist/server/context.js +432 -53
  276. package/dist/server/context.js.map +1 -1
  277. package/dist/server/deps.d.ts +5 -6
  278. package/dist/server/deps.d.ts.map +1 -1
  279. package/dist/server/deps.js +2 -2
  280. package/dist/server/deps.js.map +1 -1
  281. package/dist/server/handlers/completeConnect.d.ts +8 -0
  282. package/dist/server/handlers/completeConnect.d.ts.map +1 -0
  283. package/dist/server/handlers/completeConnect.js +74 -0
  284. package/dist/server/handlers/completeConnect.js.map +1 -0
  285. package/dist/server/handlers/handleAuth.d.ts +9 -0
  286. package/dist/server/handlers/handleAuth.d.ts.map +1 -0
  287. package/dist/server/handlers/handleAuth.js +69 -0
  288. package/dist/server/handlers/handleAuth.js.map +1 -0
  289. package/dist/server/handlers/handleConnect.d.ts +2 -4
  290. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  291. package/dist/server/handlers/handleConnect.js +140 -67
  292. package/dist/server/handlers/handleConnect.js.map +1 -1
  293. package/dist/server/handlers/handleDisconnect.d.ts +1 -1
  294. package/dist/server/handlers/handleDisconnect.d.ts.map +1 -1
  295. package/dist/server/handlers/handleDisconnect.js +3 -3
  296. package/dist/server/handlers/handleDisconnect.js.map +1 -1
  297. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  298. package/dist/server/handlers/handlePacket.js +19 -6
  299. package/dist/server/handlers/handlePacket.js.map +1 -1
  300. package/dist/server/handlers/handlePuback.d.ts +1 -3
  301. package/dist/server/handlers/handlePuback.d.ts.map +1 -1
  302. package/dist/server/handlers/handlePuback.js +2 -8
  303. package/dist/server/handlers/handlePuback.js.map +1 -1
  304. package/dist/server/handlers/handlePubcomp.d.ts +1 -1
  305. package/dist/server/handlers/handlePubcomp.d.ts.map +1 -1
  306. package/dist/server/handlers/handlePubcomp.js +2 -4
  307. package/dist/server/handlers/handlePubcomp.js.map +1 -1
  308. package/dist/server/handlers/handlePublish.d.ts +1 -1
  309. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  310. package/dist/server/handlers/handlePublish.js +149 -45
  311. package/dist/server/handlers/handlePublish.js.map +1 -1
  312. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  313. package/dist/server/handlers/handlePubrec.js +2 -3
  314. package/dist/server/handlers/handlePubrec.js.map +1 -1
  315. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  316. package/dist/server/handlers/handlePubrel.js +6 -2
  317. package/dist/server/handlers/handlePubrel.js.map +1 -1
  318. package/dist/server/handlers/handleSubscribe.d.ts +1 -6
  319. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  320. package/dist/server/handlers/handleSubscribe.js +99 -38
  321. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  322. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  323. package/dist/server/handlers/handleUnsubscribe.js +19 -4
  324. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  325. package/dist/server/mod.d.ts +3 -3
  326. package/dist/server/mod.d.ts.map +1 -1
  327. package/dist/server/mod.js +1 -1
  328. package/dist/server/mod.js.map +1 -1
  329. package/dist/server/server.d.ts +29 -6
  330. package/dist/server/server.d.ts.map +1 -1
  331. package/dist/server/server.js +84 -15
  332. package/dist/server/server.js.map +1 -1
  333. package/dist/socket/socket.d.ts +11 -9
  334. package/dist/socket/socket.d.ts.map +1 -1
  335. package/dist/socket/socket.js +66 -18
  336. package/dist/socket/socket.js.map +1 -1
  337. package/dist/timer/timer.d.ts +32 -0
  338. package/dist/timer/timer.d.ts.map +1 -1
  339. package/dist/timer/timer.js +32 -0
  340. package/dist/timer/timer.js.map +1 -1
  341. package/dist/trie/trie.d.ts +10 -5
  342. package/dist/trie/trie.d.ts.map +1 -1
  343. package/dist/trie/trie.js +61 -41
  344. package/dist/trie/trie.js.map +1 -1
  345. package/dist/utils/assert.d.ts.map +1 -1
  346. package/dist/utils/{BufferedAsyncIterable.d.ts → bufferedAsyncIterable.d.ts} +1 -1
  347. package/dist/utils/bufferedAsyncIterable.d.ts.map +1 -0
  348. package/dist/utils/{BufferedAsyncIterable.js → bufferedAsyncIterable.js} +1 -1
  349. package/dist/utils/bufferedAsyncIterable.js.map +1 -0
  350. package/dist/utils/deferred.d.ts.map +1 -1
  351. package/dist/utils/deferred.js.map +1 -1
  352. package/dist/utils/getOrInsertPolyFill.d.ts +2 -0
  353. package/dist/utils/getOrInsertPolyFill.d.ts.map +1 -0
  354. package/dist/utils/getOrInsertPolyFill.js +12 -0
  355. package/dist/utils/getOrInsertPolyFill.js.map +1 -0
  356. package/dist/utils/logger.d.ts +40 -3
  357. package/dist/utils/logger.d.ts.map +1 -1
  358. package/dist/utils/logger.js +53 -7
  359. package/dist/utils/logger.js.map +1 -1
  360. package/dist/utils/mod.d.ts +6 -1
  361. package/dist/utils/mod.d.ts.map +1 -1
  362. package/dist/utils/mod.js +5 -1
  363. package/dist/utils/mod.js.map +1 -1
  364. package/dist/utils/outboundTopicAliasManager.d.ts +52 -0
  365. package/dist/utils/outboundTopicAliasManager.d.ts.map +1 -0
  366. package/dist/utils/outboundTopicAliasManager.js +74 -0
  367. package/dist/utils/outboundTopicAliasManager.js.map +1 -0
  368. package/dist/utils/queue.d.ts.map +1 -1
  369. package/dist/utils/topicFilter.d.ts +32 -0
  370. package/dist/utils/topicFilter.d.ts.map +1 -0
  371. package/dist/utils/topicFilter.js +52 -0
  372. package/dist/utils/topicFilter.js.map +1 -0
  373. package/dist/utils/utils.d.ts +2 -0
  374. package/dist/utils/utils.d.ts.map +1 -1
  375. package/dist/utils/utils.js +2 -0
  376. package/dist/utils/utils.js.map +1 -1
  377. package/dist/utils/validators.d.ts +34 -0
  378. package/dist/utils/validators.d.ts.map +1 -0
  379. package/dist/utils/validators.js +61 -0
  380. package/dist/utils/validators.js.map +1 -0
  381. package/dist/web/webSocketStream.d.ts +29 -0
  382. package/dist/web/webSocketStream.d.ts.map +1 -0
  383. package/dist/web/webSocketStream.js +69 -0
  384. package/dist/web/webSocketStream.js.map +1 -0
  385. package/dist/web/wrapWebSocket.d.ts +12 -0
  386. package/dist/web/wrapWebSocket.d.ts.map +1 -0
  387. package/dist/web/wrapWebSocket.js +41 -0
  388. package/dist/web/wrapWebSocket.js.map +1 -0
  389. package/dist/web/wsClient.d.ts +7 -0
  390. package/dist/web/wsClient.d.ts.map +1 -0
  391. package/dist/web/wsClient.js +22 -0
  392. package/dist/web/wsClient.js.map +1 -0
  393. package/dist/web/wsClient.test.d.ts +2 -0
  394. package/dist/web/wsClient.test.d.ts.map +1 -0
  395. package/dist/web/wsClient.test.js +20 -0
  396. package/dist/web/wsClient.test.js.map +1 -0
  397. package/examples/authHandler.test.ts +164 -0
  398. package/examples/mqtt.test.ts +89 -0
  399. package/examples/mqtts.test.ts +100 -0
  400. package/examples/webSocket.test.ts +94 -0
  401. package/mqttConn/mqttConn.test.ts +9 -9
  402. package/mqttConn/mqttConn.ts +76 -44
  403. package/mqttPacket/Properties.ts +6 -3
  404. package/mqttPacket/ReasonCode.ts +2 -1
  405. package/mqttPacket/auth.test.ts +1 -1
  406. package/mqttPacket/auth.ts +41 -48
  407. package/mqttPacket/codec.ts +146 -0
  408. package/mqttPacket/connack.ts +57 -68
  409. package/mqttPacket/connect.test.ts +2 -2
  410. package/mqttPacket/connect.ts +175 -182
  411. package/mqttPacket/decoder.test.ts +0 -39
  412. package/mqttPacket/decoder.ts +8 -35
  413. package/mqttPacket/disconnect.ts +57 -68
  414. package/mqttPacket/encoder.ts +5 -40
  415. package/mqttPacket/mod.ts +48 -200
  416. package/mqttPacket/pingreq.ts +21 -27
  417. package/mqttPacket/pingres.ts +21 -27
  418. package/mqttPacket/protocolLevels.ts +12 -7
  419. package/mqttPacket/pubblishAcks.ts +56 -70
  420. package/mqttPacket/publish.ts +67 -74
  421. package/mqttPacket/suback.ts +48 -58
  422. package/mqttPacket/subscribe.ts +141 -117
  423. package/mqttPacket/types.ts +1 -9
  424. package/mqttPacket/unsuback.ts +46 -58
  425. package/mqttPacket/unsubscribe.ts +74 -63
  426. package/mqttPacket/validators.ts +5 -31
  427. package/node/socket-node-stream.test.ts +322 -0
  428. package/node/socket-node-stream.ts +174 -0
  429. package/node/tcpClient.test.ts +70 -0
  430. package/node/tcpClient.ts +13 -12
  431. package/node/tcpServer.test.ts +24 -20
  432. package/node/tcpServer.ts +6 -0
  433. package/node/tlsServer.test.ts +94 -0
  434. package/node/tlsServer.ts +81 -0
  435. package/node/wrapNodeSocket.ts +7 -30
  436. package/package.json +72 -44
  437. package/persistence/basicPersistence.ts +495 -0
  438. package/persistence/deps.ts +11 -1
  439. package/persistence/memory/memoryPersistence.ts +12 -153
  440. package/persistence/memory/memoryStorage.ts +232 -0
  441. package/persistence/mod.ts +4 -9
  442. package/persistence/persistence.test.ts +24 -0
  443. package/persistence/persistence.testing.ts +1324 -0
  444. package/persistence/persistence.ts +111 -67
  445. package/persistence/sqlite/sqliteDatabase.ts +294 -0
  446. package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
  447. package/persistence/sqlite/sqlitePersistence.ts +36 -0
  448. package/persistence/sqlite/sqliteStorage.ts +324 -0
  449. package/persistence/storage.ts +84 -0
  450. package/server/config.ts +65 -0
  451. package/server/context.ts +658 -74
  452. package/server/deps.ts +25 -5
  453. package/server/handlers/completeConnect.ts +93 -0
  454. package/server/handlers/duplicate.test.ts +196 -0
  455. package/server/handlers/handleAuth.test.ts +225 -0
  456. package/server/handlers/handleAuth.ts +88 -0
  457. package/server/handlers/handleConnect.test.ts +589 -0
  458. package/server/handlers/handleConnect.ts +201 -86
  459. package/server/handlers/handleConnect.version.test.ts +108 -0
  460. package/server/handlers/handleDisconnect.test.ts +56 -0
  461. package/server/handlers/handleDisconnect.ts +3 -3
  462. package/server/handlers/handlePacket.test.ts +24 -0
  463. package/server/handlers/handlePacket.ts +30 -8
  464. package/server/handlers/handlePingreq.test.ts +29 -0
  465. package/server/handlers/handlePuback.test.ts +28 -0
  466. package/server/handlers/handlePuback.ts +5 -8
  467. package/server/handlers/handlePubcomp.test.ts +28 -0
  468. package/server/handlers/handlePubcomp.ts +5 -4
  469. package/server/handlers/handlePublish.test.ts +471 -0
  470. package/server/handlers/handlePublish.ts +189 -35
  471. package/server/handlers/handlePubrec.test.ts +28 -0
  472. package/server/handlers/handlePubrec.ts +2 -3
  473. package/server/handlers/handlePubrel.test.ts +74 -0
  474. package/server/handlers/handlePubrel.ts +12 -2
  475. package/server/handlers/handleSubscribe.test.ts +971 -0
  476. package/server/handlers/handleSubscribe.ts +158 -39
  477. package/server/handlers/handleUnsubscribe.test.ts +79 -0
  478. package/server/handlers/handleUnsubscribe.ts +29 -5
  479. package/server/handlers/keepalive.test.ts +132 -0
  480. package/server/handlers/session.persistence.test.ts +194 -0
  481. package/server/handlers/will.delivery.test.ts +221 -0
  482. package/server/mod.ts +4 -3
  483. package/server/preconnect.test.ts +151 -0
  484. package/server/server.ts +115 -17
  485. package/socket/socket.test.ts +91 -0
  486. package/socket/socket.ts +81 -34
  487. package/timer/timer.test.ts +4 -7
  488. package/timer/timer.ts +36 -0
  489. package/tools/benchmarks/receiver.ts +51 -0
  490. package/tools/benchmarks/sender.ts +48 -0
  491. package/tools/benchmarks/utils.ts +31 -0
  492. package/tools/mqtt-compat/README.md +130 -0
  493. package/tools/mqtt-compat/broker.ts +52 -0
  494. package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
  495. package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
  496. package/trie/trie.test.ts +9 -1
  497. package/trie/trie.ts +70 -45
  498. package/utils/bufferedAsyncIterable.test.ts +92 -0
  499. package/utils/deferred.test.ts +36 -0
  500. package/utils/deferred.ts +0 -1
  501. package/utils/getOrInsertPolyFill.ts +12 -0
  502. package/utils/logger.test.ts +189 -0
  503. package/utils/logger.ts +62 -7
  504. package/utils/mod.ts +15 -1
  505. package/utils/outboundTopicAliasManager.ts +100 -0
  506. package/utils/queue.test.ts +61 -0
  507. package/utils/topicFilter.test.ts +63 -0
  508. package/utils/topicFilter.ts +61 -0
  509. package/utils/utils.ts +3 -0
  510. package/utils/validators.ts +67 -0
  511. package/web/webSocketStream.ts +97 -0
  512. package/web/wrapWebSocket.ts +52 -0
  513. package/web/wsClient.test.ts +26 -0
  514. package/web/wsClient.ts +25 -0
  515. package/benchmarks/receiver.ts +0 -35
  516. package/benchmarks/sender.ts +0 -32
  517. package/benchmarks/utils.ts +0 -9
  518. package/dev_utils/dummyConn.ts +0 -110
  519. package/dev_utils/socketPair.ts +0 -85
  520. package/dist/persistence/store.d.ts +0 -14
  521. package/dist/persistence/store.d.ts.map +0 -1
  522. package/dist/persistence/store.js +0 -2
  523. package/dist/persistence/store.js.map +0 -1
  524. package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
  525. package/dist/utils/BufferedAsyncIterable.js.map +0 -1
  526. package/examples/tcpServer.test.ts +0 -148
  527. package/persistence/memory/memoryPersistence.test.ts +0 -156
  528. package/persistence/store.ts +0 -16
  529. package/server/test/handleConnect.test.ts +0 -122
  530. package/server/test/test-handlers.ts +0 -53
  531. /package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +0 -0
@@ -0,0 +1,95 @@
1
+ import forge from "node-forge";
2
+
3
+ /**
4
+ * Generates a minimal, in-memory TLS certificate bundle for localhost development.
5
+ * Includes Root CA, Server Certificate, and Server Private Key with SAN support (IPv4 & IPv6).
6
+ */
7
+ export function generateLocalhostCerts(): {
8
+ caCert: string;
9
+ key: string;
10
+ cert: string;
11
+ fullChain: string;
12
+ } {
13
+ // Generate the keypairs
14
+ // 2048-bit RSA is used here for fast generation during local development/testing
15
+ const caKeys = forge.pki.rsa.generateKeyPair(2048);
16
+ const serverKeys = forge.pki.rsa.generateKeyPair(2048);
17
+
18
+ // Create root CA
19
+ const caCert = forge.pki.createCertificate();
20
+ caCert.publicKey = caKeys.publicKey;
21
+ caCert.serialNumber = "01";
22
+ caCert.validity.notBefore = new Date();
23
+ caCert.validity.notAfter = new Date();
24
+ caCert.validity.notAfter.setFullYear(
25
+ caCert.validity.notBefore.getFullYear() + 1,
26
+ ); // Valid for 1 year
27
+
28
+ // Hardcoded CA Attributes
29
+ const caAttrs = [{ name: "commonName", value: "Local Dev Root CA" }];
30
+ caCert.setSubject(caAttrs);
31
+ caCert.setIssuer(caAttrs); // Self-signed: issuer equals subject
32
+
33
+ // Critical for CA: Define basic constraints to flag this certificate as a trusted issuer
34
+ caCert.setExtensions([
35
+ { name: "basicConstraints", cA: true, critical: true },
36
+ {
37
+ name: "keyUsage",
38
+ keyCertSign: true,
39
+ digitalSignature: true,
40
+ critical: true,
41
+ },
42
+ ]);
43
+
44
+ // Sign the CA certificate using its own private key
45
+ caCert.sign(caKeys.privateKey, forge.md.sha256.create());
46
+
47
+ // Create server certificate for localhost, valid for a year
48
+ const serverCert = forge.pki.createCertificate();
49
+ serverCert.publicKey = serverKeys.publicKey;
50
+ serverCert.serialNumber = "02"; // Unique serial number within this CA scope
51
+ serverCert.validity.notBefore = new Date();
52
+ serverCert.validity.notAfter = new Date();
53
+ serverCert.validity.notAfter.setFullYear(
54
+ serverCert.validity.notBefore.getFullYear() + 1,
55
+ );
56
+
57
+ // Hardcoded Server Attributes
58
+ serverCert.setSubject([{ name: "commonName", value: "localhost" }]);
59
+ serverCert.setIssuer(caCert.subject.attributes); // Issued by our custom Root CA
60
+
61
+ // Critical for Modern TLS: X509v3 Extensions containing Subject Alternative Names (SAN)
62
+ // Ensures compatibility with strict TLS parsers (like Deno/rustls, Go, Node.js, and modern browsers)
63
+ serverCert.setExtensions([
64
+ { name: "basicConstraints", cA: false, critical: true },
65
+ {
66
+ name: "keyUsage",
67
+ digitalSignature: true,
68
+ keyEncipherment: true,
69
+ critical: true,
70
+ },
71
+ {
72
+ name: "subjectAltName",
73
+ altNames: [
74
+ { type: 2, value: "localhost" }, // type 2 = DNS
75
+ { type: 7, ip: "127.0.0.1" }, // type 7 = IPv4 loopback
76
+ { type: 7, ip: "::1" }, // type 7 = IPv6 loopback
77
+ ],
78
+ },
79
+ ]);
80
+
81
+ // Sign the server certificate using the Root CA's private key
82
+ serverCert.sign(caKeys.privateKey, forge.md.sha256.create());
83
+
84
+ // convert data to PEM
85
+ const caCertPem = forge.pki.certificateToPem(caCert);
86
+ const serverCertPem = forge.pki.certificateToPem(serverCert);
87
+ const serverKeyPem = forge.pki.privateKeyToPem(serverKeys.privateKey);
88
+
89
+ return {
90
+ caCert: caCertPem,
91
+ key: serverKeyPem,
92
+ cert: serverCertPem,
93
+ fullChain: `${serverCertPem}\n${caCertPem}`, // Full certificate chain (Server + CA)
94
+ };
95
+ }
@@ -0,0 +1,36 @@
1
+ class Uint8Writer implements WritableStreamDefaultWriter {
2
+ private buff: Uint8Array;
3
+ private pos: number;
4
+ closed = Promise.resolve(undefined);
5
+ close = () => Promise.resolve();
6
+ abort = () => Promise.resolve();
7
+ ready = Promise.resolve(undefined);
8
+ releaseLock = () => {};
9
+ desiredSize = 20;
10
+
11
+ constructor(
12
+ buff: Uint8Array,
13
+ ) {
14
+ this.buff = buff;
15
+ this.pos = 0;
16
+ }
17
+ write(chunk: Uint8Array): Promise<void> {
18
+ this.buff.set(chunk, this.pos);
19
+ this.pos += chunk.length;
20
+ return Promise.resolve();
21
+ }
22
+ }
23
+
24
+ export function createMockSockConn(
25
+ readerBuffs: Uint8Array[],
26
+ writerBuf: Uint8Array,
27
+ close = () => {},
28
+ ) {
29
+ const readable = ReadableStream.from(readerBuffs);
30
+ const writable = new WritableStream(new Uint8Writer(writerBuf));
31
+ return {
32
+ readable,
33
+ writable,
34
+ close,
35
+ };
36
+ }
@@ -0,0 +1,28 @@
1
+ import { createWebStreamPair } from "./webStreamPair.ts";
2
+ import { MqttConn } from "../mqttConn/mqttConn.ts";
3
+ import { Context, MqttServer } from "../server/mod.ts";
4
+ import { handlers } from "./test-handlers.ts";
5
+ import type { MqttServerOptions } from "../server/mod.ts";
6
+
7
+ export function startMockServer(opts: MqttServerOptions = {}): {
8
+ mqttConn: MqttConn;
9
+ mqttServer: MqttServer;
10
+ } {
11
+ const serverOpts = { handlers, ...opts };
12
+ // start with a fresh clientlist
13
+ Context.clientList.clear();
14
+ // create a new MQTT server
15
+
16
+ const mqttServer = new MqttServer(serverOpts);
17
+ const { input, output } = createWebStreamPair();
18
+ const mqttConn = new MqttConn({ conn: output });
19
+ mqttServer.serve(input);
20
+ return { mqttConn, mqttServer };
21
+ }
22
+
23
+ export function addMockClient(mqttServer: MqttServer): MqttConn {
24
+ const { input, output } = createWebStreamPair();
25
+ const mqttConn = new MqttConn({ conn: output });
26
+ mqttServer.serve(input);
27
+ return mqttConn;
28
+ }
package/dev_utils/mod.ts CHANGED
@@ -1,3 +1,30 @@
1
- export { makeDummyQueueSockConn, makeDummySockConn } from "./dummyConn.ts";
2
- export { createWebSocketPair } from "./socketPair.ts";
3
- export { resolveAsap, resolveNextTick, runAsap } from "./timers.ts";
1
+ export { createMockSockConn } from "./mockConn.ts";
2
+ export { createWebStreamPair } from "./webStreamPair.ts";
3
+ export {
4
+ delay,
5
+ resolveAsap,
6
+ resolveNextTick,
7
+ runAsap,
8
+ withTimeout,
9
+ } from "./timers.ts";
10
+ export { addMockClient, startMockServer } from "./mockServer.ts";
11
+ export {
12
+ auth,
13
+ checkNoPacket,
14
+ connect,
15
+ connect5,
16
+ disconnect,
17
+ disconnect5,
18
+ nextPacketWithTimeOut,
19
+ ping,
20
+ publish,
21
+ publish5,
22
+ receiveMessages,
23
+ receiveMessages5,
24
+ subscribe,
25
+ subscribe5,
26
+ unsubscribe,
27
+ unsubscribe5,
28
+ } from "./packetHelpers.ts";
29
+ export { generateLocalhostCerts } from "./generateCert.ts";
30
+ export { handlers, isAuthenticatedBroker } from "./test-handlers.ts";
@@ -0,0 +1,404 @@
1
+ import type { MqttConn } from "../mqttConn/mqttConn.ts";
2
+ import { withTimeout } from "./timers.ts";
3
+ import { delay } from "./timers.ts";
4
+ import { MQTTLevel, PacketType, ReasonCode } from "../mqttPacket/mod.ts";
5
+ import type {
6
+ AnyPacket,
7
+ AuthPacket,
8
+ ConnackPacket,
9
+ ConnectPacket,
10
+ DisconnectProperties,
11
+ ProtocolLevel,
12
+ PublishProperties,
13
+ QoS,
14
+ Topic,
15
+ TopicFilter,
16
+ UnsubackPacket,
17
+ } from "../mqttPacket/mod.ts";
18
+ import type {
19
+ ConnackPacketV4,
20
+ ConnackPacketV5,
21
+ } from "../mqttPacket/connack.ts";
22
+ import type { ConnectPacketV5 } from "../mqttPacket/connect.ts";
23
+ import assert from "node:assert/strict";
24
+ import { logger } from "../utils/mod.ts";
25
+
26
+ const txtEncoder = new TextEncoder();
27
+
28
+ let clientIdCounter = 1;
29
+
30
+ const PINGREQ_PACKET: AnyPacket = Object.freeze({
31
+ type: PacketType.pingreq,
32
+ protocolLevel: MQTTLevel.v4,
33
+ });
34
+
35
+ export function nextPacketWithTimeOut(
36
+ conn: MqttConn,
37
+ timeoutMs: number,
38
+ ): Promise<IteratorResult<AnyPacket> | null> {
39
+ return withTimeout(conn.next(), timeoutMs);
40
+ }
41
+
42
+ export async function checkNoPacket(mqttConn: MqttConn, timeoutMs = 10) {
43
+ const result = await nextPacketWithTimeOut(mqttConn, timeoutMs);
44
+ assert.equal(result, null, "no packet received");
45
+ }
46
+
47
+ async function baseConnect(mqttConn: MqttConn, {
48
+ level = MQTTLevel.v4 as ProtocolLevel,
49
+ clientId = `testClient-${clientIdCounter++}`,
50
+ username = "IoTester_1",
51
+ password = "strong_password",
52
+ keepAlive = 0,
53
+ clean = true,
54
+ will = undefined as ConnectPacket["will"],
55
+ properties = {},
56
+ checkAck = true,
57
+ } = {}): Promise<ConnackPacket | AuthPacket> {
58
+ mqttConn.codecOpts.protocolLevel = level;
59
+ const connectPacket: ConnectPacket = {
60
+ type: PacketType.connect,
61
+ protocolName: "MQTT",
62
+ protocolLevel: level,
63
+ clientId,
64
+ clean,
65
+ keepAlive,
66
+ username,
67
+ password: password !== "" ? txtEncoder.encode(password) : undefined,
68
+ will,
69
+ };
70
+ if (connectPacket.protocolLevel === MQTTLevel.v5) {
71
+ connectPacket.properties = properties;
72
+ }
73
+ logger.verbose("connectHelper: sending connect");
74
+ logger.debug({ connectPacket });
75
+
76
+ mqttConn.send(connectPacket);
77
+ const { value: connack } = await mqttConn.next();
78
+ logger.verbose("connectHelper: connack", connack);
79
+ if (checkAck) {
80
+ assert.deepStrictEqual(
81
+ connack.type,
82
+ PacketType.connack,
83
+ "Expected CONNACK",
84
+ );
85
+ }
86
+ mqttConn.codecOpts.protocolLevel = level;
87
+ return connack;
88
+ }
89
+
90
+ export async function connect(mqttConn: MqttConn, {
91
+ level = MQTTLevel.v4,
92
+ clientId = `testClient-${clientIdCounter++}`,
93
+ username = "IoTester_1",
94
+ password = "strong_password",
95
+ keepAlive = 0,
96
+ clean = true,
97
+ will = undefined as ConnectPacket["will"],
98
+ checkAck = true,
99
+ } = {}): Promise<ConnackPacketV4> {
100
+ return await baseConnect(mqttConn, {
101
+ level,
102
+ clientId,
103
+ username,
104
+ password,
105
+ keepAlive,
106
+ clean,
107
+ will,
108
+ checkAck,
109
+ }) as ConnackPacketV4;
110
+ }
111
+
112
+ export async function connect5(mqttConn: MqttConn, {
113
+ clientId = `testClient-${clientIdCounter++}`,
114
+ username = "IoTester_1",
115
+ password = "strong_password",
116
+ keepAlive = 0,
117
+ clean = true,
118
+ will = undefined as ConnectPacket["will"],
119
+ properties = {} as ConnectPacketV5["properties"],
120
+ checkAck = true,
121
+ } = {}): Promise<ConnackPacketV5> {
122
+ return await baseConnect(mqttConn, {
123
+ level: MQTTLevel.v5,
124
+ clientId,
125
+ username,
126
+ password,
127
+ keepAlive,
128
+ clean,
129
+ will,
130
+ properties,
131
+ checkAck,
132
+ }) as ConnackPacketV5;
133
+ }
134
+
135
+ export async function auth(mqttConn: MqttConn, {
136
+ reasonCode = ReasonCode.continueAuthentication,
137
+ authMethod = "SCRAM-SHA-256",
138
+ authData = new Uint8Array([1]),
139
+ noMethod = false,
140
+ noData = false,
141
+ } = {}) {
142
+ const authPacket: AuthPacket = {
143
+ type: PacketType.auth,
144
+ protocolLevel: 5,
145
+ reasonCode,
146
+ properties: {
147
+ authenticationMethod: noMethod ? undefined : authMethod,
148
+ authenticationData: noData ? undefined : authData,
149
+ },
150
+ };
151
+ await mqttConn.send(authPacket);
152
+ const { value } = await mqttConn.next();
153
+ return value;
154
+ }
155
+
156
+ export async function subscribe(
157
+ subscriber: MqttConn,
158
+ subscriptions: {
159
+ topicFilter: TopicFilter;
160
+ qos: QoS;
161
+ }[],
162
+ {
163
+ id = 24,
164
+ checkAcks = true,
165
+ } = {},
166
+ ) {
167
+ const subscribePacket = {
168
+ type: PacketType.subscribe,
169
+ protocolLevel: MQTTLevel.v4,
170
+ id,
171
+ subscriptions,
172
+ };
173
+
174
+ subscriber.send(subscribePacket);
175
+
176
+ const { value: packet } = await subscriber.next();
177
+ if (checkAcks) {
178
+ assert.equal(packet.type, PacketType.suback, "Expected SUBACK");
179
+ assert.equal(packet.id, id, "SUBACK ID should match SUBSCRIBE ID");
180
+ const results = packet.returnCodes || packet.reasonCodes;
181
+ assert.equal(results.length, subscriptions.length, "ACK count match");
182
+ for (let i = 0; i < results.length; i++) {
183
+ assert.equal(results[i], subscriptions[i].qos);
184
+ }
185
+ }
186
+ return packet;
187
+ }
188
+
189
+ export async function subscribe5(
190
+ subscriber: MqttConn,
191
+ subscriptions: {
192
+ topicFilter: TopicFilter;
193
+ qos: QoS;
194
+ noLocal?: boolean;
195
+ retainAsPublished?: boolean;
196
+ retainHandling?: number;
197
+ }[],
198
+ {
199
+ id = 24,
200
+ subscriptionIdentifier = undefined as number | undefined,
201
+ checkAcks = true,
202
+ } = {},
203
+ ) {
204
+ const properties = subscriptionIdentifier !== undefined
205
+ ? { subscriptionIdentifier }
206
+ : {};
207
+
208
+ const subscribePacket = {
209
+ type: PacketType.subscribe,
210
+ protocolLevel: MQTTLevel.v5,
211
+ id,
212
+ subscriptions,
213
+ properties,
214
+ };
215
+
216
+ subscriber.send(subscribePacket);
217
+ logger.debug("subscribe helper: sent subscription request");
218
+
219
+ const { value: packet } = await subscriber.next();
220
+ assert.equal(packet.type, PacketType.suback, "Expected SUBACK");
221
+ assert.equal(packet.id, id, "SUBACK ID should match SUBSCRIBE ID");
222
+ logger.debug("subscribe helper: received SubAck");
223
+
224
+ if (checkAcks) {
225
+ const results = packet.returnCodes || packet.reasonCodes;
226
+ assert.equal(results.length, subscriptions.length, "ACK count match");
227
+ for (let i = 0; i < results.length; i++) {
228
+ assert.equal(results[i], subscriptions[i].qos);
229
+ }
230
+ }
231
+ logger.debug("subscribe helper: acks ok");
232
+ return packet;
233
+ }
234
+
235
+ export async function unsubscribe(
236
+ subscriber: MqttConn,
237
+ topicFilters: TopicFilter[],
238
+ {
239
+ level = MQTTLevel.v4,
240
+ id = 24,
241
+ } = {},
242
+ ) {
243
+ subscriber.send({
244
+ type: PacketType.unsubscribe,
245
+ protocolLevel: level,
246
+ id,
247
+ topicFilters,
248
+ });
249
+ const { value: packet } = await subscriber.next();
250
+ assert.equal(packet.type, PacketType.unsuback, "Expected UNSUBACK");
251
+ assert.equal(packet.protocolLevel, level, "received expected level");
252
+ assert.equal(packet.id, id, "UNSUBACK ID should match UNSUBSCRIBE ID");
253
+ }
254
+
255
+ export async function unsubscribe5(
256
+ subscriber: MqttConn,
257
+ topicFilters: TopicFilter[],
258
+ { id = 24 } = {},
259
+ ): Promise<UnsubackPacket> {
260
+ subscriber.send({
261
+ type: PacketType.unsubscribe,
262
+ protocolLevel: MQTTLevel.v5,
263
+ id,
264
+ topicFilters,
265
+ });
266
+ const { value: packet } = await subscriber.next();
267
+ assert.equal(packet.type, PacketType.unsuback, "Expected UNSUBACK");
268
+ assert.equal(packet.protocolLevel, MQTTLevel.v5, "received expected level");
269
+ assert.equal(packet.id, id, "UNSUBACK ID should match UNSUBSCRIBE ID");
270
+ return packet;
271
+ }
272
+
273
+ export async function publish(
274
+ publisher: MqttConn,
275
+ topic: Topic,
276
+ qos: QoS,
277
+ {
278
+ level = MQTTLevel.v4 as ProtocolLevel,
279
+ id = 22,
280
+ payload = "payload",
281
+ retain = false,
282
+ properties = {},
283
+ checkAcks = true,
284
+ } = {},
285
+ ) {
286
+ const encodedPayload = txtEncoder.encode(payload);
287
+
288
+ await publisher.send({
289
+ type: PacketType.publish,
290
+ protocolLevel: level,
291
+ id,
292
+ topic,
293
+ qos,
294
+ payload: encodedPayload,
295
+ retain,
296
+ properties,
297
+ });
298
+ logger.debug("publish helper: sent publish");
299
+ if (!checkAcks || qos === 0) return;
300
+
301
+ const { value: ackPacket } = await publisher.next();
302
+ const expectedAckType = qos === 1 ? PacketType.puback : PacketType.pubrec;
303
+ assert.equal(ackPacket.type, expectedAckType, "received expected ack");
304
+ assert.equal(ackPacket.protocolLevel, level, "received expected level");
305
+ assert.equal(ackPacket.id, id, "packetid matches");
306
+ logger.debug("publish helper: received pubAck");
307
+
308
+ if (qos === 1) return ackPacket;
309
+
310
+ publisher.send({
311
+ type: PacketType.pubrel,
312
+ protocolLevel: level,
313
+ id,
314
+ });
315
+
316
+ const { value: compPacket } = await publisher.next();
317
+ assert.equal(
318
+ compPacket.type,
319
+ PacketType.pubcomp,
320
+ "received expected pubcomp",
321
+ );
322
+ assert.equal(compPacket.id, id, "packetid of pubcomp matches");
323
+ }
324
+
325
+ export function publish5(
326
+ publisher: MqttConn,
327
+ topic: Topic,
328
+ qos: QoS,
329
+ opts?: {
330
+ id?: number;
331
+ payload?: string;
332
+ retain?: boolean;
333
+ properties?: PublishProperties;
334
+ checkAcks?: boolean;
335
+ },
336
+ ) {
337
+ return publish(
338
+ publisher,
339
+ topic,
340
+ qos,
341
+ Object.assign({}, opts, { level: MQTTLevel.v5 }),
342
+ );
343
+ }
344
+
345
+ export async function disconnect(
346
+ mqttConn: MqttConn,
347
+ { level = MQTTLevel.v4 } = {},
348
+ ) {
349
+ mqttConn.send({
350
+ type: PacketType.disconnect,
351
+ protocolLevel: level,
352
+ });
353
+ await mqttConn.next();
354
+
355
+ assert.strictEqual(
356
+ mqttConn.isClosed,
357
+ true,
358
+ "Expected connection to be closed",
359
+ );
360
+ }
361
+
362
+ export async function disconnect5(mqttConn: MqttConn, opts?: {
363
+ reasonCode?: number;
364
+ properties?: DisconnectProperties;
365
+ }) {
366
+ const packet = {
367
+ type: PacketType.disconnect,
368
+ protocolLevel: MQTTLevel.v5,
369
+ reasonCode: opts?.reasonCode,
370
+ properties: opts?.properties,
371
+ };
372
+
373
+ mqttConn.send(packet);
374
+ await mqttConn.next();
375
+ await mqttConn.next();
376
+
377
+ assert.strictEqual(
378
+ mqttConn.isClosed,
379
+ true,
380
+ "Expected connection to be closed",
381
+ );
382
+ }
383
+
384
+ export async function ping(mqttConn: MqttConn) {
385
+ mqttConn.send(PINGREQ_PACKET);
386
+ const { value: pingres } = await mqttConn.next();
387
+ assert.strictEqual(pingres.type, PacketType.pingres);
388
+ }
389
+
390
+ export async function receiveMessages(conn: MqttConn) {
391
+ const received = Array.fromAsync(conn);
392
+ await delay(10);
393
+ await disconnect(conn);
394
+ const messages = await received;
395
+ return messages;
396
+ }
397
+
398
+ export async function receiveMessages5(conn: MqttConn) {
399
+ const received = Array.fromAsync(conn);
400
+ await delay(10);
401
+ await disconnect5(conn);
402
+ const messages = await received;
403
+ return messages;
404
+ }
@@ -0,0 +1,98 @@
1
+ import { ReasonCode } from "../server/mod.ts";
2
+ import { logger } from "../utils/mod.ts";
3
+ import type {
4
+ AuthenticatedResult,
5
+ Context,
6
+ ShareName,
7
+ Topic,
8
+ } from "../server/mod.ts";
9
+
10
+ const utf8Decoder = new TextDecoder();
11
+ const userTable = new Map();
12
+ userTable.set("IoTester_1", "strong_password");
13
+ userTable.set("IoTester_2", "strong_password");
14
+ const strictUsername = new RegExp(/^[a-zA-Z0-9]{0,23}$/);
15
+
16
+ function isAuthenticated(
17
+ _ctx: Context,
18
+ clientId: string,
19
+ username: string,
20
+ password: Uint8Array,
21
+ ): AuthenticatedResult {
22
+ const pwd = utf8Decoder.decode(password);
23
+ logger.debug(
24
+ `Verifying authentication of client '${clientId}' with username '${username}'`,
25
+ );
26
+
27
+ if (!userTable.has(username)) {
28
+ if (!strictUsername.test(username)) {
29
+ return { reasonCode: ReasonCode.success };
30
+ }
31
+ }
32
+
33
+ const pass = userTable.get(username);
34
+ if (pwd === pass) {
35
+ return { reasonCode: ReasonCode.success };
36
+ }
37
+ return {
38
+ reasonCode: ReasonCode.badUserNameOrPassword,
39
+ reasonString: "Bad username or password",
40
+ };
41
+ }
42
+
43
+ function processAuth(
44
+ _ctx: Context,
45
+ _clientId: string,
46
+ _authMethod: string,
47
+ _authData: Uint8Array,
48
+ ) {
49
+ return {
50
+ reasonCode: ReasonCode.badAuthenticationMethod,
51
+ reasonString: "Authentication method not supported",
52
+ };
53
+ }
54
+
55
+ function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
56
+ logger.debug(
57
+ "Checking authorization of client",
58
+ ctx.clientId,
59
+ "to publish on topic",
60
+ topic,
61
+ );
62
+ if (topic === "topic/unauthorized") {
63
+ return false;
64
+ }
65
+ return true;
66
+ }
67
+ function isAuthorizedToSubscribe(
68
+ ctx: Context,
69
+ topic: Topic,
70
+ shareName: ShareName,
71
+ ): boolean {
72
+ logger.debug(
73
+ "Checking authorization of client",
74
+ ctx.clientId,
75
+ "to subscribe to topic",
76
+ topic,
77
+ "using shareName",
78
+ shareName,
79
+ );
80
+ if (topic === "topic/unauthorized") {
81
+ return false;
82
+ }
83
+ return true;
84
+ }
85
+
86
+ export const handlers = {
87
+ isAuthenticated,
88
+ processAuth,
89
+ isAuthorizedToPublish,
90
+ isAuthorizedToSubscribe,
91
+ };
92
+
93
+ export function isAuthenticatedBroker(
94
+ ctx: Context,
95
+ ): AuthenticatedResult {
96
+ ctx.isBroker = true;
97
+ return { reasonCode: ReasonCode.success };
98
+ }