@seriousme/opifex 1.11.2 → 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.
- package/LICENSE.txt +1 -1
- package/README.md +102 -43
- package/bin/conformanceServer.ts +45 -13
- package/bin/demoServer.ts +38 -13
- package/bin/mqtt.ts +52 -30
- package/client/ConnectionState.ts +2 -0
- package/client/client.ts +57 -47
- package/client/context.ts +75 -21
- package/client/deps.ts +5 -0
- package/client/handlers/handleAuth.test.ts +193 -0
- package/client/handlers/handleAuth.ts +89 -0
- package/client/handlers/handleConnack.test.ts +173 -0
- package/client/handlers/handleConnack.ts +16 -6
- package/client/handlers/handleDisconnect.test.ts +22 -0
- package/client/handlers/handleDisconnect.ts +17 -0
- package/client/handlers/handlePacket.test.ts +242 -0
- package/client/handlers/handlePacket.ts +19 -5
- package/client/handlers/handlePuback.test.ts +99 -0
- package/client/handlers/handlePuback.ts +6 -0
- package/client/handlers/handlePubcomp.test.ts +112 -0
- package/client/handlers/handlePubcomp.ts +5 -0
- package/client/handlers/handlePublish.test.ts +188 -0
- package/client/handlers/handlePubrec.test.ts +119 -0
- package/client/handlers/handlePubrec.ts +5 -1
- package/client/handlers/handlePubrel.test.ts +136 -0
- package/client/handlers/handleSuback.test.ts +122 -0
- package/client/handlers/handleSuback.ts +3 -0
- package/client/handlers/handleUnsuback.test.ts +101 -0
- package/client/mod.ts +2 -2
- package/client/store/memoryStore.ts +2 -2
- package/client/store/store.ts +3 -1
- package/deno/README.md +1 -2
- package/deno/tcpClient.test.ts +75 -0
- package/deno/tcpClient.ts +16 -11
- package/deno/tcpServer.test.ts +22 -21
- package/deno/tcpServer.ts +5 -0
- package/deno/tlsServer.test.ts +97 -0
- package/deno/tlsServer.ts +42 -0
- package/deno/wsServer.test.ts +93 -0
- package/deno/wsServer.ts +73 -0
- package/dev_utils/generateCert.ts +95 -0
- package/dev_utils/mockConn.ts +36 -0
- package/dev_utils/mockServer.ts +28 -0
- package/dev_utils/mod.ts +30 -2
- package/dev_utils/packetHelpers.ts +404 -0
- package/dev_utils/test-handlers.ts +98 -0
- package/dev_utils/timers.ts +14 -0
- package/dev_utils/webStreamPair.test.ts +171 -0
- package/dev_utils/webStreamPair.ts +143 -0
- package/dist/bin/conformanceServer.js +17 -12
- package/dist/bin/conformanceServer.js.map +1 -1
- package/dist/bin/demoServer.js +16 -12
- package/dist/bin/demoServer.js.map +1 -1
- package/dist/bin/mqtt.js +19 -16
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/ConnectionState.d.ts +2 -0
- package/dist/client/ConnectionState.d.ts.map +1 -1
- package/dist/client/ConnectionState.js +2 -0
- package/dist/client/ConnectionState.js.map +1 -1
- package/dist/client/client.d.ts +19 -22
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +34 -20
- package/dist/client/client.js.map +1 -1
- package/dist/client/context.d.ts +11 -3
- package/dist/client/context.d.ts.map +1 -1
- package/dist/client/context.js +44 -12
- package/dist/client/context.js.map +1 -1
- package/dist/client/deps.d.ts +3 -2
- package/dist/client/deps.d.ts.map +1 -1
- package/dist/client/deps.js +1 -1
- package/dist/client/deps.js.map +1 -1
- package/dist/client/handlers/handleAuth.d.ts +9 -0
- package/dist/client/handlers/handleAuth.d.ts.map +1 -0
- package/dist/client/handlers/handleAuth.js +66 -0
- package/dist/client/handlers/handleAuth.js.map +1 -0
- package/dist/client/handlers/handleConnack.d.ts +2 -2
- package/dist/client/handlers/handleConnack.d.ts.map +1 -1
- package/dist/client/handlers/handleConnack.js +16 -6
- package/dist/client/handlers/handleConnack.js.map +1 -1
- package/dist/client/handlers/handleDisconnect.d.ts +11 -0
- package/dist/client/handlers/handleDisconnect.d.ts.map +1 -0
- package/dist/client/handlers/handleDisconnect.js +15 -0
- package/dist/client/handlers/handleDisconnect.js.map +1 -0
- package/dist/client/handlers/handlePacket.d.ts.map +1 -1
- package/dist/client/handlers/handlePacket.js +14 -3
- package/dist/client/handlers/handlePacket.js.map +1 -1
- package/dist/client/handlers/handlePuback.d.ts.map +1 -1
- package/dist/client/handlers/handlePuback.js +5 -0
- package/dist/client/handlers/handlePuback.js.map +1 -1
- package/dist/client/handlers/handlePubcomp.d.ts.map +1 -1
- package/dist/client/handlers/handlePubcomp.js +5 -0
- package/dist/client/handlers/handlePubcomp.js.map +1 -1
- package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/client/handlers/handlePubrec.js +5 -1
- package/dist/client/handlers/handlePubrec.js.map +1 -1
- package/dist/client/handlers/handleSuback.d.ts +1 -0
- package/dist/client/handlers/handleSuback.d.ts.map +1 -1
- package/dist/client/handlers/handleSuback.js +3 -0
- package/dist/client/handlers/handleSuback.js.map +1 -1
- package/dist/client/mod.d.ts +2 -2
- package/dist/client/mod.d.ts.map +1 -1
- package/dist/client/mod.js +1 -1
- package/dist/client/mod.js.map +1 -1
- package/dist/client/store/memoryStore.d.ts.map +1 -1
- package/dist/client/store/memoryStore.js +2 -2
- package/dist/client/store/memoryStore.js.map +1 -1
- package/dist/client/store/store.d.ts +2 -1
- package/dist/client/store/store.d.ts.map +1 -1
- package/dist/client/store/store.js +1 -1
- package/dist/client/store/store.js.map +1 -1
- package/dist/dev_utils/generateCert.d.ts +11 -0
- package/dist/dev_utils/generateCert.d.ts.map +1 -0
- package/dist/dev_utils/generateCert.js +76 -0
- package/dist/dev_utils/generateCert.js.map +1 -0
- package/dist/examples/authHandler.test.d.ts +2 -0
- package/dist/examples/authHandler.test.d.ts.map +1 -0
- package/dist/examples/authHandler.test.js +123 -0
- package/dist/examples/authHandler.test.js.map +1 -0
- package/dist/examples/mqtt.test.d.ts +2 -0
- package/dist/examples/mqtt.test.d.ts.map +1 -0
- package/dist/examples/mqtt.test.js +70 -0
- package/dist/examples/mqtt.test.js.map +1 -0
- package/dist/examples/mqtts.test.d.ts +2 -0
- package/dist/examples/mqtts.test.d.ts.map +1 -0
- package/dist/examples/mqtts.test.js +81 -0
- package/dist/examples/mqtts.test.js.map +1 -0
- package/dist/mqttConn/mqttConn.d.ts +25 -16
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +69 -40
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts +12 -11
- package/dist/mqttPacket/BitMask.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.js +10 -18
- package/dist/mqttPacket/BitMask.js.map +1 -1
- package/dist/mqttPacket/PacketType.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.d.ts +2 -2
- package/dist/mqttPacket/Properties.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.js.map +1 -1
- package/dist/mqttPacket/ReasonCode.d.ts +1 -0
- package/dist/mqttPacket/ReasonCode.d.ts.map +1 -1
- package/dist/mqttPacket/ReasonCode.js +1 -0
- package/dist/mqttPacket/ReasonCode.js.map +1 -1
- package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
- package/dist/mqttPacket/auth.d.ts +3 -5
- package/dist/mqttPacket/auth.d.ts.map +1 -1
- package/dist/mqttPacket/auth.js +31 -30
- package/dist/mqttPacket/auth.js.map +1 -1
- package/dist/mqttPacket/codec.d.ts +48 -0
- package/dist/mqttPacket/codec.d.ts.map +1 -0
- package/dist/mqttPacket/codec.js +93 -0
- package/dist/mqttPacket/codec.js.map +1 -0
- package/dist/mqttPacket/connack.d.ts +4 -5
- package/dist/mqttPacket/connack.d.ts.map +1 -1
- package/dist/mqttPacket/connack.js +43 -45
- package/dist/mqttPacket/connack.js.map +1 -1
- package/dist/mqttPacket/connect.d.ts +26 -27
- package/dist/mqttPacket/connect.d.ts.map +1 -1
- package/dist/mqttPacket/connect.js +156 -157
- package/dist/mqttPacket/connect.js.map +1 -1
- package/dist/mqttPacket/decoder.d.ts +1 -13
- package/dist/mqttPacket/decoder.d.ts.map +1 -1
- package/dist/mqttPacket/decoder.js +7 -28
- package/dist/mqttPacket/decoder.js.map +1 -1
- package/dist/mqttPacket/disconnect.d.ts +4 -5
- package/dist/mqttPacket/disconnect.d.ts.map +1 -1
- package/dist/mqttPacket/disconnect.js +41 -43
- package/dist/mqttPacket/disconnect.js.map +1 -1
- package/dist/mqttPacket/encoder.d.ts +1 -15
- package/dist/mqttPacket/encoder.d.ts.map +1 -1
- package/dist/mqttPacket/encoder.js +4 -27
- package/dist/mqttPacket/encoder.js.map +1 -1
- package/dist/mqttPacket/length.js +1 -1
- package/dist/mqttPacket/length.js.map +1 -1
- package/dist/mqttPacket/mod.d.ts +21 -103
- package/dist/mqttPacket/mod.d.ts.map +1 -1
- package/dist/mqttPacket/mod.js +5 -94
- package/dist/mqttPacket/mod.js.map +1 -1
- package/dist/mqttPacket/pingreq.d.ts +4 -5
- package/dist/mqttPacket/pingreq.d.ts.map +1 -1
- package/dist/mqttPacket/pingreq.js +11 -13
- package/dist/mqttPacket/pingreq.js.map +1 -1
- package/dist/mqttPacket/pingres.d.ts +4 -5
- package/dist/mqttPacket/pingres.d.ts.map +1 -1
- package/dist/mqttPacket/pingres.js +11 -13
- package/dist/mqttPacket/pingres.js.map +1 -1
- package/dist/mqttPacket/protocolLevels.d.ts +11 -6
- package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
- package/dist/mqttPacket/protocolLevels.js +5 -1
- package/dist/mqttPacket/protocolLevels.js.map +1 -1
- package/dist/mqttPacket/pubblishAcks.d.ts +9 -10
- package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
- package/dist/mqttPacket/pubblishAcks.js +43 -45
- package/dist/mqttPacket/pubblishAcks.js.map +1 -1
- package/dist/mqttPacket/publish.d.ts +14 -14
- package/dist/mqttPacket/publish.d.ts.map +1 -1
- package/dist/mqttPacket/publish.js +53 -55
- package/dist/mqttPacket/publish.js.map +1 -1
- package/dist/mqttPacket/suback.d.ts +4 -5
- package/dist/mqttPacket/suback.d.ts.map +1 -1
- package/dist/mqttPacket/suback.js +38 -40
- package/dist/mqttPacket/suback.js.map +1 -1
- package/dist/mqttPacket/subscribe.d.ts +36 -7
- package/dist/mqttPacket/subscribe.d.ts.map +1 -1
- package/dist/mqttPacket/subscribe.js +90 -89
- package/dist/mqttPacket/subscribe.js.map +1 -1
- package/dist/mqttPacket/types.d.ts +1 -8
- package/dist/mqttPacket/types.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.d.ts +4 -5
- package/dist/mqttPacket/unsuback.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.js +32 -34
- package/dist/mqttPacket/unsuback.js.map +1 -1
- package/dist/mqttPacket/unsubscribe.d.ts +23 -6
- package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
- package/dist/mqttPacket/unsubscribe.js +45 -44
- package/dist/mqttPacket/unsubscribe.js.map +1 -1
- package/dist/mqttPacket/validators.d.ts +4 -16
- package/dist/mqttPacket/validators.d.ts.map +1 -1
- package/dist/mqttPacket/validators.js +5 -26
- package/dist/mqttPacket/validators.js.map +1 -1
- package/dist/node/tcpClient.d.ts +1 -1
- package/dist/node/tcpClient.d.ts.map +1 -1
- package/dist/node/tcpClient.js +12 -7
- package/dist/node/tcpClient.js.map +1 -1
- package/dist/node/tcpServer.d.ts.map +1 -1
- package/dist/node/tcpServer.js +4 -0
- package/dist/node/tcpServer.js.map +1 -1
- package/dist/node/tlsServer.d.ts +19 -0
- package/dist/node/tlsServer.d.ts.map +1 -0
- package/dist/node/tlsServer.js +58 -0
- package/dist/node/tlsServer.js.map +1 -0
- package/dist/node/wrapNodeSocket.d.ts.map +1 -1
- package/dist/node/wrapNodeSocket.js +6 -28
- package/dist/node/wrapNodeSocket.js.map +1 -1
- package/dist/persistence/basicPersistence.d.ts +36 -0
- package/dist/persistence/basicPersistence.d.ts.map +1 -0
- package/dist/persistence/basicPersistence.js +306 -0
- package/dist/persistence/basicPersistence.js.map +1 -0
- package/dist/persistence/deps.d.ts +3 -2
- package/dist/persistence/deps.d.ts.map +1 -1
- package/dist/persistence/deps.js +2 -1
- package/dist/persistence/deps.js.map +1 -1
- package/dist/persistence/memory/memoryPersistence.d.ts +6 -23
- package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
- package/dist/persistence/memory/memoryPersistence.js +12 -115
- package/dist/persistence/memory/memoryPersistence.js.map +1 -1
- package/dist/persistence/memory/memoryStorage.d.ts +45 -0
- package/dist/persistence/memory/memoryStorage.d.ts.map +1 -0
- package/dist/persistence/memory/memoryStorage.js +143 -0
- package/dist/persistence/memory/memoryStorage.js.map +1 -0
- package/dist/persistence/mod.d.ts +3 -3
- package/dist/persistence/mod.d.ts.map +1 -1
- package/dist/persistence/mod.js +6 -1
- package/dist/persistence/mod.js.map +1 -1
- package/dist/persistence/persistence.d.ts +44 -69
- package/dist/persistence/persistence.d.ts.map +1 -1
- package/dist/persistence/persistence.js +1 -2
- package/dist/persistence/persistence.js.map +1 -1
- package/dist/persistence/sqlite/sqliteDatabase.d.ts +46 -0
- package/dist/persistence/sqlite/sqliteDatabase.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqliteDatabase.js +215 -0
- package/dist/persistence/sqlite/sqliteDatabase.js.map +1 -0
- package/dist/persistence/sqlite/sqlitePersistence.d.ts +16 -0
- package/dist/persistence/sqlite/sqlitePersistence.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqlitePersistence.js +29 -0
- package/dist/persistence/sqlite/sqlitePersistence.js.map +1 -0
- package/dist/persistence/sqlite/sqliteStorage.d.ts +36 -0
- package/dist/persistence/sqlite/sqliteStorage.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqliteStorage.js +194 -0
- package/dist/persistence/sqlite/sqliteStorage.js.map +1 -0
- package/dist/persistence/storage.d.ts +38 -0
- package/dist/persistence/storage.d.ts.map +1 -0
- package/dist/persistence/storage.js +5 -0
- package/dist/persistence/storage.js.map +1 -0
- package/dist/server/config.d.ts +47 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +41 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/context.d.ts +198 -24
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +432 -53
- package/dist/server/context.js.map +1 -1
- package/dist/server/deps.d.ts +5 -6
- package/dist/server/deps.d.ts.map +1 -1
- package/dist/server/deps.js +2 -2
- package/dist/server/deps.js.map +1 -1
- package/dist/server/handlers/completeConnect.d.ts +8 -0
- package/dist/server/handlers/completeConnect.d.ts.map +1 -0
- package/dist/server/handlers/completeConnect.js +74 -0
- package/dist/server/handlers/completeConnect.js.map +1 -0
- package/dist/server/handlers/handleAuth.d.ts +9 -0
- package/dist/server/handlers/handleAuth.d.ts.map +1 -0
- package/dist/server/handlers/handleAuth.js +69 -0
- package/dist/server/handlers/handleAuth.js.map +1 -0
- package/dist/server/handlers/handleConnect.d.ts +2 -4
- package/dist/server/handlers/handleConnect.d.ts.map +1 -1
- package/dist/server/handlers/handleConnect.js +140 -67
- package/dist/server/handlers/handleConnect.js.map +1 -1
- package/dist/server/handlers/handleDisconnect.d.ts +1 -1
- package/dist/server/handlers/handleDisconnect.d.ts.map +1 -1
- package/dist/server/handlers/handleDisconnect.js +3 -3
- package/dist/server/handlers/handleDisconnect.js.map +1 -1
- package/dist/server/handlers/handlePacket.d.ts.map +1 -1
- package/dist/server/handlers/handlePacket.js +19 -6
- package/dist/server/handlers/handlePacket.js.map +1 -1
- package/dist/server/handlers/handlePuback.d.ts +1 -3
- package/dist/server/handlers/handlePuback.d.ts.map +1 -1
- package/dist/server/handlers/handlePuback.js +2 -8
- package/dist/server/handlers/handlePuback.js.map +1 -1
- package/dist/server/handlers/handlePubcomp.d.ts +1 -1
- package/dist/server/handlers/handlePubcomp.d.ts.map +1 -1
- package/dist/server/handlers/handlePubcomp.js +2 -4
- package/dist/server/handlers/handlePubcomp.js.map +1 -1
- package/dist/server/handlers/handlePublish.d.ts +1 -1
- package/dist/server/handlers/handlePublish.d.ts.map +1 -1
- package/dist/server/handlers/handlePublish.js +149 -45
- package/dist/server/handlers/handlePublish.js.map +1 -1
- package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrec.js +2 -3
- package/dist/server/handlers/handlePubrec.js.map +1 -1
- package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrel.js +6 -2
- package/dist/server/handlers/handlePubrel.js.map +1 -1
- package/dist/server/handlers/handleSubscribe.d.ts +1 -6
- package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleSubscribe.js +99 -38
- package/dist/server/handlers/handleSubscribe.js.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.js +19 -4
- package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
- package/dist/server/mod.d.ts +3 -3
- package/dist/server/mod.d.ts.map +1 -1
- package/dist/server/mod.js +1 -1
- package/dist/server/mod.js.map +1 -1
- package/dist/server/server.d.ts +29 -6
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +84 -15
- package/dist/server/server.js.map +1 -1
- package/dist/socket/socket.d.ts +11 -9
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +67 -15
- package/dist/socket/socket.js.map +1 -1
- package/dist/timer/timer.d.ts +32 -0
- package/dist/timer/timer.d.ts.map +1 -1
- package/dist/timer/timer.js +32 -0
- package/dist/timer/timer.js.map +1 -1
- package/dist/trie/trie.d.ts +10 -5
- package/dist/trie/trie.d.ts.map +1 -1
- package/dist/trie/trie.js +47 -17
- package/dist/trie/trie.js.map +1 -1
- package/dist/utils/assert.d.ts.map +1 -1
- package/dist/utils/{BufferedAsyncIterable.d.ts → bufferedAsyncIterable.d.ts} +1 -1
- package/dist/utils/bufferedAsyncIterable.d.ts.map +1 -0
- package/dist/utils/{BufferedAsyncIterable.js → bufferedAsyncIterable.js} +1 -1
- package/dist/utils/bufferedAsyncIterable.js.map +1 -0
- package/dist/utils/deferred.d.ts.map +1 -1
- package/dist/utils/deferred.js.map +1 -1
- package/dist/utils/getOrInsertPolyFill.d.ts +2 -0
- package/dist/utils/getOrInsertPolyFill.d.ts.map +1 -0
- package/dist/utils/getOrInsertPolyFill.js +12 -0
- package/dist/utils/getOrInsertPolyFill.js.map +1 -0
- package/dist/utils/logger.d.ts +40 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +53 -7
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/mod.d.ts +6 -1
- package/dist/utils/mod.d.ts.map +1 -1
- package/dist/utils/mod.js +5 -1
- package/dist/utils/mod.js.map +1 -1
- package/dist/utils/outboundTopicAliasManager.d.ts +52 -0
- package/dist/utils/outboundTopicAliasManager.d.ts.map +1 -0
- package/dist/utils/outboundTopicAliasManager.js +74 -0
- package/dist/utils/outboundTopicAliasManager.js.map +1 -0
- package/dist/utils/queue.d.ts.map +1 -1
- package/dist/utils/topicFilter.d.ts +32 -0
- package/dist/utils/topicFilter.d.ts.map +1 -0
- package/dist/utils/topicFilter.js +52 -0
- package/dist/utils/topicFilter.js.map +1 -0
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +2 -0
- package/dist/utils/utils.js.map +1 -1
- package/dist/utils/validators.d.ts +34 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +61 -0
- package/dist/utils/validators.js.map +1 -0
- package/dist/web/webSocketStream.d.ts +29 -0
- package/dist/web/webSocketStream.d.ts.map +1 -0
- package/dist/web/webSocketStream.js +69 -0
- package/dist/web/webSocketStream.js.map +1 -0
- package/dist/web/wrapWebSocket.d.ts +12 -0
- package/dist/web/wrapWebSocket.d.ts.map +1 -0
- package/dist/web/wrapWebSocket.js +41 -0
- package/dist/web/wrapWebSocket.js.map +1 -0
- package/dist/web/wsClient.d.ts +7 -0
- package/dist/web/wsClient.d.ts.map +1 -0
- package/dist/web/wsClient.js +22 -0
- package/dist/web/wsClient.js.map +1 -0
- package/dist/web/wsClient.test.d.ts +2 -0
- package/dist/web/wsClient.test.d.ts.map +1 -0
- package/dist/web/wsClient.test.js +20 -0
- package/dist/web/wsClient.test.js.map +1 -0
- package/examples/authHandler.test.ts +164 -0
- package/examples/mqtt.test.ts +89 -0
- package/examples/mqtts.test.ts +100 -0
- package/examples/webSocket.test.ts +94 -0
- package/mqttConn/mqttConn.test.ts +9 -9
- package/mqttConn/mqttConn.ts +91 -49
- package/mqttPacket/BitMask.ts +11 -19
- package/mqttPacket/Properties.ts +6 -3
- package/mqttPacket/ReasonCode.ts +2 -1
- package/mqttPacket/auth.test.ts +1 -1
- package/mqttPacket/auth.ts +41 -48
- package/mqttPacket/codec.ts +146 -0
- package/mqttPacket/connack.ts +57 -68
- package/mqttPacket/connect.test.ts +2 -2
- package/mqttPacket/connect.ts +197 -204
- package/mqttPacket/decoder.test.ts +0 -39
- package/mqttPacket/decoder.ts +9 -36
- package/mqttPacket/disconnect.ts +57 -68
- package/mqttPacket/encoder.ts +5 -40
- package/mqttPacket/length.ts +1 -1
- package/mqttPacket/mod.ts +48 -200
- package/mqttPacket/pingreq.ts +21 -27
- package/mqttPacket/pingres.ts +21 -27
- package/mqttPacket/protocolLevels.ts +12 -7
- package/mqttPacket/pubblishAcks.ts +68 -77
- package/mqttPacket/publish.ts +76 -83
- package/mqttPacket/suback.ts +48 -58
- package/mqttPacket/subscribe.ts +141 -117
- package/mqttPacket/types.ts +1 -9
- package/mqttPacket/unsuback.ts +46 -58
- package/mqttPacket/unsubscribe.ts +74 -63
- package/mqttPacket/validators.ts +5 -31
- package/node/socket-node-stream.test.ts +322 -0
- package/node/socket-node-stream.ts +174 -0
- package/node/tcpClient.test.ts +70 -0
- package/node/tcpClient.ts +13 -12
- package/node/tcpServer.test.ts +24 -20
- package/node/tcpServer.ts +6 -0
- package/node/tlsServer.test.ts +94 -0
- package/node/tlsServer.ts +81 -0
- package/node/wrapNodeSocket.ts +7 -30
- package/package.json +73 -45
- package/persistence/basicPersistence.ts +495 -0
- package/persistence/deps.ts +11 -1
- package/persistence/memory/memoryPersistence.ts +12 -152
- package/persistence/memory/memoryStorage.ts +232 -0
- package/persistence/mod.ts +4 -4
- package/persistence/persistence.test.ts +24 -0
- package/persistence/persistence.testing.ts +1324 -0
- package/persistence/persistence.ts +111 -67
- package/persistence/sqlite/sqliteDatabase.ts +294 -0
- package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
- package/persistence/sqlite/sqlitePersistence.ts +36 -0
- package/persistence/sqlite/sqliteStorage.ts +324 -0
- package/persistence/storage.ts +84 -0
- package/server/config.ts +65 -0
- package/server/context.ts +658 -74
- package/server/deps.ts +25 -5
- package/server/handlers/completeConnect.ts +93 -0
- package/server/handlers/duplicate.test.ts +196 -0
- package/server/handlers/handleAuth.test.ts +225 -0
- package/server/handlers/handleAuth.ts +88 -0
- package/server/handlers/handleConnect.test.ts +589 -0
- package/server/handlers/handleConnect.ts +201 -86
- package/server/handlers/handleConnect.version.test.ts +108 -0
- package/server/handlers/handleDisconnect.test.ts +56 -0
- package/server/handlers/handleDisconnect.ts +3 -3
- package/server/handlers/handlePacket.test.ts +24 -0
- package/server/handlers/handlePacket.ts +30 -8
- package/server/handlers/handlePingreq.test.ts +29 -0
- package/server/handlers/handlePuback.test.ts +28 -0
- package/server/handlers/handlePuback.ts +5 -8
- package/server/handlers/handlePubcomp.test.ts +28 -0
- package/server/handlers/handlePubcomp.ts +5 -4
- package/server/handlers/handlePublish.test.ts +471 -0
- package/server/handlers/handlePublish.ts +189 -35
- package/server/handlers/handlePubrec.test.ts +28 -0
- package/server/handlers/handlePubrec.ts +2 -3
- package/server/handlers/handlePubrel.test.ts +74 -0
- package/server/handlers/handlePubrel.ts +12 -2
- package/server/handlers/handleSubscribe.test.ts +971 -0
- package/server/handlers/handleSubscribe.ts +158 -39
- package/server/handlers/handleUnsubscribe.test.ts +79 -0
- package/server/handlers/handleUnsubscribe.ts +29 -5
- package/server/handlers/keepalive.test.ts +132 -0
- package/server/handlers/session.persistence.test.ts +194 -0
- package/server/handlers/will.delivery.test.ts +221 -0
- package/server/mod.ts +4 -3
- package/server/preconnect.test.ts +151 -0
- package/server/server.ts +115 -17
- package/socket/socket.test.ts +91 -0
- package/socket/socket.ts +81 -31
- package/timer/timer.test.ts +4 -7
- package/timer/timer.ts +36 -0
- package/tools/benchmarks/receiver.ts +51 -0
- package/tools/benchmarks/sender.ts +48 -0
- package/tools/benchmarks/utils.ts +31 -0
- package/tools/mqtt-compat/README.md +130 -0
- package/tools/mqtt-compat/broker.ts +52 -0
- package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
- package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
- package/trie/trie.test.ts +9 -1
- package/trie/trie.ts +57 -22
- package/utils/bufferedAsyncIterable.test.ts +92 -0
- package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +1 -1
- package/utils/deferred.test.ts +36 -0
- package/utils/deferred.ts +0 -1
- package/utils/getOrInsertPolyFill.ts +12 -0
- package/utils/logger.test.ts +189 -0
- package/utils/logger.ts +62 -7
- package/utils/mod.ts +15 -1
- package/utils/outboundTopicAliasManager.ts +100 -0
- package/utils/queue.test.ts +61 -0
- package/utils/topicFilter.test.ts +63 -0
- package/utils/topicFilter.ts +61 -0
- package/utils/utils.ts +3 -0
- package/utils/validators.ts +67 -0
- package/web/webSocketStream.ts +97 -0
- package/web/wrapWebSocket.ts +52 -0
- package/web/wsClient.test.ts +26 -0
- package/web/wsClient.ts +25 -0
- package/benchmarks/receiver.ts +0 -35
- package/benchmarks/sender.ts +0 -32
- package/benchmarks/utils.ts +0 -9
- package/dev_utils/dummyConn.ts +0 -110
- package/dist/persistence/store.d.ts +0 -13
- package/dist/persistence/store.d.ts.map +0 -1
- package/dist/persistence/store.js +0 -2
- package/dist/persistence/store.js.map +0 -1
- package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
- package/dist/utils/BufferedAsyncIterable.js.map +0 -1
- package/examples/tcpServer.test.ts +0 -148
- package/persistence/memory/memoryPersistence.test.ts +0 -156
- package/persistence/store.ts +0 -15
- package/server/test/handleConnect.test.ts +0 -130
- package/server/test/test-handlers.ts +0 -53
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { PacketType } from "../deps.ts";
|
|
4
|
+
import {
|
|
5
|
+
addMockClient,
|
|
6
|
+
connect,
|
|
7
|
+
disconnect,
|
|
8
|
+
ping,
|
|
9
|
+
startMockServer,
|
|
10
|
+
subscribe,
|
|
11
|
+
} from "../../dev_utils/mod.ts";
|
|
12
|
+
|
|
13
|
+
const txtEncoder = new TextEncoder();
|
|
14
|
+
|
|
15
|
+
test("MQTT-3.1.2.5: will message delivered on ungraceful disconnect", async () => {
|
|
16
|
+
const willTopic = "will/topic";
|
|
17
|
+
const payload = txtEncoder.encode("goodbye");
|
|
18
|
+
const { mqttConn: subscriber, mqttServer } = startMockServer();
|
|
19
|
+
|
|
20
|
+
// Subscriber connects
|
|
21
|
+
await connect(subscriber, { clientId: "subscriber1" });
|
|
22
|
+
await subscribe(subscriber, [{ topicFilter: willTopic, qos: 0 }]);
|
|
23
|
+
|
|
24
|
+
const publisher = addMockClient(mqttServer);
|
|
25
|
+
// Publisher connects
|
|
26
|
+
await connect(publisher, {
|
|
27
|
+
clientId: "publisher1",
|
|
28
|
+
will: {
|
|
29
|
+
topic: willTopic,
|
|
30
|
+
payload,
|
|
31
|
+
qos: 0,
|
|
32
|
+
retain: false,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Force close the publisher connection without sending DISCONNECT
|
|
37
|
+
// This simulates an ungraceful disconnect
|
|
38
|
+
publisher.close();
|
|
39
|
+
assert.deepStrictEqual(publisher.isClosed, true, "publisher is closed");
|
|
40
|
+
|
|
41
|
+
// Subscriber should receive the will message
|
|
42
|
+
const { value: willMessage } = await subscriber.next();
|
|
43
|
+
|
|
44
|
+
assert.deepStrictEqual(
|
|
45
|
+
willMessage.type,
|
|
46
|
+
PacketType.publish,
|
|
47
|
+
"Expecting a Publish packet",
|
|
48
|
+
);
|
|
49
|
+
assert.deepStrictEqual(
|
|
50
|
+
willMessage.topic,
|
|
51
|
+
willTopic,
|
|
52
|
+
"Expecting correct topic",
|
|
53
|
+
);
|
|
54
|
+
assert.deepStrictEqual(
|
|
55
|
+
willMessage.payload,
|
|
56
|
+
payload,
|
|
57
|
+
"Expecting correct payload",
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
// Clean up
|
|
61
|
+
await disconnect(subscriber);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("MQTT-3.1.2.5: will message NOT delivered on graceful DISCONNECT", async () => {
|
|
65
|
+
const willTopic = "will/topic2";
|
|
66
|
+
const payload = txtEncoder.encode("goodbye");
|
|
67
|
+
const { mqttConn: subscriber, mqttServer } = startMockServer();
|
|
68
|
+
|
|
69
|
+
// Subscriber connects
|
|
70
|
+
await connect(subscriber, { clientId: "subscriber2" });
|
|
71
|
+
await subscribe(subscriber, [{ topicFilter: willTopic, qos: 0 }]);
|
|
72
|
+
|
|
73
|
+
const publisher = addMockClient(mqttServer);
|
|
74
|
+
// Publisher connects
|
|
75
|
+
await connect(publisher, {
|
|
76
|
+
clientId: "publisher2",
|
|
77
|
+
will: {
|
|
78
|
+
topic: willTopic,
|
|
79
|
+
payload,
|
|
80
|
+
qos: 0,
|
|
81
|
+
retain: false,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
// Publisher gracefully disconnects
|
|
85
|
+
await disconnect(publisher);
|
|
86
|
+
|
|
87
|
+
// Send PINGREQ to verify no will message was queued before it
|
|
88
|
+
await ping(subscriber);
|
|
89
|
+
|
|
90
|
+
// Clean up
|
|
91
|
+
await disconnect(subscriber);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("MQTT-3.1.2.5: will message delivered with correct QoS", async () => {
|
|
95
|
+
const willTopic = "will/qos";
|
|
96
|
+
const payload = txtEncoder.encode("goodbye");
|
|
97
|
+
const { mqttConn: subscriber, mqttServer } = startMockServer();
|
|
98
|
+
|
|
99
|
+
// Subscriber connects
|
|
100
|
+
await connect(subscriber, { clientId: "subscriber3" });
|
|
101
|
+
await subscribe(subscriber, [{ topicFilter: willTopic, qos: 1 }]);
|
|
102
|
+
|
|
103
|
+
// Publisher connects with will message QoS 1
|
|
104
|
+
const publisher = addMockClient(mqttServer);
|
|
105
|
+
await connect(publisher, {
|
|
106
|
+
clientId: "publisher3",
|
|
107
|
+
will: {
|
|
108
|
+
topic: willTopic,
|
|
109
|
+
payload,
|
|
110
|
+
qos: 1,
|
|
111
|
+
retain: false,
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Force close the publisher connection
|
|
116
|
+
publisher.close();
|
|
117
|
+
|
|
118
|
+
// Subscriber should receive the will message with QoS 1
|
|
119
|
+
const { value: willMessage } = await subscriber.next();
|
|
120
|
+
assert.deepStrictEqual(willMessage.type, PacketType.publish);
|
|
121
|
+
|
|
122
|
+
assert.deepStrictEqual(
|
|
123
|
+
willMessage.type,
|
|
124
|
+
PacketType.publish,
|
|
125
|
+
"Expecting a Publish packet",
|
|
126
|
+
);
|
|
127
|
+
assert.deepStrictEqual(
|
|
128
|
+
willMessage.topic,
|
|
129
|
+
willTopic,
|
|
130
|
+
"Expecting correct topic",
|
|
131
|
+
);
|
|
132
|
+
assert.deepStrictEqual(
|
|
133
|
+
willMessage.qos,
|
|
134
|
+
1,
|
|
135
|
+
"Expecting correct QoS",
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// Clean up
|
|
139
|
+
await disconnect(subscriber);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("MQTT-3.1.2.5: will message stored as retained when retain=true", async () => {
|
|
143
|
+
const willTopic = "will/retained";
|
|
144
|
+
const payload = txtEncoder.encode("Retained message");
|
|
145
|
+
|
|
146
|
+
const { mqttConn: subscriber, mqttServer } = startMockServer();
|
|
147
|
+
|
|
148
|
+
// Subscriber connects
|
|
149
|
+
await connect(subscriber, { clientId: "subscriber4" });
|
|
150
|
+
|
|
151
|
+
// Publisher connects with will retain true
|
|
152
|
+
const publisher = addMockClient(mqttServer);
|
|
153
|
+
await connect(publisher, {
|
|
154
|
+
clientId: "publisher4",
|
|
155
|
+
will: {
|
|
156
|
+
topic: willTopic,
|
|
157
|
+
payload,
|
|
158
|
+
qos: 0,
|
|
159
|
+
retain: true,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Force close the publisher connection
|
|
164
|
+
publisher.close();
|
|
165
|
+
|
|
166
|
+
// Now subscribe to the topic - should receive the retained message
|
|
167
|
+
await subscribe(subscriber, [{ topicFilter: willTopic, qos: 0 }]);
|
|
168
|
+
|
|
169
|
+
// Should receive the retained will message
|
|
170
|
+
const { value: willMessage } = await subscriber.next();
|
|
171
|
+
assert.deepStrictEqual(
|
|
172
|
+
willMessage.type,
|
|
173
|
+
PacketType.publish,
|
|
174
|
+
"Expecting PUBLISH packet",
|
|
175
|
+
);
|
|
176
|
+
assert.deepStrictEqual(
|
|
177
|
+
willMessage.topic,
|
|
178
|
+
willTopic,
|
|
179
|
+
"Expecting correct topic",
|
|
180
|
+
);
|
|
181
|
+
assert.deepStrictEqual(willMessage.retain, true, "Expecting retain true");
|
|
182
|
+
assert.deepStrictEqual(
|
|
183
|
+
willMessage.payload,
|
|
184
|
+
payload,
|
|
185
|
+
"Expecting correct payload",
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// Clean up
|
|
189
|
+
await disconnect(subscriber);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
test("MQTT-3.1.2.5: will message to $ topic is rejected", async () => {
|
|
193
|
+
const willTopic = "$SYS/will";
|
|
194
|
+
const payload = txtEncoder.encode("System Will");
|
|
195
|
+
const { mqttConn: subscriber, mqttServer } = startMockServer();
|
|
196
|
+
|
|
197
|
+
// Subscriber connects
|
|
198
|
+
await connect(subscriber, { clientId: "subscriber5" });
|
|
199
|
+
await subscribe(subscriber, [{ topicFilter: willTopic, qos: 0 }]);
|
|
200
|
+
|
|
201
|
+
// Publisher connects with will message to system topic
|
|
202
|
+
const publisher = addMockClient(mqttServer);
|
|
203
|
+
await connect(publisher, {
|
|
204
|
+
clientId: "publisher5",
|
|
205
|
+
will: {
|
|
206
|
+
topic: willTopic,
|
|
207
|
+
payload,
|
|
208
|
+
qos: 0,
|
|
209
|
+
retain: false,
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Force close the publisher connection
|
|
214
|
+
publisher.close();
|
|
215
|
+
|
|
216
|
+
// Send PINGREQ to verify no will message was queued
|
|
217
|
+
await ping(subscriber);
|
|
218
|
+
|
|
219
|
+
// Clean up
|
|
220
|
+
await disconnect(subscriber);
|
|
221
|
+
});
|
package/server/mod.ts
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
* This module provides an MQTT Server interface see the /bin folder for examples
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
export {
|
|
5
|
+
export { ReasonCode } from "./deps.ts";
|
|
6
6
|
export type {
|
|
7
|
+
ConnectPacket,
|
|
7
8
|
IPersistence,
|
|
9
|
+
ShareName,
|
|
8
10
|
SockConn,
|
|
9
|
-
TAuthenticationResult,
|
|
10
11
|
Topic,
|
|
11
12
|
} from "./deps.ts";
|
|
12
13
|
export { MqttServer } from "./server.ts";
|
|
13
14
|
export type { MqttServerOptions } from "./server.ts";
|
|
14
15
|
export { Context } from "./context.ts";
|
|
15
|
-
export type { Handlers } from "./context.ts";
|
|
16
|
+
export type { AuthenticatedResult, Handlers } from "./context.ts";
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import {
|
|
4
|
+
connect,
|
|
5
|
+
delay,
|
|
6
|
+
disconnect,
|
|
7
|
+
startMockServer,
|
|
8
|
+
} from "../dev_utils/mod.ts";
|
|
9
|
+
import type { AnyPacket } from "./deps.ts";
|
|
10
|
+
import { MQTTLevel } from "./deps.ts";
|
|
11
|
+
import { PacketType } from "../mqttPacket/mod.ts";
|
|
12
|
+
|
|
13
|
+
test(
|
|
14
|
+
"Preconnect timer: connection closes if CONNECT not received within timeout",
|
|
15
|
+
{ concurrency: false },
|
|
16
|
+
async () => {
|
|
17
|
+
const { mqttConn } = startMockServer({
|
|
18
|
+
configuration: { context: { preconnectTimeoutMs: 500 } },
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Wait 750 ms without sending CONNECT packet
|
|
22
|
+
await delay(750);
|
|
23
|
+
|
|
24
|
+
// Try to get next packet (should timeout/close)
|
|
25
|
+
await mqttConn.next();
|
|
26
|
+
|
|
27
|
+
// Connection should be closed
|
|
28
|
+
assert.deepStrictEqual(
|
|
29
|
+
mqttConn.isClosed,
|
|
30
|
+
true,
|
|
31
|
+
"Connection should be closed after preconnect timeout",
|
|
32
|
+
);
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
test(
|
|
37
|
+
"Preconnect timer: connection succeeds if CONNECT received before timeout",
|
|
38
|
+
{ concurrency: false },
|
|
39
|
+
async () => {
|
|
40
|
+
const { mqttConn } = startMockServer({
|
|
41
|
+
configuration: { context: { preconnectTimeoutMs: 500 } },
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Wait 200 ms (before timeout)
|
|
45
|
+
await delay(200);
|
|
46
|
+
|
|
47
|
+
// Send CONNECT packet
|
|
48
|
+
await connect(mqttConn, { clientId: "preconnectTestClient" });
|
|
49
|
+
|
|
50
|
+
// Connection should still be open
|
|
51
|
+
assert.deepStrictEqual(
|
|
52
|
+
mqttConn.isClosed,
|
|
53
|
+
false,
|
|
54
|
+
"Connection should remain open after successful CONNECT",
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// Cleanup
|
|
58
|
+
await disconnect(mqttConn);
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
test(
|
|
63
|
+
"Preconnect timer: connection succeeds with immediate CONNECT",
|
|
64
|
+
{ concurrency: false },
|
|
65
|
+
async () => {
|
|
66
|
+
const { mqttConn } = startMockServer({
|
|
67
|
+
configuration: { context: { preconnectTimeoutMs: 500 } },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Send CONNECT immediately
|
|
71
|
+
await connect(mqttConn, { clientId: "preconnectTestImmediate" });
|
|
72
|
+
await delay(750);
|
|
73
|
+
|
|
74
|
+
// Connection should be open
|
|
75
|
+
assert.deepStrictEqual(
|
|
76
|
+
mqttConn.isClosed,
|
|
77
|
+
false,
|
|
78
|
+
"Connection should remain open after immediate CONNECT",
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Cleanup
|
|
82
|
+
await disconnect(mqttConn);
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
test(
|
|
87
|
+
"Preconnect timer: closes connection at exact time",
|
|
88
|
+
{ concurrency: false },
|
|
89
|
+
async () => {
|
|
90
|
+
const { mqttConn } = startMockServer({
|
|
91
|
+
configuration: { context: { preconnectTimeoutMs: 500 } },
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Wait just under 500 ms - should still be connected
|
|
95
|
+
await delay(400);
|
|
96
|
+
|
|
97
|
+
// Connection should still be open
|
|
98
|
+
assert.deepStrictEqual(
|
|
99
|
+
mqttConn.isClosed,
|
|
100
|
+
false,
|
|
101
|
+
"Connection should be open at 2.9 seconds",
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// Wait additional 200ms to cross the 500 ms boundary
|
|
105
|
+
await delay(200);
|
|
106
|
+
|
|
107
|
+
// Try to interact with connection
|
|
108
|
+
await mqttConn.next();
|
|
109
|
+
|
|
110
|
+
// Connection should now be closed
|
|
111
|
+
assert.deepStrictEqual(
|
|
112
|
+
mqttConn.isClosed,
|
|
113
|
+
true,
|
|
114
|
+
"Connection should be closed now",
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
test("Preconnect handler: handler disconnects session", async () => {
|
|
120
|
+
const txtEncoder = new TextEncoder();
|
|
121
|
+
|
|
122
|
+
const connectPacket: AnyPacket = {
|
|
123
|
+
type: PacketType.connect,
|
|
124
|
+
protocolName: "MQTT",
|
|
125
|
+
protocolLevel: MQTTLevel.v4,
|
|
126
|
+
clientId: "testClient",
|
|
127
|
+
clean: true,
|
|
128
|
+
keepAlive: 0,
|
|
129
|
+
username: "IoTester_1",
|
|
130
|
+
password: txtEncoder.encode("strong_password"),
|
|
131
|
+
will: undefined,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const { mqttConn } = startMockServer({
|
|
135
|
+
handlers: {
|
|
136
|
+
preconnect: () => false,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
await mqttConn.send(connectPacket);
|
|
140
|
+
const { value } = await mqttConn.next();
|
|
141
|
+
assert.deepStrictEqual(
|
|
142
|
+
value,
|
|
143
|
+
undefined,
|
|
144
|
+
"No connack received",
|
|
145
|
+
);
|
|
146
|
+
assert.deepStrictEqual(
|
|
147
|
+
mqttConn.isClosed,
|
|
148
|
+
true,
|
|
149
|
+
"Connection should be closed by the preconnect handler",
|
|
150
|
+
);
|
|
151
|
+
});
|
package/server/server.ts
CHANGED
|
@@ -1,69 +1,167 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logger, MemoryPersistence, ReasonCode } from "./deps.ts";
|
|
2
2
|
import { Context } from "./context.ts";
|
|
3
3
|
import type { Handlers } from "./context.ts";
|
|
4
|
-
import type { IPersistence, SockConn, Topic } from "./deps.ts";
|
|
4
|
+
import type { IPersistence, ShareName, SockConn, Topic } from "./deps.ts";
|
|
5
5
|
import { handlePacket } from "./handlers/handlePacket.ts";
|
|
6
|
+
import { createConfiguration } from "./config.ts";
|
|
7
|
+
import type { Configuration, ConfigurationInput } from "./config.ts";
|
|
6
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Default preconnect handler that unconditionally permits all connections.
|
|
11
|
+
* @param {SockConn} _conn - The connection.
|
|
12
|
+
* @returns {boolean} Always returns true
|
|
13
|
+
*/
|
|
14
|
+
const defaultPreconnect = (
|
|
15
|
+
_conn: SockConn,
|
|
16
|
+
) => (true) as const;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Default authentication handler that unconditionally permits all connections.
|
|
20
|
+
* @param {Context} _ctx - The connection context.
|
|
21
|
+
* @param {string} _clientId - The client identifier.
|
|
22
|
+
* @param {string} _username - The username provided by the client.
|
|
23
|
+
* @param {Uint8Array} _password - The password provided by the client.
|
|
24
|
+
* @returns {IsAuthenticatedResult} Always returns ReasonCode.success.
|
|
25
|
+
*/
|
|
7
26
|
const defaultIsAuthenticated = (
|
|
8
27
|
_ctx: Context,
|
|
9
28
|
_clientId: string,
|
|
10
29
|
_username: string,
|
|
11
30
|
_password: Uint8Array,
|
|
12
|
-
) =>
|
|
31
|
+
) => ({ reasonCode: ReasonCode.success }) as const;
|
|
32
|
+
|
|
33
|
+
const defaultProcessAuth = (
|
|
34
|
+
_ctx: Context,
|
|
35
|
+
_clientId: string,
|
|
36
|
+
_authMethod: string,
|
|
37
|
+
_authData: Uint8Array,
|
|
38
|
+
) =>
|
|
39
|
+
({
|
|
40
|
+
reasonCode: ReasonCode.badAuthenticationMethod,
|
|
41
|
+
reasonString: "Authentication method not supported",
|
|
42
|
+
}) as const;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Default authorization handler that unconditionally permits all publish operations.
|
|
46
|
+
* @param {Context} _ctx - The connection context.
|
|
47
|
+
* @param {Topic} _topic - The topic being accessed.
|
|
48
|
+
* @returns {boolean} Always returns true.
|
|
49
|
+
*/
|
|
50
|
+
const defaultIsAuthorizedToPublish = (_ctx: Context, _topic: Topic) =>
|
|
51
|
+
(true) as const;
|
|
13
52
|
|
|
14
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Default authorization handler that unconditionally permits all subscribe operations.
|
|
55
|
+
* @param {Context} _ctx - The connection context.
|
|
56
|
+
* @param {Topic} _topic - The topic being accessed.
|
|
57
|
+
* @param {ShareName} _shareName - The share name being accessed when using shared subscriptions
|
|
58
|
+
* @returns {boolean} Always returns true.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
const defaultIsAuthorizedToSubscribe = (
|
|
62
|
+
_ctx: Context,
|
|
63
|
+
_topic: Topic,
|
|
64
|
+
_shareName: ShareName,
|
|
65
|
+
) => (true) as const;
|
|
15
66
|
|
|
16
67
|
/**
|
|
17
|
-
*
|
|
68
|
+
* Configuration options for creating an MqttServer instance.
|
|
18
69
|
*/
|
|
19
70
|
export type MqttServerOptions = {
|
|
71
|
+
/** Optional persistence layer implementation. Defaults to MemoryPersistence. */
|
|
20
72
|
persistence?: IPersistence;
|
|
73
|
+
/** Optional custom handlers for authentication and authorization. */
|
|
21
74
|
handlers?: Handlers;
|
|
75
|
+
/** Optional configuration data */
|
|
76
|
+
configuration?: ConfigurationInput;
|
|
22
77
|
};
|
|
23
78
|
|
|
24
|
-
/** The MqttServer class provides
|
|
79
|
+
/** * The MqttServer class provides an MQTT server with configurable persistence and
|
|
25
80
|
* authentication/authorization handlers.
|
|
26
81
|
*
|
|
27
82
|
* The default handlers are:
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
83
|
+
* - isAuthenticated: always returns ok
|
|
84
|
+
* - isAuthorizedToPublish: always returns true
|
|
85
|
+
* - isAuthorizedToSubscribe: always returns true
|
|
31
86
|
*
|
|
32
87
|
* To customize the handlers, pass in a Handlers object.
|
|
33
88
|
* To customize the persistence, pass in a Persistence object.
|
|
34
89
|
*/
|
|
35
|
-
|
|
36
90
|
export class MqttServer {
|
|
91
|
+
/** The registered authentication and authorization handlers. */
|
|
37
92
|
handlers: Handlers;
|
|
93
|
+
/** The persistence layer used for storing sessions and messages. */
|
|
38
94
|
persistence: IPersistence;
|
|
95
|
+
/** The persistence layer used for storing sessions and messages. */
|
|
96
|
+
configuration: Configuration;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Initializes a new instance of the MqttServer.
|
|
100
|
+
* * @param {MqttServerOptions} options - The configuration options for the server.
|
|
101
|
+
*/
|
|
39
102
|
constructor({
|
|
40
103
|
persistence,
|
|
41
104
|
handlers,
|
|
105
|
+
configuration,
|
|
42
106
|
}: MqttServerOptions) {
|
|
43
107
|
this.persistence = persistence || new MemoryPersistence();
|
|
44
108
|
this.handlers = {
|
|
109
|
+
preconnect: handlers?.preconnect || defaultPreconnect,
|
|
45
110
|
isAuthenticated: handlers?.isAuthenticated || defaultIsAuthenticated,
|
|
111
|
+
processAuth: handlers?.processAuth || defaultProcessAuth,
|
|
46
112
|
isAuthorizedToPublish: handlers?.isAuthorizedToPublish ||
|
|
47
|
-
|
|
113
|
+
defaultIsAuthorizedToPublish,
|
|
48
114
|
isAuthorizedToSubscribe: handlers?.isAuthorizedToSubscribe ||
|
|
49
|
-
|
|
115
|
+
defaultIsAuthorizedToSubscribe,
|
|
50
116
|
};
|
|
117
|
+
this.configuration = createConfiguration(configuration);
|
|
51
118
|
}
|
|
52
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Serve a new client connection.
|
|
122
|
+
* @param {SockConn} conn - The socket connection to serve.
|
|
123
|
+
* @returns {Promise<void>} A promise that resolves when the connection is closed.
|
|
124
|
+
*/
|
|
53
125
|
async serve(conn: SockConn): Promise<void> {
|
|
54
|
-
|
|
126
|
+
if (this.handlers.preconnect) {
|
|
127
|
+
if (!await this.handlers.preconnect(conn)) {
|
|
128
|
+
conn.close();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const ctx = new Context(
|
|
133
|
+
this.configuration,
|
|
134
|
+
this.persistence,
|
|
135
|
+
conn,
|
|
136
|
+
this.handlers,
|
|
137
|
+
);
|
|
55
138
|
if (conn.remoteAddr?.transport === "tcp") {
|
|
56
|
-
logger.debug(
|
|
139
|
+
logger.debug("socket connected from", conn.remoteAddr.hostname);
|
|
57
140
|
}
|
|
58
141
|
try {
|
|
59
142
|
for await (const packet of ctx.mqttConn) {
|
|
143
|
+
logger.debug("next packet");
|
|
60
144
|
await handlePacket(ctx, packet);
|
|
61
145
|
}
|
|
62
146
|
} catch (err) {
|
|
63
|
-
logger.debug(
|
|
147
|
+
logger.debug("Error while serving:", err);
|
|
64
148
|
} finally {
|
|
65
|
-
|
|
66
|
-
|
|
149
|
+
logger.debug("done serving for", ctx.clientId);
|
|
150
|
+
await ctx.close();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Close the server and all active client connections.
|
|
156
|
+
* @param {boolean} cleanUp - If true, clean up client sessions on close.
|
|
157
|
+
*/
|
|
158
|
+
async close(cleanUp: boolean = false): Promise<void> {
|
|
159
|
+
logger.debug("stopping mqttServer");
|
|
160
|
+
for (const [clientid, ctx] of Context.clientList) {
|
|
161
|
+
logger.debug("closing session for clientid:", clientid);
|
|
162
|
+
await ctx.close();
|
|
163
|
+
if (cleanUp) {
|
|
164
|
+
await ctx.clean();
|
|
67
165
|
}
|
|
68
166
|
}
|
|
69
167
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { Conn } from "./socket.ts";
|
|
4
|
+
import { createMockSockConn } from "../dev_utils/mod.ts";
|
|
5
|
+
|
|
6
|
+
test("Conn.read peaks and buffers partial data correctly", async () => {
|
|
7
|
+
const chunk1 = new Uint8Array([1, 2, 3]);
|
|
8
|
+
const chunk2 = new Uint8Array([4, 5, 6, 7]);
|
|
9
|
+
const chunk3 = new Uint8Array([8, 9]);
|
|
10
|
+
|
|
11
|
+
const mockTarget = new Uint8Array();
|
|
12
|
+
const sockConn = createMockSockConn([chunk1, chunk2, chunk3], mockTarget);
|
|
13
|
+
const conn = new Conn(sockConn);
|
|
14
|
+
|
|
15
|
+
const res1 = await conn.read(2);
|
|
16
|
+
assert.deepStrictEqual(res1, new Uint8Array([1, 2]));
|
|
17
|
+
|
|
18
|
+
const res2 = await conn.read(3);
|
|
19
|
+
assert.deepStrictEqual(res2, new Uint8Array([3, 4, 5]));
|
|
20
|
+
|
|
21
|
+
const res3 = await conn.read(4);
|
|
22
|
+
assert.deepStrictEqual(res3, new Uint8Array([6, 7, 8, 9]));
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test("Conn.read returns null when stream ends before length is met", async () => {
|
|
26
|
+
const chunk = new Uint8Array([1, 2, 3]);
|
|
27
|
+
const mockTarget = new Uint8Array(0);
|
|
28
|
+
const sockConn = createMockSockConn([chunk], mockTarget);
|
|
29
|
+
const conn = new Conn(sockConn);
|
|
30
|
+
|
|
31
|
+
// asking for5 bytes, but only 3 are available in the stream
|
|
32
|
+
const res = await conn.read(5);
|
|
33
|
+
assert.deepStrictEqual(res, null);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("Conn.read returns null when length <= 0", async () => {
|
|
37
|
+
const chunk = new Uint8Array([1, 2, 3]);
|
|
38
|
+
const mockTarget = new Uint8Array(0);
|
|
39
|
+
const sockConn = createMockSockConn([chunk], mockTarget);
|
|
40
|
+
const conn = new Conn(sockConn);
|
|
41
|
+
|
|
42
|
+
const res = await conn.read(-1);
|
|
43
|
+
assert.deepStrictEqual(res, null);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("Conn.read returns empty array when length = 0", async () => {
|
|
47
|
+
const chunk = new Uint8Array([1, 2, 3]);
|
|
48
|
+
const mockTarget = new Uint8Array(0);
|
|
49
|
+
const sockConn = createMockSockConn([chunk], mockTarget);
|
|
50
|
+
const conn = new Conn(sockConn);
|
|
51
|
+
|
|
52
|
+
const res = await conn.read(0);
|
|
53
|
+
assert.deepStrictEqual(res?.length, 0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("Conn.write successfully forwards data to writable stream", async () => {
|
|
57
|
+
const dataToWrite = new Uint8Array([10, 20, 30, 40]);
|
|
58
|
+
const mockTarget = new Uint8Array(4);
|
|
59
|
+
const sockConn = createMockSockConn([], mockTarget);
|
|
60
|
+
const conn = new Conn(sockConn);
|
|
61
|
+
|
|
62
|
+
const bytesWritten = await conn.write(dataToWrite);
|
|
63
|
+
|
|
64
|
+
assert.deepStrictEqual(bytesWritten, 4);
|
|
65
|
+
assert.deepStrictEqual(mockTarget, dataToWrite);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("Conn.write rejects when connection is closed", async () => {
|
|
69
|
+
const mockTarget = new Uint8Array(4);
|
|
70
|
+
const sockConn = createMockSockConn([], mockTarget);
|
|
71
|
+
const conn = new Conn(sockConn);
|
|
72
|
+
|
|
73
|
+
conn.close();
|
|
74
|
+
|
|
75
|
+
await assert.rejects(
|
|
76
|
+
conn.write(new Uint8Array([1, 2])),
|
|
77
|
+
/Connection closed/,
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test("Conn.close closes writer, releases reader lock and sets closed flag", () => {
|
|
82
|
+
const mockTarget = new Uint8Array(0);
|
|
83
|
+
const sockConn = createMockSockConn([], mockTarget);
|
|
84
|
+
const conn = new Conn(sockConn);
|
|
85
|
+
|
|
86
|
+
assert.deepStrictEqual(conn.closed, false);
|
|
87
|
+
|
|
88
|
+
conn.close();
|
|
89
|
+
|
|
90
|
+
assert.deepStrictEqual(conn.closed, true);
|
|
91
|
+
});
|