소스 검색

Replace config with .env

poeti8 6 년 전
부모
커밋
8b594a006c

+ 0 - 1
.env

@@ -1 +0,0 @@
-TEST=test

+ 55 - 0
.example.env

@@ -0,0 +1,55 @@
+# App port to run on
+PORT=3000
+
+# The domain that this website is on
+DEFAULT_DOMAIN="kutt.it"
+
+# Neo4j database credential details
+DB_URI="bolt://localhost"
+DB_USERNAME=
+DB_PASSWORD=
+
+# Redis host and port
+REDIS_DISABLED=false
+REDIS_HOST="127.0.0.1"
+REDIS_PORT=6379
+REDIS_PASSWORD=
+
+# The daily limit for each user
+USER_LIMIT_PER_DAY=50
+
+# A passphrase to encrypt JWT. Use a long and secure key.
+JWT_SECRET=securekey
+
+# Admin emails so they can access admin actions on settings page
+# Comma seperated
+ADMIN_EMAILS=
+
+# Invisible reCaptcha secret key
+# Create one in https://www.google.com/recaptcha/intro/
+RECAPTCHA_SITE_KEY=6LdVeUYUAAAAAAPX2XAH71soH8xVPrMjpIR3pE8f
+RECAPTCHA_SECRET_KEY=
+
+# Google Cloud API to prevent from users from submitting malware URLs.
+# Get it from https://developers.google.com/safe-browsing/v4/get-started
+GOOGLE_SAFE_BROWSING_KEY=
+
+# Google Analytics tracking ID for universal analytics.
+# Example: UA-XXXX-XX
+GOOGLE_ANALYTICS=
+
+# Your email host details to use to send verification emails.
+# More info on http://nodemailer.com/
+# Mail from example "Kutt <support@kutt.it>". Leave empty to use MAIL_USER
+MAIL_HOST=
+MAIL_PORT=587
+MAIL_SECURE=
+MAIL_USER=
+MAIL_FROM=
+MAIL_PASSWORD=
+
+# The email address that will receive submitted reports.
+REPORT_MAIL=
+
+# Support email to show on the app
+CONTACT_EMAIL=

+ 1 - 0
.gitignore

@@ -1,3 +1,4 @@
+.env
 .vscode/
 .vscode/
 client/.next/
 client/.next/
 node_modules/
 node_modules/

+ 1 - 2
client/components/BodyWrapper/BodyWrapper.js

@@ -8,7 +8,6 @@ import Header from '../Header';
 import PageLoading from '../PageLoading';
 import PageLoading from '../PageLoading';
 import { renewAuthUser, hidePageLoading } from '../../actions';
 import { renewAuthUser, hidePageLoading } from '../../actions';
 import { initGA, logPageView } from '../../helpers/analytics';
 import { initGA, logPageView } from '../../helpers/analytics';
-import { GOOGLE_ANALYTICS_ID } from '../../config';
 
 
 const Wrapper = styled.div`
 const Wrapper = styled.div`
   position: relative;
   position: relative;
@@ -43,7 +42,7 @@ const ContentWrapper = styled.div`
 
 
 class BodyWrapper extends React.Component {
 class BodyWrapper extends React.Component {
   componentDidMount() {
   componentDidMount() {
-    if (GOOGLE_ANALYTICS_ID) {
+    if (process.env.GOOGLE_ANALYTICS_ID) {
       if (!window.GA_INITIALIZED) {
       if (!window.GA_INITIALIZED) {
         initGA();
         initGA();
         window.GA_INITIALIZED = true;
         window.GA_INITIALIZED = true;

+ 2 - 3
client/components/Footer/Footer.js

@@ -4,7 +4,6 @@ import { connect } from 'react-redux';
 import styled from 'styled-components';
 import styled from 'styled-components';
 import ReCaptcha from './ReCaptcha';
 import ReCaptcha from './ReCaptcha';
 import showRecaptcha from '../../helpers/recaptcha';
 import showRecaptcha from '../../helpers/recaptcha';
-import config from '../../config';
 
 
 const Wrapper = styled.footer`
 const Wrapper = styled.footer`
   width: 100%;
   width: 100%;
@@ -61,10 +60,10 @@ class Footer extends Component {
           <a href="/report" title="Report abuse">
           <a href="/report" title="Report abuse">
             Report Abuse
             Report Abuse
           </a>
           </a>
-          {config.CONTACT_EMAIL && (
+          {process.env.CONTACT_EMAIL && (
             <Fragment>
             <Fragment>
               {' | '}
               {' | '}
-              <a href={`mailto:${config.CONTACT_EMAIL}`} title="Contact us">
+              <a href={`mailto:${process.env.CONTACT_EMAIL}`} title="Contact us">
                 Contact us
                 Contact us
               </a>
               </a>
             </Fragment>
             </Fragment>

+ 1 - 2
client/components/Footer/ReCaptcha.js

@@ -1,6 +1,5 @@
 import React from 'react';
 import React from 'react';
 import styled from 'styled-components';
 import styled from 'styled-components';
-import config from '../../config';
 
 
 const Recaptcha = styled.div`
 const Recaptcha = styled.div`
   display: flex;
   display: flex;
@@ -11,7 +10,7 @@ const ReCaptcha = () => (
   <Recaptcha
   <Recaptcha
     id="g-recaptcha"
     id="g-recaptcha"
     className="g-recaptcha"
     className="g-recaptcha"
-    data-sitekey={config.RECAPTCHA_SITE_KEY}
+    data-sitekey={process.env.RECAPTCHA_SITE_KEY}
     data-callback="recaptchaCallback"
     data-callback="recaptchaCallback"
     data-size="invisible"
     data-size="invisible"
     data-badge="inline"
     data-badge="inline"

+ 0 - 16
client/config.example.js

@@ -1,16 +0,0 @@
-module.exports = {
-  /*
-    Invisible reCaptcha site key
-    Create one in https://www.google.com/recaptcha/intro/
-  */
-  RECAPTCHA_SITE_KEY: '',
-
-  // Google analytics tracking ID
-  GOOGLE_ANALYTICS_ID: '',
-
-  // Contact email address
-  CONTACT_EMAIL: '',
-
-  // Report email address
-  REPORT_EMAIL: '',
-};

+ 1 - 2
client/helpers/analytics.js

@@ -1,8 +1,7 @@
 import ReactGA from 'react-ga';
 import ReactGA from 'react-ga';
-import { GOOGLE_ANALYTICS_ID } from '../config';
 
 
 export const initGA = () => {
 export const initGA = () => {
-  ReactGA.initialize(GOOGLE_ANALYTICS_ID);
+  ReactGA.initialize(process.env.GOOGLE_ANALYTICS_ID);
 };
 };
 
 
 export const logPageView = () => {
 export const logPageView = () => {

+ 1 - 2
client/pages/report.js

@@ -3,7 +3,6 @@ import styled from 'styled-components';
 import axios from 'axios';
 import axios from 'axios';
 import BodyWrapper from '../components/BodyWrapper';
 import BodyWrapper from '../components/BodyWrapper';
 import { authUser } from '../actions';
 import { authUser } from '../actions';
-import { REPORT_EMAIL } from '../config';
 import TextInput from '../components/TextInput';
 import TextInput from '../components/TextInput';
 import Button from '../components/Button';
 import Button from '../components/Button';
 
 
@@ -98,7 +97,7 @@ class ReportPage extends Component {
             Report abuses, malware and phishing links to the below email address or use the form. We
             Report abuses, malware and phishing links to the below email address or use the form. We
             will take actions shortly.
             will take actions shortly.
           </p>
           </p>
-          <p>{REPORT_EMAIL}</p>
+          <p>{process.env.REPORT_EMAIL}</p>
           <p>
           <p>
             <b>URL containting malware/scam:</b>
             <b>URL containting malware/scam:</b>
           </p>
           </p>

+ 10 - 0
next.config.js

@@ -0,0 +1,10 @@
+const { parsed: localEnv } = require('dotenv').config();
+const webpack = require('webpack'); // eslint-disable-line
+
+module.exports = {
+  webpack(config) {
+    config.plugins.push(new webpack.EnvironmentPlugin(localEnv));
+
+    return config;
+  },
+};

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 211 - 504
package-lock.json


+ 1 - 0
package.json

@@ -36,6 +36,7 @@
     "cookie-parser": "^1.4.4",
     "cookie-parser": "^1.4.4",
     "cors": "^2.8.5",
     "cors": "^2.8.5",
     "date-fns": "^1.30.1",
     "date-fns": "^1.30.1",
+    "dotenv": "^8.0.0",
     "email-validator": "^1.2.3",
     "email-validator": "^1.2.3",
     "express": "^4.16.4",
     "express": "^4.16.4",
     "express-validator": "^4.3.0",
     "express-validator": "^4.3.0",

+ 0 - 63
server/config.example.js

@@ -1,63 +0,0 @@
-module.exports = {
-  PORT: 3000,
-
-  /* The domain that this website is on */
-  DEFAULT_DOMAIN: 'kutt.it',
-
-  /* Neo4j database credential details */
-  DB_URI: 'bolt://localhost',
-  DB_USERNAME: '',
-  DB_PASSWORD: '',
-
-  /* Redis host and port */
-  REDIS_DISABLED: false,
-  REDIS_HOST: '127.0.0.1',
-  REDIS_PORT: 6379,
-  REDIS_PASSWORD: '',
-
-  /* The daily limit for each user */
-  USER_LIMIT_PER_DAY: 50,
-
-  /* A passphrase to encrypt JWT. Use a long and secure key. */
-  JWT_SECRET: 'securekey',
-
-  /*
-    Admin emails so they can access admin actions on settings page
-    Array of strings
-  */
-  ADMIN_EMAILS: [],
-
-  /*
-    Invisible reCaptcha secret key
-    Create one in https://www.google.com/recaptcha/intro/
-  */
-  RECAPTCHA_SECRET_KEY: '',
-
-  /* 
-    Google Cloud API to prevent from users from submitting malware URLs.
-    Get it from https://developers.google.com/safe-browsing/v4/get-started
-  */
-  GOOGLE_SAFE_BROWSING_KEY: '',
-
-  /* 
-    Google Analytics tracking ID for universal analytics.
-    Example: UA-XXXX-XX
-  */
-  GOOGLE_ANALYTICS: '',
-
-  /*
-    Your email host details to use to send verification emails.
-    More info on http://nodemailer.com/
-  */
-  MAIL_HOST: '',
-  MAIL_PORT: 587,
-  MAIL_SECURE: false,
-  MAIL_USER: '',
-  MAIL_FROM: '', // Example: "Kutt <support@kutt.it>". Leave empty to use MAIL_USER
-  MAIL_PASSWORD: '',
-
-  /*
-    The email address that will receive submitted reports.
-  */
-  REPORT_MAIL: '',
-};

+ 8 - 9
server/controllers/authController.js

@@ -3,7 +3,6 @@ const path = require('path');
 const passport = require('passport');
 const passport = require('passport');
 const JWT = require('jsonwebtoken');
 const JWT = require('jsonwebtoken');
 const axios = require('axios');
 const axios = require('axios');
-const config = require('../config');
 const { isAdmin } = require('../utils');
 const { isAdmin } = require('../utils');
 const transporter = require('../mail/mail');
 const transporter = require('../mail/mail');
 const { resetMailText, verifyMailText } = require('../mail/text');
 const { resetMailText, verifyMailText } = require('../mail/text');
@@ -22,10 +21,10 @@ const resetEmailTemplatePath = path.join(__dirname, '../mail/template-reset.html
 const verifyEmailTemplatePath = path.join(__dirname, '../mail/template-verify.html');
 const verifyEmailTemplatePath = path.join(__dirname, '../mail/template-verify.html');
 const resetEmailTemplate = fs
 const resetEmailTemplate = fs
   .readFileSync(resetEmailTemplatePath, { encoding: 'utf-8' })
   .readFileSync(resetEmailTemplatePath, { encoding: 'utf-8' })
-  .replace(/{{domain}}/gm, config.DEFAULT_DOMAIN);
+  .replace(/{{domain}}/gm, process.env.DEFAULT_DOMAIN);
 const verifyEmailTemplate = fs
 const verifyEmailTemplate = fs
   .readFileSync(verifyEmailTemplatePath, { encoding: 'utf-8' })
   .readFileSync(verifyEmailTemplatePath, { encoding: 'utf-8' })
-  .replace(/{{domain}}/gm, config.DEFAULT_DOMAIN);
+  .replace(/{{domain}}/gm, process.env.DEFAULT_DOMAIN);
 
 
 /* Function to generate JWT */
 /* Function to generate JWT */
 const signToken = user =>
 const signToken = user =>
@@ -38,7 +37,7 @@ const signToken = user =>
       iat: new Date().getTime(),
       iat: new Date().getTime(),
       exp: new Date().setDate(new Date().getDate() + 7),
       exp: new Date().setDate(new Date().getDate() + 7),
     },
     },
-    config.JWT_SECRET
+    process.env.JWT_SECRET
   );
   );
 
 
 /* Passport.js authentication controller */
 /* Passport.js authentication controller */
@@ -84,7 +83,7 @@ exports.recaptcha = async (req, res, next) => {
         'Content-type': 'application/x-www-form-urlencoded',
         'Content-type': 'application/x-www-form-urlencoded',
       },
       },
       params: {
       params: {
-        secret: config.RECAPTCHA_SECRET_KEY,
+        secret: process.env.RECAPTCHA_SECRET_KEY,
         response: req.body.reCaptchaToken,
         response: req.body.reCaptchaToken,
         remoteip: req.realIp,
         remoteip: req.realIp,
       },
       },
@@ -115,7 +114,7 @@ exports.signup = async (req, res) => {
   if (user && user.verified) return res.status(403).json({ error: 'Email is already in use.' });
   if (user && user.verified) return res.status(403).json({ error: 'Email is already in use.' });
   const newUser = await createUser({ email, password });
   const newUser = await createUser({ email, password });
   const mail = await transporter.sendMail({
   const mail = await transporter.sendMail({
-    from: config.MAIL_FROM || config.MAIL_USER,
+    from: process.env.MAIL_FROM || process.env.MAIL_USER,
     to: newUser.email,
     to: newUser.email,
     subject: 'Verify your account',
     subject: 'Verify your account',
     text: verifyMailText.replace(/{{verification}}/gim, newUser.verificationToken),
     text: verifyMailText.replace(/{{verification}}/gim, newUser.verificationToken),
@@ -183,15 +182,15 @@ exports.requestPasswordReset = async ({ body: { email } }, res) => {
     return res.status(400).json({ error: "Couldn't reset password." });
     return res.status(400).json({ error: "Couldn't reset password." });
   }
   }
   const mail = await transporter.sendMail({
   const mail = await transporter.sendMail({
-    from: config.MAIL_USER,
+    from: process.env.MAIL_USER,
     to: user.email,
     to: user.email,
     subject: 'Reset your password',
     subject: 'Reset your password',
     text: resetMailText
     text: resetMailText
       .replace(/{{resetpassword}}/gm, user.resetPasswordToken)
       .replace(/{{resetpassword}}/gm, user.resetPasswordToken)
-      .replace(/{{domain}}/gm, config.DEFAULT_DOMAIN),
+      .replace(/{{domain}}/gm, process.env.DEFAULT_DOMAIN),
     html: resetEmailTemplate
     html: resetEmailTemplate
       .replace(/{{resetpassword}}/gm, user.resetPasswordToken)
       .replace(/{{resetpassword}}/gm, user.resetPasswordToken)
-      .replace(/{{domain}}/gm, config.DEFAULT_DOMAIN),
+      .replace(/{{domain}}/gm, process.env.DEFAULT_DOMAIN),
   });
   });
   if (mail.accepted.length) {
   if (mail.accepted.length) {
     return res.status(200).json({ email, message: 'Reset password email has been sent.' });
     return res.status(200).json({ email, message: 'Reset password email has been sent.' });

+ 16 - 17
server/controllers/urlController.js

@@ -32,7 +32,6 @@ const {
 const transporter = require('../mail/mail');
 const transporter = require('../mail/mail');
 const redis = require('../redis');
 const redis = require('../redis');
 const { addProtocol, generateShortUrl, getStatsCacheTime } = require('../utils');
 const { addProtocol, generateShortUrl, getStatsCacheTime } = require('../utils');
-const config = require('../config');
 
 
 const dnsLookup = promisify(dns.lookup);
 const dnsLookup = promisify(dns.lookup);
 
 
@@ -48,8 +47,8 @@ exports.urlShortener = async ({ body, user }, res) => {
     const domain = URL.parse(body.target).hostname;
     const domain = URL.parse(body.target).hostname;
 
 
     const queries = await Promise.all([
     const queries = await Promise.all([
-      config.GOOGLE_SAFE_BROWSING_KEY && cooldownCheck(user),
-      config.GOOGLE_SAFE_BROWSING_KEY && malwareCheck(user, body.target),
+      process.env.GOOGLE_SAFE_BROWSING_KEY && cooldownCheck(user),
+      process.env.GOOGLE_SAFE_BROWSING_KEY && malwareCheck(user, body.target),
       user && urlCountsCheck(user.email),
       user && urlCountsCheck(user.email),
       user && body.reuse && findUrl({ target: addProtocol(body.target) }),
       user && body.reuse && findUrl({ target: addProtocol(body.target) }),
       user && body.customurl && findUrl({ id: body.customurl || '' }),
       user && body.customurl && findUrl({ id: body.customurl || '' }),
@@ -109,7 +108,7 @@ exports.goToUrl = async (req, res, next) => {
   const { host } = req.headers;
   const { host } = req.headers;
   const reqestedId = req.params.id || req.body.id;
   const reqestedId = req.params.id || req.body.id;
   const id = reqestedId.replace('+', '');
   const id = reqestedId.replace('+', '');
-  const domain = host !== config.DEFAULT_DOMAIN && host;
+  const domain = host !== process.env.DEFAULT_DOMAIN && host;
   const agent = useragent.parse(req.headers['user-agent']);
   const agent = useragent.parse(req.headers['user-agent']);
   const [browser = 'Other'] = browsersList.filter(filterInBrowser(agent));
   const [browser = 'Other'] = browsersList.filter(filterInBrowser(agent));
   const [os = 'Other'] = osList.filter(filterInOs(agent));
   const [os = 'Other'] = osList.filter(filterInOs(agent));
@@ -131,7 +130,7 @@ exports.goToUrl = async (req, res, next) => {
   }
   }
 
 
   if (!url) {
   if (!url) {
-    if (host !== config.DEFAULT_DOMAIN) {
+    if (host !== process.env.DEFAULT_DOMAIN) {
       const { homepage } = await getCustomDomain({ customDomain: domain });
       const { homepage } = await getCustomDomain({ customDomain: domain });
       if (!homepage) return next();
       if (!homepage) return next();
       return res.redirect(301, homepage);
       return res.redirect(301, homepage);
@@ -185,8 +184,8 @@ exports.goToUrl = async (req, res, next) => {
     });
     });
   }
   }
 
 
-  if (config.GOOGLE_ANALYTICS && !isBot) {
-    const visitor = ua(config.GOOGLE_ANALYTICS);
+  if (process.env.GOOGLE_ANALYTICS && !isBot) {
+    const visitor = ua(process.env.GOOGLE_ANALYTICS);
     visitor
     visitor
       .pageview({
       .pageview({
         dp: `/${id}`,
         dp: `/${id}`,
@@ -217,7 +216,7 @@ exports.setCustomDomain = async ({ body, user }, res) => {
   if (customDomain.length > 40) {
   if (customDomain.length > 40) {
     return res.status(400).json({ error: 'Maximum custom domain length is 40.' });
     return res.status(400).json({ error: 'Maximum custom domain length is 40.' });
   }
   }
-  if (customDomain === config.DEFAULT_DOMAIN) {
+  if (customDomain === process.env.DEFAULT_DOMAIN) {
     return res.status(400).json({ error: "You can't use default domain." });
     return res.status(400).json({ error: "You can't use default domain." });
   }
   }
   const isValidHomepage =
   const isValidHomepage =
@@ -256,19 +255,19 @@ exports.deleteCustomDomain = async ({ user }, res) => {
 exports.customDomainRedirection = async (req, res, next) => {
 exports.customDomainRedirection = async (req, res, next) => {
   const { headers, path } = req;
   const { headers, path } = req;
   if (
   if (
-    headers.host !== config.DEFAULT_DOMAIN &&
+    headers.host !== process.env.DEFAULT_DOMAIN &&
     (path === '/' ||
     (path === '/' ||
       preservedUrls.filter(u => u !== 'url-password').some(item => item === path.replace('/', '')))
       preservedUrls.filter(u => u !== 'url-password').some(item => item === path.replace('/', '')))
   ) {
   ) {
     const { homepage } = await getCustomDomain({ customDomain: headers.host });
     const { homepage } = await getCustomDomain({ customDomain: headers.host });
-    return res.redirect(301, homepage || `https://${config.DEFAULT_DOMAIN + path}`);
+    return res.redirect(301, homepage || `https://${process.env.DEFAULT_DOMAIN + path}`);
   }
   }
   return next();
   return next();
 };
 };
 
 
 exports.deleteUrl = async ({ body: { id, domain }, user }, res) => {
 exports.deleteUrl = async ({ body: { id, domain }, user }, res) => {
   if (!id) return res.status(400).json({ error: 'No id has been provided.' });
   if (!id) return res.status(400).json({ error: 'No id has been provided.' });
-  const customDomain = domain !== config.DEFAULT_DOMAIN && domain;
+  const customDomain = domain !== process.env.DEFAULT_DOMAIN && domain;
   const urls = await findUrl({ id, domain: customDomain });
   const urls = await findUrl({ id, domain: customDomain });
   if (!urls && !urls.length) return res.status(400).json({ error: "Couldn't find the short URL." });
   if (!urls && !urls.length) return res.status(400).json({ error: "Couldn't find the short URL." });
   redis.del(id + (customDomain || ''));
   redis.del(id + (customDomain || ''));
@@ -279,7 +278,7 @@ exports.deleteUrl = async ({ body: { id, domain }, user }, res) => {
 
 
 exports.getStats = async ({ query: { id, domain }, user }, res) => {
 exports.getStats = async ({ query: { id, domain }, user }, res) => {
   if (!id) return res.status(400).json({ error: 'No id has been provided.' });
   if (!id) return res.status(400).json({ error: 'No id has been provided.' });
-  const customDomain = domain !== config.DEFAULT_DOMAIN && domain;
+  const customDomain = domain !== process.env.DEFAULT_DOMAIN && domain;
   const redisKey = id + (customDomain || '') + user.email;
   const redisKey = id + (customDomain || '') + user.email;
   const cached = await redis.get(redisKey);
   const cached = await redis.get(redisKey);
   if (cached) return res.status(200).json(JSON.parse(cached));
   if (cached) return res.status(200).json(JSON.parse(cached));
@@ -288,9 +287,9 @@ exports.getStats = async ({ query: { id, domain }, user }, res) => {
   const [url] = urls;
   const [url] = urls;
   const stats = await getStats({ id, domain: customDomain, user });
   const stats = await getStats({ id, domain: customDomain, user });
   if (!stats) return res.status(400).json({ error: 'Could not get the short URL stats.' });
   if (!stats) return res.status(400).json({ error: 'Could not get the short URL stats.' });
-  stats.shortUrl = `http${!domain ? 's' : ''}://${domain ? url.domain : config.DEFAULT_DOMAIN}/${
-    url.id
-  }`;
+  stats.shortUrl = `http${!domain ? 's' : ''}://${
+    domain ? url.domain : process.env.DEFAULT_DOMAIN
+  }/${url.id}`;
   stats.target = url.target;
   stats.target = url.target;
   const cacheTime = getStatsCacheTime(stats.total);
   const cacheTime = getStatsCacheTime(stats.total);
   redis.set(redisKey, JSON.stringify(stats), 'EX', cacheTime);
   redis.set(redisKey, JSON.stringify(stats), 'EX', cacheTime);
@@ -304,8 +303,8 @@ exports.reportUrl = async ({ body: { url } }, res) => {
   if (!isValidUrl) return res.status(400).json({ error: 'URL is not valid.' });
   if (!isValidUrl) return res.status(400).json({ error: 'URL is not valid.' });
 
 
   const mail = await transporter.sendMail({
   const mail = await transporter.sendMail({
-    from: config.MAIL_USER,
-    to: config.REPORT_MAIL,
+    from: process.env.MAIL_USER,
+    to: process.env.REPORT_MAIL,
     subject: '[REPORT]',
     subject: '[REPORT]',
     text: url,
     text: url,
     html: url,
     html: url,

+ 4 - 5
server/controllers/validateBodyController.js

@@ -7,7 +7,6 @@ const { subHours } = require('date-fns/');
 const { validationResult } = require('express-validator/check');
 const { validationResult } = require('express-validator/check');
 const { addCooldown, banUser } = require('../db/user');
 const { addCooldown, banUser } = require('../db/user');
 const { getBannedDomain, getBannedHost, urlCountFromDate } = require('../db/url');
 const { getBannedDomain, getBannedHost, urlCountFromDate } = require('../db/url');
-const config = require('../config');
 const subDay = require('date-fns/sub_days');
 const subDay = require('date-fns/sub_days');
 
 
 const dnsLookup = promisify(dns.lookup);
 const dnsLookup = promisify(dns.lookup);
@@ -119,11 +118,11 @@ exports.cooldownCheck = async user => {
 exports.malwareCheck = async (user, target) => {
 exports.malwareCheck = async (user, target) => {
   const isMalware = await axios.post(
   const isMalware = await axios.post(
     `https://safebrowsing.googleapis.com/v4/threatMatches:find?key=${
     `https://safebrowsing.googleapis.com/v4/threatMatches:find?key=${
-      config.GOOGLE_SAFE_BROWSING_KEY
+      process.env.GOOGLE_SAFE_BROWSING_KEY
     }`,
     }`,
     {
     {
       client: {
       client: {
-        clientId: config.DEFAULT_DOMAIN.toLowerCase().replace('.', ''),
+        clientId: process.env.DEFAULT_DOMAIN.toLowerCase().replace('.', ''),
         clientVersion: '1.0.0',
         clientVersion: '1.0.0',
       },
       },
       threatInfo: {
       threatInfo: {
@@ -153,9 +152,9 @@ exports.urlCountsCheck = async email => {
     email,
     email,
     date: subDay(new Date(), 1).toJSON(),
     date: subDay(new Date(), 1).toJSON(),
   });
   });
-  if (count > config.USER_LIMIT_PER_DAY) {
+  if (count > Number(process.env.USER_LIMIT_PER_DAY)) {
     throw new Error(
     throw new Error(
-      `You have reached your daily limit (${config.USER_LIMIT_PER_DAY}). Please wait 24h.`
+      `You have reached your daily limit (${process.env.USER_LIMIT_PER_DAY}). Please wait 24h.`
     );
     );
   }
   }
 };
 };

+ 2 - 3
server/db/neo4j.js

@@ -1,9 +1,8 @@
 const neo4j = require('neo4j-driver').v1;
 const neo4j = require('neo4j-driver').v1;
-const config = require('../config');
 
 
 const driver = neo4j.driver(
 const driver = neo4j.driver(
-  config.DB_URI,
-  neo4j.auth.basic(config.DB_USERNAME, config.DB_PASSWORD)
+  process.env.DB_URI,
+  neo4j.auth.basic(process.env.DB_USERNAME, process.env.DB_PASSWORD)
 );
 );
 
 
 module.exports = driver;
 module.exports = driver;

+ 1 - 2
server/db/url.js

@@ -2,7 +2,6 @@ const bcrypt = require('bcryptjs');
 const _ = require('lodash/');
 const _ = require('lodash/');
 const { isAfter, subDays } = require('date-fns');
 const { isAfter, subDays } = require('date-fns');
 const driver = require('./neo4j');
 const driver = require('./neo4j');
-const config = require('../config');
 const {
 const {
   generateShortUrl,
   generateShortUrl,
   statsObjectToArray,
   statsObjectToArray,
@@ -181,7 +180,7 @@ exports.getUrls = ({ user, options, setCount }) =>
             ...record.get('l').properties,
             ...record.get('l').properties,
             count: typeof visitCount === 'object' ? visitCount.toNumber() : visitCount,
             count: typeof visitCount === 'object' ? visitCount.toNumber() : visitCount,
             password: !!record.get('l').properties.password,
             password: !!record.get('l').properties.password,
-            shortUrl: `${protocol}${domain || config.DEFAULT_DOMAIN}/${
+            shortUrl: `${protocol}${domain || process.env.DEFAULT_DOMAIN}/${
               record.get('l').properties.id
               record.get('l').properties.id
             }`,
             }`,
           };
           };

+ 5 - 6
server/mail/mail.js

@@ -1,13 +1,12 @@
-const config = require('../config');
 const nodemailer = require('nodemailer');
 const nodemailer = require('nodemailer');
 
 
 const mailConfig = {
 const mailConfig = {
-  host: config.MAIL_HOST,
-  port: config.MAIL_PORT,
-  secure: config.MAIL_SECURE,
+  host: process.env.MAIL_HOST,
+  port: process.env.MAIL_PORT,
+  secure: process.env.MAIL_SECURE === 'true',
   auth: {
   auth: {
-    user: config.MAIL_USER,
-    pass: config.MAIL_PASSWORD,
+    user: process.env.MAIL_USER,
+    pass: process.env.MAIL_PASSWORD,
   },
   },
 };
 };
 
 

+ 1 - 2
server/passport.js

@@ -4,12 +4,11 @@ const { ExtractJwt } = require('passport-jwt');
 const LocalStratergy = require('passport-local').Strategy;
 const LocalStratergy = require('passport-local').Strategy;
 const LocalAPIKeyStrategy = require('passport-localapikey-update').Strategy;
 const LocalAPIKeyStrategy = require('passport-localapikey-update').Strategy;
 const bcrypt = require('bcryptjs');
 const bcrypt = require('bcryptjs');
-const config = require('./config');
 const { getUser } = require('./db/user');
 const { getUser } = require('./db/user');
 
 
 const jwtOptions = {
 const jwtOptions = {
   jwtFromRequest: ExtractJwt.fromHeader('authorization'),
   jwtFromRequest: ExtractJwt.fromHeader('authorization'),
-  secretOrKey: config.JWT_SECRET,
+  secretOrKey: process.env.JWT_SECRET,
 };
 };
 
 
 passport.use(
 passport.use(

+ 4 - 5
server/redis.js

@@ -1,16 +1,15 @@
 const { promisify } = require('util');
 const { promisify } = require('util');
 const redis = require('redis');
 const redis = require('redis');
-const config = require('./config');
 
 
-if (config.REDIS_DISABLED === true) {
+if (process.env.REDIS_DISABLED === 'true') {
   exports.get = () => Promise.resolve(null);
   exports.get = () => Promise.resolve(null);
   exports.set = () => Promise.resolve(null);
   exports.set = () => Promise.resolve(null);
   exports.del = () => Promise.resolve(null);
   exports.del = () => Promise.resolve(null);
 } else {
 } else {
   const client = redis.createClient({
   const client = redis.createClient({
-    host: config.REDIS_HOST || '127.0.0.1',
-    port: config.REDIS_PORT || 6379,
-    ...(config.REDIS_PASSWORD && { password: config.REDIS_PASSWORD }),
+    host: process.env.REDIS_HOST || '127.0.0.1',
+    port: Number(process.env.REDIS_PORT) || 6379,
+    ...(process.env.REDIS_PASSWORD && { password: process.env.REDIS_PASSWORD }),
   });
   });
 
 
   exports.get = promisify(client.get).bind(client);
   exports.get = promisify(client.get).bind(client);

+ 5 - 5
server/server.js

@@ -1,3 +1,4 @@
+require('dotenv').config();
 const nextApp = require('next');
 const nextApp = require('next');
 const express = require('express');
 const express = require('express');
 const helmet = require('helmet');
 const helmet = require('helmet');
@@ -14,17 +15,16 @@ const {
 } = require('./controllers/validateBodyController');
 } = require('./controllers/validateBodyController');
 const auth = require('./controllers/authController');
 const auth = require('./controllers/authController');
 const url = require('./controllers/urlController');
 const url = require('./controllers/urlController');
-const config = require('./config');
 
 
 require('./passport');
 require('./passport');
 
 
-if (config.RAVEN_DSN) {
-  Raven.config(config.RAVEN_DSN).install();
+if (process.env.RAVEN_DSN) {
+  Raven.config(process.env.RAVEN_DSN).install();
 }
 }
 const catchErrors = fn => (req, res, next) =>
 const catchErrors = fn => (req, res, next) =>
   fn(req, res, next).catch(err => {
   fn(req, res, next).catch(err => {
     res.status(500).json({ error: 'Sorry an error ocurred. Please try again later.' });
     res.status(500).json({ error: 'Sorry an error ocurred. Please try again later.' });
-    if (config.RAVEN_DSN) {
+    if (process.env.RAVEN_DSN) {
       Raven.captureException(err, {
       Raven.captureException(err, {
         user: { email: req.user && req.user.email },
         user: { email: req.user && req.user.email },
       });
       });
@@ -33,7 +33,7 @@ const catchErrors = fn => (req, res, next) =>
     }
     }
   });
   });
 
 
-const port = Number(config.PORT) || 3000;
+const port = Number(process.env.PORT) || 3000;
 const dev = process.env.NODE_ENV !== 'production';
 const dev = process.env.NODE_ENV !== 'production';
 const app = nextApp({ dir: './client', dev });
 const app = nextApp({ dir: './client', dev });
 const handle = app.getRequestHandler();
 const handle = app.getRequestHandler();

+ 5 - 3
server/utils/index.js

@@ -1,7 +1,6 @@
 const URL = require('url');
 const URL = require('url');
 const ms = require('ms');
 const ms = require('ms');
 const { differenceInDays, differenceInHours, differenceInMonths } = require('date-fns');
 const { differenceInDays, differenceInHours, differenceInMonths } = require('date-fns');
-const config = require('../config');
 
 
 exports.addProtocol = url => {
 exports.addProtocol = url => {
   const hasProtocol = /^https?/.test(URL.parse(url).protocol);
   const hasProtocol = /^https?/.test(URL.parse(url).protocol);
@@ -10,10 +9,13 @@ exports.addProtocol = url => {
 
 
 exports.generateShortUrl = (id, domain, useHttps) => {
 exports.generateShortUrl = (id, domain, useHttps) => {
   const protocol = useHttps || !domain ? 'https://' : 'http://';
   const protocol = useHttps || !domain ? 'https://' : 'http://';
-  return `${protocol}${domain || config.DEFAULT_DOMAIN}/${id}`;
+  return `${protocol}${domain || process.env.DEFAULT_DOMAIN}/${id}`;
 };
 };
 
 
-exports.isAdmin = email => config.ADMIN_EMAILS.includes(email);
+exports.isAdmin = email =>
+  process.env.ADMIN_EMAILS.split(',')
+    .map(e => e.trim())
+    .includes(email);
 
 
 exports.getStatsCacheTime = total => {
 exports.getStatsCacheTime = total => {
   switch (true) {
   switch (true) {

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.