Skip to content

Commit d5850b7

Browse files
Yoseph MaguirequickstarCédric von Allmen
authored
feat(client): auth handler for enhanced auth (mqttjs#1380)
* add draft of extended auth * expose handleAuth for api * do not handle auth packet directly for now * handle auth packet * point to dev version of mqtt-packet to make use of auth packages * solve hacky connected/disconnected flagging to send auth packages * remove unused code in handle auth * add packetcallback to auth handler * fix this and that issue * point to mqtt-packet dev master * switch to mqtt-packet 6.7.0 as our PR was merged * merge Co-authored-by: Lukas Läderach <lukas.laederach@3volutions.ch> Co-authored-by: Cédric von Allmen <cedric.vonallmen@gmail.com>
1 parent 06f2fd2 commit d5850b7

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

lib/client.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,10 @@ MqttClient.prototype._handlePacket = function (packet, done) {
547547
this._handleConnack(packet)
548548
done()
549549
break
550+
case 'auth':
551+
this._handleAuth(packet)
552+
done()
553+
break
550554
case 'pingresp':
551555
this._handlePingresp(packet)
552556
done()
@@ -1208,6 +1212,13 @@ MqttClient.prototype._sendPacket = function (packet, cb, cbStorePut) {
12081212
}
12091213

12101214
if (!this.connected) {
1215+
// allow auth packets to be sent while authenticating with the broker (mqtt5 enhanced auth)
1216+
if (packet.cmd === 'auth') {
1217+
this._shiftPingInterval()
1218+
sendPacket(this, packet, cb)
1219+
return
1220+
}
1221+
12111222
debug('_sendPacket :: client not connected. Storing packet offline.')
12121223
this._storePacket(packet, cb, cbStorePut)
12131224
return
@@ -1384,6 +1395,45 @@ MqttClient.prototype._handleConnack = function (packet) {
13841395
}
13851396
}
13861397

1398+
MqttClient.prototype._handleAuth = function (packet) {
1399+
const options = this.options
1400+
const version = options.protocolVersion
1401+
const rc = version === 5 ? packet.reasonCode : packet.returnCode
1402+
1403+
if (version !== 5) {
1404+
const err = new Error('Protocol error: Auth packets are only supported in MQTT 5. Your version:' + version)
1405+
err.code = rc
1406+
this.emit('error', err)
1407+
return
1408+
}
1409+
1410+
const that = this
1411+
this.handleAuth(packet, function (err, packet) {
1412+
if (err) {
1413+
that.emit('error', err)
1414+
return
1415+
}
1416+
1417+
if (rc === 24) {
1418+
that.reconnecting = false
1419+
that._sendPacket(packet)
1420+
} else {
1421+
const error = new Error('Connection refused: ' + errors[rc])
1422+
err.code = rc
1423+
that.emit('error', error)
1424+
}
1425+
})
1426+
}
1427+
1428+
/**
1429+
* @param packet the packet received by the broker
1430+
* @return the auth packet to be returned to the broker
1431+
* @api public
1432+
*/
1433+
MqttClient.prototype.handleAuth = function (packet, callback) {
1434+
callback()
1435+
}
1436+
13871437
/**
13881438
* _handlePublish
13891439
*

types/lib/client.d.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
IClientReconnectOptions
99
} from './client-options'
1010
import { Store } from './store'
11-
import { Packet, IConnectPacket, IPublishPacket, IDisconnectPacket, QoS, IConnackPacket } from 'mqtt-packet'
11+
import { IAuthPacket, IConnectPacket, IPublishPacket, IDisconnectPacket, IConnackPacket, Packet, QoS } from 'mqtt-packet'
1212

1313
export interface ISubscriptionGrant {
1414
/**
@@ -232,6 +232,27 @@ export declare class MqttClient extends events.EventEmitter {
232232
*/
233233
public handleMessage (packet: Packet, callback: PacketCallback): void
234234

235+
/**
236+
* Handle auth packages for MQTT 5 enhanced authentication methods such
237+
* as challenge response authentication.
238+
*
239+
* Challenge-response authentication flow would look something like this:
240+
*
241+
* --> CONNECT | authMethod = "mathChallenge" -->
242+
* <-- AUTH | authMethod = "mathChallenge", authData = "12 + 34" <--
243+
* --> AUTH | authMethod = "mathChallenge", authData = "46" -->
244+
* <-- CONNACK | reasonCode = SUCCESS <--
245+
*
246+
* This form of authentication has several advantages over traditional
247+
* credential-based approaches. For instance authentication without the direct
248+
* exchange of authentication secrets.
249+
*
250+
* @param packet the auth packet to handle
251+
* @param callback call when finished
252+
* @api public
253+
*/
254+
public handleAuth (packet: IAuthPacket, callback: PacketCallback): void
255+
235256
/**
236257
* getLastMessageId
237258
*/

0 commit comments

Comments
 (0)