aedes 0.46.3 → 0.48.0
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/.github/workflows/ci.yml +25 -5
- package/.github/workflows/sast.yml +29 -0
- package/README.md +2 -2
- package/aedes.d.ts +3 -9
- package/aedes.js +40 -20
- package/docs/Aedes.md +5 -3
- package/lib/client.js +15 -4
- package/lib/handlers/connect.js +4 -4
- package/lib/handlers/subscribe.js +7 -8
- package/lib/utils.js +11 -1
- package/package.json +20 -22
- package/test/auth.js +28 -10
- package/test/basic.js +8 -4
- package/test/bridge.js +57 -0
- package/test/client-pub-sub.js +7 -5
- package/test/connect.js +4 -4
- package/test/events.js +42 -1
- package/test/helper.js +11 -11
- package/test/meta.js +1 -1
- package/test/not-blocking.js +5 -5
- package/test/qos2.js +4 -2
- package/test/retain.js +2 -2
- package/test/topics.js +4 -4
- package/test/types/aedes.test-d.ts +17 -14
- package/test/will.js +66 -15
- package/types/.eslintrc.json +7 -5
- package/types/client.d.ts +28 -23
- package/types/instance.d.ts +98 -97
- package/types/packet.d.ts +18 -12
- package/types/tsconfig.json +6 -4
package/test/bridge.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const { setup, connect, subscribe } = require('./helper')
|
|
5
|
+
|
|
6
|
+
for (const qos of [0, 1, 2]) {
|
|
7
|
+
const packet = {
|
|
8
|
+
qos,
|
|
9
|
+
cmd: 'publish',
|
|
10
|
+
topic: 'hello',
|
|
11
|
+
payload: 'world'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (qos > 0) packet.messageId = 42
|
|
15
|
+
|
|
16
|
+
test('normal client sends a publish message and shall receive it back, qos = ' + qos, function (t) {
|
|
17
|
+
const s = connect(setup())
|
|
18
|
+
t.teardown(s.broker.close.bind(s.broker))
|
|
19
|
+
|
|
20
|
+
const handle = setTimeout(() => {
|
|
21
|
+
t.fail('did not receive packet back')
|
|
22
|
+
t.end()
|
|
23
|
+
}, 1000)
|
|
24
|
+
|
|
25
|
+
subscribe(t, s, 'hello', qos, function () {
|
|
26
|
+
s.outStream.on('data', (packet) => {
|
|
27
|
+
if (packet.cmd === 'publish') {
|
|
28
|
+
clearTimeout(handle)
|
|
29
|
+
t.end()
|
|
30
|
+
} else if (packet.cmd === 'pubrec') {
|
|
31
|
+
s.inStream.write({ cmd: 'pubrel', messageId: 42 })
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
s.inStream.write(packet)
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
test('bridge client sends a publish message but shall not receive it back, qos = ' + qos, function (t) {
|
|
40
|
+
// protocolVersion 128 + 4 means mqtt 3.1.1 with bridgeMode enabled
|
|
41
|
+
// https://github.com/mqttjs/mqtt-packet/blob/7f7c2ed8bcb4b2c582851d120a94e0b4a731f661/parser.js#L171
|
|
42
|
+
const s = connect(setup(), { clientId: 'my-client-bridge-1', protocolVersion: 128 + 4 })
|
|
43
|
+
t.teardown(s.broker.close.bind(s.broker))
|
|
44
|
+
|
|
45
|
+
const handle = setTimeout(() => t.end(), 1000)
|
|
46
|
+
|
|
47
|
+
subscribe(t, s, 'hello', qos, function () {
|
|
48
|
+
s.outStream.on('data', function () {
|
|
49
|
+
clearTimeout(handle)
|
|
50
|
+
t.fail('should not receive packet back')
|
|
51
|
+
t.end()
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
s.inStream.write(packet)
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
}
|
package/test/client-pub-sub.js
CHANGED
|
@@ -905,10 +905,10 @@ test('should not receive a message on negated subscription', function (t) {
|
|
|
905
905
|
test('programmatically add custom subscribe', function (t) {
|
|
906
906
|
t.plan(6)
|
|
907
907
|
|
|
908
|
-
const broker = aedes()
|
|
908
|
+
const broker = aedes({ clientId: 'my-client-xyz-7' })
|
|
909
909
|
t.teardown(broker.close.bind(broker))
|
|
910
910
|
|
|
911
|
-
const s = connect(setup(broker))
|
|
911
|
+
const s = connect(setup(broker), { clientId: 'my-client-xyz-7' })
|
|
912
912
|
const expected = {
|
|
913
913
|
cmd: 'publish',
|
|
914
914
|
topic: 'hello',
|
|
@@ -924,7 +924,8 @@ test('programmatically add custom subscribe', function (t) {
|
|
|
924
924
|
payload: Buffer.from('world'),
|
|
925
925
|
qos: 0,
|
|
926
926
|
retain: false,
|
|
927
|
-
dup: false
|
|
927
|
+
dup: false,
|
|
928
|
+
clientId: 'my-client-xyz-7'
|
|
928
929
|
}
|
|
929
930
|
subscribe(t, s, 'hello', 0, function () {
|
|
930
931
|
broker.subscribe('hello', deliver, function () {
|
|
@@ -963,9 +964,10 @@ test('custom function in broker.subscribe', function (t) {
|
|
|
963
964
|
qos: 1,
|
|
964
965
|
retain: false,
|
|
965
966
|
dup: false,
|
|
966
|
-
messageId: undefined
|
|
967
|
+
messageId: undefined,
|
|
968
|
+
clientId: 'my-client-xyz-6'
|
|
967
969
|
}
|
|
968
|
-
connect(s, {}, function () {
|
|
970
|
+
connect(s, { clientId: 'my-client-xyz-6' }, function () {
|
|
969
971
|
broker.subscribe('hello', deliver, function () {
|
|
970
972
|
t.pass('subscribed')
|
|
971
973
|
})
|
package/test/connect.js
CHANGED
|
@@ -214,13 +214,13 @@ test('client connect clear outgoing', function (t) {
|
|
|
214
214
|
const broker = aedes({ id: brokerId })
|
|
215
215
|
t.teardown(broker.close.bind(broker))
|
|
216
216
|
|
|
217
|
-
const subs = [{ clientId
|
|
217
|
+
const subs = [{ clientId }]
|
|
218
218
|
const packet = {
|
|
219
219
|
cmd: 'publish',
|
|
220
220
|
topic: 'hello',
|
|
221
221
|
payload: Buffer.from('world'),
|
|
222
222
|
qos: 1,
|
|
223
|
-
brokerId
|
|
223
|
+
brokerId,
|
|
224
224
|
brokerCounter: 2,
|
|
225
225
|
retain: true,
|
|
226
226
|
messageId: 42,
|
|
@@ -235,7 +235,7 @@ test('client connect clear outgoing', function (t) {
|
|
|
235
235
|
protocolId: 'MQTT',
|
|
236
236
|
protocolVersion: 4,
|
|
237
237
|
clean: true,
|
|
238
|
-
clientId
|
|
238
|
+
clientId,
|
|
239
239
|
keepalive: 0
|
|
240
240
|
})
|
|
241
241
|
|
|
@@ -705,7 +705,7 @@ test('websocket clients have access to the request object', function (t) {
|
|
|
705
705
|
|
|
706
706
|
const server = http.createServer()
|
|
707
707
|
ws.createServer({
|
|
708
|
-
server
|
|
708
|
+
server
|
|
709
709
|
}, broker.handle)
|
|
710
710
|
|
|
711
711
|
server.listen(port, function (err) {
|
package/test/events.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { test } = require('tap')
|
|
4
|
+
const mqemitter = require('mqemitter')
|
|
4
5
|
const { setup, connect, subscribe } = require('./helper')
|
|
5
6
|
const aedes = require('../')
|
|
6
7
|
|
|
@@ -16,9 +17,49 @@ test('publishes an hearbeat', function (t) {
|
|
|
16
17
|
const id = message.topic.match(/\$SYS\/([^/]+)\/heartbeat/)[1]
|
|
17
18
|
t.equal(id, broker.id, 'broker id matches')
|
|
18
19
|
t.same(message.payload.toString(), id, 'message has id as the payload')
|
|
20
|
+
cb()
|
|
19
21
|
})
|
|
20
22
|
})
|
|
21
23
|
|
|
24
|
+
test('publishes birth', function (t) {
|
|
25
|
+
t.plan(4)
|
|
26
|
+
|
|
27
|
+
const mq = mqemitter()
|
|
28
|
+
const brokerId = 'test-broker'
|
|
29
|
+
const fakeBroker = 'fake-broker'
|
|
30
|
+
const clientId = 'test-client'
|
|
31
|
+
|
|
32
|
+
mq.on(`$SYS/${brokerId}/birth`, (message, cb) => {
|
|
33
|
+
t.pass('broker birth received')
|
|
34
|
+
t.same(message.payload.toString(), brokerId, 'message has id as the payload')
|
|
35
|
+
cb()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const broker = aedes({
|
|
39
|
+
id: brokerId,
|
|
40
|
+
mq
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
broker.on('client', (client) => {
|
|
44
|
+
t.equal(client.id, clientId, 'client connected')
|
|
45
|
+
// set a fake counter on a fake broker
|
|
46
|
+
process.nextTick(() => {
|
|
47
|
+
broker.clients[clientId].duplicates[fakeBroker] = 42
|
|
48
|
+
mq.emit({ topic: `$SYS/${fakeBroker}/birth`, payload: Buffer.from(fakeBroker) })
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
mq.on(`$SYS/${fakeBroker}/birth`, (message, cb) => {
|
|
53
|
+
process.nextTick(() => {
|
|
54
|
+
t.equal(!!broker.clients[clientId].duplicates[fakeBroker], false, 'client duplicates has been resetted')
|
|
55
|
+
cb()
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const s = connect(setup(broker), { clientId })
|
|
60
|
+
t.teardown(s.broker.close.bind(s.broker))
|
|
61
|
+
})
|
|
62
|
+
|
|
22
63
|
;['$mcollina', '$SYS'].forEach(function (topic) {
|
|
23
64
|
test('does not forward $ prefixed topics to # subscription - ' + topic, function (t) {
|
|
24
65
|
t.plan(4)
|
|
@@ -161,7 +202,7 @@ test('Test backpressure aedes published function', function (t) {
|
|
|
161
202
|
|
|
162
203
|
server.listen(0, function () {
|
|
163
204
|
const port = server.address().port
|
|
164
|
-
publisher = mqtt.connect({ port
|
|
205
|
+
publisher = mqtt.connect({ port, host: 'localhost', clean: true, keepalive: 30 })
|
|
165
206
|
|
|
166
207
|
function next () {
|
|
167
208
|
if (--publishCount > 0) { process.nextTick(publish) }
|
package/test/helper.js
CHANGED
|
@@ -19,10 +19,10 @@ function setup (broker) {
|
|
|
19
19
|
|
|
20
20
|
return {
|
|
21
21
|
client: broker.handle(conn),
|
|
22
|
-
conn
|
|
23
|
-
inStream
|
|
24
|
-
outStream
|
|
25
|
-
broker
|
|
22
|
+
conn,
|
|
23
|
+
inStream,
|
|
24
|
+
outStream,
|
|
25
|
+
broker
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -74,8 +74,8 @@ function subscribe (t, subscriber, topic, qos, done) {
|
|
|
74
74
|
cmd: 'subscribe',
|
|
75
75
|
messageId: 24,
|
|
76
76
|
subscriptions: [{
|
|
77
|
-
topic
|
|
78
|
-
qos
|
|
77
|
+
topic,
|
|
78
|
+
qos
|
|
79
79
|
}]
|
|
80
80
|
})
|
|
81
81
|
|
|
@@ -110,10 +110,10 @@ function subscribeMultiple (t, subscriber, subs, expectedGranted, done) {
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
module.exports = {
|
|
113
|
-
setup
|
|
114
|
-
connect
|
|
115
|
-
noError
|
|
116
|
-
subscribe
|
|
117
|
-
subscribeMultiple
|
|
113
|
+
setup,
|
|
114
|
+
connect,
|
|
115
|
+
noError,
|
|
116
|
+
subscribe,
|
|
117
|
+
subscribeMultiple,
|
|
118
118
|
delay: util.promisify(setTimeout)
|
|
119
119
|
}
|
package/test/meta.js
CHANGED
package/test/not-blocking.js
CHANGED
|
@@ -42,7 +42,7 @@ test('connect 500 concurrent clients', function (t) {
|
|
|
42
42
|
|
|
43
43
|
for (let i = 0; i < total; i++) {
|
|
44
44
|
clients[i] = mqtt.connect({
|
|
45
|
-
port
|
|
45
|
+
port,
|
|
46
46
|
keepalive: 0,
|
|
47
47
|
reconnectPeriod: 100
|
|
48
48
|
}).on('connect', function () {
|
|
@@ -79,7 +79,7 @@ test('do not block after a subscription', function (t) {
|
|
|
79
79
|
const port = server.address().port
|
|
80
80
|
|
|
81
81
|
const publisher = mqtt.connect({
|
|
82
|
-
port
|
|
82
|
+
port,
|
|
83
83
|
keepalive: 0
|
|
84
84
|
}).on('error', function (err) {
|
|
85
85
|
clock.clearTimeout(clockId)
|
|
@@ -103,7 +103,7 @@ test('do not block after a subscription', function (t) {
|
|
|
103
103
|
|
|
104
104
|
function startSubscriber () {
|
|
105
105
|
subscriber = mqtt.connect({
|
|
106
|
-
port
|
|
106
|
+
port,
|
|
107
107
|
keepalive: 0
|
|
108
108
|
}).on('error', function (err) {
|
|
109
109
|
clock.clearTimeout(clockId)
|
|
@@ -163,7 +163,7 @@ test('do not block with overlapping subscription', function (t) {
|
|
|
163
163
|
const port = server.address().port
|
|
164
164
|
|
|
165
165
|
const publisher = mqtt.connect({
|
|
166
|
-
port
|
|
166
|
+
port,
|
|
167
167
|
keepalive: 0
|
|
168
168
|
}).on('error', function (err) {
|
|
169
169
|
clock.clearTimeout(clockId)
|
|
@@ -187,7 +187,7 @@ test('do not block with overlapping subscription', function (t) {
|
|
|
187
187
|
|
|
188
188
|
function startSubscriber () {
|
|
189
189
|
subscriber = mqtt.connect({
|
|
190
|
-
port
|
|
190
|
+
port,
|
|
191
191
|
keepalive: 0
|
|
192
192
|
}).on('error', function (err) {
|
|
193
193
|
clock.clearTimeout(clockId)
|
package/test/qos2.js
CHANGED
|
@@ -239,7 +239,7 @@ test('call published method with client with QoS 2', function (t) {
|
|
|
239
239
|
t.teardown(broker.close.bind(broker))
|
|
240
240
|
|
|
241
241
|
const opts = { clean: cleanSession }
|
|
242
|
-
const publisher = connect(setup(broker))
|
|
242
|
+
const publisher = connect(setup(broker), { clientId: 'my-client-xyz-8' })
|
|
243
243
|
const subscriber = connect(setup(broker), { ...opts, clientId: 'abcde' })
|
|
244
244
|
const forwarded = {
|
|
245
245
|
cmd: 'publish',
|
|
@@ -248,7 +248,8 @@ test('call published method with client with QoS 2', function (t) {
|
|
|
248
248
|
qos: 2,
|
|
249
249
|
retain: false,
|
|
250
250
|
dup: false,
|
|
251
|
-
messageId: undefined
|
|
251
|
+
messageId: undefined,
|
|
252
|
+
clientId: 'my-client-xyz-8'
|
|
252
253
|
}
|
|
253
254
|
const expected = {
|
|
254
255
|
cmd: 'publish',
|
|
@@ -262,6 +263,7 @@ test('call published method with client with QoS 2', function (t) {
|
|
|
262
263
|
broker.authorizeForward = function (client, packet) {
|
|
263
264
|
forwarded.brokerId = broker.id
|
|
264
265
|
forwarded.brokerCounter = broker.counter
|
|
266
|
+
delete packet.nl
|
|
265
267
|
t.same(packet, forwarded, 'forwarded packet must match')
|
|
266
268
|
return packet
|
|
267
269
|
}
|
package/test/retain.js
CHANGED
|
@@ -275,7 +275,7 @@ test('new QoS 0 subscribers receive QoS 0 retained messages when clean', functio
|
|
|
275
275
|
})
|
|
276
276
|
|
|
277
277
|
clock.setTimeout(() => {
|
|
278
|
-
t.equal(broker.counter,
|
|
278
|
+
t.equal(broker.counter, 9)
|
|
279
279
|
}, 200)
|
|
280
280
|
})
|
|
281
281
|
|
|
@@ -315,7 +315,7 @@ test('new QoS 0 subscribers receive downgraded QoS 1 retained messages when clea
|
|
|
315
315
|
})
|
|
316
316
|
})
|
|
317
317
|
broker.on('closed', function () {
|
|
318
|
-
t.equal(broker.counter,
|
|
318
|
+
t.equal(broker.counter, 8)
|
|
319
319
|
})
|
|
320
320
|
})
|
|
321
321
|
|
package/test/topics.js
CHANGED
|
@@ -108,7 +108,7 @@ test('publish invalid topic with +', function (t) {
|
|
|
108
108
|
cmd: 'subscribe',
|
|
109
109
|
messageId: 24,
|
|
110
110
|
subscriptions: [{
|
|
111
|
-
topic
|
|
111
|
+
topic,
|
|
112
112
|
qos: 0
|
|
113
113
|
}]
|
|
114
114
|
})
|
|
@@ -157,7 +157,7 @@ test('topics are case-sensitive', function (t) {
|
|
|
157
157
|
;['hello', 'HELLO', 'heLLo', 'HELLO/#', 'hello/+'].forEach(function (topic) {
|
|
158
158
|
publisher.inStream.write({
|
|
159
159
|
cmd: 'publish',
|
|
160
|
-
topic
|
|
160
|
+
topic,
|
|
161
161
|
payload: 'world',
|
|
162
162
|
qos: 0,
|
|
163
163
|
retain: false
|
|
@@ -171,7 +171,7 @@ function subscribeMultipleTopics (t, broker, qos, subscriber, subscriptions, don
|
|
|
171
171
|
subscriber.inStream.write({
|
|
172
172
|
cmd: 'subscribe',
|
|
173
173
|
messageId: 24,
|
|
174
|
-
subscriptions
|
|
174
|
+
subscriptions
|
|
175
175
|
})
|
|
176
176
|
|
|
177
177
|
subscriber.outStream.once('data', function (packet) {
|
|
@@ -183,7 +183,7 @@ function subscribeMultipleTopics (t, broker, qos, subscriber, subscriptions, don
|
|
|
183
183
|
cmd: 'publish',
|
|
184
184
|
topic: 'hello/world',
|
|
185
185
|
payload: 'world',
|
|
186
|
-
qos
|
|
186
|
+
qos,
|
|
187
187
|
messageId: 42
|
|
188
188
|
})
|
|
189
189
|
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
/// <reference path="../../aedes.d.ts" />
|
|
2
|
+
|
|
3
|
+
import type { AedesPublishPacket, ConnackPacket, ConnectPacket, PingreqPacket, PublishPacket, PubrelPacket, SubscribePacket, Subscription, UnsubscribePacket } from 'aedes:packet'
|
|
4
|
+
import type { AuthenticateError, Brokers, Connection } from 'aedes:server'
|
|
5
|
+
import Server, { Aedes } from 'aedes:server'
|
|
6
|
+
|
|
7
|
+
import { IncomingMessage } from 'node:http'
|
|
8
|
+
import type { Client } from 'aedes:client'
|
|
9
|
+
import { Socket } from 'node:net'
|
|
1
10
|
import { expectType } from 'tsd'
|
|
2
|
-
import { Socket } from 'net'
|
|
3
|
-
import type {
|
|
4
|
-
Aedes,
|
|
5
|
-
Brokers,
|
|
6
|
-
AuthenticateError,
|
|
7
|
-
Client,
|
|
8
|
-
Connection
|
|
9
|
-
} from '../../aedes'
|
|
10
|
-
import { Server } from '../../aedes'
|
|
11
|
-
import type { AedesPublishPacket, ConnackPacket, ConnectPacket, PingreqPacket, PublishPacket, PubrelPacket, Subscription, SubscribePacket, UnsubscribePacket } from '../../types/packet'
|
|
12
11
|
|
|
13
12
|
// Aedes server
|
|
14
|
-
|
|
13
|
+
let broker = new Server()
|
|
14
|
+
expectType<Aedes>(broker)
|
|
15
|
+
|
|
16
|
+
broker = new Aedes({
|
|
15
17
|
id: 'aedes',
|
|
16
18
|
concurrency: 100,
|
|
17
19
|
heartbeatInterval: 60000,
|
|
@@ -37,7 +39,7 @@ const broker = Server({
|
|
|
37
39
|
callback(error, false)
|
|
38
40
|
}
|
|
39
41
|
},
|
|
40
|
-
authorizePublish: (client: Client, packet: PublishPacket, callback) => {
|
|
42
|
+
authorizePublish: (client: Client | null, packet: PublishPacket, callback) => {
|
|
41
43
|
if (packet.topic === 'aaaa') {
|
|
42
44
|
return callback(new Error('wrong topic'))
|
|
43
45
|
}
|
|
@@ -93,7 +95,7 @@ expectType<Aedes>(broker.on('clientError', (client: Client, error: Error) => {})
|
|
|
93
95
|
expectType<Aedes>(broker.on('connectionError', (client: Client, error: Error) => {}))
|
|
94
96
|
expectType<Aedes>(broker.on('connackSent', (packet: ConnackPacket, client: Client) => {}))
|
|
95
97
|
expectType<Aedes>(broker.on('ping', (packet: PingreqPacket, client: Client) => {}))
|
|
96
|
-
expectType<Aedes>(broker.on('publish', (packet: AedesPublishPacket, client: Client) => {}))
|
|
98
|
+
expectType<Aedes>(broker.on('publish', (packet: AedesPublishPacket, client: Client | null) => {}))
|
|
97
99
|
expectType<Aedes>(broker.on('ack', (packet: PublishPacket | PubrelPacket, client: Client) => {}))
|
|
98
100
|
expectType<Aedes>(broker.on('subscribe', (subscriptions: Subscription[], client: Client) => {}))
|
|
99
101
|
expectType<Aedes>(broker.on('unsubscribe', (unsubscriptions: string[], client: Client) => {}))
|
|
@@ -123,11 +125,12 @@ expectType<void>(broker.close())
|
|
|
123
125
|
expectType<void>(broker.close(() => {}))
|
|
124
126
|
|
|
125
127
|
// Aedes client
|
|
126
|
-
const client = broker.handle({} as Connection)
|
|
128
|
+
const client = broker.handle({} as Connection, {} as IncomingMessage)
|
|
127
129
|
|
|
128
130
|
expectType<Client>(client)
|
|
129
131
|
|
|
130
132
|
expectType<Connection>(client.conn)
|
|
133
|
+
expectType<IncomingMessage>(client.req!)
|
|
131
134
|
|
|
132
135
|
expectType<Client>(client.on('connected', () => {}))
|
|
133
136
|
expectType<Client>(client.on('error', (error: Error) => {
|
package/test/will.js
CHANGED
|
@@ -58,8 +58,11 @@ test('calling close two times should not deliver two wills', function (t) {
|
|
|
58
58
|
willConnect(setup(broker), opts)
|
|
59
59
|
|
|
60
60
|
function onWill (packet, cb) {
|
|
61
|
-
broker.mq.removeListener('mywill', onWill)
|
|
62
|
-
|
|
61
|
+
broker.mq.removeListener('mywill', onWill, function () {
|
|
62
|
+
broker.mq.on('mywill', function (packet) {
|
|
63
|
+
t.fail('the will must be delivered only once')
|
|
64
|
+
})
|
|
65
|
+
})
|
|
63
66
|
t.equal(packet.topic, opts.will.topic, 'topic matches')
|
|
64
67
|
t.same(packet.payload, opts.will.payload, 'payload matches')
|
|
65
68
|
t.equal(packet.qos, opts.will.qos, 'qos matches')
|
|
@@ -69,7 +72,7 @@ test('calling close two times should not deliver two wills', function (t) {
|
|
|
69
72
|
})
|
|
70
73
|
|
|
71
74
|
test('delivers old will in case of a crash', function (t) {
|
|
72
|
-
t.plan(
|
|
75
|
+
t.plan(8)
|
|
73
76
|
|
|
74
77
|
const persistence = memory()
|
|
75
78
|
const will = {
|
|
@@ -88,10 +91,16 @@ test('delivers old will in case of a crash', function (t) {
|
|
|
88
91
|
}, will, function (err) {
|
|
89
92
|
t.error(err, 'no error')
|
|
90
93
|
|
|
94
|
+
let authorized = false
|
|
91
95
|
const interval = 10 // ms, so that the will check happens fast!
|
|
92
96
|
const broker = aedes({
|
|
93
|
-
persistence
|
|
94
|
-
heartbeatInterval: interval
|
|
97
|
+
persistence,
|
|
98
|
+
heartbeatInterval: interval,
|
|
99
|
+
authorizePublish: function (client, packet, callback) {
|
|
100
|
+
t.strictSame(client, null, 'client must be null')
|
|
101
|
+
authorized = true
|
|
102
|
+
callback(null)
|
|
103
|
+
}
|
|
95
104
|
})
|
|
96
105
|
t.teardown(broker.close.bind(broker))
|
|
97
106
|
|
|
@@ -100,15 +109,58 @@ test('delivers old will in case of a crash', function (t) {
|
|
|
100
109
|
broker.mq.on('mywill', check)
|
|
101
110
|
|
|
102
111
|
function check (packet, cb) {
|
|
103
|
-
broker.mq.removeListener('mywill', check)
|
|
112
|
+
broker.mq.removeListener('mywill', check, function () {
|
|
113
|
+
broker.mq.on('mywill', function (packet) {
|
|
114
|
+
t.fail('the will must be delivered only once')
|
|
115
|
+
})
|
|
116
|
+
})
|
|
104
117
|
t.ok(Date.now() - start >= 3 * interval, 'the will needs to be emitted after 3 heartbeats')
|
|
105
118
|
t.equal(packet.topic, will.topic, 'topic matches')
|
|
106
119
|
t.same(packet.payload, will.payload, 'payload matches')
|
|
107
120
|
t.equal(packet.qos, will.qos, 'qos matches')
|
|
108
121
|
t.equal(packet.retain, will.retain, 'retain matches')
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
t.equal(authorized, true, 'authorization called')
|
|
123
|
+
cb()
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
test('deliver old will without authorization in case of a crash', function (t) {
|
|
129
|
+
t.plan(2)
|
|
130
|
+
|
|
131
|
+
const persistence = memory()
|
|
132
|
+
const will = {
|
|
133
|
+
topic: 'mywill',
|
|
134
|
+
payload: Buffer.from('last will'),
|
|
135
|
+
qos: 0,
|
|
136
|
+
retain: false
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
persistence.broker = {
|
|
140
|
+
id: 'anotherBroker'
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
persistence.putWill({
|
|
144
|
+
id: 'myClientId42'
|
|
145
|
+
}, will, function (err) {
|
|
146
|
+
t.error(err, 'no error')
|
|
147
|
+
|
|
148
|
+
const interval = 10 // ms, so that the will check happens fast!
|
|
149
|
+
const broker = aedes({
|
|
150
|
+
persistence,
|
|
151
|
+
heartbeatInterval: interval,
|
|
152
|
+
authorizePublish: function (client, packet, callback) {
|
|
153
|
+
t.strictSame(client, null, 'client must be null')
|
|
154
|
+
callback(new Error())
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
t.teardown(broker.close.bind(broker))
|
|
159
|
+
|
|
160
|
+
broker.mq.on('mywill', check)
|
|
161
|
+
|
|
162
|
+
function check (packet, cb) {
|
|
163
|
+
t.fail('received will without authorization')
|
|
112
164
|
cb()
|
|
113
165
|
}
|
|
114
166
|
})
|
|
@@ -121,7 +173,7 @@ test('delete old broker', function (t) {
|
|
|
121
173
|
|
|
122
174
|
const heartbeatInterval = 100
|
|
123
175
|
const broker = aedes({
|
|
124
|
-
heartbeatInterval
|
|
176
|
+
heartbeatInterval
|
|
125
177
|
})
|
|
126
178
|
t.teardown(broker.close.bind(broker))
|
|
127
179
|
|
|
@@ -185,8 +237,7 @@ test('delete the will in the persistence after publish', function (t) {
|
|
|
185
237
|
willConnect(setup(broker), opts)
|
|
186
238
|
|
|
187
239
|
function check (packet, cb) {
|
|
188
|
-
broker.mq.removeListener('mywill', check)
|
|
189
|
-
setImmediate(function () {
|
|
240
|
+
broker.mq.removeListener('mywill', check, function () {
|
|
190
241
|
broker.persistence.getWill({
|
|
191
242
|
id: opts.clientId
|
|
192
243
|
}, function (err, p) {
|
|
@@ -421,7 +472,7 @@ test('don\'t delivers a will if broker alive', function (t) {
|
|
|
421
472
|
t.error(err, 'no error')
|
|
422
473
|
|
|
423
474
|
const opts = {
|
|
424
|
-
persistence
|
|
475
|
+
persistence,
|
|
425
476
|
heartbeatInterval: 10
|
|
426
477
|
}
|
|
427
478
|
|
|
@@ -472,7 +523,7 @@ test('handle will publish error', function (t) {
|
|
|
472
523
|
t.error(err, 'no error')
|
|
473
524
|
|
|
474
525
|
const opts = {
|
|
475
|
-
persistence
|
|
526
|
+
persistence,
|
|
476
527
|
heartbeatInterval: 10
|
|
477
528
|
}
|
|
478
529
|
|
|
@@ -509,7 +560,7 @@ test('handle will publish error 2', function (t) {
|
|
|
509
560
|
t.error(err, 'no error')
|
|
510
561
|
|
|
511
562
|
const opts = {
|
|
512
|
-
persistence
|
|
563
|
+
persistence,
|
|
513
564
|
heartbeatInterval: 10
|
|
514
565
|
}
|
|
515
566
|
|
package/types/.eslintrc.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": [
|
|
3
3
|
"eslint:recommended",
|
|
4
|
-
"plugin:@typescript-eslint/eslint-recommended",
|
|
5
4
|
"plugin:@typescript-eslint/recommended",
|
|
6
5
|
"standard"
|
|
7
6
|
],
|
|
@@ -15,16 +14,19 @@
|
|
|
15
14
|
"createDefaultProgram": true
|
|
16
15
|
},
|
|
17
16
|
"rules": {
|
|
17
|
+
"linebreak-style": ["warn", "unix"],
|
|
18
18
|
"no-console": "off",
|
|
19
|
-
"@typescript-eslint/indent": ["error", 2],
|
|
20
19
|
"semi": ["error", "never"],
|
|
21
|
-
"import/export": "off" // this errors on multiple exports (overload interfaces)
|
|
20
|
+
"import/export": "off", // this errors on multiple exports (overload interfaces)
|
|
21
|
+
"@typescript-eslint/indent": ["error", 2]
|
|
22
22
|
},
|
|
23
23
|
"overrides": [
|
|
24
24
|
{
|
|
25
|
-
"files": ["*.d.ts","*.test-d.ts"],
|
|
25
|
+
"files": ["*.d.ts", "*.test-d.ts"],
|
|
26
26
|
"rules": {
|
|
27
|
-
"
|
|
27
|
+
"no-dupe-class-members": "off",
|
|
28
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
29
|
+
"@typescript-eslint/triple-slash-reference": "off"
|
|
28
30
|
}
|
|
29
31
|
},
|
|
30
32
|
{
|
package/types/client.d.ts
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
declare module 'client' {
|
|
2
|
+
import { IncomingMessage } from 'node:http'
|
|
3
|
+
import { PublishPacket, SubscribePacket, Subscription, Subscriptions, UnsubscribePacket } from 'aedes:packet'
|
|
4
|
+
import { Connection } from 'aedes:server'
|
|
5
|
+
import { EventEmitter } from 'node:events'
|
|
5
6
|
|
|
6
|
-
export interface Client extends EventEmitter {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
export interface Client extends EventEmitter {
|
|
8
|
+
id: Readonly<string>
|
|
9
|
+
clean: Readonly<boolean>
|
|
10
|
+
version: Readonly<number>
|
|
11
|
+
conn: Connection
|
|
12
|
+
req?: IncomingMessage
|
|
13
|
+
connecting: Readonly<boolean>
|
|
14
|
+
connected: Readonly<boolean>
|
|
15
|
+
closed: Readonly<boolean>
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
on (event: 'connected', listener: () => void): this
|
|
18
|
+
on (event: 'error', listener: (error: Error) => void): this
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
publish (message: PublishPacket, callback?: (error?: Error) => void): void
|
|
21
|
+
subscribe (
|
|
22
|
+
subscriptions: Subscriptions | Subscription | Subscription[] | SubscribePacket,
|
|
23
|
+
callback?: (error?: Error) => void
|
|
24
|
+
): void
|
|
25
|
+
unsubscribe (topicObjects: Subscriptions | Subscription | Subscription[] | UnsubscribePacket, callback?: (error?: Error) => void): void
|
|
26
|
+
close (callback?: () => void): void
|
|
27
|
+
emptyOutgoingQueue (callback?: () => void): void
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
declare module 'aedes:client' {
|
|
31
|
+
export * from 'client'
|
|
27
32
|
}
|