From 3a9977986b3e8bb2074a9ace4c51dc215ed07136 Mon Sep 17 00:00:00 2001 From: Thomas E Tuoti Date: Mon, 23 Dec 2024 17:33:05 -0700 Subject: [PATCH] Allow same user to login on multiple devices --- .../modules/store/sql-tiddler-database.js | 74 +++++++++++++------ 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/plugins/tiddlywiki/multiwikiserver/modules/store/sql-tiddler-database.js b/plugins/tiddlywiki/multiwikiserver/modules/store/sql-tiddler-database.js index 0c8fe8237..8f908f4af 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/store/sql-tiddler-database.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/store/sql-tiddler-database.js @@ -46,7 +46,26 @@ SqlTiddlerDatabase.prototype.transaction = function(fn) { return this.engine.transaction(fn); }; -SqlTiddlerDatabase.prototype.createTables = function() { + SqlTiddlerDatabase.prototype.createTables = function () { + // Drop and recreate sessions table + this.engine.runStatement(` + DROP TABLE IF EXISTS sessions +`); + + this.engine.runStatement(` + CREATE TABLE sessions ( + session_id TEXT PRIMARY KEY, + user_id INTEGER NOT NULL, + created_at TEXT NOT NULL, + last_accessed TEXT NOT NULL, + FOREIGN KEY (user_id) REFERENCES users(user_id) + ) +`); + + this.engine.runStatement(` + CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON sessions(user_id) +`); + this.engine.runStatements([` -- Users table CREATE TABLE IF NOT EXISTS users ( @@ -194,6 +213,19 @@ SqlTiddlerDatabase.prototype.createTables = function() { `]); }; +SqlTiddlerDatabase.prototype.updateSessionTimestamp = function(sessionId) { + const currentTimestamp = new Date().toISOString(); + + this.engine.runStatement(` + UPDATE sessions + SET last_accessed = $timestamp + WHERE session_id = $sessionId + `, { + $sessionId: sessionId, + $timestamp: currentTimestamp + }); +}; + SqlTiddlerDatabase.prototype.listBags = function() { const rows = this.engine.runStatementGetAll(` SELECT bag_name, bag_id, accesscontrol, description @@ -984,33 +1016,31 @@ SqlTiddlerDatabase.prototype.listUsers = function() { SqlTiddlerDatabase.prototype.createOrUpdateUserSession = function(userId, sessionId) { const currentTimestamp = new Date().toISOString(); - - // First, try to update an existing session - const updateResult = this.engine.runStatement(` - UPDATE sessions - SET session_id = $sessionId, last_accessed = $timestamp - WHERE user_id = $userId + + this.engine.runStatement(` + INSERT INTO sessions (session_id, user_id, created_at, last_accessed) + VALUES ($sessionId, $userId, $timestamp, $timestamp) `, { - $userId: userId, - $sessionId: sessionId, - $timestamp: currentTimestamp + $userId: userId, + $sessionId: sessionId, + $timestamp: currentTimestamp }); - // If no existing session was updated, create a new one - if (updateResult.changes === 0) { - this.engine.runStatement(` - INSERT INTO sessions (user_id, session_id, created_at, last_accessed) - VALUES ($userId, $sessionId, $timestamp, $timestamp) - `, { - $userId: userId, - $sessionId: sessionId, - $timestamp: currentTimestamp - }); - } - return sessionId; }; +SqlTiddlerDatabase.prototype.deleteExpiredSessions = function() { + const expiryTime = new Date(); + expiryTime.setHours(expiryTime.getHours() - 24); // 24 hour expiry + + this.engine.runStatement(` + DELETE FROM sessions + WHERE last_accessed < $expiryTime + `, { + $expiryTime: expiryTime.toISOString() + }); +}; + SqlTiddlerDatabase.prototype.createUserSession = function(userId, sessionId) { const currentTimestamp = new Date().toISOString(); this.engine.runStatement(`