godprotocol
Version:
A distributed computing environment for Web 4.0 — integrating AI, decentralisation, and virtual computation.
174 lines (150 loc) • 5.18 kB
JavaScript
import { set_page } from "../html/index.js";
import { generate_random_string } from "generalised-datastore/utils/functions.js";
let PORT = Number(process.env.PORT) || 1408,
account_uids = {};
const set_account_uid = async (uid, account_name, manager) => {
account_uids[uid] = account_name;
manager.oracle.write_local(
`.account_uids/${uid}`,
JSON.stringify({
account_name,
timestamp: Date.now(),
})
);
};
const get_account = async (uid, manager) => {
if (account_uids[uid]) return account_uids[uid];
let account_name = await manager.oracle.read_local(`.account_uids/${uid}`);
if (account_name) account_name = JSON.parse(account_name);
if (account_name && account_name.timestamp) {
// UID valid for a day
if (Date.now() - account_name.timestamp > 86400000) {
delete account_uids[uid];
return null;
} else {
account_name = account_name.account_name;
account_uids[uid] = account_name;
}
}
return account_name;
};
export const handle_routes = async (req, res, manager, app) => {
try {
// CORS
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS"
);
res.setHeader("Access-Control-Allow-Headers", "*");
if (req.method === "OPTIONS") {
res.writeHead(204);
return res.end();
}
// GET pages
if (req.method === "GET") {
if (req.url === "/") {
res.writeHead(200, { "Content-Type": "text/html" });
return res.end(set_page(req.url, manager));
}
if (
["/create_account", "/load", "/run", "/parse", "/oracle"].includes(
req.url
)
) {
res.writeHead(200, { "Content-Type": "text/html" });
return res.end(set_page(req.url.slice(1), manager));
}
// hand over untouched
return app ? app(req, res) : res.writeHead(404).end("Not Found");
}
// Only custom POST endpoints handled here
if (
["/create_account", "/load", "/run", "/parse", "/oracle"].includes(
req.url
)
) {
let body = "";
req.on("data", (chunk) => {
body += chunk;
});
await new Promise((resolve) => req.on("end", resolve));
if (!body) {
res.writeHead(400, { "Content-Type": "application/json" });
return res.end(
JSON.stringify({ error: "Request body cannot be empty" })
);
}
const data = JSON.parse(body);
let result;
switch (req.url) {
case "/create_account": {
let acc = await manager.get_account(data.name);
if (acc) {
if (!(await acc.verify(data.password))) {
result = { message: "Incorrect password." };
} else {
const uid = generate_random_string(16, "alnum");
await set_account_uid(uid, data.name, manager);
result = { uid, message: "Account signed-in successfully." };
}
} else {
let new_acc = await manager.add_account(data.name, {
password: data.password,
});
if (new_acc) {
const uid = generate_random_string(16, "alnum");
await set_account_uid(uid, data.name, manager);
result = { uid, message: "Account created successfully." };
} else {
result = { message: "Account creation failed." };
}
}
break;
}
case "/oracle":
result = await manager.oracle.call(data);
break;
case "/load":
case "/run":
case "/parse": {
let account_name = await get_account(data.account, manager),
message;
if (account_name && typeof account_name === "object") {
message = `Session expired. Please sign in again.`;
account_name = null;
}
if (!account_name) {
result = {
message: message || `Account ${data.account} not found`,
};
} else {
let account_obj = await manager.get_account(account_name);
if (req.url === "/load") result = await account_obj.load(data);
if (req.url === "/run") result = await account_obj.run(data);
if (req.url === "/parse") result = await account_obj.parse(data);
}
break;
}
}
res.writeHead(200, { "Content-Type": "application/json" });
return res.end(JSON.stringify(result));
}
// Everything else → forward to express app
return app ? app(req, res) : res.writeHead(404).end("Not Found");
} catch (err) {
console.error("Handler error:", err);
res.writeHead(500, { "Content-Type": "application/json" });
return res.end(JSON.stringify({ error: err.message }));
}
};
const create_server = (settings) => {
settings = settings || {};
let { port, manager } = settings;
port = port || PORT;
let handler = async (req, res) =>
await handle_routes(req, res, manager, manager.options.app);
return handler;
};
export default create_server;
export { PORT };