validators.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import { body, validationResult } from "express-validator";
  2. import urlRegex from "url-regex";
  3. import URL from "url";
  4. import { findDomain } from "../queries/domain";
  5. import { CustomError } from "../utils";
  6. export const verify = (req, res, next) => {
  7. const errors = validationResult(req);
  8. if (!errors.isEmpty()) {
  9. const message = errors.array()[0].msg;
  10. throw new CustomError(message, 400);
  11. }
  12. return next();
  13. };
  14. export const preservedUrls = [
  15. "login",
  16. "logout",
  17. "signup",
  18. "reset-password",
  19. "resetpassword",
  20. "url-password",
  21. "url-info",
  22. "settings",
  23. "stats",
  24. "verify",
  25. "api",
  26. "404",
  27. "static",
  28. "images",
  29. "banned",
  30. "terms",
  31. "privacy",
  32. "report",
  33. "pricing"
  34. ];
  35. export const createLink = [
  36. body("target")
  37. .exists({ checkNull: true, checkFalsy: true })
  38. .withMessage("Target is missing.")
  39. .isLength({ min: 1, max: 2040 })
  40. .withMessage("Maximum URL length is 2040.")
  41. .custom(
  42. value =>
  43. urlRegex({ exact: true, strict: false }).test(value) ||
  44. /^(?!https?)(\w+):\/\//.test(value)
  45. )
  46. .withMessage("URL is not valid.")
  47. .custom(value => URL.parse(value).host !== process.env.DEFAULT_DOMAIN)
  48. .withMessage(`${process.env.DEFAULT_DOMAIN} URLs are not allowed.`),
  49. body("password")
  50. .optional()
  51. .isLength({ min: 3, max: 64 })
  52. .withMessage("Password length must be between 3 and 64."),
  53. body("customurl")
  54. .optional()
  55. .isLength({ min: 1, max: 64 })
  56. .withMessage("Custom URL length must be between 1 and 64.")
  57. .custom(value => /^[a-zA-Z0-9-_]+$/g.test(value))
  58. .withMessage("Custom URL is not valid")
  59. .custom(value => preservedUrls.some(url => url.toLowerCase() === value))
  60. .withMessage("You can't use this custom URL."),
  61. body("reuse")
  62. .optional()
  63. .isBoolean()
  64. .withMessage("Reuse must be boolean."),
  65. body("domain")
  66. .optional()
  67. .isString()
  68. .withMessage("Domain should be string.")
  69. .custom(async (address, { req }) => {
  70. const domain = await findDomain({
  71. address,
  72. userId: req.user && req.user.id
  73. });
  74. req.body.domain = domain || null;
  75. if (domain) return true;
  76. throw new CustomError("You can't use this domain.", 400);
  77. })
  78. ];