/** * Auth API handlers */ import type { IApiContext, IApiResponse } from '../router.ts'; import { AuthService } from '../../services/auth.service.ts'; export class AuthApi { private authService: AuthService; constructor(authService: AuthService) { this.authService = authService; } /** * POST /api/v1/auth/login */ public async login(ctx: IApiContext): Promise { try { const body = await ctx.request.json(); const { email, password } = body; if (!email || !password) { return { status: 400, body: { error: 'Email and password are required' }, }; } const result = await this.authService.login(email, password, { userAgent: ctx.userAgent, ipAddress: ctx.ip, }); if (!result.success) { return { status: 401, body: { error: result.errorMessage, code: result.errorCode, }, }; } return { status: 200, body: { user: { id: result.user!.id, email: result.user!.email, username: result.user!.username, displayName: result.user!.displayName, isSystemAdmin: result.user!.isSystemAdmin, }, accessToken: result.accessToken, refreshToken: result.refreshToken, sessionId: result.sessionId, }, }; } catch (error) { console.error('[AuthApi] Login error:', error); return { status: 500, body: { error: 'Login failed' }, }; } } /** * POST /api/v1/auth/refresh */ public async refresh(ctx: IApiContext): Promise { try { const body = await ctx.request.json(); const { refreshToken } = body; if (!refreshToken) { return { status: 400, body: { error: 'Refresh token is required' }, }; } const result = await this.authService.refresh(refreshToken); if (!result.success) { return { status: 401, body: { error: result.errorMessage, code: result.errorCode, }, }; } return { status: 200, body: { accessToken: result.accessToken, }, }; } catch (error) { console.error('[AuthApi] Refresh error:', error); return { status: 500, body: { error: 'Token refresh failed' }, }; } } /** * POST /api/v1/auth/logout */ public async logout(ctx: IApiContext): Promise { if (!ctx.actor?.userId) { return { status: 401, body: { error: 'Authentication required' }, }; } try { const body = await ctx.request.json().catch(() => ({})); const { sessionId, all } = body; if (all) { const count = await this.authService.logoutAll(ctx.actor.userId, { ipAddress: ctx.ip, }); return { status: 200, body: { message: `Logged out from ${count} sessions` }, }; } if (sessionId) { await this.authService.logout(sessionId, { userId: ctx.actor.userId, ipAddress: ctx.ip, }); } return { status: 200, body: { message: 'Logged out successfully' }, }; } catch (error) { console.error('[AuthApi] Logout error:', error); return { status: 500, body: { error: 'Logout failed' }, }; } } /** * GET /api/v1/auth/me */ public async me(ctx: IApiContext): Promise { if (!ctx.actor?.userId || !ctx.actor.user) { return { status: 401, body: { error: 'Authentication required' }, }; } const user = ctx.actor.user; return { status: 200, body: { id: user.id, email: user.email, username: user.username, displayName: user.displayName, avatarUrl: user.avatarUrl, isSystemAdmin: user.isSystemAdmin, isActive: user.isActive, createdAt: user.createdAt, lastLoginAt: user.lastLoginAt, }, }; } }