174 lines
4.0 KiB
JavaScript
174 lines
4.0 KiB
JavaScript
const crypt = require("../crypt");
|
|
|
|
// methods
|
|
const isAuthed = require("./is-authed");
|
|
const logIn = require("./log-in");
|
|
const setupToken = require("./setup-token");
|
|
|
|
// authed sessions
|
|
global.authed = new WeakMap();
|
|
global.authed.tokens = new Object();
|
|
|
|
function parseRq (bytes) {
|
|
try {
|
|
return JSON.parse(bytes.toString());
|
|
} catch (e) {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
class APIMethods {
|
|
constructor (parentObj) {
|
|
this.parentObj = parentObj;
|
|
this.info.cache = new Object();
|
|
|
|
// Clear method cache on update config
|
|
global.server.on("config.update", () => {
|
|
this.info.cache = new Object();
|
|
});
|
|
}
|
|
|
|
info (con, req, cb) {
|
|
if (!req.fields) req.fields = "*";
|
|
if (!req.fieldsExtSource) req.fieldsExtSource = "*";
|
|
const cache = this.info.cache[
|
|
JSON.stringify({
|
|
f: req.fields, e: req.fieldsExtSource
|
|
})
|
|
];
|
|
|
|
if (cache) {
|
|
console.debug("CACHE!");
|
|
return cb({ result: cache, trace_id: req.trace_id, ended: true });
|
|
}
|
|
|
|
const serverInfo = require("./server-info")();
|
|
if (req.fields !== "*") {
|
|
const fields = Object.fromEntries(req.fields.split(/\s*,\s*/g).map(x => [x.trim(), true]));
|
|
Object.keys(serverInfo).forEach(k => {
|
|
if (!fields[k]) serverInfo[k] = undefined;
|
|
});
|
|
}
|
|
if (req.fieldsExtSource !== "*" && req.fields.extSource !== undefined) {
|
|
const fields = Object.fromEntries(req.fieldsExtSource.split(/\s*,\s*/g).map(x => [x.trim(), true]));
|
|
Object.keys(serverInfo).forEach(k => {
|
|
if (!fields[k]) serverInfo.extSource[k] = undefined;
|
|
});
|
|
}
|
|
this.info.cache[
|
|
JSON.stringify({
|
|
f: req.fields, e: req.fieldsExtSource
|
|
})
|
|
] = serverInfo;
|
|
|
|
cb({ result: serverInfo, trace_id: req.trace_id, ended: true });
|
|
}
|
|
|
|
authed (con, req, cb) {
|
|
isAuthed(con, req, cb);
|
|
}
|
|
|
|
async token (con, req, cb) {
|
|
const authedMethod = this.authed;
|
|
const isAuthed = await (new Promise((rs, rj) => {
|
|
authedMethod(con, req, ({ result, ended }) => {
|
|
if (ended)
|
|
return rs(result);
|
|
});
|
|
}));
|
|
if (!isAuthed) {
|
|
return setupToken(con, req, cb);
|
|
}
|
|
cb({
|
|
error: "already logged-in",
|
|
trace_id: req.trace_id,
|
|
ended: true
|
|
});
|
|
}
|
|
|
|
async login (con, req, cb) {
|
|
const authedMethod = this.authed;
|
|
const isAuthed = await (new Promise((rs, rj) => {
|
|
authedMethod(con, req, ({ result, ended }) => {
|
|
if (ended)
|
|
return rs(result);
|
|
});
|
|
}));
|
|
if (!isAuthed) {
|
|
return logIn(con, req, cb);
|
|
}
|
|
cb({
|
|
error: "already logged-in",
|
|
trace_id: req.trace_id,
|
|
ended: true
|
|
});
|
|
}
|
|
|
|
/*setSession (isEncrypted, address, { key, counter }, cb) {
|
|
if (!global.config.server.secureMode)
|
|
return cb({ error: "Encryption is off by configuration file into server" });
|
|
if (!isEncrypted)
|
|
return cb({ error: "Encryption required" });
|
|
try {
|
|
this.parent.sessions[address] = new crypt.AES(key, counter);
|
|
return cb({ result: "Session key installed" });
|
|
} catch (err) {
|
|
return cb({ error: "Invalid params. Must be key and counter" });
|
|
}
|
|
}*/
|
|
}
|
|
|
|
class API {
|
|
constructor () {
|
|
this.methods = new APIMethods(this);
|
|
this.sessions = global.authed;
|
|
}
|
|
|
|
decrypt (address, bytes) {
|
|
throw new Error("Deprecated. Use TLS. If you see this error, please, create issue into: https://git.fullgream.tech/fullgream/ai-adventure-labs/issues");
|
|
}
|
|
|
|
async exec (connection, bytes, cb) {
|
|
const request = parseRq(bytes);
|
|
|
|
if (request === undefined)
|
|
return cb({
|
|
error: "required JSON object request"
|
|
});
|
|
|
|
if (typeof request === "object" && request !== null) {
|
|
const {
|
|
method,
|
|
trace_id
|
|
} = request;
|
|
if (!method)
|
|
return cb({
|
|
error: "method missed",
|
|
trace_id: trace_id ?? null,
|
|
ended: true
|
|
});
|
|
if (!trace_id)
|
|
return cb({
|
|
error: "trace_id missed",
|
|
trace_id: null,
|
|
ended: true
|
|
});
|
|
if (this.methods[method] === undefined)
|
|
return cb({
|
|
error: "unknown method: " + method,
|
|
trace_id,
|
|
ended: true
|
|
});
|
|
return this.methods[method](connection, request, cb);
|
|
} else {
|
|
return cb({
|
|
error: "required JSON-object based request",
|
|
trace_id: null,
|
|
ended: true
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = { API };
|