From 5c1d5d9c2a74502e40f67ef47337a97349be0d0d Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Tue, 2 Aug 2022 12:20:00 +0200 Subject: Moderation tools for admin user. Ban and unban users. Delete forum posts and threads. --- schema.sql | 2 +- server.js | 43 ++++++++++++++++++++++++++++++++++++++++++- views/forum_thread.pug | 5 ++++- views/head.pug | 3 +++ views/user.pug | 6 ++++++ 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/schema.sql b/schema.sql index f3d5d02..ca86e67 100644 --- a/schema.sql +++ b/schema.sql @@ -91,7 +91,7 @@ create view user_login_view as drop view if exists user_profile_view; create view user_profile_view as select - user_id, name, mail, notify, ctime, atime, about + user_id, name, mail, notify, ctime, atime, about, is_banned from users natural left join user_last_seen diff --git a/server.js b/server.js index 4145b43..d95b33c 100644 --- a/server.js +++ b/server.js @@ -265,7 +265,8 @@ const SQL_SELECT_USER_INFO = SQL(` status = 1 and players.user_id = users.user_id and active in ( players.role, 'Both', 'All' ) - ) as active + ) as active, + is_banned from users where user_id = ? @@ -280,6 +281,7 @@ const SQL_UPDATE_USER_MAIL = SQL("UPDATE users SET mail=? WHERE user_id=?") const SQL_UPDATE_USER_ABOUT = SQL("UPDATE users SET about=? WHERE user_id=?") const SQL_UPDATE_USER_PASSWORD = SQL("UPDATE users SET password=?, salt=? WHERE user_id=?") const SQL_UPDATE_USER_LAST_SEEN = SQL("INSERT OR REPLACE INTO user_last_seen (user_id,atime) VALUES (?,datetime('now'))") +const SQL_UPDATE_USER_IS_BANNED = SQL("update users set is_banned=? where name=?") const SQL_FIND_TOKEN = SQL("SELECT token FROM tokens WHERE user_id=? AND datetime('now') < datetime(time, '+5 minutes')").pluck() const SQL_CREATE_TOKEN = SQL("INSERT OR REPLACE INTO tokens (user_id,token,time) VALUES (?, lower(hex(randomblob(16))), datetime('now')) RETURNING token").pluck() @@ -336,6 +338,8 @@ app.use(function (req, res, next) { login_touch(res, sid) req.user = SQL_SELECT_USER_INFO.get(user_id) SQL_UPDATE_USER_LAST_SEEN.run(user_id) + if (req.user.is_banned) + return res.status(403).send("") } } @@ -355,6 +359,12 @@ function must_be_logged_in(req, res, next) { return next() } +function must_be_administrator(req, res, next) { + if (!req.user || req.user.user_id !== 1) + return res.status(401).send("Not authorized") + return next() +} + app.get('/', function (req, res) { res.render('index.pug', { user: req.user, titles: TITLES }) }) @@ -513,6 +523,18 @@ app.post('/change-password', must_be_logged_in, function (req, res) { return res.redirect('/profile') }) +app.get('/admin/ban-user/:who', must_be_administrator, function (req, res) { + let who = req.params.who + SQL_UPDATE_USER_IS_BANNED.run(1, who) + return res.redirect('/user/' + who) +}) + +app.get('/admin/unban-user/:who', must_be_administrator, function (req, res) { + let who = req.params.who + SQL_UPDATE_USER_IS_BANNED.run(0, who) + return res.redirect('/user/' + who) +}) + /* * USER PROFILE */ @@ -747,6 +769,10 @@ const FORUM_NEW_THREAD = SQL("INSERT INTO threads (author_id,subject) VALUES (?, const FORUM_NEW_POST = SQL("INSERT INTO posts (thread_id,author_id,body) VALUES (?,?,?)") const FORUM_EDIT_POST = SQL("UPDATE posts SET body=?, mtime=datetime('now') WHERE post_id=? AND author_id=? RETURNING thread_id").pluck() +const FORUM_DELETE_THREAD_POSTS = SQL("delete from posts where thread_id=?") +const FORUM_DELETE_THREAD = SQL("delete from threads where thread_id=?") +const FORUM_DELETE_POST = SQL("delete from posts where post_id=?") + function show_forum_page(req, res, page) { let thread_count = FORUM_COUNT_THREADS.get() let page_count = Math.ceil(thread_count / FORUM_PAGE_SIZE) @@ -800,6 +826,21 @@ app.get('/forum/thread/:thread_id', function (req, res) { }) }) +app.get('/admin/delete-thread/:thread_id', must_be_administrator, function (req, res) { + let thread_id = req.params.thread_id + res.send(JSON.stringify({ + posts: FORUM_DELETE_THREAD_POSTS.run(thread_id), + thread: FORUM_DELETE_THREAD.run(thread_id), + })) +}) + +app.get('/admin/delete-post/:post_id', must_be_administrator, function (req, res) { + let post_id = req.params.post_id + res.send(JSON.stringify( + FORUM_DELETE_POST.run(post_id) + )) +}) + app.get('/forum/post', must_be_logged_in, function (req, res) { res.render('forum_post.pug', { user: req.user, diff --git a/views/forum_thread.pug b/views/forum_thread.pug index 3ed117e..be3f0f4 100644 --- a/views/forum_thread.pug +++ b/views/forum_thread.pug @@ -13,4 +13,7 @@ html +forumpost(row,1) if user - p: a(href="/forum/reply/"+posts[0].post_id) Reply + if posts.length > 0 + p: a(href="/forum/reply/"+posts[0].post_id) Reply + if user.user_id === 1 + p: a(href="/admin/delete-thread/"+thread.thread_id) DELETE THREAD diff --git a/views/head.pug b/views/head.pug index 08f2660..4df5759 100644 --- a/views/head.pug +++ b/views/head.pug @@ -29,6 +29,9 @@ mixin forumpost(row,show_buttons) .body!= row.body if show_buttons && user .edit + if user.user_id === 1 + | #[a(href="/admin/delete-post/"+row.post_id) DELETE] + | if row.author_id === user.user_id | #[a(href="/forum/edit/"+row.post_id) Edit] | diff --git a/views/user.pug b/views/user.pug index fb98da7..c28fbd0 100644 --- a/views/user.pug +++ b/views/user.pug @@ -38,3 +38,9 @@ html +gamelist(finished_games) p All #{who.name}'s finished games + + if user && user.user_id === 1 + if who.is_banned + p UNBAN USER + else + p BAN USER -- cgit v1.2.3