diff --git a/README.md b/README.md index c4044c2..2db25f6 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Create a redirect url in discord developer portal: ### EMAIL AUTH: You can configure it. Just edit `config.json` and `.env` files. -`"email_auth": true` in config.json. +`"email_auth": true, "default_user_state": "APPROVAL"` in config.json. Add your email credentials to `.env` as `EMAIL_USER` and `EMAIL_PASS`. Add your email domain to `.env` as `EMAIL_SERVICE`. @@ -60,9 +60,7 @@ Akf-forum has got an API for AJAX (fetch), other clients etc. And, you can learn - user.state for ban, delete, etc. - Add a feature list to README.md - delete admin??? -- MODALS'S CSS & JS - change category name -- click to user message count to view message W/search ## Major Version History - V4: Caching diff --git a/config.json.example b/config.json.example index 4199bf3..2bf0dc7 100644 --- a/config.json.example +++ b/config.json.example @@ -16,5 +16,6 @@ "discord_auth": "", "defaultThreadState": "OPEN", "email_auth": false, + "default_user_state": "ACTIVE", "host": "https://akf-forum.glitch.me" } \ No newline at end of file diff --git a/index.js b/index.js index fcd42be..54f139e 100644 --- a/index.js +++ b/index.js @@ -35,12 +35,13 @@ app.use(express.static("public"), express.json(), express.urlencoded({ extended: res.error = (type, error) => res.reply("error", { type, error }, type); - if (req.user && !req.user.approved&& !req.user.admin && !req.url.startsWith("/auth/email")) return res.error(403, "Your account is not approved yet."); - if (req.user?.deleted) { req.session.destroy(); return res.error(403, "Your account has been deleted."); } + + if (req.user && req.user.state == "APPROVAL" && !req.user.admin && !req.url.startsWith("/auth/email")) return res.error(403, "Your account is not approved yet."); + next(); } ); diff --git a/lib.js b/lib.js index de55d19..6c5d1c3 100644 --- a/lib.js +++ b/lib.js @@ -4,6 +4,7 @@ const config = require("./config.json"); require("dotenv").config(); module.exports = { threadEnum: ["OPEN", "APPROVAL", "DELETED"], + userEnum: ["ACTIVE", "APPROVAL", "DELETED", "BANNED"], themes: ["default", "black"], RL(windowMs = 60_000, max = 1) { return RL({ diff --git a/models/Thread.js b/models/Thread.js index 89eb0b1..16ffd3f 100644 --- a/models/Thread.js +++ b/models/Thread.js @@ -22,7 +22,7 @@ const schema = new mongoose.Schema({ time: { type: Date, default: Date.now }, edited: { type: Boolean, default: false }, - state: { type: String, default: defaultThreadState, enum: threadEnum }, + state: { type: String, default: defaultThreadState, enum: threadEnum, uppercase: true }, messages: [String], views: { type: Number, default: 0 } }); diff --git a/models/User.js b/models/User.js index 25cc825..b429320 100644 --- a/models/User.js +++ b/models/User.js @@ -1,12 +1,13 @@ const mongoose = require("mongoose") -const { def_theme, limits, email_auth } = require("../config.json"); +const { def_theme, limits, email_auth, default_user_state } = require("../config.json"); +const { userEnum } = require("../lib"); + const schema = new mongoose.Schema({ id: { type: String, unique: true }, discordID: { type: String }, name: { type: String, maxlength: limits.names }, avatar: { type: String, default: "/images/avatars/default.jpg" }, time: { type: Date, default: Date.now }, - deleted: { type: Boolean, default: false }, edited: { type: Boolean, default: false }, about: { type: String, default: "", maxlength: limits.desp }, admin: { type: Boolean, default: false }, @@ -16,11 +17,20 @@ const schema = new mongoose.Schema({ ips: { type: [String], default: [], select: false }, password: { type: String, select: false }, discord_code: { type: String, select: false }, - approved: { type: Boolean, default: !email_auth }, + state: { type: String, default: default_user_state, enum: userEnum, uppercase: true }, email: { type: String, select: false }, email_code: { type: String, select: false }, }); +schema.virtual("deleted").get(function () { + return this.state === "DELETED"; +}).set(function (value) { + this.set({ state: value ? "DELETED" : "ACTIVE" }); +}); +schema.virtual("active").get(function () { + return this.state === "ACTIVE"; +}) + schema.methods.takeId = async function () { this.id = String(await model.count() || 0); return this; @@ -32,6 +42,6 @@ schema.methods.getLink = function (id = this.id) { const model = mongoose.model('user', schema); -model.get = (id, select) => model.findOne({ id }).select(select); +model.get = (id, select = "") => model.findOne({ id }, select); module.exports = model; \ No newline at end of file diff --git a/routes/api/index.js b/routes/api/index.js index 06ccb18..971a642 100644 --- a/routes/api/index.js +++ b/routes/api/index.js @@ -20,7 +20,7 @@ app.use(async (req, res, next) => { const user = await UserModel.findOne({ name }); if (!user || user.deleted) return res.error(401, `We don't have any user with name ${name}.`) - if (!user.approved) return res.error(401, "Your account is not approved yet."); + if (!user.active) return res.error(401, "Your account is not approved yet."); if (!await bcrypt.compare(password, user.password)) return res.error(401, 'Incorrect Password!'); diff --git a/routes/auth.js b/routes/auth.js index 094bdcb..37393a4 100644 --- a/routes/auth.js +++ b/routes/auth.js @@ -90,7 +90,7 @@ app.get("/email", async (req, res) => { const { code } = req.query; if (!code) return res.error(400, "No code provided"); if (code !== req.user.email_code) return res.error(403, "Invalid code"); - req.user.approved = true; + req.user.state = "ACTIVE"; await req.user.save(); res.send("Your email has been linked to your forum account."); }); diff --git a/views/user.ejs b/views/user.ejs index ff4caab..d11ccfd 100644 --- a/views/user.ejs +++ b/views/user.ejs @@ -16,7 +16,7 @@ <% if (!member.discordID && discord && user?.id === member.id) { %> Auth with discord <% } else if(member.discordID && user?.id === member.id) { %> - Unauth with discord! + Unauth with discord! <% } %> <% if (user?.admin || user?.id === member.id) { %> Upload avatar @@ -32,7 +32,7 @@

Edit <%= member.name %>

- + <% if (user?.admin){ %> @@ -56,20 +56,23 @@ document.addEventListener("click", async e => { if (e.target.id == "delete") { const response = await request("/api/users/<%= member.id %>", "DELETE"); - if (!response.deleted) return + if (response.state !== "DELETED") return alert("User is deleted!"); location.reload() } else if (e.target.id == "undelete") { - const response = await request("/api/users/<%= member.id %>/", "PATCH", { deleted: false }); - if (response.deleted) return; + const response = await request("/api/users/<%= member.id %>/", "PATCH", { + deleted: false + }); + if (response.state == "DELETED") return; alert("User is undeleted successfully!"); location.reload() } else if (e.target.id == "un_discord") { - const response = await fetch("/auth/discord/", {method:"DELETE"}); + const response = await fetch("/auth/discord/", { + method: "DELETE" + }); alert(await response.text()); location.reload() - } - else if (e.target.id == "toogle") + } else if (e.target.id == "toogle") document.getElementById('user-edit').classList.toggle('no-active') }); @@ -94,15 +97,15 @@ Delete user! <% } %> <% if (user?.admin) {%> -
- IP adresses of user: - -
- +
+ IP adresses of user: + +
+ <% } %>