import { Injectable, Logger } from "@nestjs/common"; import type { PrismaClient } from "@prisma/client"; import { PrismaService } from "../prisma/prisma.service"; import { createAuth, type Auth } from "./auth.config"; @Injectable() export class AuthService { private readonly logger = new Logger(AuthService.name); private readonly auth: Auth; constructor(private readonly prisma: PrismaService) { // PrismaService extends PrismaClient and is compatible with BetterAuth's adapter // Cast is safe as PrismaService provides all required PrismaClient methods this.auth = createAuth(this.prisma as unknown as PrismaClient); } /** * Get BetterAuth instance */ getAuth(): Auth { return this.auth; } /** * Get user by ID */ async getUserById(userId: string): Promise<{ id: string; email: string; name: string; authProviderId: string | null; } | null> { return this.prisma.user.findUnique({ where: { id: userId }, select: { id: true, email: true, name: true, authProviderId: true, }, }); } /** * Get user by email */ async getUserByEmail(email: string): Promise<{ id: string; email: string; name: string; authProviderId: string | null; } | null> { return this.prisma.user.findUnique({ where: { email }, select: { id: true, email: true, name: true, authProviderId: true, }, }); } /** * Verify session token * Returns session data if valid, null if invalid or expired */ async verifySession( token: string ): Promise<{ user: Record; session: Record } | null> { try { const session = await this.auth.api.getSession({ headers: { authorization: `Bearer ${token}`, }, }); if (!session) { return null; } return { user: session.user as Record, session: session.session as Record, }; } catch (error) { this.logger.error( "Session verification failed", error instanceof Error ? error.message : "Unknown error" ); return null; } } }