## 概要 [Task3752: API実装(一括登録)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3752) - ユーザー一括登録APIとテストを実装しました。 - メール文面はまだ翻訳が来ていないので日本語のものを使用しています。別タスクで多言語対応します。 ## レビューポイント - ファイル名は認識通りでしょうか? - ファイルの内容は認識通りでしょうか? ## UIの変更 - なし ## 動作確認状況 - ローカルで確認
1155 lines
30 KiB
TypeScript
1155 lines
30 KiB
TypeScript
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<ConfirmResponse> {
|
|
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<ConfirmResponse> {
|
|
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<GetUsersResponse> {
|
|
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<SignupResponse> {
|
|
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<GetRelationsResponse> {
|
|
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<PostSortCriteriaResponse> {
|
|
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<GetSortCriteriaResponse> {
|
|
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<PostUpdateUserResponse> {
|
|
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<AllocateLicenseResponse> {
|
|
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<DeallocateLicenseResponse> {
|
|
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<UpdateAcceptedVersionResponse> {
|
|
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<GetMyUserResponse> {
|
|
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<PostDeleteUserResponse> {
|
|
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<PostMultipleImportsResponse> {
|
|
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<PostMultipleImportsCompleteResponse> {
|
|
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 {};
|
|
}
|
|
}
|