From 904090f51e81d0980bd12fdcb0680c54ad30df63 Mon Sep 17 00:00:00 2001 From: fullgream Date: Mon, 18 Aug 2025 01:59:57 +0300 Subject: [PATCH] Add new params + secure any critical params from being overwritten for clumsy idiots --- server/frontend/public/js/connect/api.js | 56 ++++++++++++++++++++---- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/server/frontend/public/js/connect/api.js b/server/frontend/public/js/connect/api.js index 4bd51e8..cf138f3 100644 --- a/server/frontend/public/js/connect/api.js +++ b/server/frontend/public/js/connect/api.js @@ -15,12 +15,28 @@ const curUrl = new URL(location.href); const [address, port] = curUrl.searchParams.get("server").split(/:/); const isTLSmode = curUrl.searchParams.get("encrypted") === "true"; +const apiMethodsProtected = new WeakMap(); class ProtoApiMethods { constructor (api) { - this.api = api; + //this.api = api; + if (!(api instanceof ApiSocket)) + throw new Error("api must be instance of ApiSocket class"); + apiMethodsProtected.set(this, api); + } + + set api (_) { + throw new Error("api is not writeable"); + } + + get api () { + return apiMethodsProtected.get(this); } async _protoMethod (rqdata, threadcb = null) { + if (!(this instanceof ProtoApiMethods)) { + throw new Error("_protoMethod allowed only into original abstract class"); + } + const socket = this.api.socket; const trace_id = getTraceId() @@ -48,9 +64,9 @@ class ProtoApiMethods { } class ApiMethods extends ProtoApiMethods { - async _protoMethod (rqdata) { + /*async _protoMethod (rqdata) { throw new Error("_protoMethod allowed only into abstract class"); - } + }*/ constructor (api) { super(api); @@ -84,16 +100,28 @@ class ApiMethods extends ProtoApiMethods { }); } - async characters () { + async characters (fields = "*") { return await super._protoMethod({ - method: "characters" + method: "characters", fields }); } } +const apiHTMLProtected = new WeakMap(); class ApiHTML { constructor (api) { - this.api = api; + //this.api = api; + if (!(api instanceof ApiSocket)) + throw new Error("api must be instance of ApiSocket class"); + apiHTMLProtected.set(this, api); + } + + set api (_) { + throw new Error("api is not writeable"); + } + + get api () { + return apiHTMLProtected.get(this); } async renderMainMenu (user, bgUrl = null, favicon = null) { @@ -109,12 +137,13 @@ class ApiHTML { document.getElementById("server.area").innerHTML = ''; $(document.getElementById("server.area")).append(ServerAuth.mainMenuForm); // JS-Events - this.api.methods.characters() + this.api.methods.characters("*") .then(characters => { const addCharBtn = document.createElement("button"); addCharBtn.setAttribute("type", "button"); ["btn", "btn-success", "btn-outline-light"].forEach(c => addCharBtn.classList.add(c)); + addCharBtn.innerText = "Add character"; const charlist = $.find("#user-charlist")[0]; for (let character of characters) { @@ -186,6 +215,7 @@ class ApiHTML { } } +const apiSocketsProtected = new WeakMap(); export class ApiSocket { constructor ({ isTLSmode, address, port @@ -194,13 +224,23 @@ export class ApiSocket { this.address = address; this.port = port; - this.socket = new WebSocket(`${!isTLSmode ? "ws" : "wss"}://${address}:${port}`); + //this.socket = new WebSocket(`${!isTLSmode ? "ws" : "wss"}://${address}:${port}`); + const socket = new WebSocket(`${!isTLSmode ? "ws" : "wss"}://${address}:${port}`); + apiSocketsProtected.set(this, socket); this.methods = new ApiMethods(this); this.user = null; this.html = new ApiHTML(this); } + set socket (_) { + throw new Error("api is not writeable"); + } + + get socket () { + return apiSocketsProtected.get(this); + } + async run () { const socket = this.socket; const promise = new Promise((rs, rj) => {