add file support, fix issue #2, add interactive auth form prototype
This commit is contained in:
parent
0e411989ce
commit
1ef209d9a6
@ -1,3 +1,7 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const mime = require('mime-types');
|
||||||
|
|
||||||
const authModes = [
|
const authModes = [
|
||||||
"free",
|
"free",
|
||||||
"confirmation",
|
"confirmation",
|
||||||
@ -5,9 +9,24 @@ const authModes = [
|
|||||||
"password",
|
"password",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function getBGMain () {
|
||||||
|
let bgMain = global.config.source.bgmain;
|
||||||
|
if (typeof bgMain === "string") {
|
||||||
|
if (!path.isAbsolute(bgMain))
|
||||||
|
bgMain = path.join(__dirname, "..", bgMain);
|
||||||
|
const mimetype = mime.lookup(bgMain);
|
||||||
|
const base64content = fs.readFileSync(bgMain, { encoding: 'base64' });
|
||||||
|
return `data:${mimetype};base64,${base64content}`;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: global.config.server.info.name,
|
name: global.config.server.info.name,
|
||||||
tag: global.config.server.info.tag,
|
tag: global.config.server.info.tag,
|
||||||
authMode: authModes[global.config.server["auth-mode"] ?? 1],
|
authMode: authModes[global.config.server["auth-mode"] ?? 1],
|
||||||
secureMode: global.config.server.secureMode ?? false,
|
secureMode: global.config.server.secureMode ?? false,
|
||||||
|
extSource: {
|
||||||
|
bgmain: getBGMain(),
|
||||||
|
}
|
||||||
};
|
};
|
@ -22,5 +22,13 @@
|
|||||||
},
|
},
|
||||||
"ai": {
|
"ai": {
|
||||||
"apiType": "kobold"
|
"apiType": "kobold"
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"bgmain": "/home/fullgream/Загрузки/21380429c504a974479d31c96a9c3c3f.jpg"
|
||||||
|
},
|
||||||
|
"rootuser": {
|
||||||
|
"login": "admin",
|
||||||
|
"password": "admin",
|
||||||
|
"activated": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
height: 650px;
|
height: 650px;
|
||||||
|
|
||||||
margin-left: calc(50% - 250px);
|
margin-left: calc(50% - 250px);
|
||||||
margin-top: calc(50vh - 325px);
|
margin-top: calc(5%);
|
||||||
|
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
@ -66,12 +66,39 @@ class ApiHTML {
|
|||||||
this.api = api;
|
this.api = api;
|
||||||
}
|
}
|
||||||
|
|
||||||
async renderAuth (authMode) {
|
async renderAuth (authMode, bgUrl = null) {
|
||||||
document.body.style.backgroundImage = "url('assets/hello/1.png')";
|
bgUrl = bgUrl ?? "assets/hello/1.png";
|
||||||
|
|
||||||
|
document.body.style.backgroundImage = `url(${
|
||||||
|
JSON.stringify(bgUrl)
|
||||||
|
})`;
|
||||||
|
document.body.style.backgroundSize = `${screen.width}px ${screen.height}px`;
|
||||||
|
|
||||||
document.getElementById("server.area").innerHTML = '';
|
document.getElementById("server.area").innerHTML = '';
|
||||||
$(document.getElementById("server.area")).append(ServerAuth.authForm);
|
$(document.getElementById("server.area")).append(ServerAuth.authForm);
|
||||||
//switch (authMode) {}
|
|
||||||
|
[...$.find(".auth-act-item")].forEach(authEl => {
|
||||||
|
const authElJQ = $(authEl);
|
||||||
|
const isHidden = authEl.hidden;
|
||||||
|
authEl.hidden = false;
|
||||||
|
const buttonBlock = authElJQ.find(".btn-auth-block")[0];
|
||||||
|
const paramsBlock = authElJQ.find(".params-auth")[0];
|
||||||
|
|
||||||
|
buttonBlock.style.marginTop = `calc(100% - ${paramsBlock.offsetHeight}px)`;
|
||||||
|
authEl.hidden = isHidden;
|
||||||
|
});
|
||||||
|
|
||||||
|
$.find("#menu-log-in")[0].onclick = function () {
|
||||||
|
$.find("#log-in")[0].hidden = false;
|
||||||
|
$.find("#register")[0].hidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.find("#menu-register")[0].onclick = function () {
|
||||||
|
$.find("#log-in")[0].hidden = true;
|
||||||
|
$.find("#register")[0].hidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$.find("#server-code-form")[0].hidden = authMode !== "password";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,4 +17,75 @@ export class ServerAuth {
|
|||||||
ServerAuth.authForm = document.createElement("div");
|
ServerAuth.authForm = document.createElement("div");
|
||||||
["auth-window"].forEach(c =>
|
["auth-window"].forEach(c =>
|
||||||
ServerAuth.authForm.classList.add(c));
|
ServerAuth.authForm.classList.add(c));
|
||||||
ServerAuth.authForm.innerHTML = `<center><h1>Log-In</h1></center><hr/>`;
|
ServerAuth.authForm.innerHTML = `
|
||||||
|
<center><h1>Authorization</h1></center>
|
||||||
|
<hr/>
|
||||||
|
|
||||||
|
<div id="auth-zone">
|
||||||
|
<center style="" id="register" class="auth-act-item">
|
||||||
|
<div class="params-auth">
|
||||||
|
<div class="btn-group" role="group" style="width: 90%; margin-bottom: 15px;">
|
||||||
|
<button type="button" class="btn btn-light text-dark btn-outline-light">Register</button>
|
||||||
|
<button type="button" class="btn btn-dark btn-outline-light" id="menu-log-in">Log-In</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field: username -->
|
||||||
|
<div class="mb-3" style="width: 90%; margin-bottom: 15px;">
|
||||||
|
<label class="form-label">Username</label>
|
||||||
|
<input type="text" class="form-control text-light bg-dark" id="rg.username">
|
||||||
|
<div class="form-text text-light">Your username into server.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field: password -->
|
||||||
|
<div class="mb-3" style="width: 90%; margin-bottom: 15px;">
|
||||||
|
<label class="form-label">Password</label>
|
||||||
|
<input type="password" class="form-control text-light bg-dark" id="rg.password">
|
||||||
|
<div class="form-text text-light">Your password into server.</div>
|
||||||
|
</div>
|
||||||
|
<!-- Not field: retry password -->
|
||||||
|
<div class="mb-3" style="width: 90%; margin-bottom: 15px;">
|
||||||
|
<label class="form-label">Retry password</label>
|
||||||
|
<input type="password" class="form-control text-light bg-dark" id="rg.retry-password">
|
||||||
|
<div class="form-text text-light">Retry password for you don't forget password.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field: server-code -->
|
||||||
|
<div class="mb-3" style="width: 90%; margin-bottom: 15px;" id="server-code-form" hidden>
|
||||||
|
<label class="form-label">Server password</label>
|
||||||
|
<input type="text" class="form-control text-light bg-dark" id="rg.server-code">
|
||||||
|
<div class="form-text text-light">Enter the password from server.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-auth-block">
|
||||||
|
<hr><button type="button" class="btn btn-dark btn-outline-light" id="reg-btn">Register</button>
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
|
||||||
|
<center style="" id="log-in" class="auth-act-item" hidden>
|
||||||
|
<div class="params-auth">
|
||||||
|
<div class="btn-group" role="group" style="width: 90%; margin-bottom: 15px;">
|
||||||
|
<button type="button" class="btn btn-dark btn-outline-light" id="menu-register">Register</button>
|
||||||
|
<button type="button" class="btn btn-light text-dark btn-outline-light">Log-In</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field: username -->
|
||||||
|
<div class="mb-3" style="width: 90%; margin-bottom: 15px;">
|
||||||
|
<label class="form-label">Username</label>
|
||||||
|
<input type="text" class="form-control text-light bg-dark" id="username">
|
||||||
|
<div class="form-text text-light">Your username into server.</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Field: password -->
|
||||||
|
<div class="mb-3" style="width: 90%; margin-bottom: 15px;">
|
||||||
|
<label class="form-label">Password</label>
|
||||||
|
<input type="password" class="form-control text-light bg-dark" id="password">
|
||||||
|
<div class="form-text text-light">Your password into server.</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-auth-block">
|
||||||
|
<hr><button type="button" class="btn btn-dark btn-outline-light" id="auth-btn">Log-In</button>
|
||||||
|
</div>
|
||||||
|
</center>
|
||||||
|
`;
|
||||||
|
@ -49,7 +49,7 @@ socket.run()
|
|||||||
console.log("socket sends:", data);
|
console.log("socket sends:", data);
|
||||||
document.title = data.name;
|
document.title = data.name;
|
||||||
document.getElementById("server-name").innerText = data.name;
|
document.getElementById("server-name").innerText = data.name;
|
||||||
await socket.html.renderAuth(data.authMode);
|
await socket.html.renderAuth(data.authMode, data.extSource?.bgmain ?? null);
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
305
server/server.js
305
server/server.js
@ -4,173 +4,196 @@ const parser = require("./packet-parser");
|
|||||||
const frontend = require("./frontend");
|
const frontend = require("./frontend");
|
||||||
const websocket = require("./ws-handler");
|
const websocket = require("./ws-handler");
|
||||||
const crypt = require("./crypt");
|
const crypt = require("./crypt");
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require("events");
|
||||||
const net = require('net');
|
const net = require("net");
|
||||||
const fs = require('fs');
|
const fs = require("fs");
|
||||||
const path = require('path');
|
const path = require("path");
|
||||||
|
|
||||||
const { API } = require('./api');
|
const { API } = require("./api");
|
||||||
|
|
||||||
class Server extends EventEmitter {
|
class Server extends EventEmitter {
|
||||||
constructor () {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.on("config.update", ({
|
this.on("config.update", ({ oldConfig, newConfig }) => {});
|
||||||
oldConfig, newConfig
|
}
|
||||||
}) => {
|
|
||||||
|
|
||||||
});
|
run(address, port) {
|
||||||
}
|
this.address = address;
|
||||||
|
this.port = port;
|
||||||
|
|
||||||
run (address, port) {
|
const wsPort = global.config.server?.staticInfo?.wsPort ?? 57891;
|
||||||
this.address = address;
|
const httpPort = global.config.server?.staticInfo?.httpPort ?? 49901;
|
||||||
this.port = port;
|
|
||||||
|
|
||||||
const wsPort = global.config.server?.staticInfo?.wsPort ?? 57891;
|
logger.log({
|
||||||
const httpPort = global.config.server?.staticInfo?.httpPort ?? 49901;
|
wsPort,
|
||||||
|
httpPort,
|
||||||
|
});
|
||||||
|
|
||||||
logger.log({
|
this.api = new API();
|
||||||
wsPort, httpPort
|
|
||||||
});
|
|
||||||
|
|
||||||
this.api = new API();
|
if (global.config.server.useFrontend)
|
||||||
|
this.frontend = frontend("127.0.0.1", httpPort);
|
||||||
|
if (global.config.server.useWebSocketAPI)
|
||||||
|
this.websocket = websocket("127.0.0.1", wsPort, this.api);
|
||||||
|
|
||||||
if (global.config.server.useFrontend)
|
this.server = net.createServer((srvSocket) => {
|
||||||
this.frontend = frontend("127.0.0.1", httpPort);
|
srvSocket.on("error", (err) => {
|
||||||
if (global.config.server.useWebSocketAPI)
|
logger.log("Caught server socket error: ");
|
||||||
this.websocket = websocket("127.0.0.1", wsPort, this.api);
|
logger.log(err.stack);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.server = net.createServer((srvSocket) => {
|
function socketErrHanler(err) {
|
||||||
srvSocket.on("error", (err) => {
|
if (err) {
|
||||||
logger.log("Caught server socket error: ");
|
logger.log("Caught server socket error: ");
|
||||||
logger.log(err.stack);
|
logger.log(err.stack);
|
||||||
});
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
function socketErrHanler (err) {
|
function socketDataHandler(data, socket) {
|
||||||
if (err) {
|
socket.write(data, function (err) {
|
||||||
logger.log("Caught server socket error: ");
|
if (err) {
|
||||||
logger.log(err.stack);
|
logger.log(
|
||||||
}
|
`error: ${socket.remoteAddress} (remote) throwed: ${err.name}\n${err.stack}`,
|
||||||
}
|
);
|
||||||
|
|
||||||
function socketDataHandler (data, socket) {
|
|
||||||
socket.write(data, function(err) {
|
|
||||||
if (err) {
|
|
||||||
logger.log(`error: ${socket.remoteAddress} (remote) throwed: ${err.name}\n${err.stack}`);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.server.on("connection", (socket) => {
|
this.server.on("connection", (socket) => {
|
||||||
logger.log(`${socket.remoteAddress}${socket.remotePort} is connected`);
|
logger.log(`${socket.remoteAddress}${socket.remotePort} is connected`);
|
||||||
socket.mainconnect = null;
|
socket.mainconnect = null;
|
||||||
|
|
||||||
if (global.config.server.useWebSocketAPI) {
|
if (global.config.server.useWebSocketAPI) {
|
||||||
socket.wsReverse = net.createConnection(wsPort, "127.0.0.1");
|
socket.wsReverse = net.createConnection(wsPort, "127.0.0.1");
|
||||||
socket.wsReverse.on("error", socketErrHanler);
|
socket.wsReverse.on("error", socketErrHanler);
|
||||||
socket.wsReverse.on("data", (data) => socketDataHandler(data, socket));
|
socket.wsReverse.on("data", (data) => socketDataHandler(data, socket));
|
||||||
}
|
}
|
||||||
if (global.config.server.useFrontend) {
|
if (global.config.server.useFrontend) {
|
||||||
socket.httpReverse = net.createConnection(httpPort, "127.0.0.1");
|
socket.httpReverse = net.createConnection(httpPort, "127.0.0.1");
|
||||||
socket.httpReverse.on("error", socketErrHanler);
|
socket.httpReverse.on("error", socketErrHanler);
|
||||||
socket.httpReverse.on("data", (data) => socketDataHandler(data, socket));
|
socket.httpReverse.on("data", (data) =>
|
||||||
}
|
socketDataHandler(data, socket),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
socket.on("error", (err) => {
|
socket.on("error", (err) => {
|
||||||
logger.log(
|
logger.log(`socket.on(${socket.remoteAddress}) error:`);
|
||||||
`socket.on(${socket.remoteAddress}) error:`
|
logger.log(err.stack);
|
||||||
);
|
try {
|
||||||
logger.log(err.stack);
|
socket.end();
|
||||||
try { socket.end(); } catch (_) {}
|
} catch (_) {}
|
||||||
// socket.end();
|
// socket.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('data', async (data) => {
|
socket.on("data", async (data) => {
|
||||||
const parserResult = await parser(data);
|
const parserResult = await parser(data);
|
||||||
// if (global.config.server.secureMode && data.toString().includes("http/1.1")) {
|
// if (global.config.server.secureMode && data.toString().includes("http/1.1")) {
|
||||||
// logger.log("Encrypted WS!");
|
// logger.log("Encrypted WS!");
|
||||||
// parserResult.result.isWebSocket = true;
|
// parserResult.result.isWebSocket = true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// const parserDecryptedResult = await parser(global.openSSH.decrypt(data));
|
// const parserDecryptedResult = await parser(global.openSSH.decrypt(data));
|
||||||
const peerAddress = `${socket.remoteAddress}:${socket.remotePort}`;
|
const peerAddress = `${socket.remoteAddress}:${socket.remotePort}`;
|
||||||
//logger.log("Parser result is", parserResult);
|
//logger.log("Parser result is", parserResult);
|
||||||
|
|
||||||
if (!socket.mainconnect) {
|
if (!socket.mainconnect) {
|
||||||
// if (parserResult.result.isWebSocket || parserDecryptedResult.result.isWebSocket) {
|
// if (parserResult.result.isWebSocket || parserDecryptedResult.result.isWebSocket) {
|
||||||
if (parserResult.result.isWebSocket) {
|
if (parserResult.result.isWebSocket) {
|
||||||
socket.mainconnect = "ws";
|
socket.mainconnect = "ws";
|
||||||
if (global.config.server.useFrontend)
|
if (global.config.server.useFrontend) socket.httpReverse.end();
|
||||||
socket.httpReverse.end();
|
if (global.config.server.useWebSocketAPI) {
|
||||||
if (global.config.server.useWebSocketAPI) {
|
return socket.wsReverse.write(data, socketErrHanler);
|
||||||
return socket.wsReverse.write(data, socketErrHanler);
|
}
|
||||||
}
|
return;
|
||||||
return;
|
} else if (parserResult.result.isHTTP) {
|
||||||
}
|
socket.mainconnect = "http";
|
||||||
else if (parserResult.result.isHTTP) {
|
|
||||||
socket.mainconnect = "http";
|
|
||||||
socket.wsReverse.end();
|
socket.wsReverse.end();
|
||||||
if (global.config.server.useFrontend) {
|
if (global.config.server.useFrontend) {
|
||||||
return socket.httpReverse.write(data, socketErrHanler);
|
return socket.httpReverse.write(data, socketErrHanler);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
} else {
|
||||||
else {
|
if (global.config.server.useFrontend) socket.httpReverse.end();
|
||||||
if (global.config.server.useFrontend)
|
if (global.config.server.useWebSocketAPI) socket.wsReverse.end();
|
||||||
socket.httpReverse.end();
|
socket.mainconnect = "tcp";
|
||||||
if (global.config.server.useWebSocketAPI)
|
return await this.api.exec(peerAddress, data, () => {});
|
||||||
socket.wsReverse.end();
|
}
|
||||||
socket.mainconnect = "tcp";
|
} else {
|
||||||
return await this.api.exec(peerAddress, data, () => {});
|
switch (socket.mainconnect) {
|
||||||
}
|
case "ws":
|
||||||
}
|
if (global.config.server.useWebSocketAPI) {
|
||||||
else {
|
if (!socket.wsReverse.destroyed) {
|
||||||
switch (socket.mainconnect) {
|
return socket.wsReverse.write(data, socketErrHanler);
|
||||||
case "ws":
|
} else {
|
||||||
if (global.config.server.useWebSocketAPI) {
|
socket.wsReverse = net.createConnection(wsPort, "127.0.0.1");
|
||||||
return socket.wsReverse.write(data, socketErrHanler);
|
socket.wsReverse.on("error", socketErrHanler);
|
||||||
}
|
socket.wsReverse.on("data", (data) =>
|
||||||
case "http":
|
socketDataHandler(data, socket),
|
||||||
if (global.config.server.useFrontend) {
|
);
|
||||||
return socket.httpReverse.write(data, socketErrHanler);
|
return socket.wsReverse.write(data, socketErrHanler);
|
||||||
}
|
}
|
||||||
case "tcp":
|
}
|
||||||
return await this.api.exec(peerAddress, data);
|
case "http":
|
||||||
default:
|
if (global.config.server.useFrontend) {
|
||||||
return;
|
if (!socket.httpReverse.destroyed) {
|
||||||
}
|
return socket.httpReverse.write(data, socketErrHanler);
|
||||||
}
|
} else {
|
||||||
});
|
socket.httpReverse = net.createConnection(
|
||||||
});
|
httpPort,
|
||||||
|
"127.0.0.1",
|
||||||
|
);
|
||||||
|
socket.httpReverse.on("error", socketErrHanler);
|
||||||
|
socket.httpReverse.on("data", (data) =>
|
||||||
|
socketDataHandler(data, socket),
|
||||||
|
);
|
||||||
|
return socket.httpReverse.write(data, socketErrHanler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "tcp":
|
||||||
|
return await this.api.exec(peerAddress, data, () => {});
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.server.on('error', (err) => {
|
this.server.on("error", (err) => {
|
||||||
logger.log("Error of server");
|
logger.log("Error of server");
|
||||||
logger.log(err.stack);
|
logger.log(err.stack);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.server.listen(this.port, this.address, (err) => {
|
this.server.listen(this.port, this.address, (err) => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
logger.log(`TCP server for ai-adventure labs connected on ${this.address}:${this.port}`);
|
logger.log(
|
||||||
});
|
`TCP server for ai-adventure labs connected on ${this.address}:${this.port}`,
|
||||||
}
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const defaultConfigData = {
|
const defaultConfigData = {
|
||||||
server: {
|
server: {
|
||||||
address: "0.0.0.0",
|
address: "0.0.0.0",
|
||||||
port: 8841,
|
port: 8841,
|
||||||
useWebSocketAPI: true,
|
useWebSocketAPI: true,
|
||||||
useFrontend: true,
|
useFrontend: true,
|
||||||
staticInfo: {
|
staticInfo: {
|
||||||
wsPort: 57891,
|
wsPort: 57891,
|
||||||
httpPort: 49901
|
httpPort: 49901,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
database: {
|
database: {
|
||||||
dialect: "sqlite",
|
dialect: "sqlite",
|
||||||
path: "./data"
|
path: "./data",
|
||||||
},
|
},
|
||||||
ai: {
|
ai: {
|
||||||
apiType: "kobold"
|
apiType: "kobold",
|
||||||
|
},
|
||||||
|
rootuser: {
|
||||||
|
"login": "admin",
|
||||||
|
"password": "admin",
|
||||||
|
"activated": true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user