Browse Source

fix: remove www when checking and adding domains

poeti8 5 years ago
parent
commit
5e42185df5

+ 16 - 10
server/__v1/controllers/linkController.ts

@@ -21,7 +21,12 @@ import {
 } from "../db/link";
 import transporter from "../../mail/mail";
 import * as redis from "../../redis";
-import { addProtocol, generateShortLink, getStatsCacheTime } from "../../utils";
+import {
+  addProtocol,
+  generateShortLink,
+  getStatsCacheTime,
+  removeWww
+} from "../../utils";
 import {
   checkBannedDomain,
   checkBannedHost,
@@ -47,7 +52,7 @@ const generateId = async () => {
 export const shortener: Handler = async (req, res) => {
   try {
     const target = addProtocol(req.body.target);
-    const targetDomain = URL.parse(target).hostname;
+    const targetDomain = removeWww(URL.parse(target).hostname);
 
     const queries = await Promise.all([
       env.GOOGLE_SAFE_BROWSING_KEY && cooldownCheck(req.user),
@@ -112,7 +117,7 @@ export const shortener: Handler = async (req, res) => {
 };
 
 export const goToLink: Handler = async (req, res, next) => {
-  const { host } = req.headers;
+  const host = removeWww(req.headers.host);
   const reqestedId = req.params.id || req.body.id;
   const address = reqestedId.replace("+", "");
   const customDomain = host !== env.DEFAULT_DOMAIN && host;
@@ -202,7 +207,7 @@ export const getUserLinks: Handler = async (req, res) => {
 
 export const setCustomDomain: Handler = async (req, res) => {
   const parsed = URL.parse(req.body.customDomain);
-  const customDomain = parsed.hostname || parsed.href;
+  const customDomain = removeWww(parsed.hostname || parsed.href);
   if (!customDomain)
     return res.status(400).json({ error: "Domain is not valid." });
   if (customDomain.length > 40) {
@@ -258,15 +263,16 @@ export const deleteCustomDomain: Handler = async (req, res) => {
 };
 
 export const customDomainRedirection: Handler = async (req, res, next) => {
-  const { headers, path } = req;
+  const { path } = req;
+  const host = removeWww(req.headers.host);
   if (
-    headers.host !== env.DEFAULT_DOMAIN &&
+    host !== env.DEFAULT_DOMAIN &&
     (path === "/" ||
       preservedUrls
         .filter(l => l !== "url-password")
         .some(item => item === path.replace("/", "")))
   ) {
-    const domain = await getDomain({ address: headers.host });
+    const domain = await getDomain({ address: host });
     return res.redirect(
       301,
       (domain && domain.homepage) || `https://${env.DEFAULT_DOMAIN + path}`
@@ -300,7 +306,7 @@ export const getLinkStats: Handler = async (req, res) => {
     return res.status(400).json({ error: "No id has been provided." });
   }
 
-  const { hostname } = URL.parse(req.query.domain);
+  const hostname = removeWww(URL.parse(req.query.domain).hostname);
   const hasCustomDomain = req.query.domain && hostname !== env.DEFAULT_DOMAIN;
   const customDomain = hasCustomDomain
     ? (await getDomain({ address: req.query.domain })) || ({ id: -1 } as Domain)
@@ -338,7 +344,7 @@ export const reportLink: Handler = async (req, res) => {
     return res.status(400).json({ error: "No URL has been provided." });
   }
 
-  const { hostname } = URL.parse(req.body.link);
+  const hostname = removeWww(URL.parse(req.body.link).hostname);
   if (hostname !== env.DEFAULT_DOMAIN) {
     return res.status(400).json({
       error: `You can only report a ${env.DEFAULT_DOMAIN} link`
@@ -374,7 +380,7 @@ export const ban: Handler = async (req, res) => {
     return res.status(200).json({ message: "Link was banned already." });
   }
 
-  const domain = URL.parse(link.target).hostname;
+  const domain = removeWww(URL.parse(link.target).hostname);
 
   let host;
   if (req.body.host) {

+ 2 - 2
server/__v1/controllers/validateBodyController.ts

@@ -8,7 +8,7 @@ import axios from "axios";
 import dns from "dns";
 import URL from "url";
 
-import { addProtocol, CustomError } from "../../utils";
+import { addProtocol, CustomError, removeWww } from "../../utils";
 import { addCooldown, banUser } from "../db/user";
 import { getUserLinksCount } from "../db/link";
 import { getDomain } from "../db/domain";
@@ -83,7 +83,7 @@ export const validateUrl: RequestHandler = async (req, res, next) => {
     return res.status(400).json({ error: "URL is not valid." });
 
   // If target is the URL shortener itself
-  const { host } = URL.parse(addProtocol(req.body.target));
+  const host = removeWww(URL.parse(addProtocol(req.body.target)).host);
   if (host === env.DEFAULT_DOMAIN) {
     return res
       .status(400)

+ 6 - 8
server/handlers/links.ts

@@ -53,7 +53,7 @@ export const create: Handler = async (req: CreateLinkReq, res) => {
   } = req.body;
   const domain_id = domain ? domain.id : null;
 
-  const targetDomain = URL.parse(target).hostname;
+  const targetDomain = utils.removeWww(URL.parse(target).hostname);
 
   const queries = await Promise.all([
     validators.cooldown(req.user),
@@ -123,7 +123,7 @@ export const edit: Handler = async (req, res) => {
     throw new CustomError("Link was not found.");
   }
 
-  const targetDomain = URL.parse(target).hostname;
+  const targetDomain = utils.removeWww(URL.parse(target).hostname);
   const domain_id = link.domain_id || null;
 
   const queries = await Promise.all([
@@ -218,7 +218,7 @@ export const ban: Handler = async (req, res) => {
   // 2. Ban link
   tasks.push(query.link.update({ uuid: id }, update));
 
-  const domain = URL.parse(link.target).hostname;
+  const domain = utils.removeWww(URL.parse(link.target).hostname);
 
   // 3. Ban target's domain
   if (req.body.domain) {
@@ -266,7 +266,7 @@ export const redirect = (app: ReturnType<typeof next>): Handler => async (
   if (isPreservedUrl) return next();
 
   // 1. If custom domain, get domain info
-  const { host } = req.headers;
+  const host = utils.removeWww(req.headers.host);
   const domain =
     host !== env.DEFAULT_DOMAIN
       ? await query.domain.find({ address: host })
@@ -371,10 +371,8 @@ export const redirectProtected: Handler = async (req, res) => {
 };
 
 export const redirectCustomDomain: Handler = async (req, res, next) => {
-  const {
-    headers: { host },
-    path
-  } = req;
+  const { path } = req;
+  const host = utils.removeWww(req.headers.host);
 
   if (host === env.DEFAULT_DOMAIN) {
     return next();

+ 8 - 6
server/handlers/validators.ts

@@ -8,7 +8,7 @@ import dns from "dns";
 import URL from "url";
 import ms from "ms";
 
-import { CustomError, addProtocol } from "../utils";
+import { CustomError, addProtocol, removeWww } from "../utils";
 import query from "../queries";
 import knex from "../knex";
 import env from "../env";
@@ -55,7 +55,7 @@ export const createLink = [
         /^(?!https?)(\w+):\/\//.test(value)
     )
     .withMessage("URL is not valid.")
-    .custom(value => URL.parse(value).host !== env.DEFAULT_DOMAIN)
+    .custom(value => removeWww(URL.parse(value).host) !== env.DEFAULT_DOMAIN)
     .withMessage(`${env.DEFAULT_DOMAIN} URLs are not allowed.`),
   body("password")
     .optional({ nullable: true, checkFalsy: true })
@@ -111,7 +111,7 @@ export const createLink = [
     .isString()
     .withMessage("Domain should be string.")
     .customSanitizer(value => value.toLowerCase())
-    .customSanitizer(value => URL.parse(value).hostname || value)
+    .customSanitizer(value => removeWww(URL.parse(value).hostname || value))
     .custom(async (address, { req }) => {
       if (address === env.DEFAULT_DOMAIN) {
         req.body.domain = null;
@@ -143,7 +143,7 @@ export const editLink = [
         /^(?!https?)(\w+):\/\//.test(value)
     )
     .withMessage("URL is not valid.")
-    .custom(value => URL.parse(value).host !== env.DEFAULT_DOMAIN)
+    .custom(value => removeWww(URL.parse(value).host) !== env.DEFAULT_DOMAIN)
     .withMessage(`${env.DEFAULT_DOMAIN} URLs are not allowed.`),
   body("address")
     .optional({ checkFalsy: true, nullable: true })
@@ -201,7 +201,7 @@ export const addDomain = [
     .trim()
     .customSanitizer(value => {
       const parsed = URL.parse(value);
-      return parsed.hostname || parsed.href;
+      return removeWww(parsed.hostname || parsed.href);
     })
     .custom(value => urlRegex({ exact: true, strict: false }).test(value))
     .custom(value => value !== env.DEFAULT_DOMAIN)
@@ -243,7 +243,9 @@ export const reportLink = [
       checkNull: true
     })
     .customSanitizer(addProtocol)
-    .custom(value => URL.parse(value).hostname === env.DEFAULT_DOMAIN)
+    .custom(
+      value => removeWww(URL.parse(value).hostname) === env.DEFAULT_DOMAIN
+    )
     .withMessage(`You can only report a ${env.DEFAULT_DOMAIN} link.`)
 ];
 

+ 3 - 2
server/queues/visit.ts

@@ -3,7 +3,7 @@ import geoip from "geoip-lite";
 import URL from "url";
 
 import query from "../queries";
-import { getStatsLimit } from "../utils";
+import { getStatsLimit, removeWww } from "../utils";
 
 const browsersList = ["IE", "Firefox", "Chrome", "Opera", "Safari", "Edge"];
 const osList = ["Windows", "Mac OS", "Linux", "Android", "iOS"];
@@ -21,7 +21,8 @@ export default function({ data }) {
     const agent = useragent.parse(data.headers["user-agent"]);
     const [browser = "Other"] = browsersList.filter(filterInBrowser(agent));
     const [os = "Other"] = osList.filter(filterInOs(agent));
-    const referrer = data.referrer && URL.parse(data.referrer).hostname;
+    const referrer =
+      data.referrer && removeWww(URL.parse(data.referrer).hostname);
     const location = geoip.lookup(data.realIP);
     const country = location && location.country;
     tasks.push(

+ 4 - 0
server/utils/index.ts

@@ -164,3 +164,7 @@ export const sanitize = {
     link: generateShortLink(link.address, link.domain)
   })
 };
+
+export const removeWww = (host = "") => {
+  return host.replace("www.", "");
+};