diff --git a/createSchema.sql b/createSchema.sql new file mode 100644 index 0000000..c553d6d --- /dev/null +++ b/createSchema.sql @@ -0,0 +1,27 @@ +drop schema if exists zerotwohub; + +create schema zerotwohub; +use zerotwohub; + +CREATE TABLE `users` ( + `User_ID` bigint NOT NULL AUTO_INCREMENT, + `User_Name` varchar(250) NOT NULL, + `User_PW` varchar(45) NOT NULL, + `User_CreationStamp` varchar(1000) NOT NULL DEFAULT 'None', + `User_CreationIP` varchar(45) NOT NULL DEFAULT 'None', + `User_LastIP` varchar(45) NOT NULL DEFAULT 'None', + `User_Bio` varchar(100) DEFAULT 'wow such empty', + PRIMARY KEY (`User_ID`,`User_Name`), + UNIQUE KEY `User_Name_UNIQUE` (`User_Name`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; + + +CREATE TABLE `posts` ( + `post_id` bigint NOT NULL AUTO_INCREMENT, + `post_user_name` varchar(25) NOT NULL, + `post_text` varchar(4000) NOT NULL, + `post_time` bigint NOT NULL, + `post_special_text` varchar(100) DEFAULT NULL, + `post_ip` varchar(12) DEFAULT NULL, + PRIMARY KEY (`post_id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; diff --git a/css/posts.css b/css/posts.css index caef756..cddab2a 100644 --- a/css/posts.css +++ b/css/posts.css @@ -65,3 +65,17 @@ a:link, a:visited { a:hover { color: red; } + +.post,.self { + width: 50%; + margin-left: 25%; + margin-right: 25%; + margin-top: 10px; + margin-bottom: 10px; + border-radius: 10px; +} + +#post-text, button { + border-radius: 5px; + resize: none; +} diff --git a/js/posts.js b/js/posts.js index 55a44bd..e8c3661 100644 --- a/js/posts.js +++ b/js/posts.js @@ -15,8 +15,8 @@ socket.addEventListener("message", function (event) { } }) function urlify(text) { - let textregex = /(([a-z]+:\/\/)?(([a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal|tk|ga))(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(\s+|$)/gi - return text.replace(textregex,'$1 ') + let textregex = /(([a-z]+:\/\/)(([a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal|tk|ga|xxx|to))(:[0-9]{1,5})?(\/[a-z0-9_\-\.~]+)*(\/([a-z0-9_\-\.]*)(\?[a-z0-9+_\-\.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(\s+|$)/gi + return text.replace(textregex,'$1 ') } function newlineify(text) { @@ -76,7 +76,7 @@ function spacerTextNode() { return document.createTextNode(" | ") } -function createPost(username,text,time,specialtext) { +function createPost(username,text,time,specialtext,postid) { if(!specialtext)specialtext="" const newDiv = document.createElement("div"); const newP = document.createElement("p"); @@ -115,7 +115,7 @@ function createPost(username,text,time,specialtext) { newDiv.appendChild(newP) newDiv.innerHTML += filterPost(text) - + newDiv.id = postid document.getElementById("posts").appendChild(newDiv) } @@ -132,8 +132,14 @@ async function main(){ if(!last_10_posts)return; document.getElementById("posts").innerHTML = "" last_10_posts.forEach((item, i) => { - createPost(item.post_user_name,item.post_text,item.post_time,item.post_special_text) + createPost(decodeURIComponent(atob(item.post_user_name)),decodeURIComponent(atob(item.post_text)),item.post_time,item.post_special_text,item.post_id) }); + + let links = document.getElementsByClassName("insertedlink") + for (let i = 0; i < links.length; i++) { + links[i].innerText = links[i].innerText.split("\/\/")[1].split("\/")[0] + } + let mentions = document.getElementsByClassName("mention") for (let i = 0; i < mentions.length; i++) { if(mentions[i]!=undefined && mentions[i].innerText == "@"+username) { diff --git a/package-lock.json b/package-lock.json index f12eb86..b2d4ed6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "npm-proj-1652743886349-0.8272252042668449rQTGrH", + "name": "npm-proj-1653260782527-0.21350200299500766FoScfK", "lockfileVersion": 2, "requires": true, "packages": { @@ -8,12 +8,12 @@ "body-parser": "^1.20.0", "cookie-parser": "^1.4.6", "csurf": "^1.11.0", - "express": "^4.18.0", + "express": "^4.18.1", "express-fileupload": "^1.3.1", "express-useragent": "^1.0.15", "helmet": "^5.0.2", "mysql": "^2.18.1", - "ws": "^8.5.0" + "ws": "^8.6.0" } }, "node_modules/accepts": { @@ -286,9 +286,9 @@ } }, "node_modules/express": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", - "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -916,9 +916,9 @@ } }, "node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz", + "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==", "engines": { "node": ">=10.0.0" }, @@ -1145,9 +1145,9 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "express": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", - "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -1622,9 +1622,9 @@ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz", + "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==", "requires": {} } } diff --git a/package.json b/package.json index e3377b8..2976260 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,11 @@ "body-parser": "^1.20.0", "cookie-parser": "^1.4.6", "csurf": "^1.11.0", - "express": "^4.18.0", + "express": "^4.18.1", "express-fileupload": "^1.3.1", "express-useragent": "^1.0.15", "helmet": "^5.0.2", "mysql": "^2.18.1", - "ws": "^8.5.0" + "ws": "^8.6.0" } } diff --git a/server.js b/server.js index 4a94bd5..c243321 100644 --- a/server.js +++ b/server.js @@ -49,6 +49,11 @@ function SHA256(str,salt,num) { return ret; } +function b64(data) { + let buff = Buffer.from(data); + return buff.toString('base64'); +} + function RNG(seed) { if(!seed)seed = Date.now(); this.seed = seed @@ -214,34 +219,37 @@ router.use("/api/*",async function(req,res,next) { } let unsigned = unsign(cookie,req,res) if(!unsigned)return + unsigned = decodeURIComponent(unsigned) let sql = `select * from zerotwohub.users where User_Name=? and User_PW=?;` let values = unsigned.split(" ") values[1] = SHA256(values[1],values[0],HASHES_DIFF) + values[0] = b64(values[0]) con.query(sql, values, function (err, result) { if (err) throw err; if(result[0] && result[0].User_Name && result[0].User_Name == values[0]) { - res.locals.username = values[0]; + res.locals.username = atob(values[0]); res.locals.bio = result[0].User_Bio next() } else { + console.log(result[0],values[0],values[1]); res.json({"error":"you cannot access the api without being logged in"}) } }); }) router.get("/api/getuser",async function(req,res) { - res.json({"username":res.locals.username,"bio":res.locals.bio}) + res.json({"username":res.locals.username,"bio":atob(res.locals.bio)}) }) router.get("/api/getotheruser",async function(req,res) { //already counted due to the /api/* handler - let username = req.query.user + let username = b64(req.query.user) let sql = `select * from zerotwohub.users where User_Name=?;` con.query(sql, [username], function (err, result) { if (err) throw err; if(result[0] && result[0].User_Name && result[0].User_Name == username) { - res.json({"username":username,"bio":result[0].User_Bio}) + res.json({"username":atob(username),"bio":atob(result[0].User_Bio)}) } else { res.json({"error":"there is no such user!"}) } @@ -249,12 +257,14 @@ router.get("/api/getotheruser",async function(req,res) { }) router.post("/api/post", async function(req,res) { + req.body.message = encodeURIComponent(req.body.message.trim()) if(!req.body.message) { res.json({"error":"no message to post"}) return } + let sql = `insert into zerotwohub.posts (post_user_name,post_text,post_time) values (?,?,?);` - let values = [res.locals.username,req.body.message,Date.now()] + let values = [b64(encodeURIComponent(res.locals.username)),b64(req.body.message),Date.now()] con.query(sql, values, function (err, result) { if (err) throw err; console.log(result); @@ -278,7 +288,7 @@ router.post("/api/post", async function(req,res) { // }) router.get("/api/getPosts/*", async function(req,res) { - let sql = `select post_user_name,post_text,post_time,post_special_text from zerotwohub.posts order by post_id desc;` + let sql = `select post_user_name,post_text,post_time,post_special_text,post_id from zerotwohub.posts order by post_id desc;` con.query(sql, [], function (err, result) { if (err) throw err; res.json(result) @@ -293,7 +303,7 @@ router.post("/api/setBio", async function(req,res) { return } let sql = `update zerotwohub.users set User_Bio=? where User_Name=?` - con.query(sql, [bio,res.locals.username], function (err, result) { + con.query(sql, [b64(encodeURIComponent(bio)),b64(encodeURIComponent(res.locals.username))], function (err, result) { if (err) throw err; res.json({"success":"updated bio"}) }); @@ -310,12 +320,12 @@ router.post("/api/changePW", async function(req,res) { let hashed_new_pw = SHA256(req.body.newPW,res.locals.username,HASHES_DB) let sql = `select * from zerotwohub.users where User_Name=? and User_PW=?;` - let values = [res.locals.username,hashed_pw] + let values = [b64(res.locals.username),hashed_pw] con.query(sql, values, function (err, result) { if (err) throw err; if(result[0] && result[0].User_Name && result[0].User_Name == res.locals.username) { let sql = `update zerotwohub.users set User_PW=? where User_Name=? and User_PW=?;` - let values = [hashed_new_pw,res.locals.username,hashed_pw] + let values = [hashed_new_pw,b64(res.locals.username),hashed_pw] con.query(sql, values, function (err, result) { if (err) throw err; let ip = req.socket.remoteAddress @@ -424,7 +434,7 @@ router.post("/register",async function(req,res) { return } let userexistssql = `SELECT User_Name from zerotwohub.users where User_Name = ?` - con.query(userexistssql,[username],function(error,result) { + con.query(userexistssql,[b64(encodeURIComponent(username))],function(error,result) { if(result && result[0] && result[0].User_Name) { res.status(400) res.redirect("/register?success=false&reason=already_exists") @@ -432,12 +442,13 @@ router.post("/register",async function(req,res) { } let hashed_pw = SHA256(password,username,HASHES_DB) let ip = req.socket.remoteAddress - let values = [username,hashed_pw, Date.now(), ip, ip] + let cookiesigned = signature.sign(setTo, cookiesecret+ip); + let setTo = username + " " + SHA256(password,username,HASHES_COOKIE) + ip = SHA256(ip,setTo,HASHES_DB) + let values = [b64(encodeURIComponent(username)),hashed_pw, Date.now(), ip, ip] let sql = `INSERT INTO zerotwohub.users (User_Name, User_PW, User_CreationStamp, User_CreationIP, User_LastIP) VALUES (?, ?, ?, ? ,?);` con.query(sql, values, function (err, result) { if (err) throw err; - let setTo = username + " " + SHA256(password,username,HASHES_COOKIE) - let cookiesigned = signature.sign(setTo, cookiesecret+ip); res.cookie('AUTH_COOKIE',cookiesigned, { maxAge: Math.pow(10,10), httpOnly: true, secure: DID_I_FINALLY_ADD_HTTPS }); res.redirect("/user?success=true") }); @@ -475,21 +486,24 @@ router.post("/login",async function(req,res) { let hashed_pw = SHA256(password,username,HASHES_DB) let userexistssql = `SELECT User_Name,User_PW,User_LastIP from zerotwohub.users where User_Name = ? and User_PW = ?;` - con.query(userexistssql,[username,hashed_pw],function(error,result) { - if(result && result[0] && result[0].User_Name && result[0].User_Name==username && result[0].User_PW && result[0].User_PW == hashed_pw) { + con.query(userexistssql,[b64(encodeURIComponent(username)),hashed_pw],function(error,result) { + if(result && result[0] && result[0].User_Name && result[0].User_Name==b64(encodeURIComponent(username)) && result[0].User_PW && result[0].User_PW == hashed_pw) { let ip = req.socket.remoteAddress let setTo = username + " " + SHA256(password,username,HASHES_COOKIE) let cookiesigned = signature.sign(setTo, cookiesecret+ip); res.cookie('AUTH_COOKIE',cookiesigned, { maxAge: Math.pow(10,10), httpOnly: true, secure: DID_I_FINALLY_ADD_HTTPS }); res.redirect("/user?success=true") + + ip = SHA256(ip,setTo,HASHES_DB) + if(result[0].User_LastIP != ip) { let sql = `update zerotwohub.users set User_LastIP = ? where User_Name = ?;` - con.query(sql,[ip,username],function(error,result) { + con.query(sql,[ip,b64(encodeURIComponent(username))],function(error,result) { if(error)throw error }) } } else { - res.redirect("/login?success=false") + res.redirect("/login?success=false?reason=noUser") } }); })