import { Controller, All, Req, Get, UseGuards, Request } from "@nestjs/common"; import type { AuthUser, AuthSession } from "@mosaic/shared"; import { AuthService } from "./auth.service"; import { AuthGuard } from "./guards/auth.guard"; import { CurrentUser } from "./decorators/current-user.decorator"; interface RequestWithSession { user?: AuthUser; session?: { id: string; token: string; expiresAt: Date; [key: string]: unknown; }; } @Controller("auth") export class AuthController { constructor(private readonly authService: AuthService) {} /** * Get current session * Returns user and session data for authenticated user */ @Get("session") @UseGuards(AuthGuard) getSession(@Request() req: RequestWithSession): AuthSession { if (!req.user || !req.session) { // This should never happen after AuthGuard, but TypeScript needs the check throw new Error("User session not found"); } return { user: req.user, session: { id: req.session.id, token: req.session.token, expiresAt: req.session.expiresAt, }, }; } /** * Get current user profile * Returns basic user information */ @Get("profile") @UseGuards(AuthGuard) getProfile(@CurrentUser() user: AuthUser): AuthUser { // Return only defined properties to maintain type safety const profile: AuthUser = { id: user.id, email: user.email, name: user.name, }; if (user.image !== undefined) { profile.image = user.image; } if (user.emailVerified !== undefined) { profile.emailVerified = user.emailVerified; } if (user.workspaceId !== undefined) { profile.workspaceId = user.workspaceId; } if (user.currentWorkspaceId !== undefined) { profile.currentWorkspaceId = user.currentWorkspaceId; } if (user.workspaceRole !== undefined) { profile.workspaceRole = user.workspaceRole; } return profile; } /** * Handle all other auth routes (sign-in, sign-up, sign-out, etc.) * Delegates to BetterAuth */ @All("*") async handleAuth(@Req() req: Request): Promise { const auth = this.authService.getAuth(); return auth.handler(req); } }