mirror of
https://github.com/Akif9748/akf-forum.git
synced 2024-11-22 20:10:40 +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:
|
### EMAIL AUTH:
|
||||||
You can configure it. Just edit `config.json` and `.env` files.
|
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 credentials to `.env` as `EMAIL_USER` and `EMAIL_PASS`.
|
||||||
Add your email domain to `.env` as `EMAIL_SERVICE`.
|
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.
|
- user.state for ban, delete, etc.
|
||||||
- Add a feature list to README.md
|
- Add a feature list to README.md
|
||||||
- delete admin???
|
- delete admin???
|
||||||
- MODALS'S CSS & JS
|
|
||||||
- change category name
|
- change category name
|
||||||
- click to user message count to view message W/search
|
|
||||||
|
|
||||||
## Major Version History
|
## Major Version History
|
||||||
- V4: Caching
|
- V4: Caching
|
||||||
|
|
|
@ -16,5 +16,6 @@
|
||||||
"discord_auth": "",
|
"discord_auth": "",
|
||||||
"defaultThreadState": "OPEN",
|
"defaultThreadState": "OPEN",
|
||||||
"email_auth": false,
|
"email_auth": false,
|
||||||
|
"default_user_state": "ACTIVE",
|
||||||
"host": "https://akf-forum.glitch.me"
|
"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);
|
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) {
|
if (req.user?.deleted) {
|
||||||
req.session.destroy();
|
req.session.destroy();
|
||||||
return res.error(403, "Your account has been deleted.");
|
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();
|
next();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
1
lib.js
1
lib.js
|
@ -4,6 +4,7 @@ const config = require("./config.json");
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
module.exports = {
|
module.exports = {
|
||||||
threadEnum: ["OPEN", "APPROVAL", "DELETED"],
|
threadEnum: ["OPEN", "APPROVAL", "DELETED"],
|
||||||
|
userEnum: ["ACTIVE", "APPROVAL", "DELETED", "BANNED"],
|
||||||
themes: ["default", "black"],
|
themes: ["default", "black"],
|
||||||
RL(windowMs = 60_000, max = 1) {
|
RL(windowMs = 60_000, max = 1) {
|
||||||
return RL({
|
return RL({
|
||||||
|
|
|
@ -22,7 +22,7 @@ const schema = new mongoose.Schema({
|
||||||
|
|
||||||
time: { type: Date, default: Date.now },
|
time: { type: Date, default: Date.now },
|
||||||
edited: { type: Boolean, default: false },
|
edited: { type: Boolean, default: false },
|
||||||
state: { type: String, default: defaultThreadState, enum: threadEnum },
|
state: { type: String, default: defaultThreadState, enum: threadEnum, uppercase: true },
|
||||||
messages: [String],
|
messages: [String],
|
||||||
views: { type: Number, default: 0 }
|
views: { type: Number, default: 0 }
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
const mongoose = require("mongoose")
|
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({
|
const schema = new mongoose.Schema({
|
||||||
id: { type: String, unique: true },
|
id: { type: String, unique: true },
|
||||||
discordID: { type: String },
|
discordID: { type: String },
|
||||||
name: { type: String, maxlength: limits.names },
|
name: { type: String, maxlength: limits.names },
|
||||||
avatar: { type: String, default: "/images/avatars/default.jpg" },
|
avatar: { type: String, default: "/images/avatars/default.jpg" },
|
||||||
time: { type: Date, default: Date.now },
|
time: { type: Date, default: Date.now },
|
||||||
deleted: { type: Boolean, default: false },
|
|
||||||
edited: { type: Boolean, default: false },
|
edited: { type: Boolean, default: false },
|
||||||
about: { type: String, default: "", maxlength: limits.desp },
|
about: { type: String, default: "", maxlength: limits.desp },
|
||||||
admin: { type: Boolean, default: false },
|
admin: { type: Boolean, default: false },
|
||||||
|
@ -16,11 +17,20 @@ const schema = new mongoose.Schema({
|
||||||
ips: { type: [String], default: [], select: false },
|
ips: { type: [String], default: [], select: false },
|
||||||
password: { type: String, select: false },
|
password: { type: String, select: false },
|
||||||
discord_code: { 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: { type: String, select: false },
|
||||||
email_code: { 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 () {
|
schema.methods.takeId = async function () {
|
||||||
this.id = String(await model.count() || 0);
|
this.id = String(await model.count() || 0);
|
||||||
return this;
|
return this;
|
||||||
|
@ -32,6 +42,6 @@ schema.methods.getLink = function (id = this.id) {
|
||||||
|
|
||||||
const model = mongoose.model('user', schema);
|
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;
|
module.exports = model;
|
|
@ -20,7 +20,7 @@ app.use(async (req, res, next) => {
|
||||||
const user = await UserModel.findOne({ name });
|
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 || 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!');
|
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;
|
const { code } = req.query;
|
||||||
if (!code) return res.error(400, "No code provided");
|
if (!code) return res.error(400, "No code provided");
|
||||||
if (code !== req.user.email_code) return res.error(403, "Invalid code");
|
if (code !== req.user.email_code) return res.error(403, "Invalid code");
|
||||||
req.user.approved = true;
|
req.user.state = "ACTIVE";
|
||||||
await req.user.save();
|
await req.user.save();
|
||||||
res.send("Your email has been linked to your forum account.");
|
res.send("Your email has been linked to your forum account.");
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
<h1 class="title" style="text-align:center;">Edit <a class="see" href="/users/<%= member.id %>"><%= member.name %></a></h1>
|
<h1 class="title" style="text-align:center;">Edit <a class="see" href="/users/<%= member.id %>"><%= member.name %></a></h1>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<form id="form" class="see" style="box-shadow:none">
|
<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>
|
<textarea class="input" name="about" rows="4" cols="60" name="content" placeholder="<%=member.about%>"></textarea>
|
||||||
<% if (user?.admin){ %>
|
<% if (user?.admin){ %>
|
||||||
|
@ -56,20 +56,23 @@
|
||||||
document.addEventListener("click", async e => {
|
document.addEventListener("click", async e => {
|
||||||
if (e.target.id == "delete") {
|
if (e.target.id == "delete") {
|
||||||
const response = await request("/api/users/<%= member.id %>", "DELETE");
|
const response = await request("/api/users/<%= member.id %>", "DELETE");
|
||||||
if (!response.deleted) return
|
if (response.state !== "DELETED") return
|
||||||
alert("User is deleted!");
|
alert("User is deleted!");
|
||||||
location.reload()
|
location.reload()
|
||||||
} else if (e.target.id == "undelete") {
|
} else if (e.target.id == "undelete") {
|
||||||
const response = await request("/api/users/<%= member.id %>/", "PATCH", { deleted: false });
|
const response = await request("/api/users/<%= member.id %>/", "PATCH", {
|
||||||
if (response.deleted) return;
|
deleted: false
|
||||||
|
});
|
||||||
|
if (response.state == "DELETED") return;
|
||||||
alert("User is undeleted successfully!");
|
alert("User is undeleted successfully!");
|
||||||
location.reload()
|
location.reload()
|
||||||
} else if (e.target.id == "un_discord") {
|
} 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());
|
alert(await response.text());
|
||||||
location.reload()
|
location.reload()
|
||||||
}
|
} else if (e.target.id == "toogle")
|
||||||
else if (e.target.id == "toogle")
|
|
||||||
document.getElementById('user-edit').classList.toggle('no-active')
|
document.getElementById('user-edit').classList.toggle('no-active')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue