Hi, after a lot of trial and thanks to chatGPT’s expertise on the matter
I found a working code, but it has a major drawback as it takes its toll on server performance and it uses databases so the more users you have the more you will need to pay for the website to actually keep working. Also, it only works with the default login.
Frontend :
import wixUsers from 'wix-users';
import {registerSession, invalidateOtherSessions, isSessionValid} from 'backend/sessionManager';
import wixLocation from 'wix-location';
let checkSessionInterval;
wixUsers.onLogin((user) => {
registerSession(user.id)
.then((sessionId) => {
// The session is now registered. Next, invalidate any other sessions.
invalidateOtherSessions(user.id, sessionId);
// Set interval to check if session is still valid every minute
checkSessionInterval = setInterval(() => {
isSessionValid(user.id, sessionId)
.then(valid => {
console.log(`Session validity checked at ${new Date().toString()}. Status: ${valid ? 'Valid' : 'Invalid'}`);
if(!valid) {
clearInterval(checkSessionInterval);
wixLocation.to("/sessioninterrupted");
}
})
.catch((error) => {
console.log("Error checking session: ", error);
});
}, 300000); // Check every 30sec
})
.catch((error) => {
console.log("Error managing session: ", error);
});
});
Backend :
import wixData from 'wix-data';
import {v4 as uuidv4} from 'uuid'; // Importing UUID generator
// Registers a new session
export function registerSession(userId) {
const sessionId = uuidv4(); // generates a unique session ID
return wixData.insert('UserSessions', {
userId,
sessionId,
loginTimestamp: new Date()
}).then(() => sessionId); // returns the sessionId for later checks
}
// Invalidates other sessions this user has, with added logging for debugging
export function invalidateOtherSessions(userId, currentSessionId) {
// Log when the function is called, along with the userId and currentSessionId
console.log("invalidateOtherSessions called for userId:", userId, "with currentSessionId:", currentSessionId);
return wixData.query('UserSessions')
.eq('userId', userId)
.ne('sessionId', currentSessionId)
.find()
.then(results => {
// Log how many sessions were found to invalidate
console.log(`Found ${results.items.length} sessions to invalidate for user ${userId}`);
const itemsToRemove = results.items.map(item => item._id);
// If there are sessions to remove, proceed with removal
if (itemsToRemove.length > 0) {
return wixData.bulkRemove('UserSessions', itemsToRemove)
.then((results) => {
// Log successful removal
console.log(`Successfully removed ${results.length} sessions for user ${userId}`);
return results; // Return the removal results
})
.catch((error) => {
// Log if there was an error during removal
console.error("Error during session invalidation: ", error);
throw error; // Rethrow the error to handle it outside if needed
});
} else {
// Log if no sessions to remove were found
console.log("No sessions to remove were found.")
return null; // Return null if there's nothing to remove
}
})
.catch((error) => {
// Log if there was an error during the query operation
console.error("Error querying sessions for invalidation: ", error);
throw error; // Rethrow the error to handle it outside if needed
});
}
export function isSessionValid(userId, sessionId) {
return wixData.query('UserSessions')
.eq('userId', userId)
.eq('sessionId', sessionId)
.find()
.then(results => results.items.length > 0 ? true : false) // Return true if session is still valid, false otherwise
.catch((error) => {
// Log if there was an error during the query operation
console.error("Error querying session validation: ", error);
throw error; // Rethrow the error to handle it outside if needed
});
}
session interrupted page :
import wixUsers from 'wix-users';
$w.onReady(function () {
wixUsers.logout()
});
You will need to create a sessioninterrupted page to redirect disconnected users, and a database with the correct parameters. Logs are also included in the code so you can check for errors directly in the logs.
If you have a better way to do it please feel free to share I would be greatful.