Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
* },
* ...
* }
*
* @apiUse AuthRequiredError
* @apiUse PermissionDeniedError
* @apiUse RequestValidationError
* @apiUse DocumentNotFoundError
* @apiUse DocumentNotModifiedError
*/
router.patch(
'/api/board/',
// access
adminOnly,
// validator
checkSchema({
'data.uri': _boardUriValidator,
'regenerate': {
isBoolean: true,
toBoolean: true,
in: 'body',
},
...boardParamsValidator,
}),
validateRequest,
filterMatched,
async (req, res, next) => {
try {
const { data, regenerate } = req.body;
const boardUri = data.uri;
const board = await Board.findOne({ uri: boardUri });
if (!board) {
* @api {get} /api/style/ Get styles
* @apiName GetStyle
* @apiGroup Style
* @apiParam {String} name Name of style to get. If not present, array of all styles
* will be returned.
* @apiSuccess {String} name Name of style.
* @apiSuccess {Date} updatedAt When style was last updated.
* @apiSuccess {rawCSS} CSS to insert on page.
* @apiUse RequestValidationError
* @apiUse DocumentNotFoundError
* @apiUse AuthRequiredError
* @apiUse PermissionDeniedError
*/
router.get(
'/api/style/',
checkSchema({
name: {
in: 'query',
matches: {
options: [validStyleNameRegexp],
errorMessage: 'Style name can contain only lowercase letters and numbers'
},
trim: true,
}
}),
validateRequest,
async (req, res, next) => {
try {
const styleName = req.query.name;
if (styleName) {
const style = await Style.findByName(styleName);
if (!style) {
const express = require('express');
const router = express.Router();
const { checkSchema } = require('express-validator');
const {Post, Thread} = require('../models/post');
const { authRequired } = require('../middlewares/permission');
const { validateRequest } = require('../middlewares/validation');
router.post('/preview/news',
authRequired,
checkSchema({
}),
validateRequest,
async (req, res, next) => {
try {
res.render('includes/newsentry', { n: req.body.data });
}
catch (err) {
next(err);
}
}
);
router.post('/preview/markdown',
authRequired,
* "uri": "b"
* }
*
* @apiSuccessExample GET /api/board/b?select=createdAt,postcount:
* HTTP/1.1 200 OK
* {
* "postcount": 4815162342,
* "createdAt": "2019-01-12T17:37:55.337Z"
* }
*
* @apiUse DocumentNotFoundError
* @apiUse RequestValidationError
*/
router.get(
'/api/board/:uri?',
checkSchema({
uri: {
in: 'params',
optional: true,
isLength: {
options: { min: 1 },
errorMessage: 'Board uri must not be empty',
},
matches: {
options: [/^[a-zA-Z0-9_]*$/],
errorMessage: 'Board uri can contain only letters and numbers or underscore',
},
custom: {
options: (v) => !boardparams.uriBlacklist.includes(v),
errorMessage: 'This board uri is not allowed',
},
},
* "_id": "..."
* "isDeleted":[true, false]
* "status": 400,
* "error":{
* "code": "RequestValidation",
* "message": "Conflicting updates",
* "param": "reports",
* "location": "body"
* }
* }
* ]
* }
*/
router.patch('/api/report',
adminOnly,
checkSchema({
reports: {
isArray: true,
in: 'body',
custom: {
options: (arr) => arr.length > 0,
errorMessage: 'Array is empty',
},
errorMessage: 'Array is missing or not an array',
},
'reports.*._id': {
isMongoId: true,
in: 'body',
errorMessage: 'report._id is not a valid Mongo ObjectId',
},
'reports.*.isDeleted': {
isBoolean: true,
* @apiUse IncorrectCaptchaError
* @apiSuccessExample Captcha entered correctly
* HTTP/1.1 200 OK
* {
* "key": "reply.c",
* "expireAt": "2007-01-01T02:55:42.228Z",
* "isSolved": true
* }
* @apiSuccessExample Captcha is not required for board
* HTTP/1.1 200 OK
* {
* "isSolved": true
* }
*/
router.post('/api/captcha/:boardUri/:action',
checkSchema({
...captchaParamsValidators,
answer: {
in: 'body',
isLength: {
errorMessage: 'Captcha answer is empty or too long',
options: {
min: 1,
max: 64
},
},
trim: true,
},
}),
validateRequest,
async (req, res, next) => {
try {
}
}
}),
validateRequest,
async (req, res, next) => {
try {
res.send(res.locals.filters.markdown(req.body.data));
} catch (err) {
next(err);
}
}
);
router.get('/preview/replies/:board/:thread',
checkSchema({
board: {
in: 'params',
matches: {
options: [/^[a-zA-Z0-9_]*$/],
errorMessage: 'Board uri can contain only letters and numbers or underscore',
},
},
thread: {
in: 'params',
isNumeric: {
options: {
no_symbols: true,
},
},
errorMessage: 'Invalid thread Id',
},
* @apiSuccess {Object[]} success List of successful updates
* @apiSuccess {Object} success._id Report mongo ObjectId
* @apiSuccess {Object[]} fail List of updates that were rejected
* @apiSuccess {Object} fail.target Original target object that was in
* request
* @apiSuccess {Number} fail.status HTTP status for this action
* @apiSuccess {Object} fail.error Error object (if only one error)
* @apiSuccess {Object[]} fail.errors Errors objects (if multiple errors)
* @apiError RequestValidationError Request did not pass validation
* @apiError DocumentNotFoundError Target Report not found
* @apiError PermissionDeniedError User has not rights to delete reports
* @apiError AuthRequiredError User is not authenticated
*/
router.delete('/api/report',
adminOnly,
checkSchema({
reports: {
in: 'body',
isArray: true,
custom: {
options: (arr) => arr.length > 0,
errorMessage: 'Array is empty',
},
errorMessage: 'Array is missing or not an array',
},
'reports.*._id': {
in: 'body',
isMongoId: true,
errorMessage: 'item.target._id is not a valid Mongo ObjectId',
}
}),
validateRequest,
* @apiParam {Number} items.target.postId Post number
* @apiSuccess {Object[]} success List of successful updates
* @apiSuccess {Object} success.ref Reflink to post
* @apiSuccess {Number} success.status HTTP status for this action
* @apiSuccess {Object[]} fail List of updates that were rejected
* @apiSuccess {Object} fail.ref Reflink to post, if post was resolved
* @apiSuccess {Object} fail.target If post was not resolved, original target
* object that was in request
* @apiSuccess {Number} fail.status HTTP status for this action
* @apiSuccess {Object} fail.error Error object (if only one error)
* @apiSuccess {Object[]} fail.errors Errors objects (if multiple errors)
* @apiError RequestValidationError Request did not pass validation
* @apiError PostNotFoundError Target Post not found
*/
router.post('/api/report',
checkSchema({
reason: {
in: 'body',
isLength: {
errorMessage: 'Report text is too long (maximum is 280 characters)',
options: { max: 280 },
},
trim: true,
},
items: {
in: 'body',
isArray: true,
},
'items.*.target.boardUri': {
in: 'body',
isLength: {
options: { min: 1 },
* "key": "reply.c",
* "expireAt": "2007-01-01T02:55:42.228Z",
* "isSolved": true
* }
* @apiSuccessExample raw flag is set
* HTTP/1.1 200 OK
* Content-Type: image/gif
*
* @apiSuccessExample Captcha is not required for board
* HTTP/1.1 200 OK
* {
* "isSolved": true
* }
*/
router.get('/api/captcha/:boardUri/:action',
checkSchema({
...captchaParamsValidators,
...captchaQueryValidator
}),
validateRequest,
async (req, res, next) => {
try {
const data = matchedData(req, { locations: ['params', 'query'] });
const { action, boardUri } = data;
if (data.lookup) {
const response = await Captcha.lookup(req.session.id, action, boardUri);
return res.status(200).json(response);
}
const board = await Board.findBoard(boardUri);
if (!board) {