mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-22 12:00:41 +03:00
Added state for users.
This commit is contained in:
parent
a471f19f04
commit
410859fbe3
9 changed files with 43 additions and 29 deletions
|
@ -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
|
||||
|
|
|
@ -16,5 +16,6 @@
|
|||
"discord_auth": "",
|
||||
"defaultThreadState": "OPEN",
|
||||
"email_auth": false,
|
||||
"default_user_state": "ACTIVE",
|
||||
"host": "https://akf-forum.glitch.me"
|
||||
}
|
5
index.js
5
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();
|
||||
}
|
||||
);
|
||||
|
|
1
lib.js
1
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({
|
||||
|
|
|
@ -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 }
|
||||
});
|
||||
|
|
|
@ -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;
|
|
@ -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!');
|
||||
|
||||
|
|
|
@ -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.");
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<% if (!member.discordID && discord && user?.id === member.id) { %>
|
||||
<a href="<%=discord%>" class="btn-outline-primary">Auth with discord</a>
|
||||
<% } else if(member.discordID && user?.id === member.id) { %>
|
||||
<a class="btn-outline-primary" id="un_discord">Unauth with discord!</a>
|
||||
<a class="btn-outline-primary" id="un_discord">Unauth with discord!</a>
|
||||
<% } %>
|
||||
<% if (user?.admin || user?.id === member.id) { %>
|
||||
<a href="/users/<%=member.id%>/avatar" class="btn-outline-primary">Upload avatar</a>
|
||||
|
@ -32,7 +32,7 @@
|
|||
<h1 class="title" style="text-align:center;">Edit <a class="see" href="/users/<%= member.id %>"><%= member.name %></a></h1>
|
||||
<div class="content">
|
||||
<form id="form" class="see" style="box-shadow:none">
|
||||
<input type="text" name="name" placeholder="<%=member.name%>" class="input" >
|
||||
<input type="text" name="name" placeholder="<%=member.name%>" class="input">
|
||||
|
||||
<textarea class="input" name="about" rows="4" cols="60" name="content" placeholder="<%=member.about%>"></textarea>
|
||||
<% 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 @@
|
|||
<a id="delete" class="btn-outline-primary">Delete user! </a>
|
||||
<% } %>
|
||||
<% if (user?.admin) {%>
|
||||
<details>
|
||||
<summary class="btn-outline-primary">IP adresses of user:</summary>
|
||||
<select>
|
||||
<% for(const ip of member.ips) { %>
|
||||
<option><%= ip %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary class="btn-outline-primary">IP adresses of user:</summary>
|
||||
<select>
|
||||
<% for(const ip of member.ips) { %>
|
||||
<option><%= ip %></option>
|
||||
<% } %>
|
||||
</select>
|
||||
</details>
|
||||
|
||||
<% } %>
|
||||
|
||||
<div class="box" style="justify-content:center;">
|
||||
|
|
Loading…
Reference in a new issue