basic session manager

This commit is contained in:
Bruno Windels 2019-02-06 23:19:14 +00:00
parent 7601a9b2f8
commit 7a15f12525
6 changed files with 40 additions and 64 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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() {

View file

@ -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;