@seriousme/opifex 1.11.3 → 2.1.0

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 (542) 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 +3 -1
  6. package/client/client.ts +88 -47
  7. package/client/context.ts +79 -27
  8. package/client/deps.ts +10 -3
  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 +18 -8
  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 +13 -2
  29. package/client/store/memoryStore.ts +12 -11
  30. package/client/store/store.ts +4 -2
  31. package/deno/README.md +1 -2
  32. package/deno/tcpClient.test.ts +75 -0
  33. package/deno/tcpClient.ts +36 -18
  34. package/deno/tcpServer.test.ts +22 -21
  35. package/deno/tcpServer.ts +26 -4
  36. package/deno/tlsServer.test.ts +97 -0
  37. package/deno/tlsServer.ts +58 -0
  38. package/deno/wsServer.test.ts +93 -0
  39. package/deno/wsServer.ts +96 -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 +3 -1
  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 +47 -21
  60. package/dist/client/client.d.ts.map +1 -1
  61. package/dist/client/client.js +57 -20
  62. package/dist/client/client.js.map +1 -1
  63. package/dist/client/context.d.ts +15 -7
  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 +4 -3
  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 +3 -2
  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 +3 -3
  104. package/dist/client/store/memoryStore.d.ts.map +1 -1
  105. package/dist/client/store/memoryStore.js +3 -3
  106. package/dist/client/store/memoryStore.js.map +1 -1
  107. package/dist/client/store/store.d.ts +3 -2
  108. package/dist/client/store/store.d.ts.map +1 -1
  109. package/dist/client/store/store.js +1 -1
  110. package/dist/client/store/store.js.map +1 -1
  111. package/dist/dev_utils/generateCert.d.ts +11 -0
  112. package/dist/dev_utils/generateCert.d.ts.map +1 -0
  113. package/dist/dev_utils/generateCert.js +76 -0
  114. package/dist/dev_utils/generateCert.js.map +1 -0
  115. package/dist/examples/authHandler.test.d.ts +2 -0
  116. package/dist/examples/authHandler.test.d.ts.map +1 -0
  117. package/dist/examples/authHandler.test.js +123 -0
  118. package/dist/examples/authHandler.test.js.map +1 -0
  119. package/dist/examples/mqtt.test.d.ts +2 -0
  120. package/dist/examples/mqtt.test.d.ts.map +1 -0
  121. package/dist/examples/mqtt.test.js +70 -0
  122. package/dist/examples/mqtt.test.js.map +1 -0
  123. package/dist/examples/mqtts.test.d.ts +2 -0
  124. package/dist/examples/mqtts.test.d.ts.map +1 -0
  125. package/dist/examples/mqtts.test.js +81 -0
  126. package/dist/examples/mqtts.test.js.map +1 -0
  127. package/dist/mqttConn/mqttConn.d.ts +24 -31
  128. package/dist/mqttConn/mqttConn.d.ts.map +1 -1
  129. package/dist/mqttConn/mqttConn.js +57 -36
  130. package/dist/mqttConn/mqttConn.js.map +1 -1
  131. package/dist/mqttPacket/AuthenticationResult.d.ts +4 -0
  132. package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
  133. package/dist/mqttPacket/AuthenticationResult.js.map +1 -1
  134. package/dist/mqttPacket/BitMask.d.ts.map +1 -1
  135. package/dist/mqttPacket/PacketType.d.ts +4 -0
  136. package/dist/mqttPacket/PacketType.d.ts.map +1 -1
  137. package/dist/mqttPacket/Properties.d.ts +4 -4
  138. package/dist/mqttPacket/Properties.d.ts.map +1 -1
  139. package/dist/mqttPacket/Properties.js.map +1 -1
  140. package/dist/mqttPacket/ReasonCode.d.ts +4 -5
  141. package/dist/mqttPacket/ReasonCode.d.ts.map +1 -1
  142. package/dist/mqttPacket/ReasonCode.js +1 -0
  143. package/dist/mqttPacket/ReasonCode.js.map +1 -1
  144. package/dist/mqttPacket/RetainHandling.d.ts +4 -0
  145. package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
  146. package/dist/mqttPacket/auth.d.ts +7 -8
  147. package/dist/mqttPacket/auth.d.ts.map +1 -1
  148. package/dist/mqttPacket/auth.js +31 -30
  149. package/dist/mqttPacket/auth.js.map +1 -1
  150. package/dist/mqttPacket/codec.d.ts +48 -0
  151. package/dist/mqttPacket/codec.d.ts.map +1 -0
  152. package/dist/mqttPacket/codec.js +93 -0
  153. package/dist/mqttPacket/codec.js.map +1 -0
  154. package/dist/mqttPacket/connack.d.ts +11 -10
  155. package/dist/mqttPacket/connack.d.ts.map +1 -1
  156. package/dist/mqttPacket/connack.js +43 -45
  157. package/dist/mqttPacket/connack.js.map +1 -1
  158. package/dist/mqttPacket/connect.d.ts +7 -7
  159. package/dist/mqttPacket/connect.d.ts.map +1 -1
  160. package/dist/mqttPacket/connect.js +156 -157
  161. package/dist/mqttPacket/connect.js.map +1 -1
  162. package/dist/mqttPacket/decoder.d.ts +6 -16
  163. package/dist/mqttPacket/decoder.d.ts.map +1 -1
  164. package/dist/mqttPacket/decoder.js +7 -28
  165. package/dist/mqttPacket/decoder.js.map +1 -1
  166. package/dist/mqttPacket/disconnect.d.ts +9 -8
  167. package/dist/mqttPacket/disconnect.d.ts.map +1 -1
  168. package/dist/mqttPacket/disconnect.js +41 -43
  169. package/dist/mqttPacket/disconnect.js.map +1 -1
  170. package/dist/mqttPacket/encoder.d.ts +7 -19
  171. package/dist/mqttPacket/encoder.d.ts.map +1 -1
  172. package/dist/mqttPacket/encoder.js +5 -28
  173. package/dist/mqttPacket/encoder.js.map +1 -1
  174. package/dist/mqttPacket/mod.d.ts +21 -103
  175. package/dist/mqttPacket/mod.d.ts.map +1 -1
  176. package/dist/mqttPacket/mod.js +5 -94
  177. package/dist/mqttPacket/mod.js.map +1 -1
  178. package/dist/mqttPacket/pingreq.d.ts +6 -6
  179. package/dist/mqttPacket/pingreq.d.ts.map +1 -1
  180. package/dist/mqttPacket/pingreq.js +11 -13
  181. package/dist/mqttPacket/pingreq.js.map +1 -1
  182. package/dist/mqttPacket/pingres.d.ts +6 -6
  183. package/dist/mqttPacket/pingres.d.ts.map +1 -1
  184. package/dist/mqttPacket/pingres.js +11 -13
  185. package/dist/mqttPacket/pingres.js.map +1 -1
  186. package/dist/mqttPacket/protocolLevels.d.ts +11 -6
  187. package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
  188. package/dist/mqttPacket/protocolLevels.js +5 -1
  189. package/dist/mqttPacket/protocolLevels.js.map +1 -1
  190. package/dist/mqttPacket/pubblishAcks.d.ts +9 -10
  191. package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
  192. package/dist/mqttPacket/pubblishAcks.js +43 -45
  193. package/dist/mqttPacket/pubblishAcks.js.map +1 -1
  194. package/dist/mqttPacket/publish.d.ts +8 -7
  195. package/dist/mqttPacket/publish.d.ts.map +1 -1
  196. package/dist/mqttPacket/publish.js +53 -55
  197. package/dist/mqttPacket/publish.js.map +1 -1
  198. package/dist/mqttPacket/suback.d.ts +9 -8
  199. package/dist/mqttPacket/suback.d.ts.map +1 -1
  200. package/dist/mqttPacket/suback.js +38 -40
  201. package/dist/mqttPacket/suback.js.map +1 -1
  202. package/dist/mqttPacket/subscribe.d.ts +41 -10
  203. package/dist/mqttPacket/subscribe.d.ts.map +1 -1
  204. package/dist/mqttPacket/subscribe.js +90 -89
  205. package/dist/mqttPacket/subscribe.js.map +1 -1
  206. package/dist/mqttPacket/types.d.ts +2 -29
  207. package/dist/mqttPacket/types.d.ts.map +1 -1
  208. package/dist/mqttPacket/unsuback.d.ts +9 -8
  209. package/dist/mqttPacket/unsuback.d.ts.map +1 -1
  210. package/dist/mqttPacket/unsuback.js +32 -34
  211. package/dist/mqttPacket/unsuback.js.map +1 -1
  212. package/dist/mqttPacket/unsubscribe.d.ts +26 -8
  213. package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
  214. package/dist/mqttPacket/unsubscribe.js +45 -44
  215. package/dist/mqttPacket/unsubscribe.js.map +1 -1
  216. package/dist/mqttPacket/validators.d.ts +4 -16
  217. package/dist/mqttPacket/validators.d.ts.map +1 -1
  218. package/dist/mqttPacket/validators.js +5 -26
  219. package/dist/mqttPacket/validators.js.map +1 -1
  220. package/dist/node/tcpClient.d.ts +22 -2
  221. package/dist/node/tcpClient.d.ts.map +1 -1
  222. package/dist/node/tcpClient.js +29 -10
  223. package/dist/node/tcpClient.js.map +1 -1
  224. package/dist/node/tcpServer.d.ts +18 -0
  225. package/dist/node/tcpServer.d.ts.map +1 -1
  226. package/dist/node/tcpServer.js +21 -2
  227. package/dist/node/tcpServer.js.map +1 -1
  228. package/dist/node/tlsServer.d.ts +37 -0
  229. package/dist/node/tlsServer.d.ts.map +1 -0
  230. package/dist/node/tlsServer.js +73 -0
  231. package/dist/node/tlsServer.js.map +1 -0
  232. package/dist/node/wrapNodeSocket.d.ts.map +1 -1
  233. package/dist/node/wrapNodeSocket.js +6 -28
  234. package/dist/node/wrapNodeSocket.js.map +1 -1
  235. package/dist/persistence/basicPersistence.d.ts +36 -0
  236. package/dist/persistence/basicPersistence.d.ts.map +1 -0
  237. package/dist/persistence/basicPersistence.js +306 -0
  238. package/dist/persistence/basicPersistence.js.map +1 -0
  239. package/dist/persistence/deps.d.ts +3 -2
  240. package/dist/persistence/deps.d.ts.map +1 -1
  241. package/dist/persistence/deps.js +2 -1
  242. package/dist/persistence/deps.js.map +1 -1
  243. package/dist/persistence/memory/memoryPersistence.d.ts +6 -23
  244. package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
  245. package/dist/persistence/memory/memoryPersistence.js +12 -115
  246. package/dist/persistence/memory/memoryPersistence.js.map +1 -1
  247. package/dist/persistence/memory/memoryStorage.d.ts +45 -0
  248. package/dist/persistence/memory/memoryStorage.d.ts.map +1 -0
  249. package/dist/persistence/memory/memoryStorage.js +143 -0
  250. package/dist/persistence/memory/memoryStorage.js.map +1 -0
  251. package/dist/persistence/mod.d.ts +3 -3
  252. package/dist/persistence/mod.d.ts.map +1 -1
  253. package/dist/persistence/mod.js +6 -1
  254. package/dist/persistence/mod.js.map +1 -1
  255. package/dist/persistence/persistence.d.ts +45 -70
  256. package/dist/persistence/persistence.d.ts.map +1 -1
  257. package/dist/persistence/persistence.js +1 -2
  258. package/dist/persistence/persistence.js.map +1 -1
  259. package/dist/persistence/sqlite/sqliteDatabase.d.ts +46 -0
  260. package/dist/persistence/sqlite/sqliteDatabase.d.ts.map +1 -0
  261. package/dist/persistence/sqlite/sqliteDatabase.js +215 -0
  262. package/dist/persistence/sqlite/sqliteDatabase.js.map +1 -0
  263. package/dist/persistence/sqlite/sqlitePersistence.d.ts +16 -0
  264. package/dist/persistence/sqlite/sqlitePersistence.d.ts.map +1 -0
  265. package/dist/persistence/sqlite/sqlitePersistence.js +29 -0
  266. package/dist/persistence/sqlite/sqlitePersistence.js.map +1 -0
  267. package/dist/persistence/sqlite/sqliteStorage.d.ts +36 -0
  268. package/dist/persistence/sqlite/sqliteStorage.d.ts.map +1 -0
  269. package/dist/persistence/sqlite/sqliteStorage.js +194 -0
  270. package/dist/persistence/sqlite/sqliteStorage.js.map +1 -0
  271. package/dist/persistence/storage.d.ts +38 -0
  272. package/dist/persistence/storage.d.ts.map +1 -0
  273. package/dist/persistence/storage.js +5 -0
  274. package/dist/persistence/storage.js.map +1 -0
  275. package/dist/server/config.d.ts +47 -0
  276. package/dist/server/config.d.ts.map +1 -0
  277. package/dist/server/config.js +41 -0
  278. package/dist/server/config.js.map +1 -0
  279. package/dist/server/context.d.ts +199 -25
  280. package/dist/server/context.d.ts.map +1 -1
  281. package/dist/server/context.js +432 -53
  282. package/dist/server/context.js.map +1 -1
  283. package/dist/server/deps.d.ts +5 -6
  284. package/dist/server/deps.d.ts.map +1 -1
  285. package/dist/server/deps.js +2 -2
  286. package/dist/server/deps.js.map +1 -1
  287. package/dist/server/handlers/completeConnect.d.ts +9 -0
  288. package/dist/server/handlers/completeConnect.d.ts.map +1 -0
  289. package/dist/server/handlers/completeConnect.js +74 -0
  290. package/dist/server/handlers/completeConnect.js.map +1 -0
  291. package/dist/server/handlers/handleAuth.d.ts +9 -0
  292. package/dist/server/handlers/handleAuth.d.ts.map +1 -0
  293. package/dist/server/handlers/handleAuth.js +69 -0
  294. package/dist/server/handlers/handleAuth.js.map +1 -0
  295. package/dist/server/handlers/handleConnect.d.ts +2 -4
  296. package/dist/server/handlers/handleConnect.d.ts.map +1 -1
  297. package/dist/server/handlers/handleConnect.js +140 -67
  298. package/dist/server/handlers/handleConnect.js.map +1 -1
  299. package/dist/server/handlers/handleDisconnect.d.ts +1 -1
  300. package/dist/server/handlers/handleDisconnect.d.ts.map +1 -1
  301. package/dist/server/handlers/handleDisconnect.js +3 -3
  302. package/dist/server/handlers/handleDisconnect.js.map +1 -1
  303. package/dist/server/handlers/handlePacket.d.ts.map +1 -1
  304. package/dist/server/handlers/handlePacket.js +19 -6
  305. package/dist/server/handlers/handlePacket.js.map +1 -1
  306. package/dist/server/handlers/handlePuback.d.ts +1 -3
  307. package/dist/server/handlers/handlePuback.d.ts.map +1 -1
  308. package/dist/server/handlers/handlePuback.js +2 -8
  309. package/dist/server/handlers/handlePuback.js.map +1 -1
  310. package/dist/server/handlers/handlePubcomp.d.ts +1 -1
  311. package/dist/server/handlers/handlePubcomp.d.ts.map +1 -1
  312. package/dist/server/handlers/handlePubcomp.js +2 -4
  313. package/dist/server/handlers/handlePubcomp.js.map +1 -1
  314. package/dist/server/handlers/handlePublish.d.ts +1 -1
  315. package/dist/server/handlers/handlePublish.d.ts.map +1 -1
  316. package/dist/server/handlers/handlePublish.js +149 -45
  317. package/dist/server/handlers/handlePublish.js.map +1 -1
  318. package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
  319. package/dist/server/handlers/handlePubrec.js +2 -3
  320. package/dist/server/handlers/handlePubrec.js.map +1 -1
  321. package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
  322. package/dist/server/handlers/handlePubrel.js +6 -2
  323. package/dist/server/handlers/handlePubrel.js.map +1 -1
  324. package/dist/server/handlers/handleSubscribe.d.ts +1 -6
  325. package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
  326. package/dist/server/handlers/handleSubscribe.js +99 -38
  327. package/dist/server/handlers/handleSubscribe.js.map +1 -1
  328. package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
  329. package/dist/server/handlers/handleUnsubscribe.js +19 -4
  330. package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
  331. package/dist/server/mod.d.ts +3 -3
  332. package/dist/server/mod.d.ts.map +1 -1
  333. package/dist/server/mod.js +1 -1
  334. package/dist/server/mod.js.map +1 -1
  335. package/dist/server/server.d.ts +32 -9
  336. package/dist/server/server.d.ts.map +1 -1
  337. package/dist/server/server.js +84 -15
  338. package/dist/server/server.js.map +1 -1
  339. package/dist/socket/socket.d.ts +15 -9
  340. package/dist/socket/socket.d.ts.map +1 -1
  341. package/dist/socket/socket.js +66 -18
  342. package/dist/socket/socket.js.map +1 -1
  343. package/dist/timer/timer.d.ts +32 -0
  344. package/dist/timer/timer.d.ts.map +1 -1
  345. package/dist/timer/timer.js +32 -0
  346. package/dist/timer/timer.js.map +1 -1
  347. package/dist/trie/trie.d.ts +10 -5
  348. package/dist/trie/trie.d.ts.map +1 -1
  349. package/dist/trie/trie.js +61 -41
  350. package/dist/trie/trie.js.map +1 -1
  351. package/dist/utils/assert.d.ts.map +1 -1
  352. package/dist/utils/{BufferedAsyncIterable.d.ts → bufferedAsyncIterable.d.ts} +1 -1
  353. package/dist/utils/bufferedAsyncIterable.d.ts.map +1 -0
  354. package/dist/utils/{BufferedAsyncIterable.js → bufferedAsyncIterable.js} +1 -1
  355. package/dist/utils/bufferedAsyncIterable.js.map +1 -0
  356. package/dist/utils/deferred.d.ts.map +1 -1
  357. package/dist/utils/deferred.js.map +1 -1
  358. package/dist/utils/getOrInsertPolyFill.d.ts +2 -0
  359. package/dist/utils/getOrInsertPolyFill.d.ts.map +1 -0
  360. package/dist/utils/getOrInsertPolyFill.js +12 -0
  361. package/dist/utils/getOrInsertPolyFill.js.map +1 -0
  362. package/dist/utils/logger.d.ts +42 -5
  363. package/dist/utils/logger.d.ts.map +1 -1
  364. package/dist/utils/logger.js +53 -7
  365. package/dist/utils/logger.js.map +1 -1
  366. package/dist/utils/mod.d.ts +6 -1
  367. package/dist/utils/mod.d.ts.map +1 -1
  368. package/dist/utils/mod.js +5 -1
  369. package/dist/utils/mod.js.map +1 -1
  370. package/dist/utils/outboundTopicAliasManager.d.ts +52 -0
  371. package/dist/utils/outboundTopicAliasManager.d.ts.map +1 -0
  372. package/dist/utils/outboundTopicAliasManager.js +74 -0
  373. package/dist/utils/outboundTopicAliasManager.js.map +1 -0
  374. package/dist/utils/queue.d.ts.map +1 -1
  375. package/dist/utils/topicFilter.d.ts +32 -0
  376. package/dist/utils/topicFilter.d.ts.map +1 -0
  377. package/dist/utils/topicFilter.js +52 -0
  378. package/dist/utils/topicFilter.js.map +1 -0
  379. package/dist/utils/utils.d.ts +2 -0
  380. package/dist/utils/utils.d.ts.map +1 -1
  381. package/dist/utils/utils.js +2 -0
  382. package/dist/utils/utils.js.map +1 -1
  383. package/dist/utils/validators.d.ts +34 -0
  384. package/dist/utils/validators.d.ts.map +1 -0
  385. package/dist/utils/validators.js +61 -0
  386. package/dist/utils/validators.js.map +1 -0
  387. package/dist/web/webSocketStream.d.ts +29 -0
  388. package/dist/web/webSocketStream.d.ts.map +1 -0
  389. package/dist/web/webSocketStream.js +69 -0
  390. package/dist/web/webSocketStream.js.map +1 -0
  391. package/dist/web/wrapWebSocket.d.ts +12 -0
  392. package/dist/web/wrapWebSocket.d.ts.map +1 -0
  393. package/dist/web/wrapWebSocket.js +41 -0
  394. package/dist/web/wrapWebSocket.js.map +1 -0
  395. package/dist/web/wsClient.d.ts +14 -0
  396. package/dist/web/wsClient.d.ts.map +1 -0
  397. package/dist/web/wsClient.js +33 -0
  398. package/dist/web/wsClient.js.map +1 -0
  399. package/dist/web/wsClient.test.d.ts +2 -0
  400. package/dist/web/wsClient.test.d.ts.map +1 -0
  401. package/dist/web/wsClient.test.js +20 -0
  402. package/dist/web/wsClient.test.js.map +1 -0
  403. package/examples/authHandler.test.ts +164 -0
  404. package/examples/mqtt.test.ts +89 -0
  405. package/examples/mqtts.test.ts +100 -0
  406. package/examples/webSocket.test.ts +94 -0
  407. package/mqttConn/mqttConn.test.ts +9 -9
  408. package/mqttConn/mqttConn.ts +76 -60
  409. package/mqttPacket/AuthenticationResult.ts +6 -0
  410. package/mqttPacket/PacketType.ts +5 -0
  411. package/mqttPacket/Properties.ts +8 -5
  412. package/mqttPacket/ReasonCode.ts +8 -9
  413. package/mqttPacket/RetainHandling.ts +5 -0
  414. package/mqttPacket/auth.test.ts +1 -1
  415. package/mqttPacket/auth.ts +44 -51
  416. package/mqttPacket/codec.ts +147 -0
  417. package/mqttPacket/connack.ts +63 -73
  418. package/mqttPacket/connect.test.ts +2 -2
  419. package/mqttPacket/connect.ts +178 -192
  420. package/mqttPacket/decoder.test.ts +0 -39
  421. package/mqttPacket/decoder.ts +17 -46
  422. package/mqttPacket/disconnect.ts +60 -71
  423. package/mqttPacket/encoder.test.ts +2 -2
  424. package/mqttPacket/encoder.ts +13 -46
  425. package/mqttPacket/mod.ts +48 -204
  426. package/mqttPacket/pingreq.ts +22 -28
  427. package/mqttPacket/pingres.ts +22 -28
  428. package/mqttPacket/protocolLevels.ts +12 -7
  429. package/mqttPacket/pubblishAcks.ts +61 -75
  430. package/mqttPacket/publish.ts +70 -84
  431. package/mqttPacket/publishAcks.test.ts +3 -3
  432. package/mqttPacket/suback.ts +53 -68
  433. package/mqttPacket/subscribe.ts +146 -128
  434. package/mqttPacket/types.ts +2 -35
  435. package/mqttPacket/unsuback.ts +50 -61
  436. package/mqttPacket/unsubscribe.ts +77 -72
  437. package/mqttPacket/validators.ts +5 -31
  438. package/node/socket-node-stream.test.ts +322 -0
  439. package/node/socket-node-stream.ts +174 -0
  440. package/node/tcpClient.test.ts +70 -0
  441. package/node/tcpClient.ts +33 -17
  442. package/node/tcpServer.test.ts +24 -20
  443. package/node/tcpServer.ts +29 -6
  444. package/node/tlsServer.test.ts +94 -0
  445. package/node/tlsServer.ts +97 -0
  446. package/node/wrapNodeSocket.ts +7 -30
  447. package/package.json +72 -44
  448. package/persistence/basicPersistence.ts +495 -0
  449. package/persistence/deps.ts +11 -1
  450. package/persistence/memory/memoryPersistence.ts +12 -153
  451. package/persistence/memory/memoryStorage.ts +232 -0
  452. package/persistence/mod.ts +5 -10
  453. package/persistence/persistence.test.ts +24 -0
  454. package/persistence/persistence.testing.ts +1324 -0
  455. package/persistence/persistence.ts +112 -68
  456. package/persistence/sqlite/sqliteDatabase.ts +294 -0
  457. package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
  458. package/persistence/sqlite/sqlitePersistence.ts +36 -0
  459. package/persistence/sqlite/sqliteStorage.ts +324 -0
  460. package/persistence/storage.ts +84 -0
  461. package/server/config.ts +65 -0
  462. package/server/context.ts +660 -76
  463. package/server/deps.ts +24 -5
  464. package/server/handlers/completeConnect.ts +93 -0
  465. package/server/handlers/duplicate.test.ts +196 -0
  466. package/server/handlers/handleAuth.test.ts +225 -0
  467. package/server/handlers/handleAuth.ts +88 -0
  468. package/server/handlers/handleConnect.test.ts +589 -0
  469. package/server/handlers/handleConnect.ts +201 -86
  470. package/server/handlers/handleConnect.version.test.ts +108 -0
  471. package/server/handlers/handleDisconnect.test.ts +56 -0
  472. package/server/handlers/handleDisconnect.ts +3 -3
  473. package/server/handlers/handlePacket.test.ts +24 -0
  474. package/server/handlers/handlePacket.ts +30 -8
  475. package/server/handlers/handlePingreq.test.ts +29 -0
  476. package/server/handlers/handlePuback.test.ts +28 -0
  477. package/server/handlers/handlePuback.ts +5 -8
  478. package/server/handlers/handlePubcomp.test.ts +28 -0
  479. package/server/handlers/handlePubcomp.ts +5 -4
  480. package/server/handlers/handlePublish.test.ts +471 -0
  481. package/server/handlers/handlePublish.ts +188 -35
  482. package/server/handlers/handlePubrec.test.ts +28 -0
  483. package/server/handlers/handlePubrec.ts +2 -3
  484. package/server/handlers/handlePubrel.test.ts +74 -0
  485. package/server/handlers/handlePubrel.ts +12 -2
  486. package/server/handlers/handleSubscribe.test.ts +971 -0
  487. package/server/handlers/handleSubscribe.ts +157 -39
  488. package/server/handlers/handleUnsubscribe.test.ts +79 -0
  489. package/server/handlers/handleUnsubscribe.ts +28 -4
  490. package/server/handlers/keepalive.test.ts +132 -0
  491. package/server/handlers/session.persistence.test.ts +194 -0
  492. package/server/handlers/will.delivery.test.ts +221 -0
  493. package/server/mod.ts +5 -4
  494. package/server/preconnect.test.ts +151 -0
  495. package/server/server.ts +117 -19
  496. package/socket/socket.test.ts +91 -0
  497. package/socket/socket.ts +85 -34
  498. package/timer/timer.test.ts +4 -7
  499. package/timer/timer.ts +36 -0
  500. package/tools/benchmarks/receiver.ts +51 -0
  501. package/tools/benchmarks/sender.ts +48 -0
  502. package/tools/benchmarks/utils.ts +31 -0
  503. package/tools/mqtt-compat/README.md +130 -0
  504. package/tools/mqtt-compat/broker.ts +52 -0
  505. package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
  506. package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
  507. package/trie/trie.test.ts +9 -1
  508. package/trie/trie.ts +70 -45
  509. package/utils/bufferedAsyncIterable.test.ts +92 -0
  510. package/utils/deferred.test.ts +36 -0
  511. package/utils/deferred.ts +0 -1
  512. package/utils/getOrInsertPolyFill.ts +12 -0
  513. package/utils/logger.test.ts +189 -0
  514. package/utils/logger.ts +64 -9
  515. package/utils/mod.ts +15 -1
  516. package/utils/outboundTopicAliasManager.ts +100 -0
  517. package/utils/queue.test.ts +61 -0
  518. package/utils/topicFilter.test.ts +63 -0
  519. package/utils/topicFilter.ts +61 -0
  520. package/utils/utils.ts +3 -0
  521. package/utils/validators.ts +67 -0
  522. package/web/webSocketStream.ts +97 -0
  523. package/web/wrapWebSocket.ts +52 -0
  524. package/web/wsClient.test.ts +26 -0
  525. package/web/wsClient.ts +37 -0
  526. package/benchmarks/receiver.ts +0 -35
  527. package/benchmarks/sender.ts +0 -32
  528. package/benchmarks/utils.ts +0 -9
  529. package/dev_utils/dummyConn.ts +0 -110
  530. package/dev_utils/socketPair.ts +0 -85
  531. package/dist/persistence/store.d.ts +0 -14
  532. package/dist/persistence/store.d.ts.map +0 -1
  533. package/dist/persistence/store.js +0 -2
  534. package/dist/persistence/store.js.map +0 -1
  535. package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
  536. package/dist/utils/BufferedAsyncIterable.js.map +0 -1
  537. package/examples/tcpServer.test.ts +0 -148
  538. package/persistence/memory/memoryPersistence.test.ts +0 -156
  539. package/persistence/store.ts +0 -16
  540. package/server/test/handleConnect.test.ts +0 -122
  541. package/server/test/test-handlers.ts +0 -53
  542. /package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +0 -0
package/server/deps.ts CHANGED
@@ -1,12 +1,18 @@
1
- export type { SockConn } from "../socket/socket.ts";
1
+ export type { SockAddr, SockConn } from "../socket/socket.ts";
2
2
  export { MqttConn } from "../mqttConn/mqttConn.ts";
3
- export type { IPersistence } from "../persistence/persistence.ts";
4
- export type { IStore } from "../persistence/store.ts";
3
+ export type {
4
+ ClientSubscription,
5
+ ExtPublishPacket,
6
+ Persistence,
7
+ ShareName,
8
+ } from "../persistence/persistence.ts";
5
9
  export { MemoryPersistence } from "../persistence/memory/memoryPersistence.ts";
6
10
  export type {
7
11
  AnyPacket,
12
+ AuthPacket,
8
13
  ClientId,
9
14
  ConnackPacket,
15
+ ConnackProperties,
10
16
  ConnectPacket,
11
17
  DisconnectPacket,
12
18
  PacketId,
@@ -16,13 +22,14 @@ export type {
16
22
  PubackPacket,
17
23
  PubcompPacket,
18
24
  PublishPacket,
25
+ PublishPacketV5,
19
26
  PubrecPacket,
20
27
  PubrelPacket,
21
28
  QoS,
22
29
  SubackPacket,
23
30
  SubscribePacket,
24
31
  Subscription,
25
- TAuthenticationResult,
32
+ SubscriptionV5,
26
33
  Topic,
27
34
  TopicFilter,
28
35
  UnsubackPacket,
@@ -34,6 +41,18 @@ export {
34
41
  MQTTLevel,
35
42
  PacketNameByType,
36
43
  PacketType,
44
+ ReasonCode,
37
45
  } from "../mqttPacket/mod.ts";
38
46
  export { Timer } from "../timer/timer.ts";
39
- export { logger } from "../utils/mod.ts";
47
+ export {
48
+ assert,
49
+ hasWildcards,
50
+ invalidmaxTopicLevels,
51
+ invalidTopic,
52
+ invalidTopicFilter,
53
+ joinTopicFilter,
54
+ logger,
55
+ LogLevel,
56
+ OutboundTopicAliasManager,
57
+ parseTopicFilter,
58
+ } from "../utils/mod.ts";
@@ -0,0 +1,93 @@
1
+ import { AuthenticationResult, PacketType, ReasonCode } from "../deps.ts";
2
+ import type { ProtocolLevel } from "../deps.ts";
3
+ import type { Context } from "../context.ts";
4
+
5
+ /**
6
+ * Maps MQTT v5 ReasonCodes to MQTT v3.1.1 ReturnCodes (AuthenticationResult)
7
+ */
8
+ const V4_RETURN_CODE_MAP: Record<number, number> = {
9
+ [ReasonCode.success]: AuthenticationResult.ok, // 0x00
10
+ [ReasonCode.unsupportedProtocolVersion]:
11
+ AuthenticationResult.unacceptableProtocol, // 0x01
12
+ [ReasonCode.clientIdentifierNotValid]: AuthenticationResult.rejectedUsername, // 0x02
13
+ [ReasonCode.badUserNameOrPassword]:
14
+ AuthenticationResult.badUsernameOrPassword, // 0x04
15
+ [ReasonCode.badAuthenticationMethod]:
16
+ AuthenticationResult.badUsernameOrPassword, // 0x04
17
+ [ReasonCode.notAuthorized]: AuthenticationResult.notAuthorized, // 0x05
18
+ [ReasonCode.banned]: AuthenticationResult.notAuthorized, // 0x05
19
+ };
20
+
21
+ export function reasonToReturnCode(reasonCode: number): number {
22
+ return V4_RETURN_CODE_MAP[reasonCode] ??
23
+ AuthenticationResult.serverUnavailable; // 0x03
24
+ }
25
+
26
+ /**
27
+ * complete connect
28
+ */
29
+ export async function completeConnect(
30
+ ctx: Context,
31
+ protocolLevel: ProtocolLevel,
32
+ reasonCode: ReasonCode,
33
+ reasonString: string | undefined,
34
+ ) {
35
+ const cfg = ctx.config.context;
36
+ const connectOpts = ctx.connectOptions || {};
37
+ const isSuccess = reasonCode === ReasonCode.success;
38
+ const isProtocolV5 = protocolLevel === 5;
39
+
40
+ let sessionPresent = false;
41
+ if (isSuccess) {
42
+ // Establish Session on Success
43
+ sessionPresent = await ctx.connect();
44
+ }
45
+
46
+ // Send CONNACK
47
+ const result = isProtocolV5
48
+ ? {
49
+ reasonCode,
50
+ properties: {
51
+ // only send full details on success
52
+ ...(isSuccess
53
+ ? {
54
+ receiveMaximum: cfg.receiveMaximum,
55
+ maximumQos: cfg.maximumQos,
56
+ retainAvailable: cfg.retainAvailable,
57
+ maximumPacketSize: cfg.maximumIncomingPacketSize,
58
+ topicAliasMaximum: cfg.topicAliasMaximum,
59
+ wildcardSubscriptionAvailable: cfg.wildcardSubscriptionAvailable,
60
+ subscriptionIdentifierAvailable:
61
+ cfg.subscriptionIdentifierAvailable,
62
+ sharedSubscriptionAvailable: cfg.sharedSubscriptionAvailable,
63
+ serverKeepAlive: cfg.serverKeepAlive,
64
+ assignedClientIdentifier: connectOpts.assignedClientIdentifier,
65
+ sessionExpiryInterval: connectOpts.sessionExpiryInterval,
66
+ }
67
+ : {}),
68
+ reasonString: reasonString,
69
+ },
70
+ }
71
+ : { returnCode: reasonToReturnCode(reasonCode) };
72
+
73
+ await ctx.send({
74
+ type: PacketType.connack,
75
+ protocolLevel,
76
+ sessionPresent,
77
+ ...result,
78
+ });
79
+
80
+ // Finalize or Terminate Connection
81
+ if (!isSuccess) {
82
+ await ctx.close(false);
83
+ return;
84
+ }
85
+
86
+ // reset connectOptions
87
+ ctx.connectOptions = undefined;
88
+
89
+ // start redelivery
90
+ if (sessionPresent) {
91
+ await ctx.handleRedelivery();
92
+ }
93
+ }
@@ -0,0 +1,196 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import {
4
+ connect,
5
+ disconnect,
6
+ ping,
7
+ startMockServer,
8
+ } from "../../dev_utils/mod.ts";
9
+ import type { AnyPacket } from "../deps.ts";
10
+ import { MQTTLevel, PacketType } from "../deps.ts";
11
+
12
+ const txtEncoder = new TextEncoder();
13
+
14
+ test("MQTT-4.3.1: QoS 1 duplicate PUBLISH is acknowledged", async () => {
15
+ const { mqttConn } = startMockServer();
16
+
17
+ await connect(mqttConn);
18
+
19
+ // Send QoS 1 PUBLISH with dup=false
20
+ const publishPacket: AnyPacket = {
21
+ type: PacketType.publish,
22
+ protocolLevel: MQTTLevel.v4,
23
+ topic: "test/topic",
24
+ payload: txtEncoder.encode("message"),
25
+ qos: 1,
26
+ retain: false,
27
+ dup: false,
28
+ id: 1,
29
+ };
30
+ mqttConn.send(publishPacket);
31
+
32
+ // Receive first PUBACK
33
+ const { value: puback1 } = await mqttConn.next();
34
+ assert.deepStrictEqual(puback1.type, PacketType.puback);
35
+ if (puback1.type === PacketType.puback) {
36
+ assert.deepStrictEqual(puback1.id, 1);
37
+ }
38
+
39
+ // Send duplicate PUBLISH with dup=true and same packet ID
40
+ const duplicatePublishPacket: AnyPacket = {
41
+ type: PacketType.publish,
42
+ protocolLevel: MQTTLevel.v4,
43
+ topic: "test/topic",
44
+ payload: txtEncoder.encode("message"),
45
+ qos: 1,
46
+ retain: false,
47
+ dup: true,
48
+ id: 1,
49
+ };
50
+ mqttConn.send(duplicatePublishPacket);
51
+
52
+ // Should receive PUBACK for duplicate as well
53
+ const { value: puback2 } = await mqttConn.next();
54
+ assert.deepStrictEqual(
55
+ puback2.type,
56
+ PacketType.puback,
57
+ "Duplicate PUBLISH should receive PUBACK",
58
+ );
59
+ if (puback2.type === PacketType.puback) {
60
+ assert.deepStrictEqual(puback2.id, 1, "PUBACK ID should match");
61
+ }
62
+
63
+ await disconnect(mqttConn);
64
+ });
65
+
66
+ test("MQTT-4.3.2: QoS 2 duplicate PUBLISH returns PUBREC without redelivery", async () => {
67
+ const { mqttConn } = startMockServer();
68
+
69
+ await connect(mqttConn);
70
+
71
+ // Send QoS 2 PUBLISH with dup=false
72
+ const publishPacket: AnyPacket = {
73
+ type: PacketType.publish,
74
+ protocolLevel: MQTTLevel.v4,
75
+ topic: "test/topic",
76
+ payload: txtEncoder.encode("qos2message"),
77
+ qos: 2,
78
+ retain: false,
79
+ dup: false,
80
+ id: 2,
81
+ };
82
+ mqttConn.send(publishPacket);
83
+
84
+ // Receive first PUBREC
85
+ const { value: pubrec1 } = await mqttConn.next();
86
+ assert.deepStrictEqual(pubrec1.type, PacketType.pubrec);
87
+ if (pubrec1.type === PacketType.pubrec) {
88
+ assert.deepStrictEqual(pubrec1.id, 2);
89
+ }
90
+
91
+ // Send duplicate PUBLISH with dup=true and same packet ID
92
+ // Per MQTT spec: "the Receiver MUST acknowledge any subsequent
93
+ // PUBLISH packet with the same Packet Identifier by sending a PUBREC.
94
+ // It MUST NOT cause duplicate messages to be delivered to any onward recipients"
95
+ const duplicatePublishPacket: AnyPacket = {
96
+ type: PacketType.publish,
97
+ protocolLevel: MQTTLevel.v4,
98
+ topic: "test/topic",
99
+ payload: txtEncoder.encode("qos2message"),
100
+ qos: 2,
101
+ retain: false,
102
+ dup: true,
103
+ id: 2,
104
+ };
105
+ mqttConn.send(duplicatePublishPacket);
106
+
107
+ // Should receive PUBREC for duplicate without redelivery
108
+ const { value: pubrec2 } = await mqttConn.next();
109
+ assert.deepStrictEqual(
110
+ pubrec2.type,
111
+ PacketType.pubrec,
112
+ "Duplicate QoS 2 PUBLISH should return PUBREC",
113
+ );
114
+ if (pubrec2.type === PacketType.pubrec) {
115
+ assert.deepStrictEqual(pubrec2.id, 2);
116
+ }
117
+
118
+ // Complete the QoS 2 exchange with PUBREL
119
+ const pubrelPacket: AnyPacket = {
120
+ type: PacketType.pubrel,
121
+ protocolLevel: MQTTLevel.v4,
122
+ id: 2,
123
+ };
124
+ mqttConn.send(pubrelPacket);
125
+
126
+ // Should receive PUBCOMP
127
+ const { value: pubcomp } = await mqttConn.next();
128
+ assert.deepStrictEqual(pubcomp.type, PacketType.pubcomp);
129
+
130
+ await disconnect(mqttConn);
131
+ });
132
+
133
+ test("ignores duplicate PUBACK gracefully", async () => {
134
+ const { mqttConn } = startMockServer();
135
+
136
+ await connect(mqttConn);
137
+
138
+ // Send QoS 1 PUBLISH (incoming)
139
+ const publishPacket: AnyPacket = {
140
+ type: PacketType.publish,
141
+ protocolLevel: MQTTLevel.v4,
142
+ topic: "test/topic",
143
+ payload: txtEncoder.encode("message"),
144
+ qos: 1,
145
+ retain: false,
146
+ dup: false,
147
+ id: 3,
148
+ };
149
+ mqttConn.send(publishPacket);
150
+
151
+ // Receive PUBACK
152
+ const { value: puback } = await mqttConn.next();
153
+ assert.deepStrictEqual(puback.type, PacketType.puback);
154
+
155
+ // Send duplicate PUBACK (shouldn't cause any issue or response)
156
+ const duplicatePubackPacket: AnyPacket = {
157
+ type: PacketType.puback,
158
+ protocolLevel: MQTTLevel.v4,
159
+ id: 3,
160
+ };
161
+ mqttConn.send(duplicatePubackPacket);
162
+
163
+ // Send PINGREQ to verify server is still responsive
164
+ // Should receive PINGRES (duplicate PUBACK should be silently ignored)
165
+ await ping(mqttConn);
166
+
167
+ await disconnect(mqttConn);
168
+ });
169
+
170
+ test("PUBREL without prior PUBREC still returns PUBCOMP", async () => {
171
+ const { mqttConn } = startMockServer();
172
+
173
+ await connect(mqttConn);
174
+
175
+ // Send PUBREL directly without prior QoS 2 PUBLISH/PUBREC sequence
176
+ // This can happen if PUBREC was lost and client retransmits PUBREL
177
+ const pubrelPacket: AnyPacket = {
178
+ type: PacketType.pubrel,
179
+ protocolLevel: MQTTLevel.v4,
180
+ id: 99,
181
+ };
182
+ mqttConn.send(pubrelPacket);
183
+
184
+ // Should still receive PUBCOMP per MQTT spec [MQTT-4.3.3-1]
185
+ const { value: pubcomp } = await mqttConn.next();
186
+ assert.deepStrictEqual(
187
+ pubcomp.type,
188
+ PacketType.pubcomp,
189
+ "PUBREL without prior PUBREC should still return PUBCOMP",
190
+ );
191
+ if (pubcomp.type === PacketType.pubcomp) {
192
+ assert.deepStrictEqual(pubcomp.id, 99);
193
+ }
194
+
195
+ await disconnect(mqttConn);
196
+ });
@@ -0,0 +1,225 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import type { Context } from "../context.ts";
4
+ import { PacketType, ReasonCode } from "../deps.ts";
5
+ import {
6
+ auth,
7
+ connect5,
8
+ publish5,
9
+ startMockServer,
10
+ subscribe5,
11
+ unsubscribe5,
12
+ } from "../../dev_utils/mod.ts";
13
+
14
+ const successHandler = () => {
15
+ return {
16
+ reasonCode: ReasonCode.success,
17
+ authData: new Uint8Array([9, 9]),
18
+ reasonString: "Re-auth successful",
19
+ };
20
+ };
21
+
22
+ const multiStepHandler = (
23
+ _ctx: Context,
24
+ _clientId: string,
25
+ _authMethod: string,
26
+ authData: Uint8Array,
27
+ ) => {
28
+ if (authData[0] === 2) {
29
+ return {
30
+ reasonCode: ReasonCode.success,
31
+ };
32
+ }
33
+ return {
34
+ reasonCode: ReasonCode.continueAuthentication,
35
+ authData: new Uint8Array([12]),
36
+ };
37
+ };
38
+
39
+ test("Auth packet with no handler, closes connection", async () => {
40
+ const { mqttConn } = startMockServer();
41
+
42
+ // Connect first
43
+ await connect5(mqttConn);
44
+
45
+ // Send AUTH packet
46
+ await auth(mqttConn);
47
+ await mqttConn.next();
48
+
49
+ assert.strictEqual(mqttConn.isClosed, true);
50
+ });
51
+
52
+ test("Auth packet without authenticationMethod or authenticationData closes connection", async () => {
53
+ const { mqttConn } = startMockServer({
54
+ handlers: { processAuth: successHandler },
55
+ });
56
+
57
+ await connect5(mqttConn);
58
+ // Missing authenticationMethod and authenticationData
59
+ await auth(mqttConn, { noMethod: true, noData: true });
60
+ await mqttConn.next();
61
+ assert.strictEqual(mqttConn.isClosed, true);
62
+ });
63
+
64
+ test("Auth packet triggers continueAuthentication response", async () => {
65
+ const { mqttConn } = startMockServer({
66
+ handlers: {
67
+ processAuth(_ctx, _clientId, authMethod, authData) {
68
+ assert.strictEqual(authMethod, "SCRAM-SHA-256");
69
+ assert.deepStrictEqual(authData, new Uint8Array([1, 2, 3]));
70
+ return {
71
+ reasonCode: ReasonCode.continueAuthentication,
72
+ authData: new Uint8Array([4, 5, 6]),
73
+ reasonString: "Continue auth",
74
+ };
75
+ },
76
+ },
77
+ });
78
+
79
+ await connect5(mqttConn);
80
+ const response = await auth(mqttConn, {
81
+ authMethod: "SCRAM-SHA-256",
82
+ authData: new Uint8Array([1, 2, 3]),
83
+ });
84
+
85
+ assert.strictEqual(response?.type, PacketType.auth);
86
+ assert.strictEqual(response?.reasonCode, ReasonCode.continueAuthentication);
87
+ assert.strictEqual(
88
+ response?.properties?.authenticationMethod,
89
+ "SCRAM-SHA-256",
90
+ );
91
+ assert.deepStrictEqual(
92
+ response?.properties?.authenticationData,
93
+ new Uint8Array([4, 5, 6]),
94
+ );
95
+ assert.strictEqual(mqttConn.isClosed, false);
96
+ });
97
+
98
+ test("Connect packet completes initial connection with auth data", async () => {
99
+ const { mqttConn } = startMockServer({
100
+ handlers: { processAuth: successHandler },
101
+ });
102
+
103
+ await connect5(mqttConn, {
104
+ clientId: "test",
105
+ properties: {
106
+ authenticationMethod: "SCRAM-SHA-256",
107
+ authenticationData: new Uint8Array([1]),
108
+ },
109
+ });
110
+ });
111
+
112
+ test("Auth packet completes initial connection when in connecting state", async () => {
113
+ const { mqttConn } = startMockServer({
114
+ handlers: { processAuth: multiStepHandler },
115
+ });
116
+
117
+ const authResponse = await connect5(mqttConn, {
118
+ clientId: "test",
119
+ properties: {
120
+ authenticationMethod: "SCRAM-SHA-256",
121
+ authenticationData: new Uint8Array([1]),
122
+ },
123
+ checkAck: false,
124
+ });
125
+
126
+ assert.strictEqual(authResponse?.type, PacketType.auth);
127
+ assert.strictEqual(
128
+ authResponse?.reasonCode,
129
+ ReasonCode.continueAuthentication,
130
+ );
131
+ assert.deepEqual(
132
+ authResponse?.properties?.authenticationData,
133
+ new Uint8Array([12]),
134
+ );
135
+
136
+ const connack = await auth(mqttConn, {
137
+ authMethod: "SCRAM-SHA-256",
138
+ authData: new Uint8Array([2]),
139
+ });
140
+
141
+ assert.strictEqual(connack?.type, PacketType.connack);
142
+ assert.strictEqual(
143
+ connack?.reasonCode,
144
+ ReasonCode.success,
145
+ );
146
+
147
+ // check if connection is active by sending a qos1 and verifying puback
148
+ await publish5(mqttConn, "test/topic", 1);
149
+ });
150
+
151
+ test("Auth packet re-authentication success transitions state back to connected", async () => {
152
+ const { mqttConn } = startMockServer({
153
+ handlers: { processAuth: successHandler },
154
+ });
155
+
156
+ await connect5(mqttConn);
157
+ const response = await auth(mqttConn);
158
+ assert.strictEqual(response?.type, PacketType.auth);
159
+ assert.strictEqual(response?.reasonCode, ReasonCode.success);
160
+ assert.deepStrictEqual(
161
+ response?.properties?.authenticationData,
162
+ new Uint8Array([9, 9]),
163
+ );
164
+
165
+ // check if connection is active by sending a qos1 and verifying puback
166
+ await publish5(mqttConn, "test/topic", 1);
167
+ });
168
+
169
+ test("Auth packet re-authentication failure sends DISCONNECT and closes connection", async () => {
170
+ const { mqttConn } = startMockServer({
171
+ handlers: {
172
+ processAuth() {
173
+ return {
174
+ reasonCode: ReasonCode.notAuthorized,
175
+ reasonString: "Re-auth failed",
176
+ };
177
+ },
178
+ },
179
+ });
180
+
181
+ await connect5(mqttConn);
182
+ const response = await auth(mqttConn);
183
+ assert.strictEqual(response?.type, PacketType.disconnect);
184
+ assert.strictEqual(response?.reasonCode, ReasonCode.notAuthorized);
185
+ await mqttConn.next();
186
+ assert.strictEqual(mqttConn.isClosed, true);
187
+ });
188
+
189
+ test("Packets are blocked/rejected while state is authenticating", async () => {
190
+ const { mqttConn } = startMockServer({
191
+ handlers: { processAuth: multiStepHandler },
192
+ });
193
+
194
+ await connect5(mqttConn);
195
+
196
+ // subscribeso we can unsubscribe later
197
+ await subscribe5(mqttConn, [{
198
+ topicFilter: "test/topicToUnsubscribe",
199
+ qos: 0,
200
+ }]);
201
+ // start reauthentication
202
+ await auth(mqttConn);
203
+ // Publish attempt must be rejected with notAuthorized
204
+ const pubResp = await publish5(mqttConn, "test/topic", 1);
205
+ assert.strictEqual(pubResp?.type, PacketType.puback);
206
+ assert.strictEqual(pubResp?.reasonCode, ReasonCode.notAuthorized);
207
+
208
+ // Subscribe attempt must be rejected with notAuthorized
209
+ const subResp = await subscribe5(mqttConn, [{
210
+ topicFilter: "test/topic",
211
+ qos: 0,
212
+ }], { checkAcks: false });
213
+ assert.strictEqual(subResp?.type, PacketType.suback);
214
+ assert.strictEqual(subResp?.reasonCodes[0], ReasonCode.notAuthorized);
215
+
216
+ // Unsubscribe attempt must return noSubscriptionExisted
217
+ const unsubResp = await unsubscribe5(mqttConn, ["test/topicToUnsubscribe"]);
218
+
219
+ assert.strictEqual(unsubResp?.type, PacketType.unsuback);
220
+ assert.strictEqual(unsubResp?.protocolLevel, 5);
221
+ assert.strictEqual(
222
+ unsubResp?.reasonCodes[0],
223
+ ReasonCode.noSubscriptionExisted,
224
+ );
225
+ });
@@ -0,0 +1,88 @@
1
+ import { SessionState } from "../context.ts";
2
+ import type { AuthenticatedResult, Context } from "../context.ts";
3
+ import { PacketType, ReasonCode } from "../deps.ts";
4
+ import type { AuthPacket } from "../deps.ts";
5
+ import { completeConnect } from "./completeConnect.ts";
6
+
7
+ /**
8
+ * Handle success
9
+ */
10
+
11
+ async function handleResult(
12
+ ctx: Context,
13
+ authMethod: string,
14
+ result: AuthenticatedResult,
15
+ ) {
16
+ await ctx.send({
17
+ type: PacketType.auth,
18
+ protocolLevel: 5,
19
+ reasonCode: result.reasonCode,
20
+ properties: result.authData
21
+ ? {
22
+ authenticationMethod: authMethod,
23
+ authenticationData: result.authData,
24
+ reasonString: result.reasonString,
25
+ }
26
+ : {},
27
+ });
28
+ }
29
+ /**
30
+ * Handle errors
31
+ */
32
+
33
+ async function handleError(ctx: Context, result?: AuthenticatedResult) {
34
+ await ctx.send({
35
+ type: PacketType.disconnect,
36
+ protocolLevel: 5,
37
+ reasonCode: result?.reasonCode ?? ReasonCode.badAuthenticationMethod,
38
+ properties: {
39
+ reasonString: result?.reasonString ?? "Bad authentication mode",
40
+ },
41
+ });
42
+ await ctx.close(false);
43
+ }
44
+
45
+ /**
46
+ * Handles v5 Auth packet
47
+ * @param ctx - The connection context containing send method
48
+ * @returns Promise that resolves
49
+ */
50
+
51
+ export async function handleAuth(
52
+ ctx: Context,
53
+ authPacket: AuthPacket,
54
+ ): Promise<void> {
55
+ if (ctx.handlers.processAuth) {
56
+ const authMethod = authPacket.properties?.authenticationMethod;
57
+ const authData = authPacket.properties?.authenticationData;
58
+ if (!(authMethod && authData)) {
59
+ return await ctx.close(false);
60
+ }
61
+
62
+ if (ctx.state === SessionState.connected) {
63
+ ctx.state = SessionState.authenticating;
64
+ }
65
+ const result = await ctx.handlers.processAuth(
66
+ ctx,
67
+ ctx.clientId!,
68
+ authMethod,
69
+ authData,
70
+ );
71
+ // we need more data
72
+ if (result.reasonCode === ReasonCode.continueAuthentication) {
73
+ return handleResult(ctx, authMethod, result);
74
+ }
75
+ // we are done but were still connecting
76
+ if (ctx.state === SessionState.connecting) {
77
+ await completeConnect(ctx, 5, result.reasonCode, result.reasonString);
78
+ return;
79
+ }
80
+ // we are done but were reauthentication in flight
81
+ if (result.reasonCode === ReasonCode.success) {
82
+ ctx.state = SessionState.connected;
83
+ return handleResult(ctx, authMethod, result);
84
+ }
85
+ return handleError(ctx, result);
86
+ }
87
+ return handleError(ctx);
88
+ }