From ff2c4c203ec3240d8e09bcb0d668d5f8d348889e Mon Sep 17 00:00:00 2001 From: Lucien Cartier-Tilet Date: Sat, 17 Feb 2024 03:40:48 +0100 Subject: [PATCH] refactor(models, store): stronger typing --- src/models/Auth.ts | 55 ++++++++++++++++++++++++++++++++++++++++ src/models/User.ts | 1 - src/stores/pocketbase.ts | 15 +++++++---- 3 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 src/models/Auth.ts diff --git a/src/models/Auth.ts b/src/models/Auth.ts new file mode 100644 index 0000000..5bfe1ec --- /dev/null +++ b/src/models/Auth.ts @@ -0,0 +1,55 @@ +import type { RecordAuthResponse } from "pocketbase"; +import { User, type IUser } from "./User"; + +interface IAuthenticatedUser { + id: string, + name?: string, + username: string, + email: string, + avatarUrl?: string, + accessToken: string, + refreshToken: string, + rawUser?: { [key: string]: any }; +} + +export interface IOAuthResponse extends RecordAuthResponse { + token: string, + record: IUser, + meta?: IAuthenticatedUser +} + +class AuthenticatedUser implements IAuthenticatedUser { + id: string; + name?: string; + username: string; + email: string; + avatarUrl?: string; + accessToken: string; + refreshToken: string; + rawUser?: { [key: string]: any; }; + + constructor(from: IAuthenticatedUser) { + this.id = from.id; + this.name = from.name; + this.username = from.username; + this.email = from.email; + this.avatarUrl = from.avatarUrl; + this.accessToken = from.accessToken; + this.refreshToken = from.refreshToken; + this.rawUser = from.rawUser; + } +} + +export class OAuthResponse implements IOAuthResponse { + token: string; + record: User; + meta?: AuthenticatedUser; + + constructor(from: RecordAuthResponse) { + this.token = from.token; + this.record = new User(from.record); + if(from.meta) { + this.meta = new AuthenticatedUser(from.meta as IAuthenticatedUser); + } + } +} diff --git a/src/models/User.ts b/src/models/User.ts index 5af1089..f049cda 100644 --- a/src/models/User.ts +++ b/src/models/User.ts @@ -7,7 +7,6 @@ export interface ISimpleUser extends RecordModel { name?: string; avatar?: string; expand?: { [key: string]: any }; - avatarLink: (pbStore: any) => Observable; } export interface IUser extends SimpleUser { diff --git a/src/stores/pocketbase.ts b/src/stores/pocketbase.ts index 918e346..28f26dd 100644 --- a/src/stores/pocketbase.ts +++ b/src/stores/pocketbase.ts @@ -5,6 +5,7 @@ import { computed, ref } from 'vue'; import { Campaign, type ICampaign, type NewCampaign } from '@/models/Campaign'; import { SimpleUser, type IUser } from '@/models/User'; +import { OAuthResponse } from '@/models/Auth'; export const usePocketbaseStore = defineStore('pocketbase', () => { const pb = new PocketBase(import.meta.env.VITE_PB_URL); @@ -14,20 +15,24 @@ export const usePocketbaseStore = defineStore('pocketbase', () => { // Authentication // ///////////////////////////////////////////////////////////////////////////// - const authData = ref | null>(null); + const authData = ref(null); const authStore = computed(() => pb.authStore); const loggedIn = computed(() => pb.authStore.isValid); const username = computed(() => authStore.value.model?.username); const userId = computed(() => authStore.value.model?.id); - function login(): Observable> { - return from(pb.collection('users').authWithOAuth2({ provider: 'discord' })).pipe( - map((auth) => (authData.value = auth)) + function login(): Observable { + return from(pb.collection('users').authWithOAuth2({ provider: 'discord' })).pipe( + map((auth) => new OAuthResponse(auth)), + tap((auth) => (authData.value = auth)) ); } function refresh(): Observable> { - return from(pb.collection('users').authRefresh()).pipe(tap((auth) => (authData.value = auth))); + return from(pb.collection('users').authRefresh()).pipe( + map((auth) => new OAuthResponse(auth)), + tap((auth) => (authData.value = auth)) + ); } function logout() {