2019-11-04 22:27:36 +00:00
|
|
|
const express = require("express");
|
|
|
|
const app = express();
|
2019-11-04 22:56:58 +00:00
|
|
|
const request = require("request");
|
2019-11-04 22:27:36 +00:00
|
|
|
|
2019-11-03 11:33:59 +00:00
|
|
|
var fuzIsOpen = false;
|
2019-11-03 11:45:01 +00:00
|
|
|
var lastSeen = new Date("1970-01-01");
|
2019-11-03 19:31:00 +00:00
|
|
|
var lastNofified = new Date("1970-01-01");
|
|
|
|
var lastClosed = new Date("1970-01-01");
|
2019-11-03 11:45:01 +00:00
|
|
|
|
|
|
|
const fs = require("fs");
|
|
|
|
const db = "./.data/data.json";
|
2019-11-04 23:30:51 +00:00
|
|
|
const closingTimeout = 5 * 60 * 1000; // 5 mins
|
2019-11-03 11:45:01 +00:00
|
|
|
|
|
|
|
try {
|
|
|
|
var content = fs.readFileSync(db, "utf8");
|
2019-11-03 19:43:00 +00:00
|
|
|
fuzIsOpen = JSON.parse(content)["fuzIsOpen"] || fuzIsOpen;
|
|
|
|
lastSeen = new Date(JSON.parse(content)["lastSeen"] || lastSeen);
|
|
|
|
lastNofified = new Date(JSON.parse(content)["lastNofified"] || lastNofified);
|
|
|
|
lastClosed = new Date(JSON.parse(content)["lastClosed"] || lastClosed);
|
2019-11-03 11:45:01 +00:00
|
|
|
} catch (err) {}
|
2019-11-03 11:33:59 +00:00
|
|
|
|
2019-09-30 21:05:06 +00:00
|
|
|
app.use(express.static("public"));
|
2018-03-13 20:25:39 +00:00
|
|
|
|
2019-11-03 11:33:59 +00:00
|
|
|
app.get("/", (req, res) => {
|
|
|
|
res.sendFile(__dirname + "/views/index.html");
|
|
|
|
});
|
|
|
|
|
|
|
|
app.get("/img", (req, res) => {
|
2019-11-04 23:42:52 +00:00
|
|
|
if (fuzIsOpen && new Date() - closingTimeout < lastSeen) {
|
2019-11-05 08:54:58 +00:00
|
|
|
return res.sendFile(__dirname + "/views/open.svg"); // https://www.flaticon.com/free-icon/open_1234189, maybe try https://flaticons.net/customize.php?dir=Miscellaneous&icon=Open.png without attribution
|
2019-11-03 11:45:01 +00:00
|
|
|
}
|
2019-11-05 08:42:57 +00:00
|
|
|
res.sendFile(__dirname + "/views/closed.svg"); // https://www.flaticon.com/free-icon/closed_1234190, maybe try https://flaticons.net/customize.php?dir=Miscellaneous&icon=Closed.png without attribution
|
2018-03-13 20:25:39 +00:00
|
|
|
});
|
2019-11-04 22:03:48 +00:00
|
|
|
|
2019-11-03 11:56:59 +00:00
|
|
|
app.get("/api", (req, res) => {
|
2019-11-03 15:01:00 +00:00
|
|
|
res.header("Access-Control-Allow-Origin", "*");
|
|
|
|
res.header(
|
|
|
|
"Access-Control-Allow-Headers",
|
|
|
|
"Origin, X-Requested-With, Content-Type, Accept"
|
|
|
|
);
|
2019-11-03 22:54:02 +00:00
|
|
|
res.send({ fuzIsOpen, lastSeen, lastClosed });
|
2019-11-03 11:56:59 +00:00
|
|
|
});
|
2018-03-13 20:25:39 +00:00
|
|
|
|
2019-11-03 11:33:59 +00:00
|
|
|
app.get("/status", (req, res) => {
|
2019-11-03 15:24:00 +00:00
|
|
|
// http basic auth handling without 3rd-party lib https://stackoverflow.com/a/33905671
|
|
|
|
const auth = {
|
|
|
|
login: process.env.MATRIXUSERNAME,
|
|
|
|
password: process.env.MATRIXPASSWORD
|
2019-11-03 15:35:01 +00:00
|
|
|
};
|
2019-11-03 15:12:01 +00:00
|
|
|
|
|
|
|
// parse login and password from headers
|
2019-11-03 15:24:00 +00:00
|
|
|
const b64auth = (req.headers.authorization || "").split(" ")[1] || "";
|
2019-11-03 16:10:01 +00:00
|
|
|
const [_, login, password] =
|
|
|
|
new Buffer(b64auth, "base64").toString().match(/(.*):(.*)/) || []; // slightly modified as we use : in username
|
2019-11-03 15:47:00 +00:00
|
|
|
|
2019-11-03 15:35:01 +00:00
|
|
|
if (
|
|
|
|
!login ||
|
|
|
|
!password ||
|
|
|
|
login !== auth.login ||
|
|
|
|
password !== auth.password
|
|
|
|
) {
|
2019-11-03 16:10:01 +00:00
|
|
|
console.log(login, password);
|
2019-11-03 15:35:01 +00:00
|
|
|
res.set("WWW-Authenticate", 'Basic realm="Authentication required"');
|
|
|
|
return res.status(401).send("Authentication required.");
|
2019-11-03 11:33:59 +00:00
|
|
|
}
|
2019-11-03 17:57:00 +00:00
|
|
|
fuzIsOpen = req.query.fuzisopen === "1";
|
2019-11-03 14:37:00 +00:00
|
|
|
lastSeen = new Date();
|
2019-11-03 11:56:59 +00:00
|
|
|
try {
|
2019-11-03 23:06:02 +00:00
|
|
|
fs.writeFileSync(db, JSON.stringify({ fuzIsOpen, lastSeen, lastClosed }));
|
2019-11-03 11:56:59 +00:00
|
|
|
} catch (err) {}
|
|
|
|
|
2019-11-03 11:33:59 +00:00
|
|
|
res.sendStatus(200);
|
2019-11-03 11:22:00 +00:00
|
|
|
});
|
|
|
|
|
2018-10-15 15:38:54 +00:00
|
|
|
const listener = app.listen(process.env.PORT, function() {
|
2019-09-30 21:05:06 +00:00
|
|
|
console.log("Your app is listening on port " + listener.address().port);
|
2018-03-13 20:25:39 +00:00
|
|
|
});
|
2019-11-03 11:22:00 +00:00
|
|
|
|
2019-11-04 23:08:36 +00:00
|
|
|
request.post(
|
|
|
|
{
|
2019-11-04 22:56:58 +00:00
|
|
|
url:
|
|
|
|
"https://" +
|
|
|
|
process.env.MATRIXUSERNAME.substring(
|
|
|
|
process.env.MATRIXUSERNAME.indexOf(":") + 1
|
|
|
|
) +
|
|
|
|
"/_matrix/client/r0/login",
|
2019-11-04 23:08:36 +00:00
|
|
|
body: JSON.stringify({
|
|
|
|
type: "m.login.password",
|
|
|
|
user: process.env.MATRIXUSERNAME.substring(
|
|
|
|
0,
|
|
|
|
process.env.MATRIXUSERNAME.indexOf(":")
|
|
|
|
),
|
|
|
|
password: process.env.MATRIXPASSWORD,
|
|
|
|
identifier: {
|
|
|
|
type: "m.id.user",
|
|
|
|
user: process.env.MATRIXUSERNAME.substring(
|
|
|
|
0,
|
|
|
|
process.env.MATRIXUSERNAME.indexOf(":")
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}),
|
2019-11-04 22:56:58 +00:00
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json"
|
|
|
|
}
|
2019-11-04 23:08:36 +00:00
|
|
|
},
|
|
|
|
function(error, response, body) {
|
|
|
|
console.log(body);
|
2019-11-04 23:19:45 +00:00
|
|
|
const accessToken = JSON.parse(body)["access_token"];
|
2019-11-04 22:56:58 +00:00
|
|
|
const loop = () => {
|
|
|
|
console.log("loop", lastClosed);
|
2019-11-05 10:04:43 +00:00
|
|
|
if (fuzIsOpen && lastSeen < new Date() - closingTimeout && lastClosed < lastSeen) {
|
2019-11-04 22:56:58 +00:00
|
|
|
// the Fuz is newly closed, notify on matrix and write file to survive reboot
|
|
|
|
lastClosed = new Date();
|
|
|
|
//lastNofified = new Date();
|
|
|
|
//https.post ... send message to Fuz process.env.MATRIXROOM
|
2019-11-04 23:19:45 +00:00
|
|
|
request.put(
|
|
|
|
{
|
|
|
|
url:
|
|
|
|
"https://" +
|
|
|
|
process.env.MATRIXUSERNAME.substring(
|
|
|
|
process.env.MATRIXUSERNAME.indexOf(":") + 1
|
|
|
|
) +
|
2019-11-04 23:30:51 +00:00
|
|
|
"/_matrix/client/r0/rooms/" +
|
|
|
|
process.env.MATRIXROOM +
|
|
|
|
"/send/m.room.message/" +
|
|
|
|
new Date().getTime() +
|
|
|
|
"?access_token=" +
|
|
|
|
accessToken +
|
|
|
|
"&limit=1",
|
2019-11-04 23:19:45 +00:00
|
|
|
body: JSON.stringify({
|
|
|
|
msgtype: "m.text",
|
|
|
|
body: process.env.MATRIXMESSAGE
|
|
|
|
}),
|
|
|
|
headers: {
|
|
|
|
"Content-Type": "application/json"
|
|
|
|
}
|
|
|
|
},
|
2019-11-04 23:30:51 +00:00
|
|
|
function(error, response, body2) {
|
|
|
|
if (!error) {
|
|
|
|
try {
|
|
|
|
fs.writeFileSync(
|
|
|
|
db,
|
|
|
|
JSON.stringify({ fuzIsOpen, lastSeen, lastClosed })
|
|
|
|
);
|
|
|
|
} catch (err) {}
|
|
|
|
}
|
|
|
|
console.log(body2)
|
|
|
|
setTimeout(loop, 10 * 1000);
|
|
|
|
}
|
2019-11-04 23:19:45 +00:00
|
|
|
);
|
2019-11-04 23:30:51 +00:00
|
|
|
} else {
|
|
|
|
setTimeout(loop, 10 * 1000);
|
2019-11-04 22:56:58 +00:00
|
|
|
}
|
|
|
|
};
|
2019-11-04 23:42:52 +00:00
|
|
|
setTimeout(loop, 1 * 60 * 1000); // give some time for presence button to show up (1 min)
|
2019-11-04 23:08:36 +00:00
|
|
|
}
|
|
|
|
);
|
2019-11-03 19:19:00 +00:00
|
|
|
|
2019-11-03 17:45:01 +00:00
|
|
|
if (process.env.PROJECT_DOMAIN != "") {
|
|
|
|
process.on("SIGTERM", function() {
|
|
|
|
console.log("SIGTERM received, sending SOS to Resurrect...");
|
|
|
|
require("https").get(
|
|
|
|
"https://resurrect.glitch.me/" + process.env.PROJECT_DOMAIN + "",
|
|
|
|
process.exit
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|