links.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { Handler, Request } from "express";
  2. import URL from "url";
  3. import { generateShortLink, generateId, CustomError } from "../utils";
  4. import {
  5. getLinksQuery,
  6. getTotalQuery,
  7. findLinkQuery,
  8. createLinkQuery
  9. } from "../queries/link";
  10. import {
  11. cooldownCheck,
  12. malwareCheck,
  13. urlCountsCheck,
  14. checkBannedDomain,
  15. checkBannedHost
  16. } from "../controllers/validateBodyController";
  17. import { addIP } from "../db/ip";
  18. export const getLinks: Handler = async (req, res) => {
  19. const { limit, skip, search, all } = req.query;
  20. const userId = req.user.id;
  21. const [links, total] = await Promise.all([
  22. getLinksQuery({ all, limit, search, skip, userId }),
  23. getTotalQuery({ all, search, userId })
  24. ]);
  25. const data = links.map(link => ({
  26. ...link,
  27. id: link.uuid,
  28. password: !!link.password,
  29. link: generateShortLink(link.address, link.domain)
  30. }));
  31. return res.send({
  32. total,
  33. limit,
  34. skip,
  35. data
  36. });
  37. };
  38. interface CreateLinkReq extends Request {
  39. body: {
  40. reuse?: boolean;
  41. password?: string;
  42. customurl?: string;
  43. domain?: Domain;
  44. target: string;
  45. };
  46. }
  47. export const createLink: Handler = async (req: CreateLinkReq, res) => {
  48. const { reuse, password, customurl, target, domain } = req.body;
  49. const domainId = domain ? domain.id : null;
  50. const domainAddress = domain ? domain.address : null;
  51. try {
  52. const targetDomain = URL.parse(target).hostname;
  53. const queries = await Promise.all([
  54. process.env.GOOGLE_SAFE_BROWSING_KEY && cooldownCheck(req.user),
  55. process.env.GOOGLE_SAFE_BROWSING_KEY && malwareCheck(req.user, target),
  56. req.user && urlCountsCheck(req.user),
  57. reuse &&
  58. findLinkQuery({
  59. target,
  60. userId: req.user.id,
  61. domainId
  62. }),
  63. customurl &&
  64. findLinkQuery({
  65. address: customurl,
  66. domainId
  67. }),
  68. !customurl && generateId(domainId),
  69. checkBannedDomain(targetDomain),
  70. checkBannedHost(targetDomain)
  71. ]);
  72. // if "reuse" is true, try to return
  73. // the existent URL without creating one
  74. if (queries[3]) {
  75. const { domain_id: d, user_id: u, ...currentLink } = queries[3];
  76. const link = generateShortLink(currentLink.address, req.user.domain);
  77. const data = {
  78. ...currentLink,
  79. id: currentLink.uuid,
  80. password: !!currentLink.password,
  81. link
  82. };
  83. return res.json(data);
  84. }
  85. // Check if custom link already exists
  86. if (queries[4]) {
  87. throw new CustomError("Custom URL is already in use.");
  88. }
  89. // Create new link
  90. const address = customurl || queries[5];
  91. const link = await createLinkQuery({
  92. password,
  93. address,
  94. domainAddress,
  95. domainId,
  96. target,
  97. userId: req.user && req.user.id
  98. });
  99. if (!req.user && Number(process.env.NON_USER_COOLDOWN)) {
  100. addIP(req.realIP);
  101. }
  102. return res.json({ ...link, id: link.uuid });
  103. } catch (error) {
  104. return res.status(400).json({ error: error.message });
  105. }
  106. };