use singleton context to manage user state

This commit is contained in:
Hayden 2023-03-22 21:13:16 -08:00
parent 29f2f7bcfe
commit a275090e03
No known key found for this signature in database
GPG key ID: 17CF79474E257545
2 changed files with 30 additions and 20 deletions

View file

@ -4,7 +4,6 @@ import { UserOut } from "~~/lib/api/types/data-contracts";
import { UserClient } from "~~/lib/api/user"; import { UserClient } from "~~/lib/api/user";
export interface IAuthContext { export interface IAuthContext {
self?: UserOut;
get token(): string | null; get token(): string | null;
get expiresAt(): string | null; get expiresAt(): string | null;
get attachmentToken(): string | null; get attachmentToken(): string | null;
@ -41,6 +40,9 @@ export interface IAuthContext {
} }
class AuthContext implements IAuthContext { class AuthContext implements IAuthContext {
// eslint-disable-next-line no-use-before-define
private static _instance?: AuthContext;
user?: UserOut; user?: UserOut;
private _token: CookieRef<string | null>; private _token: CookieRef<string | null>;
private _expiresAt: CookieRef<string | null>; private _expiresAt: CookieRef<string | null>;
@ -58,14 +60,18 @@ class AuthContext implements IAuthContext {
return this._attachmentToken.value; return this._attachmentToken.value;
} }
constructor( private constructor(token: string, expiresAt: string, attachmentToken: string) {
token: CookieRef<string | null>, this._token = useCookie(token);
expiresAt: CookieRef<string | null>, this._expiresAt = useCookie(expiresAt);
attachmentToken: CookieRef<string | null> this._attachmentToken = useCookie(attachmentToken);
) { }
this._token = token;
this._expiresAt = expiresAt; static get instance() {
this._attachmentToken = attachmentToken; if (!this._instance) {
this._instance = new AuthContext("hb.auth.token", "hb.auth.expires_at", "hb.auth.attachment_token");
}
return this._instance;
} }
isExpired() { isExpired() {
@ -81,14 +87,21 @@ class AuthContext implements IAuthContext {
} }
isAuthorized() { isAuthorized() {
return this._token.value !== null && !this.isExpired(); return !!this._token.value && !this.isExpired();
} }
invalidateSession() { invalidateSession() {
this.user = undefined; this.user = undefined;
this._token.value = null;
this._expiresAt.value = null; // Delete the cookies
this._attachmentToken.value = null; // @ts-expect-error
this._token.value = undefined;
// @ts-expect-error
this._expiresAt.value = undefined;
// @ts-expect-error
this._attachmentToken.value = undefined;
console.log("Session invalidated");
} }
async login(api: PublicApi, email: string, password: string) { async login(api: PublicApi, email: string, password: string) {
@ -121,9 +134,5 @@ class AuthContext implements IAuthContext {
} }
export function useAuthContext(): IAuthContext { export function useAuthContext(): IAuthContext {
const tokenCookie = useCookie("hb.auth.token"); return AuthContext.instance;
const expiresAtCookie = useCookie("hb.auth.expires_at");
const attachmentTokenCookie = useCookie("hb.auth.attachment_token");
return new AuthContext(tokenCookie, expiresAtCookie, attachmentTokenCookie);
} }

View file

@ -82,14 +82,15 @@
const auth = useAuthContext(); const auth = useAuthContext();
const details = computed(() => { const details = computed(() => {
console.log(auth.user);
return [ return [
{ {
name: "Name", name: "Name",
text: auth.self?.name || "Unknown", text: auth.user?.name || "Unknown",
}, },
{ {
name: "Email", name: "Email",
text: auth.self?.email || "Unknown", text: auth.user?.email || "Unknown",
}, },
] as Detail[]; ] as Detail[];
}); });