## 概要 [Task2807: API作成(アカウント情報取得(未認証時最小アクセス)API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2807) - 未ログインユーザーについて、IDトークンを受け取ってユーザの所属するアカウントの階層情報を返却するAPIを実装しました。 ## レビューポイント - ContorollerでIDトークンをデコードしているが問題ないか? - ※ログインAPIを参考にしています。 - テストケースは適切か ## UIの変更 - なし ## 動作確認状況 - ローカルで確認
1142 lines
31 KiB
TypeScript
1142 lines
31 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
HttpStatus,
|
|
Post,
|
|
Get,
|
|
Req,
|
|
UseGuards,
|
|
Param,
|
|
Query,
|
|
HttpException,
|
|
} from '@nestjs/common';
|
|
import {
|
|
ApiOperation,
|
|
ApiResponse,
|
|
ApiTags,
|
|
ApiBearerAuth,
|
|
} from '@nestjs/swagger';
|
|
import { ErrorResponse } from '../../common/error/types/types';
|
|
import { Request } from 'express';
|
|
import { AccountsService } from './accounts.service';
|
|
import {
|
|
CreateAccountRequest,
|
|
CreateAccountResponse,
|
|
GetLicenseSummaryRequest,
|
|
GetLicenseSummaryResponse,
|
|
GetMyAccountResponse,
|
|
GetTypistGroupsResponse,
|
|
GetTypistsResponse,
|
|
CreatePartnerAccountRequest,
|
|
CreatePartnerAccountResponse,
|
|
GetPartnerLicensesRequest,
|
|
GetPartnerLicensesResponse,
|
|
GetOrderHistoriesRequest,
|
|
GetOrderHistoriesResponse,
|
|
IssueLicenseRequest,
|
|
IssueLicenseResponse,
|
|
GetDealersResponse,
|
|
CreateTypistGroupResponse,
|
|
CreateTypistGroupRequest,
|
|
GetTypistGroupResponse,
|
|
GetTypistGroupRequest,
|
|
UpdateTypistGroupRequest,
|
|
UpdateTypistGroupRequestParam,
|
|
CancelIssueRequest,
|
|
CancelIssueResponse,
|
|
GetWorktypesResponse,
|
|
CreateWorktypeResponse,
|
|
CreateWorktypesRequest,
|
|
GetPartnersRequest,
|
|
GetPartnersResponse,
|
|
UpdateWorktypeRequestParam,
|
|
UpdateWorktypeResponse,
|
|
UpdateWorktypesRequest,
|
|
GetOptionItemsRequestParam,
|
|
GetOptionItemsResponse,
|
|
UpdateOptionItemsResponse,
|
|
UpdateOptionItemsRequestParam,
|
|
UpdateOptionItemsRequest,
|
|
PostActiveWorktypeRequest,
|
|
PostActiveWorktypeResponse,
|
|
UpdateAccountInfoRequest,
|
|
UpdateAccountInfoResponse,
|
|
DeleteAccountRequest,
|
|
DeleteAccountResponse,
|
|
GetAuthorsResponse,
|
|
GetAccountInfoMinimalAccessRequest,
|
|
GetAccountInfoMinimalAccessResponse,
|
|
} from './types/types';
|
|
import { USER_ROLES, ADMIN_ROLES, TIERS } from '../../constants';
|
|
import { AuthGuard } from '../../common/guards/auth/authguards';
|
|
import { RoleGuard } from '../../common/guards/role/roleguards';
|
|
import { retrieveAuthorizationToken } from '../../common/http/helper';
|
|
import { AccessToken } from '../../common/token';
|
|
import jwt from 'jsonwebtoken';
|
|
import { makeContext } from '../../common/log';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
import { AuthService } from '../auth/auth.service';
|
|
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
|
|
|
@ApiTags('accounts')
|
|
@Controller('accounts')
|
|
export class AccountsController {
|
|
constructor(
|
|
private readonly accountService: AccountsService, //private readonly cryptoService: CryptoService,
|
|
private readonly authService: AuthService,
|
|
) {}
|
|
|
|
@Post()
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CreateAccountResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: '登録済みユーザーからの登録など',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'createAccount' })
|
|
async createAccount(
|
|
@Body() body: CreateAccountRequest,
|
|
): Promise<CreateAccountResponse> {
|
|
const {
|
|
companyName,
|
|
country,
|
|
dealerAccountId,
|
|
adminMail,
|
|
adminPassword,
|
|
adminName,
|
|
acceptedEulaVersion,
|
|
acceptedDpaVersion,
|
|
} = body;
|
|
const role = USER_ROLES.NONE;
|
|
|
|
const context = makeContext(uuidv4());
|
|
|
|
await this.accountService.createAccount(
|
|
context,
|
|
companyName,
|
|
country,
|
|
dealerAccountId,
|
|
adminMail,
|
|
adminPassword,
|
|
adminName,
|
|
role,
|
|
acceptedEulaVersion,
|
|
acceptedDpaVersion,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetLicenseSummaryResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({
|
|
operationId: 'getLicenseSummary',
|
|
description: '指定したアカウントのライセンス集計情報を取得します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
@Post('licenses/summary')
|
|
async getLicenseSummary(
|
|
@Req() req: Request,
|
|
@Body() body: GetLicenseSummaryRequest,
|
|
): Promise<GetLicenseSummaryResponse> {
|
|
const response = await this.accountService.getLicenseSummary(
|
|
body.accountId,
|
|
);
|
|
return response;
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetMyAccountResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: '該当アカウントがDBに存在しない場合',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({
|
|
operationId: 'getMyAccount',
|
|
description: 'ログインしているユーザーのアカウント情報を取得します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
@Get('me')
|
|
async getMyAccount(@Req() req: Request): Promise<GetMyAccountResponse> {
|
|
// アクセストークン取得
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
const context = makeContext(payload.userId);
|
|
//アカウントID取得処理
|
|
const accountInfo = await this.accountService.getAccountInfo(
|
|
context,
|
|
payload.userId,
|
|
);
|
|
return accountInfo;
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetAuthorsResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({
|
|
operationId: 'getAuthors',
|
|
description:
|
|
'ログインしているユーザーのアカウント配下のAuthor一覧を取得します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
@Get('authors')
|
|
async getAuthors(@Req() req: Request): Promise<GetAuthorsResponse> {
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
const context = makeContext(userId);
|
|
|
|
const authors = await this.accountService.getAuthors(context, userId);
|
|
|
|
return { authors };
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetTypistsResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({
|
|
operationId: 'getTypists',
|
|
description:
|
|
'ログインしているユーザーのアカウント配下のタイピスト一覧を取得します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@Get('typists')
|
|
async getTypists(@Req() req: Request): Promise<GetTypistsResponse> {
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
const typists = await this.accountService.getTypists(payload.userId);
|
|
|
|
return { typists };
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetTypistGroupsResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({
|
|
operationId: 'getTypistGroups',
|
|
description:
|
|
'ログインしているユーザーのアカウント配下のタイピストグループ一覧を取得します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@Get('typist-groups')
|
|
async getTypistGroups(@Req() req: Request): Promise<GetTypistGroupsResponse> {
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
const typistGroups = await this.accountService.getTypistGroups(
|
|
payload.userId,
|
|
);
|
|
|
|
return { typistGroups };
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetTypistGroupResponse,
|
|
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: 'getTypistGroup',
|
|
description:
|
|
'ログインしているユーザーのアカウント配下でIDで指定されたタイピストグループを取得します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
@Get('typist-groups/:typistGroupId')
|
|
async getTypistGroup(
|
|
@Req() req: Request,
|
|
@Param() param: GetTypistGroupRequest,
|
|
): Promise<GetTypistGroupResponse> {
|
|
const { typistGroupId } = param;
|
|
|
|
// アクセストークン取得
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
|
|
const typistGroup = await this.accountService.getTypistGroup(
|
|
context,
|
|
userId,
|
|
typistGroupId,
|
|
);
|
|
|
|
return typistGroup;
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CreateTypistGroupResponse,
|
|
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: 'createTypistGroup',
|
|
description:
|
|
'ログインしているユーザーのアカウント配下にタイピストグループを追加します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
@Post('typist-groups')
|
|
async createTypistGroup(
|
|
@Req() req: Request,
|
|
@Body() body: CreateTypistGroupRequest,
|
|
): Promise<CreateTypistGroupResponse> {
|
|
const { typistGroupName, typistIds } = body;
|
|
// アクセストークン取得
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
const context = makeContext(userId);
|
|
await this.accountService.createTypistGroup(
|
|
context,
|
|
userId,
|
|
typistGroupName,
|
|
typistIds,
|
|
);
|
|
return {};
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CreateTypistGroupResponse,
|
|
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: 'updateTypistGroup',
|
|
description:
|
|
'ログインしているユーザーのアカウント配下でIDで指定されたタイピストグループを更新します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
@Post('typist-groups/:typistGroupId')
|
|
async updateTypistGroup(
|
|
@Req() req: Request,
|
|
@Body() body: UpdateTypistGroupRequest,
|
|
@Param() param: UpdateTypistGroupRequestParam,
|
|
): Promise<CreateTypistGroupResponse> {
|
|
const { typistGroupName, typistIds } = body;
|
|
const { typistGroupId } = param;
|
|
|
|
// アクセストークン取得
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
|
|
await this.accountService.updateTypistGroup(
|
|
context,
|
|
userId,
|
|
typistGroupId,
|
|
typistGroupName,
|
|
typistIds,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@Post('partner')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CreatePartnerAccountResponse,
|
|
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: 'createPartnerAccount' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER1, TIERS.TIER2, TIERS.TIER3],
|
|
}),
|
|
)
|
|
async createPartnerAccount(
|
|
@Req() req: Request,
|
|
@Body() body: CreatePartnerAccountRequest,
|
|
): Promise<CreatePartnerAccountResponse> {
|
|
const { companyName, country, email, adminName } = body;
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(payload.userId);
|
|
|
|
await this.accountService.createPartnerAccount(
|
|
context,
|
|
companyName,
|
|
country,
|
|
email,
|
|
adminName,
|
|
payload.userId,
|
|
payload.tier,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@Post('partner-licenses')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetPartnerLicensesResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'getPartnerLicenses' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER1, TIERS.TIER2, TIERS.TIER3, TIERS.TIER4],
|
|
}),
|
|
)
|
|
async getPartnerLicenses(
|
|
@Req() req: Request,
|
|
@Body() body: GetPartnerLicensesRequest,
|
|
): Promise<GetPartnerLicensesResponse> {
|
|
const { limit, offset, accountId } = body;
|
|
|
|
const getPartnerLicensesResponse =
|
|
await this.accountService.getPartnerLicenses(limit, offset, accountId);
|
|
|
|
return getPartnerLicensesResponse;
|
|
}
|
|
|
|
@Post('order-histories')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetOrderHistoriesResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'getOrderHistories' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
}),
|
|
)
|
|
async getOrderHistories(
|
|
@Req() req: Request,
|
|
@Body() body: GetOrderHistoriesRequest,
|
|
): Promise<GetOrderHistoriesResponse> {
|
|
const { limit, offset, accountId } = body;
|
|
|
|
const getOrderHistoriesResponse =
|
|
await this.accountService.getOrderHistories(limit, offset, accountId);
|
|
|
|
return getOrderHistoriesResponse;
|
|
}
|
|
|
|
@Post('/licenses/issue')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: IssueLicenseResponse,
|
|
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: 'issueLicense' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER1, TIERS.TIER2, TIERS.TIER3, TIERS.TIER4],
|
|
}),
|
|
)
|
|
async issueLicense(
|
|
@Req() req: Request,
|
|
@Body() body: IssueLicenseRequest,
|
|
): Promise<IssueLicenseResponse> {
|
|
const { orderedAccountId, poNumber } = body;
|
|
|
|
const token = retrieveAuthorizationToken(req);
|
|
const accessToken = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(accessToken.userId);
|
|
await this.accountService.issueLicense(
|
|
context,
|
|
orderedAccountId,
|
|
accessToken.userId,
|
|
accessToken.tier,
|
|
poNumber,
|
|
);
|
|
return {};
|
|
}
|
|
|
|
@Get('/dealers')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetDealersResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'getDealers' })
|
|
async getDealers(): Promise<GetDealersResponse> {
|
|
return await this.accountService.getDealers();
|
|
}
|
|
|
|
@Post('/issue/cancel')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CancelIssueResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description:
|
|
'対象注文のステータスが発行済以外/発行日から15日以降/ライセンスをユーザに割り当てている',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({
|
|
operationId: 'cancelIssue',
|
|
description: 'ライセンス発行をキャンセルします',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER1, TIERS.TIER2],
|
|
}),
|
|
)
|
|
async cancelIssue(
|
|
@Req() req: Request,
|
|
@Body() body: CancelIssueRequest,
|
|
): Promise<CancelIssueResponse> {
|
|
const token = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(payload.userId);
|
|
|
|
await this.accountService.cancelIssue(
|
|
context,
|
|
payload.userId,
|
|
body.poNumber,
|
|
body.orderedAccountId,
|
|
);
|
|
return {};
|
|
}
|
|
|
|
@Get('/worktypes')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetWorktypesResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'getWorktypes' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
async getWorktypes(@Req() req: Request): Promise<GetWorktypesResponse> {
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
const worktypes = await this.accountService.getWorktypes(context, userId);
|
|
|
|
return worktypes;
|
|
}
|
|
|
|
@Post('/worktypes')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CreateWorktypeResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: 'WorktypeIDが重複 / WorktypeIDが空 / WorktypeIDが20件登録済み',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'createWorktype' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
async createWorktype(
|
|
@Req() req: Request,
|
|
@Body() body: CreateWorktypesRequest,
|
|
): Promise<CreateWorktypeResponse> {
|
|
const { worktypeId, description } = body;
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
await this.accountService.createWorktype(
|
|
context,
|
|
userId,
|
|
worktypeId,
|
|
description,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@Post('/worktypes/:id')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: UpdateWorktypeResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: 'WorktypeIDが重複 / WorktypeIDが空',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'updateWorktype' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
async updateWorktype(
|
|
@Req() req: Request,
|
|
@Param() param: UpdateWorktypeRequestParam,
|
|
@Body() body: UpdateWorktypesRequest,
|
|
): Promise<UpdateWorktypeResponse> {
|
|
const { worktypeId, description } = body;
|
|
const { id } = param;
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
|
|
await this.accountService.updateWorktype(
|
|
context,
|
|
userId,
|
|
id,
|
|
worktypeId,
|
|
description,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@Get('/worktypes/:id/option-items')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetOptionItemsResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: 'WorktypeIDが不在',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'getOptionItems' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
async getOptionItems(
|
|
@Req() req: Request,
|
|
@Param() param: GetOptionItemsRequestParam,
|
|
): Promise<GetOptionItemsResponse> {
|
|
const { id } = param;
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
|
|
const optionItems = await this.accountService.getOptionItems(
|
|
context,
|
|
userId,
|
|
id,
|
|
);
|
|
|
|
return optionItems;
|
|
}
|
|
|
|
@Post('/worktypes/:id/option-items')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: UpdateOptionItemsResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: 'WorktypeIDが不在',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'updateOptionItems' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
async updateOptionItems(
|
|
@Req() req: Request,
|
|
@Param() param: UpdateOptionItemsRequestParam,
|
|
@Body() body: UpdateOptionItemsRequest,
|
|
): Promise<UpdateOptionItemsResponse> {
|
|
const { optionItems } = body;
|
|
const { id } = param;
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
|
|
await this.accountService.updateOptionItems(
|
|
context,
|
|
userId,
|
|
id,
|
|
optionItems,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@Post('/active-worktype')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: PostActiveWorktypeResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: 'WorktypeIDが存在しない',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'activeWorktype' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
|
async activeWorktype(
|
|
@Req() req: Request,
|
|
@Body() body: PostActiveWorktypeRequest,
|
|
): Promise<PostActiveWorktypeResponse> {
|
|
const { id } = body;
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
|
|
await this.accountService.updateActiveWorktype(context, userId, id);
|
|
return {};
|
|
}
|
|
|
|
@Get('/partners')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetPartnersResponse,
|
|
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: 'getPartners' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER1, TIERS.TIER2, TIERS.TIER3, TIERS.TIER4],
|
|
}),
|
|
)
|
|
async getPartners(
|
|
@Req() req: Request,
|
|
@Query() query: GetPartnersRequest,
|
|
): Promise<GetPartnersResponse> {
|
|
const { limit, offset } = query;
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(userId);
|
|
const response = await this.accountService.getPartners(
|
|
context,
|
|
userId,
|
|
limit,
|
|
offset,
|
|
);
|
|
|
|
return response;
|
|
}
|
|
|
|
@Post('/me')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: UpdateAccountInfoResponse,
|
|
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: 'updateAccountInfo' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
}),
|
|
)
|
|
async updateAccountInfo(
|
|
@Req() req: Request,
|
|
@Body() body: UpdateAccountInfoRequest,
|
|
): Promise<UpdateAccountInfoResponse> {
|
|
const {
|
|
parentAccountId,
|
|
delegationPermission,
|
|
primaryAdminUserId,
|
|
secondryAdminUserId,
|
|
} = body;
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId, tier } = jwt.decode(token, { json: true }) as AccessToken;
|
|
const context = makeContext(userId);
|
|
|
|
await this.accountService.updateAccountInfo(
|
|
context,
|
|
userId,
|
|
tier,
|
|
delegationPermission,
|
|
primaryAdminUserId,
|
|
parentAccountId,
|
|
secondryAdminUserId,
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
@Post('/delete')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: UpdateAccountInfoResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: 'DBアクセスに失敗しログインできる状態で処理が終了した場合',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'deleteAccountAndData' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
}),
|
|
)
|
|
async deleteAccountAndData(
|
|
@Req() req: Request,
|
|
@Body() body: DeleteAccountRequest,
|
|
): Promise<DeleteAccountResponse> {
|
|
const { accountId } = body;
|
|
const token = retrieveAuthorizationToken(req);
|
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
|
const context = makeContext(userId);
|
|
|
|
await this.accountService.deleteAccountAndData(context, userId, accountId);
|
|
return;
|
|
}
|
|
|
|
@Post('/minimal-access')
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetAccountInfoMinimalAccessResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: '対象のユーザーIDが存在しない場合',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'getAccountInfoMinimalAccess' })
|
|
async getAccountInfoMinimalAccess(
|
|
@Body() body: GetAccountInfoMinimalAccessRequest,
|
|
): Promise<GetAccountInfoMinimalAccessResponse> {
|
|
// IDトークンの検証
|
|
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(idToken.sub);
|
|
|
|
const tier = await this.accountService.getAccountInfoMinimalAccess(
|
|
context,
|
|
idToken.sub,
|
|
);
|
|
return { tier };
|
|
}
|
|
}
|