## 概要 [Task2157: API実装(パートナーアカウント追加API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2157) - 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず) - 何をどう変更したか、追加したライブラリなど パートナーアカウント追加APIを実装しました。 - このPull Requestでの対象/対象外 認証メール送信後のフローは既存機能のため対象外 - 影響範囲(他の機能にも影響があるか) 既存のaccounts.service.spec.tsのテスト ## レビューポイント - 特にレビューしてほしい箇所 エラー判定に過不足ないか ## UIの変更 なし ## 動作確認状況 - ローカルで確認 Azureに管理者ユーザが追加されたこと、認証メールが送信されてくることを確認。 (対象外だが、認証後に追加されたアカウントでログインできることを確認) ## 補足 - 相談、参考資料などがあれば
293 lines
7.9 KiB
TypeScript
293 lines
7.9 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
HttpStatus,
|
|
Post,
|
|
Get,
|
|
Req,
|
|
UseGuards,
|
|
} 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,
|
|
} 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';
|
|
|
|
@ApiTags('accounts')
|
|
@Controller('accounts')
|
|
export class AccountsController {
|
|
constructor(
|
|
private readonly accountService: AccountsService, //private readonly cryptoService: CryptoService,
|
|
) {}
|
|
|
|
@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,
|
|
acceptedTermsVersion,
|
|
} = body;
|
|
const role = USER_ROLES.NONE;
|
|
|
|
await this.accountService.createAccount(
|
|
companyName,
|
|
country,
|
|
dealerAccountId,
|
|
adminMail,
|
|
adminPassword,
|
|
adminName,
|
|
role,
|
|
acceptedTermsVersion,
|
|
);
|
|
|
|
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], tiers: [TIERS.TIER5] }),
|
|
)
|
|
@Post('licenses/summary')
|
|
async getLicenseSummary(
|
|
@Req() req: Request,
|
|
@Body() body: GetLicenseSummaryRequest,
|
|
): Promise<GetLicenseSummaryResponse> {
|
|
console.log(req.header('Authorization'));
|
|
console.log(body);
|
|
|
|
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> {
|
|
console.log(req.header('Authorization'));
|
|
|
|
// アクセストークン取得
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
//アカウントID取得処理
|
|
const accountId = await this.accountService.getMyAccountInfo(payload);
|
|
return {
|
|
account: {
|
|
accountId: accountId,
|
|
},
|
|
};
|
|
}
|
|
|
|
@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> {
|
|
console.log(req.header('Authorization'));
|
|
// アクセストークン取得
|
|
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> {
|
|
console.log(req.header('Authorization'));
|
|
// アクセストークン取得
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
const typistGroups = await this.accountService.getTypistGroups(
|
|
payload.userId,
|
|
);
|
|
|
|
return { typistGroups };
|
|
}
|
|
|
|
@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> {
|
|
console.log(req.header('Authorization'));
|
|
console.log(body);
|
|
|
|
const { companyName, country, email, adminName } = body;
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
await this.accountService.createPartnerAccount(
|
|
companyName,
|
|
country,
|
|
email,
|
|
adminName,
|
|
payload.userId,
|
|
payload.tier,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
}
|