-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
104 lines (85 loc) · 2.54 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
const _ = require("lodash");
const topics = [];
const mqttPattern = require("mqtt-pattern");
let subscriptionTopics = [];
let publishTopics = [];
exports.clearTopics = () => {
subscriptionTopics = [];
publishTopics = [];
};
/**
* Function to be used as plugin to the aedes.instance.authorizeSubscribe
* See Aedes documentation for more detail
*/
exports.authorizeSubscribe = async (client, sub, callback) => {
let topic = isSubscriptionTopic(sub.topic);
if (!topic) {
return callback({ returnCode: 4 }, null);
}
await authorize(client, sub, callback, topic, subscriptionTopics);
};
/**
* Function to be used as plugin to the aedes.instance.authorizePublish
* See Aedes documentation for more detail
*/
exports.authorizePublish = async (client, sub, callback) => {
let topic = isPublishTopic(sub.topic);
if (!topic) {
return callback({ returnCode: 4 }, null);
}
await authorize(client, sub, callback, topic, publishTopics);
};
/**
* Adds an expected MQTT topic prototype
* @param {string} topic expected mqtt topic prototype
* @param {function(client,sub)} authorizer authoization function to be evaluated upon subscription
* @param {object} opts isPublishTopic || isSubscriptionTopic - empty object assumes both subscription and publish topic
*/
exports.addTopic = (topic, authorizer, opts) => {
if (!authorizer) {
throw Error("No authorization function defined.");
}
let out = {
topic,
authorizer
};
if (!opts || (!opts.isSubscriptionTopic && !opts.isPublishTopic)) {
subscriptionTopics.push(out);
publishTopics.push(out);
}
if (opts && opts.isSubscriptionTopic) {
subscriptionTopics.push(out);
}
if (opts && opts.isPublishTopic) {
publishTopics.push(out);
}
return;
};
async function authorize(client, sub, callback, pattern, topicList) {
sub.params = mqttPattern.exec(pattern.topic, sub.topic);
let auth = await pattern.authorizer(client, sub);
if (auth) {
// everything is bene
callback(null, sub);
} else {
// have to do this because of bug in retained Aedes subscription payloads
return callback({ returnCode: 4 }, null);
}
}
isSubscriptionTopic = topic => {
for (let i = 0; i < subscriptionTopics.length; i++) {
let test = mqttPattern.exec(subscriptionTopics[i].topic, topic);
if (test) {
return subscriptionTopics[i];
}
}
return false;
};
isPublishTopic = topic => {
for (let i = 0; i < publishTopics.length; i++) {
if (mqttPattern.exec(publishTopics[i].topic, topic)) {
return publishTopics[i];
}
}
return false;
};