profile photo fix

This commit is contained in:
Akif9748 2022-08-27 10:31:16 +03:00
parent 87cf4f3274
commit 6eeca272af
15 changed files with 55 additions and 56 deletions

5
.gitignore vendored
View File

@ -4,6 +4,5 @@ node_modules/
# env # env
.env .env
# Test files: # Test files
a.js test.js
db.js

View File

@ -10,6 +10,7 @@ A Node.js based forum software.
### Extra ### Extra
Run `node util/reset` to **reset the database**, and run `node util/admin` for give admin perms to first member. Run `node util/reset` to **reset the database**, and run `node util/admin` for give admin perms to first member.
Edit `config.json` for default themes of users...
## API ## API
Akf-forum has got an API for AJAX, other clients etc. And, you can learn about API in `util/APIDOCS.md`. Akf-forum has got an API for AJAX, other clients etc. And, you can learn about API in `util/APIDOCS.md`.
@ -43,6 +44,7 @@ Akf-forum has got an API for AJAX, other clients etc. And, you can learn about A
| Message count | 🟢 | MEDIUM | | Message count | 🟢 | MEDIUM |
| Delete user | 🟢 | HIGH | | Delete user | 🟢 | HIGH |
| Undelete | 🟢 | MEDIUM | | Undelete | 🟢 | MEDIUM |
| PM | 🔴 | MEDIUM |
| About me | 🔴 | LOW | | About me | 🔴 | LOW |
| Edit user | 🔴 | HIGH | | Edit user | 🔴 | HIGH |
| IP ban | 🔴 | MEDIUM | | IP ban | 🔴 | MEDIUM |
@ -81,13 +83,13 @@ Akf-forum has got an API for AJAX, other clients etc. And, you can learn about A
### Other ### Other
| To do | Is done? | Priority | | To do | Is done? | Priority |
| ----- | -------- | -------- | | ----- | -------- | -------- |
| Footer | 🔴 | LOW | | from form to AJAX | 🟢 | HIGH |
| auto-scroll | 🟢 | LOW | | auto-scroll | 🟢 | LOW |
| Multi-theme support, black theme | 🟡 | LOW | | Multi-theme support, black theme | 🟡 | LOW |
| Search | 🔴 | MEDIUM | | Search | 🔴 | MEDIUM |
| Page support, support message limit correct | 🔴 | MEDIUM | | Page support, support message limit correct | 🔴 | MEDIUM |
| from form to AJAX | 🟢 | HIGH | | Locales | 🔴 | MEDIUM |
| Footer | 🔴 | LOW |
## Major Version History ## Major Version History
- V3: New Theme - V3: New Theme
- V2: Backend fix, mongoose is fixed. Really big fix. - V2: Backend fix, mongoose is fixed. Really big fix.

3
config.json Normal file
View File

@ -0,0 +1,3 @@
{
"def_theme": "default"
}

View File

@ -1,5 +1,6 @@
const { UserModel } = require("./models"), const { def_theme } = require("./config.json"),
session = require('express-session'), session = require('express-session'),
{ UserModel } = require("./models"),
bodyParser = require('body-parser'), bodyParser = require('body-parser'),
port = process.env.PORT || 3000, port = process.env.PORT || 3000,
mongoose = require("mongoose"), mongoose = require("mongoose"),
@ -17,7 +18,11 @@ app.set("view engine", "ejs");
app.use(express.json()); app.use(express.json());
app.use(async (req, res, next) => { app.use(async (req, res, next) => {
req.user = await UserModel.get(req.session.userid); req.user = await UserModel.get(req.session.userid);
res.error = (type, error) => res.status(type).render("error", {user: req.user, type, error }); res.reply = (page, options = {}, status = 200) => res.status(status)
.render(page, { user: req.user, theme: req.user?.theme || def_theme, ...options });
res.error = (type, error) => res.reply("error", { type, error }, type);
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.");

View File

@ -1,5 +1,5 @@
const mongoose = require("mongoose") const mongoose = require("mongoose")
const { def_theme } = require("../config.json");
const schema = new mongoose.Schema({ const schema = new mongoose.Schema({
id: { type: String }, id: { type: String },
@ -7,7 +7,8 @@ const schema = new mongoose.Schema({
avatar: { type: String, default: "/images/guest.png" }, avatar: { type: String, default: "/images/guest.png" },
time: { type: Date, default: Date.now }, time: { type: Date, default: Date.now },
deleted: { type: Boolean, default: false }, deleted: { type: Boolean, default: false },
admin: { type: Boolean, default: false } admin: { type: Boolean, default: false },
theme: { type: String, default: def_theme }
}); });

View File

@ -12,7 +12,7 @@ app.get("/", async (req, res) => {
messages = await MessageModel.count({deleted:false}), messages = await MessageModel.count({deleted:false}),
user = req.user; user = req.user;
res.render("index", { mem, user, users, threads, messages }) res.reply("index", { mem, users, threads, messages })
}) })

View File

@ -9,7 +9,7 @@ app.get("/", async (req, res) => {
if (!user?.admin) return res.error( 403, "You have not got permissions for view to this page."); if (!user?.admin) return res.error( 403, "You have not got permissions for view to this page.");
res.render("admin", { user, user2: false }) res.reply("admin", { user2: false })
}); });

View File

@ -3,7 +3,7 @@ const { Router } = require("express");
const app = Router(); const app = Router();
const bcrypt = require("bcrypt"); const bcrypt = require("bcrypt");
app.get("/", (req, res) => res.render("login",{redirect: req.query.redirect,user:null})); app.get("/", (req, res) => res.reply("login",{redirect: req.query.redirect,user:null}));
app.post("/", async (req, res) => { app.post("/", async (req, res) => {
req.session.userid = null; req.session.userid = null;

View File

@ -5,42 +5,35 @@ const rateLimit = require('express-rate-limit')
const app = Router(); const app = Router();
app.get("/", (req, res) => res.render("register",{user:null})); app.get("/", (req, res) => res.reply("register", { user: null }));
app.post("/", rateLimit({ app.post("/", rateLimit({
windowMs: 24*60*60_000, max: 1, standardHeaders: true, legacyHeaders: false, windowMs: 24 * 60 * 60_000, max: 1, standardHeaders: true, legacyHeaders: false,
handler: (request, response, next, options) => handler: (_r, response, _n, options) => response.error(options.statusCode, "You are begin ratelimited")
response.error(options.statusCode, "You are begin ratelimited")
}), async (req, res) => { }), async (req, res) => {
req.session.userid = null; req.session.userid = null;
let { username = null, password = null, avatar } = req.body; let { username = null, password: body_pass = null, avatar } = req.body;
if (username && password) { if (!username || !body_pass) return res.error(res, 400, "You forgot entering some values");
const user = await SecretModel.findOne({ username }); const user = await SecretModel.findOne({ username });
if (user) if (user) return res.error(res, 400, `We have got an user named ${username}!`)
res.error(res, 400, `We have got an user named ${username}!`)
else {
const user2 = new UserModel({ name: req.body.username, avatar }) const user2 = new UserModel({ name: req.body.username })
await user2.takeId() if (avatar) user2.avatar = avatar;
await user2.save(); await user2.takeId()
await user2.save();
const salt = await bcrypt.genSalt(10); const salt = await bcrypt.genSalt(10);
password = await bcrypt.hash(password, salt); const password = await bcrypt.hash(body_pass, salt);
await SecretModel.create({ username, password, id: user2.id }) await SecretModel.create({ username, password, id: user2.id })
req.session.userid = user2.id; req.session.userid = user2.id;
res.redirect('/'); res.redirect('/');
}
} else
res.error(res, 400, "You forgot entering some values")
}) })

View File

@ -6,19 +6,14 @@ const { ThreadModel, MessageModel } = require("../models")
app.get("/", async (req, res) => { app.get("/", async (req, res) => {
const user = req.user; const threads = await ThreadModel.find(req.user?.admin ? {} : { deleted: false }).limit(10);
const threads = await ThreadModel.find(user?.admin ? {} : { deleted: false }).limit(10); return res.reply("threads", { threads });
return res.render("threads", { threads, user });
}); });
app.get("/create*", async (req, res) => { app.get("/create*", async (req, res) => {
res.reply("create_thread")
const user = req.user
res.render("create_thread", { user })
}); });
app.get("/:id", async (req, res) => { app.get("/:id", async (req, res) => {
@ -31,13 +26,13 @@ app.get("/:id", async (req, res) => {
if (thread && (user?.admin || !thread.deleted)) { if (thread && (user?.admin || !thread.deleted)) {
const messages = await Promise.all(thread.messages.map(async id => { const messages = await Promise.all(thread.messages.map(async id => {
const message = await MessageModel.get(id) const message = await MessageModel.get(id)
return user?.admin || !message?.deleted ? message.toObject({ virtuals: true }) : null; return user?.admin || !message?.deleted ? message.toObject({ virtuals: true }) : null;
})); }));
res.render("thread", { thread, messages, user,scroll:req.query.scroll || false }); res.reply("thread", { thread, messages, scroll: req.query.scroll || false });
} else } else
res.error( 404, "We have not got this thread."); res.error(404, "We have not got this thread.");
}); });

View File

@ -5,7 +5,7 @@ const { UserModel, MessageModel, ThreadModel } = require("../models");
app.get("/", async ({ user }, res) => { app.get("/", async ({ user }, res) => {
const users = await UserModel.find(user?.admin ? {} : { deleted: false }); const users = await UserModel.find(user?.admin ? {} : { deleted: false });
return res.render("users", { users, user }) return res.reply("users", { users })
}); });
@ -19,7 +19,7 @@ app.get("/:id", async (req, res) => {
const message = await MessageModel.count({ "author.id": id });// this place was having problem. fixed const message = await MessageModel.count({ "author.id": id });// this place was having problem. fixed
const thread = await ThreadModel.count({ "author.id": id }); const thread = await ThreadModel.count({ "author.id": id });
res.render("user", { user, member, counts: { message, thread } }) res.reply("user", { member, counts: { message, thread } })
} }
else res.error(404, "We have not got this user."); else res.error(404, "We have not got this user.");

View File

@ -3,10 +3,11 @@
<%- include("extra/meta", {title: "Create thread!" }) %> <%- include("extra/meta", {title: "Create thread!" }) %>
<link rel="stylesheet" href="/css/create_thread.css" />
<body style="text-align: center;"> <body style="text-align: center;">
<link rel="stylesheet" href="/css/create_thread.css" />
<%- include("extra/navbar") %> <%- include("extra/navbar") %>

View File

@ -15,8 +15,8 @@
<%= thread.title %> <%= thread.title %>
</h1> </h1>
<h2 style="display:inline;">By <a href=<%="/users/" + thread.author.id %>> <%= thread.author.name %></a> <h2 style="display:inline;">By <a href="<%="/users/" + thread.author.id %>"> <%= thread.author.name %></a>
<img class="circle" src=<%=thread.author.avatar %> alt=<%= thread.author.name %>> <img class="circle" src="<%=thread.author.avatar %>">
</h2> </h2>
<% if (user && !thread.deleted){ %> <% if (user && !thread.deleted){ %>

View File

@ -10,7 +10,7 @@
<ul> <ul>
<li> <li>
<h1 style="color: #4d18e6;">Avatar:</h1> <h1 style="color: #4d18e6;">Avatar:</h1>
<img style="width:256px;height:256px;" src=<%=member.avatar %> alt=<%= member.name %>> <img style="width:256px;height:256px;" src="<%=member.avatar %>">
</li> </li>
<li> <li>
@ -92,7 +92,7 @@
if (response.deleted) return; if (response.deleted) return;
alert("User is undeleted successfully!"); alert("User is undeleted successfully!");
location.reload() location.reload()
}); });

View File

@ -12,9 +12,9 @@
<div class="users"> <div class="users">
<% users.forEach(user=>{ %> <% users.forEach(user=>{ %>
<div class="user-box"> <div class="user-box">
<img src="<%=user.avatar %>" class="user-box-img"> <img src="<%= user.avatar %>" class="user-box-img">
<div class="user-box-title"> <a href="<%= user.getLink() %>"> <div class="user-box-title"> <a href="<%= user.getLink() %>">
<% if (user.deleted) { %> <span style="color: RED;">[DELETED]</span><% } %> <% if (user.deleted) { %> <span style="color: RED;">[DELETED]</span><% } %>
<%= user.name %></a></div> <%= user.name %></a></div>
</div> </div>
<% }); %> <% }); %>