513 lines
14 KiB
TypeScript
513 lines
14 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Get,
|
|
HttpException,
|
|
HttpStatus,
|
|
Logger,
|
|
Post,
|
|
Req,
|
|
UseGuards,
|
|
} from '@nestjs/common';
|
|
import {
|
|
ApiResponse,
|
|
ApiTags,
|
|
ApiOperation,
|
|
ApiBearerAuth,
|
|
} from '@nestjs/swagger';
|
|
import { ErrorResponse } from '../../common/error/types/types';
|
|
import { LicensesService } from './licenses.service';
|
|
import {
|
|
CreateOrdersResponse,
|
|
CreateOrdersRequest,
|
|
IssueCardLicensesResponse,
|
|
IssueCardLicensesRequest,
|
|
ActivateCardLicensesResponse,
|
|
ActivateCardLicensesRequest,
|
|
GetAllocatableLicensesResponse,
|
|
CancelOrderRequest,
|
|
CancelOrderResponse,
|
|
IssueTrialLicenseResponse,
|
|
IssueTrialLicenseRequest,
|
|
} from './types/types';
|
|
import { Request } from 'express';
|
|
import { retrieveAuthorizationToken } from '../../common/http/helper';
|
|
import { AccessToken } from '../../common/token';
|
|
import { AuthGuard } from '../../common/guards/auth/authguards';
|
|
import { RoleGuard } from '../../common/guards/role/roleguards';
|
|
import { ADMIN_ROLES, TIERS } from '../../constants';
|
|
import jwt from 'jsonwebtoken';
|
|
import { makeContext, retrieveRequestId, retrieveIp } from '../../common/log';
|
|
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
|
|
|
@ApiTags('licenses')
|
|
@Controller('licenses')
|
|
export class LicensesController {
|
|
private readonly logger = new Logger(LicensesController.name);
|
|
constructor(private readonly licensesService: LicensesService) {}
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CreateOrdersResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: '同一PONumberの注文がすでに存在する場合など',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'createOrders' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER2, TIERS.TIER3, TIERS.TIER4, TIERS.TIER5],
|
|
delegation: true,
|
|
}),
|
|
)
|
|
@Post('/orders')
|
|
async createOrders(
|
|
@Req() req: Request,
|
|
@Body() body: CreateOrdersRequest,
|
|
): Promise<CreateOrdersResponse> {
|
|
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.licensesService.licenseOrders(
|
|
context,
|
|
userId,
|
|
body.poNumber,
|
|
body.orderCount,
|
|
);
|
|
return {};
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: IssueCardLicensesResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'issueCardLicenses' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], tiers: [TIERS.TIER1] }),
|
|
)
|
|
@Post('/cards')
|
|
async issueCardLicenses(
|
|
@Req() req: Request,
|
|
@Body() body: IssueCardLicensesRequest,
|
|
): Promise<IssueCardLicensesResponse> {
|
|
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 cardLicenseKeys = await this.licensesService.issueCardLicenseKeys(
|
|
context,
|
|
userId,
|
|
body.createCount,
|
|
);
|
|
|
|
return cardLicenseKeys;
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: ActivateCardLicensesResponse,
|
|
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: 'activateCardLicenses' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER5],
|
|
delegation: true,
|
|
}),
|
|
)
|
|
@Post('/cards/activate')
|
|
async activateCardLicenses(
|
|
@Req() req: Request,
|
|
@Body() body: ActivateCardLicensesRequest,
|
|
): Promise<ActivateCardLicensesResponse> {
|
|
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.licensesService.activateCardLicenseKey(
|
|
context,
|
|
userId,
|
|
body.cardLicenseKey,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetAllocatableLicensesResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({
|
|
operationId: 'getAllocatableLicenses',
|
|
description: '割り当て可能なライセンスを取得します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER5],
|
|
delegation: true,
|
|
}),
|
|
)
|
|
@Get('/allocatable')
|
|
async getAllocatableLicenses(
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@Req() req: Request,
|
|
): Promise<GetAllocatableLicensesResponse> {
|
|
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 allocatableLicenses =
|
|
await this.licensesService.getAllocatableLicenses(context, userId);
|
|
|
|
return allocatableLicenses;
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: IssueTrialLicenseResponse,
|
|
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: 'issueTrialLicenses',
|
|
description: '第五階層アカウントにトライアルライセンスを発行します。',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER1, TIERS.TIER2],
|
|
delegation: true,
|
|
}),
|
|
)
|
|
@Post('/trial')
|
|
async issueTrialLicense(
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@Req() req: Request,
|
|
@Body() body: IssueTrialLicenseRequest,
|
|
): Promise<IssueTrialLicenseResponse> {
|
|
const { issuedAccount } = 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.licensesService.issueTrialLicense(
|
|
context,
|
|
userId,
|
|
issuedAccount,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CancelOrderResponse,
|
|
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: 'cancelOrder',
|
|
description: 'ライセンス注文をキャンセルします',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER2, TIERS.TIER3, TIERS.TIER4, TIERS.TIER5],
|
|
delegation: true,
|
|
}),
|
|
)
|
|
@Post('/orders/cancel')
|
|
async cancelOrder(
|
|
@Req() req: Request,
|
|
@Body() body: CancelOrderRequest,
|
|
): Promise<CancelOrderResponse> {
|
|
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.licensesService.cancelOrder(context, userId, body.poNumber);
|
|
return {};
|
|
}
|
|
}
|