feat: migrate authentication to Better Auth and update profile management logic
This commit is contained in:
@@ -15,6 +15,7 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import type { UserProfileResponse } from '@repo/api-contract';
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { useEffect } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
|
||||
@@ -62,19 +63,27 @@ export function ProfilePage() {
|
||||
},
|
||||
});
|
||||
|
||||
// Sync form with displayName when session data is loaded or updated elsewhere
|
||||
useEffect(() => {
|
||||
if (displayName && !updateProfileForm.formState.isDirty) {
|
||||
updateProfileForm.reset({ fullName: displayName });
|
||||
}
|
||||
}, [displayName, updateProfileForm]);
|
||||
|
||||
const updateProfileMutation = useMutation({
|
||||
mutationFn: updateProfile,
|
||||
onSuccess: () => {
|
||||
onSuccess: (_, variables) => {
|
||||
queryClient.invalidateQueries({ queryKey: ['user-profile'] });
|
||||
updateProfileForm.reset();
|
||||
updateProfileForm.reset({ fullName: variables.fullName });
|
||||
},
|
||||
});
|
||||
|
||||
const updatePasswordMutation = useMutation({
|
||||
mutationFn: async (data: UpdatePasswordForm) => {
|
||||
// Note: Supabase doesn't require current password for password update
|
||||
// The user needs to be recently authenticated
|
||||
await updatePassword({ password: data.newPassword });
|
||||
await updatePassword({
|
||||
currentPassword: data.currentPassword,
|
||||
password: data.newPassword,
|
||||
});
|
||||
},
|
||||
onSuccess: () => {
|
||||
updatePasswordForm.reset();
|
||||
@@ -118,9 +127,7 @@ export function ProfilePage() {
|
||||
<AvatarFallback>{initials}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div>
|
||||
<h1 className="text-2xl font-semibold">
|
||||
{profileQuery.data?.fullName ?? displayName}
|
||||
</h1>
|
||||
<h1 className="text-2xl font-semibold">{displayName}</h1>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{profileQuery.data?.email ?? user?.email}
|
||||
</p>
|
||||
|
||||
@@ -20,6 +20,7 @@ type UpdateProfileParams = {
|
||||
};
|
||||
|
||||
type UpdatePasswordParams = {
|
||||
currentPassword?: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
@@ -172,11 +173,11 @@ export function AuthProvider({ children }: PropsWithChildren) {
|
||||
}
|
||||
|
||||
return {
|
||||
requiresEmailConfirmation: !signUpData?.session,
|
||||
requiresEmailConfirmation: !signUpData || !('session' in signUpData),
|
||||
};
|
||||
},
|
||||
updateProfile: async ({ fullName }) => {
|
||||
const { error } = await authClient.user.update({
|
||||
const { error } = await authClient.updateUser({
|
||||
name: fullName,
|
||||
});
|
||||
|
||||
@@ -184,10 +185,11 @@ export function AuthProvider({ children }: PropsWithChildren) {
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
updatePassword: async ({ password }) => {
|
||||
updatePassword: async ({ currentPassword, password }) => {
|
||||
// Better Auth uses changePassword for authenticated users
|
||||
const { error } = await authClient.changePassword({
|
||||
newPassword: password,
|
||||
currentPassword: currentPassword || '',
|
||||
revokeOtherSessions: true,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user