Przeglądaj źródła

Append + to a short URl to get info without redirecting. Closes #42

Pouria Ezzati 7 lat temu
rodzic
commit
8d1557040a
3 zmienionych plików z 91 dodań i 4 usunięć
  1. 73 0
      client/pages/url-info.js
  2. 9 1
      server/controllers/urlController.js
  3. 9 3
      server/server.js

+ 73 - 0
client/pages/url-info.js

@@ -0,0 +1,73 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import styled from 'styled-components';
+import withRedux from 'next-redux-wrapper';
+import initialState from '../store';
+import BodyWrapper from '../components/BodyWrapper';
+import Footer from '../components/Footer';
+import { authUser } from '../actions';
+
+const Wrapper = styled.div`
+  display: flex;
+  flex: 1 1 100%;
+  flex-direction: column;
+  align-items: cetner;
+`;
+
+const Title = styled.h3`
+  font-size: 28px;
+  font-weight: 300;
+  text-align: center;
+  margin: 24px 0;
+
+  @media only screen and (max-width: 448px) {
+    font-size: 18px;
+  }
+`;
+
+const Target = styled.h3`
+  font-size: 18px;
+  text-align: center;
+
+  @media only screen and (max-width: 448px) {
+    font-size: 16px;
+  }
+`;
+
+class UrlInfoPage extends Component {
+  static getInitialProps({ query, req, store }) {
+    const token = req && req.cookies && req.cookies.token;
+    if (token && store) store.dispatch(authUser(token));
+    return { query };
+  }
+
+  render() {
+    if (!this.props.query) {
+      return (
+        <BodyWrapper>
+          <Title>404 | Not found.</Title>
+        </BodyWrapper>
+      );
+    }
+
+    return (
+      <BodyWrapper>
+        <Wrapper>
+          <Title>Target:</Title>
+          <Target>{this.props.query}</Target>
+        </Wrapper>
+        <Footer />
+      </BodyWrapper>
+    );
+  }
+}
+
+UrlInfoPage.propTypes = {
+  query: PropTypes.string,
+};
+
+UrlInfoPage.defaultProps = {
+  query: null,
+};
+
+export default withRedux(initialState)(UrlInfoPage);

+ 9 - 1
server/controllers/urlController.js

@@ -89,7 +89,8 @@ const filterInOs = agent => item =>
 
 exports.goToUrl = async (req, res, next) => {
   const { host } = req.headers;
-  const id = req.params.id || req.body.id;
+  const reqestedId = req.params.id || req.body.id;
+  const id = reqestedId.replace('+', '');
   const domain = host !== config.DEFAULT_DOMAIN && host;
   const agent = useragent.parse(req.headers['user-agent']);
   const [browser = 'Other'] = browsersList.filter(filterInBrowser(agent));
@@ -102,8 +103,15 @@ exports.goToUrl = async (req, res, next) => {
     botList.some(bot => agent.source.toLowerCase().includes(bot)) || agent.family === 'Other';
   if (!urls && !urls.length) return next();
   const url = urls.find(item => (domain ? item.domain === domain : !item.domain));
+  const doesRequestInfo = /.*\+$/gi.test(reqestedId);
+  if (doesRequestInfo && !url.password) {
+    req.urlTarget = url.target;
+    req.pageType = 'info';
+    return next();
+  }
   if (url.password && !req.body.password) {
     req.protectedUrl = id;
+    req.pageType = 'password';
     return next();
   }
   if (url.password) {

+ 9 - 3
server/server.js

@@ -111,9 +111,15 @@ app.prepare().then(() => {
   server.delete('/api/url/customdomain', auth.authJwt, catchErrors(url.deleteCustomDomain));
   server.get('/api/url/stats', auth.authApikey, auth.authJwt, catchErrors(url.getStats));
   server.post('/api/url/requesturl', catchErrors(url.goToUrl));
-  server.get('/:id', catchErrors(url.goToUrl), (req, res) =>
-    app.render(req, res, '/url-password', req.protectedUrl)
-  );
+  server.get('/:id', catchErrors(url.goToUrl), (req, res) => {
+    switch (req.pageType) {
+      case 'password':
+        return app.render(req, res, '/url-password', req.protectedUrl);
+      case 'info':
+      default:
+        return app.render(req, res, '/url-info', req.urlTarget);
+    }
+  });
 
   server.get('*', (req, res) => handle(req, res));