@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
package/README.md CHANGED
@@ -6,21 +6,58 @@
6
6
 
7
7
  Opifex aims to provide a MQTT server and MQTT client in Typescript to be used
8
8
  with [NodeJS](https://nodejs.org), [Deno](https://deno.land) or
9
- [Bun](https://bun.sh) It has _no_ third party dependencies, it only relies on
10
- built in modules.
9
+ [Bun](https://bun.sh). It has _no_ third-party dependencies, it only relies on
10
+ built-in modules.
11
11
 
12
12
  # Compatibility
13
13
 
14
14
  The following MQTT versions are supported:
15
15
 
16
- | | MQTT 3.1 (v3) | MQTT 3.1.1 (v4) | MQTT 5.0 (v5) |
17
- | -------------- | ------------- | --------------- | ------------- |
18
- | Packet/encoder | ✅ | ✅ | ✅ |
19
- | Client | ✅ | ✅ | ✅ partially |
20
- | Server | ❌ | ✅ | ❌ |
16
+ | | MQTT 3.1 (v3) | MQTT 3.1.1 (v4) | MQTT 5.0 (v5) |
17
+ | -------------- | ------------- | --------------- | --------------- |
18
+ | Packet/encoder | ✅ | ✅ | ✅ |
19
+ | Client | ✅ | ✅ | ✅ <sup>1</sup> |
20
+ | Server | ❌ | ✅ | ✅ |
21
21
 
22
- Client and server currently only have memory based persistence, but one can
23
- provide its own persistence. (see [Architecture](#architecture))
22
+ <sup>1</sup> The client API fully supports MQTTv5, the CLI only supports a
23
+ subset
24
+
25
+ Version 5 support includes:
26
+
27
+ - Client Topic Alias ✅
28
+ - Server Topic Alias ✅
29
+ - Subscription Identifiers ✅
30
+ - Subscription options (NoLocal, RetainAsPublished, RetainHandling) ✅
31
+ - Message expiry interval ✅
32
+ - Will delay ✅
33
+ - Assigned Client Identifier ✅
34
+ - Client receive maximum ✅
35
+ - Server receive maximum ✅
36
+ - Shared Subscriptions ✅
37
+
38
+ # Transports
39
+
40
+ The following transports are currently supported:
41
+
42
+ - plain TCP ✅
43
+ - TLS ✅
44
+ - WebSockets ✅ <sup>2</sup>
45
+
46
+ <sup>2</sup> Deno + Browser only, NodeJS has no native websocket support.
47
+
48
+ You can add your own transports.
49
+
50
+ # Persistence
51
+
52
+ Opifex offers pluggable persistence, but one can provide its own persistence.
53
+ (see [Architecture](#architecture))
54
+
55
+ The following types are currently provided:
56
+
57
+ | | Plugable | Memory | Sqlite |
58
+ | ------ | -------- | ------ | ------ |
59
+ | Client | ✅ | ✅ | ❌ |
60
+ | Server | ✅ | ✅ | ✅ |
24
61
 
25
62
  ## Usage
26
63
 
@@ -35,8 +72,8 @@ can be done with CLI options then the next step is to clone the demo server
35
72
  and/or the client scripts and modify them to your liking.
36
73
 
37
74
  If you want to port the platform independent client and server libs to other
38
- types of transports (e.g. Unix sockets or websocketstream) then it's recommended
39
- to clone and modify the platform specific code in `/node` or `/deno` as well.
75
+ types of transports (e.g. Unix sockets) then it's recommended to clone and
76
+ modify the platform specific code in `/node` , `/deno` or `/web` as well.
40
77
 
41
78
  If you want to port the platform independent client and server libs to another
42
79
  platform then the platform specific code in `/node` or `/deno` might serve as
@@ -47,20 +84,25 @@ but for historic reasons `/deno` still exists.
47
84
 
48
85
  ## Example
49
86
 
50
- A simple server example using Deno.
87
+ A simple server example:
51
88
 
52
89
  ```typescript
53
- import { MqttServer } from "./server/mod.ts";
54
-
55
- const listener = Deno.listen();
56
- const mqttServer = new MqttServer(mqttOptions);
57
- for await (const conn of this.listener) {
58
- mqttServer.serve(conn);
59
- }
90
+ import { TcpServer } from "@seriousme/opifex/tcpServer";
91
+
92
+ const server = new TcpServer({ port: 1883 }, {
93
+ // just an example of how to configure the server
94
+ configuration: {
95
+ context: { maximumConnectPacketSize: 3000 },
96
+ },
97
+ });
98
+ server.start();
99
+ console.log(
100
+ `MQTT server running on port: ${server.port}, address: ${server.address}`,
101
+ );
60
102
  ```
61
103
 
62
- A more elaborate example including client and server can be found in the
63
- [examples](/examples/) folder.
104
+ More elaborate examples including client and server, TLS, Websockets and sqlite
105
+ can be found in the [examples](/examples/) folder.
64
106
 
65
107
  ## Architecture
66
108
 
@@ -69,10 +111,10 @@ A more elaborate example including client and server can be found in the
69
111
  encode and decode packets.
70
112
 
71
113
  2. On top of mqttPacket sits the MQTT connection module
72
- ([mqttConn/mod.ts](mqttConn/mod.ts)) module that reads packets from a
73
- Readable stream and writes them to Writable stream. It will take care of
74
- incomplete and/or malformed packets. mqttConn provides an async iterable that
75
- can be awaited for new packets.
114
+ ([mqttConn/mod.ts](mqttConn/mod.ts)) that reads packets from a Readable
115
+ stream and writes them to Writable stream. It will take care of incomplete
116
+ and/or malformed packets. mqttConn provides an async iterable that can be
117
+ awaited for new packets.
76
118
 
77
119
  3. On top of mqttConn live the MQTT server ([server/mod.ts](server/mod.ts)) and
78
120
  MQTT client ([client/mod.ts](client/mod.ts)) that take care of the MQTT
@@ -88,29 +130,46 @@ A more elaborate example including client and server can be found in the
88
130
  keep track of its state and associated timers.
89
131
 
90
132
  5. Persistence of data is handled by a pluggable persistence module
91
- ([persistence](persistence)) which currently only offers memory persistence
92
- ([persistence/memory](persistence/memory)) but can be extended with database
93
- backed persistence supported by third party modules.
133
+ ([persistence](persistence)) which currently offers single process
134
+ persistence which you can replace by something more scalable (e.g. redis
135
+ based clusters etc) This is backed by two storage providers:
136
+ - [memory](persistence/memory)
137
+ - [sqlite](persistence/sqlite), based on node:sqlite
138
+
139
+ but can be extended with other database backend persistence supported by
140
+ third-party modules.
141
+
142
+ 6. Server behavior can be customized by passing a
143
+ [ConfigurationInput object](server/config.ts) via
144
+ `MqttServerOptions.configuration`, see the example above.
94
145
 
95
- 6. The demo server listens to a platform specific socket and runs the `serve()`
146
+ 7. The demo server listens to a platform specific socket and runs the `serve()`
96
147
  method from the server module on the platform independent streams of every
97
148
  connection.
98
149
 
99
- 7. The demo client opens a platform specific socket and passes the resulting
150
+ 8. The demo client opens a platform specific socket and passes the resulting
100
151
  platform independent streams to the client module.
101
152
 
102
153
  ## Exports
103
154
 
104
- | Export | Description |
105
- | ----------------------------- | ------------------------------------------------------- |
106
- | @seriousme/opifex/tcpClient | Exports a MQTT over TCP client |
107
- | @seriousme/opifex/tcpServer | Exports a MQTT over TCP server |
108
- | @seriousme/opifex/server | Exports a transport agnostic MQTT server |
109
- | @seriousme/opifex/client | Exports a transport agnostic MQTT client |
110
- | @seriousme/opifex/persistence | Exports an Typescript interface for storage persistence |
111
- | @seriousme/opifex/mqttConn | Exports MQTT connection handling |
112
- | @seriousme/opifex/mqttPacket | Exports MQTT packet handling |
113
- | @seriousme/opifex/utils | Exports various utilities |
155
+ | Export | Description |
156
+ | ----------------------------- | ------------------------------------------------------------ |
157
+ | @seriousme/opifex/tcpClient | Exports a MQTT over TCP/TLS client |
158
+ | @seriousme/opifex/tcpServer | Exports a MQTT over TCP server |
159
+ | @seriousme/opifex/tlsServer | Exports a MQTT over TLS server |
160
+ | @seriousme/opifex/wsClient | Exports a MQTT over Websocket client (deno and browser only) |
161
+ | @seriousme/opifex/wsServer | Exports a MQTT over Websocket server (deno only) |
162
+ | @seriousme/opifex/server | Exports a transport agnostic MQTT server |
163
+ | @seriousme/opifex/client | Exports a transport agnostic MQTT client |
164
+ | @seriousme/opifex/persistence | Exports a Typescript interface for storage persistence |
165
+ | @seriousme/opifex/mqttConn | Exports MQTT connection handling |
166
+ | @seriousme/opifex/mqttPacket | Exports MQTT packet handling |
167
+ | @seriousme/opifex/utils | Exports various utilities |
168
+
169
+ ## API docs
170
+
171
+ The latest API documentation can be found at:
172
+ https://jsr.io/@seriousme/opifex@latest/doc
114
173
 
115
174
  ## Naming
116
175
 
@@ -7,8 +7,14 @@
7
7
  */
8
8
  import { parseArgs } from "node:util";
9
9
  import { TcpServer } from "../node/tcpServer.ts";
10
- import type { Context, TAuthenticationResult, Topic } from "../server/mod.ts";
11
- import { AuthenticationResult } from "../server/mod.ts";
10
+ import type {
11
+ AuthenticatedResult,
12
+ ConnectPacket,
13
+ Context,
14
+ ShareName,
15
+ Topic,
16
+ } from "../server/mod.ts";
17
+ import { ReasonCode } from "../server/mod.ts";
12
18
  import { logger, LogLevel } from "../utils/mod.ts";
13
19
 
14
20
  /**
@@ -42,35 +48,49 @@ const checkUsername = true;
42
48
  * @param {string} clientId - Client identifier
43
49
  * @param {string} username - Username to authenticate
44
50
  * @param {Uint8Array} password - Password as byte array
45
- * @returns {TAuthenticationResult} Authentication result
51
+ * @param {ConnectPacket} connectPacket - The raw connect packet
52
+ * @returns {IsAuthenticationResult} Authentication result
46
53
  */
47
54
  function isAuthenticated(
48
55
  _ctx: Context,
49
56
  clientId: string,
50
57
  username: string,
51
58
  password: Uint8Array,
52
- ): TAuthenticationResult {
59
+ connectPacket: ConnectPacket,
60
+ ): AuthenticatedResult {
53
61
  const pwd = utf8Decoder.decode(password);
54
62
  logger.info(
55
- `Verifying authentication of client '${clientId}' with username '${username}' and password '${pwd}'`,
63
+ "Verifying authentication of client",
64
+ clientId,
65
+ "with username",
66
+ username,
67
+ );
68
+ logger.debug(
69
+ "Client",
70
+ clientId,
71
+ "connecting with protocol level",
72
+ connectPacket.protocolLevel,
56
73
  );
57
74
 
58
75
  if (!checkUsername) {
59
76
  // allow all users access
60
- return AuthenticationResult.ok;
77
+ return { reasonCode: ReasonCode.success };
61
78
  }
62
79
  // is the username valid according to MQTT specification
63
80
  if (!strictUsername.test(username)) {
64
- return AuthenticationResult.badUsernameOrPassword;
81
+ return { reasonCode: ReasonCode.badUserNameOrPassword };
65
82
  }
66
83
  // Does user and password match an entry in userTable
67
84
  if (userTable.has(username)) {
68
85
  const pass = userTable.get(username);
69
86
  if (pwd === pass) {
70
- return AuthenticationResult.ok;
87
+ return { reasonCode: ReasonCode.success };
71
88
  }
72
89
  }
73
- return AuthenticationResult.notAuthorized;
90
+ return {
91
+ reasonCode: ReasonCode.notAuthorized,
92
+ reasonString: "Authentication failed",
93
+ };
74
94
  }
75
95
 
76
96
  /**
@@ -81,7 +101,10 @@ function isAuthenticated(
81
101
  */
82
102
  function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
83
103
  logger.debug(
84
- `Checking authorization of client '${ctx.store?.clientId}' to publish on topic '${topic}'`,
104
+ "Checking authorization of client",
105
+ ctx.clientId,
106
+ "to publish on topic",
107
+ topic,
85
108
  );
86
109
  return true;
87
110
  }
@@ -92,9 +115,18 @@ function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
92
115
  * @param {Topic} topic - Topic to subscribe to
93
116
  * @returns {boolean} True if authorized
94
117
  */
95
- function isAuthorizedToSubscribe(ctx: Context, topic: Topic): boolean {
118
+ function isAuthorizedToSubscribe(
119
+ ctx: Context,
120
+ topic: Topic,
121
+ shareName: ShareName,
122
+ ): boolean {
96
123
  logger.debug(
97
- `Checking authorization of client '${ctx.store?.clientId}' to subscribe to topic '${topic}'`,
124
+ "Checking authorization of client",
125
+ ctx.clientId,
126
+ "to subscribe to topic",
127
+ topic,
128
+ "using shareName",
129
+ shareName,
98
130
  );
99
131
  return true;
100
132
  }
@@ -118,4 +150,4 @@ const tcpServer = new TcpServer({ port, hostname }, {
118
150
  },
119
151
  });
120
152
  tcpServer.start();
121
- logger.info(`Server started on port ${tcpServer.port}`);
153
+ logger.info("Server started on port", tcpServer.port);
package/bin/demoServer.ts CHANGED
@@ -6,8 +6,14 @@
6
6
  */
7
7
  import { parseArgs } from "node:util";
8
8
  import { TcpServer } from "../node/tcpServer.ts";
9
- import type { Context, TAuthenticationResult, Topic } from "../server/mod.ts";
10
- import { AuthenticationResult } from "../server/mod.ts";
9
+ import type {
10
+ AuthenticatedResult,
11
+ ConnectPacket,
12
+ Context,
13
+ ShareName,
14
+ Topic,
15
+ } from "../server/mod.ts";
16
+ import { ReasonCode } from "../server/mod.ts";
11
17
  import { logger, LogLevel } from "../utils/mod.ts";
12
18
 
13
19
  /**
@@ -41,35 +47,42 @@ const checkUsername = false;
41
47
  * @param {string} clientId - Client identifier
42
48
  * @param {string} username - Username to authenticate
43
49
  * @param {Uint8Array} password - Password as byte array
44
- * @returns {TAuthenticationResult} Authentication result
50
+ * @returns {IsAuthenticationResult} Authentication result
45
51
  */
46
52
  function isAuthenticated(
47
53
  _ctx: Context,
48
54
  clientId: string,
49
55
  username: string,
50
56
  password: Uint8Array,
51
- ): TAuthenticationResult {
57
+ connectPacket: ConnectPacket,
58
+ ): AuthenticatedResult {
52
59
  const pwd = utf8Decoder.decode(password);
53
60
  logger.info(
54
- `Verifying authentication of client '${clientId}' with username '${username}' and password '${pwd}'`,
61
+ `Verifying authentication of client '${clientId}' with username '${username}'`,
62
+ );
63
+ logger.debug(
64
+ `Client '${clientId}' connecting with protocol level ${connectPacket.protocolLevel}`,
55
65
  );
56
66
 
57
67
  if (!checkUsername) {
58
68
  // allow all users access
59
- return AuthenticationResult.ok;
69
+ return { reasonCode: ReasonCode.success };
60
70
  }
61
71
  // is the username valid according to MQTT specification
62
72
  if (!strictUsername.test(username)) {
63
- return AuthenticationResult.badUsernameOrPassword;
73
+ return { reasonCode: ReasonCode.badUserNameOrPassword };
64
74
  }
65
75
  // Does user and password match an entry in userTable
66
76
  if (userTable.has(username)) {
67
77
  const pass = userTable.get(username);
68
78
  if (pwd === pass) {
69
- return AuthenticationResult.ok;
79
+ return { reasonCode: ReasonCode.success };
70
80
  }
71
81
  }
72
- return AuthenticationResult.notAuthorized;
82
+ return {
83
+ reasonCode: ReasonCode.notAuthorized,
84
+ reasonString: "Authentication failed",
85
+ };
73
86
  }
74
87
 
75
88
  /**
@@ -80,7 +93,10 @@ function isAuthenticated(
80
93
  */
81
94
  function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
82
95
  logger.debug(
83
- `Checking authorization of client '${ctx.store?.clientId}' to publish on topic '${topic}'`,
96
+ "Checking authorization of client",
97
+ ctx.clientId,
98
+ "to publish on topic",
99
+ topic,
84
100
  );
85
101
  return true;
86
102
  }
@@ -91,9 +107,18 @@ function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
91
107
  * @param {Topic} topic - Topic to subscribe to
92
108
  * @returns {boolean} True if authorized
93
109
  */
94
- function isAuthorizedToSubscribe(ctx: Context, topic: Topic): boolean {
110
+ function isAuthorizedToSubscribe(
111
+ ctx: Context,
112
+ topic: Topic,
113
+ shareName: ShareName,
114
+ ): boolean {
95
115
  logger.debug(
96
- `Checking authorization of client '${ctx.store?.clientId}' to subscribe to topic '${topic}'`,
116
+ "Checking authorization of client",
117
+ ctx.clientId,
118
+ "to subscribe to topic",
119
+ topic,
120
+ "using shareName",
121
+ shareName,
97
122
  );
98
123
  return true;
99
124
  }
@@ -117,4 +142,4 @@ const tcpServer = new TcpServer({ port, hostname }, {
117
142
  },
118
143
  });
119
144
  tcpServer.start();
120
- logger.info(`Server started on port ${tcpServer.port}`);
145
+ logger.info("Server started on port", tcpServer.port);
package/bin/mqtt.ts CHANGED
@@ -229,7 +229,7 @@ async function subscribe() {
229
229
  } catch (err) {
230
230
  if (err instanceof Error) {
231
231
  const errorWithCode = err as Error & { code?: string };
232
- logger.info(`Error: ${errorWithCode.message || errorWithCode.code}`);
232
+ logger.info("Error:", errorWithCode.message || errorWithCode.code);
233
233
  }
234
234
  }
235
235
  }
@@ -283,7 +283,7 @@ async function publish() {
283
283
  } catch (err) {
284
284
  if (err instanceof Error) {
285
285
  const errorWithCode = err as Error & { code?: string };
286
- logger.info(`Error: ${errorWithCode.message || errorWithCode.code}`);
286
+ logger.info("Error:", errorWithCode.message || errorWithCode.code);
287
287
  }
288
288
  }
289
289
  }
@@ -13,6 +13,8 @@ export const ConnectionState = {
13
13
  disconnecting: "disconnecting",
14
14
  /** System has been disconnected */
15
15
  disconnected: "disconnected",
16
+ /** System is authenticating mid session */
17
+ authenticating: "authenticating",
16
18
  } as const;
17
19
 
18
20
  /**
package/client/client.ts CHANGED
@@ -4,21 +4,23 @@ import {
4
4
  MemoryStore,
5
5
  MQTTLevel,
6
6
  PacketType,
7
+ ReasonCode,
7
8
  } from "./deps.ts";
8
9
 
9
10
  import type {
10
11
  ConnectPacket,
12
+ IStore,
11
13
  PublishPacket,
12
14
  SockConn,
13
15
  SubscribePacket,
14
16
  TAuthenticationResult,
15
17
  } from "./deps.ts";
16
18
 
17
- import { noop } from "../utils/utils.ts";
19
+ import { noop } from "../utils/mod.ts";
18
20
 
19
21
  import { Context } from "./context.ts";
22
+ import type { AuthenticatedResult } from "./context.ts";
20
23
  import type { TConnectionState } from "./ConnectionState.ts";
21
- import { assert } from "../utils/assert.ts";
22
24
  import { BufferedAsyncIterable } from "./deps.ts";
23
25
 
24
26
  /**
@@ -84,6 +86,20 @@ export const DEFAULT_KEEPALIVE = 60; // 60 seconds
84
86
  const DEFAULT_RETRIES = 3; // on first connect
85
87
  const CLIENTID_PREFIX = "opifex"; // on first connect
86
88
 
89
+ // convert an ErrorEvent into an Error
90
+ // NodeJS does not know ErrorEvent
91
+ function normalizeError(err: unknown): Error {
92
+ if (typeof ErrorEvent !== "undefined" && err instanceof ErrorEvent) {
93
+ return new Error(err.message);
94
+ }
95
+
96
+ if (err instanceof Error) {
97
+ return err;
98
+ }
99
+
100
+ throw err;
101
+ }
102
+
87
103
  /**
88
104
  * The Client class provides an MQTT Client that can be used to connect to
89
105
  * a MQTT broker and publish/subscribe messages.
@@ -94,6 +110,15 @@ const CLIENTID_PREFIX = "opifex"; // on first connect
94
110
  * connection type that is supported by the subclass.
95
111
  */
96
112
  export class Client {
113
+ public onAuth: (
114
+ authMethod: string,
115
+ authData: Uint8Array,
116
+ ) => AuthenticatedResult = () => {
117
+ return {
118
+ reasonCode: ReasonCode.badAuthenticationMethod,
119
+ reasonString: "No authentication method configured",
120
+ };
121
+ };
97
122
  public onError: (err: Error) => void = noop;
98
123
  public onPacket: (pkt: PublishPacket) => void | Promise<void> = noop;
99
124
  public onConnected: () => void = noop;
@@ -102,51 +127,43 @@ export class Client {
102
127
 
103
128
  protected clientIdPrefix = CLIENTID_PREFIX;
104
129
  protected numberOfRetries = DEFAULT_RETRIES;
105
- protected url: URL = new URL(DEFAULT_URL);
130
+ protected connectUrl: URL = new URL(DEFAULT_URL);
106
131
  protected keepAlive = DEFAULT_KEEPALIVE;
107
132
  protected protocolLevel = DEFAULT_PROTOCOLLEVEL;
108
133
  protected autoReconnect = true;
109
- private caCerts?: string[] | undefined;
110
- private cert?: string | undefined;
111
- private key?: string | undefined;
112
- private clientId: string;
134
+ protected caCerts?: string[] | undefined;
135
+ protected cert?: string | undefined;
136
+ protected key?: string | undefined;
137
+ protected clientId: string;
113
138
  private ctx: Context;
114
139
  private connectPacket?: ConnectPacket;
115
140
 
116
141
  /**
117
142
  * Creates a new MQTT client instance
118
143
  */
119
- constructor() {
120
- this.ctx = new Context(new MemoryStore(), this);
144
+ constructor(store?: IStore) {
145
+ const cStore = store ? store : new MemoryStore();
146
+ this.ctx = new Context(cStore, this);
121
147
  this.clientId = generateClientId(this.clientIdPrefix);
122
148
  this.numberOfRetries = DEFAULT_RETRIES;
123
149
  }
124
150
 
125
- get connectionState(): TConnectionState {
151
+ public get connectionState(): TConnectionState {
126
152
  return this.ctx.connectionState;
127
153
  }
128
154
 
155
+ public get url(): URL {
156
+ return this.connectUrl;
157
+ }
158
+
129
159
  /**
130
160
  * Creates a new connection to the MQTT broker
131
- * @param protocol - The protocol to use (mqtt, mqtts, etc)
132
- * @param _hostname - The hostname to connect to
133
- * @param _port - The port to connect to
134
- * @param _caCerts - Optional CA certificates
135
- * @param _cert - Optional client certificate
136
- * @param _key - Optional client key
137
161
  * @returns Promise resolving to a SockConn connection
138
162
  */
139
- protected createConn(
140
- protocol: string,
141
- _hostname: string,
142
- _port?: number,
143
- _caCerts?: string[],
144
- _cert?: string,
145
- _key?: string,
146
- ): Promise<SockConn> {
163
+ protected createConn(): Promise<SockConn> {
147
164
  // if you need to support alternative connection types just
148
165
  // overload this method in your subclass
149
- throw new Error(`Unsupported protocol: ${protocol}`);
166
+ throw new Error(`Unsupported protocol: ${this.url.protocol}`);
150
167
  }
151
168
 
152
169
  /**
@@ -163,16 +180,12 @@ export class Client {
163
180
  let lastMessage = new Error();
164
181
  let tryConnect = true;
165
182
  while (tryConnect) {
166
- logger.debug(`${isReconnect ? "re" : ""}connecting, attempt ${attempt}`);
183
+ logger.debug(
184
+ isReconnect ? "reconnecting, attempt" : "connecting, attempt",
185
+ attempt,
186
+ );
167
187
  try {
168
- const conn = await this.createConn(
169
- this.url.protocol,
170
- this.url.hostname,
171
- Number(this.url.port) ?? undefined,
172
- this.caCerts,
173
- this.cert,
174
- this.key,
175
- );
188
+ const conn = await this.createConn();
176
189
  // if we get this far we have a connection
177
190
  tryConnect =
178
191
  (await this.ctx.handleConnection(conn, this.connectPacket)) &&
@@ -182,12 +195,9 @@ export class Client {
182
195
  this.connectPacket.clean = false;
183
196
  this.ctx.close();
184
197
  } catch (err) {
185
- assert(
186
- err instanceof Error,
187
- `Caught something that is not an instance of Error: ${err}`,
188
- );
189
- queueMicrotask(() => this.onError(err));
190
- lastMessage = err;
198
+ const normalizedErr = normalizeError(err);
199
+ queueMicrotask(() => this.onError(normalizedErr));
200
+ lastMessage = normalizedErr;
191
201
  logger.debug({ lastMessage });
192
202
  }
193
203
 
@@ -213,7 +223,7 @@ export class Client {
213
223
  * @returns Promise resolving to authentication result
214
224
  */
215
225
  connect(params: ConnectParameters = {}): Promise<TAuthenticationResult> {
216
- this.url = params?.url || this.url;
226
+ this.connectUrl = params?.url || this.connectUrl;
217
227
  this.numberOfRetries = params.numberOfRetries || this.numberOfRetries;
218
228
  this.caCerts = params?.caCerts;
219
229
  this.cert = params?.cert;