Files
timmal/app/composables/useAuth.ts
Lucien Cartier-Tilet 40ae2145cc
All checks were successful
ci / ci (push) Successful in 16m22s
feat: authentication with OAuth
2025-12-12 03:08:52 +01:00

85 lines
2.2 KiB
TypeScript

import type { AuthProviderInfo, RecordModel } from 'pocketbase';
import { usePocketbase } from './usePocketbase';
export interface LoggedInUser extends RecordModel {
id: string;
email: string;
emailVisibility: boolean;
verified: boolean;
name: string;
avatar?: string;
created: Date;
updated: Date;
}
const user = ref<LoggedInUser | null>(null);
const loading = ref<boolean>(false);
const error = ref<Error | null>(null);
export const useAuth = () => {
const pb = usePocketbase();
const router = useRouter();
const userCollection = 'users';
const isAuthenticated = computed<boolean>(() => pb.authStore.isValid && !!user.value);
const initAuth = async () => {
user.value = pb.authStore.record as LoggedInUser;
pb.authStore.onChange((_token, model) => (user.value = model as LoggedInUser));
};
const authProviders = async (): Promise<AuthProviderInfo[]> => {
const authMethods = await pb.collection(userCollection).listAuthMethods();
return authMethods.oauth2.enabled ? authMethods.oauth2.providers : [];
};
const login = async (provider: string) => {
loading.value = true;
error.value = null;
try {
const providers = await authProviders();
const providerData = providers.find((p) => p.name === provider);
if (!providerData) {
throw new Error(`${provider} OAuth is not configured`);
}
const response = await pb.collection(userCollection).authWithOAuth2({ provider });
user.value = response.record as LoggedInUser;
} catch (pbError) {
error.value = pbError as Error;
} finally {
loading.value = false;
}
};
const refreshAuth = async () => await pb.collection(userCollection).authRefresh();
const handleOAuthCallback = async () => {
user.value = pb.authStore.record as LoggedInUser;
if (isAuthenticated.value) {
await router.push('/dashboard');
} else {
await router.push('/');
}
};
const logout = () => {
pb.authStore.clear();
user.value = null;
error.value = null;
};
return {
user,
loading,
error,
isAuthenticated,
login,
logout,
initAuth,
refreshAuth,
handleOAuthCallback,
authProviders,
};
};