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:
parent
2dbd0fb9dc
commit
994f1c57d3
2 changed files with 36 additions and 36 deletions
53
src/main.js
53
src/main.js
|
@ -11,50 +11,61 @@ const USERNAME = "bruno1";
|
||||||
const USER_ID = `@${USERNAME}:${HOST}`;
|
const USER_ID = `@${USERNAME}:${HOST}`;
|
||||||
const PASSWORD = "testtest";
|
const PASSWORD = "testtest";
|
||||||
|
|
||||||
function getSessionId(userId) {
|
function getSessionInfo(userId) {
|
||||||
const sessionsJson = localStorage.getItem("morpheus_sessions_v1");
|
const sessionsJson = localStorage.getItem("morpheus_sessions_v1");
|
||||||
if (sessionsJson) {
|
if (sessionsJson) {
|
||||||
const sessions = JSON.parse(sessionsJson);
|
const sessions = JSON.parse(sessionsJson);
|
||||||
const session = sessions.find(session => session.userId === userId);
|
const session = sessions.find(session => session.userId === userId);
|
||||||
if (session) {
|
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) {
|
async function login(username, password, homeserver) {
|
||||||
const hsApi = new HomeServerApi(homeserver);
|
const hsApi = new HomeServerApi(homeserver);
|
||||||
const loginData = await hsApi.passwordLogin(username, password).response();
|
const loginData = await hsApi.passwordLogin(username, password).response();
|
||||||
const sessionsJson = localStorage.getItem("morpheus_sessions_v1");
|
return storeSessionInfo(loginData);
|
||||||
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};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSession(container, session) {
|
function showSession(container, session) {
|
||||||
const vm = new SessionViewModel(session);
|
const vm = new SessionViewModel(session);
|
||||||
const view = new SessionView(vm);
|
const view = new SessionView(vm);
|
||||||
container.appendChild(view.mount());
|
view.mount();
|
||||||
|
container.appendChild(view.root());
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
export default async function main(label, button, container) {
|
export default async function main(label, button, container) {
|
||||||
try {
|
try {
|
||||||
let sessionId = getSessionId(USER_ID);
|
let sessionInfo = getSessionInfo(USER_ID);
|
||||||
let loginData;
|
if (!sessionInfo) {
|
||||||
if (!sessionId) {
|
sessionInfo = await login(USERNAME, PASSWORD, HOMESERVER);
|
||||||
({sessionId, loginData} = await login(USERNAME, PASSWORD, HOMESERVER));
|
|
||||||
}
|
}
|
||||||
const storage = await createIdbStorage(`morpheus_session_${sessionId}`);
|
const storage = await createIdbStorage(`morpheus_session_${sessionInfo.id}`);
|
||||||
const session = new Session(storage);
|
const hsApi = new HomeServerApi(HOMESERVER, sessionInfo.accessToken);
|
||||||
if (loginData) {
|
const session = new Session({storage, hsApi, sessionInfo: {
|
||||||
await session.setLoginData(loginData);
|
deviceId: sessionInfo.deviceId,
|
||||||
}
|
userId: sessionInfo.userId,
|
||||||
await session.load();
|
homeServer: sessionInfo.homeServer, //only pass relevant fields to Session
|
||||||
const hsApi = new HomeServerApi(HOMESERVER, session.accessToken);
|
}});
|
||||||
|
await session.load();
|
||||||
console.log("session loaded");
|
console.log("session loaded");
|
||||||
const needsInitialSync = !session.syncToken;
|
const needsInitialSync = !session.syncToken;
|
||||||
if (needsInitialSync) {
|
if (needsInitialSync) {
|
||||||
|
|
|
@ -2,21 +2,13 @@ import Room from "./room/room.js";
|
||||||
import { ObservableMap } from "../observable/index.js";
|
import { ObservableMap } from "../observable/index.js";
|
||||||
|
|
||||||
export default class Session {
|
export default class Session {
|
||||||
constructor(storage) {
|
constructor({storage, sessionInfo}) {
|
||||||
this._storage = storage;
|
this._storage = storage;
|
||||||
this._session = null;
|
this._session = null;
|
||||||
|
this._sessionInfo = sessionInfo;
|
||||||
this._rooms = new ObservableMap();
|
this._rooms = new ObservableMap();
|
||||||
this._roomUpdateCallback = (room, params) => this._rooms.update(room.id, params);
|
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() {
|
async load() {
|
||||||
const txn = await this._storage.readTxn([
|
const txn = await this._storage.readTxn([
|
||||||
|
@ -28,7 +20,8 @@ export default class Session {
|
||||||
// restore session object
|
// restore session object
|
||||||
this._session = await txn.session.get();
|
this._session = await txn.session.get();
|
||||||
if (!this._session) {
|
if (!this._session) {
|
||||||
throw new Error("session store is empty");
|
this._session = {};
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// load rooms
|
// load rooms
|
||||||
const rooms = await txn.roomSummary.getAll();
|
const rooms = await txn.roomSummary.getAll();
|
||||||
|
@ -58,8 +51,4 @@ export default class Session {
|
||||||
get syncToken() {
|
get syncToken() {
|
||||||
return this._session.syncToken;
|
return this._session.syncToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
get accessToken() {
|
|
||||||
return this._session.loginData.access_token;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue