From f8a3b1798c8557de9918ef5bc9315801bee2a2fd Mon Sep 17 00:00:00 2001 From: "maruyama.t" Date: Fri, 14 Jul 2023 04:19:24 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20237:=20Revert=20'API=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=EF=BC=88=E3=83=91=E3=83=BC=E3=83=88=E3=83=8A=E3=83=BC?= =?UTF-8?q?=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3=E3=83=88=E8=BF=BD=E5=8A=A0?= =?UTF-8?q?API=EF=BC=89'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [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に管理者ユーザが追加されたこと、認証メールが送信されてくることを確認。 (対象外だが、認証後に追加されたアカウントでログインできることを確認) ## 補足 - 相談、参考資料などがあれば Reverts !225 --- .../features/accounts/accounts.controller.ts | 20 +--- .../accounts/accounts.service.spec.ts | 86 -------------- .../src/features/accounts/accounts.service.ts | 110 +----------------- .../accounts/test/accounts.service.mock.ts | 72 +----------- .../src/features/accounts/types/types.ts | 2 +- 5 files changed, 11 insertions(+), 279 deletions(-) diff --git a/dictation_server/src/features/accounts/accounts.controller.ts b/dictation_server/src/features/accounts/accounts.controller.ts index af8a710..b7d80c6 100644 --- a/dictation_server/src/features/accounts/accounts.controller.ts +++ b/dictation_server/src/features/accounts/accounts.controller.ts @@ -261,31 +261,21 @@ export class AccountsController { @ApiOperation({ operationId: 'createPartnerAccount' }) @ApiBearerAuth() @UseGuards(AuthGuard) - @UseGuards( - RoleGuard.requireds({ - roles: [ADMIN_ROLES.ADMIN], - tiers: [TIERS.TIER1][TIERS.TIER2][TIERS.TIER3], - }), - ) + @UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] })) async createPartnerAccount( @Req() req: Request, @Body() body: CreatePartnerAccountRequest, ): Promise { console.log(req.header('Authorization')); console.log(body); + const { companyName, country, eMail, adminName } = body; - const { companyName, country, email, adminName } = body; - const accessToken = retrieveAuthorizationToken(req); - const payload = jwt.decode(accessToken, { json: true }) as AccessToken; - - await this.accountService.createPartnerAccount( + /*await this.accountService.createPartnerAccount( companyName, country, - email, + eMail, adminName, - payload.userId, - payload.tier, - ); + );*/ return {}; } diff --git a/dictation_server/src/features/accounts/accounts.service.spec.ts b/dictation_server/src/features/accounts/accounts.service.spec.ts index f3e5dc0..c315cc8 100644 --- a/dictation_server/src/features/accounts/accounts.service.spec.ts +++ b/dictation_server/src/features/accounts/accounts.service.spec.ts @@ -8,7 +8,6 @@ import { makeDefaultUserGroupsRepositoryMockValue, makeDefaultUsersRepositoryMockValue, } from './test/accounts.service.mock'; -import { makeDefaultConfigValue } from '../users/test/users.service.mock'; describe('AccountsService', () => { it('アカウントに紐づくライセンス情報を取得する', async () => { @@ -19,14 +18,12 @@ describe('AccountsService', () => { const adb2cParam = makeDefaultAdB2cMockValue(); const accountsRepositoryMockValue = makeDefaultAccountsRepositoryMockValue(); - const configMockValue = makeDefaultConfigValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeAccountsServiceMock( accountsRepositoryMockValue, usersRepositoryMockValue, userGroupsRepositoryMockValue, adb2cParam, - configMockValue, sendGridMockValue, ); expect(await service.getLicenseSummary(accountId)).toEqual( @@ -43,14 +40,12 @@ describe('AccountsService', () => { const accountsRepositoryMockValue = makeDefaultAccountsRepositoryMockValue(); accountsRepositoryMockValue.getLicenseSummaryInfo = null; - const configMockValue = makeDefaultConfigValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeAccountsServiceMock( accountsRepositoryMockValue, usersRepositoryMockValue, userGroupsRepositoryMockValue, adb2cParam, - configMockValue, sendGridMockValue, ); await expect(service.getLicenseSummary(accountId)).rejects.toEqual( @@ -69,14 +64,12 @@ describe('AccountsService', () => { const adb2cParam = makeDefaultAdB2cMockValue(); const accountsRepositoryMockValue = makeDefaultAccountsRepositoryMockValue(); - const configMockValue = makeDefaultConfigValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeAccountsServiceMock( accountsRepositoryMockValue, usersRepositoryMockValue, userGroupsRepositoryMockValue, adb2cParam, - configMockValue, sendGridMockValue, ); expect(await service.getTypists(externalId)).toEqual([ @@ -94,14 +87,12 @@ describe('AccountsService', () => { const adb2cParam = makeDefaultAdB2cMockValue(); const accountsRepositoryMockValue = makeDefaultAccountsRepositoryMockValue(); - const configMockValue = makeDefaultConfigValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeAccountsServiceMock( accountsRepositoryMockValue, usersRepositoryMockValue, userGroupsRepositoryMockValue, adb2cParam, - configMockValue, sendGridMockValue, ); await expect(service.getTypists(externalId)).rejects.toEqual( @@ -120,14 +111,12 @@ describe('AccountsService', () => { adb2cParam.getUsers = new Error(); const accountsRepositoryMockValue = makeDefaultAccountsRepositoryMockValue(); - const configMockValue = makeDefaultConfigValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeAccountsServiceMock( accountsRepositoryMockValue, usersRepositoryMockValue, userGroupsRepositoryMockValue, adb2cParam, - configMockValue, sendGridMockValue, ); await expect(service.getTypists(externalId)).rejects.toEqual( @@ -146,14 +135,12 @@ describe('AccountsService', () => { makeDefaultAccountsRepositoryMockValue(); const userGroupsRepositoryMockValue = makeDefaultUserGroupsRepositoryMockValue(); - const configMockValue = makeDefaultConfigValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeAccountsServiceMock( accountsRepositoryMockValue, usersRepositoryMockValue, userGroupsRepositoryMockValue, adb2cParam, - configMockValue, sendGridMockValue, ); @@ -171,14 +158,12 @@ describe('AccountsService', () => { makeDefaultAccountsRepositoryMockValue(); const userGroupsRepositoryMockValue = makeDefaultUserGroupsRepositoryMockValue(); - const configMockValue = makeDefaultConfigValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeAccountsServiceMock( accountsRepositoryMockValue, usersRepositoryMockValue, userGroupsRepositoryMockValue, adb2cParam, - configMockValue, sendGridMockValue, ); @@ -198,14 +183,12 @@ describe('AccountsService', () => { const userGroupsRepositoryMockValue = makeDefaultUserGroupsRepositoryMockValue(); userGroupsRepositoryMockValue.getUserGroups = new Error('DB failed'); - const configMockValue = makeDefaultConfigValue(); const sendGridMockValue = makeDefaultSendGridlValue(); const service = await makeAccountsServiceMock( accountsRepositoryMockValue, usersRepositoryMockValue, userGroupsRepositoryMockValue, adb2cParam, - configMockValue, sendGridMockValue, ); @@ -216,75 +199,6 @@ describe('AccountsService', () => { ), ); }); - it('パートナーを追加できる', async () => { - const companyName = "TEST_COMPANY"; - const country = "US"; - const email = "xxx@example.com"; - const adminName = "ADMIN"; - const userId = "100"; - const tier = 3; - const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); - const userGroupsRepositoryMockValue = - makeDefaultUserGroupsRepositoryMockValue(); - const adb2cParam = makeDefaultAdB2cMockValue(); - const accountsRepositoryMockValue = - makeDefaultAccountsRepositoryMockValue(); - const configMockValue = makeDefaultConfigValue(); - const sendGridMockValue = makeDefaultSendGridlValue(); - - const service = await makeAccountsServiceMock( - accountsRepositoryMockValue, - usersRepositoryMockValue, - userGroupsRepositoryMockValue, - adb2cParam, - configMockValue, - sendGridMockValue, - ); - expect(await service.createPartnerAccount(companyName, country,email,adminName,userId,tier +1)).toEqual( - undefined, - ); - }); - it('アカウントの追加に失敗した場合、エラーとなる', async () => { - const companyName = 'TEST_COMPANY'; - const country = 'US'; - const email = 'xxx@example.com'; - const adminName = 'ADMIN'; - const userId = '100'; - const tier = 3; - const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); - const userGroupsRepositoryMockValue = - makeDefaultUserGroupsRepositoryMockValue(); - const adb2cParam = makeDefaultAdB2cMockValue(); - const accountsRepositoryMockValue = - makeDefaultAccountsRepositoryMockValue(); - accountsRepositoryMockValue.createAccount = new Error('DB failed'); - const configMockValue = makeDefaultConfigValue(); - const sendGridMockValue = makeDefaultSendGridlValue(); - - const service = await makeAccountsServiceMock( - accountsRepositoryMockValue, - usersRepositoryMockValue, - userGroupsRepositoryMockValue, - adb2cParam, - configMockValue, - sendGridMockValue, - ); - await expect( - service.createPartnerAccount( - companyName, - country, - email, - adminName, - userId, - tier + 1, - ), - ).rejects.toEqual( - new HttpException( - makeErrorResponse('E009999'), - HttpStatus.INTERNAL_SERVER_ERROR, - ), - ); - }); }); const expectedAccountLisenceCounts = { diff --git a/dictation_server/src/features/accounts/accounts.service.ts b/dictation_server/src/features/accounts/accounts.service.ts index d0238b5..bbf92cb 100644 --- a/dictation_server/src/features/accounts/accounts.service.ts +++ b/dictation_server/src/features/accounts/accounts.service.ts @@ -10,14 +10,13 @@ import { } from '../../gateways/adb2c/adb2c.service'; import { Account } from '../../repositories/accounts/entity/account.entity'; import { User } from '../../repositories/users/entity/user.entity'; -import { LICENSE_EXPIRATION_THRESHOLD_DAYS, TIERS, USER_ROLES } from '../../constants'; +import { LICENSE_EXPIRATION_THRESHOLD_DAYS, TIERS } from '../../constants'; import { makeErrorResponse } from '../../common/error/makeErrorResponse'; import { TypistGroup } from './types/types'; import { GetLicenseSummaryResponse, Typist } from './types/types'; import { AccessToken } from '../../common/token'; import { UserNotFoundError } from '../../repositories/users/errors/types'; import { UserGroupsRepositoryService } from '../../repositories/user_groups/user_groups.repository.service'; -import { makePassword } from '../../common/password'; @Injectable() export class AccountsService { @@ -289,111 +288,4 @@ export class AccountsService { this.logger.log(`[OUT] ${this.getTypists.name}`); } } - - /** - * パートナーを追加する - * @param companyName - * @param country - * @param email - * @param adminName - * @param userId - * @param tier - */ - async createPartnerAccount( - companyName: string, - country: string, - email: string, - adminName: string, - userId: string, - tier: number, - ): Promise { - this.logger.log(`[IN] ${this.createPartnerAccount.name}`); - - let myAccountId: number; - - try { - // アクセストークンからユーザーIDを取得する - const user = await this.usersRepository.findUserByExternalId(userId); - myAccountId = user.account_id; - } catch (e) { - this.logger.error(`error=${e}`); - if (e instanceof UserNotFoundError) { - throw new HttpException( - makeErrorResponse('E010204'), - HttpStatus.BAD_REQUEST, - ); - } else { - throw new HttpException( - makeErrorResponse('E009999'), - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - } - - const ramdomPassword = makePassword(); - - let externalUser: { sub: string } | ConflictError; - - try { - // 管理者ユーザを作成し、AzureADB2C IDを取得する - externalUser = await this.adB2cService.createUser( - email, - ramdomPassword, - adminName, - ); - console.log(externalUser); - } catch (e) { - console.log(e); - console.log('create externalUser failed'); - throw new HttpException( - makeErrorResponse('E009999'), - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - // メールアドレスが重複していた場合はエラーを返す - if (isConflictError(externalUser)) { - throw new HttpException( - makeErrorResponse('E010301'), - HttpStatus.BAD_REQUEST, - ); - } - - try { - // アカウントと管理者をセットで作成 - const { newAccount, adminUser } = - await this.accountRepository.createAccount( - companyName, - country, - myAccountId, - tier + 1, - externalUser.sub, - USER_ROLES.NONE, - null, - ); - - const from = this.configService.get('MAIL_FROM') || ''; - const { subject, text, html } = - await this.sendgridService.createMailContentFromEmailConfirmForNormalUser( - newAccount.id, - adminUser.id, - email, - ); - await this.sendgridService.sendMail( - email, - from, - subject, - text, - html, - ); - } catch (e) { - console.log('create partner account failed'); - console.log( - `[NOT IMPLEMENT] [RECOVER] delete account: ${externalUser.sub}`, - ); - throw new HttpException( - makeErrorResponse('E009999'), - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - } } diff --git a/dictation_server/src/features/accounts/test/accounts.service.mock.ts b/dictation_server/src/features/accounts/test/accounts.service.mock.ts index b543f93..4100f78 100644 --- a/dictation_server/src/features/accounts/test/accounts.service.mock.ts +++ b/dictation_server/src/features/accounts/test/accounts.service.mock.ts @@ -1,4 +1,4 @@ -import { ConfigModule, ConfigService } from '@nestjs/config'; +import { ConfigModule } from '@nestjs/config'; import { Test, TestingModule } from '@nestjs/testing'; import { User } from '../../../repositories/users/entity/user.entity'; import { UsersRepositoryService } from '../../../repositories/users/users.repository.service'; @@ -9,11 +9,10 @@ import { ConflictError, } from '../../../gateways/adb2c/adb2c.service'; import { SendGridService } from '../../../gateways/sendgrid/sendgrid.service'; -import { Account, LicenseSummaryInfo } from '../types/types'; +import { LicenseSummaryInfo } from '../types/types'; import { UserGroup } from '../../../repositories/user_groups/entity/user_group.entity'; import { UserGroupsRepositoryService } from '../../../repositories/user_groups/user_groups.repository.service'; import { AdB2cUser } from '../../../gateways/adb2c/types/types'; -import { AccountSASPermissions } from '@azure/storage-blob'; export type UsersRepositoryMockValue = { findUserById: User | Error; findUserByExternalId: User | Error; @@ -32,29 +31,19 @@ export type SendGridMockValue = { text: string; html: string; }; - createMailContentFromEmailConfirmForNormalUser: { - subject: string; - text: string; - html: string; - }; sendMail: undefined | Error; }; -export type ConfigMockValue = { - get: string | Error; -}; export type AccountsRepositoryMockValue = { getLicenseSummaryInfo: { licenseSummary: LicenseSummaryInfo; isStorageAvailable: boolean; }; - createAccount: { newAccount: Account; adminUser: User } | Error; }; export const makeAccountsServiceMock = async ( accountsRepositoryMockValue: AccountsRepositoryMockValue, usersRepositoryMockValue: UsersRepositoryMockValue, userGroupsRepositoryMockValue: UserGroupsRepositoryMockValue, adB2cMockValue: AdB2cMockValue, - configMockValue: ConfigMockValue, sendGridMockValue: SendGridMockValue, ): Promise => { const module: TestingModule = await Test.createTestingModule({ @@ -76,8 +65,6 @@ export const makeAccountsServiceMock = async ( return makeUserGroupsRepositoryMock(userGroupsRepositoryMockValue); case AdB2cService: return makeAdB2cServiceMock(adB2cMockValue); - case ConfigService: - return makeConfigMock(configMockValue); case SendGridService: return makeSendGridServiceMock(sendGridMockValue); } @@ -90,7 +77,7 @@ export const makeAccountsServiceMock = async ( export const makeAccountsRepositoryMock = ( value: AccountsRepositoryMockValue, ) => { - const { getLicenseSummaryInfo, createAccount } = value; + const { getLicenseSummaryInfo } = value; return { getLicenseSummaryInfo: getLicenseSummaryInfo instanceof Error @@ -104,12 +91,6 @@ export const makeAccountsRepositoryMock = ( [] >() .mockResolvedValue(getLicenseSummaryInfo), - createAccount: - createAccount instanceof Error - ? jest.fn, []>().mockRejectedValue(createAccount) - : jest - .fn, []>() - .mockResolvedValue(createAccount), }; }; export const makeUsersRepositoryMock = (value: UsersRepositoryMockValue) => { @@ -158,18 +139,8 @@ export const makeAdB2cServiceMock = (value: AdB2cMockValue) => { : jest.fn, []>().mockResolvedValue(getUsers), }; }; -export const makeConfigMock = (value: ConfigMockValue) => { - const { get } = value; - - return { - get: - get instanceof Error - ? jest.fn, []>().mockRejectedValue(get) - : jest.fn, []>().mockResolvedValue(get), - }; -}; export const makeSendGridServiceMock = (value: SendGridMockValue) => { - const { createMailContentFromEmailConfirm,createMailContentFromEmailConfirmForNormalUser, sendMail } = value; + const { createMailContentFromEmailConfirm, sendMail } = value; return { createMailContentFromEmailConfirm: createMailContentFromEmailConfirm instanceof Error @@ -179,14 +150,6 @@ export const makeSendGridServiceMock = (value: SendGridMockValue) => { : jest .fn, []>() .mockResolvedValue(createMailContentFromEmailConfirm), - createMailContentFromEmailConfirmForNormalUser: - createMailContentFromEmailConfirmForNormalUser instanceof Error - ? jest - .fn, []>() - .mockRejectedValue(createMailContentFromEmailConfirmForNormalUser) - : jest - .fn, []>() - .mockResolvedValue(createMailContentFromEmailConfirmForNormalUser), sendMail: sendMail instanceof Error ? jest.fn, []>().mockRejectedValue(sendMail) @@ -207,33 +170,11 @@ export const makeDefaultAccountsRepositoryMockValue = numberOfRequesting: 7, allocatableLicenseWithMargin: 8, }; - const account = new Account(); - account.accountId = 1; - const user = new User(); - user.id = 1; - user.external_id = 'ede66c43-9b9d-4222-93ed-5f11c96e08e2'; - user.account_id = 1234567890123456; - user.role = 'none admin'; - user.author_id = '6cce347f-0cf1-a15e-19ab-d00988b643f9'; - user.accepted_terms_version = '1.0'; - user.email_verified = true; - user.auto_renew = false; - user.license_alert = false; - user.notification = false; - user.deleted_at = null; - user.created_by = 'test'; - user.created_at = new Date(); - user.updated_by = null; - user.updated_at = null; return { getLicenseSummaryInfo: { licenseSummary: licenseSummaryInfo, isStorageAvailable: false, }, - createAccount: { - newAccount: account, - adminUser: user, - }, }; }; export const makeDefaultUsersRepositoryMockValue = @@ -345,10 +286,5 @@ export const makeDefaultSendGridlValue = (): SendGridMockValue => { return { sendMail: undefined, createMailContentFromEmailConfirm: { subject: '', text: '', html: '' }, - createMailContentFromEmailConfirmForNormalUser: { - subject: 'Verify your new account', - text: `The verification URL.`, - html: `

The verification URL.

`, - }, }; }; diff --git a/dictation_server/src/features/accounts/types/types.ts b/dictation_server/src/features/accounts/types/types.ts index f33d0a7..416d73a 100644 --- a/dictation_server/src/features/accounts/types/types.ts +++ b/dictation_server/src/features/accounts/types/types.ts @@ -131,7 +131,7 @@ export class CreatePartnerAccountRequest { adminName: string; @ApiProperty() @IsEmail() - email: string; + eMail: string; } export class CreatePartnerAccountResponse {} \ No newline at end of file