Browse Source

✨ feat: 增加用户封禁功能

Pchen0 1 month ago
parent
commit
49d4473eae

+ 1 - 0
apis/User/Admin/GetUserList.js

@@ -60,6 +60,7 @@ class GetUserList extends API {
                 avatar,
                 lepao_count,
                 COALESCE(send_count_auto_approve, 0) AS send_count_auto_approve,
+                COALESCE(is_banned, 0) AS is_banned,
                 (
                     SELECT lh.type
                     FROM login_history lh

+ 71 - 0
apis/User/Admin/SetUserBan.js

@@ -0,0 +1,71 @@
+const API = require("../../../lib/API")
+const db = require("../../../plugin/DataBase/db")
+const AccessControl = require("../../../lib/AccessControl")
+const { BaseStdResponse } = require("../../../BaseStdResponse")
+
+class SetUserBan extends API {
+    constructor() {
+        super()
+        this.setPath("/Admin/User/SetUserBan")
+        this.setMethod("POST")
+    }
+
+    async onRequest(req, res) {
+        let { uuid, session, userid, is_banned } = req.body
+        const flag = Number(is_banned)
+
+        if ([uuid, session, userid].some(value => value === "" || value === null || value === undefined))
+            return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
+
+        if (![0, 1].includes(flag))
+            return res.json({ ...BaseStdResponse.ERR, msg: "参数错误" })
+
+        if (!await AccessControl.checkSession(uuid, session))
+            return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED })
+
+        const permission = await AccessControl.getPermission(uuid)
+        if (!permission.includes("admin") && !permission.includes("service"))
+            return res.json({ ...BaseStdResponse.PERMISSION_DENIED })
+
+        if (userid === uuid)
+            return res.json({ ...BaseStdResponse.ERR, msg: "不能封禁自己的账号" })
+
+        const targetRows = await db.query(
+            "SELECT permission FROM users WHERE uuid = ? LIMIT 1",
+            [userid]
+        )
+        if (!targetRows || targetRows.length === 0)
+            return res.json({ ...BaseStdResponse.MISSING_FILE, msg: "未找到用户" })
+
+        const targetPermission = targetRows[0].permission || []
+        if (targetPermission.includes("admin") || targetPermission.includes("service"))
+            return res.json({ ...BaseStdResponse.ERR, msg: "不能封禁管理员或客服账号" })
+
+        const conn = await db.connect()
+        try {
+            const [r] = await conn.execute(
+                "UPDATE users SET is_banned = ? WHERE uuid = ?",
+                [flag, userid]
+            )
+            if (!r || r.affectedRows !== 1)
+                return res.json({ ...BaseStdResponse.MISSING_FILE, msg: "未找到用户或更新失败" })
+
+            if (flag === 1)
+                await AccessControl.invalidateSession(userid)
+
+            return res.json({
+                ...BaseStdResponse.OK,
+                msg: flag === 1 ? "已封禁该用户" : "已解除封禁"
+            })
+        } catch (err) {
+            this.logger.error(`设置用户封禁状态失败: ${err.message || err}`)
+            return res.json({ ...BaseStdResponse.ERR, msg: "操作失败,请稍后再试" })
+        } finally {
+            if (conn?.connection && typeof conn.connection.release === "function" && typeof conn?.release === "function") {
+                conn.release()
+            }
+        }
+    }
+}
+
+module.exports.SetUserBan = SetUserBan

+ 6 - 0
apis/User/Login.js

@@ -51,6 +51,12 @@ class Login extends API {
                 msg: '用户名或密码错误'
             })
 
+        if (Number(rows[0].is_banned) === 1)
+            return res.json({
+                ...BaseStdResponse.ERR,
+                msg: '账号已被封禁,如有疑问请邮件联系:service@xxoo365.top'
+            })
+
         const session = uuidv4()
         await Redis.set(`userSession:${rows[0].uuid}`, session, {
             EX: 2592000

+ 6 - 0
apis/User/qqLogin/qqLoginStep2.js

@@ -69,6 +69,12 @@ class qqLoginStep2 extends API {
         }
 
         else {
+            if (Number(selectRows[0].is_banned) === 1)
+                return res.json({
+                    ...BaseStdResponse.ERR,
+                    msg: '账号已被封禁,如有疑问请邮件联系:service@xxoo365.top'
+                })
+
             let updateSql = 'UPDATE users SET session = ?, lastTime = ? WHERE email = ?'
             let updateRows = await db.query(updateSql, [session, time, email])
             if (!updateRows || updateRows.affectedRows !== 1) {

+ 6 - 0
apis/User/uniLogin/Login.js

@@ -81,6 +81,12 @@ class Login extends API {
 
             const user = selectRows[0]
 
+            if (Number(user.is_banned) === 1)
+                return res.json({
+                    ...BaseStdResponse.ERR,
+                    msg: '账号已被封禁,如有疑问请邮件联系:service@xxoo365.top'
+                })
+
             await Redis.set(`userSession:${uuid}`, session, {
                 EX: 2592000
             })

+ 10 - 0
lib/AccessControl.js

@@ -6,6 +6,16 @@ class AccessControl {
         return (await Redis.get(`userSession:${uuid}`)) === session
     }
 
+    async isBanned(uuid) {
+        const sql = 'SELECT COALESCE(is_banned, 0) AS is_banned FROM users WHERE uuid = ?'
+        const rows = await db.query(sql, [uuid])
+        return Number(rows[0]?.is_banned) === 1
+    }
+
+    async invalidateSession(uuid) {
+        await Redis.del(`userSession:${uuid}`)
+    }
+
     async getPermission(uuid) {
         const sql = 'SELECT permission FROM users WHERE uuid = ?'
         const rows = await db.query(sql, [uuid])