Added char limits

This commit is contained in:
Akif9748 2022-09-17 00:27:38 +03:00
parent 171f83f4cf
commit 1cbcd16954
15 changed files with 55 additions and 38 deletions

View File

@ -13,6 +13,12 @@ You need this headers for send request to API:
```
But in front end, the API will works with session.
## Limits:
- 3 - 25 char for username, password and category name
- 256 char for user about and desp of category
- 5 - 128 char for thread titles.
- 5 - 1024 char for messages.
## How to request?
### Request types:

View File

@ -43,7 +43,6 @@ Akf-forum has got an API for AJAX (fetch), other clients etc. And, you can learn
- upload other photos, model for it
- categories page is need a update.
- preview for send messages in markdown format.
- Limits for thread title, message content, username, user about
- desp => description
## Major Version History

View File

@ -5,7 +5,7 @@ const schema = new mongoose.Schema({
author: Object,
threadID: String,
authorID: String,
content: String,
content: { type: String, maxlength: 1024 },
time: { type: Date, default: Date.now },
deleted: { type: Boolean, default: false },
edited: { type: Boolean, default: false },
@ -30,7 +30,7 @@ const model = mongoose.model('message', schema);
model.get = async id => {
const message = await model.findOne({ id })
return await message.get_author();
return await message.get_author();
};
module.exports = model;

View File

@ -1,7 +1,7 @@
const mongoose = require("mongoose")
const schema = new mongoose.Schema({
username: { type: String, unique: true },
username: { type: String, unique: true, maxlength: 25 },
password: String,
id: { type: String, unique: true }
});

View File

@ -8,7 +8,7 @@ const schema = new mongoose.Schema({
authorID: String,
author: Object,
title: String,
title: { type: String, maxlength: 128 },
time: { type: Date, default: Date.now },
deleted: { type: Boolean, default: false },
edited: { type: Boolean, default: false },
@ -21,10 +21,10 @@ const schema = new mongoose.Schema({
schema.methods.get_author = cache.getAuthor;
schema.methods.get_category = () => async function () {
return await require("./Category").findOne({ id: this.categoryID }) || {id: this.categoryID, name: "Unknown"} ;
return await require("./Category").findOne({ id: this.categoryID }) || { id: this.categoryID, name: "Unknown" };
}
schema.methods.messageCount = async function (admin = false) {
const query = { threadID: this.id };
const query = { threadID: this.id };
if (!admin) query.deleted = false;
return await MessageModel.count(query) || 0;
};
@ -47,7 +47,7 @@ const model = mongoose.model('thread', schema);
model.get = async id => {
const thread = await model.findOne({ id })
return await thread.get_author();
return await thread.get_author();
};
module.exports = model;

View File

@ -1,14 +1,13 @@
const mongoose = require("mongoose")
const { def_theme } = require("../config.json");
const schema = new mongoose.Schema({
id: { type: String },
name: String,
id: { type: String, unique: true },
name: { type: String, maxlength: 25 },
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: "" },
about: { type: String, default: "", maxlength: 256 },
admin: { type: Boolean, default: false },
theme: { type: String, default: def_theme },
lastSeen: { type: Date, default: Date.now, select: false },

View File

@ -27,6 +27,8 @@ app.patch("/:id/", async (req, res) => {
if (user.id !== message.authorID && !user.admin) return res.error(403, "You have not got permission for this.");
const { content = null } = req.body;
if (!content) return res.error(400, "Missing message content in request body.");
if (content.length < 5 || content.length > 1024) return res.error(400, "content must be between 5 - 1024 characters");
message.content = content;
message.edited = true;
@ -43,6 +45,7 @@ app.post("/", rateLimit({
const { threadID, content } = req.body;
if (!content) return res.error(400, "Missing message content in request body.");
if (content.length < 5 || content.length > 1024) return res.error(400, "content must be between 5 - 1024 characters");
const thread = await ThreadModel.get(threadID);

View File

@ -41,7 +41,8 @@ app.post("/", async (req, res) => {
const { title, content, category } = req.body;
if (!content || !title) return res.error(400, "Missing content/title in request body.");
if (title.length < 5 || title.length > 128) return res.error(400, "title must be between 5 - 128 characters");
if (content.length < 5 || content.length > 1024) return res.error(400, "content must be between 5 - 1024 characters");
const { user } = req;
const thread = await new ThreadModel({ title, author: user }).takeId()
if (category)
@ -60,6 +61,8 @@ app.patch("/:id/", async (req, res) => {
if (user.id !== thread.authorID && !user.admin) return res.error(403, "You have not got permission for this.");
const { title } = req.body;
if (!title) return res.error(400, "Missing thread title in request body.");
if (title.length < 5 || title.length > 128) return res.error(400, "title must be between 5 - 128 characters");
thread.title = title;
await thread.save();

View File

@ -5,10 +5,10 @@ const multer = require("multer");
const app = Router();
app.param("id", async (req, res, next, id) => {
req.member = await UserModel.get(id, req.user.admin ? "+lastSeen": "");
req.member = await UserModel.get(id, req.user.admin ? "+lastSeen" : "");
if (!req.member) return res.error(404, `We don't have any user with id ${id}.`);
if (req.member.deleted && !req.user?.admin)
return res.error(404, `You do not have permissions to view this user with id ${id}.`);
@ -58,12 +58,18 @@ app.patch("/:id/", async (req, res) => {
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 (name) {
if (name.length < 3 || name.length > 25) return res.error(400, "Username must be between 3 - 25 characters");
await SecretModel.updateOne({ id: member.id }, { username: name });
member.name = name;
}
if (about) member.about = about;
if (about) {
if (about.length > 256) return res.error(400, "About must be under 256 characters");
member.about = about;
}
if (theme || ["default", "black"].includes(theme)) member.theme = theme;
if (typeof admin === "boolean" || ["false", "true"].includes(admin)) member.admin = admin;

View File

@ -11,18 +11,24 @@ app.post("/", rateLimit({
handler: (_r, response, _n, options) => response.error(options.statusCode, "You are begin ratelimited")
}), async (req, res) => {
req.session.userID=null;
req.session.userID = null;
let { username = null, password: body_pass = null, about } = req.body;
if (!username || !body_pass) return res.error(res, 400, "You forgot entering some values");
if (!username || !body_pass) return res.error(400, "You forgot entering some values");
if (username.length < 3 || username.length > 25) return res.error(400, "Username must be between 3 - 25 characters");
if (body_pass.length < 3 || body_pass.length > 25) return res.error(400, "Password must be between 3 - 25 characters");
const user = await SecretModel.findOne({ username });
if (user) return res.error(res, 400, `We have got an user named ${username}!`)
if (user) return res.error(400, `We have got an user named ${username}!`)
const user2 = new UserModel({ name: req.body.username })
const user2 = new UserModel({ name: username })
if (about) user2.about = about;
if (about) {
if (about.length > 256) return res.error(400, "about must be under 256 characters");
user2.about = about;
}
await user2.takeId()
await user2.save();

View File

@ -9,9 +9,9 @@
<form>
<h2 class="title" style="align-self: baseline;">Name:</h2>
<input name="name" class="input"></input>
<input name="name" class="input" required maxlength="25" ></input>
<h2 class="title" style="align-self: baseline;">Description:</h2>
<textarea rows="4" cols="50" name="desp" class="input"></textarea>
<textarea rows="4" cols="50" name="desp" maxlength="256" class="input" required></textarea>
<button class="btn-primary" style="width:100%" type="submit">Create Category!</button>
</form>
@ -22,7 +22,7 @@
document.addEventListener("submit", async e => {
e.preventDefault();
const data = new FormData(e.target);
const response = await request("/api/categories/", "POST", {
name: data.get("name"),
desp: data.get("desp")

View File

@ -10,10 +10,10 @@
<form>
<h2 class="title" style="align-self: baseline;">Title:</h2>
<input name="title" class="input"></input>
<h2 class="title"style="align-self: baseline;">Title:</h2>
<input name="title" maxlength="128" class="input" required></input>
<h2 class="title" style="align-self: baseline;">Content:</h2>
<textarea rows="4" cols="50" name="content" class="input"></textarea>
<textarea rows="4" cols="50" maxlength="1024" name="content" class="input" required></textarea>
<h2 class="title" style="align-self: baseline;">Category:</h2>
<select name="category">

View File

@ -12,13 +12,9 @@
<h1 class="title">Register</h1>
<form action="/register" method="post">
<input type="text" name="username" placeholder="Username" class="input" required>
<input type="password" name="password" placeholder="Password" class="input" required>
<textarea class="input" name="about" rows="4" placeholder="About you... Not required"></textarea>
<input type="text" name="username" maxlength="25" placeholder="Username" class="input" required>
<input type="password" name="password" maxlength="25" placeholder="Password" class="input" required>
<textarea class="input" name="about" rows="4" maxlength="256" placeholder="About you... You can use markdown"></textarea>
<input type="submit" class="btn-primary" style="width:100%;" value="Register">
</form>

View File

@ -109,11 +109,10 @@
<div class="message" id="send-div">
<form id="send" style="width:100%">
<textarea rows="4" name="content"></textarea>
<textarea rows="4" maxlength="1024" name="content" required></textarea>
<input name="threadID" type="hidden" value="<%= thread.id %>"></input>
<input name="page" type="hidden" value="<%= page %>"></input>
<button class="btn-primary">Send!</button>
</form>
</div>

View File

@ -28,9 +28,9 @@
<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" minlength="3" maxlength="25" placeholder="<%=member.name%>" class="input" required>
<textarea class="input" name="about" rows="4" cols="60" name="content" placeholder="<%=member.about%>"></textarea>
<textarea class="input" name="about" maxlength="256" required rows="4" cols="60" name="content" placeholder="<%=member.about%>"></textarea>
<% if (user?.admin){ %>
Is Admin? <input id='admin' type='checkbox' value='true' name='admin' <%=member.admin ? "checked": ""%>>
<input id='adminHidden' type='hidden' value='false' name='admin'>