Repository: moscajs/aedes
Pull request #547 (2020-10-06 13:50:30)

feat: add `packet` to `aedes.preConnect`
With this feature users will be able to access and modify a connect packet in `aedes.preConnect` handler

This will be a __BREAKING CHANGE__ for users that are using `preConnect`

coveralls: ## Pull Request Test Coverage Report for [Build 291513846](https://coveralls.io/builds/33965665)

* **0** of **1**   **(100.0%)**  changed or added relevant line in **1** file are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage remained the same at **99.55%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/33965665/badge)](https://coveralls.io/builds/33965665) |
| :-- | --: |
| Change from base [Build 290813242](https://coveralls.io/builds/33954921): |  0.0% |
| Covered Lines: | 791 |
| Relevant Lines: | 792 |

---
##### 💛  - [Coveralls](https://coveralls.io)

coveralls: ## Pull Request Test Coverage Report for [Build 291513846](https://coveralls.io/builds/33965665)

* **1** of **1**   **(100.0%)**  changed or added relevant line in **1** file are covered.
* No unchanged relevant lines lost coverage.
* Overall coverage remained the same at **99.55%**

---



|  Totals | [![Coverage Status](https://coveralls.io/builds/33965665/badge)](https://coveralls.io/builds/33965665) |
| :-- | --: |
| Change from base [Build 290813242](https://coveralls.io/builds/33954921): |  0.0% |
| Covered Lines: | 791 |
| Relevant Lines: | 792 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/aedes.d.ts b/aedes.d.ts
index 3f06ac9..dcd8765 100644
--- a/aedes.d.ts
+++ b/aedes.d.ts
@@ -4,7 +4,7 @@
 
 /// <reference types="node" />
 
-import { IConnackPacket, IPingreqPacket, IPublishPacket, IPubrelPacket, ISubscribePacket, ISubscription, IUnsubscribePacket } from 'mqtt-packet'
+import { IConnackPacket, IConnectPacket, IPingreqPacket, IPublishPacket, IPubrelPacket, ISubscribePacket, ISubscription, IUnsubscribePacket } from 'mqtt-packet'
 import { AedesPacket } from 'aedes-packet'
 import { Duplex } from 'stream'
 import { Socket } from 'net'
@@ -33,11 +33,12 @@ declare namespace aedes {
   type PublishPacket = IPublishPacket & { cmd: 'publish' }
   type AedesPublishPacket = PublishPacket & AedesPacket
 
+  type ConnectPacket = IConnectPacket & { cmd: 'connect' }
   type ConnackPacket = IConnackPacket & { cmd: 'connack' }
   type PubrelPacket = IPubrelPacket & { cmd: 'pubrel' }
   type PingreqPacket = IPingreqPacket & { cmd: 'pingreq' }
 
-  type PreConnectHandler = (client: Client, callback: (error: Error | null, success: boolean) => void) => void
+  type PreConnectHandler = (client: Client, packet: IConnectPacket, callback: (error: Error | null, success: boolean) => void) => void
 
   type AuthenticateError = Error & { returnCode: AuthErrorCode }
 
diff --git a/aedes.js b/aedes.js
index cf1caed..659b0d1 100644
--- a/aedes.js
+++ b/aedes.js
@@ -318,7 +318,7 @@ Aedes.prototype.close = function (cb = noop) {
 
 Aedes.prototype.version = require('./package.json').version
 
-function defaultPreConnect (client, callback) {
+function defaultPreConnect (client, packet, callback) {
   callback(null, true)
 }
 
diff --git a/docs/Aedes.md b/docs/Aedes.md
index 832ef37..d6bfac8 100644
--- a/docs/Aedes.md
+++ b/docs/Aedes.md
@@ -25,7 +25,7 @@
   - [aedes.publish (packet, callback)](#aedespublish-packet-callback)
   - [aedes.close ([callback])](#aedesclose-callback)
   - [Handler: decodeProtocol (client, buffer)](#handler-decodeprotocol-client-buffer)
-  - [Handler: preConnect (client, callback)](#handler-preconnect-client-callback)
+  - [Handler: preConnect (client, packet, callback)](#handler-preconnect-client-packet-callback)
   - [Handler: authenticate (client, username, password, callback)](#handler-authenticate-client-username-password-callback)
   - [Handler: authorizePublish (client, packet, callback)](#handler-authorizepublish-client-packet-callback)
   - [Handler: authorizeSubscribe (client, subscription, callback)](#handler-authorizesubscribe-client-subscription-callback)
@@ -242,14 +242,15 @@ aedes.decodeProtocol = function(client, buffer) {
 }
 ```
 
-## Handler: preConnect (client, callback)
+## Handler: preConnect (client, packet, callback)
 
 - client: [`<Client>`](./Client.md)
+- packet: `<object>` [`CONNECT`][CONNECT]
 - callback: `<Function>` `(error, successful) => void`
   - error `<Error>` | `null`
   - successful `<boolean>`
 
-Invoked when server receives a valid [`CONNECT`][CONNECT] packet.
+Invoked when server receives a valid [`CONNECT`][CONNECT] packet. The packet can be modified.
 
 `client` object is in default state. If invoked `callback` with no errors and `successful` be `true`, server will continue to establish a session.
 
@@ -262,7 +263,7 @@ Some Use Cases:
 3. IP blacklisting
 
 ```js
-aedes.preConnect = function(client, callback) {
+aedes.preConnect = function(client, packet, callback) {
   callback(null, client.conn.remoteAddress === '::1') {
 }
 ```
diff --git a/examples/proxy/index.js b/examples/proxy/index.js
index be34406..a2f43c6 100644
--- a/examples/proxy/index.js
+++ b/examples/proxy/index.js
@@ -124,7 +124,7 @@ function startAedes () {
       concurrency: 100
     }),
     persistence: persistence(),
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       console.log('Aedes preConnect check client ip:', client.connDetails)
       if (client.connDetails && client.connDetails.ipAddress) {
         client.ip = client.connDetails.ipAddress
diff --git a/lib/handlers/connect.js b/lib/handlers/connect.js
index 2d5dd1b..a557374 100644
--- a/lib/handlers/connect.js
+++ b/lib/handlers/connect.js
@@ -43,7 +43,7 @@ function handleConnect (client, packet, done) {
   clearTimeout(client._connectTimer)
   client._connectTimer = null
   client.connecting = true
-  client.broker.preConnect(client, negate)
+  client.broker.preConnect(client, packet, negate)
 
   function negate (err, successful) {
     if (!err && successful === true) {


Test patch:
diff --git a/test/connect.js b/test/connect.js
index b5dba35..fe662c0 100644
--- a/test/connect.js
+++ b/test/connect.js
@@ -437,7 +437,7 @@ test('connect handler calls done when preConnect throws error', function (t) {
   t.plan(1)
 
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       done(Error('error in preconnect'))
     }
   })
@@ -495,7 +495,7 @@ test('reject second CONNECT Packet sent while first CONNECT still in preConnect
 
   var i = 0
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       var ms = i++ === 0 ? 2000 : 500
       setTimeout(function () {
         done(null, true)
@@ -642,7 +642,7 @@ test('Test queue limit', function (t) {
     t.plan(plan)
 
     const broker = aedes({
-      preConnect: function (client, done) {
+      preConnect: function (client, packet, done) {
         t.ok(client.connecting)
         t.notOk(client.connected)
         t.equal(client.version, null)
@@ -737,7 +737,7 @@ test('tcp clients have access to the ipAddress from the socket', function (t) {
 
   const port = 4883
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       if (client && client.connDetails && client.connDetails.ipAddress) {
         client.ip = client.connDetails.ipAddress
         t.equal('::ffff:127.0.0.1', client.ip)
@@ -794,7 +794,7 @@ test('tcp proxied (protocol v1) clients have access to the ipAddress(v4)', funct
   ).build()
 
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       if (client.connDetails && client.connDetails.ipAddress) {
         client.ip = client.connDetails.ipAddress
         t.equal(clientIp, client.ip)
@@ -852,7 +852,7 @@ test('tcp proxied (protocol v2) clients have access to the ipAddress(v4)', funct
   ).build()
 
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       if (client.connDetails && client.connDetails.ipAddress) {
         client.ip = client.connDetails.ipAddress
         t.equal(clientIp, client.ip)
@@ -913,7 +913,7 @@ test('tcp proxied (protocol v2) clients have access to the ipAddress(v6)', funct
   ).build()
 
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       if (client.connDetails && client.connDetails.ipAddress) {
         client.ip = client.connDetails.ipAddress
         t.equal(clientIp, client.ip)
@@ -953,7 +953,7 @@ test('websocket clients have access to the ipAddress from the socket (if no ip h
   const clientIp = '::ffff:127.0.0.1'
   const port = 4883
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       if (client.connDetails && client.connDetails.ipAddress) {
         client.ip = client.connDetails.ipAddress
         t.equal(clientIp, client.ip)
@@ -990,7 +990,7 @@ test('websocket proxied clients have access to the ipAddress from x-real-ip head
   const clientIp = '192.168.0.140'
   const port = 4883
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       if (client.connDetails && client.connDetails.ipAddress) {
         client.ip = client.connDetails.ipAddress
         t.equal(clientIp, client.ip)
@@ -1033,7 +1033,7 @@ test('websocket proxied clients have access to the ipAddress from x-forwarded-fo
   const clientIp = '192.168.0.140'
   const port = 4883
   const broker = aedes({
-    preConnect: function (client, done) {
+    preConnect: function (client, packet, done) {
       if (client.connDetails && client.connDetails.ipAddress) {
         client.ip = client.connDetails.ipAddress
         t.equal(clientIp, client.ip)
diff --git a/test/types/index.ts b/test/types/index.ts
index 6b99780..b0dd7e4 100644
--- a/test/types/index.ts
+++ b/test/types/index.ts
@@ -3,13 +3,14 @@
 
 import { Server, Client, AuthenticateError, AedesPublishPacket, PublishPacket, Subscription } from '../../aedes'
 import { createServer, Socket } from 'net'
+import { Packet } from 'mqtt-packet'
 
 const broker = Server({
   concurrency: 100,
   heartbeatInterval: 60000,
   connectTimeout: 30000,
   id: 'aedes',
-  preConnect: (client: Client, callback) => {
+  preConnect: (client: Client, packet: Packet, callback) => {
     if (client.req) {
       callback(new Error('not websocket stream'), false)
     }