migration to WSL

This commit is contained in:
canove
2020-06-24 09:40:51 -03:00
parent 0270ae09e6
commit c60c0f44fc
47 changed files with 17939 additions and 17696 deletions

14
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,14 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}\\backend\\app.js"
}
]
}

View File

@@ -1,4 +1,5 @@
NODE_ENV=development
HOST=localhost
PORT=8080
DB_HOST=

View File

@@ -37,7 +37,7 @@ app.use(WhatsRoutes);
app.use("/auth", AuthRoutes);
app.use((error, req, res, next) => {
console.log(error);
// console.log(error);
const status = error.statusCode || 500;
const message = error.message;
const data = error.data;

View File

@@ -1,6 +1,8 @@
const Contact = require("../models/Contact");
const Message = require("../models/Message");
const Sequelize = require("sequelize");
const { getIO } = require("../socket");
const { getWbot } = require("./wbot");
exports.getContacts = async (req, res) => {
const { searchParam } = req.query;
@@ -44,3 +46,30 @@ exports.getContacts = async (req, res) => {
console.log(err);
}
};
exports.createContact = async (req, res, next) => {
const wbot = getWbot();
const io = getIO();
const { number, name } = req.body;
try {
const res = await wbot.isRegisteredUser(`55${number}@c.us`);
if (!res) {
const error = new Error("O número informado não é um Whatsapp Válido");
error.statusCode = 422;
throw error;
}
const profilePicUrl = await wbot.getProfilePicUrl(`55${number}@c.us`);
const contact = await Contact.create({
name,
number: `55${number}`,
profilePicUrl,
});
res.status(200).json(contact);
} catch (err) {
next(err);
}
};

View File

@@ -24,7 +24,7 @@ const setMessagesAsRead = async contactId => {
const error = new Error(
"Erro ao definir as mensagens como lidas no banco de dados"
);
error.satusCode = 501;
error.statusCode = 501;
throw error;
}
@@ -61,7 +61,7 @@ exports.getContactMessages = async (req, res, next) => {
const contact = await Contact.findByPk(contactId);
if (!contact) {
const error = new Error("Erro ao localizar o contato no banco de dados");
error.satusCode = 501;
error.statusCode = 501;
throw error;
}
@@ -131,7 +131,7 @@ exports.postCreateContactMessage = async (req, res, next) => {
const newMessage = await contact.createMessage(message);
if (!newMessage) {
const error = new Error("Erro ao inserir a mensagem no banco de dados");
error.satusCode = 501;
error.statusCode = 501;
throw error;
}

View File

@@ -26,7 +26,7 @@ const wbotMessageListener = () => {
});
if (contact) {
await contact.update({ imageURL: imageUrl });
await contact.update({ profilePicUrl: imageUrl });
}
if (!contact) {
@@ -34,7 +34,7 @@ const wbotMessageListener = () => {
contact = await Contact.create({
name: msgContact.pushname || msgContact.number.toString(),
number: msgContact.number,
imageURL: imageUrl,
profilePicUrl: imageUrl,
});
} catch (err) {
console.log(err);
@@ -113,7 +113,7 @@ const wbotMessageListener = () => {
const error = new Error(
"Erro ao alterar o ack da mensagem no banco de dados"
);
error.satusCode = 501;
error.statusCode = 501;
throw error;
}
await messageToUpdate.update({ ack: ack });

View File

@@ -1,4 +1,6 @@
const Whatsapp = require("../models/Whatsapp");
const { getIO } = require("../socket");
const { getWbot, init } = require("./wbot");
exports.getSession = async (req, res, next) => {
try {
@@ -13,3 +15,16 @@ exports.getSession = async (req, res, next) => {
next(err);
}
};
exports.getContacts = async (req, res, next) => {
const io = getIO();
const wbot = getWbot();
try {
const phoneContacts = await wbot.getContacts();
return res.status(200).json(phoneContacts);
} catch (err) {
next(err);
}
};

View File

@@ -5,6 +5,7 @@ module.exports = (req, res, next) => {
try {
const [, token] = req.get("Authorization").split(" ");
decodedToken = jwt.verify(token, "mysecret");
req.userId = decodedToken.userId;
} catch (err) {
err.statusCode = 401;
err.message = "invalidToken";
@@ -17,6 +18,5 @@ module.exports = (req, res, next) => {
next(error);
}
req.userId = decodedToken.userId;
next();
};

View File

@@ -7,7 +7,7 @@ const Message = require("./Message");
const Contact = sequelize.define("contact", {
name: { type: Sequelize.STRING(100), allowNull: false },
number: { type: Sequelize.STRING(15), allowNull: false },
imageURL: { type: Sequelize.STRING(200) },
profilePicUrl: { type: Sequelize.STRING(200) },
lastMessage: { type: Sequelize.TEXT },
});

View File

@@ -2,6 +2,7 @@ const express = require("express");
const { body } = require("express-validator");
const User = require("../models/User");
const authController = require("../controllers/auth");
const isAuth = require("../middleware/is-auth");
const routes = express.Router();
@@ -27,4 +28,8 @@ routes.put(
routes.post("/login", authController.login);
routes.get("/check", isAuth, (req, res) => {
res.status(200).json({ authenticated: true });
});
module.exports = routes;

View File

@@ -8,4 +8,6 @@ const routes = express.Router();
routes.get("/contacts", isAuth, ContactController.getContacts);
// routes.post(ContactController.postCreateContact);
routes.post("/contacts", isAuth, ContactController.createContact);
module.exports = routes;

View File

@@ -12,4 +12,11 @@ routes.get("/whatsapp/session", isAuth, WhatsappController.getSession);
// WhatsappController.postCreateContactMessage
// );
routes.get("/whatsapp/contacts", isAuth, WhatsappController.getContacts);
// routes.post(
// "/messages/:contactId",
// isAuth,
// WhatsappController.postCreateContactMessage
// );
module.exports = routes;

View File

@@ -15,9 +15,29 @@ const useAuth = () => {
api.defaults.headers.Authorization = `Bearer ${JSON.parse(token)}`;
setIsAuth(true);
}
const checkAuth = async () => {
if (
history.location.pathname === "/login" ||
history.location.pathname === "/signup"
) {
setLoading(false);
setLoading(false);
}, []);
return;
}
try {
const res = await api.get("/auth/check");
if (res.status === 200) {
setIsAuth(true);
setLoading(false);
}
} catch (err) {
setLoading(false);
setIsAuth(false);
alert("Erro de autenticação. Por favor, faça login novamente");
}
};
checkAuth();
}, [history.location.pathname]);
const handleLogin = async (e, user) => {
e.preventDefault();

View File

@@ -0,0 +1,72 @@
import React, { useState } from "react";
import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogTitle from "@material-ui/core/DialogTitle";
const AddContactModal = ({ modalOpen, setModalOpen, handleAddContact }) => {
const initialState = { name: "", number: "" };
const [contact, setContact] = useState(initialState);
const handleClose = () => {
setModalOpen(false);
};
const handleChangeInput = e => {
setContact({ ...contact, [e.target.name]: e.target.value });
};
return (
<div>
<Dialog
open={modalOpen}
onClose={handleClose}
aria-labelledby="form-dialog-title"
>
<DialogTitle id="form-dialog-title">Adicionar contato</DialogTitle>
<DialogContent>
<TextField
autoComplete="false"
autoFocus
margin="dense"
name="number"
id="contactNumber"
label="Número"
type="text"
value={contact.number}
onChange={handleChangeInput}
fullWidth
/>
<TextField
margin="dense"
name="name"
id="contactName"
label="Nome do contato"
type="text"
value={contact.name}
onChange={handleChangeInput}
fullWidth
/>
</DialogContent>
<DialogActions>
<Button onClick={handleClose} color="primary">
Cancelar
</Button>
<Button
onClick={e => {
handleAddContact(contact);
setContact(initialState);
}}
color="primary"
>
Adicionar
</Button>
</DialogActions>
</Dialog>
</div>
);
};
export default AddContactModal;

View File

@@ -16,10 +16,13 @@ import ListItemText from "@material-ui/core/ListItemText";
import ListItemAvatar from "@material-ui/core/ListItemAvatar";
import Typography from "@material-ui/core/Typography";
import Avatar from "@material-ui/core/Avatar";
import AddIcon from "@material-ui/icons/Add";
import Divider from "@material-ui/core/Divider";
import Badge from "@material-ui/core/Badge";
import SearchIcon from "@material-ui/icons/Search";
import InputBase from "@material-ui/core/InputBase";
import Fab from "@material-ui/core/Fab";
import AddContactModal from "../AddContact/AddContactModal";
import ContactsHeader from "../ContactsHeader/ContactsHeader";
@@ -118,6 +121,14 @@ const useStyles = makeStyles(theme => ({
marginTop: 12,
// marginLeft: -12,
},
fabButton: {
position: "absolute",
zIndex: 1,
bottom: 20,
left: 0,
right: 0,
margin: "0 auto",
},
}));
const ContactsList = () => {
@@ -128,6 +139,8 @@ const ContactsList = () => {
const [loading, setLoading] = useState();
const [searchParam, setSearchParam] = useState("");
const [modalOpen, setModalOpen] = useState(false);
const history = useHistory();
useEffect(() => {
@@ -209,7 +222,7 @@ const ContactsList = () => {
body: `${data.message.messageBody} - ${moment(new Date())
.tz("America/Sao_Paulo")
.format("DD/MM/YY - HH:mm")}`,
icon: data.contact.imageURL,
icon: data.contact.profilePicUrl,
};
new Notification(`Mensagem de ${data.contact.name}`, options);
document.getElementById("sound").play();
@@ -234,9 +247,34 @@ const ContactsList = () => {
setSearchParam(e.target.value.toLowerCase());
};
const handleShowContactModal = e => {
setModalOpen(true);
};
const handleAddContact = async contact => {
try {
const res = await api.post("/contacts", contact);
setContacts(prevState => [res.data, ...prevState]);
setModalOpen(false);
console.log(res.data);
} catch (err) {
if (err.response.status === 422) {
console.log("deu erro", err.response);
alert(err.response.data.message);
} else {
alert(err);
}
}
};
return (
<div className={classes.contactsWrapper}>
<ContactsHeader />
<AddContactModal
setModalOpen={setModalOpen}
modalOpen={modalOpen}
handleAddContact={handleAddContact}
/>
<Paper variant="outlined" square className={classes.contactsSearchBox}>
<div className={classes.serachInputWrapper}>
<SearchIcon className={classes.searchIcon} />
@@ -260,7 +298,9 @@ const ContactsList = () => {
<ListItemAvatar>
<Avatar
src={
contact.imageURL ? contact.imageURL : profileDefaultPic
contact.profilePicUrl
? contact.profilePicUrl
: profileDefaultPic
}
></Avatar>
</ListItemAvatar>
@@ -320,6 +360,14 @@ const ContactsList = () => {
<CircularProgress className={classes.circleLoading} />
</div>
) : null}
<Fab
color="secondary"
aria-label="add"
className={classes.fabButton}
onClick={handleShowContactModal}
>
<AddIcon />
</Fab>
</Paper>
<audio id="sound" preload="auto">
<source src={require("../../../../util/sound.mp3")} type="audio/mpeg" />

View File

@@ -299,7 +299,7 @@ const MessagesList = () => {
};
const scrollToBottom = () => {
if (lastMessageRef) {
if (lastMessageRef.current) {
lastMessageRef.current.scrollIntoView({});
}
};
@@ -449,11 +449,11 @@ const MessagesList = () => {
return (
<div className={classes.mainWrapper}>
<Card variant="outlined" square className={classes.messagesHeader}>
{!loading ? (
{contact.name ? (
<CardHeader
titleTypographyProps={{ noWrap: true }}
subheaderTypographyProps={{ noWrap: true }}
avatar={<Avatar alt="contact_image" src={contact.imageURL} />}
avatar={<Avatar alt="contact_image" src={contact.profilePicUrl} />}
title={contact.name}
subheader="Contact Status"
/>

View File

@@ -9,11 +9,27 @@ import Profile from "./pages/Profile/Profile";
import Signup from "./pages/Signup/Signup";
import Login from "./pages/Login/Login";
import WhatsAuth from "./pages/WhatsAuth/WhatsAuth";
import Backdrop from "@material-ui/core/Backdrop";
import CircularProgress from "@material-ui/core/CircularProgress";
import { makeStyles } from "@material-ui/core/styles";
const useStyles = makeStyles(theme => ({
backdrop: {
zIndex: theme.zIndex.drawer + 1,
color: "#fff",
},
}));
const PrivateRoute = ({ component: Component, ...rest }) => {
const classes = useStyles();
const { isAuth, loading } = useContext(AuthContext);
if (loading) return <h1>Loading...</h1>;
if (loading)
return (
<Backdrop className={classes.backdrop} open={loading}>
<CircularProgress color="inherit" />
</Backdrop>
);
return (
<Route
@@ -32,9 +48,15 @@ const PrivateRoute = ({ component: Component, ...rest }) => {
};
const PublicRoute = ({ component: Component, ...rest }) => {
const classes = useStyles();
const { isAuth, loading } = useContext(AuthContext);
if (loading) return <h1>Loading...</h1>;
if (loading)
return (
<Backdrop className={classes.backdrop} open={loading}>
<CircularProgress color="inherit" />
</Backdrop>
);
return (
<Route

View File

@@ -0,0 +1,4 @@
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://notificationsounds.com/message-tones/juntos-607
HostUrl=https://notificationsounds.com/message-tones/juntos-607/download/mp3

View File

@@ -0,0 +1,4 @@
[ZoneTransfer]
ZoneId=3
ReferrerUrl=https://notificationsounds.com/message-tones/juntos-607
HostUrl=https://notificationsounds.com/message-tones/juntos-607/download/ogg