@seriousme/opifex 1.11.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -40
- package/bin/conformanceServer.ts +45 -13
- package/bin/demoServer.ts +38 -13
- package/bin/mqtt.ts +2 -2
- package/client/ConnectionState.ts +3 -1
- package/client/client.ts +88 -47
- package/client/context.ts +79 -27
- package/client/deps.ts +10 -3
- 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 +18 -8
- 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 +13 -2
- package/client/store/memoryStore.ts +12 -11
- package/client/store/store.ts +4 -2
- package/deno/README.md +1 -2
- package/deno/tcpClient.test.ts +75 -0
- package/deno/tcpClient.ts +36 -18
- package/deno/tcpServer.test.ts +22 -21
- package/deno/tcpServer.ts +26 -4
- package/deno/tlsServer.test.ts +97 -0
- package/deno/tlsServer.ts +58 -0
- package/deno/wsServer.test.ts +93 -0
- package/deno/wsServer.ts +96 -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 -3
- 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 +2 -2
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/ConnectionState.d.ts +3 -1
- 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 +47 -21
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +57 -20
- package/dist/client/client.js.map +1 -1
- package/dist/client/context.d.ts +15 -7
- 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 +4 -3
- 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 +3 -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 +3 -3
- package/dist/client/store/memoryStore.d.ts.map +1 -1
- package/dist/client/store/memoryStore.js +3 -3
- package/dist/client/store/memoryStore.js.map +1 -1
- package/dist/client/store/store.d.ts +3 -2
- 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 +24 -31
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +57 -36
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.d.ts +4 -0
- package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.js.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts.map +1 -1
- package/dist/mqttPacket/PacketType.d.ts +4 -0
- package/dist/mqttPacket/PacketType.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.d.ts +4 -4
- package/dist/mqttPacket/Properties.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.js.map +1 -1
- package/dist/mqttPacket/ReasonCode.d.ts +4 -5
- 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 +4 -0
- package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
- package/dist/mqttPacket/auth.d.ts +7 -8
- 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 +11 -10
- 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 +7 -7
- 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 +6 -16
- 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 +9 -8
- 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 +7 -19
- package/dist/mqttPacket/encoder.d.ts.map +1 -1
- package/dist/mqttPacket/encoder.js +5 -28
- package/dist/mqttPacket/encoder.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 +6 -6
- 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 +6 -6
- 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 +8 -7
- 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 +9 -8
- 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 +41 -10
- 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 +2 -29
- package/dist/mqttPacket/types.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.d.ts +9 -8
- 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 +26 -8
- 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 +22 -2
- package/dist/node/tcpClient.d.ts.map +1 -1
- package/dist/node/tcpClient.js +29 -10
- package/dist/node/tcpClient.js.map +1 -1
- package/dist/node/tcpServer.d.ts +18 -0
- package/dist/node/tcpServer.d.ts.map +1 -1
- package/dist/node/tcpServer.js +21 -2
- package/dist/node/tcpServer.js.map +1 -1
- package/dist/node/tlsServer.d.ts +37 -0
- package/dist/node/tlsServer.d.ts.map +1 -0
- package/dist/node/tlsServer.js +73 -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 +45 -70
- 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 +199 -25
- 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 +9 -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 +32 -9
- 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 +15 -9
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +66 -18
- 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 +61 -41
- 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 +42 -5
- 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 +14 -0
- package/dist/web/wsClient.d.ts.map +1 -0
- package/dist/web/wsClient.js +33 -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 +76 -60
- package/mqttPacket/AuthenticationResult.ts +6 -0
- package/mqttPacket/PacketType.ts +5 -0
- package/mqttPacket/Properties.ts +8 -5
- package/mqttPacket/ReasonCode.ts +8 -9
- package/mqttPacket/RetainHandling.ts +5 -0
- package/mqttPacket/auth.test.ts +1 -1
- package/mqttPacket/auth.ts +44 -51
- package/mqttPacket/codec.ts +147 -0
- package/mqttPacket/connack.ts +63 -73
- package/mqttPacket/connect.test.ts +2 -2
- package/mqttPacket/connect.ts +178 -192
- package/mqttPacket/decoder.test.ts +0 -39
- package/mqttPacket/decoder.ts +17 -46
- package/mqttPacket/disconnect.ts +60 -71
- package/mqttPacket/encoder.test.ts +2 -2
- package/mqttPacket/encoder.ts +13 -46
- package/mqttPacket/mod.ts +48 -204
- package/mqttPacket/pingreq.ts +22 -28
- package/mqttPacket/pingres.ts +22 -28
- package/mqttPacket/protocolLevels.ts +12 -7
- package/mqttPacket/pubblishAcks.ts +61 -75
- package/mqttPacket/publish.ts +70 -84
- package/mqttPacket/publishAcks.test.ts +3 -3
- package/mqttPacket/suback.ts +53 -68
- package/mqttPacket/subscribe.ts +146 -128
- package/mqttPacket/types.ts +2 -35
- package/mqttPacket/unsuback.ts +50 -61
- package/mqttPacket/unsubscribe.ts +77 -72
- 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 +33 -17
- package/node/tcpServer.test.ts +24 -20
- package/node/tcpServer.ts +29 -6
- package/node/tlsServer.test.ts +94 -0
- package/node/tlsServer.ts +97 -0
- package/node/wrapNodeSocket.ts +7 -30
- package/package.json +72 -44
- package/persistence/basicPersistence.ts +495 -0
- package/persistence/deps.ts +11 -1
- package/persistence/memory/memoryPersistence.ts +12 -153
- package/persistence/memory/memoryStorage.ts +232 -0
- package/persistence/mod.ts +5 -10
- package/persistence/persistence.test.ts +24 -0
- package/persistence/persistence.testing.ts +1324 -0
- package/persistence/persistence.ts +112 -68
- 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 +660 -76
- package/server/deps.ts +24 -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 +188 -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 +157 -39
- package/server/handlers/handleUnsubscribe.test.ts +79 -0
- package/server/handlers/handleUnsubscribe.ts +28 -4
- 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 +5 -4
- package/server/preconnect.test.ts +151 -0
- package/server/server.ts +117 -19
- package/socket/socket.test.ts +91 -0
- package/socket/socket.ts +85 -34
- 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 +70 -45
- package/utils/bufferedAsyncIterable.test.ts +92 -0
- 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 +64 -9
- 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 +37 -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/dev_utils/socketPair.ts +0 -85
- package/dist/persistence/store.d.ts +0 -14
- 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 -16
- package/server/test/handleConnect.test.ts +0 -122
- package/server/test/test-handlers.ts +0 -53
- /package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { AuthenticatedResult, Context } from "../context.ts";
|
|
2
|
+
import { ConnectionState } from "../ConnectionState.ts";
|
|
3
|
+
import { PacketType, ReasonCode, ReasonCodeByNumber } from "../deps.ts";
|
|
4
|
+
import type { AuthPacket } from "../deps.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Handle error
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
function handleError(ctx: Context, errMsg: string) {
|
|
11
|
+
if (ctx.connectionState === ConnectionState.connecting) {
|
|
12
|
+
const err = new Error(
|
|
13
|
+
`Connect failed: ${errMsg}`,
|
|
14
|
+
);
|
|
15
|
+
ctx.connectionState = ConnectionState.disconnecting;
|
|
16
|
+
ctx.pingTimer?.clear();
|
|
17
|
+
ctx.unresolvedConnect?.reject(err);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
throw new Error(errMsg);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Handle success
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
async function handleResult(
|
|
28
|
+
ctx: Context,
|
|
29
|
+
authMethod: string,
|
|
30
|
+
result: AuthenticatedResult,
|
|
31
|
+
) {
|
|
32
|
+
await ctx.send({
|
|
33
|
+
type: PacketType.auth,
|
|
34
|
+
protocolLevel: 5,
|
|
35
|
+
reasonCode: result.reasonCode,
|
|
36
|
+
properties: result.authData
|
|
37
|
+
? {
|
|
38
|
+
authenticationMethod: authMethod,
|
|
39
|
+
authenticationData: result.authData,
|
|
40
|
+
reasonString: result.reasonString,
|
|
41
|
+
}
|
|
42
|
+
: {},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Handles v5 Auth packet
|
|
48
|
+
* @param ctx - The connection context containing send method
|
|
49
|
+
* @returns Promise that resolves
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
export async function handleAuth(
|
|
53
|
+
ctx: Context,
|
|
54
|
+
authPacket: AuthPacket,
|
|
55
|
+
): Promise<void> {
|
|
56
|
+
const reasonCode = authPacket.reasonCode;
|
|
57
|
+
if (reasonCode === ReasonCode.success) {
|
|
58
|
+
// we are connected again
|
|
59
|
+
ctx.connectionState = ConnectionState.connected;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (reasonCode !== ReasonCode.continueAuthentication) {
|
|
64
|
+
// something went wrong
|
|
65
|
+
handleError(ctx, ReasonCodeByNumber[reasonCode]);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// we need to send something back
|
|
70
|
+
if (ctx.connectionState === ConnectionState.connected) {
|
|
71
|
+
// pauze auther activities
|
|
72
|
+
ctx.connectionState = ConnectionState.authenticating;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const authMethod = authPacket.properties?.authenticationMethod;
|
|
76
|
+
const authData = authPacket.properties?.authenticationData;
|
|
77
|
+
if (!(authMethod && authData)) {
|
|
78
|
+
throw new Error("Auth method and/or Auth data missing");
|
|
79
|
+
}
|
|
80
|
+
const result = await ctx.authHandler(
|
|
81
|
+
ctx,
|
|
82
|
+
authMethod,
|
|
83
|
+
authData,
|
|
84
|
+
);
|
|
85
|
+
if (result.reasonCode === ReasonCode.continueAuthentication) {
|
|
86
|
+
return handleResult(ctx, authMethod, result);
|
|
87
|
+
}
|
|
88
|
+
return handleError(ctx, result.reasonString || "Error during authentication");
|
|
89
|
+
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { handleConnack } from "./handleConnack.ts";
|
|
4
|
+
import { ConnectionState } from "../ConnectionState.ts";
|
|
5
|
+
import { AuthenticationResult, MQTTLevel } from "../deps.ts";
|
|
6
|
+
import type { ConnackPacket } from "../deps.ts";
|
|
7
|
+
import { Deferred } from "../../utils/mod.ts";
|
|
8
|
+
|
|
9
|
+
function createMockContext() {
|
|
10
|
+
const sentPackets: unknown[] = [];
|
|
11
|
+
return {
|
|
12
|
+
connectionState: ConnectionState.connecting as string,
|
|
13
|
+
protocolLevel: 4 as const,
|
|
14
|
+
mqttConn: { codecOpts: { protocolLevel: MQTTLevel.unknown } },
|
|
15
|
+
pingTimer: { reset: () => {}, clear: () => {} },
|
|
16
|
+
unresolvedConnect: new Deferred<number>(),
|
|
17
|
+
store: {
|
|
18
|
+
pendingOutgoing: new Map(),
|
|
19
|
+
pendingIncoming: new Map(),
|
|
20
|
+
pendingAckOutgoing: new Map(),
|
|
21
|
+
async *pendingOutgoingPackets() {},
|
|
22
|
+
},
|
|
23
|
+
send: (packet: unknown) => {
|
|
24
|
+
sentPackets.push(packet);
|
|
25
|
+
},
|
|
26
|
+
sentPackets,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
test("handleConnack sets connected state on success", async () => {
|
|
31
|
+
const ctx = createMockContext();
|
|
32
|
+
const packet = {
|
|
33
|
+
type: 2,
|
|
34
|
+
protocolLevel: 4 as const,
|
|
35
|
+
sessionPresent: false,
|
|
36
|
+
returnCode: AuthenticationResult.ok,
|
|
37
|
+
} as ConnackPacket;
|
|
38
|
+
|
|
39
|
+
await handleConnack(ctx as never, packet);
|
|
40
|
+
|
|
41
|
+
assert.deepStrictEqual(
|
|
42
|
+
ctx.connectionState,
|
|
43
|
+
ConnectionState.connected,
|
|
44
|
+
"Should be connected after successful CONNACK",
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("handleConnack resolves connect promise on success", async () => {
|
|
49
|
+
const ctx = createMockContext();
|
|
50
|
+
const packet = {
|
|
51
|
+
type: 2,
|
|
52
|
+
protocolLevel: 4 as const,
|
|
53
|
+
sessionPresent: false,
|
|
54
|
+
returnCode: AuthenticationResult.ok,
|
|
55
|
+
} as ConnackPacket;
|
|
56
|
+
|
|
57
|
+
await handleConnack(ctx as never, packet);
|
|
58
|
+
|
|
59
|
+
const result = await ctx.unresolvedConnect.promise;
|
|
60
|
+
assert.deepStrictEqual(result, 0, "Should resolve with success code 0");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("handleConnack rejects on bad username/password", async () => {
|
|
64
|
+
const ctx = createMockContext();
|
|
65
|
+
const packet = {
|
|
66
|
+
type: 2,
|
|
67
|
+
protocolLevel: 4 as const,
|
|
68
|
+
sessionPresent: false,
|
|
69
|
+
returnCode: AuthenticationResult.badUsernameOrPassword,
|
|
70
|
+
} as ConnackPacket;
|
|
71
|
+
|
|
72
|
+
await handleConnack(ctx as never, packet);
|
|
73
|
+
|
|
74
|
+
assert.deepStrictEqual(
|
|
75
|
+
ctx.connectionState,
|
|
76
|
+
ConnectionState.disconnecting,
|
|
77
|
+
"Should be disconnecting on auth failure",
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
await assert.rejects(
|
|
81
|
+
ctx.unresolvedConnect.promise,
|
|
82
|
+
/Connect failed/,
|
|
83
|
+
"Should reject with connect failed error",
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("handleConnack rejects on not authorized", async () => {
|
|
88
|
+
const ctx = createMockContext();
|
|
89
|
+
const packet = {
|
|
90
|
+
type: 2,
|
|
91
|
+
protocolLevel: 4 as const,
|
|
92
|
+
sessionPresent: false,
|
|
93
|
+
returnCode: AuthenticationResult.notAuthorized,
|
|
94
|
+
} as ConnackPacket;
|
|
95
|
+
|
|
96
|
+
await handleConnack(ctx as never, packet);
|
|
97
|
+
|
|
98
|
+
assert.deepStrictEqual(
|
|
99
|
+
ctx.connectionState,
|
|
100
|
+
ConnectionState.disconnecting,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
await assert.rejects(
|
|
104
|
+
ctx.unresolvedConnect.promise,
|
|
105
|
+
/Connect failed/,
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("handleConnack handles MQTT v5 reason codes", async () => {
|
|
110
|
+
const ctx = createMockContext();
|
|
111
|
+
(ctx as { protocolLevel: number }).protocolLevel = 5;
|
|
112
|
+
const packet = {
|
|
113
|
+
type: 2,
|
|
114
|
+
protocolLevel: 5 as const,
|
|
115
|
+
sessionPresent: false,
|
|
116
|
+
reasonCode: 0,
|
|
117
|
+
} as ConnackPacket;
|
|
118
|
+
|
|
119
|
+
await handleConnack(ctx as never, packet);
|
|
120
|
+
|
|
121
|
+
assert.deepStrictEqual(
|
|
122
|
+
ctx.connectionState,
|
|
123
|
+
ConnectionState.connected,
|
|
124
|
+
"Should be connected with v5 success reason code",
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("handleConnack resets ping timer on success", async () => {
|
|
129
|
+
let timerReset = false;
|
|
130
|
+
const ctx = createMockContext();
|
|
131
|
+
ctx.pingTimer = {
|
|
132
|
+
reset: () => {
|
|
133
|
+
timerReset = true;
|
|
134
|
+
},
|
|
135
|
+
clear: () => {},
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const packet = {
|
|
139
|
+
type: 2,
|
|
140
|
+
protocolLevel: 4 as const,
|
|
141
|
+
sessionPresent: false,
|
|
142
|
+
returnCode: AuthenticationResult.ok,
|
|
143
|
+
} as ConnackPacket;
|
|
144
|
+
|
|
145
|
+
await handleConnack(ctx as never, packet);
|
|
146
|
+
|
|
147
|
+
assert.deepStrictEqual(timerReset, true, "Ping timer should be reset");
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test("handleConnack clears ping timer on failure", async () => {
|
|
151
|
+
let timerCleared = false;
|
|
152
|
+
const ctx = createMockContext();
|
|
153
|
+
ctx.pingTimer = {
|
|
154
|
+
reset: () => {},
|
|
155
|
+
clear: () => {
|
|
156
|
+
timerCleared = true;
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const packet = {
|
|
161
|
+
type: 2,
|
|
162
|
+
protocolLevel: 4 as const,
|
|
163
|
+
sessionPresent: false,
|
|
164
|
+
returnCode: AuthenticationResult.badUsernameOrPassword,
|
|
165
|
+
} as ConnackPacket;
|
|
166
|
+
|
|
167
|
+
await handleConnack(ctx as never, packet);
|
|
168
|
+
assert.deepStrictEqual(timerCleared, true, "Ping timer should be cleared");
|
|
169
|
+
await assert.rejects(
|
|
170
|
+
ctx.unresolvedConnect.promise,
|
|
171
|
+
/Connect failed/,
|
|
172
|
+
);
|
|
173
|
+
});
|
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
import type { Context } from "../context.ts";
|
|
2
2
|
import { ConnectionState } from "../ConnectionState.ts";
|
|
3
3
|
import { AuthenticationResultByNumber, ReasonCodeByNumber } from "../deps.ts";
|
|
4
|
-
import type { ConnackPacket,
|
|
4
|
+
import type { ConnackPacket, ReasonCode } from "../deps.ts";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Handles the CONNACK packet received from the MQTT broker
|
|
8
|
-
* @param packet - The CONNACK packet containing the connection acknowledgment
|
|
9
8
|
* @param ctx - The connection context
|
|
9
|
+
* @param packet - The CONNACK packet containing the connection acknowledgment
|
|
10
10
|
* @returns Promise that resolves when handling is complete
|
|
11
11
|
*/
|
|
12
|
-
export async function handleConnack(
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
: packet.returnCode;
|
|
12
|
+
export async function handleConnack(ctx: Context, packet: ConnackPacket) {
|
|
13
|
+
const isVersion5 = packet.protocolLevel === 5;
|
|
14
|
+
const result = isVersion5 ? packet.reasonCode : packet.returnCode;
|
|
16
15
|
if (result === 0) {
|
|
17
16
|
ctx.connectionState = ConnectionState.connected;
|
|
18
17
|
if (ctx.mqttConn) {
|
|
19
18
|
ctx.mqttConn.codecOpts.protocolLevel = ctx.protocolLevel;
|
|
20
19
|
}
|
|
21
|
-
|
|
20
|
+
|
|
21
|
+
const serverKeepAlive = isVersion5
|
|
22
|
+
? packet.properties?.serverKeepAlive
|
|
23
|
+
: undefined;
|
|
24
|
+
|
|
25
|
+
if (serverKeepAlive === 0) {
|
|
26
|
+
ctx.pingTimer?.clear(); // Server disabled keepalive
|
|
27
|
+
} else if (serverKeepAlive !== undefined) {
|
|
28
|
+
ctx.setPingTimer(serverKeepAlive); // Server set a new interval
|
|
29
|
+
} else {
|
|
30
|
+
ctx.pingTimer?.reset(); // Default fallback for V4 or V5 without override
|
|
31
|
+
}
|
|
22
32
|
ctx.unresolvedConnect?.resolve(result);
|
|
23
33
|
// start transmitting packets that were queued before
|
|
24
34
|
for await (const packet of ctx.store.pendingOutgoingPackets()) {
|
|
@@ -28,7 +38,7 @@ export async function handleConnack(packet: ConnackPacket, ctx: Context) {
|
|
|
28
38
|
}
|
|
29
39
|
|
|
30
40
|
const errMsg = packet.protocolLevel === 5
|
|
31
|
-
? ReasonCodeByNumber[result as
|
|
41
|
+
? ReasonCodeByNumber[result as ReasonCode]
|
|
32
42
|
: AuthenticationResultByNumber[result];
|
|
33
43
|
|
|
34
44
|
const err = new Error(
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { handleDisconnect } from "./handleDisconnect.ts";
|
|
4
|
+
import { PacketType, ReasonCode, ReasonCodeByNumber } from "../deps.ts";
|
|
5
|
+
import type { DisconnectPacket } from "../deps.ts";
|
|
6
|
+
|
|
7
|
+
function createMockContext() {
|
|
8
|
+
return {
|
|
9
|
+
close: () => {},
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
test("handleDisconnect processes V5 rejection", () => {
|
|
14
|
+
const ctx = createMockContext();
|
|
15
|
+
const reasonCode = ReasonCode.notAuthorized;
|
|
16
|
+
assert.throws(() =>
|
|
17
|
+
handleDisconnect(ctx as never, {
|
|
18
|
+
type: PacketType.disconnect,
|
|
19
|
+
protocolLevel: 5,
|
|
20
|
+
reasonCode,
|
|
21
|
+
} as DisconnectPacket), Error(ReasonCodeByNumber[reasonCode]));
|
|
22
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Context } from "../context.ts";
|
|
2
|
+
import type { DisconnectPacket } from "../deps.ts";
|
|
3
|
+
import { ReasonCodeByNumber } from "../deps.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Handles Disconnect Packet sent by the broker (V5 only)
|
|
7
|
+
* @param ctx - The MQTT client context
|
|
8
|
+
* @param packet - The PUBACK packet received from the broker
|
|
9
|
+
* @description
|
|
10
|
+
* - throw error
|
|
11
|
+
*/
|
|
12
|
+
export function handleDisconnect(ctx: Context, packet: DisconnectPacket): void {
|
|
13
|
+
if (packet.protocolLevel === 5 && ((packet.reasonCode ?? 0) !== 0)) {
|
|
14
|
+
throw new Error(ReasonCodeByNumber[packet.reasonCode!]);
|
|
15
|
+
}
|
|
16
|
+
ctx.close();
|
|
17
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { handlePacket } from "./handlePacket.ts";
|
|
4
|
+
import { ConnectionState } from "../ConnectionState.ts";
|
|
5
|
+
import { AuthenticationResult, MQTTLevel, PacketType } from "../deps.ts";
|
|
6
|
+
import type { AnyPacket, PublishPacket } from "../deps.ts";
|
|
7
|
+
import { Deferred } from "../../utils/mod.ts";
|
|
8
|
+
|
|
9
|
+
function createMockContext() {
|
|
10
|
+
const sentPackets: unknown[] = [];
|
|
11
|
+
const receivedPublishes: PublishPacket[] = [];
|
|
12
|
+
const receivedIds: {
|
|
13
|
+
puback: number[];
|
|
14
|
+
pubcomp: number[];
|
|
15
|
+
suback: number[];
|
|
16
|
+
unsuback: number[];
|
|
17
|
+
} = {
|
|
18
|
+
puback: [],
|
|
19
|
+
pubcomp: [],
|
|
20
|
+
suback: [],
|
|
21
|
+
unsuback: [],
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
connectionState: ConnectionState.connecting as string,
|
|
25
|
+
protocolLevel: 4 as const,
|
|
26
|
+
mqttConn: { codecOpts: { protocolLevel: MQTTLevel.unknown } },
|
|
27
|
+
pingTimer: { reset: () => {}, clear: () => {} },
|
|
28
|
+
unresolvedConnect: new Deferred<number>(),
|
|
29
|
+
store: {
|
|
30
|
+
pendingOutgoing: new Map<number, unknown>(),
|
|
31
|
+
pendingIncoming: new Map<number, PublishPacket>(),
|
|
32
|
+
pendingAckOutgoing: new Map<number, unknown>(),
|
|
33
|
+
async *pendingOutgoingPackets() {},
|
|
34
|
+
},
|
|
35
|
+
send: (packet: unknown) => {
|
|
36
|
+
sentPackets.push(packet);
|
|
37
|
+
},
|
|
38
|
+
receivePublish: (packet: PublishPacket) => {
|
|
39
|
+
receivedPublishes.push(packet);
|
|
40
|
+
},
|
|
41
|
+
receivePuback: (id: number) => {
|
|
42
|
+
receivedIds.puback.push(id);
|
|
43
|
+
return true;
|
|
44
|
+
},
|
|
45
|
+
receivePubcomp: (id: number) => {
|
|
46
|
+
receivedIds.pubcomp.push(id);
|
|
47
|
+
return true;
|
|
48
|
+
},
|
|
49
|
+
receiveSuback: (id: number, _codes: number[]) => {
|
|
50
|
+
receivedIds.suback.push(id);
|
|
51
|
+
return true;
|
|
52
|
+
},
|
|
53
|
+
receiveUnsuback: (id: number) => {
|
|
54
|
+
receivedIds.unsuback.push(id);
|
|
55
|
+
return true;
|
|
56
|
+
},
|
|
57
|
+
sentPackets,
|
|
58
|
+
receivedPublishes,
|
|
59
|
+
receivedIds,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
test("handlePacket dispatches CONNACK before connected", async () => {
|
|
64
|
+
const ctx = createMockContext();
|
|
65
|
+
|
|
66
|
+
const packet = {
|
|
67
|
+
type: PacketType.connack,
|
|
68
|
+
protocolLevel: 4 as const,
|
|
69
|
+
sessionPresent: false,
|
|
70
|
+
returnCode: AuthenticationResult.ok,
|
|
71
|
+
} as AnyPacket;
|
|
72
|
+
|
|
73
|
+
await handlePacket(ctx as never, packet);
|
|
74
|
+
|
|
75
|
+
assert.deepStrictEqual(
|
|
76
|
+
ctx.connectionState,
|
|
77
|
+
ConnectionState.connected,
|
|
78
|
+
"Should handle CONNACK and set connected state",
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("handlePacket rejects non-CONNACK before connected", async () => {
|
|
83
|
+
const ctx = createMockContext();
|
|
84
|
+
|
|
85
|
+
const packet = {
|
|
86
|
+
type: PacketType.pingreq,
|
|
87
|
+
protocolLevel: 4,
|
|
88
|
+
} as AnyPacket;
|
|
89
|
+
|
|
90
|
+
await assert.rejects(
|
|
91
|
+
handlePacket(ctx as never, packet),
|
|
92
|
+
/while connecting/,
|
|
93
|
+
"Should reject packets before CONNACK",
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("handlePacket dispatches PUBLISH after connected", async () => {
|
|
98
|
+
const ctx = createMockContext();
|
|
99
|
+
ctx.connectionState = ConnectionState.connected;
|
|
100
|
+
|
|
101
|
+
const packet = {
|
|
102
|
+
type: PacketType.publish,
|
|
103
|
+
protocolLevel: 4 as const,
|
|
104
|
+
topic: "test/topic",
|
|
105
|
+
payload: new Uint8Array([1, 2, 3]),
|
|
106
|
+
qos: 0 as const,
|
|
107
|
+
retain: false,
|
|
108
|
+
dup: false,
|
|
109
|
+
} as AnyPacket;
|
|
110
|
+
|
|
111
|
+
await handlePacket(ctx as never, packet);
|
|
112
|
+
|
|
113
|
+
assert.deepStrictEqual(
|
|
114
|
+
ctx.receivedPublishes.length,
|
|
115
|
+
1,
|
|
116
|
+
"Should dispatch PUBLISH to handler",
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test("handlePacket dispatches PUBACK after connected", async () => {
|
|
121
|
+
const ctx = createMockContext();
|
|
122
|
+
ctx.connectionState = ConnectionState.connected;
|
|
123
|
+
|
|
124
|
+
const packet = {
|
|
125
|
+
type: PacketType.puback,
|
|
126
|
+
protocolLevel: 4 as const,
|
|
127
|
+
id: 1,
|
|
128
|
+
} as AnyPacket;
|
|
129
|
+
|
|
130
|
+
await handlePacket(ctx as never, packet);
|
|
131
|
+
|
|
132
|
+
assert.deepStrictEqual(
|
|
133
|
+
ctx.receivedIds.puback,
|
|
134
|
+
[1],
|
|
135
|
+
"Should dispatch PUBACK to handler",
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("handlePacket dispatches PINGRES silently", async () => {
|
|
140
|
+
const ctx = createMockContext();
|
|
141
|
+
ctx.connectionState = ConnectionState.connected;
|
|
142
|
+
|
|
143
|
+
const packet = {
|
|
144
|
+
type: PacketType.pingres,
|
|
145
|
+
protocolLevel: 4,
|
|
146
|
+
} as AnyPacket;
|
|
147
|
+
|
|
148
|
+
// Should not throw
|
|
149
|
+
await handlePacket(ctx as never, packet);
|
|
150
|
+
|
|
151
|
+
// PINGRES is silently handled (no specific action)
|
|
152
|
+
assert.deepStrictEqual(ctx.sentPackets.length, 0);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("handlePacket dispatches SUBACK after connected", async () => {
|
|
156
|
+
const ctx = createMockContext();
|
|
157
|
+
ctx.connectionState = ConnectionState.connected;
|
|
158
|
+
ctx.store.pendingOutgoing.set(1, { type: PacketType.subscribe });
|
|
159
|
+
|
|
160
|
+
const packet = {
|
|
161
|
+
type: PacketType.suback,
|
|
162
|
+
protocolLevel: 4 as const,
|
|
163
|
+
id: 1,
|
|
164
|
+
returnCodes: [0],
|
|
165
|
+
} as AnyPacket;
|
|
166
|
+
|
|
167
|
+
await handlePacket(ctx as never, packet);
|
|
168
|
+
|
|
169
|
+
assert.deepStrictEqual(
|
|
170
|
+
ctx.receivedIds.suback,
|
|
171
|
+
[1],
|
|
172
|
+
"Should dispatch SUBACK to handler",
|
|
173
|
+
);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test("handlePacket dispatches UNSUBACK after connected", async () => {
|
|
177
|
+
const ctx = createMockContext();
|
|
178
|
+
ctx.connectionState = ConnectionState.connected;
|
|
179
|
+
ctx.store.pendingOutgoing.set(2, { type: PacketType.unsubscribe });
|
|
180
|
+
|
|
181
|
+
const packet = {
|
|
182
|
+
type: PacketType.unsuback,
|
|
183
|
+
protocolLevel: 4 as const,
|
|
184
|
+
id: 2,
|
|
185
|
+
} as AnyPacket;
|
|
186
|
+
|
|
187
|
+
await handlePacket(ctx as never, packet);
|
|
188
|
+
|
|
189
|
+
assert.deepStrictEqual(
|
|
190
|
+
ctx.receivedIds.unsuback,
|
|
191
|
+
[2],
|
|
192
|
+
"Should dispatch UNSUBACK to handler",
|
|
193
|
+
);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("handlePacket rejects unexpected packet types", async () => {
|
|
197
|
+
const ctx = createMockContext();
|
|
198
|
+
ctx.connectionState = ConnectionState.connected;
|
|
199
|
+
|
|
200
|
+
// CONNECT shouldn't be received by client after connection
|
|
201
|
+
const packet = {
|
|
202
|
+
type: PacketType.connect,
|
|
203
|
+
protocolName: "MQTT",
|
|
204
|
+
protocolLevel: 4 as const,
|
|
205
|
+
clientId: "test",
|
|
206
|
+
clean: true,
|
|
207
|
+
keepAlive: 0,
|
|
208
|
+
} as AnyPacket;
|
|
209
|
+
|
|
210
|
+
await assert.rejects(
|
|
211
|
+
handlePacket(ctx as never, packet),
|
|
212
|
+
/unexpected/i,
|
|
213
|
+
"Should reject unexpected packet types",
|
|
214
|
+
);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test("handlePacket handles QoS 2 flow packets", async () => {
|
|
218
|
+
const ctx = createMockContext();
|
|
219
|
+
ctx.connectionState = ConnectionState.connected;
|
|
220
|
+
|
|
221
|
+
// Test PUBREC
|
|
222
|
+
ctx.store.pendingOutgoing.set(10, { type: PacketType.publish, id: 10 });
|
|
223
|
+
await handlePacket(ctx as never, {
|
|
224
|
+
type: PacketType.pubrec,
|
|
225
|
+
protocolLevel: 4,
|
|
226
|
+
id: 10,
|
|
227
|
+
} as AnyPacket);
|
|
228
|
+
assert.deepStrictEqual(ctx.sentPackets.length, 1);
|
|
229
|
+
assert.deepStrictEqual(
|
|
230
|
+
(ctx.sentPackets[0] as { type: number }).type,
|
|
231
|
+
PacketType.pubrel,
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
// Test PUBCOMP
|
|
235
|
+
ctx.store.pendingAckOutgoing.set(10, { type: PacketType.pubrel, id: 10 });
|
|
236
|
+
await handlePacket(ctx as never, {
|
|
237
|
+
type: PacketType.pubcomp,
|
|
238
|
+
protocolLevel: 4,
|
|
239
|
+
id: 10,
|
|
240
|
+
} as AnyPacket);
|
|
241
|
+
assert.deepStrictEqual(ctx.receivedIds.pubcomp, [10]);
|
|
242
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Context } from "../context.ts";
|
|
2
2
|
import { ConnectionState } from "../ConnectionState.ts";
|
|
3
|
+
import { handleAuth } from "./handleAuth.ts";
|
|
3
4
|
import { handleConnack } from "./handleConnack.ts";
|
|
4
5
|
import { handlePublish } from "./handlePublish.ts";
|
|
5
6
|
import { handlePuback } from "./handlePuback.ts";
|
|
@@ -8,10 +9,13 @@ import { handlePubrel } from "./handlePubrel.ts";
|
|
|
8
9
|
import { handlePubcomp } from "./handlePubcomp.ts";
|
|
9
10
|
import { handleSuback } from "./handleSuback.ts";
|
|
10
11
|
import { handleUnsuback } from "./handleUnsuback.ts";
|
|
12
|
+
import { handleDisconnect } from "./handleDisconnect.ts";
|
|
11
13
|
import { logger, PacketNameByType, PacketType } from "../deps.ts";
|
|
12
14
|
import type {
|
|
13
15
|
AnyPacket,
|
|
16
|
+
AuthPacket,
|
|
14
17
|
ConnackPacket,
|
|
18
|
+
DisconnectPacket,
|
|
15
19
|
PubackPacket,
|
|
16
20
|
PubcompPacket,
|
|
17
21
|
PublishPacket,
|
|
@@ -35,14 +39,21 @@ export async function handlePacket(
|
|
|
35
39
|
logger.debug({ received: PacketNameByType[packet.type], packet });
|
|
36
40
|
if (ctx.connectionState !== ConnectionState.connected) {
|
|
37
41
|
if (packet.type === PacketType.connack) {
|
|
38
|
-
handleConnack(packet as ConnackPacket
|
|
39
|
-
|
|
40
|
-
throw new Error(
|
|
41
|
-
`Received ${PacketNameByType[packet.type]} packet before connect`,
|
|
42
|
-
);
|
|
42
|
+
handleConnack(ctx, packet as ConnackPacket);
|
|
43
|
+
return;
|
|
43
44
|
}
|
|
45
|
+
if (packet.type === PacketType.auth) {
|
|
46
|
+
await handleAuth(ctx, packet as AuthPacket);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Received ${PacketNameByType[packet.type]} packet while connecting`,
|
|
51
|
+
);
|
|
44
52
|
} else {
|
|
45
53
|
switch (packet.type) {
|
|
54
|
+
case PacketType.auth:
|
|
55
|
+
await handleAuth(ctx, packet as AuthPacket);
|
|
56
|
+
break;
|
|
46
57
|
case PacketType.pingres:
|
|
47
58
|
break;
|
|
48
59
|
case PacketType.publish:
|
|
@@ -66,6 +77,9 @@ export async function handlePacket(
|
|
|
66
77
|
case PacketType.unsuback:
|
|
67
78
|
handleUnsuback(ctx, packet as UnsubackPacket);
|
|
68
79
|
break;
|
|
80
|
+
case PacketType.disconnect:
|
|
81
|
+
handleDisconnect(ctx, packet as DisconnectPacket);
|
|
82
|
+
break;
|
|
69
83
|
|
|
70
84
|
default:
|
|
71
85
|
throw new Error(
|