mirror of
https://github.com/cheveguerra/whaticket-community.git
synced 2026-04-20 20:59:16 +00:00
Add environment variable in frontend and ssl
This commit is contained in:
14
.env.example
14
.env.example
@@ -1,7 +1,19 @@
|
|||||||
|
# MYSQL
|
||||||
MYSQL_ROOT_PASSWORD=strongpassword
|
MYSQL_ROOT_PASSWORD=strongpassword
|
||||||
MYSQL_DATABASE=whaticket
|
MYSQL_DATABASE=whaticket
|
||||||
|
TZ=America/Fortaleza
|
||||||
|
|
||||||
|
# BACKEND
|
||||||
|
BACKEND_PORT=8080
|
||||||
|
BACKEND_SERVER_NAME=api.mydomain.com
|
||||||
|
BACKEND_URL=https://api.mydomain.com/
|
||||||
JWT_SECRET=3123123213123
|
JWT_SECRET=3123123213123
|
||||||
JWT_REFRESH_SECRET=75756756756
|
JWT_REFRESH_SECRET=75756756756
|
||||||
|
|
||||||
|
# FRONTEND
|
||||||
FRONTEND_PORT=3000
|
FRONTEND_PORT=3000
|
||||||
TZ=America/Fortaleza
|
FRONTEND_SERVER_NAME=myapp.mydomain.com
|
||||||
|
FRONTEND_URL=https://myapp.mydomain.com/
|
||||||
|
|
||||||
|
# BROWSERLESS
|
||||||
MAX_CONCURRENT_SESSIONS=1
|
MAX_CONCURRENT_SESSIONS=1
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
.docker/data/
|
.docker/data/
|
||||||
|
ssl/
|
||||||
.env
|
.env
|
||||||
@@ -16,9 +16,11 @@ services:
|
|||||||
- DB_NAME=${MYSQL_DATABASE:-whaticket}
|
- DB_NAME=${MYSQL_DATABASE:-whaticket}
|
||||||
- JWT_SECRET=${JWT_SECRET:-3123123213123}
|
- JWT_SECRET=${JWT_SECRET:-3123123213123}
|
||||||
- JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET:-75756756756}
|
- JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET:-75756756756}
|
||||||
- BACKEND_URL=${BACKEND_URL:-http://localhost:3000/api}
|
- BACKEND_URL=${BACKEND_URL:-http://localhost:8080}
|
||||||
- FRONTEND_URL=${BACKEND_URL:-http://localhost:3000}
|
- FRONTEND_URL=${FRONTEND_URL:-http://localhost:3000}
|
||||||
- CHROME_ARGS=--no-sandbox --disable-setuid-sandbox
|
- CHROME_ARGS=--no-sandbox --disable-setuid-sandbox
|
||||||
|
ports:
|
||||||
|
- ${BACKEND_PORT:-8080}:3000
|
||||||
networks:
|
networks:
|
||||||
- whaticket
|
- whaticket
|
||||||
|
|
||||||
@@ -29,7 +31,12 @@ services:
|
|||||||
context: ./frontend
|
context: ./frontend
|
||||||
dockerfile: ./Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
environment:
|
environment:
|
||||||
- URL_BACKEND=http://backend:3000/
|
- URL_BACKEND=backend:3000
|
||||||
|
- REACT_APP_BACKEND_URL=${BACKEND_URL:-http://localhost:8080/}
|
||||||
|
- FRONTEND_SERVER_NAME=${FRONTEND_SERVER_NAME}
|
||||||
|
- BACKEND_SERVER_NAME=${BACKEND_SERVER_NAME}
|
||||||
|
volumes:
|
||||||
|
- ./ssl/:/etc/nginx/ssl/
|
||||||
networks:
|
networks:
|
||||||
- whaticket
|
- whaticket
|
||||||
|
|
||||||
|
|||||||
27
frontend/.docker/add-env-vars.sh
Normal file
27
frontend/.docker/add-env-vars.sh
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
_writeFrontendEnvVars() {
|
||||||
|
ENV_JSON="$(jq --compact-output --null-input 'env | with_entries(select(.key | startswith("REACT_APP_")))')"
|
||||||
|
ENV_JSON_ESCAPED="$(printf "%s" "${ENV_JSON}" | sed -e 's/[\&/]/\\&/g')"
|
||||||
|
sed -i "s/<noscript id=\"env-insertion-point\"><\/noscript>/<script>var ENV=${ENV_JSON_ESCAPED}<\/script>/g" ${PUBLIC_HTML}index.html
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeNginxEnvVars() {
|
||||||
|
dockerize -template /etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
|
||||||
|
}
|
||||||
|
|
||||||
|
_addSslConfig() {
|
||||||
|
SSL_CERTIFICATE=/etc/nginx/ssl/${1}/fullchain.pem;
|
||||||
|
SSL_CERTIFICATE_KEY=/etc/nginx/ssl/${1}/privkey.pem;
|
||||||
|
FILE_CONF=/etc/nginx/sites.d/${1}.conf
|
||||||
|
|
||||||
|
if [ -f ${SSL_CERTIFICATE} ] && [ -f ${SSL_CERTIFICATE_KEY} ]; then
|
||||||
|
echo 'include "include.d/ssl.conf";' >> ${FILE_CONF};
|
||||||
|
echo "ssl_certificate ${SSL_CERTIFICATE};" >> ${FILE_CONF};
|
||||||
|
echo "ssl_certificate_key ${SSL_CERTIFICATE_KEY};" >> ${FILE_CONF};
|
||||||
|
fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
_writeFrontendEnvVars;
|
||||||
|
_writeNginxEnvVars;
|
||||||
|
|
||||||
|
_addSslConfig 'backend'
|
||||||
|
_addSslConfig 'frontend'
|
||||||
@@ -1,4 +1,18 @@
|
|||||||
server {
|
upstream backend {
|
||||||
server_name _;
|
server {{ .Env.URL_BACKEND }};
|
||||||
include include.d/spa.conf;
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
index index.html;
|
||||||
|
root /var/www/public/;
|
||||||
|
|
||||||
|
server_name {{ default .Env.FRONTEND_SERVER_NAME "_" }};
|
||||||
|
include sites.d/frontend.conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ default .Env.BACKEND_SERVER_NAME "_" }};
|
||||||
|
include sites.d/backend.conf;
|
||||||
}
|
}
|
||||||
45
frontend/.docker/nginx/include.d/letsencrypt.conf
Normal file
45
frontend/.docker/nginx/include.d/letsencrypt.conf
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#############################################################################
|
||||||
|
# Configuration file for Let's Encrypt ACME Challenge location
|
||||||
|
# This file is already included in listen_xxx.conf files.
|
||||||
|
# Do NOT include it separately!
|
||||||
|
#############################################################################
|
||||||
|
#
|
||||||
|
# This config enables to access /.well-known/acme-challenge/xxxxxxxxxxx
|
||||||
|
# on all our sites (HTTP), including all subdomains.
|
||||||
|
# This is required by ACME Challenge (webroot authentication).
|
||||||
|
# You can check that this location is working by placing ping.txt here:
|
||||||
|
# /var/www/letsencrypt/.well-known/acme-challenge/ping.txt
|
||||||
|
# And pointing your browser to:
|
||||||
|
# http://xxx.domain.tld/.well-known/acme-challenge/ping.txt
|
||||||
|
#
|
||||||
|
# Sources:
|
||||||
|
# https://community.letsencrypt.org/t/howto-easy-cert-generation-and-renewal-with-nginx/3491
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
# Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx)
|
||||||
|
# We use ^~ here, so that we don't check other regexes (for speed-up). We actually MUST cancel
|
||||||
|
# other regex checks, because in our other config files have regex rule that denies access to files with dotted names.
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
|
|
||||||
|
# Set correct content type. According to this:
|
||||||
|
# https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29
|
||||||
|
# Current specification requires "text/plain" or no content header at all.
|
||||||
|
# It seems that "text/plain" is a safe option.
|
||||||
|
default_type "text/plain";
|
||||||
|
|
||||||
|
# This directory must be the same as in /etc/letsencrypt/cli.ini
|
||||||
|
# as "webroot-path" parameter. Also don't forget to set "authenticator" parameter
|
||||||
|
# there to "webroot".
|
||||||
|
# Do NOT use alias, use root! Target directory is located here:
|
||||||
|
# /var/www/common/letsencrypt/.well-known/acme-challenge/
|
||||||
|
root /var/www/letsencrypt;
|
||||||
|
autoindex on;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Hide /acme-challenge subdirectory and return 404 on all requests.
|
||||||
|
# It is somewhat more secure than letting Nginx return 403.
|
||||||
|
# Ending slash is important!
|
||||||
|
location = /.well-known/acme-challenge/ {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# X-Frame-Options is to prevent from clickJacking attack
|
|
||||||
add_header X-Frame-Options SAMEORIGIN;
|
|
||||||
|
|
||||||
# disable content-type sniffing on some browsers.
|
|
||||||
add_header X-Content-Type-Options nosniff;
|
|
||||||
|
|
||||||
# This header enables the Cross-site scripting (XSS) filter
|
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
|
||||||
|
|
||||||
# This will enforce HTTP browsing into HTTPS and avoid ssl stripping attack
|
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
|
|
||||||
|
|
||||||
add_header Referrer-Policy "no-referrer-when-downgrade";
|
|
||||||
|
|
||||||
# Enables response header of "Vary: Accept-Encoding"
|
|
||||||
gzip_vary on;
|
|
||||||
@@ -1,28 +1,16 @@
|
|||||||
listen 80;
|
# X-Frame-Options is to prevent from clickJacking attack
|
||||||
index index.html;
|
add_header X-Frame-Options SAMEORIGIN;
|
||||||
root /var/www/public/;
|
|
||||||
|
|
||||||
location /{{ default .Env.FOLDER_BACKEND "api" }}/ {
|
# disable content-type sniffing on some browsers.
|
||||||
proxy_pass {{ .Env.URL_BACKEND }};
|
add_header X-Content-Type-Options nosniff;
|
||||||
}
|
|
||||||
|
|
||||||
location /socket.io/ {
|
# This header enables the Cross-site scripting (XSS) filter
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
add_header X-XSS-Protection "1; mode=block";
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_pass {{ .Env.URL_BACKEND }}socket.io/;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
}
|
|
||||||
|
|
||||||
location / {
|
# This will enforce HTTP browsing into HTTPS and avoid ssl stripping attack
|
||||||
try_files $uri $uri/ /index.html;
|
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
|
||||||
include include.d/nocache.conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
location /static {
|
add_header Referrer-Policy "no-referrer-when-downgrade";
|
||||||
alias /var/www/public/static/;
|
|
||||||
include include.d/allcache.conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
include include.d/root.conf;
|
# Enables response header of "Vary: Accept-Encoding"
|
||||||
|
gzip_vary on;
|
||||||
2
frontend/.docker/nginx/include.d/ssl.conf
Normal file
2
frontend/.docker/nginx/include.d/ssl.conf
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
listen 443 ssl http2;
|
||||||
|
listen [::]:443 ssl http2;
|
||||||
11
frontend/.docker/nginx/sites.d/backend.conf
Normal file
11
frontend/.docker/nginx/sites.d/backend.conf
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
location / {
|
||||||
|
proxy_pass http://backend;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection 'upgrade';
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_cache_bypass $http_upgrade;
|
||||||
|
}
|
||||||
11
frontend/.docker/nginx/sites.d/frontend.conf
Executable file
11
frontend/.docker/nginx/sites.d/frontend.conf
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
include include.d/nocache.conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
alias /var/www/public/static/;
|
||||||
|
include include.d/allcache.conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
include "include.d/spa.conf";
|
||||||
@@ -5,20 +5,21 @@ RUN npm install
|
|||||||
COPY .env* ./
|
COPY .env* ./
|
||||||
COPY src/ ./src/
|
COPY src/ ./src/
|
||||||
COPY public/ ./public/
|
COPY public/ ./public/
|
||||||
RUN echo "REACT_APP_BACKEND_URL=/api/" > .env.production
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
FROM nginx:alpine
|
FROM nginx:alpine
|
||||||
|
RUN apk add --no-cache jq openssl
|
||||||
|
|
||||||
RUN apk add --no-cache openssl
|
|
||||||
ENV DOCKERIZE_VERSION v0.6.1
|
ENV DOCKERIZE_VERSION v0.6.1
|
||||||
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
|
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
|
||||||
&& tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
|
&& tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
|
||||||
&& rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz
|
&& rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz
|
||||||
|
|
||||||
|
ENV PUBLIC_HTML=/var/www/public/
|
||||||
|
|
||||||
COPY .docker/nginx /etc/nginx/
|
COPY .docker/nginx /etc/nginx/
|
||||||
COPY --from=build-deps /usr/src/app/build /var/www/public/
|
COPY --from=build-deps /usr/src/app/build ${PUBLIC_HTML}
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
RUN echo "dockerize -template /etc/nginx/include.d/spa.conf:/etc/nginx/include.d/spa.conf" > /docker-entrypoint.d/01-change-url-backend.sh \
|
COPY .docker/add-env-vars.sh /docker-entrypoint.d/01-add-env-vars.sh
|
||||||
&& chmod +x /docker-entrypoint.d/01-change-url-backend.sh
|
RUN chmod +x /docker-entrypoint.d/01-add-env-vars.sh
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
name="viewport"
|
name="viewport"
|
||||||
content="minimum-scale=1, initial-scale=1, width=device-width"
|
content="minimum-scale=1, initial-scale=1, width=device-width"
|
||||||
/>
|
/>
|
||||||
|
<noscript id="env-insertion-point"></noscript>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect, useReducer, useRef } from "react";
|
import React, { useState, useEffect, useReducer, useRef } from "react";
|
||||||
|
|
||||||
import { isSameDay, parseISO, format } from "date-fns";
|
import { isSameDay, parseISO, format } from "date-fns";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
import { green } from "@material-ui/core/colors";
|
import { green } from "@material-ui/core/colors";
|
||||||
@@ -358,7 +358,7 @@ const MessagesList = ({ ticketId, isGroup }) => {
|
|||||||
}, [pageNumber, ticketId]);
|
}, [pageNumber, ticketId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("connect", () => socket.emit("joinChatBox", ticketId));
|
socket.on("connect", () => socket.emit("joinChatBox", ticketId));
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { useState, useRef, useEffect, useContext } from "react";
|
|||||||
|
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
import useSound from "use-sound";
|
import useSound from "use-sound";
|
||||||
|
|
||||||
import Popover from "@material-ui/core/Popover";
|
import Popover from "@material-ui/core/Popover";
|
||||||
@@ -78,7 +78,7 @@ const NotificationsPopOver = () => {
|
|||||||
}, [ticketIdUrl]);
|
}, [ticketIdUrl]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("connect", () => socket.emit("joinNotification"));
|
socket.on("connect", () => socket.emit("joinNotification"));
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import QRCode from "qrcode.react";
|
import QRCode from "qrcode.react";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from "../../errors/toastError";
|
||||||
|
|
||||||
import { Dialog, DialogContent, Paper, Typography } from "@material-ui/core";
|
import { Dialog, DialogContent, Paper, Typography } from "@material-ui/core";
|
||||||
@@ -26,7 +26,7 @@ const QrcodeModal = ({ open, onClose, whatsAppId }) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!whatsAppId) return;
|
if (!whatsAppId) return;
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("whatsappSession", data => {
|
socket.on("whatsappSession", data => {
|
||||||
if (data.action === "update" && data.session.id === whatsAppId) {
|
if (data.action === "update" && data.session.id === whatsAppId) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
|
|||||||
import { useParams, useHistory } from "react-router-dom";
|
import { useParams, useHistory } from "react-router-dom";
|
||||||
|
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
|
|
||||||
import { Paper, makeStyles } from "@material-ui/core";
|
import { Paper, makeStyles } from "@material-ui/core";
|
||||||
@@ -104,7 +104,7 @@ const Ticket = () => {
|
|||||||
}, [ticketId, history]);
|
}, [ticketId, history]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("connect", () => socket.emit("joinChatBox", ticketId));
|
socket.on("connect", () => socket.emit("joinChatBox", ticketId));
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect, useReducer, useContext } from "react";
|
import React, { useState, useEffect, useReducer, useContext } from "react";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
import List from "@material-ui/core/List";
|
import List from "@material-ui/core/List";
|
||||||
@@ -182,7 +182,7 @@ const reducer = (state, action) => {
|
|||||||
}, [tickets, status, searchParam]);
|
}, [tickets, status, searchParam]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
const shouldUpdateTicket = ticket =>
|
const shouldUpdateTicket = ticket =>
|
||||||
(!ticket.userId || ticket.userId === user?.id || showAll) &&
|
(!ticket.userId || ticket.userId === user?.id || showAll) &&
|
||||||
|
|||||||
16
frontend/src/config.js
Normal file
16
frontend/src/config.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
function getConfig(name, defaultValue=null) {
|
||||||
|
// If inside a docker container, use window.ENV
|
||||||
|
if( window.ENV !== undefined ) {
|
||||||
|
return window.ENV[name] || defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return process.env[name] || defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBackendUrl() {
|
||||||
|
return getConfig('REACT_APP_BACKEND_URL');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getHoursCloseTicketsAuto() {
|
||||||
|
return getConfig('REACT_APP_HOURS_CLOSE_TICKETS_AUTO');
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
|
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ const useAuth = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("user", data => {
|
socket.on("user", data => {
|
||||||
if (data.action === "update" && data.user.id === user.id) {
|
if (data.action === "update" && data.user.id === user.id) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
|
import { getHoursCloseTicketsAuto } from "../../config";
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from "../../errors/toastError";
|
||||||
|
|
||||||
import api from "../../services/api";
|
import api from "../../services/api";
|
||||||
@@ -35,7 +36,7 @@ const useTickets = ({
|
|||||||
})
|
})
|
||||||
setTickets(data.tickets)
|
setTickets(data.tickets)
|
||||||
|
|
||||||
let horasFecharAutomaticamente = process.env.REACT_APP_HOURS_CLOSE_TICKETS_AUTO
|
let horasFecharAutomaticamente = getHoursCloseTicketsAuto();
|
||||||
|
|
||||||
if (status === "open" && horasFecharAutomaticamente && horasFecharAutomaticamente !== "" &&
|
if (status === "open" && horasFecharAutomaticamente && horasFecharAutomaticamente !== "" &&
|
||||||
horasFecharAutomaticamente !== "0" && Number(horasFecharAutomaticamente) > 0) {
|
horasFecharAutomaticamente !== "0" && Number(horasFecharAutomaticamente) > 0) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useState, useEffect, useReducer } from "react";
|
import { useState, useEffect, useReducer } from "react";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
import toastError from "../../errors/toastError";
|
import toastError from "../../errors/toastError";
|
||||||
|
|
||||||
import api from "../../services/api";
|
import api from "../../services/api";
|
||||||
@@ -73,7 +73,7 @@ const useWhatsApps = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("whatsapp", data => {
|
socket.on("whatsapp", data => {
|
||||||
if (data.action === "update") {
|
if (data.action === "update") {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect, useReducer, useContext } from "react";
|
import React, { useState, useEffect, useReducer, useContext } from "react";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import { useHistory } from "react-router-dom";
|
import { useHistory } from "react-router-dom";
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ const Contacts = () => {
|
|||||||
}, [searchParam, pageNumber]);
|
}, [searchParam, pageNumber]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("contact", (data) => {
|
socket.on("contact", (data) => {
|
||||||
if (data.action === "update" || data.action === "create") {
|
if (data.action === "update" || data.action === "create") {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useEffect, useReducer, useState } from "react";
|
import React, { useEffect, useReducer, useState } from "react";
|
||||||
|
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -111,7 +111,7 @@ const Queues = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("queue", (data) => {
|
socket.on("queue", (data) => {
|
||||||
if (data.action === "update" || data.action === "create") {
|
if (data.action === "update" || data.action === "create") {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect, useReducer } from "react";
|
import React, { useState, useEffect, useReducer } from "react";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -122,7 +122,7 @@ const QuickAnswers = () => {
|
|||||||
}, [searchParam, pageNumber]);
|
}, [searchParam, pageNumber]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("quickAnswer", (data) => {
|
socket.on("quickAnswer", (data) => {
|
||||||
if (data.action === "update" || data.action === "create") {
|
if (data.action === "update" || data.action === "create") {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
import Paper from "@material-ui/core/Paper";
|
import Paper from "@material-ui/core/Paper";
|
||||||
@@ -55,7 +55,7 @@ const Settings = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("settings", data => {
|
socket.on("settings", data => {
|
||||||
if (data.action === "update") {
|
if (data.action === "update") {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect, useReducer } from "react";
|
import React, { useState, useEffect, useReducer } from "react";
|
||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
import openSocket from "socket.io-client";
|
import openSocket from "../../services/socket-io";
|
||||||
|
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
import { makeStyles } from "@material-ui/core/styles";
|
||||||
import Paper from "@material-ui/core/Paper";
|
import Paper from "@material-ui/core/Paper";
|
||||||
@@ -122,7 +122,7 @@ const Users = () => {
|
|||||||
}, [searchParam, pageNumber]);
|
}, [searchParam, pageNumber]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
const socket = openSocket();
|
||||||
|
|
||||||
socket.on("user", (data) => {
|
socket.on("user", (data) => {
|
||||||
if (data.action === "update" || data.action === "create") {
|
if (data.action === "update" || data.action === "create") {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
import { getBackendUrl } from "../config";
|
||||||
|
|
||||||
const api = axios.create({
|
const api = axios.create({
|
||||||
baseURL: process.env.REACT_APP_BACKEND_URL,
|
baseURL: getBackendUrl(),
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
8
frontend/src/services/socket-io.js
Normal file
8
frontend/src/services/socket-io.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import openSocket from "socket.io-client";
|
||||||
|
import { getBackendUrl } from "../config";
|
||||||
|
|
||||||
|
function connectToSocket() {
|
||||||
|
return openSocket(getBackendUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connectToSocket;
|
||||||
Reference in New Issue
Block a user