links.ts 2.9 KB

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