store all logout data outside of the session storage

so we could store it in gnome keyring, macOs keychain, ... on non-webclients,
also better separation
This commit is contained in:
Bruno Windels 2019-03-08 20:00:37 +01:00
parent 2dbd0fb9dc
commit 994f1c57d3
2 changed files with 36 additions and 36 deletions

View file

@ -11,50 +11,61 @@ const USERNAME = "bruno1";
const USER_ID = `@${USERNAME}:${HOST}`;
const PASSWORD = "testtest";
function getSessionId(userId) {
function getSessionInfo(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;
return session;
}
}
}
function storeSessionInfo(loginData) {
const sessionsJson = localStorage.getItem("morpheus_sessions_v1");
const sessions = sessionsJson ? JSON.parse(sessionsJson) : [];
const sessionId = (Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)).toString();
const sessionInfo = {
id: sessionId,
deviceId: loginData.device_id,
userId: loginData.user_id,
homeServer: loginData.home_server,
accessToken: loginData.access_token,
};
sessions.push(sessionInfo);
localStorage.setItem("morpheus_sessions_v1", JSON.stringify(sessions));
return sessionInfo;
}
async function login(username, password, homeserver) {
const hsApi = new HomeServerApi(homeserver);
const loginData = await hsApi.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};
return storeSessionInfo(loginData);
}
function showSession(container, session) {
const vm = new SessionViewModel(session);
const view = new SessionView(vm);
container.appendChild(view.mount());
view.mount();
container.appendChild(view.root());
}
// eslint-disable-next-line no-unused-vars
export default async function main(label, button, container) {
try {
let sessionId = getSessionId(USER_ID);
let loginData;
if (!sessionId) {
({sessionId, loginData} = await login(USERNAME, PASSWORD, HOMESERVER));
let sessionInfo = getSessionInfo(USER_ID);
if (!sessionInfo) {
sessionInfo = await login(USERNAME, PASSWORD, HOMESERVER);
}
const storage = await createIdbStorage(`morpheus_session_${sessionId}`);
const session = new Session(storage);
if (loginData) {
await session.setLoginData(loginData);
}
await session.load();
const hsApi = new HomeServerApi(HOMESERVER, session.accessToken);
const storage = await createIdbStorage(`morpheus_session_${sessionInfo.id}`);
const hsApi = new HomeServerApi(HOMESERVER, sessionInfo.accessToken);
const session = new Session({storage, hsApi, sessionInfo: {
deviceId: sessionInfo.deviceId,
userId: sessionInfo.userId,
homeServer: sessionInfo.homeServer, //only pass relevant fields to Session
}});
await session.load();
console.log("session loaded");
const needsInitialSync = !session.syncToken;
if (needsInitialSync) {

View file

@ -2,21 +2,13 @@ import Room from "./room/room.js";
import { ObservableMap } from "../observable/index.js";
export default class Session {
constructor(storage) {
constructor({storage, sessionInfo}) {
this._storage = storage;
this._session = null;
this._sessionInfo = sessionInfo;
this._rooms = new ObservableMap();
this._roomUpdateCallback = (room, params) => this._rooms.update(room.id, params);
}
// should be called before load
// loginData has device_id, user_id, home_server, access_token
async setLoginData(loginData) {
console.log("session.setLoginData");
const txn = await this._storage.readWriteTxn([this._storage.storeNames.session]);
const session = {loginData};
txn.session.set(session);
await txn.complete();
}
async load() {
const txn = await this._storage.readTxn([
@ -28,7 +20,8 @@ export default class Session {
// restore session object
this._session = await txn.session.get();
if (!this._session) {
throw new Error("session store is empty");
this._session = {};
return;
}
// load rooms
const rooms = await txn.roomSummary.getAll();
@ -58,8 +51,4 @@ export default class Session {
get syncToken() {
return this._session.syncToken;
}
get accessToken() {
return this._session.loginData.access_token;
}
}