-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
170 lines (146 loc) · 6.11 KB
/
main.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
const fs = require("fs")
const http = require("http");
const https = require('https');
var host = "localhost";
var port = 8000;
var adminPasscode = "";
const maxNameCharacters = 16;
const maxEmailCharacters = 24;
const maxMessageCharacters = 4096;
const minMessageCharacters = 2;
const defaultContent =
"<div class=\"comment\">\n" +
" <em title=\"EMAIL\">NAME said:</em>\n" +
" <em class=\"comment-date\">DATE</em>\n" +
" <p>CONTENT</p>\n" +
"</div>\n";
function sanitise(string) {
return string.replace(/&/g,"&").replace(/</g,"<").replace(/"/g,""");
}
function urlify(string) {
var urlRegex = /(https?:\/\/[^\s]+)/g;
return string.replace(urlRegex, function(url) {
if (string.includes(".gif") || string.includes(".png") || string.includes(".jpg") || string.includes(".webp")) {
return '<img src="' + url + '" width="300px">';
}
return '<a href="' + url + '">' + url + '</a>';
})
}
//Check for empty / whitespace strings
function isBlank(string) {
return (!string || /^\s*$/.test(string));
}
const requestListener = function (req, res) { //request (incoming) response (outgoing)
res.setHeader("Content-Type", "text/html");
res.setHeader("Access-Control-Allow-Origin", "*");
res.writeHead(200);
if (req.method == "GET") {
fs.readFile("comments.html", 'utf8' , (err, newContent) => {
if (err) {
console.error(err)
return
}
res.end(newContent);
});
}
if (req.method == "POST") {
let body = '';
req.on('data', chunk => {
//Convert Buffer to string
body += chunk.toString();
});
req.on('end', () => {
fs.readFile("comments.html", (err, data) => {
if (err) {
console.error(err);
return;
}
//Generated ANSI escape codes from @https://ansi.gabebanks.net/
try {
var commentObject = JSON.parse(body);
if (isBlank(commentObject.name)) { //Check for blank name
commentObject.name = "Anonymous";
}
if (isBlank(commentObject.email) || !commentObject.email.includes("@")) { //Check for blank or invalid email
commentObject.email = "anonymous@anonymous.com";
}
if (isBlank(commentObject.message) || commentObject.message.trim().length <= minMessageCharacters) { //Check for blank message
console.log("\033[90;49;3mEmpty or spam comment detected, rejecting.\033[0m");
return;
}
//Trim all aspects, to prevent server overload and spam.
commentObject.name = commentObject.name.substring(0, maxNameCharacters);
commentObject.email = commentObject.email.substring(0, maxEmailCharacters);
commentObject.message = commentObject.message.substring(0, maxMessageCharacters);
//The order of these operations is important, or else things may go south...
commentObject.message = sanitise(commentObject.message);
commentObject.message = urlify(commentObject.message);
let date = new Date();
var bodyHTML = commentObject.message.replaceAll("\n", "<br>");
var newComments = defaultContent
.replace("EMAIL", commentObject.email)
.replace("NAME", commentObject.name)
.replace("DATE", `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`)
.replace("CONTENT", bodyHTML) + "\n" + data
;
fs.writeFile("comments.html", newComments, err => {
if (err) {
console.error(err);
return;
}
console.log("\033[90;49;3mSucessfully added comment | " + req.socket.remoteAddress + " | " + commentObject.name + " | " + commentObject.email + " | " + commentObject.message + "\033[0m");
});
}
catch (exception) {
console.error(`Critical failure when posting message:\n${exception}, from ${req.socket.remoteAddress}`);
}
});
});
}
};
function startServer() {
if (!fs.existsSync("comments_server.conf")) {
const defaultConfig = {host: host, port: port, adminPasscode: adminPasscode, httpsEnabled: false, certPath: "", keyPath: "" };
fs.writeFile("comments_server.conf", JSON.stringify(defaultConfig, null, 2), err => {
if (err) {
console.error(err);
return;
}
});
}
fs.readFile("comments_server.conf", 'utf8' , (err, config) => {
if (err) {
console.error(err)
return
}
var configObject = JSON.parse(config);
host = configObject.host;
port = configObject.port;
adminPasscode = configObject.adminPasscode;
httpsEnabled = configObject.httpsEnabled;
var server;
if (configObject.httpsEnabled) {
const options = {
key: fs.readFileSync(configObject.keyPath),
cert: fs.readFileSync(configObject.certPath)
};
server = https.createServer(options, requestListener);
}
else {
server = http.createServer(requestListener);
}
server.listen(port, host, () => {
console.log(`Server is running on http${configObject.httpsEnabled ? "s" : ""}://${host}:${port}`);
if (!fs.existsSync("comments.html"))
{
fs.writeFile("comments.html", "", err => {
if (err) {
console.error(err);
return;
}
});
}
});
});
}
startServer();