133 lines
4.2 KiB
TypeScript
133 lines
4.2 KiB
TypeScript
import {PublicUserData} from '../domain/common.schema.js';
|
|
import {DatabaseAPI} from '../storage/database.js';
|
|
import {KeyringAPI} from '../storage/keyring.js';
|
|
import {KeyValueAPI} from '../storage/keyvalue.js';
|
|
import {Session, ValidateSessionReq, ValidateSessionResp} from '../domain/sessionManager.schema.js';
|
|
import {AxiosInstance} from "axios";
|
|
import {getClient} from '../core/http.js';
|
|
import {PersonalUserData} from '../domain/userService.schema.js';
|
|
|
|
export class SessionManager {
|
|
client: AxiosInstance;
|
|
database: DatabaseAPI;
|
|
keyring: KeyringAPI;
|
|
KeyValue: KeyValueAPI;
|
|
|
|
constructor(database: DatabaseAPI, keyring: KeyringAPI, KeyValue: KeyValueAPI) {
|
|
this.database = database;
|
|
this.keyring = keyring;
|
|
this.KeyValue = KeyValue;
|
|
this.client = getClient(false)
|
|
}
|
|
|
|
/**
|
|
* Saves the new session to the database and the keyring
|
|
* @param userData
|
|
* @param token
|
|
*/
|
|
addSession(userData: PublicUserData, token: string): void {
|
|
this.database.set("sessions", userData.userid, JSON.stringify(userData))
|
|
this.keyring.set(userData.userid, token)
|
|
}
|
|
|
|
/**
|
|
* Loads all saved sessions
|
|
*/
|
|
async loadSessions(): Promise<Session[]> {
|
|
const tokens = await this.keyring.getAll()
|
|
const sessions: Session[] = []
|
|
for (const token of tokens) {
|
|
const userData = await this.database.get("sessions", token.split(".")[0])
|
|
if (userData) {
|
|
sessions.push({
|
|
token: token,
|
|
userData: JSON.parse(userData)
|
|
})
|
|
}
|
|
}
|
|
|
|
return sessions
|
|
}
|
|
|
|
/**
|
|
* Gets the preferred user set by the client
|
|
*/
|
|
async getPreferredUser(): Promise<string> {
|
|
return await this.KeyValue.get("preferredUser") ?? ""
|
|
}
|
|
|
|
/**
|
|
* Sets a new preferred user
|
|
* @param userid
|
|
*/
|
|
setPreferredUser(userid: string): void {
|
|
this.KeyValue.set("preferredUser", userid)
|
|
}
|
|
|
|
/**
|
|
* Loads the preferred session by the client
|
|
*/
|
|
async loadPreferredSession() {
|
|
const sessions = await this.loadSessions()
|
|
let preferredUser = await this.getPreferredUser()
|
|
if (preferredUser == "") {
|
|
preferredUser = sessions[0].userData.userid
|
|
this.setPreferredUser(sessions[0].userData.userid)
|
|
}
|
|
|
|
const preferredSession = sessions.find(s => s.userData.userid == preferredUser)
|
|
if (preferredSession) {
|
|
return preferredSession
|
|
} else {
|
|
return sessions[0]
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validates and updates all sessions and returns with a new session list
|
|
* @param sessions
|
|
*/
|
|
updateSessions(sessions: Session[]): Session[] {
|
|
sessions.forEach(async session => {
|
|
const index = sessions.indexOf(session)
|
|
if (!await this.validateSession(session.token)) {
|
|
this.database.delete("sessions", session.userData.userid)
|
|
this.keyring.delete(session.userData.userid)
|
|
sessions.splice(index, 1)
|
|
}
|
|
|
|
const updatedUserData = await this.updateUserData(session)
|
|
this.database.set("sessions", session.userData.userid, updatedUserData)
|
|
sessions[index] = updatedUserData
|
|
})
|
|
|
|
return sessions
|
|
}
|
|
|
|
private async validateSession(token: string): Promise<boolean> {
|
|
try {
|
|
const resp = await this.client.post<ValidateSessionResp>("v2/user/validateSession", <ValidateSessionReq>{
|
|
token: token,
|
|
})
|
|
return resp.data.validationOk
|
|
} catch (e) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
private async updateUserData(session: Session): Promise<Session> {
|
|
const authenticatedClient = this.client.create({
|
|
headers: {
|
|
"Authorization": session.token,
|
|
}
|
|
})
|
|
|
|
try {
|
|
const resp = await authenticatedClient.get<PersonalUserData>(`user/byUseridPersonal?userid=${session.userData.userid}`)
|
|
session.userData = resp.data
|
|
return session
|
|
} catch (e) {
|
|
throw new Error("Session update error")
|
|
}
|
|
}
|
|
} |