feature/IO-3096-GlobalNotifications - Checkpoint, socket to email to bodyshop mapping.

This commit is contained in:
Dave Richer
2025-02-18 11:02:46 -05:00
parent a15f86cc4e
commit c02c36c548
4 changed files with 123 additions and 128 deletions

View File

@@ -3,12 +3,13 @@ const { admin } = require("../firebase/firebase-handler");
const redisSocketEvents = ({
io,
redisHelpers: {
setSessionData,
clearSessionData,
addUserSocketMapping,
removeUserSocketMapping,
getUserSocketMapping
}, // Note: Used if we persist user to Redis
setSessionData,
getSessionData,
clearSessionData,
refreshUserSocketTTL
},
ioHelpers: { getBodyshopRoom, getBodyshopConversationRoom },
logger
}) => {
@@ -19,16 +20,18 @@ const redisSocketEvents = ({
// Socket Auth Middleware
const authMiddleware = async (socket, next) => {
if (!socket.handshake.auth.token) {
const { token, bodyshopId } = socket.handshake.auth;
if (!token) {
return next(new Error("Authentication error - no authorization token."));
}
if (!bodyshopId) {
return next(new Error("Authentication error - no bodyshopId provided."));
}
try {
const user = await admin.auth().verifyIdToken(socket.handshake.auth.token);
const user = await admin.auth().verifyIdToken(token);
socket.user = user;
// Persist the user data in Redis for this socket
await setSessionData(socket.id, "user", user);
// Store a mapping from the user's email to the socket id
// await addUserSocketMapping(user.email, socket.id);
await setSessionData(socket.id, "user", { ...user, bodyshopId });
await addUserSocketMapping(user.email, socket.id, bodyshopId);
next();
} catch (error) {
next(new Error(`Authentication error: ${error.message}`));
@@ -37,32 +40,33 @@ const redisSocketEvents = ({
// Register Socket Events
const registerSocketEvents = (socket) => {
// Uncomment for further testing
// createLogEvent(socket, "debug", `Registering RedisIO Socket Events.`);
// getUserSocketMapping(socket.user.email).then((socketIds) => {
// console.log(socketIds);
// });
// Token Update Events
const registerUpdateEvents = (socket) => {
let latestTokenTimestamp = 0;
const updateToken = async (newToken) => {
const updateToken = async ({ token, bodyshopId }) => {
const currentTimestamp = Date.now();
latestTokenTimestamp = currentTimestamp;
if (!token || !bodyshopId) {
socket.emit("token-updated", { success: false, error: "Token or bodyshopId missing" });
return;
}
try {
const user = await admin.auth().verifyIdToken(newToken, true);
const user = await admin.auth().verifyIdToken(token, true);
if (currentTimestamp < latestTokenTimestamp) {
createLogEvent(socket, "warn", "Outdated token validation skipped.");
return;
}
socket.user = user;
// Update the session data in Redis with the new token info
// await setSessionData(socket.id, "user", user);
// Update the mapping with the user's email
await addUserSocketMapping(user.email, socket.id);
createLogEvent(socket, "debug", `Token updated successfully for socket ID: ${socket.id}`);
await setSessionData(socket.id, "user", { ...user, bodyshopId });
await refreshUserSocketTTL(user.email, bodyshopId);
createLogEvent(
socket,
"debug",
`Token updated successfully for socket ID: ${socket.id} (bodyshop: ${bodyshopId})`
);
socket.emit("token-updated", { success: true });
} catch (error) {
if (error.code === "auth/id-token-expired") {
@@ -119,21 +123,19 @@ const redisSocketEvents = ({
// Disconnect Events
const registerDisconnectEvents = (socket) => {
const disconnect = async () => {
// Remove session data from Redis
// await clearSessionData(socket.id);
// Remove the mapping from user email to this socket id, if available
// if (socket.user?.email) {
// await removeUserSocketMapping(socket.user.email, socket.id);
// }
// Leave all joined rooms
if (socket.user?.email) {
const userData = await getSessionData(socket.id, "user");
const bodyshopId = userData?.bodyshopId;
if (bodyshopId) {
await removeUserSocketMapping(socket.user.email, socket.id, bodyshopId);
}
await clearSessionData(socket.id);
}
const rooms = Array.from(socket.rooms).filter((room) => room !== socket.id);
for (const room of rooms) {
socket.leave(room);
}
};
socket.on("disconnect", disconnect);
};
@@ -152,6 +154,7 @@ const redisSocketEvents = ({
});
}
};
const leaveConversationRoom = ({ bodyshopId, conversationId }) => {
try {
const room = getBodyshopConversationRoom({ bodyshopId, conversationId });