import { Controller, Delete, Get, HttpCode, NotFoundException, Param, ParseUUIDPipe, Query, } from "@nestjs/common"; import { ApiOperation, ApiResponse, ApiTags } from "@nestjs/swagger"; import { PaginationQueryDto } from "../common/dto/pagination.dto"; import { SessionContextService } from "./session-context.service"; import { SessionOrderBy, SessionService } from "./session.service"; function maskToken(token: string, head = 6, tail = 4): string { if (token.length <= head + tail + 1) return token; return `${token.slice(0, head)}\u2026${token.slice(-tail)}`; } @ApiTags("sessions") @Controller("sessions") export class SessionController { constructor( private readonly sessionService: SessionService, private readonly sessionContextService: SessionContextService, ) {} @Get() @ApiOperation({ summary: "List all stored sessions (paginated)" }) @ApiResponse({ status: 200, description: "Paginated sessions" }) findAll(@Query() query: PaginationQueryDto) { return this.sessionService.findAll(query); } @Get(":id") @ApiOperation({ summary: "Get a session by ID" }) @ApiResponse({ status: 200, description: "Session found" }) @ApiResponse({ status: 404, description: "Session not found" }) async findOne(@Param("id", ParseUUIDPipe) id: string) { const session = await this.sessionService.findById(id); if (!session) throw new NotFoundException(`Session ${id} not found`); const { token, cookies: _cookies, localStorage: _localStorage, ...rest } = session; return { ...rest, token: maskToken(token), }; } @Delete(":id") @HttpCode(204) @ApiOperation({ summary: "Delete a session by ID (closes it first if open)" }) @ApiResponse({ status: 204, description: "Session deleted" }) @ApiResponse({ status: 404, description: "Session not found" }) async remove(@Param("id", ParseUUIDPipe) id: string): Promise { await this.sessionContextService.delete(id); } }