Skip to content

Commit ce50326

Browse files
committed
Merge remote-tracking branch 'upstream/main' into task/RNTL-25108-sync-fork
2 parents 790ded9 + d0c4414 commit ce50326

28 files changed

+605
-305
lines changed

.github/dependabot.yml

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
version: 2
22
updates:
3-
- package-ecosystem: github-actions
4-
directory: "/"
5-
schedule:
6-
interval: daily
7-
open-pull-requests-limit: 10
8-
- package-ecosystem: npm
9-
directory: "/"
10-
schedule:
11-
interval: daily
12-
open-pull-requests-limit: 10
3+
- package-ecosystem: github-actions
4+
directory: /
5+
schedule:
6+
interval: daily
7+
open-pull-requests-limit: 10
8+
9+
- package-ecosystem: npm
10+
directory: /
11+
schedule:
12+
interval: daily
13+
open-pull-requests-limit: 10

.github/workflows/ci.yml

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: ci
1+
name: CI
22

33
on:
44
push:
@@ -10,40 +10,43 @@ on:
1010
- 'docs/**'
1111
- '*.md'
1212

13+
permissions:
14+
contents: read
15+
1316
jobs:
1417
dependency-review:
1518
name: Dependency Review
1619
if: github.event_name == 'pull_request'
1720
runs-on: ubuntu-latest
18-
permissions:
19-
contents: read
2021
steps:
21-
- name: Check out repo
22-
uses: actions/checkout@v3
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
2324
with:
2425
persist-credentials: false
2526

2627
- name: Dependency review
27-
uses: actions/dependency-review-action@v2
28+
uses: actions/dependency-review-action@v4
2829

2930
test:
3031
runs-on: ${{ matrix.os }}
31-
permissions:
32-
contents: read
3332
strategy:
3433
matrix:
35-
node-version: [14, 16, '*']
34+
node-version: [16, 18, 20]
3635
os: [ubuntu-latest, windows-latest, macOS-latest]
36+
fail-fast: false
3737
steps:
38-
- uses: actions/checkout@v3
38+
- name: Checkout repository
39+
uses: actions/checkout@v4
3940
with:
4041
persist-credentials: false
4142

4243
- name: Use Node.js
43-
uses: actions/setup-node@v3
44+
uses: actions/setup-node@v4
4445
with:
4546
node-version: ${{ matrix.node-version }}
4647
check-latest: true
48+
cache: npm
49+
cache-dependency-path: package.json
4750

4851
- name: Install
4952
run: |
@@ -67,8 +70,6 @@ jobs:
6770
coverage:
6871
needs: test
6972
runs-on: ubuntu-latest
70-
permissions:
71-
contents: read
7273
steps:
7374
- name: Coveralls Finished
7475
uses: coverallsapp/github-action@master
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: sast
1+
name: CodeQL
22

33
on:
44
push:
@@ -11,19 +11,25 @@ jobs:
1111
name: Analyze
1212
runs-on: ubuntu-latest
1313
permissions:
14+
actions: read
1415
contents: read
1516
security-events: write
1617
strategy:
1718
fail-fast: true
1819
matrix:
19-
language: [ 'javascript' ]
20+
language: [ 'javascript-typescript' ]
2021
steps:
21-
- uses: actions/checkout@v3
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
2224
with:
2325
persist-credentials: false
2426

25-
- uses: github/codeql-action/init@v2
27+
- name: Initialize CodeQL
28+
uses: github/codeql-action/init@v3
2629
with:
2730
languages: ${{ matrix.language }}
2831

29-
- uses: github/codeql-action/analyze@v2
32+
- name: Perform CodeQL Analysis
33+
uses: github/codeql-action/analyze@v3
34+
with:
35+
category: "/language:${{ matrix.language }}"

.github/workflows/labeler.yml

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
name: "Pull Request Labeler"
1+
name: Pull Request Labeler
2+
23
on: pull_request_target
34

5+
permissions:
6+
contents: read
7+
pull-requests: write
8+
49
jobs:
510
label:
611
runs-on: ubuntu-latest
712
steps:
8-
- uses: actions/labeler@main
9-
with:
10-
repo-token: "${{ secrets.GITHUB_TOKEN }}"
13+
- uses: actions/labeler@v5
14+
with:
15+
repo-token: "${{ secrets.GITHUB_TOKEN }}"

README.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
<!-- markdownlint-disable MD013 MD024 -->
1+
<!-- markdownlint-disable MD013 -->
22
# Aedes
33

44
![ci](https://github.com/moscajs/aedes/workflows/ci/badge.svg)
5-
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/)
5+
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/)
66
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/moscajs/aedes/graphs/commit-activity)
77
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/moscajs/aedes/pulls)\
8-
[![Total alerts](https://img.shields.io/lgtm/alerts/g/moscajs/aedes.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/moscajs/aedes/alerts/)
9-
[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/moscajs/aedes.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/moscajs/aedes/context:javascript)
108
[![Coverage Status](https://coveralls.io/repos/moscajs/aedes/badge.svg?branch=main&service=github)](https://coveralls.io/github/moscajs/aedes?branch=main)
119
[![Known Vulnerabilities](https://snyk.io/test/github/moscajs/aedes/badge.svg)](https://snyk.io/test/github/moscajs/aedes)\
1210
![node](https://img.shields.io/node/v/aedes)
@@ -281,6 +279,12 @@ Here is a list of some interesting projects that are using Aedes as MQTT Broker.
281279
Want to contribute? Check our list of
282280
[features/bugs](https://github.com/moscajs/aedes/projects/1)
283281

282+
## Security notice
283+
284+
Messages sent to the broker are considered _valid_ once they pass the [`authorizePublish`](./docs/Aedes.md#handler-authorizepublish-client-packet-callback) callback.
285+
In other terms, if permissions for the given client are revoked after the call completes, the message is still considered valid.
286+
In case you are sending time-sensitive messages, make sure to use QoS 0 or connect with a clean session.
287+
284288
## Support
285289

286290
If there are bugs/leaks in production scenarios, we encourage people to send Pull Request and/or reach out maintainers for some paid support.

SECURITY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
## Reporting a Vulnerability
44

5-
Please email daniel.sorridi+aedes@gmail.com; matteo.collina+aedes@gmail.com
5+
Please report all vulnerabilities to [https://github.com/moscajs/aedes/security](https://github.com/moscajs/aedes/security).

aedes.d.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
/// <reference path="./types/instance.d.ts" />
2-
/// <reference path="./types/client.d.ts" />
3-
/// <reference path="./types/packet.d.ts" />
1+
import Aedes, { AedesOptions } from './types/instance'
2+
3+
export declare function createBroker(options?: AedesOptions): Aedes
4+
5+
export * from './types/instance'
6+
export * from './types/packet'
7+
export * from './types/client'
8+
9+
export { default } from './types/instance'

aedes.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const Client = require('./lib/client')
1414
const { $SYS_PREFIX, bulk } = require('./lib/utils')
1515
const _ = require('lodash')
1616

17-
module.exports = Aedes.Server = Aedes
17+
module.exports = Aedes.createBroker = Aedes
1818

1919
const defaultOptions = {
2020
concurrency: 100,
@@ -31,7 +31,8 @@ const defaultOptions = {
3131
sharedTopicsEnabled: false,
3232
trustedProxies: [],
3333
queueLimit: 42,
34-
maxClientsIdLength: 23
34+
maxClientsIdLength: 23,
35+
keepaliveLimit: 0
3536
}
3637

3738
function Aedes (opts) {
@@ -49,6 +50,7 @@ function Aedes (opts) {
4950
this.counter = 0
5051
this.queueLimit = opts.queueLimit
5152
this.connectTimeout = opts.connectTimeout
53+
this.keepaliveLimit = opts.keepaliveLimit
5254
this.maxClientsIdLength = opts.maxClientsIdLength
5355
this.mq = opts.mq || mqemitter({
5456
concurrency: opts.concurrency,
@@ -171,7 +173,13 @@ function Aedes (opts) {
171173
const clientId = packet.payload.toString()
172174

173175
if (that.clients[clientId] && serverId !== that.id) {
174-
that.clients[clientId].close(done)
176+
if (that.clients[clientId].closed) {
177+
// remove the client from the list if it is already closed
178+
that.deleteClient(clientId)
179+
done()
180+
} else {
181+
that.clients[clientId].close(done)
182+
}
175183
} else {
176184
done()
177185
}
@@ -347,15 +355,19 @@ Aedes.prototype._finishRegisterClient = function (client) {
347355
}
348356

349357
Aedes.prototype.unregisterClient = function (client) {
350-
this.connectedClients--
351-
delete this.clients[client.id]
358+
this.deleteClient(client.id)
352359
this.emit('clientDisconnect', client)
353360
this.publish({
354361
topic: $SYS_PREFIX + this.id + '/disconnect/clients',
355362
payload: Buffer.from(client.id, 'utf8')
356363
}, noop)
357364
}
358365

366+
Aedes.prototype.deleteClient = function (clientId) {
367+
this.connectedClients--
368+
delete this.clients[clientId]
369+
}
370+
359371
function closeClient (client, cb) {
360372
this.clients[client].close(cb)
361373
}

docs/Aedes.md

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
- `heartbeatInterval` `<number>` an interval in millisconds at which server beats its health signal in `$SYS/<aedes.id>/heartbeat` topic. __Default__: `60000`
4343
- `id` `<string>` aedes broker unique identifier. __Default__: `uuidv4()`
4444
- `connectTimeout` `<number>` maximum waiting time in milliseconds waiting for a [`CONNECT`][CONNECT] packet. __Default__: `30000`
45+
- `keepaliveLimit` `<number>` maximum client keep alive time allowed, 0 means no limit. __Default__: `0`
4546
- Returns `<Aedes>`
4647

4748
Create a new Aedes server.

docs/Examples.md

+16
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ server.listen(port, function () {
1313
})
1414
```
1515

16+
## Typescript
17+
18+
```ts
19+
import Aedes from 'aedes'
20+
import { createServer } from 'net'
21+
22+
const port = 1883
23+
24+
const aedes = new Aedes()
25+
const server = createServer(aedes.handle)
26+
27+
server.listen(port, function () {
28+
console.log('server started and listening on port ', port)
29+
})
30+
```
31+
1632
## Simple plain MQTT server using server-factory
1733

1834
```js

examples/clusters/index.js

+30-18
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,46 @@
11
const cluster = require('cluster')
2-
const mqemitter = require('mqemitter-mongodb')
3-
const mongoPersistence = require('aedes-persistence-mongodb')
4-
2+
const Aedes = require('aedes')
3+
const { createServer } = require('net')
4+
const { cpus } = require('os')
55
const MONGO_URL = 'mongodb://127.0.0.1/aedes-clusters'
66

7+
const mq = process.env.MQ === 'redis'
8+
? require('mqemitter-redis')({
9+
port: process.env.REDIS_PORT || 6379
10+
})
11+
: require('mqemitter-mongodb')({
12+
url: MONGO_URL
13+
})
14+
15+
const persistence = process.env.PERSISTENCE === 'redis'
16+
? require('aedes-persistence-redis')({
17+
port: process.env.REDIS_PORT || 6379
18+
})
19+
: require('aedes-persistence-mongodb')({
20+
url: MONGO_URL
21+
})
22+
723
function startAedes () {
824
const port = 1883
925

10-
const aedes = require('aedes')({
26+
const aedes = Aedes({
1127
id: 'BROKER_' + cluster.worker.id,
12-
mq: mqemitter({
13-
url: MONGO_URL
14-
}),
15-
persistence: mongoPersistence({
16-
url: MONGO_URL,
17-
// Optional ttl settings
18-
ttl: {
19-
packets: 300, // Number of seconds
20-
subscriptions: 300
21-
}
22-
})
28+
mq,
29+
persistence
2330
})
2431

25-
const server = require('net').createServer(aedes.handle)
32+
const server = createServer(aedes.handle)
2633

27-
server.listen(port, function () {
34+
server.listen(port, '0.0.0.0', function () {
2835
console.log('Aedes listening on port:', port)
2936
aedes.publish({ topic: 'aedes/hello', payload: "I'm broker " + aedes.id })
3037
})
3138

39+
server.on('error', function (err) {
40+
console.log('Server error', err)
41+
process.exit(1)
42+
})
43+
3244
aedes.on('subscribe', function (subscriptions, client) {
3345
console.log('MQTT client \x1b[32m' + (client ? client.id : client) +
3446
'\x1b[0m subscribed to topics: ' + subscriptions.map(s => s.topic).join('\n'), 'from broker', aedes.id)
@@ -56,7 +68,7 @@ function startAedes () {
5668
}
5769

5870
if (cluster.isMaster) {
59-
const numWorkers = require('os').cpus().length
71+
const numWorkers = cpus().length
6072
for (let i = 0; i < numWorkers; i++) {
6173
cluster.fork()
6274
}

examples/clusters/package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
"author": "robertsLando",
1010
"license": "MIT",
1111
"dependencies": {
12-
"aedes": "^0.45.0",
13-
"aedes-persistence-mongodb": "^7.0.1",
14-
"mqemitter-mongodb": "^7.0.1"
12+
"aedes": "^0.48.1",
13+
"aedes-persistence-mongodb": "^9.1.0",
14+
"aedes-persistence-redis": "^9.0.1",
15+
"mqemitter-mongodb": "^8.1.0",
16+
"mqemitter-redis": "^5.0.0"
1517
}
1618
}

lib/client.js

+7
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,14 @@ Client.prototype.close = function (done) {
320320
}, noop)
321321
}
322322
})
323+
} else if (will) {
324+
// delete the persisted will even on clean disconnect https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349232
325+
that.broker.persistence.delWill({
326+
id: that.id,
327+
brokerId: that.broker.id
328+
}, noop)
323329
}
330+
324331
that.will = null // this function might be called twice
325332
that._will = null
326333

0 commit comments

Comments
 (0)