const auth = require("../lib/authorize_socket.js") const { User, Friend } = require("../models") module.exports = { init(app, server) { const io = require("socket.io")(server, { cors: { origin: [app.locals.config.corsHostname], methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"] } }) io.use(auth) io.on("connection", async (socket) => { const user = await User.findOne({ where: { id: socket.user.id } }) if (user && socket.user.id) { console.log(user.id + " client connect") console.log(socket.user.id) socket.join(user.id) socket.emit("siteState", { release: app.locals.config.release, notification: app.locals.config.notification, notificationType: app.locals.config.notificationType, latestVersion: require("../../frontend/package.json").version, allowRegistrations: app.locals.config.allowRegistrations, publicUsers: app.locals.config.publicUsers, emailVerification: app.locals.config.emailVerification, rules: app.locals.config.rules, name: app.locals.config.siteName }) const friends = await Friend.findAll({ where: { userId: user.id, status: "accepted" } }) await user.update({ status: user.storedStatus === "invisible" ? "offline" : user.storedStatus }) friends.forEach((friend) => { io.to(friend.friendId).emit("userStatus", { userId: user.id, status: user.storedStatus === "invisible" ? "offline" : user.storedStatus }) }) socket.on("ping", () => { console.log(user.id + " client ping") socket.emit("pong") }) socket.on("bcBots/deleteMessage", (e) => { if (socket.user.bot) { socket.to(e.userId).emit("deleteMessage", e) } else { socket.emit("bcBots/deleteMessage", { error: "You cannot perform this action." }) } }) socket.on("idle", async () => { console.log(user.id + " client online") if (user.storedStatus === "online") { friends.forEach((friend) => { io.to(friend.friendId).emit("userStatus", { userId: user.id, status: "away" }) }) io.to(user.id).emit("userStatus", { userId: user.id, status: "away" }) await user.update({ status: "away" }) } }) socket.on("online", async () => { console.log(user.id + " client online") if (user.storedStatus === "online") { friends.forEach((friend) => { io.to(friend.friendId).emit("userStatus", { userId: user.id, status: "online" }) }) io.to(user.id).emit("userStatus", { userId: user.id, status: "online" }) await user.update({ status: "online" }) } }) socket.on("disconnect", async function () { console.log(user.id + " client disconnected") const clients = io.sockets.adapter.rooms.get(user.id) || new Set() if (!clients.size || clients.size === 0) { friends.forEach((friend) => { io.to(friend.friendId).emit("userStatus", { userId: user.id, status: "offline" }) }) await user.update({ status: "offline" }) } }) } else { socket.join(-1) socket.emit("siteState", { release: app.locals.config.release, notification: app.locals.config.notification, notificationType: app.locals.config.notificationType, latestVersion: require("../../frontend/package.json").version, allowRegistrations: app.locals.config.allowRegistrations, publicUsers: app.locals.config.publicUsers, emailVerification: app.locals.config.emailVerification, rules: app.locals.config.rules, name: app.locals.config.siteName }) socket.emit("unauthorized", { message: "Please reauth." }) socket.on("token", async () => { socket.emit("unsupported", { message: "This authentication method is unsupported." }) }) console.log("Unauthenticated user") socket.on("reAuth", async () => { socket.disconnect() }) } }) console.log("WS OK") app.set("io", io) } }