Started improvement of validators and respective error messages

This commit is contained in:
rainbow napkin 2025-04-29 00:13:19 -04:00
parent 8305494915
commit a6228a9fd9
5 changed files with 180 additions and 22 deletions

View file

@ -14,6 +14,9 @@ GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//config
const config = require('../../../../config.json');
//npm imports
const {validationResult, matchedData} = require('express-validator');

View file

@ -42,7 +42,8 @@ const channelSchema = new mongoose.Schema({
name: {
type: mongoose.SchemaTypes.String,
required: true,
maxLength: 50,
//Calculate max length by the validator max length and the size of an escaped character
maxLength: 50 * 6,
default: 0
},
description: {

View file

@ -73,23 +73,25 @@ const userSchema = new mongoose.Schema({
required: true,
default: "/img/johnny.png"
},
//These should be larger than validator values to make room for escaped characters
bio: {
type: mongoose.SchemaTypes.String,
required: true,
maxLength: 2000,
//Calculate max length by the validator max length and the size of an escaped character
maxLength: 1000 * 6,
default: "Bio not set!"
},
pronouns:{
type: mongoose.SchemaTypes.String,
optional: true,
maxLength: 50,
//Calculate max length by the validator max length and the size of an escaped character
maxLength: 15 * 6,
default: ""
},
signature: {
type: mongoose.SchemaTypes.String,
required: true,
maxLength: 300,
//Calculate max length by the validator max length and the size of an escaped character
maxLength: 25 * 6,
default: "Signature not set!"
},
highLevel: {

View file

@ -15,31 +15,166 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.*/
//NPM Imports
const { check, body, checkSchema, checkExact} = require('express-validator');
const {checkSchema} = require('express-validator');
//local imports
const {isRank} = require('./permissionsValidator');
module.exports = {
user: (field = 'user') => check(field).escape().trim().isAlphanumeric().isLength({min: 1, max: 22}),
module.exports.user = function(field = 'user'){
return checkSchema({
[field]: {
escape: true,
trim: true,
isAlphanumeric: {
errorMessage: "Usernames must be alphanumeric."
},
isLength: {
options: {
min: 1,
max: 22
},
errorMessage: "Usernames must be between 1 and 22 characters."
},
}
});
}
//Password security requirements may change over time, therefore we should only validate against strongPassword() when creating new accounts
//that way we don't break old ones upon change
pass: (field = 'pass') => body(field).notEmpty().escape().trim(),
securePass: (field) => module.exports.pass(field).isStrongPassword({minLength: 8, minLowercase: 1, minUppercase: 1, minNumbers: 1, minSymbols: 1}),
function getPassSchema(field = 'pass'){
//Heavily simplified from previous versions.
//Trimming passwords is iffy, and escaping them is a down-right bad idea
return {
[field]: {
notEmpty: true,
}
}
}
email: (field = 'email') => body(field).optional().isEmail().normalizeEmail(),
module.exports.pass = function(field = 'pass'){
return checkSchema(getPassSchema(field));
}
img: (field = 'img') => body(field).optional().isURL({require_tld: false, require_host: false}).trim(),
module.exports.securePass = function(field = 'pass'){
const schema = getPassSchema(field);
//Length check before escaping to keep symbols from throwing the count
pronouns: (field = 'pronouns') => body(field).optional().trim().isLength({min: 0, max: 15}).escape(),
schema[field].isStrongPassword = {
options: {
minLength: 8,
minLowercase: 1,
minUppercase: 1,
minNumbers: 1,
minSymbols: 1
},
errorMessage: "Passwords must contain 8 characters, including at least one: Upper, Lower, Number, and Special char."
}
signature: (field = 'signature') => body(field).optional().trim().isLength({min: 1, max: 25}).escape(),
return checkSchema(schema);
}
bio: (field = 'bio') => body(field).optional().trim().isLength({min: 1, max: 1000}).escape(),
module.exports.email = function(field = 'email'){
return checkSchema({
[field]: {
optional: true,
isEmail: {
errorMessage: "Invalid E-Mail Address"
},
normalizeEmail: true
}
});
}
rank: (field = 'rank') => body(field).escape().trim().custom(isRank),
module.exports.img = function(field = 'img'){
return checkSchema({
[field]: {
optional: true,
isURL: {
options: {
require_tld: false,
require_host: false
},
errorMessage: "Invalid URL."
},
trim: true
}
});
}
securityToken: (field = 'token') => check(field).escape().trim().isHexadecimal().isLength({min:32, max:32})
module.exports.pronouns = function(field = 'pronouns'){
return checkSchema({
[field]: {
optional: true,
trim: true,
isLength: {
options: {
min: 0,
max: 15
},
errorMessage: "Pronouns must be under 15 characters."
},
escape: true
}
});
}
module.exports.signature = function(field = 'signature'){
return checkSchema({
[field]: {
optional: true,
trim: true,
isLength: {
options: {
min: 1,
max: 25
},
errorMessage: "Signature must be between 1 and 25 characters."
},
escape: true
}
});
}
module.exports.bio = function(field = 'bio'){
return checkSchema({
[field]: {
optional: true,
trim: true,
isLength: {
options: {
min: 1,
max: 1000
},
errorMessage: "Bio must be between 1 and 1000 characters."
},
escape: true
}
});
}
module.exports.rank = function(field = 'rank'){
return checkSchema({
[field]: {
escape: true,
trim: true,
custom: {
options: isRank,
},
errorMessage: "Invalid rank."
}
});
}
module.exports.securityToken = function(field = 'token'){
return checkSchema({
[field]: {
escape: true,
trim: true,
isHexadecimal: true,
isLength: {
options: {
min: 32,
max: 32
}
},
errorMessage: "Invalid security token."
}
});
}

View file

@ -21,8 +21,6 @@ const { check, body, checkSchema, checkExact} = require('express-validator');
const accountValidator = require('./accountValidator');
module.exports = {
name: (field = 'name') => check(field).escape().trim().isAlphanumeric().isLength({min: 1, max: 50}),
description: (field = 'description') => body(field).escape().trim().isLength({min: 1, max: 1000}),
thumbnail: (field = 'thumbnail') => accountValidator.img(field),
@ -35,4 +33,23 @@ module.exports = {
isBoolean: true,
}
}))
}
module.exports.name = function(field = 'name'){
return checkSchema({
[field]: {
esacpe: true,
isAlphanumeric: {
errorMessage: "Channel names must be alphanumeric."
},
isLength: {
options: {
min: 1,
max: 50
},
errorMessage: "Channel numes must be between 1 and 50 characters."
},
trim: true
}
});
}