import { Body, Controller, HttpException, HttpStatus, Post, Req, } from '@nestjs/common'; import { ApiResponse, ApiOperation, ApiBearerAuth, ApiTags, } from '@nestjs/swagger'; import { makeErrorResponse } from '../../common/error/makeErrorResponse'; import { ErrorResponse } from '../../common/error/types/types'; import { AuthService } from './auth.service'; import { AccessTokenResponse, TokenRequest, TokenResponse, } from './types/types'; import { retrieveAuthorizationToken } from '../../common/http/helper'; import { makeContext } from '../../common/log'; import { v4 as uuidv4 } from 'uuid'; @ApiTags('auth') @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} @Post('token') @ApiResponse({ status: HttpStatus.OK, type: TokenResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ description: 'AzureADB2Cでのサインイン後に払いだされるIDトークンを元に認証用のアクセストークンとリフレッシュトークンを生成します', operationId: 'token', }) async token(@Body() body: TokenRequest): Promise { const idToken = await this.authService.getVerifiedIdToken(body.idToken); const isVerified = await this.authService.isVerifiedUser(idToken); if (!isVerified) { throw new HttpException( makeErrorResponse('E010201'), HttpStatus.BAD_REQUEST, ); } const context = makeContext(uuidv4()); const refreshToken = await this.authService.generateRefreshToken( context, idToken, body.type, ); const accessToken = await this.authService.generateAccessToken( context, refreshToken, ); return { accessToken, refreshToken, }; } @Post('accessToken') @ApiBearerAuth() @ApiResponse({ status: HttpStatus.OK, type: AccessTokenResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'accessToken', description: 'リフレッシュトークンを元にアクセストークンを再生成します', }) async accessToken(@Req() req): Promise { const refreshToken = retrieveAuthorizationToken(req); if (!refreshToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const context = makeContext(uuidv4()); const accessToken = await this.authService.generateAccessToken( context, refreshToken, ); return { accessToken }; } }