rewrite to a module

This commit is contained in:
Mystikfluu 2022-08-19 19:29:14 +02:00
parent c78f4cba3a
commit 6ed17497c5
13 changed files with 1522 additions and 540 deletions

View File

@ -1,5 +1,4 @@
const crypto = require('crypto'); import crypto from "crypto";
/** /**
* hashes with the secure hashing algorithm 256 * hashes with the secure hashing algorithm 256
* @param {string} str string to hash * @param {string} str string to hash
@ -8,8 +7,10 @@ const crypto = require('crypto');
* @returns {string} base64 digested hash * @returns {string} base64 digested hash
*/ */
function SHA256(str, salt, num) { function SHA256(str, salt, num) {
if(!num && num!==0)num=1; if (!num && num !== 0)
if(!str)return; num = 1;
if (!str)
return;
let ret = str; let ret = str;
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
ret = crypto ret = crypto
@ -19,7 +20,7 @@ function SHA256(str,salt,num) {
} }
return ret; return ret;
} }
export { SHA256 };
module.exports = { export default {
SHA256: SHA256 SHA256: SHA256
} };

View File

@ -1,6 +1,5 @@
const fs = require('fs'); import fs from "fs";
const config = JSON.parse(fs.readFileSync("server_config.json")) const config = JSON.parse(fs.readFileSync("server_config.json"));
/** /**
* gets ip of a request * gets ip of a request
* @param {request} req * @param {request} req
@ -8,8 +7,8 @@ const config = JSON.parse(fs.readFileSync("server_config.json"))
*/ */
function getIP(req) { function getIP(req) {
let ip = req.socket.remoteAddress; let ip = req.socket.remoteAddress;
if(req.headers[config.preferred_ip_header] != undefined && ip == config.only_prefer_when_ip)ip = req.headers[config.preferred_ip_header] if (req.headers[config.preferred_ip_header] != undefined && ip == config.only_prefer_when_ip)
return ip ip = req.headers[config.preferred_ip_header];
return ip;
} }
export default getIP;
module.exports = getIP

View File

@ -1,7 +1,7 @@
const signature = require('cookie-signature') import * as signature from "cookie-signature";
const fs = require('fs'); import fs from "fs";
const cookiesecret = fs.readFileSync("cookiesecret.txt").toString() import getIP from "./getip.js";
const getIP = require("./getip.js") const cookiesecret = fs.readFileSync("cookiesecret.txt").toString();
/** /**
* usignes a string * usignes a string
* @param {string} text text to unsign * @param {string} text text to unsign
@ -10,14 +10,13 @@ const getIP = require("./getip.js")
* @return {string/boolean} unsigned text, or if unsigning was unsuccessful, false * @return {string/boolean} unsigned text, or if unsigning was unsuccessful, false
*/ */
function unsign(text, req, res) { function unsign(text, req, res) {
let ip = getIP(req) let ip = getIP(req);
let unsigned = signature.unsign(text,cookiesecret+ip) let unsigned = signature.unsign(text, cookiesecret + ip);
if (!unsigned) { if (!unsigned) {
return false return false;
} }
return unsigned return unsigned;
} }
/** /**
* unsignes the auth cookie of a request, also sends json response if auth cookie was invalid * unsignes the auth cookie of a request, also sends json response if auth cookie was invalid
* @param {request} req request object * @param {request} req request object
@ -25,24 +24,26 @@ function unsign(text,req,res) {
* @return {string/boolean} unsigned cookie, or if unsigning was unsuccessful, false * @return {string/boolean} unsigned cookie, or if unsigning was unsuccessful, false
*/ */
function getunsigned(req, res) { function getunsigned(req, res) {
let cookie = req.cookies.AUTH_COOKIE let cookie = req.cookies.AUTH_COOKIE;
if (!cookie) { if (!cookie) {
res.status(400) res.status(400);
res.json({"error":"you are not logged in! (no cookie)"}) res.json({ "error": "you are not logged in! (no cookie)" });
return return;
} }
let unsigned = unsign(cookie,req,res) let unsigned = unsign(cookie, req, res);
if (!unsigned) { if (!unsigned) {
try { try {
res.status(400) res.status(400);
res.json({"error":"Bad auth cookie set"}) res.json({ "error": "Bad auth cookie set" });
} catch (ignored) {} //sometimes it errors, gotta debug soon
return false
} }
return decodeURIComponent(unsigned) catch (ignored) { } //sometimes it errors, gotta debug soon
return false;
} }
return decodeURIComponent(unsigned);
module.exports = { }
export { unsign };
export { getunsigned };
export default {
unsign: unsign, unsign: unsign,
getunsigned: getunsigned getunsigned: getunsigned
} };

View File

@ -1,27 +1,19 @@
function XOR_hex(a, b) { function XOR_hex(a, b) {
var res = "", var res = "", i = a.length, j = b.length;
i = a.length,
j = b.length;
while (i-- > 0 && j-- > 0) while (i-- > 0 && j-- > 0)
res = (parseInt(a.charAt(i), 16) ^ parseInt(b.charAt(j), 16)).toString(16) + res; res = (parseInt(a.charAt(i), 16) ^ parseInt(b.charAt(j), 16)).toString(16) + res;
return res; return res;
} }
function hexEncode(a) { function hexEncode(a) {
let hex; let hex;
let result = ""; let result = "";
for (let i = 0; i < a.length; i++) { for (let i = 0; i < a.length; i++) {
hex = a.charCodeAt(i).toString(16); hex = a.charCodeAt(i).toString(16);
result += ("000" + hex).slice(-4); result += ("000" + hex).slice(-4);
} }
return result;
return result
} }
function xor(a, b) { function xor(a, b) {
return XOR_hex(hexEncode(a),hexEncode(b)).toString("hex") return XOR_hex(hexEncode(a), hexEncode(b)).toString("hex");
} }
export default xor;
module.exports = xor

View File

@ -16,6 +16,7 @@
"start": "node server.js", "start": "node server.js",
"test": "node tests" "test": "node tests"
}, },
"type": "module",
"name": "ipost", "name": "ipost",
"description": "IPost is a revolutionary open-source chatting platform featuring an innovative design", "description": "IPost is a revolutionary open-source chatting platform featuring an innovative design",
"version": "1.0.0", "version": "1.0.0",

View File

@ -1,51 +1,57 @@
const fs = require('fs'); import fs from "fs";
const SHA = require("../../extra_modules/SHA.js") import SHA from "../../extra_modules/SHA.js";
const unsign = require("../../extra_modules/unsign.js") import unsign from "../../extra_modules/unsign.js";
const config = JSON.parse(fs.readFileSync("server_config.json")) const config = JSON.parse(fs.readFileSync("server_config.json"));
const HASHES_DB = config.cookies.server_hashes const HASHES_DB = config.cookies.server_hashes;
const HASHES_COOKIE = config.cookies.client_hashes const HASHES_COOKIE = config.cookies.client_hashes;
const HASHES_DIFF = HASHES_DB - HASHES_COOKIE const HASHES_DIFF = HASHES_DB - HASHES_COOKIE;
export const setup = function (router, con, server) {
module.exports = {
"setup": function(router,con,server) {
router.use("/api/*", async function (req, res, next) { router.use("/api/*", async function (req, res, next) {
res.set("Access-Control-Allow-Origin","*") //we'll allow it for now res.set("Access-Control-Allow-Origin", "*"); //we'll allow it for now
if (config["allow_getotheruser_without_cookie"] && req.originalUrl.split("\?")[0] == "/api/getotheruser") { if (config["allow_getotheruser_without_cookie"] && req.originalUrl.split("\?")[0] == "/api/getotheruser") {
next() next();
return return;
} }
if(!server.increaseAPICall(req,res))return; if (!server.increaseAPICall(req, res))
return;
let unsigned; let unsigned;
if (req.body.user == undefined || req.body.pass == undefined) { if (req.body.user == undefined || req.body.pass == undefined) {
unsigned = unsign.getunsigned(req,res) unsigned = unsign.getunsigned(req, res);
if(!unsigned)return if (!unsigned)
} else { return;
unsigned = `${req.body.user} ${SHA.SHA256(req.body.pass,req.body.user,HASHES_COOKIE)}`
//basically we generate the unsigned cookie
res.locals.isbot = true //only bots use user+pass
} }
let sql = `select User_Name,User_Bio,User_Avatar,User_Settings from ipost.users where User_Name=? and User_PW=?;` else {
let values = unsigned.split(" ") unsigned = `${req.body.user} ${SHA.SHA256(req.body.pass, req.body.user, HASHES_COOKIE)}`;
values[1] = SHA.SHA256(values[1],values[0],HASHES_DIFF) //basically we generate the unsigned cookie
res.locals.bio = "" res.locals.isbot = true; //only bots use user+pass
res.locals.avatar = "" }
res.locals.settings = {} let sql = `select User_Name,User_Bio,User_Avatar,User_Settings from ipost.users where User_Name=? and User_PW=?;`;
let values = unsigned.split(" ");
values[1] = SHA.SHA256(values[1], values[0], HASHES_DIFF);
res.locals.bio = "";
res.locals.avatar = "";
res.locals.settings = {};
con.query(sql, values, function (err, result) { con.query(sql, values, function (err, result) {
if (err) throw err; if (err)
throw err;
if (result[0] && result[0].User_Name && result[0].User_Name == values[0]) { if (result[0] && result[0].User_Name && result[0].User_Name == values[0]) {
res.locals.username = values[0]; res.locals.username = values[0];
res.locals.bio = result[0].User_Bio || "" res.locals.bio = result[0].User_Bio || "";
res.locals.avatar = result[0].User_Avatar || "" res.locals.avatar = result[0].User_Avatar || "";
res.locals.settings = JSON.parse(result[0].User_Settings) res.locals.settings = JSON.parse(result[0].User_Settings);
if(res.locals.settings == "null")res.locals.settings = {} if (res.locals.settings == "null")
if(res.locals.settings == null)res.locals.settings = {} res.locals.settings = {};
if (res.locals.settings == null)
next() res.locals.settings = {};
} else { next();
res.status(400) }
res.json({"error":"you cannot access the api without being logged in"}) else {
res.status(400);
res.json({ "error": "you cannot access the api without being logged in" });
} }
}); });
}) });
} };
} export default {
setup
};

View File

@ -1,66 +1,62 @@
import {web_version} from "unsafe_encrypt" //const web_version = require("unsafe_encrypt").web_version
import { web_version } from "unsafe_encrypt";
module.exports = { export const setup = function (router, con, server) {
"setup": function(router,con,server) {
router.get("/api/getPersonalPosts", async function (req, res) { router.get("/api/getPersonalPosts", async function (req, res) {
res.set("Access-Control-Allow-Origin","") res.set("Access-Control-Allow-Origin", "");
let otherperson = encodeURIComponent(req.query.otherperson || "");
let otherperson = encodeURIComponent(req.query.otherperson||"")
if (typeof otherperson != "string" || otherperson.length > 100 || otherperson == "") { if (typeof otherperson != "string" || otherperson.length > 100 || otherperson == "") {
res.status(400).json({"error": "invalid otherperson given"}) res.status(400).json({ "error": "invalid otherperson given" });
return return;
} }
const columns = [ const columns = [
"dms_user_name", "dms_text", "dms_time", "dms_special_text", "dms_id", "dms_from_bot", "dms_reply_id" "dms_user_name", "dms_text", "dms_time", "dms_special_text", "dms_id", "dms_from_bot", "dms_reply_id"
] ];
//dms_user_name = sender //dms_user_name = sender
//dms_receiver = receiver //dms_receiver = receiver
//if (sender == current and receiver == other) or (receiver == current and sender == other) //if (sender == current and receiver == other) or (receiver == current and sender == other)
let sql = `select ${columns.join(",")} from ipost.dms where ((dms_receiver = ? and dms_user_name = ?) or (dms_receiver = ? and dms_user_name = ?)) order by dms_id desc;` let sql = `select ${columns.join(",")} from ipost.dms where ((dms_receiver = ? and dms_user_name = ?) or (dms_receiver = ? and dms_user_name = ?)) order by dms_id desc;`;
con.query(sql, [otherperson, encodeURIComponent(res.locals.username), encodeURIComponent(res.locals.username), otherperson], function (err, result) { con.query(sql, [otherperson, encodeURIComponent(res.locals.username), encodeURIComponent(res.locals.username), otherperson], function (err, result) {
if (err) throw err; if (err)
res.json(result) throw err;
res.json(result);
});
}); });
})
router.get("/api/dms/conversations", async function (req, res) { router.get("/api/dms/conversations", async function (req, res) {
res.set("Access-Control-Allow-Origin","*") res.set("Access-Control-Allow-Origin", "*");
const columns = [ const columns = [
"dms_user_name", "dms_receiver" "dms_user_name", "dms_receiver"
] ];
let uriencusername = encodeURIComponent(res.locals.username);
let uriencusername = encodeURIComponent(res.locals.username) let sql = `select ${columns.join(",")} from ipost.dms where ((dms_receiver = ?) or (dms_user_name = ?)) group by dms_receiver,dms_user_name;`;
let sql = `select ${columns.join(",")} from ipost.dms where ((dms_receiver = ?) or (dms_user_name = ?)) group by dms_receiver,dms_user_name;`
con.query(sql, [uriencusername, uriencusername], function (err, result) { con.query(sql, [uriencusername, uriencusername], function (err, result) {
if (err) throw err; if (err)
res.json(result) throw err;
res.json(result);
});
}); });
})
router.get("/api/dms/encrypt.js", async function (req, res) { router.get("/api/dms/encrypt.js", async function (req, res) {
res.set("Access-Control-Allow-Origin","*") res.set("Access-Control-Allow-Origin", "*");
res.send(web_version()) res.send(web_version());
}) });
// //
router.get("/api/dms/getDM", async function (req, res) { router.get("/api/dms/getDM", async function (req, res) {
res.set("Access-Control-Allow-Origin","*") res.set("Access-Control-Allow-Origin", "*");
let arg = req.query.id let arg = req.query.id;
let uriencusername = encodeURIComponent(res.locals.username) let uriencusername = encodeURIComponent(res.locals.username);
let sql = `select dms_user_name,dms_text,dms_time,dms_special_text,dms_id,dms_from_bot,dms_reply_id,dms_receiver from ipost.dms where dms_id=? and (dms_user_name=? or dms_receiver=?);` let sql = `select dms_user_name,dms_text,dms_time,dms_special_text,dms_id,dms_from_bot,dms_reply_id,dms_receiver from ipost.dms where dms_id=? and (dms_user_name=? or dms_receiver=?);`;
con.query(sql, [arg, uriencusername, uriencusername], function (err, result) { con.query(sql, [arg, uriencusername, uriencusername], function (err, result) {
if (err) throw err; if (err)
throw err;
if (result[0]) { if (result[0]) {
res.set('Cache-Control', 'public, max-age=2592000'); //cache it for one month-ish res.set('Cache-Control', 'public, max-age=2592000'); //cache it for one month-ish
res.json(result[0]) res.json(result[0]);
} else { }
res.json({"error":"there is no such dm!"}) else {
res.json({ "error": "there is no such dm!" });
} }
}); });
}) });
} };
} export default {
setup
};

View File

@ -1,83 +1,72 @@
const xor = require("../../../extra_modules/xor.js") import xor from "../../../extra_modules/xor.js";
export const setup = function (router, con, server) {
module.exports = { const PIDS = {}; //[pid]: true/"already_used"
"setup": function(router,con,server) {
const PIDS = {} //[pid]: true/"already_used"
router.get("/api/dms/pid", async function (req, res) { router.get("/api/dms/pid", async function (req, res) {
res.set("Access-Control-Allow-Origin","*") res.set("Access-Control-Allow-Origin", "*");
let pid = server.genstring(10) //collision chance is low enough, but we'll check anyways let pid = server.genstring(10); //collision chance is low enough, but we'll check anyways
while (PIDS[pid] != undefined) { while (PIDS[pid] != undefined) {
pid = server.genstring(10) pid = server.genstring(10);
console.log(5, "pid collision"); console.log(5, "pid collision");
} }
PIDS[pid] = true PIDS[pid] = true;
setTimeout(function () { setTimeout(function () {
PIDS[pid]=undefined PIDS[pid] = undefined;
},40000) }, 40000);
res.json({"pid":pid}) res.json({ "pid": pid });
}) });
router.post("/api/dms/post", async function (req, res) { router.post("/api/dms/post", async function (req, res) {
if (!req.body.message) { if (!req.body.message) {
res.json({"error":"no message to post"}) res.json({ "error": "no message to post" });
return return;
} }
if ((typeof req.body.message) != "string") { if ((typeof req.body.message) != "string") {
res.json({"error":"no message to post"}) res.json({ "error": "no message to post" });
return return;
} }
if ((typeof req.body.pid) != "string") { if ((typeof req.body.pid) != "string") {
res.json({"error":"no pid given"}) res.json({ "error": "no pid given" });
return return;
} }
if (req.body.pid.length != 10 || PIDS[req.body.pid] !== true) { if (req.body.pid.length != 10 || PIDS[req.body.pid] !== true) {
res.json({"error":"invalid pid given"}) res.json({ "error": "invalid pid given" });
return return;
} }
PIDS[req.body.pid] = "already_used" PIDS[req.body.pid] = "already_used";
let reply_id;
let reply_id
if (!req.body.reply_id || req.body.reply_id < 0) { if (!req.body.reply_id || req.body.reply_id < 0) {
reply_id = 0 reply_id = 0;
} else { }
reply_id = req.body.reply_id else {
reply_id = req.body.reply_id;
} }
if ((typeof reply_id) != "number") { if ((typeof reply_id) != "number") {
res.json({"error":"no valid reply id given"}) res.json({ "error": "no valid reply id given" });
return return;
} }
if (req.body.message.length > 1000) { if (req.body.message.length > 1000) {
res.json({"error":"message too long"}) res.json({ "error": "message too long" });
return return;
} }
req.body.message = encodeURIComponent(req.body.message.trim());
req.body.message = encodeURIComponent(req.body.message.trim())
if (req.body.message.length > 3000) { if (req.body.message.length > 3000) {
res.json({"error":"message too long"}) //check again after URI encoding it res.json({ "error": "message too long" }); //check again after URI encoding it
return return;
} }
req.body.receiver = encodeURIComponent(req.body.receiver || "");
req.body.receiver = encodeURIComponent(req.body.receiver||"")
if (req.body.receiver == "" || req.body.receiver == encodeURIComponent(res.locals.username) || req.body.receiver.length > 100) { if (req.body.receiver == "" || req.body.receiver == encodeURIComponent(res.locals.username) || req.body.receiver.length > 100) {
res.status(400).json({"error": "invalid receiver given"}) res.status(400).json({ "error": "invalid receiver given" });
return return;
} }
let otherperson = req.body.receiver let otherperson = req.body.receiver;
if (!req.body.message) { if (!req.body.message) {
res.json({"error":"no message to post"}) res.json({ "error": "no message to post" });
return return;
} }
let sql = `insert into ipost.dms (dms_user_name,dms_text,dms_time,dms_receiver,dms_from_bot,dms_reply_id) values (?,?,?,?,?,?);`;
let sql = `insert into ipost.dms (dms_user_name,dms_text,dms_time,dms_receiver,dms_from_bot,dms_reply_id) values (?,?,?,?,?,?);` let values = [encodeURIComponent(res.locals.username), req.body.message, Date.now(), otherperson, res.locals.isbot, reply_id];
let values = [encodeURIComponent(res.locals.username),req.body.message,Date.now(),otherperson,res.locals.isbot,reply_id]
con.query(sql, values, function (err, result) { con.query(sql, values, function (err, result) {
if (err) throw err; if (err)
throw err;
// let post_obj = { // let post_obj = {
// post_user_name: encodeURIComponent(res.locals.username), // post_user_name: encodeURIComponent(res.locals.username),
// post_text: req.body.message, // post_text: req.body.message,
@ -87,7 +76,6 @@ module.exports = {
// post_from_bot: res.locals.isbot, // post_from_bot: res.locals.isbot,
// post_reply_id: reply_id // post_reply_id: reply_id
// } // }
// let message = { // let message = {
// message: "new_post", // message: "new_post",
// data: post_obj // data: post_obj
@ -98,9 +86,11 @@ module.exports = {
// ws.send(messagestr) // ws.send(messagestr)
// } // }
// }); // });
res.json({"success":"successfully posted dm"}) res.json({ "success": "successfully posted dm" });
console.log(5, `posted new dm by ${res.locals.username} to ${otherperson} : ${xor(encodeURIComponent(res.locals.username), otherperson)}`); console.log(5, `posted new dm by ${res.locals.username} to ${otherperson} : ${xor(encodeURIComponent(res.locals.username), otherperson)}`);
}); });
}) });
} };
} export default {
setup
};

View File

@ -1,57 +1,18 @@
function allowAllTraffic(router, str, type) { function allowAllTraffic(router, str, type) {
router.options(str, async function (req, res, next) { router.options(str, async function (req, res, next) {
res.set("Access-Control-Allow-Origin","*") //we'll allow it for now res.set("Access-Control-Allow-Origin", "*"); //we'll allow it for now
res.set("Access-Control-Allow-Methods",type || "GET") res.set("Access-Control-Allow-Methods", type || "GET");
res.set("Access-Control-Allow-Headers","Content-Type") res.set("Access-Control-Allow-Headers", "Content-Type");
res.status(200).send("") res.status(200).send("");
}) });
}
module.exports = {
"setup": function(router,con,server) {
// router.options("/api/pid",async function(req,res,next) {
// res.set("Access-Control-Allow-Origin","*") //we'll allow it for now
// res.set("Access-Control-Allow-Methods","GET")
// res.set("Access-Control-Allow-Headers","Content-Type")
// res.status(200).send("")
// })
// router.options("/api/post",async function(req,res,next) {
// res.set("Access-Control-Allow-Origin","*") //we'll allow it for now
// res.set("Access-Control-Allow-Methods","POST")
// res.set("Access-Control-Allow-Headers","Content-Type")
// res.status(200).send("")
// })
// router.options("/api/getotheruser",async function(req,res,next) {
// res.set("Access-Control-Allow-Origin","*") //we'll allow it for now
// res.set("Access-Control-Allow-Methods","GET")
// res.set("Access-Control-Allow-Headers","Content-Type")
// res.status(200).send("")
// })
// router.options("/api/getPost",async function(req,res,next) {
// res.set("Access-Control-Allow-Origin","*") //we'll allow it for now
// res.set("Access-Control-Allow-Methods","GET")
// res.set("Access-Control-Allow-Headers","Content-Type")
// res.status(200).send("")
// })
//
// router.options("/api/getPostsLowerThan",async function(req,res,next) {
// res.set("Access-Control-Allow-Origin","*") //we'll allow it for now
// res.set("Access-Control-Allow-Methods","GET")
// res.set("Access-Control-Allow-Headers","Content-Type")
// res.status(200).send("")
// })
allowAllTraffic(router,"/api/pid")
allowAllTraffic(router,"/api/post","POST")
allowAllTraffic(router,"/api/getotheruser")
allowAllTraffic(router,"/api/getPost")
allowAllTraffic(router,"/api/getPostsLowerThan")
allowAllTraffic(router,"/api/settings")
allowAllTraffic(router,"/api/settings","POST")
} }
function setup(router, con, server) {
allowAllTraffic(router, "/api/pid");
allowAllTraffic(router, "/api/post", "POST");
allowAllTraffic(router, "/api/getotheruser");
allowAllTraffic(router, "/api/getPost");
allowAllTraffic(router, "/api/getPostsLowerThan");
allowAllTraffic(router, "/api/settings");
allowAllTraffic(router, "/api/settings", "POST");
} }
export { setup };

View File

@ -1,77 +1,68 @@
module.exports = { export const setup = function (router, con, server) {
"setup": function(router,con,server) { const PIDS = {}; //[pid]: true/"already_used"
const PIDS = {} //[pid]: true/"already_used"
router.get("/api/pid", async function (req, res) { router.get("/api/pid", async function (req, res) {
res.set("Access-Control-Allow-Origin","*") res.set("Access-Control-Allow-Origin", "*");
let pid = server.genstring(10) //collision chance is low enough, but we'll check anyways let pid = server.genstring(10); //collision chance is low enough, but we'll check anyways
while (PIDS[pid] != undefined) { while (PIDS[pid] != undefined) {
pid = server.genstring(10) pid = server.genstring(10);
console.log(5, "pid collision"); console.log(5, "pid collision");
} }
PIDS[pid] = true PIDS[pid] = true;
setTimeout(function () { setTimeout(function () {
PIDS[pid]=undefined PIDS[pid] = undefined;
},40000) }, 40000);
res.json({"pid":pid}) res.json({ "pid": pid });
}) });
router.post("/api/post", async function (req, res) { router.post("/api/post", async function (req, res) {
if (!req.body.message) { if (!req.body.message) {
res.json({"error":"no message to post"}) res.json({ "error": "no message to post" });
return return;
} }
if ((typeof req.body.message) != "string") { if ((typeof req.body.message) != "string") {
res.json({"error":"no message to post"}) res.json({ "error": "no message to post" });
return return;
} }
if ((typeof req.body.pid) != "string") { if ((typeof req.body.pid) != "string") {
res.json({"error":"no pid given"}) res.json({ "error": "no pid given" });
return return;
} }
if (req.body.pid.length != 10 || PIDS[req.body.pid] !== true) { if (req.body.pid.length != 10 || PIDS[req.body.pid] !== true) {
res.json({"error":"invalid pid given"}) res.json({ "error": "invalid pid given" });
return return;
} }
PIDS[req.body.pid] = "already_used" PIDS[req.body.pid] = "already_used";
let reply_id;
let reply_id
if (!req.body.reply_id || req.body.reply_id < 0) { if (!req.body.reply_id || req.body.reply_id < 0) {
reply_id = 0 reply_id = 0;
} else { }
reply_id = req.body.reply_id else {
reply_id = req.body.reply_id;
} }
if ((typeof req.body.reply_id) != "number") { if ((typeof req.body.reply_id) != "number") {
res.json({"error":"no valid reply id given"}) res.json({ "error": "no valid reply id given" });
return return;
} }
if (req.body.message.length > 1000) { if (req.body.message.length > 1000) {
res.json({"error":"message too long"}) res.json({ "error": "message too long" });
return return;
} }
req.body.message = encodeURIComponent(req.body.message.trim());
req.body.message = encodeURIComponent(req.body.message.trim())
if (req.body.message.length > 3000) { if (req.body.message.length > 3000) {
res.json({"error":"message too long"}) //check again after URI encoding it res.json({ "error": "message too long" }); //check again after URI encoding it
return return;
} }
req.body.receiver = encodeURIComponent(req.body.receiver || "");
req.body.receiver = encodeURIComponent(req.body.receiver||"") if (req.body.receiver == "")
if(req.body.receiver == "")req.body.receiver="everyone" req.body.receiver = "everyone";
if (!req.body.message) { if (!req.body.message) {
res.json({"error":"no message to post"}) res.json({ "error": "no message to post" });
return return;
} }
let sql = `insert into ipost.posts (post_user_name,post_text,post_time,post_receiver_name,post_from_bot,post_reply_id) values (?,?,?,?,?,?);`;
let sql = `insert into ipost.posts (post_user_name,post_text,post_time,post_receiver_name,post_from_bot,post_reply_id) values (?,?,?,?,?,?);` let values = [encodeURIComponent(res.locals.username), req.body.message, Date.now(), req.body.receiver, res.locals.isbot, reply_id];
let values = [encodeURIComponent(res.locals.username),req.body.message,Date.now(),req.body.receiver,res.locals.isbot,reply_id]
con.query(sql, values, function (err, result) { con.query(sql, values, function (err, result) {
if (err) throw err; if (err)
throw err;
let post_obj = { let post_obj = {
post_user_name: encodeURIComponent(res.locals.username), post_user_name: encodeURIComponent(res.locals.username),
post_text: req.body.message, post_text: req.body.message,
@ -80,22 +71,23 @@ module.exports = {
post_receiver_name: req.body.receiver, post_receiver_name: req.body.receiver,
post_from_bot: res.locals.isbot, post_from_bot: res.locals.isbot,
post_reply_id: reply_id post_reply_id: reply_id
} };
let message = { let message = {
message: "new_post", message: "new_post",
data: post_obj data: post_obj
} };
let messagestr = JSON.stringify(message) let messagestr = JSON.stringify(message);
let channel = decodeURIComponent(req.body.receiver) let channel = decodeURIComponent(req.body.receiver);
server.wss.clients.forEach(async function (ws) { server.wss.clients.forEach(async function (ws) {
if (ws.channel == channel) { if (ws.channel == channel) {
ws.send(messagestr) ws.send(messagestr);
} }
}); });
res.json({"success":"successfully posted message"}) res.json({ "success": "successfully posted message" });
console.log(5, `posted new message by ${res.locals.username} : ${req.body.message}`); console.log(5, `posted new message by ${res.locals.username} : ${req.body.message}`);
}); });
}) });
} };
} export default {
setup
};

View File

@ -1,27 +1,22 @@
const allowed_settings = { //"settingname":["validtypes"] const allowed_settings = {
"ACCR": ["boolean"] "ACCR": ["boolean"]
} };
export const setup = function (router, con, server) {
module.exports = {
"setup": function(router,con,server) {
router.get("/api/settings", function (req, res) { router.get("/api/settings", function (req, res) {
res.json(res.locals.settings) res.json(res.locals.settings);
}) });
router.post("/api/settings", function (req, res) { router.post("/api/settings", function (req, res) {
if (!req.body.setting) { if (!req.body.setting) {
res.json({"error":"no setting to change"}) res.json({ "error": "no setting to change" });
return return;
} }
if ((typeof req.body.setting) != "string") { if ((typeof req.body.setting) != "string") {
res.json({"error":"no setting to change"}) res.json({ "error": "no setting to change" });
return return;
} }
let types = allowed_settings[req.body.setting];
let types = allowed_settings[req.body.setting] let allowed = false;
let allowed = false let got = typeof req.body.value;
let got = typeof req.body.value
for (let index = 0; index < types.length; index++) { for (let index = 0; index < types.length; index++) {
if (types[index] == got) { if (types[index] == got) {
allowed = true; allowed = true;
@ -29,27 +24,25 @@ module.exports = {
} }
} }
if (!allowed) { if (!allowed) {
console.log(5,"incorrect type given, received, expected", typeof req.body.value, allowed_settings[req.body.setting]) console.log(5, "incorrect type given, received, expected", typeof req.body.value, allowed_settings[req.body.setting]);
res.json({"error":"no new setting value given"}) res.json({ "error": "no new setting value given" });
return return;
} }
let setting_to_change = req.body.setting;
let setting_to_change = req.body.setting let setting_new_value = req.body.value;
let setting_new_value = req.body.value res.locals.settings[setting_to_change] = setting_new_value;
console.log(5, "changing settings", setting_to_change, setting_new_value, res.locals.settings);
res.locals.settings[setting_to_change] = setting_new_value let sql = "update ipost.users set User_Settings=? where User_Name=?";
let values = [JSON.stringify(res.locals.settings), res.locals.username];
console.log(5,"changing settings", setting_to_change, setting_new_value, res.locals.settings)
let sql = "update ipost.users set User_Settings=? where User_Name=?"
let values = [JSON.stringify(res.locals.settings),res.locals.username]
con.query(sql, values, function (err, result) { con.query(sql, values, function (err, result) {
if (err) { if (err) {
res.json({"status":"error","code":err}) res.json({ "status": "error", "code": err });
return return;
}
res.json({"status":"success"})
})
})
}
} }
res.json({ "status": "success" });
});
});
};
export default {
setup
};

View File

@ -1,5 +1,5 @@
const fs = require("fs"); import "fs"
const util = require('util'); import {format} from "util"
/** /**
@ -14,7 +14,7 @@ function ensureExists(path, mask, cb) {
cb = mask; cb = mask;
mask = 0o744; mask = 0o744;
} }
fs.mkdir(path, mask, function(err) { mkdir(path, mask, function(err) {
if (err) { if (err) {
if (err.code == 'EEXIST') cb(null); // Ignore the error if the folder already exists if (err.code == 'EEXIST') cb(null); // Ignore the error if the folder already exists
else cb(err); // Something else went wrong else cb(err); // Something else went wrong
@ -22,7 +22,7 @@ function ensureExists(path, mask, cb) {
}); });
} }
const config = JSON.parse(fs.readFileSync("server_config.json")) const config = JSON.parse(readFileSync("server_config.json"))
const time = Date.now() const time = Date.now()
const original_log = console.log const original_log = console.log
@ -41,13 +41,13 @@ function log_info(level, ...info) {
level = 5 level = 5
} }
if(config["logs"] && config["logs"]["level"] && config["logs"]["level"] >= level) { if(config["logs"] && config["logs"]["level"] && config["logs"]["level"] >= level) {
let tolog = `[INFO] [${Date.now()}] : ${util.format(text)} \n` let tolog = `[INFO] [${Date.now()}] : ${format(text)} \n`
original_log(tolog) //still has some nicer colors original_log(tolog) //still has some nicer colors
ensureExists(__dirname + '/logs/', function(err) { ensureExists(__dirname + '/logs/', function(err) {
if(err) { if(err) {
process.stderr.write(tolog) //just write it to stderr process.stderr.write(tolog) //just write it to stderr
} else { } else {
fs.appendFile(__dirname+"/logs/"+time,tolog,function(err){ appendFile(__dirname+"/logs/"+time,tolog,function(err){
if(err){ if(err){
process.stderr.write(err) process.stderr.write(err)
} }
@ -67,7 +67,6 @@ console.log(5,"starting up")
const http = require('http'); const http = require('http');
const https = require('https'); const https = require('https');
const crypto = require("crypto");
const express = require("express"); const express = require("express");
const useragent = require('express-useragent'); const useragent = require('express-useragent');
const fileUpload = require('express-fileupload'); const fileUpload = require('express-fileupload');
@ -93,12 +92,12 @@ const con = mysql.createPool({
connectionLimit : config.mysql.connections, connectionLimit : config.mysql.connections,
host: config.mysql.host, host: config.mysql.host,
user: config.mysql.user, user: config.mysql.user,
password: fs.readFileSync(config.mysql.password_file).toString() password: readFileSync(config.mysql.password_file).toString()
}); });
const dir = __dirname + "/" const dir = __dirname + "/"
const cookiesecret = fs.readFileSync("cookiesecret.txt").toString() const cookiesecret = readFileSync("cookiesecret.txt").toString()
const SHA = require("./extra_modules/SHA.js") const SHA = require("./extra_modules/SHA.js")
@ -419,19 +418,34 @@ var commonfunctions = {
genstring genstring
} }
const toLoad = [ import {setup as optionssetup} from "./routes/api/options.js"
"api/options.js", import {setup as allsetup} from "./routes/api/all.js"
"api/all.js", import {setup as settingshandlersetup} from "./routes/api/settingshandler.js"
"api/settingshandler.js", import {setup as postsetup} from "./routes/api/post.js"
"api/post.js", import {setup as dmsPersonalMessagessetup} from "./routes/api/dms/PersonalMessages.js"
"api/dms/PersonalMessages.js", import {setup as dmspostsetup} from "./routes/api/dms/post.js"
"api/dms/post.js",
]
for (let i = 0; i < toLoad.length; i++) { optionssetup(router,con,commonfunctions)
require("./routes/"+toLoad[i]).setup(router,con,commonfunctions) allsetup(router,con,commonfunctions)
} settingshandlersetup(router,con,commonfunctions)
postsetup(router,con,commonfunctions)
dmsPersonalMessagessetup(router,con,commonfunctions)
dmspostsetup(router,con,commonfunctions)
// const toLoad = [
// "api/options.js",
// "api/all.js",
// "api/settingshandler.js",
// "api/post.js",
// "api/dms/PersonalMessages.js",
// "api/dms/post.js",
// ]
// for (let i = 0; i < toLoad.length; i++) {
// require("./routes/"+toLoad[i]).setup(router,con,commonfunctions)
// }
// let options = require("./routes/api/options.js") // let options = require("./routes/api/options.js")
// options.setup(router,con,commonfunctions) // options.setup(router,con,commonfunctions)
@ -494,10 +508,10 @@ router.post("/api/setavatar",function(req,res) {
return res.status(500).json({"error":"there's been an internal server error."}) return res.status(500).json({"error":"there's been an internal server error."})
} }
if(res.locals.avatar) { if(res.locals.avatar) {
fs.unlinkSync(avatars + res.locals.avatar) unlinkSync(avatars + res.locals.avatar)
} }
let filename = genstring(96) + ".png" let filename = genstring(96) + ".png"
while(fs.existsSync(avatars + "/" + filename) || filename == ".png") { while(existsSync(avatars + "/" + filename) || filename == ".png") {
console.log(5,"already have file: ",filename); console.log(5,"already have file: ",filename);
original_log("already have file: ",filename) original_log("already have file: ",filename)
filename = genstring(96) + ".png" filename = genstring(96) + ".png"
@ -513,7 +527,7 @@ router.post("/api/setavatar",function(req,res) {
con.query(sql, [filename,encodeURIComponent(res.locals.username)], function (err, result) { con.query(sql, [filename,encodeURIComponent(res.locals.username)], function (err, result) {
if (err) throw err; if (err) throw err;
res.json({"success":"updated avatar"}) res.json({"success":"updated avatar"})
fs.unlinkSync(avatars+"temp_"+filename) unlinkSync(avatars+"temp_"+filename)
}); });
}) })
}) })
@ -769,7 +783,7 @@ router.get("/users/*", async function(req,res) {
router.get("/css/*", (request, response) => { router.get("/css/*", (request, response) => {
if(!increaseUSERCall(request,response))return if(!increaseUSERCall(request,response))return
if(fs.existsSync(__dirname + request.originalUrl)){ if(existsSync(__dirname + request.originalUrl)){
response.sendFile(__dirname + request.originalUrl); response.sendFile(__dirname + request.originalUrl);
} else { } else {
response.status(404).send("no file with that name found") response.status(404).send("no file with that name found")
@ -779,7 +793,7 @@ router.get("/css/*", (request, response) => {
router.get("/js/*", (request, response) => { router.get("/js/*", (request, response) => {
if(!increaseUSERCall(request,response))return if(!increaseUSERCall(request,response))return
if(fs.existsSync(__dirname + request.originalUrl)){ if(existsSync(__dirname + request.originalUrl)){
response.sendFile(__dirname + request.originalUrl); response.sendFile(__dirname + request.originalUrl);
} else { } else {
response.status(404).send("no file with that name found") response.status(404).send("no file with that name found")
@ -789,7 +803,7 @@ router.get("/js/*", (request, response) => {
router.get("/images/*", (request, response) => { router.get("/images/*", (request, response) => {
if(!increaseUSERCall(request,response))return if(!increaseUSERCall(request,response))return
if(fs.existsSync(__dirname + request.originalUrl)){ if(existsSync(__dirname + request.originalUrl)){
response.sendFile(__dirname + request.originalUrl); response.sendFile(__dirname + request.originalUrl);
} else { } else {
response.status(404).send("no file with that name found") response.status(404).send("no file with that name found")
@ -801,10 +815,10 @@ router.get("/avatars/*", (request, response, next) => {
if(!increaseUSERCall(request,response))return if(!increaseUSERCall(request,response))return
response.set('Cache-Control', 'public, max-age=2592000'); //cache it for one month-ish response.set('Cache-Control', 'public, max-age=2592000'); //cache it for one month-ish
let originalUrl = request.originalUrl.split("?").shift() let originalUrl = request.originalUrl.split("?").shift()
if(fs.existsSync(dir + originalUrl + ".png")) { if(existsSync(dir + originalUrl + ".png")) {
return response.sendFile(dir + originalUrl + ".png"); return response.sendFile(dir + originalUrl + ".png");
} }
if(fs.existsSync(dir + originalUrl)) { if(existsSync(dir + originalUrl)) {
return response.sendFile(dir + originalUrl); return response.sendFile(dir + originalUrl);
} }
response.status(404).send("No avatar with that name found") response.status(404).send("No avatar with that name found")
@ -818,16 +832,16 @@ router.get("/logout",async function(req,res) {
router.get("/*", (request, response, next) => { router.get("/*", (request, response, next) => {
if(!increaseUSERCall(request,response))return if(!increaseUSERCall(request,response))return
let originalUrl = request.originalUrl.split("?").shift() let originalUrl = request.originalUrl.split("?").shift()
if(fs.existsSync(dir + "views/"+originalUrl+".html")) { if(existsSync(dir + "views/"+originalUrl+".html")) {
return response.sendFile(dir + "views/"+originalUrl+".html"); return response.sendFile(dir + "views/"+originalUrl+".html");
} }
if(fs.existsSync(dir + "views"+originalUrl)) { if(existsSync(dir + "views"+originalUrl)) {
return response.sendFile(dir + "views"+originalUrl); return response.sendFile(dir + "views"+originalUrl);
} }
if(fs.existsSync(dir + "views"+originalUrl+".html")) { if(existsSync(dir + "views"+originalUrl+".html")) {
return response.sendFile(dir + "views"+originalUrl+".html"); return response.sendFile(dir + "views"+originalUrl+".html");
} }
if(fs.existsSync(dir + "views"+originalUrl)) { if(existsSync(dir + "views"+originalUrl)) {
return response.sendFile(dir + "views"+originalUrl); return response.sendFile(dir + "views"+originalUrl);
} }
response.status(404).send("No file with that name found") response.status(404).send("No file with that name found")
@ -986,8 +1000,8 @@ httpServer.listen(config["ports"]["http"],function(){
console.log(5,"HTTP Server is listening") console.log(5,"HTTP Server is listening")
}); });
const privateKey = fs.readFileSync(config["ssl"]["privateKey"]).toString() const privateKey = readFileSync(config["ssl"]["privateKey"]).toString()
const certificate = fs.readFileSync(config["ssl"]["certificate"]).toString() const certificate = readFileSync(config["ssl"]["certificate"]).toString()
const credentials = {key: privateKey, cert: certificate}; const credentials = {key: privateKey, cert: certificate};

1036
server_esm.js Normal file

File diff suppressed because it is too large Load Diff