import { Body, Controller, Get, HttpException, HttpStatus, Logger, Post, Query, Req, UseGuards, } from '@nestjs/common'; import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags, } from '@nestjs/swagger'; import { Request } from 'express'; import { makeErrorResponse } from '../../common/error/makeErrorResponse'; import { ErrorResponse } from '../../common/error/types/types'; import { retrieveAuthorizationToken } from '../../common/http/helper'; import { AccessToken } from '../../common/token'; import { ConfirmRequest, ConfirmResponse, GetRelationsResponse, GetUsersResponse, SignupRequest, SignupResponse, PostSortCriteriaRequest, PostSortCriteriaResponse, GetSortCriteriaRequest, GetSortCriteriaResponse, PostUpdateUserRequest, PostUpdateUserResponse, AllocateLicenseResponse, AllocateLicenseRequest, DeallocateLicenseResponse, DeallocateLicenseRequest, UpdateAcceptedVersionRequest, UpdateAcceptedVersionResponse, GetMyUserResponse, PostDeleteUserRequest, PostDeleteUserResponse, PostMultipleImportsRequest, PostMultipleImportsResponse, PostMultipleImportsCompleteRequest, PostMultipleImportsCompleteResponse, } from './types/types'; import { UsersService } from './users.service'; import { AuthService } from '../auth/auth.service'; import jwt from 'jsonwebtoken'; import { AuthGuard } from '../../common/guards/auth/authguards'; import { isSortDirection, isTaskListSortableAttribute, } from '../../common/types/sort'; import { ADMIN_ROLES, TIERS } from '../../constants'; import { RoleGuard } from '../../common/guards/role/roleguards'; import { makeContext, retrieveRequestId, retrieveIp } from '../../common/log'; import { UserRoles } from '../../common/types/role'; import { SystemAccessGuard } from '../../common/guards/system/accessguards'; import { SystemAccessToken } from '../../common/token/types'; @ApiTags('users') @Controller('users') export class UsersController { private readonly logger = new Logger(UsersController.name); constructor( private readonly usersService: UsersService, private readonly authService: AuthService, ) {} @ApiResponse({ status: HttpStatus.OK, type: ConfirmResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なトークン', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'confirmUser' }) @Post('confirm') async confirmUser( @Body() body: ConfirmRequest, @Req() req: Request, ): Promise { const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const context = makeContext('anonymous', requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); await this.usersService.confirmUser(context, body.token); return {}; } @ApiResponse({ status: HttpStatus.OK, type: ConfirmResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なトークン', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'confirmUserAndInitPassword' }) @Post('confirm/initpassword') async confirmUserAndInitPassword( @Body() body: ConfirmRequest, @Req() req: Request, ): Promise { const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const context = makeContext('anonymous', requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); await this.usersService.confirmUserAndInitPassword(context, body.token); return {}; } @ApiResponse({ status: HttpStatus.OK, type: GetUsersResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'getUsers' }) @ApiBearerAuth() @UseGuards(AuthGuard) @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], delegation: true }), ) @Get() async getUsers(@Req() req: Request): Promise { const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); const users = await this.usersService.getUsers(context, userId); return { users }; } @ApiResponse({ status: HttpStatus.OK, type: SignupResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '登録済みメールによる再登録、AuthorIDの重複など', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'signup' }) @ApiBearerAuth() @Post('/signup') @UseGuards(AuthGuard) @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], delegation: true }), ) async signup( @Req() req: Request, @Body() body: SignupRequest, ): Promise { const { name, role, email, autoRenew, notification, authorId, encryption, encryptionPassword, prompt, } = body; const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); //ユーザ作成処理 await this.usersService.createUser( context, userId, name, role as UserRoles, email, autoRenew, notification, authorId, encryption, encryptionPassword, prompt, ); return {}; } @ApiResponse({ status: HttpStatus.OK, type: GetRelationsResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'getRelations', description: 'ログインしているユーザーに関連する各種情報を取得します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @Get('relations') async getRelations(@Req() req: Request): Promise { const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); return await this.usersService.getRelations(context, userId); } @ApiResponse({ status: HttpStatus.OK, type: PostSortCriteriaResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'updateSortCriteria', description: 'ログインしているユーザーのタスクソート条件を更新します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @Post('sort-criteria') async updateSortCriteria( @Body() body: PostSortCriteriaRequest, @Req() req: Request, ): Promise { const { direction, paramName } = body; const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); //型チェック if ( !isTaskListSortableAttribute(paramName) || !isSortDirection(direction) ) { throw new HttpException( makeErrorResponse('E010001'), HttpStatus.BAD_REQUEST, ); } await this.usersService.updateSortCriteria( context, paramName, direction, userId, ); return {}; } @ApiResponse({ status: HttpStatus.OK, type: GetSortCriteriaResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'getSortCriteria', description: 'ログインしているユーザーのタスクソート条件を取得します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @Get('sort-criteria') async getSortCriteria( @Query() query: GetSortCriteriaRequest, @Req() req: Request, ): Promise { const {} = query; const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); const { direction, paramName } = await this.usersService.getSortCriteria( context, userId, ); return { direction, paramName }; } @ApiResponse({ status: HttpStatus.OK, type: PostUpdateUserResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'updateUser', description: 'ユーザーの情報を更新します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], delegation: true }), ) @Post('update') async updateUser( @Body() body: PostUpdateUserRequest, @Req() req: Request, ): Promise { const { id, role, authorId, autoRenew, notification, encryption, encryptionPassword, prompt, } = body; const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); await this.usersService.updateUser( context, userId, id, role, authorId, autoRenew, notification, encryption, encryptionPassword, prompt, ); return {}; } @ApiResponse({ status: HttpStatus.OK, type: AllocateLicenseResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '割り当て失敗時', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'allocateLicense', description: 'ライセンスを割り当てます', }) @ApiBearerAuth() @UseGuards(AuthGuard) @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], tiers: [TIERS.TIER5], delegation: true, }), ) @Post('/license/allocate') async allocateLicense( @Body() body: AllocateLicenseRequest, @Req() req: Request, ): Promise { const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); await this.usersService.allocateLicense( context, body.userId, body.newLicenseId, ); return {}; } @ApiResponse({ status: HttpStatus.OK, type: DeallocateLicenseResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'すでにライセンスが割り当て解除されている時', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'deallocateLicense', description: 'ライセンス割り当てを解除します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], tiers: [TIERS.TIER5], delegation: true, }), ) @Post('/license/deallocate') async deallocateLicense( @Body() body: DeallocateLicenseRequest, @Req() req: Request, ): Promise { const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); await this.usersService.deallocateLicense(context, body.userId); return {}; } @ApiResponse({ status: HttpStatus.OK, type: UpdateAcceptedVersionResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'パラメータ不正/対象のユーザidが存在しない場合', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'updateAcceptedVersion', description: '利用規約同意バージョンを更新', }) @Post('/accepted-version') async updateAcceptedVersion( @Body() body: UpdateAcceptedVersionRequest, @Req() req: Request, ): Promise { const { idToken, acceptedEULAVersion, acceptedPrivacyNoticeVersion, acceptedDPAVersion, } = body; const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const context = makeContext('anonymous', requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); const verifiedIdToken = await this.authService.getVerifiedIdToken( context, idToken, ); const isVerified = await this.authService.isVerifiedUser( context, verifiedIdToken, ); if (!isVerified) { throw new HttpException( makeErrorResponse('E010201'), HttpStatus.BAD_REQUEST, ); } await this.usersService.updateAcceptedVersion( context, verifiedIdToken.sub, acceptedEULAVersion, acceptedPrivacyNoticeVersion, acceptedDPAVersion, ); return {}; } @ApiResponse({ status: HttpStatus.OK, type: GetMyUserResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '該当ユーザーがDBに存在しない場合', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'getMyUser', description: 'ログインしているユーザーの情報を取得します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @Get('me') async getMyUser(@Req() req: Request): Promise { const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); const userName = await this.usersService.getUserName(context, userId); return { userName }; } @ApiResponse({ status: HttpStatus.OK, type: PostDeleteUserResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'deleteUser', description: 'ユーザーを削除します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], delegation: true }), ) @Post('delete') async deleteUser( @Body() body: PostDeleteUserRequest, @Req() req: Request, ): Promise { const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedAccessToken = jwt.decode(accessToken, { json: true }); if (!decodedAccessToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId } = decodedAccessToken as AccessToken; const context = makeContext(userId, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); const now = new Date(); await this.usersService.deleteUser(context, body.userId, now); return {}; } @ApiResponse({ status: HttpStatus.OK, type: PostMultipleImportsResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'multipleImports', description: 'ユーザーを一括登録します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], delegation: true }), ) @Post('multiple-imports') async multipleImports( @Body() body: PostMultipleImportsRequest, @Req() req: Request, ): Promise { const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedToken = jwt.decode(accessToken, { json: true }); if (!decodedToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { userId, delegateUserId } = decodedToken as AccessToken; const context = makeContext(userId, requestId, delegateUserId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); // 登録処理 const { users, filename } = body; await this.usersService.multipleImports(context, userId, filename, users); return {}; } @ApiResponse({ status: HttpStatus.OK, type: PostMultipleImportsCompleteResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'multipleImportsComplate', description: 'ユーザー一括登録の完了を通知します', }) @ApiBearerAuth() @UseGuards(SystemAccessGuard) @Post('multiple-imports/complete') async multipleImportsComplate( @Body() body: PostMultipleImportsCompleteRequest, @Req() req: Request, ): Promise { const accessToken = retrieveAuthorizationToken(req); if (!accessToken) { throw new HttpException( makeErrorResponse('E000107'), HttpStatus.UNAUTHORIZED, ); } const ip = retrieveIp(req); if (!ip) { throw new HttpException( makeErrorResponse('E000401'), HttpStatus.UNAUTHORIZED, ); } const requestId = retrieveRequestId(req); if (!requestId) { throw new HttpException( makeErrorResponse('E000501'), HttpStatus.INTERNAL_SERVER_ERROR, ); } const decodedToken = jwt.decode(accessToken, { json: true }); if (!decodedToken) { throw new HttpException( makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED, ); } const { systemName } = decodedToken as SystemAccessToken; const context = makeContext(systemName, requestId); this.logger.log(`[${context.getTrackingId()}] ip : ${ip}`); const { accountId, filename, requestTime, errors } = body; await this.usersService.multipleImportsComplate( context, accountId, filename, requestTime, errors, ); return {}; } }