list util bugs, force body camelCase for hyphenated endpoints

master
Kit Kasune 1 year ago
parent 77946475a1
commit 66c88a92c7
  1. 2
      api/ani/v1/routes/series/add.js
  2. 34
      api/ani/v1/routes/series/edits.js
  3. 10
      api/ani/v1/routes/user.js
  4. 3
      api/index.js
  5. 3
      api/util/bodycase.js
  6. 31
      api/util/editstring.js
  7. 17
      api/util/list.js

@ -28,7 +28,7 @@ module.exports = (app, router) => {
if (
!req.body //i just ate dinner and i can't even think straight
|| !req.body.name || !req.body.romaji || !req.params.id || !req.authenticatedUser || !req.authenticatedUser.id
|| !req.body.name.match(/^[\w_\-!?.:; ]+$/gm) || req.body.name.length > 150
|| !req.body.name.match(/^[\w\-!?.:; ]+$/gm) || req.body.name.length > 150
|| req.body.romaji.length > 150
|| !req.params.id.match(/^[0-9_-]*[a-zA-Z][\w-]*$/gm) || req.params.id.length > 25
) {return res.status(400).send("The server cannot accept your request as your body is missing fields or is malformed. Ensure fields aren't too long and that they don't contain illegal characters.");}

@ -19,7 +19,7 @@ module.exports = (app, router) => {
series.markModified('meta.edits');
};
const edits = app.util.editString(pushEdit, editCheck, router, Anime);
const edits = app.util.editString('/:id', pushEdit, editCheck, router, Anime);
router.route('/:id/synopsis') //completed i think?
.patch(app.auth.token, app.auth.perms('series-submit'), async (req, res, next) => {
@ -47,11 +47,37 @@ module.exports = (app, router) => {
});
[
['name', x => x.match(/^[\w_\-!?.:; ]+$/gm) && x.length < 150],
['name', x => x.match(/^[\w\-!?.:; ]+$/gm) && x.length < 150],
['romaji', x => x.length < 150],
['kanji', x => x.length < 150]
['kanji', x => x.length < 150],
['official-site', x => x.length]
].forEach(field => edits.stringWrap(field[0], field[1]));
].forEach(field => edits.stringWrap(...field));
const editStringList = async (name, match) => {
router.use(`/:id/${name}`, app.auth.tokenPass, app.auth.permsPass('series-approve'), async (req, res, next) => {
if (!req.params.id) {return res.status(400).send("Missing ID!");}
const series = await Anime.findOne({id: req.params.id.toLowerCase()});
if (!editCheck(series, req, res)) {return;}
req.series = series;
req.listData = req.user.permissions;
next();
}, app.util.list(router, `/:id/${name}`, true, name, async (req, res, permissions, permission) => {
if (permission && (!permission.match(/^[\w-]+$/gm) || permission.length > 15)) {res.status(400).send("The permission you provided is invalid."); return 0;}
if (permission) {permissions[permissions.length - 1] = permission.toLowerCase();}
req.user.permissions = permissions;
req.user.markModified('permissions');
await req.user.save();
}, (req, res, next) => {
if (!req.authenticatedUser) {return res.status(401).send("You must be authenticated before you do that!");}
if (req.unauthorized) {return res.status(401).send("You are not authorized to edit users!");}
return next();
}));
};
[
['tags', x => x.match()]
]

@ -22,8 +22,8 @@ module.exports = (app, router) => {
if (!req.body) {return res.status(400).send("Missing body!");}
if (
!req.body.name || !req.body.discord || !req.body.permissions || !Array.isArray(req.body.permissions)
|| !req.body.name.match(/^[\w_\- ]+$/gm) || req.body.name.length > 20
|| !req.params.id.match(/^[\w_\-]+$/gm) || req.params.id.length > 15
|| !req.body.name.match(/^[\w- ]+$/gm) || req.body.name.length > 20
|| !req.params.id.match(/^[\w-]+$/gm) || req.params.id.length > 15
|| !req.body.password || req.body.password.length > 30
) {return res.status(400).send("Malformed body or missing body data. Make sure you have all the required parameters, and you don't have illegal characters present.");}
@ -78,14 +78,14 @@ module.exports = (app, router) => {
});
router.use('/user/:id/permissions', app.auth.tokenPass, app.auth.permsPass('edit-users'), async (req, res, next) => {
if (!req.params.id) {return res.status(400).send("Missing ID!");}
if (!req.params.id) {return await res.status(400).send("Missing ID!");}
const user = await Users.findOne({id: req.params.id.toLowerCase()});
if (!user) {return res.status(404).send("That user doesn't exist!");}
if (!user) {return await res.status(404).send("That user doesn't exist!");}
req.user = user;
req.listData = req.user.permissions;
next();
}, app.util.list(router, '/user/:id/permissions', true, 'permission', async (req, res, permissions, permission) => {
if (permission && (!permission.match(/^[\w_]+$/gm) || permission.length > 15)) {res.status(400).send("The permission you provided is invalid."); return 0;}
if (permission && (!permission.match(/^[\w-]+$/gm) || permission.length > 15)) {await res.status(400).send("The permission you provided is invalid."); return 1;}
if (permission) {permissions[permissions.length - 1] = permission.toLowerCase();}
req.user.permissions = permissions;
req.user.markModified('permissions');

@ -43,8 +43,9 @@ server = app.listen(4062, async () => {
app.auth.permsPass = require('./util/auth/authorize')(app, true);
app.util = {};
app.util.list = require('./util/list');
app.util.list = require('./util/list'); //automagically add list-based fields to an endpoint
app.util.editString = require('./util/editstring').masterInit(app); //TODO consistency shithead
app.util.bodyCase = require('./util/bodycase'); //represent foo-bar as fooBar
await require('./util/startup/cache')(app);

@ -0,0 +1,3 @@
module.exports = name => name.match(/.-./g)
? `${name.split('-')[0]}${name.split('-').slice(1).map(x => `${x.slice(0, 1).toUpperCase()}${x.slice(1)}`).join()}`
: name; //moved to own file since some deps can't access central object

@ -1,26 +1,27 @@
module.exports = {
masterInit: (app) => {
return (pushEdit, editCheck, router, model) => {
return (routePrefix, pushEdit, editCheck, router, model) => {
return {
string: async (req, res, name, match) => {
string: async function (req, res, name, match) {
if (!req.params.id) {return;}
const series = await model.findOne({id: req.params.id.toLowerCase()});
if (!editCheck(series, req, res)) {return;}
if (!req.body[name]) {return res.status(400).send(`You did not provide a new ${name} in your body.`);}
if (!match(req.body[name])) {return res.status(400).send(`Your new ${name} is too long or contains illegal characters.`);}
const document = await model.findOne({id: req.params.id.toLowerCase()});
if (!editCheck(document, req, res)) {return;}
const camelName = app.util.bodyCase(name);
if (!req.body[camelName]) {return res.status(400).send(`You did not provide a new ${camelName} in your body.`);}
if (!match(req.body[camelName])) {return res.status(400).send(`Your new ${camelName} is too long or contains illegal characters.`);}
try {
series[name] = req.body[name].trim();
pushEdit(`Updated ${name}`, req, series);
return series.save()
.then(() => res.send(`${name.charAt(0)}${name.slice(1)} updated.`))
.catch(() => res.status(500).send(`There was an error trying to update your ${name}. Please try again.`));
} catch {return res.status(500).send(`There was an error trying to update your ${name}. Please try again.`);}
document[camelName] = req.body[camelName].trim();
pushEdit(`Updated ${camelName}`, req, document);
return document.save()
.then(() => res.send(`${camelName.charAt(0).toUpperCase()}${camelName.slice(1)} updated.`))
.catch(() => res.status(500).send(`There was an error trying to update your ${camelName}. Please try again.`));
} catch {return res.status(500).send(`There was an error trying to update your ${camelName}. Please try again.`);}
},
stringWrap: (name, match) => {
const route = router.route(`/:id/${name}`);
stringWrap: function (name, match) {
const route = router.route(`${routePrefix}/${name}`);
route.patch(app.auth.token, app.auth.permsPass('series-approve'), async (req, res) => {
await this.string(req, res, name, match);
await this.string(req, res, name, match).catch(() => res.status(500).send(`There was an error trying to update your ${name}. Please try again.`));
});
return route
}

@ -8,11 +8,12 @@ module.exports = (parentRouter, path, modifiable, bodyName, save, authHandler) =
router.get('/random', (req, res) => res.json(!Array.isArray(req.listData) ? Object.keys(req.listData)[Math.floor(Math.random() * Object.keys(req.listData).length)] : req.listData[Math.floor(Math.random() * req.listData.length)]));
//TODO search
if (modifiable) { //TODO auth
if (modifiable) {
const camelBodyName = require('./bodycase')(bodyName);
const add = async (req, res) => {
if (!req.body[bodyName]) {return res.status(400).send(`Missing body param "${bodyName}".`);}
req.listData.push(req.body[bodyName]);
return await save(req, res, req.listData, req.body[bodyName]) || res.json(req.listData);
if (!req.body[bodyName]) {return await res.status(400).send(`Missing body param "${camelBodyName}".`);}
req.listData.push(req.body[camelBodyName]);
return await save(req, res, req.listData, req.body[camelBodyName]) || await res.json(req.listData);
}
router.post('/add', authHandler, add);
router.post('/', authHandler, add);
@ -21,13 +22,13 @@ module.exports = (parentRouter, path, modifiable, bodyName, save, authHandler) =
return await save(req, res, req.listData) || res.json(req.listData);
});
router.delete('/remove', authHandler, async (req, res) => {
if (!req.body[bodyName]) {return res.status(400).send(`Missing body param "${bodyName}".`);}
let index = req.listData.indexOf(req.body[bodyName]);
if (!req.body[camelBodyName]) {return res.status(400).send(`Missing body param "${camelBodyName}".`);}
let index = req.listData.indexOf(req.body[camelBodyName]);
if (index === -1) {return res.status(400).send("The server was unable to find an item matching the specified criteria.");}
let length = req.listData.length;
if (req.listData.length === 1 && req.listData[0] === req.body[bodyName]) {req.listData = [];}
else {req.listData.splice(req.listData.indexOf(req.body[bodyName]), 1);}
if (req.listData.length === 1 && req.listData[0] === req.body[camelBodyName]) {req.listData = [];}
else {req.listData.splice(index, 1);}
return req.listData.length === length ? res.status(500).send("For some reason, that couldn't be removed.") : await save(req, res, req.listData) || res.json(req.listData);
});

Loading…
Cancel
Save