@seriousme/opifex 1.11.3 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +2 -0
- package/client/client.ts +51 -41
- package/client/context.ts +75 -21
- package/client/deps.ts +4 -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 +1 -1
- 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 -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 +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 +13 -16
- 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 +1 -1
- 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 +23 -15
- package/dist/mqttConn/mqttConn.d.ts.map +1 -1
- package/dist/mqttConn/mqttConn.js +56 -35
- package/dist/mqttConn/mqttConn.js.map +1 -1
- package/dist/mqttPacket/AuthenticationResult.d.ts.map +1 -1
- package/dist/mqttPacket/BitMask.d.ts.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 +4 -5
- 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 +6 -27
- 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/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 +4 -5
- 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 +5 -5
- 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 +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 +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 +76 -44
- 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 +175 -182
- package/mqttPacket/decoder.test.ts +0 -39
- package/mqttPacket/decoder.ts +8 -35
- package/mqttPacket/disconnect.ts +57 -68
- package/mqttPacket/encoder.ts +5 -40
- 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 +56 -70
- package/mqttPacket/publish.ts +67 -74
- 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 +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 +4 -9
- 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 -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 +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/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/README.md
CHANGED
|
@@ -6,21 +6,58 @@
|
|
|
6
6
|
|
|
7
7
|
Opifex aims to provide a MQTT server and MQTT client in Typescript to be used
|
|
8
8
|
with [NodeJS](https://nodejs.org), [Deno](https://deno.land) or
|
|
9
|
-
[Bun](https://bun.sh) It has _no_ third
|
|
10
|
-
built
|
|
9
|
+
[Bun](https://bun.sh). It has _no_ third-party dependencies, it only relies on
|
|
10
|
+
built-in modules.
|
|
11
11
|
|
|
12
12
|
# Compatibility
|
|
13
13
|
|
|
14
14
|
The following MQTT versions are supported:
|
|
15
15
|
|
|
16
|
-
| | MQTT 3.1 (v3) | MQTT 3.1.1 (v4) | MQTT 5.0 (v5)
|
|
17
|
-
| -------------- | ------------- | --------------- |
|
|
18
|
-
| Packet/encoder | ✅ | ✅ | ✅
|
|
19
|
-
| Client | ✅ | ✅ | ✅
|
|
20
|
-
| Server | ❌ | ✅ |
|
|
16
|
+
| | MQTT 3.1 (v3) | MQTT 3.1.1 (v4) | MQTT 5.0 (v5) |
|
|
17
|
+
| -------------- | ------------- | --------------- | --------------- |
|
|
18
|
+
| Packet/encoder | ✅ | ✅ | ✅ |
|
|
19
|
+
| Client | ✅ | ✅ | ✅ <sup>1</sup> |
|
|
20
|
+
| Server | ❌ | ✅ | ✅ |
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
<sup>1</sup> The client API fully supports MQTTv5, the CLI only supports a
|
|
23
|
+
subset
|
|
24
|
+
|
|
25
|
+
Version 5 support includes:
|
|
26
|
+
|
|
27
|
+
- Client Topic Alias ✅
|
|
28
|
+
- Server Topic Alias ✅
|
|
29
|
+
- Subscription Identifiers ✅
|
|
30
|
+
- Subscription options (NoLocal, RetainAsPublished, RetainHandling) ✅
|
|
31
|
+
- Message expiry interval ✅
|
|
32
|
+
- Will delay ✅
|
|
33
|
+
- Assigned Client Identifier ✅
|
|
34
|
+
- Client receive maximum ✅
|
|
35
|
+
- Server receive maximum ✅
|
|
36
|
+
- Shared Subscriptions ✅
|
|
37
|
+
|
|
38
|
+
# Transports
|
|
39
|
+
|
|
40
|
+
The following transports are currently supported:
|
|
41
|
+
|
|
42
|
+
- plain TCP ✅
|
|
43
|
+
- TLS ✅
|
|
44
|
+
- WebSockets ✅ <sup>2</sup>
|
|
45
|
+
|
|
46
|
+
<sup>2</sup> Deno + Browser only, NodeJS has no native websocket support.
|
|
47
|
+
|
|
48
|
+
You can add your own transports.
|
|
49
|
+
|
|
50
|
+
# Persistence
|
|
51
|
+
|
|
52
|
+
Opifex offers pluggable persistence, but one can provide its own persistence.
|
|
53
|
+
(see [Architecture](#architecture))
|
|
54
|
+
|
|
55
|
+
The following types are currently provided:
|
|
56
|
+
|
|
57
|
+
| | Plugable | Memory | Sqlite |
|
|
58
|
+
| ------ | -------- | ------ | ------ |
|
|
59
|
+
| Client | ✅ | ✅ | ❌ |
|
|
60
|
+
| Server | ✅ | ✅ | ✅ |
|
|
24
61
|
|
|
25
62
|
## Usage
|
|
26
63
|
|
|
@@ -35,8 +72,8 @@ can be done with CLI options then the next step is to clone the demo server
|
|
|
35
72
|
and/or the client scripts and modify them to your liking.
|
|
36
73
|
|
|
37
74
|
If you want to port the platform independent client and server libs to other
|
|
38
|
-
types of transports (e.g. Unix sockets
|
|
39
|
-
|
|
75
|
+
types of transports (e.g. Unix sockets) then it's recommended to clone and
|
|
76
|
+
modify the platform specific code in `/node` , `/deno` or `/web` as well.
|
|
40
77
|
|
|
41
78
|
If you want to port the platform independent client and server libs to another
|
|
42
79
|
platform then the platform specific code in `/node` or `/deno` might serve as
|
|
@@ -47,20 +84,25 @@ but for historic reasons `/deno` still exists.
|
|
|
47
84
|
|
|
48
85
|
## Example
|
|
49
86
|
|
|
50
|
-
A simple server example
|
|
87
|
+
A simple server example:
|
|
51
88
|
|
|
52
89
|
```typescript
|
|
53
|
-
import {
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
90
|
+
import { TcpServer } from "@seriousme/opifex/tcpServer";
|
|
91
|
+
|
|
92
|
+
const server = new TcpServer({ port: 1883 }, {
|
|
93
|
+
// just an example of how to configure the server
|
|
94
|
+
configuration: {
|
|
95
|
+
context: { maximumConnectPacketSize: 3000 },
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
server.start();
|
|
99
|
+
console.log(
|
|
100
|
+
`MQTT server running on port: ${server.port}, address: ${server.address}`,
|
|
101
|
+
);
|
|
60
102
|
```
|
|
61
103
|
|
|
62
|
-
|
|
63
|
-
[examples](/examples/) folder.
|
|
104
|
+
More elaborate examples including client and server, TLS, Websockets and sqlite
|
|
105
|
+
can be found in the [examples](/examples/) folder.
|
|
64
106
|
|
|
65
107
|
## Architecture
|
|
66
108
|
|
|
@@ -69,10 +111,10 @@ A more elaborate example including client and server can be found in the
|
|
|
69
111
|
encode and decode packets.
|
|
70
112
|
|
|
71
113
|
2. On top of mqttPacket sits the MQTT connection module
|
|
72
|
-
([mqttConn/mod.ts](mqttConn/mod.ts))
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
114
|
+
([mqttConn/mod.ts](mqttConn/mod.ts)) that reads packets from a Readable
|
|
115
|
+
stream and writes them to Writable stream. It will take care of incomplete
|
|
116
|
+
and/or malformed packets. mqttConn provides an async iterable that can be
|
|
117
|
+
awaited for new packets.
|
|
76
118
|
|
|
77
119
|
3. On top of mqttConn live the MQTT server ([server/mod.ts](server/mod.ts)) and
|
|
78
120
|
MQTT client ([client/mod.ts](client/mod.ts)) that take care of the MQTT
|
|
@@ -88,29 +130,46 @@ A more elaborate example including client and server can be found in the
|
|
|
88
130
|
keep track of its state and associated timers.
|
|
89
131
|
|
|
90
132
|
5. Persistence of data is handled by a pluggable persistence module
|
|
91
|
-
([persistence](persistence)) which currently
|
|
92
|
-
|
|
93
|
-
|
|
133
|
+
([persistence](persistence)) which currently offers single process
|
|
134
|
+
persistence which you can replace by something more scalable (e.g. redis
|
|
135
|
+
based clusters etc) This is backed by two storage providers:
|
|
136
|
+
- [memory](persistence/memory)
|
|
137
|
+
- [sqlite](persistence/sqlite), based on node:sqlite
|
|
138
|
+
|
|
139
|
+
but can be extended with other database backend persistence supported by
|
|
140
|
+
third-party modules.
|
|
141
|
+
|
|
142
|
+
6. Server behavior can be customized by passing a
|
|
143
|
+
[ConfigurationInput object](server/config.ts) via
|
|
144
|
+
`MqttServerOptions.configuration`, see the example above.
|
|
94
145
|
|
|
95
|
-
|
|
146
|
+
7. The demo server listens to a platform specific socket and runs the `serve()`
|
|
96
147
|
method from the server module on the platform independent streams of every
|
|
97
148
|
connection.
|
|
98
149
|
|
|
99
|
-
|
|
150
|
+
8. The demo client opens a platform specific socket and passes the resulting
|
|
100
151
|
platform independent streams to the client module.
|
|
101
152
|
|
|
102
153
|
## Exports
|
|
103
154
|
|
|
104
|
-
| Export | Description
|
|
105
|
-
| ----------------------------- |
|
|
106
|
-
| @seriousme/opifex/tcpClient | Exports a MQTT over TCP client
|
|
107
|
-
| @seriousme/opifex/tcpServer | Exports a MQTT over TCP server
|
|
108
|
-
| @seriousme/opifex/
|
|
109
|
-
| @seriousme/opifex/
|
|
110
|
-
| @seriousme/opifex/
|
|
111
|
-
| @seriousme/opifex/
|
|
112
|
-
| @seriousme/opifex/
|
|
113
|
-
| @seriousme/opifex/
|
|
155
|
+
| Export | Description |
|
|
156
|
+
| ----------------------------- | ------------------------------------------------------------ |
|
|
157
|
+
| @seriousme/opifex/tcpClient | Exports a MQTT over TCP/TLS client |
|
|
158
|
+
| @seriousme/opifex/tcpServer | Exports a MQTT over TCP server |
|
|
159
|
+
| @seriousme/opifex/tlsServer | Exports a MQTT over TLS server |
|
|
160
|
+
| @seriousme/opifex/wsClient | Exports a MQTT over Websocket client (deno and browser only) |
|
|
161
|
+
| @seriousme/opifex/wsServer | Exports a MQTT over Websocket server (deno only) |
|
|
162
|
+
| @seriousme/opifex/server | Exports a transport agnostic MQTT server |
|
|
163
|
+
| @seriousme/opifex/client | Exports a transport agnostic MQTT client |
|
|
164
|
+
| @seriousme/opifex/persistence | Exports a Typescript interface for storage persistence |
|
|
165
|
+
| @seriousme/opifex/mqttConn | Exports MQTT connection handling |
|
|
166
|
+
| @seriousme/opifex/mqttPacket | Exports MQTT packet handling |
|
|
167
|
+
| @seriousme/opifex/utils | Exports various utilities |
|
|
168
|
+
|
|
169
|
+
## API docs
|
|
170
|
+
|
|
171
|
+
The latest API documentation can be found at:
|
|
172
|
+
https://jsr.io/@seriousme/opifex@latest/doc
|
|
114
173
|
|
|
115
174
|
## Naming
|
|
116
175
|
|
package/bin/conformanceServer.ts
CHANGED
|
@@ -7,8 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { parseArgs } from "node:util";
|
|
9
9
|
import { TcpServer } from "../node/tcpServer.ts";
|
|
10
|
-
import type {
|
|
11
|
-
|
|
10
|
+
import type {
|
|
11
|
+
AuthenticatedResult,
|
|
12
|
+
ConnectPacket,
|
|
13
|
+
Context,
|
|
14
|
+
ShareName,
|
|
15
|
+
Topic,
|
|
16
|
+
} from "../server/mod.ts";
|
|
17
|
+
import { ReasonCode } from "../server/mod.ts";
|
|
12
18
|
import { logger, LogLevel } from "../utils/mod.ts";
|
|
13
19
|
|
|
14
20
|
/**
|
|
@@ -42,35 +48,49 @@ const checkUsername = true;
|
|
|
42
48
|
* @param {string} clientId - Client identifier
|
|
43
49
|
* @param {string} username - Username to authenticate
|
|
44
50
|
* @param {Uint8Array} password - Password as byte array
|
|
45
|
-
* @
|
|
51
|
+
* @param {ConnectPacket} connectPacket - The raw connect packet
|
|
52
|
+
* @returns {IsAuthenticationResult} Authentication result
|
|
46
53
|
*/
|
|
47
54
|
function isAuthenticated(
|
|
48
55
|
_ctx: Context,
|
|
49
56
|
clientId: string,
|
|
50
57
|
username: string,
|
|
51
58
|
password: Uint8Array,
|
|
52
|
-
|
|
59
|
+
connectPacket: ConnectPacket,
|
|
60
|
+
): AuthenticatedResult {
|
|
53
61
|
const pwd = utf8Decoder.decode(password);
|
|
54
62
|
logger.info(
|
|
55
|
-
|
|
63
|
+
"Verifying authentication of client",
|
|
64
|
+
clientId,
|
|
65
|
+
"with username",
|
|
66
|
+
username,
|
|
67
|
+
);
|
|
68
|
+
logger.debug(
|
|
69
|
+
"Client",
|
|
70
|
+
clientId,
|
|
71
|
+
"connecting with protocol level",
|
|
72
|
+
connectPacket.protocolLevel,
|
|
56
73
|
);
|
|
57
74
|
|
|
58
75
|
if (!checkUsername) {
|
|
59
76
|
// allow all users access
|
|
60
|
-
return
|
|
77
|
+
return { reasonCode: ReasonCode.success };
|
|
61
78
|
}
|
|
62
79
|
// is the username valid according to MQTT specification
|
|
63
80
|
if (!strictUsername.test(username)) {
|
|
64
|
-
return
|
|
81
|
+
return { reasonCode: ReasonCode.badUserNameOrPassword };
|
|
65
82
|
}
|
|
66
83
|
// Does user and password match an entry in userTable
|
|
67
84
|
if (userTable.has(username)) {
|
|
68
85
|
const pass = userTable.get(username);
|
|
69
86
|
if (pwd === pass) {
|
|
70
|
-
return
|
|
87
|
+
return { reasonCode: ReasonCode.success };
|
|
71
88
|
}
|
|
72
89
|
}
|
|
73
|
-
return
|
|
90
|
+
return {
|
|
91
|
+
reasonCode: ReasonCode.notAuthorized,
|
|
92
|
+
reasonString: "Authentication failed",
|
|
93
|
+
};
|
|
74
94
|
}
|
|
75
95
|
|
|
76
96
|
/**
|
|
@@ -81,7 +101,10 @@ function isAuthenticated(
|
|
|
81
101
|
*/
|
|
82
102
|
function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
|
|
83
103
|
logger.debug(
|
|
84
|
-
|
|
104
|
+
"Checking authorization of client",
|
|
105
|
+
ctx.clientId,
|
|
106
|
+
"to publish on topic",
|
|
107
|
+
topic,
|
|
85
108
|
);
|
|
86
109
|
return true;
|
|
87
110
|
}
|
|
@@ -92,9 +115,18 @@ function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
|
|
|
92
115
|
* @param {Topic} topic - Topic to subscribe to
|
|
93
116
|
* @returns {boolean} True if authorized
|
|
94
117
|
*/
|
|
95
|
-
function isAuthorizedToSubscribe(
|
|
118
|
+
function isAuthorizedToSubscribe(
|
|
119
|
+
ctx: Context,
|
|
120
|
+
topic: Topic,
|
|
121
|
+
shareName: ShareName,
|
|
122
|
+
): boolean {
|
|
96
123
|
logger.debug(
|
|
97
|
-
|
|
124
|
+
"Checking authorization of client",
|
|
125
|
+
ctx.clientId,
|
|
126
|
+
"to subscribe to topic",
|
|
127
|
+
topic,
|
|
128
|
+
"using shareName",
|
|
129
|
+
shareName,
|
|
98
130
|
);
|
|
99
131
|
return true;
|
|
100
132
|
}
|
|
@@ -118,4 +150,4 @@ const tcpServer = new TcpServer({ port, hostname }, {
|
|
|
118
150
|
},
|
|
119
151
|
});
|
|
120
152
|
tcpServer.start();
|
|
121
|
-
logger.info(
|
|
153
|
+
logger.info("Server started on port", tcpServer.port);
|
package/bin/demoServer.ts
CHANGED
|
@@ -6,8 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { parseArgs } from "node:util";
|
|
8
8
|
import { TcpServer } from "../node/tcpServer.ts";
|
|
9
|
-
import type {
|
|
10
|
-
|
|
9
|
+
import type {
|
|
10
|
+
AuthenticatedResult,
|
|
11
|
+
ConnectPacket,
|
|
12
|
+
Context,
|
|
13
|
+
ShareName,
|
|
14
|
+
Topic,
|
|
15
|
+
} from "../server/mod.ts";
|
|
16
|
+
import { ReasonCode } from "../server/mod.ts";
|
|
11
17
|
import { logger, LogLevel } from "../utils/mod.ts";
|
|
12
18
|
|
|
13
19
|
/**
|
|
@@ -41,35 +47,42 @@ const checkUsername = false;
|
|
|
41
47
|
* @param {string} clientId - Client identifier
|
|
42
48
|
* @param {string} username - Username to authenticate
|
|
43
49
|
* @param {Uint8Array} password - Password as byte array
|
|
44
|
-
* @returns {
|
|
50
|
+
* @returns {IsAuthenticationResult} Authentication result
|
|
45
51
|
*/
|
|
46
52
|
function isAuthenticated(
|
|
47
53
|
_ctx: Context,
|
|
48
54
|
clientId: string,
|
|
49
55
|
username: string,
|
|
50
56
|
password: Uint8Array,
|
|
51
|
-
|
|
57
|
+
connectPacket: ConnectPacket,
|
|
58
|
+
): AuthenticatedResult {
|
|
52
59
|
const pwd = utf8Decoder.decode(password);
|
|
53
60
|
logger.info(
|
|
54
|
-
`Verifying authentication of client '${clientId}' with username '${username}'
|
|
61
|
+
`Verifying authentication of client '${clientId}' with username '${username}'`,
|
|
62
|
+
);
|
|
63
|
+
logger.debug(
|
|
64
|
+
`Client '${clientId}' connecting with protocol level ${connectPacket.protocolLevel}`,
|
|
55
65
|
);
|
|
56
66
|
|
|
57
67
|
if (!checkUsername) {
|
|
58
68
|
// allow all users access
|
|
59
|
-
return
|
|
69
|
+
return { reasonCode: ReasonCode.success };
|
|
60
70
|
}
|
|
61
71
|
// is the username valid according to MQTT specification
|
|
62
72
|
if (!strictUsername.test(username)) {
|
|
63
|
-
return
|
|
73
|
+
return { reasonCode: ReasonCode.badUserNameOrPassword };
|
|
64
74
|
}
|
|
65
75
|
// Does user and password match an entry in userTable
|
|
66
76
|
if (userTable.has(username)) {
|
|
67
77
|
const pass = userTable.get(username);
|
|
68
78
|
if (pwd === pass) {
|
|
69
|
-
return
|
|
79
|
+
return { reasonCode: ReasonCode.success };
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
|
-
return
|
|
82
|
+
return {
|
|
83
|
+
reasonCode: ReasonCode.notAuthorized,
|
|
84
|
+
reasonString: "Authentication failed",
|
|
85
|
+
};
|
|
73
86
|
}
|
|
74
87
|
|
|
75
88
|
/**
|
|
@@ -80,7 +93,10 @@ function isAuthenticated(
|
|
|
80
93
|
*/
|
|
81
94
|
function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
|
|
82
95
|
logger.debug(
|
|
83
|
-
|
|
96
|
+
"Checking authorization of client",
|
|
97
|
+
ctx.clientId,
|
|
98
|
+
"to publish on topic",
|
|
99
|
+
topic,
|
|
84
100
|
);
|
|
85
101
|
return true;
|
|
86
102
|
}
|
|
@@ -91,9 +107,18 @@ function isAuthorizedToPublish(ctx: Context, topic: Topic): boolean {
|
|
|
91
107
|
* @param {Topic} topic - Topic to subscribe to
|
|
92
108
|
* @returns {boolean} True if authorized
|
|
93
109
|
*/
|
|
94
|
-
function isAuthorizedToSubscribe(
|
|
110
|
+
function isAuthorizedToSubscribe(
|
|
111
|
+
ctx: Context,
|
|
112
|
+
topic: Topic,
|
|
113
|
+
shareName: ShareName,
|
|
114
|
+
): boolean {
|
|
95
115
|
logger.debug(
|
|
96
|
-
|
|
116
|
+
"Checking authorization of client",
|
|
117
|
+
ctx.clientId,
|
|
118
|
+
"to subscribe to topic",
|
|
119
|
+
topic,
|
|
120
|
+
"using shareName",
|
|
121
|
+
shareName,
|
|
97
122
|
);
|
|
98
123
|
return true;
|
|
99
124
|
}
|
|
@@ -117,4 +142,4 @@ const tcpServer = new TcpServer({ port, hostname }, {
|
|
|
117
142
|
},
|
|
118
143
|
});
|
|
119
144
|
tcpServer.start();
|
|
120
|
-
logger.info(
|
|
145
|
+
logger.info("Server started on port", tcpServer.port);
|
package/bin/mqtt.ts
CHANGED
|
@@ -229,7 +229,7 @@ async function subscribe() {
|
|
|
229
229
|
} catch (err) {
|
|
230
230
|
if (err instanceof Error) {
|
|
231
231
|
const errorWithCode = err as Error & { code?: string };
|
|
232
|
-
logger.info(
|
|
232
|
+
logger.info("Error:", errorWithCode.message || errorWithCode.code);
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
}
|
|
@@ -283,7 +283,7 @@ async function publish() {
|
|
|
283
283
|
} catch (err) {
|
|
284
284
|
if (err instanceof Error) {
|
|
285
285
|
const errorWithCode = err as Error & { code?: string };
|
|
286
|
-
logger.info(
|
|
286
|
+
logger.info("Error:", errorWithCode.message || errorWithCode.code);
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
289
|
}
|
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
|
/**
|
|
@@ -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;
|