app.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. const express = require('express');
  2. const app = express()
  3. const cors = require("cors");
  4. const http = require('http'); //create new http
  5. const mongoose = require('mongoose');
  6. const socket = require("socket.io");
  7. const User = require('./db/models/User');
  8. const Message = require('./db/models/Message');
  9. const jwt = require('jsonwebtoken');
  10. const bcrypt = require('bcrypt');
  11. const server = http.createServer(app);
  12. const jsonParser = express.json();
  13. app.use(cors()); // cors
  14. const io = require("socket.io")(server, {
  15. cors: {
  16. origin: "http://localhost:3000" //client endpoint and port
  17. }
  18. });
  19. const PORT = process.env.PORT || 5000;
  20. //main test page
  21. app.get('/', (req, res) => {
  22. res.send('here will be login page')
  23. })
  24. const TOKEN_KEY = 'rGH4r@3DKOg06hgj';
  25. const HASH_KEY = 7;
  26. const generateToken = (id, userName, isAdmin) => {
  27. const payload = {
  28. id,
  29. userName,
  30. isAdmin
  31. }
  32. return jwt.sign(payload, TOKEN_KEY);
  33. }
  34. const isValidUserName = (userName) => {
  35. const nameRegex = /[^A-Za-z0-9]/ ;
  36. return (!nameRegex.test(userName) && userName.trim());
  37. }
  38. // const saveMessage = async (data, userName) => {
  39. // const message = new Message({
  40. // text: data.message,
  41. // userName: userName,
  42. // createDate: Date.now()
  43. // });
  44. // try {
  45. // await message.save()
  46. // } catch (error) {
  47. // console.log(error)
  48. // }
  49. // }
  50. // const getMessages = async () => {
  51. // try {
  52. // await message.find();
  53. // } catch (error) {
  54. // console.log(error)
  55. // }
  56. // }
  57. //get all users from db
  58. const getAllDbUsers = async (socket) => {
  59. const usersDb = await User.find({})
  60. socket.emit('allDbUsers', usersDb)
  61. }
  62. app.post('/login', jsonParser, async (req, res) => {
  63. try {
  64. const {userName,password} = req.body;
  65. if (!isValidUserName(userName)){
  66. return res.status(400).json({message: 'Invalid username'})
  67. }
  68. const hashPassword = await bcrypt.hash(password, HASH_KEY);
  69. const usersCount = await User.count().exec();
  70. const isFirst = !usersCount;
  71. let user;
  72. if (isFirst) { // if first create as admin
  73. user = new User({
  74. userName,
  75. hashPassword,
  76. isAdmin: true
  77. });
  78. await user.save();
  79. }
  80. user = await User.findOne({userName})
  81. if (!user) {
  82. user = new User({
  83. userName,
  84. hashPassword,
  85. isAdmin: false
  86. });
  87. await user.save()
  88. }
  89. if (!bcrypt.compareSync(password, user.hashPassword)){
  90. return res.status(400).json({message: 'Invalid credantials'})
  91. }
  92. const token = generateToken(user._id, userName, user.isAdmin);
  93. res.json({token})
  94. } catch (e) {
  95. console.log(e)
  96. res.status(500).json({message: `Error ${e}`})
  97. }
  98. })
  99. //use auth token
  100. io.use( async (socket, next) => {
  101. const token = socket.handshake.auth.token;
  102. const sockets = await io.fetchSockets();
  103. const usersOnline = [];
  104. sockets.map((sock) => {
  105. usersOnline.push(sock.user);
  106. })
  107. if(!token) {
  108. socket.disconnect();
  109. return
  110. }
  111. try {
  112. const user = jwt.verify(token, TOKEN_KEY)
  113. socket.user = user;
  114. // console.log('exist', sockets)
  115. const exist = sockets.find( current => current.user.userName == socket.user.userName)
  116. // sockets.map((current) => console.log(current.user.userName))
  117. // console.log('exist', exist)
  118. if(exist) {
  119. console.log('exist', exist)
  120. exist.disconnect();
  121. }
  122. } catch(e) {
  123. console.log(e)
  124. socket.disconnect();
  125. return
  126. }
  127. next();
  128. });
  129. io.on("connection", async (socket) => {
  130. const sockets = await io.fetchSockets();
  131. const results = [];
  132. sockets.map((sock) => {
  133. results.push(sock.user);
  134. })
  135. io.emit('usersOnline', results) // send array online users
  136. socket.emit('connected', socket.user)
  137. if(socket.user.isAdmin) getAllDbUsers(socket); //sent all users from db to admin
  138. const messagesToShow = await Message.find({}).sort({ 'createDate': -1 }).limit(20)
  139. socket.emit('allmessages', messagesToShow.reverse())
  140. socket.on("message", async (data) => {
  141. const userName = socket.user.userName;
  142. const dateNow = Date.now();
  143. const post = await Message.findOne({userName}).sort({ 'createDate': -1 })
  144. console.log(post)
  145. if(post){
  146. if(((Date.now() - Date.parse(post.createDate)) > 150)){//change later 15000
  147. const message = new Message({
  148. text: data.message,
  149. userName: userName,
  150. createDate: Date.now()
  151. });
  152. try {
  153. await message.save()
  154. } catch (error) {
  155. console.log(error)
  156. }
  157. io.emit('message', message)
  158. }
  159. } else {
  160. const message = new Message({
  161. text: data.message,
  162. userName: userName,
  163. createDate: Date.now()
  164. });
  165. try {
  166. await message.save()
  167. } catch (error) {
  168. console.log(error)
  169. }
  170. io.emit('message', message)
  171. }
  172. });
  173. try {
  174. socket.on("disconnect", () => {
  175. io.emit('usersOnline', results)
  176. console.log(`user :${socket.user.userName} , disconnected to socket`);
  177. });
  178. console.log(`user :${socket.user.userName} , connected to socket`);
  179. } catch (e) {
  180. console.log(e)
  181. }
  182. });
  183. //server and database start
  184. const start = async () => {
  185. try {
  186. await mongoose.connect('mongodb://localhost:27017/chat')
  187. .then(() => console.log(`DB started`))
  188. server.listen(PORT, () => {
  189. console.log(`Server started. Port: ${PORT}`)
  190. })
  191. } catch (e) {
  192. console.log(e)
  193. }
  194. }
  195. start();