(() => {
var pendingRequestsResponses = {}
const headers = {
'Content-Type': 'application/json'
}
function handleRequest(req, res, body) {
let uuid = req.url.match("(?<=^\/md\/web\/two-way\/)[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(?=\/.*$)");
if (!uuid) {
res.writeHead(400, headers);
let resp = { error: { basic: "Invalid request", detailed: "The provided request is invalid (the id couldn't be found).", errcode: "err_invalid_uuid" } }
res.write(JSON.stringify(resp));
res.end();
return;
}
uuid = uuid[0];
fetch(`https://trigger.macrodroid.com/${uuid}/`).then(async response => {
if (response.status == 404) {
res.writeHead(404, headers);
let resp = { error: { basic: "Invalid id", detailed: "The provided device id is invalid.", errcode: "err_invalid_uuid" } }
res.write(JSON.stringify(resp));
res.end();
return;
} else if (response.status == 200) {
let rid = req.url.match("(?<=^\/md\/web\/two-way\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/).*$");
if (!rid) rid = [""];
rid = rid[0];
let id = hash(Date.now().toString() + Math.random().toString());
pendingRequestsResponses[id] = { "time": Date.now(), "response": null }
pendingRequestsResponses[id]["promise"] = new Promise(resolve => {
pendingRequestsResponses[id]["resolve"] = resolve;
})
setTimeout(() => {
if (pendingRequestsResponses[id]) {
pendingRequestsResponses[id].resolve();
setTimeout(() => {
delete pendingRequestsResponses[id];
}, 1000)
}
}, 30000)
let thisorthat = "?";
if (rid.includes("?")) thisorthat = "&";
if (rid.match(/(\?|&)response-id=/)) rid = rid.replaceAll(/response-id=.*?(?=$|&)/g, "response-id=" + id);
let method;
if (body) { method = "POST" } else { method = "GET" };
let r = await fetch(`https://trigger.macrodroid.com/${uuid}/${rid}${thisorthat}response-id=` + id, { method: method, body: body }).catch(() => {
res.writeHead(500, headers);
let resp = { error: { basic: "Request error", detailed: "The server encountered an error making the request.", errcode: "err_request_error" } }
res.write(JSON.stringify(resp));
res.end();
return;
})
if (r.status !== 200) {
res.writeHead(424, headers);
let restext = await res.text();
let resp = { error: { basic: "Request error", detailed: "The backend encountered an error making the request. " + restext, errcode: "err_backend_request_error" } }
res.write(JSON.stringify(resp));
return;
} else {
res.writeHead(200, headers);
await pendingRequestsResponses[id]["promise"];
let resp = { response: pendingRequestsResponses[id]["response"] };
res.write(JSON.stringify(resp));
res.end();
}
} else {
res.writeHead(424, headers);
let restext = await res.text();
let resp = { error: { basic: "Unknown error", detailed: "The backend encountered an error verifying the device id. " + restext, errcode: "err_device_verification_backend_error" } }
res.write(JSON.stringify(resp));
res.end();
return;
}
}).catch((e) => {
console.log(e);
res.writeHead(500, headers);
let resp = { error: { basic: "Verification error", detailed: "The server encountered an error verifying the device id.", errcode: "err_device_verification_error" } }
res.write(JSON.stringify(resp));
res.end();
}
)
}
app.get("/md/web/two-way/*", async (req, res) => {
handleRequest(req, res)
})
app.post("/md/web/two-way/*", async (req, res) => {
let body = [];
req
.on('data', chunk => { body.push(chunk) })
.on('end', () => {
body = Buffer.concat(body).toString();
handleRequest(req, res, body)
})
})
app.post("/md/web/two-way-response/*", async (req, res) => {
let id = req.query["response-id"]
if (pendingRequestsResponses[id]) {
if (pendingRequestsResponses[id]["response"]) {
res.writeHead(409, headers)
let resp = { error: { basic: "Response conflict", detailed: "The response id already has a response assigned to it.", errcode: "err_response_conflict" } }
res.write(JSON.stringify(resp))
res.end()
}
let body = [];
req
.on('data', chunk => { body.push(chunk) })
.on('end', () => {
body = Buffer.concat(body).toString();
// at this point, `body` has the entire request body stored in it as a string
if (pendingRequestsResponses[id]) {
res.writeHead(200, headers)
let resp = { response: "Everything went correctly. Or did it?", rescode: "success" }
res.write(JSON.stringify(resp))
res.end()
pendingRequestsResponses[id]["response"] = body
pendingRequestsResponses[id].resolve()
} else {
res.writeHead(410, headers)
let resp = { error: { basic: "Too late!", detailed: "The provided response id is valid but the original request was finished before this request could finish.", errcode: "err_response_send_timeout" } }
res.write(JSON.stringify(resp))
res.end()
}
});
} else {
res.writeHead(404, headers)
let resp = { error: { basic: "Invalid response id", detailed: "The provided response id is invalid or expired.", errcode: "err_invalid_response_id" } }
res.write(JSON.stringify(resp))
res.end()
}
})
}
)()