Add initial report quote endpoint (#2367) by Bruception

* Add initial report quote endpoint

* Tune rate limiter for report quote

* Tune rate limiter

* Increase max comment size

* Add supported languages to schema validation

* Fix naming
This commit is contained in:
Bruce Berrios 2022-01-29 16:03:02 -05:00 committed by GitHub
parent e7a41c52b4
commit 7ce9146c7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 151 additions and 0 deletions

View file

@ -1,8 +1,11 @@
const joi = require("joi");
const { authenticateRequest } = require("../../middlewares/auth");
const { Router } = require("express");
const NewQuotesController = require("../controllers/new-quotes");
const QuoteRatingsController = require("../controllers/quote-ratings");
const RateLimit = require("../../middlewares/rate-limit");
const { requestValidation } = require("../../middlewares/apiUtils");
const SUPPORTED_QUOTE_LANGUAGES = require("../../constants/quoteLanguages");
const quotesRouter = Router();
@ -48,4 +51,31 @@ quotesRouter.post(
QuoteRatingsController.submitRating
);
quotesRouter.post(
"/report",
RateLimit.quoteReportSubmit,
authenticateRequest,
requestValidation({
body: {
quoteId: joi.string().required(),
quoteLanguage: joi
.string()
.valid(...SUPPORTED_QUOTE_LANGUAGES)
.required(),
reason: joi
.string()
.valid(
"Grammatical error",
"Inappropriate content",
"Low quality content"
)
.required(),
comment: joi.string().allow("").max(250).required(),
},
}),
(req, res) => {
res.sendStatus(200);
}
);
module.exports = quotesRouter;

View file

@ -0,0 +1,37 @@
const SUPPORTED_QUOTE_LANGUAGES = [
"albanian",
"arabic",
"code_c++",
"code_c",
"code_java",
"code_javascript",
"code_python",
"code_rust",
"czech",
"danish",
"dutch",
"english",
"filipino",
"french",
"german",
"hindi",
"icelandic",
"indonesian",
"irish",
"italian",
"lithuanian",
"malagasy",
"polish",
"portuguese",
"russian",
"serbian",
"slovak",
"spanish",
"swedish",
"thai",
"toki_pona",
"turkish",
"vietnamese",
];
module.exports = SUPPORTED_QUOTE_LANGUAGES;

View file

@ -0,0 +1,32 @@
const joi = require("joi");
const MonkeyError = require("../handlers/error");
function requestValidation(validationSchema) {
return (req, res, next) => {
// In dev environments, as an alternative to token authentication,
// you can pass the authentication middleware by having a user id in the body.
// Inject the user id into the schema so that validation will not fail.
if (process.env.MODE === "dev") {
validationSchema.body = {
uid: joi.any(),
...(validationSchema.body ?? {}),
};
}
Object.keys(validationSchema).forEach((key) => {
const schema = validationSchema[key];
const joiSchema = joi.object().keys(schema);
const { error } = joiSchema.validate(req[key] ?? {});
if (error) {
const errorMessage = error.details[0].message;
throw new MonkeyError(400, `Invalid request: ${errorMessage}`);
}
});
next();
};
}
module.exports = {
requestValidation,
};

View file

@ -68,6 +68,14 @@ exports.quoteRatingsSubmit = rateLimit({
keyGenerator: getAddress,
});
// Quote reporting
exports.quoteReportSubmit = rateLimit({
windowMs: 30 * 60 * 1000, // 30 min
max: 50 * multiplier,
message,
keyGenerator: getAddress,
});
// Presets Routing
exports.presetsGet = rateLimit({
windowMs: 60 * 60 * 1000, // 60 min

43
package-lock.json generated
View file

@ -1735,6 +1735,19 @@
}
}
},
"@hapi/hoek": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz",
"integrity": "sha512-gfta+H8aziZsm8pZa0vj04KO6biEiisppNgA1kbJvFrrWu9Vm7eaUEy76DIxsuTaWvti5fkJVhllWc6ZTE+Mdw=="
},
"@hapi/topo": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
"integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
"requires": {
"@hapi/hoek": "^9.0.0"
}
},
"@humanwhocodes/config-array": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
@ -2005,6 +2018,24 @@
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=",
"optional": true
},
"@sideway/address": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.3.tgz",
"integrity": "sha512-8ncEUtmnTsMmL7z1YPB47kPUq7LpKWJNFPsRzHiIajGC5uXlWGn+AmkYPcHNl8S4tcEGx+cnORnNYaw2wvL+LQ==",
"requires": {
"@hapi/hoek": "^9.0.0"
}
},
"@sideway/formula": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
"integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg=="
},
"@sideway/pinpoint": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="
},
"@sindresorhus/is": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
@ -7813,6 +7844,18 @@
"integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==",
"dev": true
},
"joi": {
"version": "17.6.0",
"resolved": "https://registry.npmjs.org/joi/-/joi-17.6.0.tgz",
"integrity": "sha512-OX5dG6DTbcr/kbMFj0KGYxuew69HPcAE3K/sZpEV2nP6e/j/C0HV+HNiBPCASxdx5T7DMoa0s8UeHWMnb6n2zw==",
"requires": {
"@hapi/hoek": "^9.0.0",
"@hapi/topo": "^5.0.0",
"@sideway/address": "^4.1.3",
"@sideway/formula": "^3.0.0",
"@sideway/pinpoint": "^2.0.0"
}
},
"jose": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz",

View file

@ -62,6 +62,7 @@
"gulp-replace": "^1.1.3",
"helmet": "^4.6.0",
"howler": "^2.2.1",
"joi": "^17.6.0",
"moment-timezone": "^0.5.33",
"mongodb": "^3.6.9",
"node-fetch": "^2.6.7",