@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
package/client/client.ts
CHANGED
|
@@ -4,21 +4,24 @@ import {
|
|
|
4
4
|
MemoryStore,
|
|
5
5
|
MQTTLevel,
|
|
6
6
|
PacketType,
|
|
7
|
+
ReasonCode,
|
|
7
8
|
} from "./deps.ts";
|
|
8
9
|
|
|
9
10
|
import type {
|
|
11
|
+
AuthenticationResult,
|
|
10
12
|
ConnectPacket,
|
|
13
|
+
ProtocolLevel,
|
|
11
14
|
PublishPacket,
|
|
12
15
|
SockConn,
|
|
16
|
+
Store,
|
|
13
17
|
SubscribePacket,
|
|
14
|
-
TAuthenticationResult,
|
|
15
18
|
} from "./deps.ts";
|
|
16
19
|
|
|
17
|
-
import { noop } from "../utils/
|
|
20
|
+
import { noop } from "../utils/mod.ts";
|
|
18
21
|
|
|
19
22
|
import { Context } from "./context.ts";
|
|
20
|
-
import type {
|
|
21
|
-
import {
|
|
23
|
+
import type { AuthenticatedResult } from "./context.ts";
|
|
24
|
+
import type { ConnectionState } from "./ConnectionState.ts";
|
|
22
25
|
import { BufferedAsyncIterable } from "./deps.ts";
|
|
23
26
|
|
|
24
27
|
/**
|
|
@@ -30,18 +33,25 @@ function generateClientId(prefix: string): string {
|
|
|
30
33
|
return `${prefix}-${Math.random().toString().slice(-10)}`;
|
|
31
34
|
}
|
|
32
35
|
|
|
33
|
-
type
|
|
36
|
+
/** All properties of a connect packet, except for type and protocol name */
|
|
37
|
+
export type ConnectOptions = Omit<
|
|
34
38
|
ConnectPacket,
|
|
35
39
|
"type" | "protocolName"
|
|
36
40
|
>;
|
|
37
41
|
|
|
38
42
|
/** ConnectParameters define how to connect */
|
|
39
43
|
export type ConnectParameters = {
|
|
44
|
+
/** the URL to connect to */
|
|
40
45
|
url?: URL | undefined;
|
|
46
|
+
/** any CA Certs to trust */
|
|
41
47
|
caCerts?: string[] | undefined;
|
|
48
|
+
/** the clients certificate */
|
|
42
49
|
cert?: string | undefined;
|
|
50
|
+
/** the clients private key*/
|
|
43
51
|
key?: string | undefined;
|
|
52
|
+
/** number of retries before stopping connection attempts */
|
|
44
53
|
numberOfRetries?: number | undefined;
|
|
54
|
+
/** connect options */
|
|
45
55
|
options?: ConnectOptions | undefined;
|
|
46
56
|
};
|
|
47
57
|
|
|
@@ -78,12 +88,26 @@ function backOffSleep(random: boolean, attempt: number): Promise<void> {
|
|
|
78
88
|
/** the default MQTT URL to connect to */
|
|
79
89
|
export const DEFAULT_URL = "mqtt://localhost:1883/";
|
|
80
90
|
/** the default protocol level to connect with*/
|
|
81
|
-
export const DEFAULT_PROTOCOLLEVEL = MQTTLevel.v4;
|
|
91
|
+
export const DEFAULT_PROTOCOLLEVEL = MQTTLevel.v4 as ProtocolLevel;
|
|
82
92
|
/** the default keepalive time */
|
|
83
93
|
export const DEFAULT_KEEPALIVE = 60; // 60 seconds
|
|
84
94
|
const DEFAULT_RETRIES = 3; // on first connect
|
|
85
95
|
const CLIENTID_PREFIX = "opifex"; // on first connect
|
|
86
96
|
|
|
97
|
+
// convert an ErrorEvent into an Error
|
|
98
|
+
// NodeJS does not know ErrorEvent
|
|
99
|
+
function normalizeError(err: unknown): Error {
|
|
100
|
+
if (typeof ErrorEvent !== "undefined" && err instanceof ErrorEvent) {
|
|
101
|
+
return new Error(err.message);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (err instanceof Error) {
|
|
105
|
+
return err;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
throw err;
|
|
109
|
+
}
|
|
110
|
+
|
|
87
111
|
/**
|
|
88
112
|
* The Client class provides an MQTT Client that can be used to connect to
|
|
89
113
|
* a MQTT broker and publish/subscribe messages.
|
|
@@ -94,59 +118,83 @@ const CLIENTID_PREFIX = "opifex"; // on first connect
|
|
|
94
118
|
* connection type that is supported by the subclass.
|
|
95
119
|
*/
|
|
96
120
|
export class Client {
|
|
121
|
+
public onAuth: (
|
|
122
|
+
authMethod: string,
|
|
123
|
+
authData: Uint8Array,
|
|
124
|
+
) => AuthenticatedResult = () => {
|
|
125
|
+
return {
|
|
126
|
+
reasonCode: ReasonCode.badAuthenticationMethod,
|
|
127
|
+
reasonString: "No authentication method configured",
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
/** callback for errors */
|
|
97
131
|
public onError: (err: Error) => void = noop;
|
|
132
|
+
/** callback for publish packets */
|
|
98
133
|
public onPacket: (pkt: PublishPacket) => void | Promise<void> = noop;
|
|
134
|
+
/** callback once connected */
|
|
99
135
|
public onConnected: () => void = noop;
|
|
136
|
+
/** callback once disconnected */
|
|
100
137
|
public onDisconnected: () => void = noop;
|
|
138
|
+
/** callback when reconnecting */
|
|
101
139
|
public onReconnecting: () => void = noop;
|
|
102
140
|
|
|
141
|
+
/** clientId prefix used when automatically generating a client Id */
|
|
103
142
|
protected clientIdPrefix = CLIENTID_PREFIX;
|
|
143
|
+
/** number of times to retry connect */
|
|
104
144
|
protected numberOfRetries = DEFAULT_RETRIES;
|
|
105
|
-
|
|
145
|
+
/** the URL to connect to */
|
|
146
|
+
protected connectUrl: URL = new URL(DEFAULT_URL);
|
|
147
|
+
/** the keepAlive value in number of seconds */
|
|
106
148
|
protected keepAlive = DEFAULT_KEEPALIVE;
|
|
149
|
+
/** the requested protocol level */
|
|
107
150
|
protected protocolLevel = DEFAULT_PROTOCOLLEVEL;
|
|
151
|
+
/** try auto reconnect if connection is lost */
|
|
108
152
|
protected autoReconnect = true;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
153
|
+
/** any CA Certs to trust */
|
|
154
|
+
protected caCerts?: string[] | undefined;
|
|
155
|
+
/** the clients certificate */
|
|
156
|
+
protected cert?: string | undefined;
|
|
157
|
+
/** the clients private key*/
|
|
158
|
+
protected key?: string | undefined;
|
|
159
|
+
/** the MQTT clientId */
|
|
160
|
+
protected clientId: string;
|
|
113
161
|
private ctx: Context;
|
|
114
162
|
private connectPacket?: ConnectPacket;
|
|
115
163
|
|
|
116
164
|
/**
|
|
117
165
|
* Creates a new MQTT client instance
|
|
118
166
|
*/
|
|
119
|
-
constructor() {
|
|
120
|
-
|
|
167
|
+
constructor(store?: Store) {
|
|
168
|
+
const cStore = store ? store : new MemoryStore();
|
|
169
|
+
this.ctx = new Context(cStore, this);
|
|
121
170
|
this.clientId = generateClientId(this.clientIdPrefix);
|
|
122
171
|
this.numberOfRetries = DEFAULT_RETRIES;
|
|
123
172
|
}
|
|
124
173
|
|
|
125
|
-
|
|
174
|
+
/**
|
|
175
|
+
* Current connection state
|
|
176
|
+
* @returns connectionState as ConnectionState
|
|
177
|
+
*/
|
|
178
|
+
public get connectionState(): ConnectionState {
|
|
126
179
|
return this.ctx.connectionState;
|
|
127
180
|
}
|
|
128
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Current configured connection URL
|
|
184
|
+
* @returns URL object
|
|
185
|
+
*/
|
|
186
|
+
public get url(): URL {
|
|
187
|
+
return this.connectUrl;
|
|
188
|
+
}
|
|
189
|
+
|
|
129
190
|
/**
|
|
130
191
|
* Creates a new connection to the MQTT broker
|
|
131
|
-
* @param protocol - The protocol to use (mqtt, mqtts, etc)
|
|
132
|
-
* @param _hostname - The hostname to connect to
|
|
133
|
-
* @param _port - The port to connect to
|
|
134
|
-
* @param _caCerts - Optional CA certificates
|
|
135
|
-
* @param _cert - Optional client certificate
|
|
136
|
-
* @param _key - Optional client key
|
|
137
192
|
* @returns Promise resolving to a SockConn connection
|
|
138
193
|
*/
|
|
139
|
-
protected createConn(
|
|
140
|
-
protocol: string,
|
|
141
|
-
_hostname: string,
|
|
142
|
-
_port?: number,
|
|
143
|
-
_caCerts?: string[],
|
|
144
|
-
_cert?: string,
|
|
145
|
-
_key?: string,
|
|
146
|
-
): Promise<SockConn> {
|
|
194
|
+
protected createConn(): Promise<SockConn> {
|
|
147
195
|
// if you need to support alternative connection types just
|
|
148
196
|
// overload this method in your subclass
|
|
149
|
-
throw new Error(`Unsupported protocol: ${protocol}`);
|
|
197
|
+
throw new Error(`Unsupported protocol: ${this.url.protocol}`);
|
|
150
198
|
}
|
|
151
199
|
|
|
152
200
|
/**
|
|
@@ -163,16 +211,12 @@ export class Client {
|
|
|
163
211
|
let lastMessage = new Error();
|
|
164
212
|
let tryConnect = true;
|
|
165
213
|
while (tryConnect) {
|
|
166
|
-
logger.debug(
|
|
214
|
+
logger.debug(
|
|
215
|
+
isReconnect ? "reconnecting, attempt" : "connecting, attempt",
|
|
216
|
+
attempt,
|
|
217
|
+
);
|
|
167
218
|
try {
|
|
168
|
-
const conn = await this.createConn(
|
|
169
|
-
this.url.protocol,
|
|
170
|
-
this.url.hostname,
|
|
171
|
-
Number(this.url.port) ?? undefined,
|
|
172
|
-
this.caCerts,
|
|
173
|
-
this.cert,
|
|
174
|
-
this.key,
|
|
175
|
-
);
|
|
219
|
+
const conn = await this.createConn();
|
|
176
220
|
// if we get this far we have a connection
|
|
177
221
|
tryConnect =
|
|
178
222
|
(await this.ctx.handleConnection(conn, this.connectPacket)) &&
|
|
@@ -182,12 +226,9 @@ export class Client {
|
|
|
182
226
|
this.connectPacket.clean = false;
|
|
183
227
|
this.ctx.close();
|
|
184
228
|
} catch (err) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
);
|
|
189
|
-
queueMicrotask(() => this.onError(err));
|
|
190
|
-
lastMessage = err;
|
|
229
|
+
const normalizedErr = normalizeError(err);
|
|
230
|
+
queueMicrotask(() => this.onError(normalizedErr));
|
|
231
|
+
lastMessage = normalizedErr;
|
|
191
232
|
logger.debug({ lastMessage });
|
|
192
233
|
}
|
|
193
234
|
|
|
@@ -212,8 +253,8 @@ export class Client {
|
|
|
212
253
|
* @param params - Connection parameters
|
|
213
254
|
* @returns Promise resolving to authentication result
|
|
214
255
|
*/
|
|
215
|
-
connect(params: ConnectParameters = {}): Promise<
|
|
216
|
-
this.
|
|
256
|
+
connect(params: ConnectParameters = {}): Promise<AuthenticationResult> {
|
|
257
|
+
this.connectUrl = params?.url || this.connectUrl;
|
|
217
258
|
this.numberOfRetries = params.numberOfRetries || this.numberOfRetries;
|
|
218
259
|
this.caCerts = params?.caCerts;
|
|
219
260
|
this.cert = params?.cert;
|
|
@@ -230,7 +271,7 @@ export class Client {
|
|
|
230
271
|
type: PacketType.connect,
|
|
231
272
|
...options,
|
|
232
273
|
};
|
|
233
|
-
const deferred = new Deferred<
|
|
274
|
+
const deferred = new Deferred<AuthenticationResult>();
|
|
234
275
|
this.ctx.unresolvedConnect = deferred;
|
|
235
276
|
this.doConnect();
|
|
236
277
|
return deferred.promise;
|
package/client/context.ts
CHANGED
|
@@ -8,37 +8,55 @@ import {
|
|
|
8
8
|
} from "./deps.ts";
|
|
9
9
|
import type {
|
|
10
10
|
AnyPacket,
|
|
11
|
+
AuthenticationResult,
|
|
11
12
|
ConnectPacket,
|
|
12
|
-
MemoryStore,
|
|
13
13
|
PacketId,
|
|
14
14
|
ProtocolLevel,
|
|
15
15
|
PublishPacket,
|
|
16
|
+
ReasonCode,
|
|
16
17
|
ReturnCodes,
|
|
17
18
|
SockConn,
|
|
19
|
+
Store,
|
|
18
20
|
SubscribePacket,
|
|
19
|
-
TAuthenticationResult,
|
|
20
21
|
UnsubscribePacket,
|
|
21
22
|
} from "./deps.ts";
|
|
22
23
|
|
|
23
24
|
import { handlePacket } from "./handlers/handlePacket.ts";
|
|
24
|
-
import type { TConnectionState } from "./ConnectionState.ts";
|
|
25
25
|
import { ConnectionState } from "./ConnectionState.ts";
|
|
26
26
|
import type { Client } from "./client.ts";
|
|
27
27
|
import { assert } from "../utils/assert.ts";
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* packets not allowed during authentication
|
|
31
|
+
*/
|
|
32
|
+
function blockedDuringAuthentication(pktType: PacketType) {
|
|
33
|
+
return (
|
|
34
|
+
pktType === PacketType.publish ||
|
|
35
|
+
pktType === PacketType.subscribe ||
|
|
36
|
+
pktType === PacketType.unsubscribe
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Possible results from authHandler */
|
|
41
|
+
export type AuthenticatedResult = {
|
|
42
|
+
reasonCode: ReasonCode;
|
|
43
|
+
reasonString?: string;
|
|
44
|
+
authData?: Uint8Array;
|
|
45
|
+
};
|
|
46
|
+
|
|
29
47
|
export class Context {
|
|
30
48
|
mqttConn?: MqttConn;
|
|
31
|
-
#connectionState:
|
|
49
|
+
#connectionState: ConnectionState;
|
|
32
50
|
protocolLevel: ProtocolLevel;
|
|
33
51
|
pingTimer?: Timer;
|
|
34
|
-
unresolvedConnect?: Deferred<
|
|
52
|
+
unresolvedConnect?: Deferred<AuthenticationResult>;
|
|
35
53
|
unresolvedPublish: Map<PacketId, Deferred<void>>;
|
|
36
54
|
unresolvedSubscribe: Map<PacketId, Deferred<ReturnCodes>>;
|
|
37
55
|
unresolvedUnSubscribe: Map<PacketId, Deferred<void>>;
|
|
38
|
-
store:
|
|
56
|
+
store: Store;
|
|
39
57
|
#client: Client;
|
|
40
58
|
|
|
41
|
-
constructor(store:
|
|
59
|
+
constructor(store: Store, client: Client) {
|
|
42
60
|
this.#client = client;
|
|
43
61
|
this.store = store;
|
|
44
62
|
this.#connectionState = ConnectionState.offline;
|
|
@@ -48,11 +66,11 @@ export class Context {
|
|
|
48
66
|
this.unresolvedUnSubscribe = new Map();
|
|
49
67
|
}
|
|
50
68
|
|
|
51
|
-
get connectionState():
|
|
69
|
+
get connectionState(): ConnectionState {
|
|
52
70
|
return this.#connectionState;
|
|
53
71
|
}
|
|
54
72
|
|
|
55
|
-
set connectionState(state:
|
|
73
|
+
set connectionState(state: ConnectionState) {
|
|
56
74
|
this.#connectionState = state;
|
|
57
75
|
switch (state) {
|
|
58
76
|
case "connected":
|
|
@@ -64,6 +82,25 @@ export class Context {
|
|
|
64
82
|
}
|
|
65
83
|
}
|
|
66
84
|
|
|
85
|
+
authHandler(
|
|
86
|
+
_ctx: Context,
|
|
87
|
+
authMethod: string,
|
|
88
|
+
authData: Uint8Array,
|
|
89
|
+
): AuthenticatedResult | Promise<AuthenticatedResult> {
|
|
90
|
+
return this.#client.onAuth(authMethod, authData);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
setPingTimer(interval: number) {
|
|
94
|
+
if (this.pingTimer) {
|
|
95
|
+
this.pingTimer.clear();
|
|
96
|
+
}
|
|
97
|
+
this.pingTimer = new Timer(
|
|
98
|
+
this.sendPing.bind(this),
|
|
99
|
+
interval * 1000,
|
|
100
|
+
true,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
67
104
|
async connect(packet: ConnectPacket) {
|
|
68
105
|
this.connectionState = ConnectionState.connecting;
|
|
69
106
|
if (packet.protocolLevel === MQTTLevel.unknown) {
|
|
@@ -73,16 +110,15 @@ export class Context {
|
|
|
73
110
|
await this.mqttConn?.send(packet);
|
|
74
111
|
const keepAlive = packet.keepAlive || 0;
|
|
75
112
|
if (keepAlive > 0) {
|
|
76
|
-
this.
|
|
77
|
-
this.sendPing.bind(this),
|
|
78
|
-
keepAlive * 1000,
|
|
79
|
-
true,
|
|
80
|
-
);
|
|
113
|
+
this.setPingTimer(keepAlive);
|
|
81
114
|
}
|
|
82
115
|
}
|
|
83
116
|
|
|
84
117
|
async disconnect() {
|
|
85
|
-
if (
|
|
118
|
+
if (
|
|
119
|
+
this.connectionState !== ConnectionState.connected &&
|
|
120
|
+
this.connectionState !== ConnectionState.authenticating
|
|
121
|
+
) {
|
|
86
122
|
throw "Not connected";
|
|
87
123
|
}
|
|
88
124
|
if (this.mqttConn) {
|
|
@@ -97,14 +133,29 @@ export class Context {
|
|
|
97
133
|
}
|
|
98
134
|
|
|
99
135
|
async send(packet: AnyPacket) {
|
|
100
|
-
logger.debug({
|
|
101
|
-
if (
|
|
102
|
-
this.connectionState === ConnectionState.connected
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
136
|
+
logger.debug("client.ctx.send", this.#connectionState, { packet });
|
|
137
|
+
if (!this.mqttConn?.isClosed) {
|
|
138
|
+
if (this.connectionState === ConnectionState.connected) {
|
|
139
|
+
await this.mqttConn?.send(packet);
|
|
140
|
+
this.pingTimer?.reset();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (
|
|
144
|
+
this.connectionState === ConnectionState.connecting &&
|
|
145
|
+
packet.type === PacketType.auth
|
|
146
|
+
) {
|
|
147
|
+
await this.mqttConn?.send(packet);
|
|
148
|
+
this.pingTimer?.reset();
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (
|
|
152
|
+
this.connectionState === ConnectionState.authenticating &&
|
|
153
|
+
!blockedDuringAuthentication(packet.type)
|
|
154
|
+
) {
|
|
155
|
+
await this.mqttConn?.send(packet);
|
|
156
|
+
this.pingTimer?.reset();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
108
159
|
}
|
|
109
160
|
logger.debug("not connected");
|
|
110
161
|
this.pingTimer?.clear();
|
|
@@ -122,6 +173,7 @@ export class Context {
|
|
|
122
173
|
connectPacket: ConnectPacket,
|
|
123
174
|
): Promise<boolean> {
|
|
124
175
|
this.mqttConn = new MqttConn({ conn });
|
|
176
|
+
this.mqttConn.codecOpts.protocolLevel = connectPacket.protocolLevel;
|
|
125
177
|
try {
|
|
126
178
|
logger.debug("Send connect packet", connectPacket);
|
|
127
179
|
await this.connect(connectPacket);
|
|
@@ -136,7 +188,7 @@ export class Context {
|
|
|
136
188
|
`Caught something that is not an instance of Error: ${err}`,
|
|
137
189
|
);
|
|
138
190
|
queueMicrotask(() => this.#client.onError(err));
|
|
139
|
-
logger.debug(
|
|
191
|
+
logger.debug("error", err);
|
|
140
192
|
if (!this.mqttConn.isClosed) {
|
|
141
193
|
this.mqttConn.close();
|
|
142
194
|
}
|
|
@@ -164,7 +216,7 @@ export class Context {
|
|
|
164
216
|
await this.send(packet);
|
|
165
217
|
return;
|
|
166
218
|
}
|
|
167
|
-
packet.id = this.store.nextId();
|
|
219
|
+
packet.id = await this.store.nextId();
|
|
168
220
|
this.store.pendingOutgoing.set(packet.id, packet);
|
|
169
221
|
const deferred = new Deferred<void>();
|
|
170
222
|
this.unresolvedPublish.set(packet.id, deferred);
|
|
@@ -173,7 +225,7 @@ export class Context {
|
|
|
173
225
|
}
|
|
174
226
|
|
|
175
227
|
async subscribe(packet: SubscribePacket): Promise<ReturnCodes> {
|
|
176
|
-
packet.id = this.store.nextId();
|
|
228
|
+
packet.id = await this.store.nextId();
|
|
177
229
|
this.store.pendingOutgoing.set(packet.id, packet);
|
|
178
230
|
const deferred = new Deferred<ReturnCodes>();
|
|
179
231
|
this.unresolvedSubscribe.set(packet.id, deferred);
|
|
@@ -182,7 +234,7 @@ export class Context {
|
|
|
182
234
|
}
|
|
183
235
|
|
|
184
236
|
async unsubscribe(packet: UnsubscribePacket): Promise<void> {
|
|
185
|
-
packet.id = this.store.nextId();
|
|
237
|
+
packet.id = await this.store.nextId();
|
|
186
238
|
this.store.pendingOutgoing.set(packet.id, packet);
|
|
187
239
|
const deferred = new Deferred<void>();
|
|
188
240
|
this.unresolvedUnSubscribe.set(packet.id, deferred);
|
package/client/deps.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type {
|
|
2
2
|
AnyPacket,
|
|
3
|
+
AuthPacket,
|
|
3
4
|
ConnackPacket,
|
|
4
5
|
ConnectPacket,
|
|
5
6
|
DisconnectPacket,
|
|
@@ -16,9 +17,7 @@ export type {
|
|
|
16
17
|
ReturnCodes,
|
|
17
18
|
SubackPacket,
|
|
18
19
|
SubscribePacket,
|
|
19
|
-
TAuthenticationResult,
|
|
20
20
|
Topic,
|
|
21
|
-
TReasonCode,
|
|
22
21
|
UnsubackPacket,
|
|
23
22
|
UnsubscribePacket,
|
|
24
23
|
} from "../mqttPacket/mod.ts";
|
|
@@ -31,11 +30,19 @@ export {
|
|
|
31
30
|
MQTTLevel,
|
|
32
31
|
PacketNameByType,
|
|
33
32
|
PacketType,
|
|
33
|
+
ReasonCode,
|
|
34
34
|
ReasonCodeByNumber,
|
|
35
35
|
} from "../mqttPacket/mod.ts";
|
|
36
36
|
|
|
37
37
|
export { MqttConn } from "../mqttConn/mqttConn.ts";
|
|
38
|
-
export type {
|
|
38
|
+
export type {
|
|
39
|
+
NetAddr,
|
|
40
|
+
SockAddr,
|
|
41
|
+
SockConn,
|
|
42
|
+
UnixAddr,
|
|
43
|
+
VsockAddr,
|
|
44
|
+
} from "../socket/socket.ts";
|
|
39
45
|
export { Timer } from "../timer/timer.ts";
|
|
40
46
|
export { BufferedAsyncIterable, Deferred, logger } from "../utils/mod.ts";
|
|
41
47
|
export { MemoryStore } from "./store/memoryStore.ts";
|
|
48
|
+
export type { Store } from "./store/store.ts";
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { handleAuth } from "./handleAuth.ts";
|
|
4
|
+
import { ConnectionState } from "../ConnectionState.ts";
|
|
5
|
+
import { PacketType, ReasonCode } from "../deps.ts";
|
|
6
|
+
import type { AuthPacket } from "../deps.ts";
|
|
7
|
+
import type { AuthenticatedResult } from "../context.ts";
|
|
8
|
+
import { Deferred } from "../../utils/mod.ts";
|
|
9
|
+
|
|
10
|
+
function createMockContext() {
|
|
11
|
+
const sentPackets: unknown[] = [];
|
|
12
|
+
return {
|
|
13
|
+
connectionState: ConnectionState.connecting as string,
|
|
14
|
+
pingTimer: { clear: () => {} },
|
|
15
|
+
unresolvedConnect: new Deferred<number>(),
|
|
16
|
+
authHandler: (
|
|
17
|
+
_ctx: unknown,
|
|
18
|
+
_authMethod: string,
|
|
19
|
+
_authData: Uint8Array,
|
|
20
|
+
): Promise<AuthenticatedResult> => {
|
|
21
|
+
return Promise.resolve({
|
|
22
|
+
reasonCode: ReasonCode.continueAuthentication,
|
|
23
|
+
authData: new Uint8Array([1, 2, 3]),
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
send: (packet: unknown) => {
|
|
27
|
+
sentPackets.push(packet);
|
|
28
|
+
},
|
|
29
|
+
sentPackets,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
test("handleAuth sets connected state on ReasonCode.success", async () => {
|
|
34
|
+
const ctx = createMockContext();
|
|
35
|
+
const packet: AuthPacket = {
|
|
36
|
+
type: PacketType.auth,
|
|
37
|
+
protocolLevel: 5 as const,
|
|
38
|
+
reasonCode: ReasonCode.success,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
await handleAuth(ctx as never, packet);
|
|
42
|
+
|
|
43
|
+
assert.deepStrictEqual(
|
|
44
|
+
ctx.connectionState,
|
|
45
|
+
ConnectionState.connected,
|
|
46
|
+
"Should set connection state to connected when reasonCode is success",
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("handleAuth handles authentication failure when connecting", async () => {
|
|
51
|
+
const ctx = createMockContext();
|
|
52
|
+
ctx.connectionState = ConnectionState.connecting;
|
|
53
|
+
|
|
54
|
+
const packet: AuthPacket = {
|
|
55
|
+
type: PacketType.auth,
|
|
56
|
+
protocolLevel: 5 as const,
|
|
57
|
+
reasonCode: ReasonCode.badAuthenticationMethod,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
await handleAuth(ctx as never, packet);
|
|
61
|
+
|
|
62
|
+
assert.deepStrictEqual(
|
|
63
|
+
ctx.connectionState,
|
|
64
|
+
ConnectionState.disconnecting,
|
|
65
|
+
"Should transition state to disconnecting on failure during connect",
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
await assert.rejects(
|
|
69
|
+
ctx.unresolvedConnect.promise,
|
|
70
|
+
/Connect failed/,
|
|
71
|
+
"Should reject unresolvedConnect with connect failed error",
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("handleAuth throws error on authentication failure when connected", async () => {
|
|
76
|
+
const ctx = createMockContext();
|
|
77
|
+
ctx.connectionState = ConnectionState.connected;
|
|
78
|
+
|
|
79
|
+
const packet: AuthPacket = {
|
|
80
|
+
type: PacketType.auth,
|
|
81
|
+
protocolLevel: 5 as const,
|
|
82
|
+
reasonCode: ReasonCode.badAuthenticationMethod,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
await assert.rejects(
|
|
86
|
+
async () => {
|
|
87
|
+
await handleAuth(ctx as never, packet);
|
|
88
|
+
},
|
|
89
|
+
Error,
|
|
90
|
+
"Should throw an error if reasonCode indicates failure after already connected",
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
test("handleAuth throws error if authMethod or authData is missing", async () => {
|
|
95
|
+
const ctx = createMockContext();
|
|
96
|
+
const packet: AuthPacket = {
|
|
97
|
+
type: PacketType.auth,
|
|
98
|
+
protocolLevel: 5 as const,
|
|
99
|
+
reasonCode: ReasonCode.continueAuthentication,
|
|
100
|
+
properties: {
|
|
101
|
+
authenticationMethod: "SCRAM-SHA-256",
|
|
102
|
+
// authenticationData missing
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
await assert.rejects(
|
|
107
|
+
async () => {
|
|
108
|
+
await handleAuth(ctx as never, packet);
|
|
109
|
+
},
|
|
110
|
+
/Auth method and\/or Auth data missing/,
|
|
111
|
+
"Should throw when missing required auth properties",
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("handleAuth transitions state and sends response packet on continueAuthentication success", async () => {
|
|
116
|
+
const ctx = createMockContext();
|
|
117
|
+
ctx.connectionState = ConnectionState.connected;
|
|
118
|
+
|
|
119
|
+
ctx.authHandler = () =>
|
|
120
|
+
Promise.resolve({
|
|
121
|
+
reasonCode: ReasonCode.continueAuthentication,
|
|
122
|
+
authData: new Uint8Array([4, 5, 6]),
|
|
123
|
+
reasonString: "Continue",
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const packet: AuthPacket = {
|
|
127
|
+
type: PacketType.auth,
|
|
128
|
+
protocolLevel: 5 as const,
|
|
129
|
+
reasonCode: ReasonCode.continueAuthentication,
|
|
130
|
+
properties: {
|
|
131
|
+
authenticationMethod: "SCRAM-SHA-256",
|
|
132
|
+
authenticationData: new Uint8Array([1, 2, 3]),
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
await handleAuth(ctx as never, packet);
|
|
137
|
+
|
|
138
|
+
assert.deepStrictEqual(
|
|
139
|
+
ctx.connectionState,
|
|
140
|
+
ConnectionState.authenticating,
|
|
141
|
+
"Should transition connection state to authenticating",
|
|
142
|
+
);
|
|
143
|
+
assert.deepStrictEqual(
|
|
144
|
+
ctx.sentPackets.length,
|
|
145
|
+
1,
|
|
146
|
+
"Should send a response auth packet",
|
|
147
|
+
);
|
|
148
|
+
assert.deepStrictEqual(ctx.sentPackets[0], {
|
|
149
|
+
type: PacketType.auth,
|
|
150
|
+
protocolLevel: 5,
|
|
151
|
+
reasonCode: ReasonCode.continueAuthentication,
|
|
152
|
+
properties: {
|
|
153
|
+
authenticationMethod: "SCRAM-SHA-256",
|
|
154
|
+
authenticationData: new Uint8Array([4, 5, 6]),
|
|
155
|
+
reasonString: "Continue",
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("handleAuth handles failure result from authHandler", async () => {
|
|
161
|
+
const ctx = createMockContext();
|
|
162
|
+
ctx.connectionState = ConnectionState.connecting;
|
|
163
|
+
|
|
164
|
+
ctx.authHandler = () =>
|
|
165
|
+
Promise.resolve({
|
|
166
|
+
reasonCode: ReasonCode.notAuthorized,
|
|
167
|
+
reasonString: "Not authorized to proceed",
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const packet: AuthPacket = {
|
|
171
|
+
type: PacketType.auth,
|
|
172
|
+
protocolLevel: 5 as const,
|
|
173
|
+
reasonCode: ReasonCode.continueAuthentication,
|
|
174
|
+
properties: {
|
|
175
|
+
authenticationMethod: "SCRAM-SHA-256",
|
|
176
|
+
authenticationData: new Uint8Array([1, 2, 3]),
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
await handleAuth(ctx as never, packet);
|
|
181
|
+
|
|
182
|
+
assert.deepStrictEqual(
|
|
183
|
+
ctx.connectionState,
|
|
184
|
+
ConnectionState.disconnecting,
|
|
185
|
+
"Should set state to disconnecting on authHandler failure",
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
await assert.rejects(
|
|
189
|
+
ctx.unresolvedConnect.promise,
|
|
190
|
+
/Connect failed: Not authorized to proceed/,
|
|
191
|
+
"Should reject unresolvedConnect with the reasonString provided by authHandler",
|
|
192
|
+
);
|
|
193
|
+
});
|