diff --git a/server/api/index.js b/server/api/index.js index 78c2391..2cb3c3f 100644 --- a/server/api/index.js +++ b/server/api/index.js @@ -13,8 +13,12 @@ class APIMethods { this.parent = parent; } - info (_, ___, __, cb) { - cb({ result: require("./server-info") }); + info (con, req, cb) { + cb({ result: require("./server-info"), trace_id: req.trace_id, ended: true }); + } + + authed (con, req, cb) { + cb({ result: require("./server-info"), trace_id: req.trace_id, ended: true }); } /*setSession (isEncrypted, address, { key, counter }, cb) { @@ -34,11 +38,12 @@ class APIMethods { class API { constructor () { this.methods = new APIMethods(this); - this.sessions = {}; + this.sessions = new WeakMap(); } decrypt (address, bytes) { - try { + throw new Error("Deprecated. Use TLS. If you see this error, please, add issue into: https://git.fullgream.tech/fullgream/ai-adventure-labs/issues"); + /*try { if (!global.config.server.secureMode) // return Buffer.from([]); return undefined; @@ -48,10 +53,10 @@ class API { this.sessions[address].decrypt(bytes); } catch (err) { return undefined; - } + }*/ } - async exec (address, bytes, cb) { + async exec (connection, bytes, cb) { const request = parseRq(bytes); if (request === undefined) @@ -61,9 +66,18 @@ class API { if (typeof request === "object" && request !== null) { const { - method + method, + trace_id } = request; - this.methods[method]?.(false, address, request, cb); + if (!method) + return cb({ + error: "method missed" + }); + if (!trace_id) + return cb({ + error: "trace_id missed" + }); + this.methods[method]?.(connection, request, cb); } else { return cb({ error: "required JSON-object based request" diff --git a/server/frontend/public/js/connect/api.js b/server/frontend/public/js/connect/api.js index ff440f5..d6dacbd 100644 --- a/server/frontend/public/js/connect/api.js +++ b/server/frontend/public/js/connect/api.js @@ -1,28 +1,79 @@ import { ServerAuth } from "/js/connect/auth.js"; -class ApiMethods { +function randint(min, max) { + return Math.ceil((Math.random() * (max - min)) + min); +} + +function getTraceId() { + const dict = "1234567890abcdefABCDEF"; + return [...new Array(16)] + .map(() => dict[randint(0, dict.length - 1)]) + .join(""); +} + +class ProtoApiMethods { constructor (api) { this.api = api; } - async info () { + async _protoMethod (rqdata, threadcb) { const socket = this.api.socket; + const trace_id = getTraceId() + const promise = new Promise((rs, rj) => { socket.onmessage = (ev) => { - const data = JSON.parse(ev.data).result; - rs(data); + ev = JSON.parse(ev.data); + const data = ev.result; + return rs(data); + if (ev.trace_id === trace_id) + if (!!ev.ended) + return rs(data); + threadcb(data); }; socket.onerror = (err) => rj(err); }); socket.send( - JSON.stringify({ - method: "info", - }), + JSON.stringify({ trace_id, ...rqdata }), ); return await promise; } } +class ApiMethods extends ProtoApiMethods { + async _protoMethod (rqdata) { + throw new Error("_protoMethod allowed only into abstract class"); + } + + constructor (api) { + super(api); + } + + async info () { + return await super._protoMethod({ + method: "info", + }); + } + + async authed () { + return await super._protoMethod({ + method: "authed", + }); + } +} + +class ApiHTML { + constructor (api) { + this.api = api; + } + + async renderAuth (authMode) { + switch (authMode) { + default: + document.getElementById("server.area").innerHTML = '
'; + } + } +} + export class ApiSocket { constructor ({ isTLSmode, address, port @@ -33,6 +84,8 @@ export class ApiSocket { this.socket = new WebSocket(`${!isTLSmode ? "ws" : "wss"}://${address}:${port}`); this.methods = new ApiMethods(this); + + this.html = new ApiHTML(this); } async run () { diff --git a/server/frontend/public/js/connect/main.js b/server/frontend/public/js/connect/main.js index 1882e26..554b154 100644 --- a/server/frontend/public/js/connect/main.js +++ b/server/frontend/public/js/connect/main.js @@ -45,10 +45,11 @@ const socket = new ApiSocket({ isTLSmode, address, port }); socket.run() - .then(data => { + .then(async (data) => { console.log("socket sends:", data); - document.getElementById("server-name").innerHTML = data.name; document.title = data.name; + document.getElementById("server-name").innerText = data.name; + await socket.html.renderAuth(data.authMode); }) .catch(err => { console.error(err);