canopy/src/validators/accountValidator.js

217 lines
6.1 KiB
JavaScript

/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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/>.*/
//NPM Imports
const { checkSchema } = require('express-validator');
const {sanitizeUrl} = require("@braintree/sanitize-url");
//local imports
const {isRank} = require('./permissionsValidator');
module.exports.user = function(field = 'user'){
return checkSchema({
[field]: {
escape: true,
trim: true,
//Caution: Nerd Rant
//isAlphanumerics only takes locale for the option flag in schemas for some reason...
matches: {
//See this is the shit I'm talking about, WHY IS THIS CALLED OPTIONS? IT SHOULD BE PATTERN
//OPTIONS IS SUPPOSED TO BE AN OBJECT THAT PASSES EXTRA VALUES THATS LITERALLY HOW EVERYTHING ELSE IN THIS FUCKING LIBRARY WORKS
//WHO FUCKING WROTE THIS SHIT!?!?!?!?!
//HOW IS THIS ACCEPTED ON ONE OF THE MOST WIDELY USED VALIDATION LIBRARIES ON THE WEB!??!?!?!!?
//IT'S NOT EVEN FUCKING DOCUMENTED ANYWHERE!!!!!!!!!!!!
//WEBDEVS, GET YOUR FUCKING SHIT TOGETHER, FUCK!
options: [/^[A-Za-z0-9-_]+$/],
errorMessage: "Usernames can only contain numbers, letters, underscores, and dashes."
},
//matches: /^[A-Za-z0-9-_]+$/,
isLength: {
options: {
min: 1,
max: 22
},
errorMessage: "Usernames must be between 1 and 22 characters."
},
}
});
}
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,
}
}
}
module.exports.pass = function(field = 'pass'){
return checkSchema(getPassSchema(field));
}
module.exports.securePass = function(field = 'pass'){
const schema = getPassSchema(field);
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."
}
return checkSchema(schema);
}
module.exports.email = function(field = 'email'){
return checkSchema({
[field]: {
optional: true,
isEmail: {
errorMessage: "Invalid E-Mail Address"
},
normalizeEmail: true
}
});
}
module.exports.img = function(field = 'img'){
return checkSchema({
[field]: {
optional: true,
isURL: {
options: {
require_tld: false,
require_host: false,
require_valid_protocol: true
},
errorMessage: "Invalid URL."
},
trim: true,
customSanitizer: {
options: sanitizeUrl
}
}
});
}
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."
}
});
}
const securityTokenSchema = {
escape: true,
trim: true,
isHexadecimal: true,
isLength: {
options: {
min: 64,
max: 64
}
},
errorMessage: "Invalid security token."
}
module.exports.securityToken = function(field = 'token'){
return checkSchema({[field]:securityTokenSchema});
}
module.exports.rememberMeID = function(field = 'rememberme.id'){
return checkSchema({
[field]:{
in: ['cookies'],
optional: true,
isUUID: true
}
})
}
module.exports.rememberMeToken = function(field = 'rememberme.token'){
//Create our own schema with blackjack and hookers
const tokenSchema = structuredClone(securityTokenSchema);
//Modify as needed
tokenSchema.in = ['cookies'];
tokenSchema.optional = true;
//Return the validator
return checkSchema({[field]:tokenSchema});
}