@seriousme/opifex 1.11.2 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +1 -1
- package/README.md +102 -43
- package/bin/conformanceServer.ts +45 -13
- package/bin/demoServer.ts +38 -13
- package/bin/mqtt.ts +52 -30
- package/client/ConnectionState.ts +2 -0
- package/client/client.ts +57 -47
- package/client/context.ts +75 -21
- package/client/deps.ts +5 -0
- package/client/handlers/handleAuth.test.ts +193 -0
- package/client/handlers/handleAuth.ts +89 -0
- package/client/handlers/handleConnack.test.ts +173 -0
- package/client/handlers/handleConnack.ts +16 -6
- package/client/handlers/handleDisconnect.test.ts +22 -0
- package/client/handlers/handleDisconnect.ts +17 -0
- package/client/handlers/handlePacket.test.ts +242 -0
- package/client/handlers/handlePacket.ts +19 -5
- package/client/handlers/handlePuback.test.ts +99 -0
- package/client/handlers/handlePuback.ts +6 -0
- package/client/handlers/handlePubcomp.test.ts +112 -0
- package/client/handlers/handlePubcomp.ts +5 -0
- package/client/handlers/handlePublish.test.ts +188 -0
- package/client/handlers/handlePubrec.test.ts +119 -0
- package/client/handlers/handlePubrec.ts +5 -1
- package/client/handlers/handlePubrel.test.ts +136 -0
- package/client/handlers/handleSuback.test.ts +122 -0
- package/client/handlers/handleSuback.ts +3 -0
- package/client/handlers/handleUnsuback.test.ts +101 -0
- package/client/mod.ts +2 -2
- package/client/store/memoryStore.ts +2 -2
- package/client/store/store.ts +3 -1
- package/deno/README.md +1 -2
- package/deno/tcpClient.test.ts +75 -0
- package/deno/tcpClient.ts +16 -11
- package/deno/tcpServer.test.ts +22 -21
- package/deno/tcpServer.ts +5 -0
- package/deno/tlsServer.test.ts +97 -0
- package/deno/tlsServer.ts +42 -0
- package/deno/wsServer.test.ts +93 -0
- package/deno/wsServer.ts +73 -0
- package/dev_utils/generateCert.ts +95 -0
- package/dev_utils/mockConn.ts +36 -0
- package/dev_utils/mockServer.ts +28 -0
- package/dev_utils/mod.ts +30 -2
- package/dev_utils/packetHelpers.ts +404 -0
- package/dev_utils/test-handlers.ts +98 -0
- package/dev_utils/timers.ts +14 -0
- package/dev_utils/webStreamPair.test.ts +171 -0
- package/dev_utils/webStreamPair.ts +143 -0
- package/dist/bin/conformanceServer.js +17 -12
- package/dist/bin/conformanceServer.js.map +1 -1
- package/dist/bin/demoServer.js +16 -12
- package/dist/bin/demoServer.js.map +1 -1
- package/dist/bin/mqtt.js +19 -16
- package/dist/bin/mqtt.js.map +1 -1
- package/dist/client/ConnectionState.d.ts +2 -0
- package/dist/client/ConnectionState.d.ts.map +1 -1
- package/dist/client/ConnectionState.js +2 -0
- package/dist/client/ConnectionState.js.map +1 -1
- package/dist/client/client.d.ts +19 -22
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +34 -20
- package/dist/client/client.js.map +1 -1
- package/dist/client/context.d.ts +11 -3
- package/dist/client/context.d.ts.map +1 -1
- package/dist/client/context.js +44 -12
- package/dist/client/context.js.map +1 -1
- package/dist/client/deps.d.ts +3 -2
- package/dist/client/deps.d.ts.map +1 -1
- package/dist/client/deps.js +1 -1
- package/dist/client/deps.js.map +1 -1
- package/dist/client/handlers/handleAuth.d.ts +9 -0
- package/dist/client/handlers/handleAuth.d.ts.map +1 -0
- package/dist/client/handlers/handleAuth.js +66 -0
- package/dist/client/handlers/handleAuth.js.map +1 -0
- package/dist/client/handlers/handleConnack.d.ts +2 -2
- package/dist/client/handlers/handleConnack.d.ts.map +1 -1
- package/dist/client/handlers/handleConnack.js +16 -6
- package/dist/client/handlers/handleConnack.js.map +1 -1
- package/dist/client/handlers/handleDisconnect.d.ts +11 -0
- package/dist/client/handlers/handleDisconnect.d.ts.map +1 -0
- package/dist/client/handlers/handleDisconnect.js +15 -0
- package/dist/client/handlers/handleDisconnect.js.map +1 -0
- package/dist/client/handlers/handlePacket.d.ts.map +1 -1
- package/dist/client/handlers/handlePacket.js +14 -3
- package/dist/client/handlers/handlePacket.js.map +1 -1
- package/dist/client/handlers/handlePuback.d.ts.map +1 -1
- package/dist/client/handlers/handlePuback.js +5 -0
- package/dist/client/handlers/handlePuback.js.map +1 -1
- package/dist/client/handlers/handlePubcomp.d.ts.map +1 -1
- package/dist/client/handlers/handlePubcomp.js +5 -0
- package/dist/client/handlers/handlePubcomp.js.map +1 -1
- package/dist/client/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/client/handlers/handlePubrec.js +5 -1
- package/dist/client/handlers/handlePubrec.js.map +1 -1
- package/dist/client/handlers/handleSuback.d.ts +1 -0
- package/dist/client/handlers/handleSuback.d.ts.map +1 -1
- package/dist/client/handlers/handleSuback.js +3 -0
- package/dist/client/handlers/handleSuback.js.map +1 -1
- package/dist/client/mod.d.ts +2 -2
- package/dist/client/mod.d.ts.map +1 -1
- package/dist/client/mod.js +1 -1
- package/dist/client/mod.js.map +1 -1
- package/dist/client/store/memoryStore.d.ts.map +1 -1
- package/dist/client/store/memoryStore.js +2 -2
- package/dist/client/store/memoryStore.js.map +1 -1
- package/dist/client/store/store.d.ts +2 -1
- package/dist/client/store/store.d.ts.map +1 -1
- package/dist/client/store/store.js +1 -1
- package/dist/client/store/store.js.map +1 -1
- package/dist/dev_utils/generateCert.d.ts +11 -0
- package/dist/dev_utils/generateCert.d.ts.map +1 -0
- package/dist/dev_utils/generateCert.js +76 -0
- package/dist/dev_utils/generateCert.js.map +1 -0
- package/dist/examples/authHandler.test.d.ts +2 -0
- package/dist/examples/authHandler.test.d.ts.map +1 -0
- package/dist/examples/authHandler.test.js +123 -0
- package/dist/examples/authHandler.test.js.map +1 -0
- package/dist/examples/mqtt.test.d.ts +2 -0
- package/dist/examples/mqtt.test.d.ts.map +1 -0
- package/dist/examples/mqtt.test.js +70 -0
- package/dist/examples/mqtt.test.js.map +1 -0
- package/dist/examples/mqtts.test.d.ts +2 -0
- package/dist/examples/mqtts.test.d.ts.map +1 -0
- package/dist/examples/mqtts.test.js +81 -0
- package/dist/examples/mqtts.test.js.map +1 -0
- package/dist/mqttConn/mqttConn.d.ts +25 -16
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +69 -40
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts +12 -11
- package/dist/mqttPacket/BitMask.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.js +10 -18
- package/dist/mqttPacket/BitMask.js.map +1 -1
- package/dist/mqttPacket/PacketType.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.d.ts +2 -2
- package/dist/mqttPacket/Properties.d.ts.map +1 -1
- package/dist/mqttPacket/Properties.js.map +1 -1
- package/dist/mqttPacket/ReasonCode.d.ts +1 -0
- package/dist/mqttPacket/ReasonCode.d.ts.map +1 -1
- package/dist/mqttPacket/ReasonCode.js +1 -0
- package/dist/mqttPacket/ReasonCode.js.map +1 -1
- package/dist/mqttPacket/RetainHandling.d.ts.map +1 -1
- package/dist/mqttPacket/auth.d.ts +3 -5
- package/dist/mqttPacket/auth.d.ts.map +1 -1
- package/dist/mqttPacket/auth.js +31 -30
- package/dist/mqttPacket/auth.js.map +1 -1
- package/dist/mqttPacket/codec.d.ts +48 -0
- package/dist/mqttPacket/codec.d.ts.map +1 -0
- package/dist/mqttPacket/codec.js +93 -0
- package/dist/mqttPacket/codec.js.map +1 -0
- package/dist/mqttPacket/connack.d.ts +4 -5
- package/dist/mqttPacket/connack.d.ts.map +1 -1
- package/dist/mqttPacket/connack.js +43 -45
- package/dist/mqttPacket/connack.js.map +1 -1
- package/dist/mqttPacket/connect.d.ts +26 -27
- package/dist/mqttPacket/connect.d.ts.map +1 -1
- package/dist/mqttPacket/connect.js +156 -157
- package/dist/mqttPacket/connect.js.map +1 -1
- package/dist/mqttPacket/decoder.d.ts +1 -13
- package/dist/mqttPacket/decoder.d.ts.map +1 -1
- package/dist/mqttPacket/decoder.js +7 -28
- package/dist/mqttPacket/decoder.js.map +1 -1
- package/dist/mqttPacket/disconnect.d.ts +4 -5
- package/dist/mqttPacket/disconnect.d.ts.map +1 -1
- package/dist/mqttPacket/disconnect.js +41 -43
- package/dist/mqttPacket/disconnect.js.map +1 -1
- package/dist/mqttPacket/encoder.d.ts +1 -15
- package/dist/mqttPacket/encoder.d.ts.map +1 -1
- package/dist/mqttPacket/encoder.js +4 -27
- package/dist/mqttPacket/encoder.js.map +1 -1
- package/dist/mqttPacket/length.js +1 -1
- package/dist/mqttPacket/length.js.map +1 -1
- package/dist/mqttPacket/mod.d.ts +21 -103
- package/dist/mqttPacket/mod.d.ts.map +1 -1
- package/dist/mqttPacket/mod.js +5 -94
- package/dist/mqttPacket/mod.js.map +1 -1
- package/dist/mqttPacket/pingreq.d.ts +4 -5
- package/dist/mqttPacket/pingreq.d.ts.map +1 -1
- package/dist/mqttPacket/pingreq.js +11 -13
- package/dist/mqttPacket/pingreq.js.map +1 -1
- package/dist/mqttPacket/pingres.d.ts +4 -5
- package/dist/mqttPacket/pingres.d.ts.map +1 -1
- package/dist/mqttPacket/pingres.js +11 -13
- package/dist/mqttPacket/pingres.js.map +1 -1
- package/dist/mqttPacket/protocolLevels.d.ts +11 -6
- package/dist/mqttPacket/protocolLevels.d.ts.map +1 -1
- package/dist/mqttPacket/protocolLevels.js +5 -1
- package/dist/mqttPacket/protocolLevels.js.map +1 -1
- package/dist/mqttPacket/pubblishAcks.d.ts +9 -10
- package/dist/mqttPacket/pubblishAcks.d.ts.map +1 -1
- package/dist/mqttPacket/pubblishAcks.js +43 -45
- package/dist/mqttPacket/pubblishAcks.js.map +1 -1
- package/dist/mqttPacket/publish.d.ts +14 -14
- package/dist/mqttPacket/publish.d.ts.map +1 -1
- package/dist/mqttPacket/publish.js +53 -55
- package/dist/mqttPacket/publish.js.map +1 -1
- package/dist/mqttPacket/suback.d.ts +4 -5
- package/dist/mqttPacket/suback.d.ts.map +1 -1
- package/dist/mqttPacket/suback.js +38 -40
- package/dist/mqttPacket/suback.js.map +1 -1
- package/dist/mqttPacket/subscribe.d.ts +36 -7
- package/dist/mqttPacket/subscribe.d.ts.map +1 -1
- package/dist/mqttPacket/subscribe.js +90 -89
- package/dist/mqttPacket/subscribe.js.map +1 -1
- package/dist/mqttPacket/types.d.ts +1 -8
- package/dist/mqttPacket/types.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.d.ts +4 -5
- package/dist/mqttPacket/unsuback.d.ts.map +1 -1
- package/dist/mqttPacket/unsuback.js +32 -34
- package/dist/mqttPacket/unsuback.js.map +1 -1
- package/dist/mqttPacket/unsubscribe.d.ts +23 -6
- package/dist/mqttPacket/unsubscribe.d.ts.map +1 -1
- package/dist/mqttPacket/unsubscribe.js +45 -44
- package/dist/mqttPacket/unsubscribe.js.map +1 -1
- package/dist/mqttPacket/validators.d.ts +4 -16
- package/dist/mqttPacket/validators.d.ts.map +1 -1
- package/dist/mqttPacket/validators.js +5 -26
- package/dist/mqttPacket/validators.js.map +1 -1
- package/dist/node/tcpClient.d.ts +1 -1
- package/dist/node/tcpClient.d.ts.map +1 -1
- package/dist/node/tcpClient.js +12 -7
- package/dist/node/tcpClient.js.map +1 -1
- package/dist/node/tcpServer.d.ts.map +1 -1
- package/dist/node/tcpServer.js +4 -0
- package/dist/node/tcpServer.js.map +1 -1
- package/dist/node/tlsServer.d.ts +19 -0
- package/dist/node/tlsServer.d.ts.map +1 -0
- package/dist/node/tlsServer.js +58 -0
- package/dist/node/tlsServer.js.map +1 -0
- package/dist/node/wrapNodeSocket.d.ts.map +1 -1
- package/dist/node/wrapNodeSocket.js +6 -28
- package/dist/node/wrapNodeSocket.js.map +1 -1
- package/dist/persistence/basicPersistence.d.ts +36 -0
- package/dist/persistence/basicPersistence.d.ts.map +1 -0
- package/dist/persistence/basicPersistence.js +306 -0
- package/dist/persistence/basicPersistence.js.map +1 -0
- package/dist/persistence/deps.d.ts +3 -2
- package/dist/persistence/deps.d.ts.map +1 -1
- package/dist/persistence/deps.js +2 -1
- package/dist/persistence/deps.js.map +1 -1
- package/dist/persistence/memory/memoryPersistence.d.ts +6 -23
- package/dist/persistence/memory/memoryPersistence.d.ts.map +1 -1
- package/dist/persistence/memory/memoryPersistence.js +12 -115
- package/dist/persistence/memory/memoryPersistence.js.map +1 -1
- package/dist/persistence/memory/memoryStorage.d.ts +45 -0
- package/dist/persistence/memory/memoryStorage.d.ts.map +1 -0
- package/dist/persistence/memory/memoryStorage.js +143 -0
- package/dist/persistence/memory/memoryStorage.js.map +1 -0
- package/dist/persistence/mod.d.ts +3 -3
- package/dist/persistence/mod.d.ts.map +1 -1
- package/dist/persistence/mod.js +6 -1
- package/dist/persistence/mod.js.map +1 -1
- package/dist/persistence/persistence.d.ts +44 -69
- package/dist/persistence/persistence.d.ts.map +1 -1
- package/dist/persistence/persistence.js +1 -2
- package/dist/persistence/persistence.js.map +1 -1
- package/dist/persistence/sqlite/sqliteDatabase.d.ts +46 -0
- package/dist/persistence/sqlite/sqliteDatabase.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqliteDatabase.js +215 -0
- package/dist/persistence/sqlite/sqliteDatabase.js.map +1 -0
- package/dist/persistence/sqlite/sqlitePersistence.d.ts +16 -0
- package/dist/persistence/sqlite/sqlitePersistence.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqlitePersistence.js +29 -0
- package/dist/persistence/sqlite/sqlitePersistence.js.map +1 -0
- package/dist/persistence/sqlite/sqliteStorage.d.ts +36 -0
- package/dist/persistence/sqlite/sqliteStorage.d.ts.map +1 -0
- package/dist/persistence/sqlite/sqliteStorage.js +194 -0
- package/dist/persistence/sqlite/sqliteStorage.js.map +1 -0
- package/dist/persistence/storage.d.ts +38 -0
- package/dist/persistence/storage.d.ts.map +1 -0
- package/dist/persistence/storage.js +5 -0
- package/dist/persistence/storage.js.map +1 -0
- package/dist/server/config.d.ts +47 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +41 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/context.d.ts +198 -24
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +432 -53
- package/dist/server/context.js.map +1 -1
- package/dist/server/deps.d.ts +5 -6
- package/dist/server/deps.d.ts.map +1 -1
- package/dist/server/deps.js +2 -2
- package/dist/server/deps.js.map +1 -1
- package/dist/server/handlers/completeConnect.d.ts +8 -0
- package/dist/server/handlers/completeConnect.d.ts.map +1 -0
- package/dist/server/handlers/completeConnect.js +74 -0
- package/dist/server/handlers/completeConnect.js.map +1 -0
- package/dist/server/handlers/handleAuth.d.ts +9 -0
- package/dist/server/handlers/handleAuth.d.ts.map +1 -0
- package/dist/server/handlers/handleAuth.js +69 -0
- package/dist/server/handlers/handleAuth.js.map +1 -0
- package/dist/server/handlers/handleConnect.d.ts +2 -4
- package/dist/server/handlers/handleConnect.d.ts.map +1 -1
- package/dist/server/handlers/handleConnect.js +140 -67
- package/dist/server/handlers/handleConnect.js.map +1 -1
- package/dist/server/handlers/handleDisconnect.d.ts +1 -1
- package/dist/server/handlers/handleDisconnect.d.ts.map +1 -1
- package/dist/server/handlers/handleDisconnect.js +3 -3
- package/dist/server/handlers/handleDisconnect.js.map +1 -1
- package/dist/server/handlers/handlePacket.d.ts.map +1 -1
- package/dist/server/handlers/handlePacket.js +19 -6
- package/dist/server/handlers/handlePacket.js.map +1 -1
- package/dist/server/handlers/handlePuback.d.ts +1 -3
- package/dist/server/handlers/handlePuback.d.ts.map +1 -1
- package/dist/server/handlers/handlePuback.js +2 -8
- package/dist/server/handlers/handlePuback.js.map +1 -1
- package/dist/server/handlers/handlePubcomp.d.ts +1 -1
- package/dist/server/handlers/handlePubcomp.d.ts.map +1 -1
- package/dist/server/handlers/handlePubcomp.js +2 -4
- package/dist/server/handlers/handlePubcomp.js.map +1 -1
- package/dist/server/handlers/handlePublish.d.ts +1 -1
- package/dist/server/handlers/handlePublish.d.ts.map +1 -1
- package/dist/server/handlers/handlePublish.js +149 -45
- package/dist/server/handlers/handlePublish.js.map +1 -1
- package/dist/server/handlers/handlePubrec.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrec.js +2 -3
- package/dist/server/handlers/handlePubrec.js.map +1 -1
- package/dist/server/handlers/handlePubrel.d.ts.map +1 -1
- package/dist/server/handlers/handlePubrel.js +6 -2
- package/dist/server/handlers/handlePubrel.js.map +1 -1
- package/dist/server/handlers/handleSubscribe.d.ts +1 -6
- package/dist/server/handlers/handleSubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleSubscribe.js +99 -38
- package/dist/server/handlers/handleSubscribe.js.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.d.ts.map +1 -1
- package/dist/server/handlers/handleUnsubscribe.js +19 -4
- package/dist/server/handlers/handleUnsubscribe.js.map +1 -1
- package/dist/server/mod.d.ts +3 -3
- package/dist/server/mod.d.ts.map +1 -1
- package/dist/server/mod.js +1 -1
- package/dist/server/mod.js.map +1 -1
- package/dist/server/server.d.ts +29 -6
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +84 -15
- package/dist/server/server.js.map +1 -1
- package/dist/socket/socket.d.ts +11 -9
- package/dist/socket/socket.d.ts.map +1 -1
- package/dist/socket/socket.js +67 -15
- package/dist/socket/socket.js.map +1 -1
- package/dist/timer/timer.d.ts +32 -0
- package/dist/timer/timer.d.ts.map +1 -1
- package/dist/timer/timer.js +32 -0
- package/dist/timer/timer.js.map +1 -1
- package/dist/trie/trie.d.ts +10 -5
- package/dist/trie/trie.d.ts.map +1 -1
- package/dist/trie/trie.js +47 -17
- package/dist/trie/trie.js.map +1 -1
- package/dist/utils/assert.d.ts.map +1 -1
- package/dist/utils/{BufferedAsyncIterable.d.ts → bufferedAsyncIterable.d.ts} +1 -1
- package/dist/utils/bufferedAsyncIterable.d.ts.map +1 -0
- package/dist/utils/{BufferedAsyncIterable.js → bufferedAsyncIterable.js} +1 -1
- package/dist/utils/bufferedAsyncIterable.js.map +1 -0
- package/dist/utils/deferred.d.ts.map +1 -1
- package/dist/utils/deferred.js.map +1 -1
- package/dist/utils/getOrInsertPolyFill.d.ts +2 -0
- package/dist/utils/getOrInsertPolyFill.d.ts.map +1 -0
- package/dist/utils/getOrInsertPolyFill.js +12 -0
- package/dist/utils/getOrInsertPolyFill.js.map +1 -0
- package/dist/utils/logger.d.ts +40 -3
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +53 -7
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/mod.d.ts +6 -1
- package/dist/utils/mod.d.ts.map +1 -1
- package/dist/utils/mod.js +5 -1
- package/dist/utils/mod.js.map +1 -1
- package/dist/utils/outboundTopicAliasManager.d.ts +52 -0
- package/dist/utils/outboundTopicAliasManager.d.ts.map +1 -0
- package/dist/utils/outboundTopicAliasManager.js +74 -0
- package/dist/utils/outboundTopicAliasManager.js.map +1 -0
- package/dist/utils/queue.d.ts.map +1 -1
- package/dist/utils/topicFilter.d.ts +32 -0
- package/dist/utils/topicFilter.d.ts.map +1 -0
- package/dist/utils/topicFilter.js +52 -0
- package/dist/utils/topicFilter.js.map +1 -0
- package/dist/utils/utils.d.ts +2 -0
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +2 -0
- package/dist/utils/utils.js.map +1 -1
- package/dist/utils/validators.d.ts +34 -0
- package/dist/utils/validators.d.ts.map +1 -0
- package/dist/utils/validators.js +61 -0
- package/dist/utils/validators.js.map +1 -0
- package/dist/web/webSocketStream.d.ts +29 -0
- package/dist/web/webSocketStream.d.ts.map +1 -0
- package/dist/web/webSocketStream.js +69 -0
- package/dist/web/webSocketStream.js.map +1 -0
- package/dist/web/wrapWebSocket.d.ts +12 -0
- package/dist/web/wrapWebSocket.d.ts.map +1 -0
- package/dist/web/wrapWebSocket.js +41 -0
- package/dist/web/wrapWebSocket.js.map +1 -0
- package/dist/web/wsClient.d.ts +7 -0
- package/dist/web/wsClient.d.ts.map +1 -0
- package/dist/web/wsClient.js +22 -0
- package/dist/web/wsClient.js.map +1 -0
- package/dist/web/wsClient.test.d.ts +2 -0
- package/dist/web/wsClient.test.d.ts.map +1 -0
- package/dist/web/wsClient.test.js +20 -0
- package/dist/web/wsClient.test.js.map +1 -0
- package/examples/authHandler.test.ts +164 -0
- package/examples/mqtt.test.ts +89 -0
- package/examples/mqtts.test.ts +100 -0
- package/examples/webSocket.test.ts +94 -0
- package/mqttConn/mqttConn.test.ts +9 -9
- package/mqttConn/mqttConn.ts +91 -49
- package/mqttPacket/BitMask.ts +11 -19
- package/mqttPacket/Properties.ts +6 -3
- package/mqttPacket/ReasonCode.ts +2 -1
- package/mqttPacket/auth.test.ts +1 -1
- package/mqttPacket/auth.ts +41 -48
- package/mqttPacket/codec.ts +146 -0
- package/mqttPacket/connack.ts +57 -68
- package/mqttPacket/connect.test.ts +2 -2
- package/mqttPacket/connect.ts +197 -204
- package/mqttPacket/decoder.test.ts +0 -39
- package/mqttPacket/decoder.ts +9 -36
- package/mqttPacket/disconnect.ts +57 -68
- package/mqttPacket/encoder.ts +5 -40
- package/mqttPacket/length.ts +1 -1
- package/mqttPacket/mod.ts +48 -200
- package/mqttPacket/pingreq.ts +21 -27
- package/mqttPacket/pingres.ts +21 -27
- package/mqttPacket/protocolLevels.ts +12 -7
- package/mqttPacket/pubblishAcks.ts +68 -77
- package/mqttPacket/publish.ts +76 -83
- package/mqttPacket/suback.ts +48 -58
- package/mqttPacket/subscribe.ts +141 -117
- package/mqttPacket/types.ts +1 -9
- package/mqttPacket/unsuback.ts +46 -58
- package/mqttPacket/unsubscribe.ts +74 -63
- package/mqttPacket/validators.ts +5 -31
- package/node/socket-node-stream.test.ts +322 -0
- package/node/socket-node-stream.ts +174 -0
- package/node/tcpClient.test.ts +70 -0
- package/node/tcpClient.ts +13 -12
- package/node/tcpServer.test.ts +24 -20
- package/node/tcpServer.ts +6 -0
- package/node/tlsServer.test.ts +94 -0
- package/node/tlsServer.ts +81 -0
- package/node/wrapNodeSocket.ts +7 -30
- package/package.json +73 -45
- package/persistence/basicPersistence.ts +495 -0
- package/persistence/deps.ts +11 -1
- package/persistence/memory/memoryPersistence.ts +12 -152
- package/persistence/memory/memoryStorage.ts +232 -0
- package/persistence/mod.ts +4 -4
- package/persistence/persistence.test.ts +24 -0
- package/persistence/persistence.testing.ts +1324 -0
- package/persistence/persistence.ts +111 -67
- package/persistence/sqlite/sqliteDatabase.ts +294 -0
- package/persistence/sqlite/sqlitePersistence.test.ts +48 -0
- package/persistence/sqlite/sqlitePersistence.ts +36 -0
- package/persistence/sqlite/sqliteStorage.ts +324 -0
- package/persistence/storage.ts +84 -0
- package/server/config.ts +65 -0
- package/server/context.ts +658 -74
- package/server/deps.ts +25 -5
- package/server/handlers/completeConnect.ts +93 -0
- package/server/handlers/duplicate.test.ts +196 -0
- package/server/handlers/handleAuth.test.ts +225 -0
- package/server/handlers/handleAuth.ts +88 -0
- package/server/handlers/handleConnect.test.ts +589 -0
- package/server/handlers/handleConnect.ts +201 -86
- package/server/handlers/handleConnect.version.test.ts +108 -0
- package/server/handlers/handleDisconnect.test.ts +56 -0
- package/server/handlers/handleDisconnect.ts +3 -3
- package/server/handlers/handlePacket.test.ts +24 -0
- package/server/handlers/handlePacket.ts +30 -8
- package/server/handlers/handlePingreq.test.ts +29 -0
- package/server/handlers/handlePuback.test.ts +28 -0
- package/server/handlers/handlePuback.ts +5 -8
- package/server/handlers/handlePubcomp.test.ts +28 -0
- package/server/handlers/handlePubcomp.ts +5 -4
- package/server/handlers/handlePublish.test.ts +471 -0
- package/server/handlers/handlePublish.ts +189 -35
- package/server/handlers/handlePubrec.test.ts +28 -0
- package/server/handlers/handlePubrec.ts +2 -3
- package/server/handlers/handlePubrel.test.ts +74 -0
- package/server/handlers/handlePubrel.ts +12 -2
- package/server/handlers/handleSubscribe.test.ts +971 -0
- package/server/handlers/handleSubscribe.ts +158 -39
- package/server/handlers/handleUnsubscribe.test.ts +79 -0
- package/server/handlers/handleUnsubscribe.ts +29 -5
- package/server/handlers/keepalive.test.ts +132 -0
- package/server/handlers/session.persistence.test.ts +194 -0
- package/server/handlers/will.delivery.test.ts +221 -0
- package/server/mod.ts +4 -3
- package/server/preconnect.test.ts +151 -0
- package/server/server.ts +115 -17
- package/socket/socket.test.ts +91 -0
- package/socket/socket.ts +81 -31
- package/timer/timer.test.ts +4 -7
- package/timer/timer.ts +36 -0
- package/tools/benchmarks/receiver.ts +51 -0
- package/tools/benchmarks/sender.ts +48 -0
- package/tools/benchmarks/utils.ts +31 -0
- package/tools/mqtt-compat/README.md +130 -0
- package/tools/mqtt-compat/broker.ts +52 -0
- package/tools/mqtt-compat/paho-mqtt4.test.ts +379 -0
- package/tools/mqtt-compat/paho-mqtt5.tests.ts +887 -0
- package/trie/trie.test.ts +9 -1
- package/trie/trie.ts +57 -22
- package/utils/bufferedAsyncIterable.test.ts +92 -0
- package/utils/{BufferedAsyncIterable.ts → bufferedAsyncIterable.ts} +1 -1
- package/utils/deferred.test.ts +36 -0
- package/utils/deferred.ts +0 -1
- package/utils/getOrInsertPolyFill.ts +12 -0
- package/utils/logger.test.ts +189 -0
- package/utils/logger.ts +62 -7
- package/utils/mod.ts +15 -1
- package/utils/outboundTopicAliasManager.ts +100 -0
- package/utils/queue.test.ts +61 -0
- package/utils/topicFilter.test.ts +63 -0
- package/utils/topicFilter.ts +61 -0
- package/utils/utils.ts +3 -0
- package/utils/validators.ts +67 -0
- package/web/webSocketStream.ts +97 -0
- package/web/wrapWebSocket.ts +52 -0
- package/web/wsClient.test.ts +26 -0
- package/web/wsClient.ts +25 -0
- package/benchmarks/receiver.ts +0 -35
- package/benchmarks/sender.ts +0 -32
- package/benchmarks/utils.ts +0 -9
- package/dev_utils/dummyConn.ts +0 -110
- package/dist/persistence/store.d.ts +0 -13
- package/dist/persistence/store.d.ts.map +0 -1
- package/dist/persistence/store.js +0 -2
- package/dist/persistence/store.js.map +0 -1
- package/dist/utils/BufferedAsyncIterable.d.ts.map +0 -1
- package/dist/utils/BufferedAsyncIterable.js.map +0 -1
- package/examples/tcpServer.test.ts +0 -148
- package/persistence/memory/memoryPersistence.test.ts +0 -156
- package/persistence/store.ts +0 -15
- package/server/test/handleConnect.test.ts +0 -130
- package/server/test/test-handlers.ts +0 -53
package/client/client.ts
CHANGED
|
@@ -4,21 +4,23 @@ import {
|
|
|
4
4
|
MemoryStore,
|
|
5
5
|
MQTTLevel,
|
|
6
6
|
PacketType,
|
|
7
|
+
ReasonCode,
|
|
7
8
|
} from "./deps.ts";
|
|
8
9
|
|
|
9
10
|
import type {
|
|
10
11
|
ConnectPacket,
|
|
12
|
+
IStore,
|
|
11
13
|
PublishPacket,
|
|
12
14
|
SockConn,
|
|
13
15
|
SubscribePacket,
|
|
14
16
|
TAuthenticationResult,
|
|
15
17
|
} from "./deps.ts";
|
|
16
18
|
|
|
17
|
-
import { noop } from "../utils/
|
|
19
|
+
import { noop } from "../utils/mod.ts";
|
|
18
20
|
|
|
19
21
|
import { Context } from "./context.ts";
|
|
22
|
+
import type { AuthenticatedResult } from "./context.ts";
|
|
20
23
|
import type { TConnectionState } from "./ConnectionState.ts";
|
|
21
|
-
import { assert } from "../utils/assert.ts";
|
|
22
24
|
import { BufferedAsyncIterable } from "./deps.ts";
|
|
23
25
|
|
|
24
26
|
/**
|
|
@@ -37,12 +39,12 @@ type ConnectOptions = Omit<
|
|
|
37
39
|
|
|
38
40
|
/** ConnectParameters define how to connect */
|
|
39
41
|
export type ConnectParameters = {
|
|
40
|
-
url?: URL;
|
|
41
|
-
caCerts?: string[];
|
|
42
|
-
cert?: string;
|
|
43
|
-
key?: string;
|
|
44
|
-
numberOfRetries?: number;
|
|
45
|
-
options?: ConnectOptions;
|
|
42
|
+
url?: URL | undefined;
|
|
43
|
+
caCerts?: string[] | undefined;
|
|
44
|
+
cert?: string | undefined;
|
|
45
|
+
key?: string | undefined;
|
|
46
|
+
numberOfRetries?: number | undefined;
|
|
47
|
+
options?: ConnectOptions | undefined;
|
|
46
48
|
};
|
|
47
49
|
|
|
48
50
|
/** PublishParameters define how a message should be published */
|
|
@@ -84,6 +86,20 @@ export const DEFAULT_KEEPALIVE = 60; // 60 seconds
|
|
|
84
86
|
const DEFAULT_RETRIES = 3; // on first connect
|
|
85
87
|
const CLIENTID_PREFIX = "opifex"; // on first connect
|
|
86
88
|
|
|
89
|
+
// convert an ErrorEvent into an Error
|
|
90
|
+
// NodeJS does not know ErrorEvent
|
|
91
|
+
function normalizeError(err: unknown): Error {
|
|
92
|
+
if (typeof ErrorEvent !== "undefined" && err instanceof ErrorEvent) {
|
|
93
|
+
return new Error(err.message);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (err instanceof Error) {
|
|
97
|
+
return err;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
|
|
87
103
|
/**
|
|
88
104
|
* The Client class provides an MQTT Client that can be used to connect to
|
|
89
105
|
* a MQTT broker and publish/subscribe messages.
|
|
@@ -94,6 +110,15 @@ const CLIENTID_PREFIX = "opifex"; // on first connect
|
|
|
94
110
|
* connection type that is supported by the subclass.
|
|
95
111
|
*/
|
|
96
112
|
export class Client {
|
|
113
|
+
public onAuth: (
|
|
114
|
+
authMethod: string,
|
|
115
|
+
authData: Uint8Array,
|
|
116
|
+
) => AuthenticatedResult = () => {
|
|
117
|
+
return {
|
|
118
|
+
reasonCode: ReasonCode.badAuthenticationMethod,
|
|
119
|
+
reasonString: "No authentication method configured",
|
|
120
|
+
};
|
|
121
|
+
};
|
|
97
122
|
public onError: (err: Error) => void = noop;
|
|
98
123
|
public onPacket: (pkt: PublishPacket) => void | Promise<void> = noop;
|
|
99
124
|
public onConnected: () => void = noop;
|
|
@@ -102,51 +127,43 @@ export class Client {
|
|
|
102
127
|
|
|
103
128
|
protected clientIdPrefix = CLIENTID_PREFIX;
|
|
104
129
|
protected numberOfRetries = DEFAULT_RETRIES;
|
|
105
|
-
protected
|
|
130
|
+
protected connectUrl: URL = new URL(DEFAULT_URL);
|
|
106
131
|
protected keepAlive = DEFAULT_KEEPALIVE;
|
|
107
132
|
protected protocolLevel = DEFAULT_PROTOCOLLEVEL;
|
|
108
133
|
protected autoReconnect = true;
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
134
|
+
protected caCerts?: string[] | undefined;
|
|
135
|
+
protected cert?: string | undefined;
|
|
136
|
+
protected key?: string | undefined;
|
|
137
|
+
protected clientId: string;
|
|
113
138
|
private ctx: Context;
|
|
114
139
|
private connectPacket?: ConnectPacket;
|
|
115
140
|
|
|
116
141
|
/**
|
|
117
142
|
* Creates a new MQTT client instance
|
|
118
143
|
*/
|
|
119
|
-
constructor() {
|
|
120
|
-
|
|
144
|
+
constructor(store?: IStore) {
|
|
145
|
+
const cStore = store ? store : new MemoryStore();
|
|
146
|
+
this.ctx = new Context(cStore, this);
|
|
121
147
|
this.clientId = generateClientId(this.clientIdPrefix);
|
|
122
148
|
this.numberOfRetries = DEFAULT_RETRIES;
|
|
123
149
|
}
|
|
124
150
|
|
|
125
|
-
get connectionState(): TConnectionState {
|
|
151
|
+
public get connectionState(): TConnectionState {
|
|
126
152
|
return this.ctx.connectionState;
|
|
127
153
|
}
|
|
128
154
|
|
|
155
|
+
public get url(): URL {
|
|
156
|
+
return this.connectUrl;
|
|
157
|
+
}
|
|
158
|
+
|
|
129
159
|
/**
|
|
130
160
|
* Creates a new connection to the MQTT broker
|
|
131
|
-
* @param protocol - The protocol to use (mqtt, mqtts, etc)
|
|
132
|
-
* @param _hostname - The hostname to connect to
|
|
133
|
-
* @param _port - The port to connect to
|
|
134
|
-
* @param _caCerts - Optional CA certificates
|
|
135
|
-
* @param _cert - Optional client certificate
|
|
136
|
-
* @param _key - Optional client key
|
|
137
161
|
* @returns Promise resolving to a SockConn connection
|
|
138
162
|
*/
|
|
139
|
-
protected createConn(
|
|
140
|
-
protocol: string,
|
|
141
|
-
_hostname: string,
|
|
142
|
-
_port?: number,
|
|
143
|
-
_caCerts?: string[],
|
|
144
|
-
_cert?: string,
|
|
145
|
-
_key?: string,
|
|
146
|
-
): Promise<SockConn> {
|
|
163
|
+
protected createConn(): Promise<SockConn> {
|
|
147
164
|
// if you need to support alternative connection types just
|
|
148
165
|
// overload this method in your subclass
|
|
149
|
-
throw new Error(`Unsupported protocol: ${protocol}`);
|
|
166
|
+
throw new Error(`Unsupported protocol: ${this.url.protocol}`);
|
|
150
167
|
}
|
|
151
168
|
|
|
152
169
|
/**
|
|
@@ -163,16 +180,12 @@ export class Client {
|
|
|
163
180
|
let lastMessage = new Error();
|
|
164
181
|
let tryConnect = true;
|
|
165
182
|
while (tryConnect) {
|
|
166
|
-
logger.debug(
|
|
183
|
+
logger.debug(
|
|
184
|
+
isReconnect ? "reconnecting, attempt" : "connecting, attempt",
|
|
185
|
+
attempt,
|
|
186
|
+
);
|
|
167
187
|
try {
|
|
168
|
-
const conn = await this.createConn(
|
|
169
|
-
this.url.protocol,
|
|
170
|
-
this.url.hostname,
|
|
171
|
-
Number(this.url.port) ?? undefined,
|
|
172
|
-
this.caCerts,
|
|
173
|
-
this.cert,
|
|
174
|
-
this.key,
|
|
175
|
-
);
|
|
188
|
+
const conn = await this.createConn();
|
|
176
189
|
// if we get this far we have a connection
|
|
177
190
|
tryConnect =
|
|
178
191
|
(await this.ctx.handleConnection(conn, this.connectPacket)) &&
|
|
@@ -182,12 +195,9 @@ export class Client {
|
|
|
182
195
|
this.connectPacket.clean = false;
|
|
183
196
|
this.ctx.close();
|
|
184
197
|
} catch (err) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
);
|
|
189
|
-
queueMicrotask(() => this.onError(err));
|
|
190
|
-
lastMessage = err;
|
|
198
|
+
const normalizedErr = normalizeError(err);
|
|
199
|
+
queueMicrotask(() => this.onError(normalizedErr));
|
|
200
|
+
lastMessage = normalizedErr;
|
|
191
201
|
logger.debug({ lastMessage });
|
|
192
202
|
}
|
|
193
203
|
|
|
@@ -213,7 +223,7 @@ export class Client {
|
|
|
213
223
|
* @returns Promise resolving to authentication result
|
|
214
224
|
*/
|
|
215
225
|
connect(params: ConnectParameters = {}): Promise<TAuthenticationResult> {
|
|
216
|
-
this.
|
|
226
|
+
this.connectUrl = params?.url || this.connectUrl;
|
|
217
227
|
this.numberOfRetries = params.numberOfRetries || this.numberOfRetries;
|
|
218
228
|
this.caCerts = params?.caCerts;
|
|
219
229
|
this.cert = params?.cert;
|
package/client/context.ts
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import type {
|
|
10
10
|
AnyPacket,
|
|
11
11
|
ConnectPacket,
|
|
12
|
-
|
|
12
|
+
IStore,
|
|
13
13
|
PacketId,
|
|
14
14
|
ProtocolLevel,
|
|
15
15
|
PublishPacket,
|
|
@@ -17,6 +17,8 @@ import type {
|
|
|
17
17
|
SockConn,
|
|
18
18
|
SubscribePacket,
|
|
19
19
|
TAuthenticationResult,
|
|
20
|
+
TPacketType,
|
|
21
|
+
TReasonCode,
|
|
20
22
|
UnsubscribePacket,
|
|
21
23
|
} from "./deps.ts";
|
|
22
24
|
|
|
@@ -26,6 +28,24 @@ import { ConnectionState } from "./ConnectionState.ts";
|
|
|
26
28
|
import type { Client } from "./client.ts";
|
|
27
29
|
import { assert } from "../utils/assert.ts";
|
|
28
30
|
|
|
31
|
+
/**
|
|
32
|
+
* packets not allowed during authentication
|
|
33
|
+
*/
|
|
34
|
+
function blockedDuringAuthentication(pktType: TPacketType) {
|
|
35
|
+
return (
|
|
36
|
+
pktType === PacketType.publish ||
|
|
37
|
+
pktType === PacketType.subscribe ||
|
|
38
|
+
pktType === PacketType.unsubscribe
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Possible results from authHandler */
|
|
43
|
+
export type AuthenticatedResult = {
|
|
44
|
+
reasonCode: TReasonCode;
|
|
45
|
+
reasonString?: string;
|
|
46
|
+
authData?: Uint8Array;
|
|
47
|
+
};
|
|
48
|
+
|
|
29
49
|
export class Context {
|
|
30
50
|
mqttConn?: MqttConn;
|
|
31
51
|
#connectionState: TConnectionState;
|
|
@@ -35,10 +55,10 @@ export class Context {
|
|
|
35
55
|
unresolvedPublish: Map<PacketId, Deferred<void>>;
|
|
36
56
|
unresolvedSubscribe: Map<PacketId, Deferred<ReturnCodes>>;
|
|
37
57
|
unresolvedUnSubscribe: Map<PacketId, Deferred<void>>;
|
|
38
|
-
store:
|
|
58
|
+
store: IStore;
|
|
39
59
|
#client: Client;
|
|
40
60
|
|
|
41
|
-
constructor(store:
|
|
61
|
+
constructor(store: IStore, client: Client) {
|
|
42
62
|
this.#client = client;
|
|
43
63
|
this.store = store;
|
|
44
64
|
this.#connectionState = ConnectionState.offline;
|
|
@@ -64,6 +84,25 @@ export class Context {
|
|
|
64
84
|
}
|
|
65
85
|
}
|
|
66
86
|
|
|
87
|
+
authHandler(
|
|
88
|
+
_ctx: Context,
|
|
89
|
+
authMethod: string,
|
|
90
|
+
authData: Uint8Array,
|
|
91
|
+
): AuthenticatedResult | Promise<AuthenticatedResult> {
|
|
92
|
+
return this.#client.onAuth(authMethod, authData);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setPingTimer(interval: number) {
|
|
96
|
+
if (this.pingTimer) {
|
|
97
|
+
this.pingTimer.clear();
|
|
98
|
+
}
|
|
99
|
+
this.pingTimer = new Timer(
|
|
100
|
+
this.sendPing.bind(this),
|
|
101
|
+
interval * 1000,
|
|
102
|
+
true,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
67
106
|
async connect(packet: ConnectPacket) {
|
|
68
107
|
this.connectionState = ConnectionState.connecting;
|
|
69
108
|
if (packet.protocolLevel === MQTTLevel.unknown) {
|
|
@@ -73,16 +112,15 @@ export class Context {
|
|
|
73
112
|
await this.mqttConn?.send(packet);
|
|
74
113
|
const keepAlive = packet.keepAlive || 0;
|
|
75
114
|
if (keepAlive > 0) {
|
|
76
|
-
this.
|
|
77
|
-
this.sendPing.bind(this),
|
|
78
|
-
keepAlive * 1000,
|
|
79
|
-
true,
|
|
80
|
-
);
|
|
115
|
+
this.setPingTimer(keepAlive);
|
|
81
116
|
}
|
|
82
117
|
}
|
|
83
118
|
|
|
84
119
|
async disconnect() {
|
|
85
|
-
if (
|
|
120
|
+
if (
|
|
121
|
+
this.connectionState !== ConnectionState.connected &&
|
|
122
|
+
this.connectionState !== ConnectionState.authenticating
|
|
123
|
+
) {
|
|
86
124
|
throw "Not connected";
|
|
87
125
|
}
|
|
88
126
|
if (this.mqttConn) {
|
|
@@ -97,14 +135,29 @@ export class Context {
|
|
|
97
135
|
}
|
|
98
136
|
|
|
99
137
|
async send(packet: AnyPacket) {
|
|
100
|
-
logger.debug({
|
|
101
|
-
if (
|
|
102
|
-
this.connectionState === ConnectionState.connected
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
138
|
+
logger.debug("client.ctx.send", this.#connectionState, { packet });
|
|
139
|
+
if (!this.mqttConn?.isClosed) {
|
|
140
|
+
if (this.connectionState === ConnectionState.connected) {
|
|
141
|
+
await this.mqttConn?.send(packet);
|
|
142
|
+
this.pingTimer?.reset();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (
|
|
146
|
+
this.connectionState === ConnectionState.connecting &&
|
|
147
|
+
packet.type === PacketType.auth
|
|
148
|
+
) {
|
|
149
|
+
await this.mqttConn?.send(packet);
|
|
150
|
+
this.pingTimer?.reset();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (
|
|
154
|
+
this.connectionState === ConnectionState.authenticating &&
|
|
155
|
+
!blockedDuringAuthentication(packet.type)
|
|
156
|
+
) {
|
|
157
|
+
await this.mqttConn?.send(packet);
|
|
158
|
+
this.pingTimer?.reset();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
108
161
|
}
|
|
109
162
|
logger.debug("not connected");
|
|
110
163
|
this.pingTimer?.clear();
|
|
@@ -122,6 +175,7 @@ export class Context {
|
|
|
122
175
|
connectPacket: ConnectPacket,
|
|
123
176
|
): Promise<boolean> {
|
|
124
177
|
this.mqttConn = new MqttConn({ conn });
|
|
178
|
+
this.mqttConn.codecOpts.protocolLevel = connectPacket.protocolLevel;
|
|
125
179
|
try {
|
|
126
180
|
logger.debug("Send connect packet", connectPacket);
|
|
127
181
|
await this.connect(connectPacket);
|
|
@@ -136,7 +190,7 @@ export class Context {
|
|
|
136
190
|
`Caught something that is not an instance of Error: ${err}`,
|
|
137
191
|
);
|
|
138
192
|
queueMicrotask(() => this.#client.onError(err));
|
|
139
|
-
logger.debug(
|
|
193
|
+
logger.debug("error", err);
|
|
140
194
|
if (!this.mqttConn.isClosed) {
|
|
141
195
|
this.mqttConn.close();
|
|
142
196
|
}
|
|
@@ -164,7 +218,7 @@ export class Context {
|
|
|
164
218
|
await this.send(packet);
|
|
165
219
|
return;
|
|
166
220
|
}
|
|
167
|
-
packet.id = this.store.nextId();
|
|
221
|
+
packet.id = await this.store.nextId();
|
|
168
222
|
this.store.pendingOutgoing.set(packet.id, packet);
|
|
169
223
|
const deferred = new Deferred<void>();
|
|
170
224
|
this.unresolvedPublish.set(packet.id, deferred);
|
|
@@ -173,7 +227,7 @@ export class Context {
|
|
|
173
227
|
}
|
|
174
228
|
|
|
175
229
|
async subscribe(packet: SubscribePacket): Promise<ReturnCodes> {
|
|
176
|
-
packet.id = this.store.nextId();
|
|
230
|
+
packet.id = await this.store.nextId();
|
|
177
231
|
this.store.pendingOutgoing.set(packet.id, packet);
|
|
178
232
|
const deferred = new Deferred<ReturnCodes>();
|
|
179
233
|
this.unresolvedSubscribe.set(packet.id, deferred);
|
|
@@ -182,7 +236,7 @@ export class Context {
|
|
|
182
236
|
}
|
|
183
237
|
|
|
184
238
|
async unsubscribe(packet: UnsubscribePacket): Promise<void> {
|
|
185
|
-
packet.id = this.store.nextId();
|
|
239
|
+
packet.id = await this.store.nextId();
|
|
186
240
|
this.store.pendingOutgoing.set(packet.id, packet);
|
|
187
241
|
const deferred = new Deferred<void>();
|
|
188
242
|
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,
|
|
@@ -12,11 +13,13 @@ export type {
|
|
|
12
13
|
PublishPacket,
|
|
13
14
|
PubrecPacket,
|
|
14
15
|
PubrelPacket,
|
|
16
|
+
QoS,
|
|
15
17
|
ReturnCodes,
|
|
16
18
|
SubackPacket,
|
|
17
19
|
SubscribePacket,
|
|
18
20
|
TAuthenticationResult,
|
|
19
21
|
Topic,
|
|
22
|
+
TPacketType,
|
|
20
23
|
TReasonCode,
|
|
21
24
|
UnsubackPacket,
|
|
22
25
|
UnsubscribePacket,
|
|
@@ -30,6 +33,7 @@ export {
|
|
|
30
33
|
MQTTLevel,
|
|
31
34
|
PacketNameByType,
|
|
32
35
|
PacketType,
|
|
36
|
+
ReasonCode,
|
|
33
37
|
ReasonCodeByNumber,
|
|
34
38
|
} from "../mqttPacket/mod.ts";
|
|
35
39
|
|
|
@@ -38,3 +42,4 @@ export type { SockConn } from "../socket/socket.ts";
|
|
|
38
42
|
export { Timer } from "../timer/timer.ts";
|
|
39
43
|
export { BufferedAsyncIterable, Deferred, logger } from "../utils/mod.ts";
|
|
40
44
|
export { MemoryStore } from "./store/memoryStore.ts";
|
|
45
|
+
export type { IStore } 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
|
+
});
|
|
@@ -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
|
+
}
|