From 7a15f12525ab012c24bb9a31e114c98638182ee7 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 6 Feb 2019 23:19:14 +0000 Subject: [PATCH] basic session manager --- src/main.js | 39 +++++++++++++++++-------- src/storage/idb/create.js | 2 +- src/storage/idb/storage.js | 2 +- src/storage/idb/stores/session-index.js | 39 ------------------------- src/storage/idb/transaction.js | 20 ++++++------- src/storage/idb/utils.js | 2 +- 6 files changed, 40 insertions(+), 64 deletions(-) delete mode 100644 src/storage/idb/stores/session-index.js diff --git a/src/main.js b/src/main.js index 8f88bc0c..b7398b2b 100644 --- a/src/main.js +++ b/src/main.js @@ -3,22 +3,37 @@ import Session from "./session.js"; import createIdbStorage from "./storage/idb/create.js"; const HOMESERVER = "http://localhost:8008"; -async function getLoginData(username, password) { - const storedCredentials = localStorage.getItem("morpheus_login"); - if (!storedCredentials) { - const api = new Network(HOMESERVER); - const loginData = await api.passwordLogin(username, password).response(); - localStorage.setItem("morpheus_login", JSON.stringify(loginData)); - return loginData; - } else { - return JSON.parse(storedCredentials); +function getSessionId(userId) { + const sessionsJson = localStorage.getItem("morpheus_sessions_v1"); + if (sessionsJson) { + const sessions = JSON.parse(sessionsJson); + const session = sessions.find(session => session.userId === userId); + if (session) { + return session.id; + } } } +async function login(username, password, homeserver) { + const api = new Network(homeserver); + const loginData = await api.passwordLogin(username, password).response(); + const sessionsJson = localStorage.getItem("morpheus_sessions_v1"); + const sessions = sessionsJson ? JSON.parse(sessionsJson) : []; + const sessionId = (Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)).toString(); + console.log(loginData); + sessions.push({userId: loginData.user_id, id: sessionId}); + localStorage.setItem("morpheus_sessions_v1", JSON.stringify(sessions)); + return {sessionId, loginData}; +} + async function main() { - const loginData = await getLoginData("bruno1", "testtest"); - const network = new Network(HOMESERVER, loginData.access_token); - const storage = await createIdbStorage("morpheus_session"); + let sessionId = getSessionId("@bruno1:localhost"); + let loginData; + if (!sessionId) { + ({sessionId, loginData} = await login("bruno1", "testtest", "http://localhost:8008")); + } + const storage = await createIdbStorage(`morpheus_session_${sessionId}`); + console.log("database created", storage); const session = new Session(loginData, storage); await session.load(); const sync = new Sync(network, session, storage); diff --git a/src/storage/idb/create.js b/src/storage/idb/create.js index 3899bef2..7074c437 100644 --- a/src/storage/idb/create.js +++ b/src/storage/idb/create.js @@ -2,7 +2,7 @@ import Storage from "./storage.js"; import { openDatabase } from "./utils.js"; export default async function createIdbStorage(databaseName) { - const db = await openDatabase(databaseName, createStores); + const db = await openDatabase(databaseName, createStores, 1); return new Storage(db); } diff --git a/src/storage/idb/storage.js b/src/storage/idb/storage.js index ba16573b..ada97bac 100644 --- a/src/storage/idb/storage.js +++ b/src/storage/idb/storage.js @@ -1,4 +1,4 @@ -export const STORE_NAMES = ["sync", "roomState", "roomSummary", "roomTimeline"]; +export const STORE_NAMES = ["session", "roomState", "roomSummary", "roomTimeline"]; export default class Storage { constructor(idbDatabase) { diff --git a/src/storage/idb/stores/session-index.js b/src/storage/idb/stores/session-index.js deleted file mode 100644 index a67096a4..00000000 --- a/src/storage/idb/stores/session-index.js +++ /dev/null @@ -1,39 +0,0 @@ -import {openDatabase, select} from "./utils"; - -function createSessionsStore(db) { - db.createObjectStore("sessions", "id"); -} - -function createStores(db) { - db.createObjectStore("sync"); //sync token - db.createObjectStore("roomSummary", "room_id", {unique: true}); - const timeline = db.createObjectStore("roomTimeline", ["room_id", "sort_key"]); - timeline.createIndex("by_event_id", ["room_id", "event.event_id"], {unique: true}); - // how to get the first/last x events for a room? - // we don't want to specify the sort key, but would need an index for the room_id? - // take sort_key as primary key then and have index on event_id? - // still, you also can't have a PK of [room_id, sort_key] and get the last or first events with just the room_id? the only thing that changes it that the PK will provide an inherent sorting that you inherit in an index that only has room_id as keyPath??? There must be a better way, need to write a prototype test for this. - // SOLUTION: with numeric keys, you can just us a min/max value to get first/last - // db.createObjectStore("members", ["room_id", "state_key"]); - const state = db.createObjectStore("roomState", ["event.room_id", "event.type", "event.state_key"]); -} - -class Sessions { - - constructor(databaseName, idToSessionDbName) { - this._databaseName = databaseName; - this._idToSessionDbName = idToSessionDbName; - } - - async getSessions(sessionsDbName) { - const db = await openDatabase(this._databaseName, db => createSessionsStore(db)); - const sessions = await select(db, "sessions"); - db.close(); - return sessions; - } - - async openSessionStore(session) { - const db = await openDatabase(this._idToSessionDbName(session.id), db => createStores(db)); - return new SessionStore(db); - } -} diff --git a/src/storage/idb/transaction.js b/src/storage/idb/transaction.js index 4dfaea39..bcfe596b 100644 --- a/src/storage/idb/transaction.js +++ b/src/storage/idb/transaction.js @@ -7,14 +7,14 @@ export default class Transaction { this._txn = txn; this._allowedStoreNames = allowedStoreNames; this._stores = { - sync: null, - summary: null, - timeline: null, - state: null, + session: null, + roomSummary: null, + roomTimeline: null, + roomState: null, }; } - _store(name) { + _idbStore(name) { if (!this._allowedStoreNames.includes(name)) { // more specific error? this is a bug, so maybe not ... throw new Error(`Invalid store for transaction: ${name}, only ${this._allowedStoreNames.join(", ")} are allowed.`); @@ -22,12 +22,12 @@ export default class Transaction { return new Store(this._txn.getObjectStore(name)); } - get timeline() { - if (!this._stores.timeline) { - const idbStore = this._idbStore("timeline"); - this._stores.timeline = new TimelineStore(idbStore); + get roomTimeline() { + if (!this._stores.roomTimeline) { + const idbStore = this._idbStore("roomTimeline"); + this._stores.roomTimeline = new TimelineStore(idbStore); } - return this._stores.timeline; + return this._stores.roomTimeline; } complete() { diff --git a/src/storage/idb/utils.js b/src/storage/idb/utils.js index c48453f2..1d522f24 100644 --- a/src/storage/idb/utils.js +++ b/src/storage/idb/utils.js @@ -1,4 +1,4 @@ -export function openDatabase(name, createObjectStore, version = undefined) { +export function openDatabase(name, createObjectStore, version) { const req = window.indexedDB.open(name, version); req.onupgradeneeded = (ev) => { const db = ev.target.result;