Ver Fonte

Add homepage field and handler for custom domains

poeti8 há 7 anos atrás
pai
commit
b577b22300

+ 5 - 1
server/controllers/authController.js

@@ -170,7 +170,11 @@ exports.generateApiKey = async ({ user }, res) => {
 };
 
 exports.userSettings = ({ user }, res) =>
-  res.status(200).json({ apikey: user.apikey || '', customDomain: user.domain || '' });
+  res.status(200).json({
+    apikey: user.apikey || '',
+    customDomain: user.domain || '',
+    homepage: user.homepage || '',
+  });
 
 exports.requestPasswordReset = async ({ body: { email } }, res) => {
   const user = await requestPasswordReset({ email });

+ 31 - 7
server/controllers/urlController.js

@@ -25,6 +25,7 @@ const {
   getBannedDomain,
   getBannedHost,
 } = require('../db/url');
+const { preservedUrls } = require('./validateBodyController');
 const transporter = require('../mail/mail');
 const redis = require('../redis');
 const { addProtocol, generateShortUrl, getStatsCacheTime } = require('../utils');
@@ -211,23 +212,33 @@ exports.getUrls = async ({ query, user }, res) => {
   return res.json({ list, countAll });
 };
 
-exports.setCustomDomain = async ({ body: { customDomain }, user }, res) => {
+exports.setCustomDomain = async ({ body, user }, res) => {
+  const parsed = URL.parse(body.customDomain);
+  const customDomain = parsed.hostname || parsed.href;
+  if (!customDomain) return res.status(400).json({ error: 'Domain is not valid.' });
   if (customDomain.length > 40) {
     return res.status(400).json({ error: 'Maximum custom domain length is 40.' });
   }
   if (customDomain === config.DEFAULT_DOMAIN) {
     return res.status(400).json({ error: "You can't use default domain." });
   }
-  const isValidDomain = urlRegex({ exact: true, strict: false }).test(customDomain);
-  if (!isValidDomain) return res.status(400).json({ error: 'Domain is not valid.' });
-  const isOwned = await getCustomDomain({ customDomain });
-  if (isOwned && isOwned.email !== user.email) {
+  const isValidHomepage =
+    !body.homepage || urlRegex({ exact: true, strict: false }).test(body.homepage);
+  if (!isValidHomepage) return res.status(400).json({ error: 'Homepage is not valid.' });
+  const homepage =
+    body.homepage &&
+    (URL.parse(body.homepage).protocol ? body.homepage : `http://${body.homepage}`);
+  const { email } = await getCustomDomain({ customDomain });
+  if (email !== user.email) {
     return res
       .status(400)
       .json({ error: 'Domain is already taken. Contact us for multiple users.' });
   }
-  const userCustomDomain = await setCustomDomain({ user, customDomain });
-  if (userCustomDomain) return res.status(201).json({ customDomain: userCustomDomain.name });
+  const userCustomDomain = await setCustomDomain({ user, customDomain, homepage });
+  if (userCustomDomain)
+    return res
+      .status(201)
+      .json({ customDomain: userCustomDomain.name, homepage: userCustomDomain.homepage });
   return res.status(400).json({ error: "Couldn't set custom domain." });
 };
 
@@ -237,6 +248,19 @@ exports.deleteCustomDomain = async ({ user }, res) => {
   return res.status(400).json({ error: "Couldn't delete custom domain." });
 };
 
+exports.customDomainRedirection = async (req, res, next) => {
+  const { headers, path } = req;
+  if (
+    headers.host !== config.DEFAULT_DOMAIN &&
+    (path === '/' ||
+      preservedUrls.filter(u => u !== 'url-password').some(item => item === path.replace('/', '')))
+  ) {
+    const { homepage } = await getCustomDomain({ customDomain: headers.host });
+    return res.redirect(301, homepage || `http://${config.DEFAULT_DOMAIN + path}`);
+  }
+  return next();
+};
+
 exports.deleteUrl = async ({ body: { id, domain }, user }, res) => {
   if (!id) return res.status(400).json({ error: 'No id has been provided.' });
   const customDomain = domain !== config.DEFAULT_DOMAIN && domain;

+ 15 - 6
server/db/url.js

@@ -197,19 +197,27 @@ exports.getCustomDomain = ({ customDomain }) =>
     const session = driver.session();
     session
       .readTransaction(tx =>
-        tx.run('MATCH (d:DOMAIN { name: $customDomain })<-[:OWNS]-(u) RETURN u', {
-          customDomain,
-        })
+        tx.run(
+          'MATCH (d:DOMAIN { name: $customDomain })<-[:OWNS]-(u) RETURN u.email as email, d.homepage as homepage',
+          {
+            customDomain,
+          }
+        )
       )
       .then(({ records }) => {
         session.close();
-        const data = records.length && records[0].get('u').properties;
+        const data = records.length
+          ? {
+              email: records[0].get('email'),
+              homepage: records[0].get('homepage'),
+            }
+          : {};
         resolve(data);
       })
       .catch(err => session.close() || reject(err));
   });
 
-exports.setCustomDomain = ({ user, customDomain }) =>
+exports.setCustomDomain = ({ user, customDomain, homepage }) =>
   new Promise((resolve, reject) => {
     const session = driver.session();
     session
@@ -217,10 +225,11 @@ exports.setCustomDomain = ({ user, customDomain }) =>
         tx.run(
           'MATCH (u:USER { email: $email }) ' +
             'OPTIONAL MATCH (u)-[r:OWNS]->() DELETE r ' +
-            'MERGE (d:DOMAIN { name: $customDomain }) ' +
+            `MERGE (d:DOMAIN { name: $customDomain, homepage: $homepage }) ` +
             'MERGE (u)-[:OWNS]->(d) RETURN u, d',
           {
             customDomain,
+            homepage: homepage || '',
             email: user.email,
           }
         )

+ 2 - 1
server/db/user.js

@@ -21,7 +21,8 @@ exports.getUser = ({ email = '', apikey = '' }) =>
         const user = res.records.length && res.records[0].get('u').properties;
         const domainProps = res.records.length && res.records[0].get('l');
         const domain = domainProps ? domainProps.properties.name : '';
-        return resolve(user && { ...user, domain });
+        const homepage = domainProps ? domainProps.properties.homepage : '';
+        return resolve(user && { ...user, domain, homepage });
       })
       .catch(err => reject(err));
   });

+ 1 - 11
server/server.js

@@ -10,7 +10,6 @@ const cors = require('cors');
 const {
   validateBody,
   validationCriterias,
-  preservedUrls,
   validateUrl,
   cooldownCheck,
   malwareCheck,
@@ -60,16 +59,7 @@ app.prepare().then(() => {
     return next();
   });
 
-  server.use((req, res, next) => {
-    const { headers, path } = req;
-    if (
-      headers.host !== config.DEFAULT_DOMAIN &&
-      (path === '/' || preservedUrls.some(item => item === path.replace('/', '')))
-    ) {
-      return res.redirect(`http://${config.DEFAULT_DOMAIN + path}`);
-    }
-    return next();
-  });
+  server.use(url.customDomainRedirection);
 
   /* View routes */
   server.get('/', (req, res) => app.render(req, res, '/'));