From 5302060f44ca9ace103b2ea8a1f47865e2fe41ad Mon Sep 17 00:00:00 2001 From: charlesgauthereau Date: Tue, 23 Dec 2025 21:44:52 +0100 Subject: [PATCH] Working and testing the profile module. --- portabase.config.ts | 1 + .../dashboard/profile/profile-providers.tsx | 25 ++++--- src/lib/auth/auth.ts | 75 ++++++++++++++----- 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/portabase.config.ts b/portabase.config.ts index cdd6dd05..a51829a4 100644 --- a/portabase.config.ts +++ b/portabase.config.ts @@ -81,6 +81,7 @@ export const SUPPORTED_PROVIDERS: AuthProviderConfig[] = [ { id: "google", icon: Chrome, + isManual: true, credentials: { clientId: process.env.GOOGLE_CLIENT_ID || "", clientSecret: process.env.GOOGLE_CLIENT_SECRET || "", diff --git a/src/components/wrappers/dashboard/profile/profile-providers.tsx b/src/components/wrappers/dashboard/profile/profile-providers.tsx index b3601c67..c6bf8121 100644 --- a/src/components/wrappers/dashboard/profile/profile-providers.tsx +++ b/src/components/wrappers/dashboard/profile/profile-providers.tsx @@ -21,39 +21,44 @@ interface ProfileProviderProps { export function ProfileProviders({accounts}: ProfileProviderProps) { const router = useRouter(); const totalConnected = accounts.length; + const [loadingProvider, setLoadingProvider] = useState(null); const [isPasswordDialogOpen, setIsPasswordDialogOpen] = useState(false); - const {mutate: unlinkAccount, isPending: isUnlinking} = useMutation({ + const {mutate: unlinkAccount} = useMutation({ mutationFn: async (providerId: string) => { - const {error} = await authClient.unlinkAccount({ - providerId, - }); + setLoadingProvider(providerId); + const {error} = await authClient.unlinkAccount({ providerId }); if (error) throw error; }, onSuccess: () => { toast.success("Provider successfully unlinked!"); + setLoadingProvider(null); router.refresh(); }, onError: () => { toast.error("An error occurred while unlinking provider."); + setLoadingProvider(null); }, }); - const {mutate: linkAccount, isPending: isLinking} = useMutation({ + const {mutate: linkAccount} = useMutation({ mutationFn: async (providerId: string) => { + setLoadingProvider(providerId); const {error} = await authClient.signIn.social({ - provider: providerId as "google" | "github", + provider: providerId as "google" | "github" | "credential", callbackURL: "/dashboard", }); if (error) throw error; }, onSuccess: () => { toast.success("Provider successfully Linked!"); + setLoadingProvider(null); router.refresh(); }, onError: () => { - toast.error("An error occurred while linked provider."); + toast.error("An error occurred while linking provider."); + setLoadingProvider(null); }, }); @@ -68,9 +73,11 @@ export function ProfileProviders({accounts}: ProfileProviderProps) { {SUPPORTED_PROVIDERS.map((provider) => { const linkedAccount = accounts.find((acc) => acc.providerId === provider.id); const isConnected = !!linkedAccount; - + console.log(totalConnected); const canUnlink = totalConnected > 1 || (totalConnected === 1 && !provider.isManual); - const isLoading = isUnlinking || isLinking; + console.log(canUnlink); + // const isLoading = isUnlinking || isLinking; + const isLoading = loadingProvider === provider.id; return (
{ + // const user = await db.query.user.findFirst({ + // where: eq(drizzleDb.schemas.user.id, session.userId), + // }); + // + // if (user && user.role != "pending") { + // const deviceInfo = getDeviceDetails(session.userAgent); + // await sendEmail({ + // to: user.email, + // subject: "New login to your account", + // html: await render( + // EmailNewLogin({ + // firstname: user.name!, + // os: deviceInfo.os, + // browser: deviceInfo.browser, + // ipAddress: session.ipAddress!, + // }), + // {} + // ), + // }); + // + // (await auth.$context).internalAdapter.updateUser(user.id, { + // lastConnectedAt: new Date(), + // }); + // } + // }, after: async (session) => { const user = await db.query.user.findFirst({ where: eq(drizzleDb.schemas.user.id, session.userId), }); - if (user && user.role != "pending") { - const deviceInfo = getDeviceDetails(session.userAgent); - await sendEmail({ - to: user.email, - subject: "New login to your account", - html: await render( - EmailNewLogin({ - firstname: user.name!, - os: deviceInfo.os, - browser: deviceInfo.browser, - ipAddress: session.ipAddress!, - }), - {} - ), - }); + if (!user) return; - (await auth.$context).internalAdapter.updateUser(user.id, { - lastConnectedAt: new Date(), - }); + const createdAtDiff = new Date(session.createdAt).getTime() - new Date(user.createdAt).getTime(); + + if (createdAtDiff < 5000) { + console.log(`Skipping new login email for freshly created user ${user.email}`); + return; } + + if (user.role === "pending") return; + + const deviceInfo = getDeviceDetails(session.userAgent); + + await sendEmail({ + to: user.email, + subject: "New login to your account", + html: await render( + EmailNewLogin({ + firstname: user.name!, + os: deviceInfo.os, + browser: deviceInfo.browser, + ipAddress: session.ipAddress!, + }), + {} + ), + }); + + (await auth.$context).internalAdapter.updateUser(user.id, { + lastConnectedAt: new Date(), + }); }, }, },