const express = require('express'); const crypto = require('crypto'); // For encrypting passwords const { fromUnixTime, format, getUnixTime } = require("date-fns") const fs = require('fs'); const users = require('./users.js'); const posts = require('./posts.js'); const config = require('./config.js'); const app = express(); const port = 8080; app.use(express.urlencoded({ extended: true })); app.use(express.json()); app.use(express.static(config.root_path)); function get_userID(username) { for (let i = 0; i < users.users.length; i++) { if (users.users[i]['username'] == username) { return i } } return -1 } function unix_time_to_date_format(unix_time) { date = fromUnixTime(unix_time) formatted_date = format(date, config.date_format) return formatted_date } function unix_time_to_rss_date(unix_time) { date = fromUnixTime(unix_time) formatted_date = format(date, "EEE, dd MMM yyyy HH:mm:ss") return `${formatted_date} ${config.time_zone}` } function hyperlink_tags(tags) { string = "" for (let tag_index = 0; tag_index < tags.length; tag_index++) { string += `${tags[tag_index]}` if (tag_index < tags.length - 1) { string += ", "; } } return string } function replace_format_indicators(input_string, post_index=0, tag_name="tag") { post_object = posts.posts[post_index] output_string = input_string .replaceAll("%A", (post_object["tags"])) .replaceAll("%B", (hyperlink_tags(post_object["tags"]))) .replaceAll("%C", post_object["content"].replaceAll("\n","
")) .replaceAll("%D", unix_time_to_date_format(post_object["pubdate"])) .replaceAll("%E", unix_time_to_date_format(post_object["editdate"])) .replaceAll("%F", users.users[post_object["userID"]]['prettyname']) .replaceAll("%G", tag_name) .replaceAll("%I", users.users[post_object['userID']]['description']) .replaceAll("%L", `/post/${post_index}`) .replaceAll("%N", users.users[post_object["userID"]]['username']) .replaceAll("%P", "/post") .replaceAll("%O", "/edit") .replaceAll("%R", "/rss") .replaceAll("%S", config.seperator) .replaceAll("%T", post_object["title"]) .replaceAll("%U", `/user/${users.users[post_object["userID"]]['username']}`) .replaceAll("%Y", config.site_name) .replaceAll("%W", config.site_description) return output_string } app.get(config.rss_path, (req,res) => { if (config.rss == false) { res.send("Sorry, RSS is disabled!") } else { let rss_content = ` ${config.site_name} ${config.site_url} ${config.site_description} ` for (let i = posts.posts.length-1; i >= 0; i--) { rss_content += ` ${posts.posts[i]["title"]} ${config.site_url}/post/${i}.${config.file_extension} ")}]]> ${config.site_url}/post/${i} ${unix_time_to_rss_date(posts.posts[i]['pubdate'])}` for (let j = 0; j < posts.posts[i]['tags'].length; j++) { rss_content += `` }; rss_content += "" } rss_content += ` ` res.setHeader('content-type', 'application/rss+xml'); res.send(rss_content) }; }); app.get("/", (req,res) => { header_div = config.timeline_header header_div = replace_format_indicators(header_div); posts_div = ""; counter = posts.posts.length - 1; while ((counter >= 0) && (counter > (posts.posts.length - (config.timeline_length + 1)))) { let post = config.timeline_post_format; posts_div += replace_format_indicators(post, counter); counter -= 1; } res.send(`
${posts_div}
`); }); app.get("/post", (req,res) => { res.send(`





`); }); app.get("/edit", (req,res) => { res.send(`Edit page under construction`); }); app.get("/user/:username", (req, res) => { header_div = config.user_page_header header_div = replace_format_indicators(header_div) posts_div = ""; for (let post_index = posts.posts.length-1; post_index >= 0; post_index--) { if (users.users[posts.posts[post_index]["userID"]]["username"] == req.params.username) { let post = config.user_post_format; posts_div += replace_format_indicators(post, post_index); } } res.send(`
${posts_div}
`); }); app.get("/post/:post_index", (req, res) => { post_div = ""; let post = config.post_page_format; post_div += replace_format_indicators(post, req.params.post_index); res.send(`
${post_div}
`); }); app.get("/tag/:tag", (req,res) => { const tag = req.params.tag let header_div = config.tag_page_header header_div = replace_format_indicators(header_div,0,tag) let page_content = "" for (let i = posts.posts.length-1; i >= 0; i--) { if (posts.posts[i]['tags'].includes(tag)) { let post = config.tag_post_format; page_content += replace_format_indicators(post, i); }; }; res.send(`
${page_content}
`); }); app.post("/submit_post", (req,res) => { const password = crypto.createHash('sha512').update(req.body.password).digest('hex'); const username = req.body.username const title = req.body.title const content = req.body.content const tags = req.body.tags.split(','); const unix_timestamp = getUnixTime(new Date()) console.log(username, "is submitting a post titled:", title); if (get_userID(username) == -1) { res.send("User does not exist") } else if (users.users[get_userID(username)]['hash'] == password) { // Password matches posts.posts.push({ "userID": get_userID(username), "title": title, "content": content, "pubdate": unix_timestamp, "editdate": unix_timestamp, "tags": tags, }) fs.writeFileSync(`${__dirname}/posts.js`, `export const posts = ${JSON.stringify(posts.posts)}`, 'utf-8'); res.redirect(302, "/"); } else { res.send(`Invalid Password for user`,username); } }); app.listen(port, () => { console.log(`Server is running at http://localhost:${port} in ${config.root_path}`); });