/** * EnrollmentController — federation enrollment HTTP layer (FED-M2-07). * * Routes: * POST /api/federation/enrollment/tokens — admin creates a single-use token * POST /api/federation/enrollment/:token — unauthenticated; token IS the auth */ import { Body, Controller, HttpCode, HttpStatus, Inject, Param, Post, UseGuards, } from '@nestjs/common'; import { AdminGuard } from '../admin/admin.guard.js'; import { EnrollmentService } from './enrollment.service.js'; import { CreateEnrollmentTokenDto, RedeemEnrollmentTokenDto } from './enrollment.dto.js'; @Controller('api/federation/enrollment') export class EnrollmentController { constructor(@Inject(EnrollmentService) private readonly enrollmentService: EnrollmentService) {} /** * Admin-only: generate a single-use enrollment token for a pending grant. * The token should be distributed out-of-band to the remote peer operator. * * POST /api/federation/enrollment/tokens */ @Post('tokens') @UseGuards(AdminGuard) @HttpCode(HttpStatus.CREATED) async createToken(@Body() dto: CreateEnrollmentTokenDto) { return this.enrollmentService.createToken(dto); } /** * Unauthenticated: remote peer redeems a token by submitting its CSR. * The token itself is the credential — no session or bearer token required. * * POST /api/federation/enrollment/:token * * Returns the signed leaf cert and full chain PEM on success. * Returns 410 Gone if the token was already used or has expired. */ @Post(':token') @HttpCode(HttpStatus.OK) async redeem(@Param('token') token: string, @Body() dto: RedeemEnrollmentTokenDto) { return this.enrollmentService.redeem(token, dto.csrPem); } }