@@ -113,11 +113,38 @@ extension MQTTClient {
113113 }
114114
115115 /// Disconnect from server
116- /// - Parameter properties: properties to attach to disconnect message
116+ /// - Parameter properties: properties to attach to disconnect packet
117117 /// - Returns: Future waiting on disconnect message to be sent
118118 public func disconnect( properties: MQTTProperties = . init( ) ) -> EventLoopFuture < Void > {
119119 return self . client. disconnect ( packet: MQTTDisconnectPacket ( reason: . success, properties: properties) )
120120 }
121+
122+ /// Re-authenticate with server
123+ ///
124+ /// - Parameters:
125+ /// - properties: properties to attach to auth packet. Must include `authenticationMethod`
126+ /// - authWorkflow: Respond to auth packets from server
127+ /// - Returns: final auth packet returned from server
128+ public func auth(
129+ properties: MQTTProperties ,
130+ authWorkflow: ( ( MQTTAuthV5 , EventLoop ) -> EventLoopFuture < MQTTAuthV5 > ) ? = nil
131+ ) -> EventLoopFuture < MQTTAuthV5 > {
132+ let authPacket = MQTTAuthPacket ( reason: . reAuthenticate, properties: properties)
133+ let authFuture = client. reAuth ( packet: authPacket)
134+ let eventLoop = authFuture. eventLoop
135+ return authFuture. flatMap { response -> EventLoopFuture < MQTTPacket > in
136+ guard let auth = response as? MQTTAuthPacket else { return eventLoop. makeFailedFuture ( MQTTError . unexpectedMessage) }
137+ if auth. reason == . success {
138+ return eventLoop. makeSucceededFuture ( auth)
139+ }
140+ guard let authWorkflow = authWorkflow else { return eventLoop. makeFailedFuture ( MQTTError . authWorkflowRequired) }
141+ return client. processAuth ( authPacket, authWorkflow: authWorkflow, on: eventLoop)
142+ }
143+ . flatMapThrowing { response -> MQTTAuthV5 in
144+ guard let auth = response as? MQTTAuthPacket else { throw MQTTError . unexpectedMessage }
145+ return MQTTAuthV5 ( reason: auth. reason, properties: auth. properties)
146+ }
147+ }
121148 }
122149
123150 /// v5 client
0 commit comments