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. 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? ## How to request?
### Request types: ### 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 - upload other photos, model for it
- categories page is need a update. - categories page is need a update.
- preview for send messages in markdown format. - preview for send messages in markdown format.
- Limits for thread title, message content, username, user about
- desp => description - desp => description
## Major Version History ## Major Version History

View file

@ -5,7 +5,7 @@ const schema = new mongoose.Schema({
author: Object, author: Object,
threadID: String, threadID: String,
authorID: String, authorID: String,
content: String, content: { type: String, maxlength: 1024 },
time: { type: Date, default: Date.now }, time: { type: Date, default: Date.now },
deleted: { type: Boolean, default: false }, deleted: { type: Boolean, default: false },
edited: { type: Boolean, default: false }, edited: { type: Boolean, default: false },

View file

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

View file

@ -8,7 +8,7 @@ const schema = new mongoose.Schema({
authorID: String, authorID: String,
author: Object, author: Object,
title: String, title: { type: String, maxlength: 128 },
time: { type: Date, default: Date.now }, time: { type: Date, default: Date.now },
deleted: { type: Boolean, default: false }, deleted: { type: Boolean, default: false },
edited: { type: Boolean, default: false }, edited: { type: Boolean, default: false },

View file

@ -1,14 +1,13 @@
const mongoose = require("mongoose") const mongoose = require("mongoose")
const { def_theme } = require("../config.json"); const { def_theme } = require("../config.json");
const schema = new mongoose.Schema({ const schema = new mongoose.Schema({
id: { type: String }, id: { type: String, unique: true },
name: { type: String, maxlength: 25 },
name: String,
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 }, deleted: { type: Boolean, default: false },
edited: { type: Boolean, default: false }, edited: { type: Boolean, default: false },
about: { type: String, default: "" }, about: { type: String, default: "", maxlength: 256 },
admin: { type: Boolean, default: false }, admin: { type: Boolean, default: false },
theme: { type: String, default: def_theme }, theme: { type: String, default: def_theme },
lastSeen: { type: Date, default: Date.now, select: false }, 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."); if (user.id !== message.authorID && !user.admin) return res.error(403, "You have not got permission for this.");
const { content = null } = req.body; const { content = null } = req.body;
if (!content) return res.error(400, "Missing message content in request 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.content = content;
message.edited = true; message.edited = true;
@ -43,6 +45,7 @@ app.post("/", rateLimit({
const { threadID, content } = req.body; const { threadID, content } = req.body;
if (!content) return res.error(400, "Missing message content in request 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); const thread = await ThreadModel.get(threadID);

View file

@ -41,7 +41,8 @@ app.post("/", async (req, res) => {
const { title, content, category } = req.body; const { title, content, category } = req.body;
if (!content || !title) return res.error(400, "Missing content/title in request 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 { user } = req;
const thread = await new ThreadModel({ title, author: user }).takeId() const thread = await new ThreadModel({ title, author: user }).takeId()
if (category) 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."); if (user.id !== thread.authorID && !user.admin) return res.error(403, "You have not got permission for this.");
const { title } = req.body; const { title } = req.body;
if (!title) return res.error(400, "Missing thread title in request 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; thread.title = title;
await thread.save(); await thread.save();

View file

@ -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 ((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) {
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 }); await SecretModel.updateOne({ id: member.id }, { username: name });
member.name = 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 (theme || ["default", "black"].includes(theme)) member.theme = theme;
if (typeof admin === "boolean" || ["false", "true"].includes(admin)) member.admin = admin; if (typeof admin === "boolean" || ["false", "true"].includes(admin)) member.admin = admin;

View file

@ -15,14 +15,20 @@ app.post("/", rateLimit({
let { username = null, password: body_pass = null, about } = req.body; 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 }); 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.takeId()
await user2.save(); await user2.save();

View file

@ -9,9 +9,9 @@
<form> <form>
<h2 class="title" style="align-self: baseline;">Name:</h2> <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> <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> <button class="btn-primary" style="width:100%" type="submit">Create Category!</button>
</form> </form>

View file

@ -11,9 +11,9 @@
<form> <form>
<h2 class="title"style="align-self: baseline;">Title:</h2> <h2 class="title"style="align-self: baseline;">Title:</h2>
<input name="title" class="input"></input> <input name="title" maxlength="128" class="input" required></input>
<h2 class="title" style="align-self: baseline;">Content:</h2> <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> <h2 class="title" style="align-self: baseline;">Category:</h2>
<select name="category"> <select name="category">

View file

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

View file

@ -109,11 +109,10 @@
<div class="message" id="send-div"> <div class="message" id="send-div">
<form id="send" style="width:100%"> <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="threadID" type="hidden" value="<%= thread.id %>"></input>
<input name="page" type="hidden" value="<%= page %>"></input> <input name="page" type="hidden" value="<%= page %>"></input>
<button class="btn-primary">Send!</button> <button class="btn-primary">Send!</button>
</form> </form>
</div> </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> <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" 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){ %> <% if (user?.admin){ %>
Is Admin? <input id='admin' type='checkbox' value='true' name='admin' <%=member.admin ? "checked": ""%>> Is Admin? <input id='admin' type='checkbox' value='true' name='admin' <%=member.admin ? "checked": ""%>>
<input id='adminHidden' type='hidden' value='false' name='admin'> <input id='adminHidden' type='hidden' value='false' name='admin'>