This repository has been archived by the owner on Jun 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
246 lines (223 loc) · 7.3 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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/*
* ====================NOTE====================
* This code was created by LostAndDead,
* please don't claim this as your own work
* https://github.com/LostAndDead
* ============================================
*/
//We require the mqtt library and file system
var mqtt = require('mqtt');
var fs = require('fs')
//We also nedd readline for taking input and serverline for a pretiier input console
const readline = require('readline');
const sl = require("serverline")
//A lot of global varibles declared
var ip;
var p;
var tls;
var keyFile;
var keyFilePath;
var certFile;
var certFilePath;
var caFile;
var caFilePath;
var subChannel;
var pubChannel;
var log = true;
//And some default values if the user doesnt enter them
var ipDefault = "192.168.1.109"
var portDefault = "8883"
var tlsDefault = true
var keyFileDefault = "./certs/user1.key"
var certFileDefault = "./certs/user1.crt"
var caFileDefault = "./certs/ca.crt"
var subChannelDefault = "test"
var pubChannelDefault = "test"
//Call the main loop
main();
async function main(){
/*
All of these are very simular we just clear the console for a nice look
then we ask the user to setup the value, if they dont give anything we assume
default value and move on to the next question
*/
console.clear()
ip = await askQuestion(`Enter the IP or FQDN of the Mosquitto Server \x1b[4m(${ipDefault})\n\x1b[0m> `)
if (ip == ""){
ip = ipDefault
}
console.clear()
p = await askQuestion(`Enter the port for the Mosquitto Server \x1b[4m(${portDefault})\n\x1b[0m> `)
if (p == ""){
p = portDefault
}
console.clear()
tls = await askQuestion(`Do you want to use TLS? \x1b[4m(${tlsDefault})\n\x1b[0m> `)
if (tls == ""){
tls = tlsDefault
}else if(tls.toLowerCase() == "true" || tls.toLowerCase() == "yes" || tls.toLowerCase() == "y"){
tls = true
}else {
tls = false
}
/*
These options are only asked for if the user wants to use tls,
if they dont we skip past
*/
if(tls){
console.clear()
keyFilePath = await askQuestion(`Enter the file path to your key file. \x1b[4m(${keyFileDefault})\n\x1b[0m> `)
if (keyFilePath == ""){
keyFilePath = keyFileDefault
}
try {
keyFile = fs.readFileSync(keyFilePath, 'utf8')
console.log(data)
} catch (err) {
console.error(err)
}
console.clear()
certFilePath = await askQuestion(`Enter the file path to your certificate file. \x1b[4m(${certFileDefault})\n\x1b[0m> `)
if (certFilePath == ""){
certFilePath = certFileDefault
}
try {
certFile = fs.readFileSync(certFilePath, 'utf8')
console.log(data)
} catch (err) {
console.error(err)
}
console.clear()
caFilePath = await askQuestion(`Enter the file path to your certificate authority file. \x1b[4m(${caFileDefault})\n\x1b[0m> `)
if (caFilePath == ""){
caFilePath = caFileDefault
}
try {
caFile = fs.readFileSync(caFilePath, 'utf8')
console.log(data)
} catch (err) {
console.error(err)
}
}
console.clear()
subChannel = await askQuestion(`Which channel would you like to subscribe to? \x1b[4m(${subChannelDefault})\n\x1b[0m> `)
if (subChannel == ""){
subChannel = subChannelDefault
}
console.clear()
pubChannel = await askQuestion(`Which channel would you like to publish to? \x1b[4m(${pubChannelDefault})\n\x1b[0m> `)
if (pubChannel == ""){
pubChannel = pubChannelDefault
}
/*
We give the user a bit of info about what they connected to and
what authentication they are using (if they are using any)
*/
console.clear()
console.log(`\x1b[0mConnected to \x1b[35m${ip + "\x1b[37m:\x1b[32m" + p}`)
if(tls){
console.log(`\x1b[0m\nKey File: \x1b[4m${keyFilePath}`)
console.log(`\x1b[0mCertificate File: \x1b[4m${certFilePath}`)
console.log(`\x1b[0mCertificate Authority File: \x1b[4m${caFilePath}`)
}
console.log(`\n\x1b[0m\x1b[34mSubscribed to ${subChannel}`)
console.log(`\x1b[33mPublishing to ${pubChannel}`)
console.log(`\n\x1b[0mType message to send or close to \x1b[31mclose\n\x1b[33m`)
//Then we run the connect object to establish a connection to the mqtt server
connect();
}
function connect(){
/*
we define 2 different object values depending on wether
the user is using tls or not
*/
var options
if(tls){
options = {
port: p,
host: ip,
key: keyFile,
cert: certFile,
rejectUnauthorized: true,
ca: caFile,
username: "node1",
protocol: "mqtts",
/*
Ignore these for now im testing modifications to packets and
authentication but it wont do anything for you as its a edited
npm module that handles it.
*/
clientId: "node1-id",
randomValue: "bob"
}
}else{
options = {
port: p,
host: ip,
rejectUnauthorized: true,
protocol: "mqtt"
}
}
//We simply connect if there is an authentication error it should be thrown here
var client = mqtt.connect(options)
//We define what hands once we have successfully connected
client.on('connect', function () {
/*We just subscribe to the channel the user wants
and if there is an error we throw it and close
*/
client.subscribe(subChannel, function (err) {
if (err) {
console.log(err)
client.end()
}
})
})
/*
When we get a messagewe just log it to the console window
*/
client.on('message', function (topic, message, packet) {
/*
This log value is just weather we actualy want to show the user the message
Its here becuase just after we send a message it loops back to us as an incoming message,
this simply stops that
*/
if(log == true){
console.log("\x1b[34m> "+message.toString()+"\x1b[33m")
//Debugging packets
//console.log(packet)
}
})
//We create the server line instance
sl.init()
/*
Server line is great as it makes the input line always at the bottom
we use this just to make it prettier and stopping the input being
above output
*/
sl.on('line', function(line) {
//If they say close we just close the connection and exit the program
if (line == "close"){
console.log("\x1b[0m")
sl.close()
process.exit()
}
//Actualy publish the message the user wants to send
client.publish(pubChannel, line)
//Stop feed back for 10ms
log = false;
setTimeout(function () {
log = true
}, 10)
})
}
//Just handles answering questions to the user for easy repetition and re-use
function askQuestion(query) {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
return new Promise(resolve => rl.question(query, ans => {
rl.close();
resolve(ans);
}))
}