rollback to v4.x, and mini fixes

This commit is contained in:
Akif9748 2023-05-08 17:16:12 +03:00
parent da214db047
commit 03d84a2564
31 changed files with 41 additions and 65 deletions

View file

@ -1,25 +1,27 @@
{ {
// exclude public folder from linting "ignorePatterns": [
"ignorePatterns": ["public/"], "test.js"
],
"env": { "env": {
"node": true, "node": true,
"commonjs": true, "commonjs": true,
"es2021": true "es2021": true
}, },
"extends": "eslint:recommended", "extends": "eslint:recommended",
"overrides": [
],
"parserOptions": { "parserOptions": {
"ecmaVersion": "latest" "ecmaVersion": "latest"
}, },
"rules": { "rules": {
"no-use-before-define": "error"
"linebreak-style": [ },
"error", "overrides": [
"windows" {
] "env": {
"browser": true
} },
} "files": [
"public/js/*"
]
}
]
}

View file

@ -54,8 +54,15 @@ Akf-forum has got an API for AJAX (fetch), other clients etc. And, you can learn
- Add a feature list to README.md - Add a feature list to README.md
- delete admin??? - delete admin???
- change category name - change category name
- enchanted theme: not take all of the public! `"/css`, patch user support!
- _id - _id
- ADD gavatar support
- routes/api/routes/users.js check,
themes/default/extra/footer.ejs check,
themes/default/extra/meta.ejs check
- "defaultThreadState" ??? better case
### front-end ### front-end
- better usermenu for user profile - better usermenu for user profile
- old contents / titles add to forum interface - old contents / titles add to forum interface
@ -65,7 +72,6 @@ Akf-forum has got an API for AJAX (fetch), other clients etc. And, you can learn
- give admin button, not is admin - give admin button, not is admin
## Major Version History ## Major Version History
- V5: Enchanted theme support
- V4: Caching - V4: Caching
- V3: New Theme - V3: New Theme
- V2: Backend fix, mongoose is fixed. Really big fix. - V2: Backend fix, mongoose is fixed. Really big fix.

View file

@ -1,7 +1,6 @@
{ {
"def_theme": { "def_theme": {
"name": "white", "name": "white",
"color": "black",
"language": "en" "language": "en"
}, },
"forum_name": "akf", "forum_name": "akf",

View file

@ -22,8 +22,8 @@ app.ips = [];
app.set("view engine", "ejs"); app.set("view engine", "ejs");
app.set("limits", limits); app.set("limits", limits);
app.use(express.static("public", { maxAge: 86400 * 1000 }), express.json(), express.urlencoded({ extended: true }), IP(), app.use(express.static("public"), express.json(), express.urlencoded({ extended: true }), IP(),
SES({ secret: process.env.SECRET, store: MS.create({ clientPromise: DB, stringify: false }), resave: true, saveUninitialized: true }), SES({ secret: process.env.SECRET, store: MS.create({ clientPromise: DB, stringify: false }), resave: false, saveUninitialized: false }),
async (req, res, next) => { async (req, res, next) => {
if (app.ips.includes(req.clientIp)) return res.status(403).send("You are banned from this forum."); if (app.ips.includes(req.clientIp)) return res.status(403).send("You are banned from this forum.");
@ -31,14 +31,14 @@ app.use(express.static("public", { maxAge: 86400 * 1000 }), express.json(), expr
lastSeen: Date.now(), $addToSet: { ips: req.clientIp } lastSeen: Date.now(), $addToSet: { ips: req.clientIp }
}) : null; }) : null;
const theme = require(`./themes/${req.user?.theme?.name || def_theme.name}`);
res.reply = (page, data = {}, status = 200) => res.reply = (page, options = {}, status = 200) => res.status(status).render(page, {
theme.render(page, { user: req.user, ...data }, { user: req.user,
color: req.user?.theme?.color || def_theme.color, theme: req.user?.theme || def_theme,
lang: req.user?.theme?.language || def_theme.language, lang: req.user?.theme?.language || def_theme.language,
forum_name, forum_name, description, ...options
description });
}, res.status(status));
res.error = (type, error) => res.reply("error", { type, error }, type); res.error = (type, error) => res.reply("error", { type, error }, type);
@ -61,6 +61,6 @@ if (RLS.enabled) app.use(RL(RLS.windowMs, RLS.max));
for (const file of fs.readdirSync("./routes")) for (const file of fs.readdirSync("./routes"))
app.use("/" + file.replace(".js", ""), require(`./routes/${file}`)); app.use("/" + file.replace(".js", ""), require(`./routes/${file}`));
app.all("*", (req, res) => res.error(404, "We have not got this page.")); app.all("*", (req, res) => res.error(404, "This page does not exist on this forum."));
app.listen(port, () => console.log(`${forum_name}-forum on port:`, port)); app.listen(port, () => console.log(`${forum_name}-forum on port:`, port));

1
lib.js
View file

@ -11,6 +11,7 @@ module.exports = {
handler: (req, res, next, opts) => !req.user?.admin ? res.error(opts.statusCode, "You are begin ratelimited") : next() handler: (req, res, next, opts) => !req.user?.admin ? res.error(opts.statusCode, "You are begin ratelimited") : next()
}) })
}, },
// eslint-disable-next-line no-useless-escape
emailRegEx: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/, emailRegEx: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,

View file

@ -13,7 +13,6 @@ const schema = new mongoose.Schema({
admin: { type: Boolean, default: false }, admin: { type: Boolean, default: false },
theme: { theme: {
name: { type: String, default: def_theme.name }, name: { type: String, default: def_theme.name },
color: { type: String, default: def_theme.color },
language: { type: String, default: def_theme.language } language: { type: String, default: def_theme.language }
}, },
lastSeen: { type: Date, default: Date.now, select: false }, lastSeen: { type: Date, default: Date.now, select: false },

View file

@ -37,7 +37,7 @@ app.patch("/:id", async (req, res) => {
if (req.user.id !== member.id && !user.admin) return res.error(403, "You have not got permission for this."); if (req.user.id !== member.id && !user.admin) return res.error(403, "You have not got permission for this.");
if (!Object.keys(req.body).some(Boolean)) return res.error(400, "Missing member informations in request body."); if (!Object.keys(req.body).some(Boolean)) return res.error(400, "Missing member informations in request body.");
const { name, about, theme, admin, deleted, hideLastSeen } = req.body; const { name, about, admin, deleted, hideLastSeen } = req.body;
if ((admin?.length || "deleted" in req.body) && !req.user.admin) return res.error(403, "You have not got permission for edit 'admin' and 'deleted' information, or bad request."); if ((admin?.length || "deleted" in req.body) && !req.user.admin) return res.error(403, "You have not got permission for edit 'admin' and 'deleted' information, or bad request.");
const { names, desp } = req.app.get("limits"); const { names, desp } = req.app.get("limits");

View file

@ -14,8 +14,8 @@ app.post("/", RL(24 * 60 * 60_000, 5), async (req, res) => {
if (!name || !password) return res.error(400, "You forgot entering some values"); if (!name || !password) return res.error(400, "You forgot entering some values");
const { names } = req.app.get("limits"); const { names } = req.app.get("limits");
if (name.length < 3 || names > 25) return res.error(400, "Name must be between 3 - 25 characters"); if (name.length < 3 || name.length > names) return res.error(400, "Name must be between 3 - 25 characters");
if (password.length < 3 || names > 25) return res.error(400, "Password must be between 3 - 25 characters"); if (password.length < 3 || password.length > names) return res.error(400, "Password must be between 3 - 25 characters");
if (await UserModel.exists({ name })) return res.error(400, `We have got an user named ${name}!`) if (await UserModel.exists({ name })) return res.error(400, `We have got an user named ${name}!`)
const user = new UserModel({ name }); const user = new UserModel({ name });
@ -43,7 +43,7 @@ app.post("/", RL(24 * 60 * 60_000, 5), async (req, res) => {
<h1>Verify your email in ${forum_name}-forum</h1> <h1>Verify your email in ${forum_name}-forum</h1>
<a href="${host}/auth/email?code=${user.email_code}">Click here to verify your email</a> <a href="${host}/auth/email?code=${user.email_code}">Click here to verify your email</a>
` `
}, (err, info) => { }, (err) => {
if (err) return res.error(500, "Failed to send email"); if (err) return res.error(500, "Failed to send email");
}); });

View file

@ -1,22 +0,0 @@
const path = require('path');
module.exports = {
name: "default",
colors: ["black", "white"],
languages: ["en"],
getFilePath(page) {
return path.resolve(__dirname, page) ;// path of the file for ejs rendering
},
/**
* Renderer function for theme
* @param {String} file a page of forum
* @param {{ user: Object }} data informations about page
* @param {{ color: String, forum_name:String, description:String }} options Extra options
* @param {Object} render request object
*/
render(file, data, options, req) {
// const { color, language, forum_name, description } = options; // General informations, meta, forum name, user language and color
// const { user } = data; // specific informations about page, user (req.user || null), and more
return req.render(this.getFilePath(file), { ...options, ...data });
}
}

View file

@ -1,6 +0,0 @@
const fs = require("fs");
for (const theme of fs.readdirSync("./themes")) {
if (theme === "index.js") continue;
module.exports[theme] = require(`./${theme}`);
}

View file

@ -4,9 +4,6 @@
<title><%= title || forum_name +"-forum" %></title> <title><%= title || forum_name +"-forum" %></title>
<meta name="description" content="<%= description %>"> <meta name="description" content="<%= description %>">
<link rel="icon" type="image/x-icon" href="/favicon.ico"> <link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="stylesheet" href="/css/themes/<%= color %>.css" /> <link rel="stylesheet" href="/css/themes/<%= theme.name %>.css" />
<link rel="stylesheet" href="/css/common.css" /> <link rel="stylesheet" href="/css/common.css" />
<% if (color === "black") { %>
<meta name="theme-color" content="#000000" />
<% } %>
</head> </head>