2021-12-11 21:04:12 +00:00
|
|
|
import { action, computed, makeAutoObservable, ObservableMap } from "mobx";
|
2021-12-10 12:53:41 +00:00
|
|
|
import { Session } from "revolt-api/types/Auth";
|
|
|
|
import { Nullable } from "revolt.js/dist/util/null";
|
|
|
|
|
2021-12-21 12:31:14 +00:00
|
|
|
import { mapToRecord } from "../../lib/conversion";
|
|
|
|
|
2021-12-11 14:36:26 +00:00
|
|
|
import Persistent from "../interfaces/Persistent";
|
2021-12-11 16:24:23 +00:00
|
|
|
import Store from "../interfaces/Store";
|
2021-12-10 12:53:41 +00:00
|
|
|
|
2021-12-11 21:04:12 +00:00
|
|
|
interface Account {
|
|
|
|
session: Session;
|
|
|
|
}
|
|
|
|
|
2021-12-21 12:31:14 +00:00
|
|
|
export interface Data {
|
|
|
|
sessions: Record<string, Account>;
|
2021-12-10 12:53:41 +00:00
|
|
|
current?: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles account authentication, managing multiple
|
|
|
|
* accounts and their sessions.
|
|
|
|
*/
|
2021-12-11 16:24:23 +00:00
|
|
|
export default class Auth implements Store, Persistent<Data> {
|
2021-12-11 21:04:12 +00:00
|
|
|
private sessions: ObservableMap<string, Account>;
|
2021-12-10 12:53:41 +00:00
|
|
|
private current: Nullable<string>;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Construct new Auth store.
|
|
|
|
*/
|
|
|
|
constructor() {
|
2021-12-10 13:55:05 +00:00
|
|
|
this.sessions = new ObservableMap();
|
2021-12-10 12:53:41 +00:00
|
|
|
this.current = null;
|
2021-12-24 02:05:18 +00:00
|
|
|
|
|
|
|
// Inject session token if it is provided.
|
|
|
|
if (import.meta.env.VITE_SESSION_TOKEN) {
|
|
|
|
this.sessions.set("0", {
|
|
|
|
session: {
|
|
|
|
name: "0",
|
|
|
|
user_id: "0",
|
|
|
|
token: import.meta.env.VITE_SESSION_TOKEN as string,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
this.current = "0";
|
|
|
|
}
|
|
|
|
|
2021-12-10 12:53:41 +00:00
|
|
|
makeAutoObservable(this);
|
|
|
|
}
|
|
|
|
|
2021-12-11 16:24:23 +00:00
|
|
|
get id() {
|
|
|
|
return "auth";
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:04:12 +00:00
|
|
|
@action toJSON() {
|
2021-12-10 12:53:41 +00:00
|
|
|
return {
|
2021-12-21 12:31:14 +00:00
|
|
|
sessions: JSON.parse(JSON.stringify(mapToRecord(this.sessions))),
|
2021-12-11 16:24:23 +00:00
|
|
|
current: this.current ?? undefined,
|
2021-12-10 12:53:41 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2021-12-11 21:04:12 +00:00
|
|
|
@action hydrate(data: Data) {
|
|
|
|
if (Array.isArray(data.sessions)) {
|
|
|
|
data.sessions.forEach(([key, value]) =>
|
|
|
|
this.sessions.set(key, value),
|
|
|
|
);
|
|
|
|
} else if (
|
|
|
|
typeof data.sessions === "object" &&
|
|
|
|
data.sessions !== null
|
|
|
|
) {
|
|
|
|
let v = data.sessions;
|
|
|
|
Object.keys(data.sessions).forEach((id) =>
|
|
|
|
this.sessions.set(id, v[id]),
|
|
|
|
);
|
|
|
|
}
|
2021-12-10 13:55:05 +00:00
|
|
|
|
|
|
|
if (data.current && this.sessions.has(data.current)) {
|
2021-12-10 12:53:41 +00:00
|
|
|
this.current = data.current;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a new session to the auth manager.
|
|
|
|
* @param session Session
|
|
|
|
*/
|
2021-12-11 21:04:12 +00:00
|
|
|
@action setSession(session: Session) {
|
|
|
|
this.sessions.set(session.user_id, { session });
|
2021-12-10 12:53:41 +00:00
|
|
|
this.current = session.user_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove existing session by user ID.
|
|
|
|
* @param user_id User ID tied to session
|
|
|
|
*/
|
2021-12-11 21:04:12 +00:00
|
|
|
@action removeSession(user_id: string) {
|
2021-12-10 12:53:41 +00:00
|
|
|
if (user_id == this.current) {
|
|
|
|
this.current = null;
|
|
|
|
}
|
2021-12-11 21:04:12 +00:00
|
|
|
|
|
|
|
this.sessions.delete(user_id);
|
|
|
|
}
|
|
|
|
|
2021-12-12 15:47:15 +00:00
|
|
|
/**
|
|
|
|
* Remove current session.
|
|
|
|
*/
|
2021-12-11 21:04:12 +00:00
|
|
|
@action logout() {
|
|
|
|
this.current && this.removeSession(this.current);
|
|
|
|
}
|
|
|
|
|
2021-12-12 15:47:15 +00:00
|
|
|
/**
|
|
|
|
* Get current session.
|
|
|
|
* @returns Current session
|
|
|
|
*/
|
2021-12-11 21:04:12 +00:00
|
|
|
@computed getSession() {
|
|
|
|
if (!this.current) return;
|
|
|
|
return this.sessions.get(this.current)!.session;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check whether we are currently logged in.
|
|
|
|
* @returns Whether we are logged in
|
|
|
|
*/
|
|
|
|
@computed isLoggedIn() {
|
|
|
|
return this.current !== null;
|
2021-12-10 12:53:41 +00:00
|
|
|
}
|
|
|
|
}
|