chat.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright (c) 2025 gugdun
  2. // All rights reserved. Unauthorized use, copying, or distribution is strictly prohibited.
  3. const path = require("path");
  4. const express = require("express");
  5. const ejs = require("ejs");
  6. const db = require("../db");
  7. const package = require("../../package.json");
  8. const { encrypt, decrypt } = require("../util/crypto");
  9. const views = path.join(__dirname, "..", "views");
  10. const router = express.Router();
  11. router.get("/chat/:chat_id", async (req, res) => {
  12. if (req.user) {
  13. try {
  14. const user = await db.one("SELECT id FROM users WHERE username = $1", [ req.params.chat_id ]);
  15. const chat = await db.one("SELECT id FROM chats WHERE (user1_id = $1 AND user2_id = $2) OR (user1_id = $2 AND user2_id = $1)", [ req.user.id, user?.id ]);
  16. const messages = await db.any("SELECT username, attachment_id, text, timestamp FROM messages JOIN users ON users.id = user_id WHERE chat_id = $1 ORDER BY messages.timestamp DESC LIMIT 20", [ chat?.id ]);
  17. const moreMessages = await db.any("SELECT 1 FROM messages WHERE chat_id = $1 AND timestamp < $2", [ chat?.id, messages[messages.length - 1]?.timestamp ]);
  18. res.render("layout", {
  19. child: await ejs.renderFile(path.join(views, "chat.ejs"), {
  20. version: package.version,
  21. username: req.user.username,
  22. title: req.params.chat_id,
  23. chatId: chat?.id,
  24. empty: messages.length < 1,
  25. messages: messages.map((message) => {
  26. return {
  27. username: message.username,
  28. text: decrypt(message.text),
  29. datetime: message.timestamp
  30. }
  31. }),
  32. hasMoreMessages: moreMessages.length > 0,
  33. firstTimestamp: messages[messages.length - 1]?.timestamp || new Date().toISOString()
  34. })
  35. });
  36. } catch (err) {
  37. console.log(err);
  38. res.render("layout", {
  39. child: await ejs.renderFile(path.join(views, "chat.ejs"), {
  40. version: package.version,
  41. username: null,
  42. title: req.params.chat_id,
  43. chatId: null,
  44. empty: true,
  45. messages: [],
  46. hasMoreMessages: false,
  47. firstTimestamp: new Date().toISOString()
  48. })
  49. });
  50. }
  51. } else {
  52. res.redirect("/login");
  53. }
  54. });
  55. router.post("/chat/:chat_id", async (req, res) => {
  56. if (req.user) {
  57. try {
  58. const user = await db.one("SELECT id FROM users WHERE username = $1", [ req.params.chat_id ]);
  59. const chat = await db.one("SELECT id FROM chats WHERE (user1_id = $1 AND user2_id = $2) OR (user1_id = $2 AND user2_id = $1)", [ req.user.id, user?.id ]);
  60. const datetime = new Date().toISOString();
  61. await db.none("INSERT INTO messages (chat_id, user_id, text, timestamp) VALUES ($1, $2, $3, $4)", [
  62. chat?.id,
  63. req.user.id,
  64. encrypt(req.body.text),
  65. datetime
  66. ]);
  67. res.json({ success: true });
  68. } catch (err) {
  69. console.log(err);
  70. res.json({ success: false });
  71. }
  72. } else {
  73. res.redirect("/login");
  74. }
  75. });
  76. router.post("/chat/:chat_id/messages", async (req, res) => {
  77. if (req.user) {
  78. try {
  79. const user = await db.one("SELECT id FROM users WHERE username = $1", [req.params.chat_id]);
  80. const chat = await db.one("SELECT id FROM chats WHERE (user1_id = $1 AND user2_id = $2) OR (user1_id = $2 AND user2_id = $1)", [ req.user.id, user?.id ]);
  81. const firstTimestamp = req.body.timestamp;
  82. const messages = await db.any("SELECT username, attachment_id, text, timestamp FROM messages JOIN users ON users.id = user_id WHERE chat_id = $1 AND timestamp < $2 ORDER BY messages.timestamp DESC LIMIT 20", [ chat?.id, firstTimestamp ]);
  83. const moreMessages = await db.any("SELECT 1 FROM messages WHERE chat_id = $1 AND timestamp < $2", [ chat?.id, messages[messages.length - 1]?.timestamp ]);
  84. res.json({
  85. messages: messages.map((message) => {
  86. return {
  87. username: message.username,
  88. text: decrypt(message.text),
  89. datetime: message.timestamp
  90. }
  91. }),
  92. hasMoreMessages: moreMessages.length > 0,
  93. timestamp: messages[messages.length - 1]?.timestamp || firstTimestamp
  94. });
  95. } catch (err) {
  96. console.log(err);
  97. res.json({
  98. messages: [],
  99. hasMoreMessages: false,
  100. timestamp: req.body.timestamp
  101. });
  102. }
  103. } else {
  104. res.redirect("/login");
  105. }
  106. });
  107. module.exports = router;