Merged PR 383: API実装(パートナー取得API)
## 概要 [Task2540: API実装(パートナー取得API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2540) パートナー取得APIを実装しました。 ## レビューポイント ・データ取得方法が適切かどうか。 以下の優先順位を意識して作成したが適切か?また、意識できていない実装になっていないか? ①QueryBuilderを使用せずに処理する ②RDB、adb2cへのアクセス回数を最小限にする ## UIの変更 なし ## 動作確認状況 ローカルで動作確認済み、UT実施済み ## 補足 プライマリ、セカンダリ管理者IDがない場合のテストはUTでは実装せず、ローカルでの動作確認で正常に動作することを確認しました。 (プライマリ、セカンダリ管理者IDを指定してアカウントを作成するテストユーティリティを作成する必要があるが、あまり汎用的には思えず作成する手間が惜しかったため)
This commit is contained in:
parent
82fb224d67
commit
2812bc3d20
@ -9,6 +9,7 @@ import { UsersRepositoryService } from '../../repositories/users/users.repositor
|
|||||||
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
|
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
|
||||||
import { AccountsRepositoryService } from '../../repositories/accounts/accounts.repository.service';
|
import { AccountsRepositoryService } from '../../repositories/accounts/accounts.repository.service';
|
||||||
import { Account } from '../../repositories/accounts/entity/account.entity';
|
import { Account } from '../../repositories/accounts/entity/account.entity';
|
||||||
|
import { AdB2cUser } from '../../gateways/adb2c/types/types';
|
||||||
|
|
||||||
// ### ユニットテスト用コード以外では絶対に使用してはいけないダーティな手段を使用しているが、他の箇所では使用しないこと ###
|
// ### ユニットテスト用コード以外では絶対に使用してはいけないダーティな手段を使用しているが、他の箇所では使用しないこと ###
|
||||||
|
|
||||||
@ -28,6 +29,10 @@ export const overrideAdB2cService = <TService>(
|
|||||||
username: string,
|
username: string,
|
||||||
) => Promise<{ sub: string } | ConflictError>;
|
) => Promise<{ sub: string } | ConflictError>;
|
||||||
deleteUser?: (externalId: string, context: Context) => Promise<void>;
|
deleteUser?: (externalId: string, context: Context) => Promise<void>;
|
||||||
|
getUsers?: (
|
||||||
|
context: Context,
|
||||||
|
externalIds: string[],
|
||||||
|
) => Promise<AdB2cUser[]>;
|
||||||
},
|
},
|
||||||
): void => {
|
): void => {
|
||||||
// テストコードでのみ許される強引な方法でprivateメンバ変数の参照を取得
|
// テストコードでのみ許される強引な方法でprivateメンバ変数の参照を取得
|
||||||
@ -44,6 +49,12 @@ export const overrideAdB2cService = <TService>(
|
|||||||
writable: true,
|
writable: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (overrides.getUsers) {
|
||||||
|
Object.defineProperty(obj, obj.getUsers.name, {
|
||||||
|
value: overrides.getUsers,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -149,6 +149,8 @@ export const makeTestAccount = async (
|
|||||||
datasource: DataSource,
|
datasource: DataSource,
|
||||||
defaultAccountValue?: AccountDefault,
|
defaultAccountValue?: AccountDefault,
|
||||||
defaultAdminUserValue?: UserDefault,
|
defaultAdminUserValue?: UserDefault,
|
||||||
|
isPrimaryAdminNotExist?: boolean,
|
||||||
|
isSecondaryAdminNotExist?: boolean,
|
||||||
): Promise<{ account: Account; admin: User }> => {
|
): Promise<{ account: Account; admin: User }> => {
|
||||||
let accountId: number;
|
let accountId: number;
|
||||||
let userId: number;
|
let userId: number;
|
||||||
@ -198,10 +200,15 @@ export const makeTestAccount = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Accountの管理者を設定する
|
// Accountの管理者を設定する
|
||||||
|
let secondaryAdminUserId = null;
|
||||||
|
if (isPrimaryAdminNotExist && !isSecondaryAdminNotExist) {
|
||||||
|
secondaryAdminUserId = userId;
|
||||||
|
}
|
||||||
await datasource.getRepository(Account).update(
|
await datasource.getRepository(Account).update(
|
||||||
{ id: accountId },
|
{ id: accountId },
|
||||||
{
|
{
|
||||||
primary_admin_user_id: userId,
|
primary_admin_user_id: isPrimaryAdminNotExist ? null : userId,
|
||||||
|
secondary_admin_user_id: secondaryAdminUserId,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -238,3 +238,11 @@ export const OPTION_ITEM_VALUE_TYPE = {
|
|||||||
BLANK: 'Blank',
|
BLANK: 'Blank',
|
||||||
LAST_INPUT: 'LastInput',
|
LAST_INPUT: 'LastInput',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADB2Cユーザのidentity.signInType
|
||||||
|
* @const {string[]}
|
||||||
|
*/
|
||||||
|
export const ADB2C_SIGN_IN_TYPE = {
|
||||||
|
EAMILADDRESS: 'emailAddress',
|
||||||
|
} as const;
|
||||||
|
|||||||
@ -957,45 +957,13 @@ export class AccountsController {
|
|||||||
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
const { userId } = jwt.decode(token, { json: true }) as AccessToken;
|
||||||
|
|
||||||
const context = makeContext(userId);
|
const context = makeContext(userId);
|
||||||
// TODO: パートナー取得APIで実装
|
const response = await this.accountService.getPartners(
|
||||||
// await this.accountService.getPartners(
|
context,
|
||||||
// context,
|
userId,
|
||||||
// body.limit,
|
limit,
|
||||||
// body.offset,
|
offset,
|
||||||
// );
|
);
|
||||||
|
|
||||||
// 仮のreturn
|
return response;
|
||||||
return {
|
|
||||||
total: 1,
|
|
||||||
partners: [
|
|
||||||
{
|
|
||||||
name: 'testA',
|
|
||||||
tier: 5,
|
|
||||||
accountId: 1,
|
|
||||||
country: 'US',
|
|
||||||
primaryAdmin: 'nameA',
|
|
||||||
email: 'aaa@example.com',
|
|
||||||
dealerManagement: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'testB',
|
|
||||||
tier: 5,
|
|
||||||
accountId: 2,
|
|
||||||
country: 'US',
|
|
||||||
primaryAdmin: 'nameB',
|
|
||||||
email: 'bbb@example.com',
|
|
||||||
dealerManagement: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'testC',
|
|
||||||
tier: 5,
|
|
||||||
accountId: 1,
|
|
||||||
country: 'US',
|
|
||||||
primaryAdmin: 'nothing',
|
|
||||||
email: 'nothing',
|
|
||||||
dealerManagement: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import {
|
|||||||
import { AccountsService } from './accounts.service';
|
import { AccountsService } from './accounts.service';
|
||||||
import { Context, makeContext } from '../../common/log';
|
import { Context, makeContext } from '../../common/log';
|
||||||
import {
|
import {
|
||||||
|
ADB2C_SIGN_IN_TYPE,
|
||||||
LICENSE_ALLOCATED_STATUS,
|
LICENSE_ALLOCATED_STATUS,
|
||||||
LICENSE_ISSUE_STATUS,
|
LICENSE_ISSUE_STATUS,
|
||||||
LICENSE_TYPE,
|
LICENSE_TYPE,
|
||||||
@ -61,6 +62,7 @@ import {
|
|||||||
selectOrderLicense,
|
selectOrderLicense,
|
||||||
} from '../licenses/test/utility';
|
} from '../licenses/test/utility';
|
||||||
import { WorktypesRepositoryService } from '../../repositories/worktypes/worktypes.repository.service';
|
import { WorktypesRepositoryService } from '../../repositories/worktypes/worktypes.repository.service';
|
||||||
|
import { AdB2cUser } from '../../gateways/adb2c/types/types';
|
||||||
import { Worktype } from '../../repositories/worktypes/entity/worktype.entity';
|
import { Worktype } from '../../repositories/worktypes/entity/worktype.entity';
|
||||||
|
|
||||||
describe('createAccount', () => {
|
describe('createAccount', () => {
|
||||||
@ -4155,3 +4157,144 @@ describe('ライセンス発行キャンセル', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('パートナー一覧取得', () => {
|
||||||
|
let source: DataSource = null;
|
||||||
|
beforeEach(async () => {
|
||||||
|
source = new DataSource({
|
||||||
|
type: 'sqlite',
|
||||||
|
database: ':memory:',
|
||||||
|
logging: false,
|
||||||
|
entities: [__dirname + '/../../**/*.entity{.ts,.js}'],
|
||||||
|
synchronize: true, // trueにすると自動的にmigrationが行われるため注意
|
||||||
|
});
|
||||||
|
return source.initialize();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await source.destroy();
|
||||||
|
source = null;
|
||||||
|
});
|
||||||
|
it('パートナー一覧を取得する', async () => {
|
||||||
|
const module = await makeTestingModule(source);
|
||||||
|
const service = module.get<AccountsService>(AccountsService);
|
||||||
|
const { tier1Accounts: tier1Accounts, tier2Accounts: tier2Accounts } =
|
||||||
|
await makeHierarchicalAccounts(source);
|
||||||
|
const tier1Difference = await makeTestAccount(source, {
|
||||||
|
tier: 1,
|
||||||
|
});
|
||||||
|
const tier2_3 = await makeTestAccount(
|
||||||
|
source,
|
||||||
|
{
|
||||||
|
parent_account_id: tier1Accounts[0].account.id,
|
||||||
|
tier: 2,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
const tier2_4 = await makeTestAccount(
|
||||||
|
source,
|
||||||
|
{
|
||||||
|
parent_account_id: tier1Accounts[0].account.id,
|
||||||
|
tier: 2,
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
await makeTestAccount(source, {
|
||||||
|
parent_account_id: tier1Difference.account.id,
|
||||||
|
tier: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
const adb2cReturn = [
|
||||||
|
{
|
||||||
|
id: tier2Accounts[0].users[0].external_id,
|
||||||
|
displayName: 'partner1',
|
||||||
|
identities: [
|
||||||
|
{
|
||||||
|
signInType: ADB2C_SIGN_IN_TYPE.EAMILADDRESS,
|
||||||
|
issuer: 'issuer',
|
||||||
|
issuerAssignedId: 'partner1@example.com',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: tier2Accounts[1].users[0].external_id,
|
||||||
|
displayName: 'partner2',
|
||||||
|
identities: [
|
||||||
|
{
|
||||||
|
signInType: ADB2C_SIGN_IN_TYPE.EAMILADDRESS,
|
||||||
|
issuer: 'issuer',
|
||||||
|
issuerAssignedId: 'partner2@example.com',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
] as AdB2cUser[];
|
||||||
|
|
||||||
|
overrideAdB2cService(service, {
|
||||||
|
getUsers: async (_context: Context, _externalIds: string[]) => {
|
||||||
|
return adb2cReturn;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const partners = await service.getPartners(
|
||||||
|
makeContext('trackingId'),
|
||||||
|
tier1Accounts[0].users[0].external_id,
|
||||||
|
15,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 違うアカウントのパートナーは取得していないこと
|
||||||
|
expect(partners.total).toBe(4);
|
||||||
|
// 会社名の昇順に取得できていること
|
||||||
|
expect(partners.partners[0].name).toBe(
|
||||||
|
tier2Accounts[1].account.company_name,
|
||||||
|
);
|
||||||
|
expect(partners.partners[1].name).toBe(
|
||||||
|
tier2Accounts[0].account.company_name,
|
||||||
|
);
|
||||||
|
expect(partners.partners[2].name).toBe(tier2_3.account.company_name);
|
||||||
|
expect(partners.partners[3].name).toBe(tier2_4.account.company_name);
|
||||||
|
expect(partners.partners[0].email).toBe('partner2@example.com');
|
||||||
|
expect(partners.partners[1].email).toBe('partner1@example.com');
|
||||||
|
expect(partners.partners[2].email).toBeUndefined;
|
||||||
|
expect(partners.partners[3].email).toBeUndefined;
|
||||||
|
|
||||||
|
expect(partners.partners[0].tier).toBe(tier2Accounts[1].account.tier);
|
||||||
|
expect(partners.partners[0].country).toBe(tier2Accounts[1].account.country);
|
||||||
|
expect(partners.partners[0].accountId).toBe(tier2Accounts[1].account.id);
|
||||||
|
expect(partners.partners[0].tier).toBe(tier2Accounts[1].account.tier);
|
||||||
|
expect(partners.partners[0].primaryAdmin).toBe('partner2');
|
||||||
|
expect(partners.partners[0].dealerManagement).toBe(
|
||||||
|
tier2Accounts[1].account.delegation_permission,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('パートナー一覧を取得する(パートナーが0件の場合)', async () => {
|
||||||
|
const module = await makeTestingModule(source);
|
||||||
|
const service = module.get<AccountsService>(AccountsService);
|
||||||
|
const account = await makeTestAccount(source, {
|
||||||
|
tier: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const adb2cReturn = [{}] as AdB2cUser[];
|
||||||
|
|
||||||
|
overrideAdB2cService(service, {
|
||||||
|
getUsers: async (_context: Context, _externalIds: string[]) => {
|
||||||
|
return adb2cReturn;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const partners = await service.getPartners(
|
||||||
|
makeContext('trackingId'),
|
||||||
|
account.admin.external_id,
|
||||||
|
15,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
// 結果が0件で成功となること
|
||||||
|
expect(partners.total).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
} from '../../gateways/adb2c/adb2c.service';
|
} from '../../gateways/adb2c/adb2c.service';
|
||||||
import { Account } from '../../repositories/accounts/entity/account.entity';
|
import { Account } from '../../repositories/accounts/entity/account.entity';
|
||||||
import { User } from '../../repositories/users/entity/user.entity';
|
import { User } from '../../repositories/users/entity/user.entity';
|
||||||
import { TIERS, USER_ROLES } from '../../constants';
|
import { TIERS, USER_ROLES, ADB2C_SIGN_IN_TYPE } from '../../constants';
|
||||||
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
import { makeErrorResponse } from '../../common/error/makeErrorResponse';
|
||||||
import {
|
import {
|
||||||
TypistGroup,
|
TypistGroup,
|
||||||
@ -23,6 +23,7 @@ import {
|
|||||||
GetMyAccountResponse,
|
GetMyAccountResponse,
|
||||||
GetTypistGroupResponse,
|
GetTypistGroupResponse,
|
||||||
GetWorktypesResponse,
|
GetWorktypesResponse,
|
||||||
|
GetPartnersResponse,
|
||||||
} from './types/types';
|
} from './types/types';
|
||||||
import {
|
import {
|
||||||
DateWithZeroTime,
|
DateWithZeroTime,
|
||||||
@ -1312,4 +1313,85 @@ export class AccountsService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* パートナー一覧を取得します
|
||||||
|
* @param context
|
||||||
|
* @param externalId
|
||||||
|
* @param limit
|
||||||
|
* @param offset
|
||||||
|
* @returns GetPartnersResponse
|
||||||
|
*/
|
||||||
|
async getPartners(
|
||||||
|
context: Context,
|
||||||
|
externalId: string,
|
||||||
|
limit: number,
|
||||||
|
offset: number,
|
||||||
|
): Promise<GetPartnersResponse> {
|
||||||
|
this.logger.log(
|
||||||
|
`[IN] [${context.trackingId}] ${this.getPartners.name} | params: { ` +
|
||||||
|
`externalId: ${externalId}, ` +
|
||||||
|
`limit: ${limit}, ` +
|
||||||
|
`offset: ${offset}, };`,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { account_id: accountId } =
|
||||||
|
await this.usersRepository.findUserByExternalId(externalId);
|
||||||
|
|
||||||
|
const partners = await this.accountRepository.getPartners(
|
||||||
|
accountId,
|
||||||
|
limit,
|
||||||
|
offset,
|
||||||
|
);
|
||||||
|
|
||||||
|
// DBから取得したユーザーの外部IDをもとにADB2Cからユーザーを取得する
|
||||||
|
let externalIds = partners.partnersInfo.map(
|
||||||
|
(x) => x.primaryAccountExternalId,
|
||||||
|
);
|
||||||
|
externalIds = externalIds.filter((item) => item !== undefined);
|
||||||
|
const adb2cUsers = await this.adB2cService.getUsers(context, externalIds);
|
||||||
|
|
||||||
|
// DBから取得した情報とADB2Cから取得した情報をマージ
|
||||||
|
const response = partners.partnersInfo.map((db) => {
|
||||||
|
const adb2cUser = adb2cUsers.find(
|
||||||
|
(adb2c) => db.primaryAccountExternalId === adb2c.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
let primaryAdmin = undefined;
|
||||||
|
let mail = undefined;
|
||||||
|
if (adb2cUser) {
|
||||||
|
primaryAdmin = adb2cUser.displayName;
|
||||||
|
mail = adb2cUser.identities.find(
|
||||||
|
(identity) =>
|
||||||
|
identity.signInType === ADB2C_SIGN_IN_TYPE.EAMILADDRESS,
|
||||||
|
).issuerAssignedId;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: db.name,
|
||||||
|
tier: db.tier,
|
||||||
|
accountId: db.accountId,
|
||||||
|
country: db.country,
|
||||||
|
primaryAdmin: primaryAdmin,
|
||||||
|
email: mail,
|
||||||
|
dealerManagement: db.dealerManagement,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
total: partners.total,
|
||||||
|
partners: response,
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error(`error=${e}`);
|
||||||
|
if (e instanceof Error) {
|
||||||
|
throw new HttpException(
|
||||||
|
makeErrorResponse('E009999'),
|
||||||
|
HttpStatus.INTERNAL_SERVER_ERROR,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
this.logger.log(`[OUT] [${context.trackingId}] ${this.getPartners.name}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -480,3 +480,13 @@ export class GetPartnersResponse {
|
|||||||
@ApiProperty({ type: [Partner] })
|
@ApiProperty({ type: [Partner] })
|
||||||
partners: Partner[];
|
partners: Partner[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RepositoryからPartnerLicenseInfoに関する情報を取得する際の型
|
||||||
|
export type PartnerInfoFromDb = {
|
||||||
|
name: string;
|
||||||
|
tier: number;
|
||||||
|
accountId: number;
|
||||||
|
country: string;
|
||||||
|
primaryAccountExternalId: string;
|
||||||
|
dealerManagement: boolean;
|
||||||
|
};
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import {
|
|||||||
TaskListSortableAttribute,
|
TaskListSortableAttribute,
|
||||||
} from '../../../common/types/sort';
|
} from '../../../common/types/sort';
|
||||||
import { AdB2cUser } from '../../../gateways/adb2c/types/types';
|
import { AdB2cUser } from '../../../gateways/adb2c/types/types';
|
||||||
|
import { ADB2C_SIGN_IN_TYPE } from '../../../constants';
|
||||||
|
|
||||||
export type SortCriteriaRepositoryMockValue = {
|
export type SortCriteriaRepositoryMockValue = {
|
||||||
updateSortCriteria: SortCriteria | Error;
|
updateSortCriteria: SortCriteria | Error;
|
||||||
@ -403,7 +404,7 @@ const AdB2cMockUsers: AdB2cUser[] = [
|
|||||||
displayName: 'test1',
|
displayName: 'test1',
|
||||||
identities: [
|
identities: [
|
||||||
{
|
{
|
||||||
signInType: 'emailAddress',
|
signInType: ADB2C_SIGN_IN_TYPE.EAMILADDRESS,
|
||||||
issuer: 'issuer',
|
issuer: 'issuer',
|
||||||
issuerAssignedId: 'test1@mail.com',
|
issuerAssignedId: 'test1@mail.com',
|
||||||
},
|
},
|
||||||
@ -414,7 +415,7 @@ const AdB2cMockUsers: AdB2cUser[] = [
|
|||||||
displayName: 'test2',
|
displayName: 'test2',
|
||||||
identities: [
|
identities: [
|
||||||
{
|
{
|
||||||
signInType: 'emailAddress',
|
signInType: ADB2C_SIGN_IN_TYPE.EAMILADDRESS,
|
||||||
issuer: 'issuer',
|
issuer: 'issuer',
|
||||||
issuerAssignedId: 'test2@mail.com',
|
issuerAssignedId: 'test2@mail.com',
|
||||||
},
|
},
|
||||||
@ -425,7 +426,7 @@ const AdB2cMockUsers: AdB2cUser[] = [
|
|||||||
displayName: 'test3',
|
displayName: 'test3',
|
||||||
identities: [
|
identities: [
|
||||||
{
|
{
|
||||||
signInType: 'emailAddress',
|
signInType: ADB2C_SIGN_IN_TYPE.EAMILADDRESS,
|
||||||
issuer: 'issuer',
|
issuer: 'issuer',
|
||||||
issuerAssignedId: 'test3@mail.com',
|
issuerAssignedId: 'test3@mail.com',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import {
|
|||||||
UserNotFoundError,
|
UserNotFoundError,
|
||||||
} from '../../repositories/users/errors/types';
|
} from '../../repositories/users/errors/types';
|
||||||
import {
|
import {
|
||||||
|
ADB2C_SIGN_IN_TYPE,
|
||||||
LICENSE_EXPIRATION_THRESHOLD_DAYS,
|
LICENSE_EXPIRATION_THRESHOLD_DAYS,
|
||||||
USER_LICENSE_STATUS,
|
USER_LICENSE_STATUS,
|
||||||
USER_ROLES,
|
USER_ROLES,
|
||||||
@ -470,7 +471,7 @@ export class UsersService {
|
|||||||
|
|
||||||
// メールアドレスを取得する
|
// メールアドレスを取得する
|
||||||
const mail = adb2cUser.identities.find(
|
const mail = adb2cUser.identities.find(
|
||||||
(identity) => identity.signInType === 'emailAddress',
|
(identity) => identity.signInType === ADB2C_SIGN_IN_TYPE.EAMILADDRESS,
|
||||||
).issuerAssignedId;
|
).issuerAssignedId;
|
||||||
|
|
||||||
let status = USER_LICENSE_STATUS.NORMAL;
|
let status = USER_LICENSE_STATUS.NORMAL;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import axios from 'axios';
|
|||||||
import { Aadb2cUser, B2cMetadata, JwkSignKey } from '../../common/token';
|
import { Aadb2cUser, B2cMetadata, JwkSignKey } from '../../common/token';
|
||||||
import { AdB2cResponse, AdB2cUser } from './types/types';
|
import { AdB2cResponse, AdB2cUser } from './types/types';
|
||||||
import { Context } from '../../common/log';
|
import { Context } from '../../common/log';
|
||||||
|
import { ADB2C_SIGN_IN_TYPE } from '../../constants';
|
||||||
|
|
||||||
export type ConflictError = {
|
export type ConflictError = {
|
||||||
reason: 'email';
|
reason: 'email';
|
||||||
@ -74,7 +75,7 @@ export class AdB2cService {
|
|||||||
},
|
},
|
||||||
identities: [
|
identities: [
|
||||||
{
|
{
|
||||||
signinType: 'emailAddress',
|
signinType: ADB2C_SIGN_IN_TYPE.EAMILADDRESS,
|
||||||
issuer: `${this.tenantName}.onmicrosoft.com`,
|
issuer: `${this.tenantName}.onmicrosoft.com`,
|
||||||
issuerAssignedId: email,
|
issuerAssignedId: email,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
LicenseSummaryInfo,
|
LicenseSummaryInfo,
|
||||||
PartnerLicenseInfoForRepository,
|
PartnerLicenseInfoForRepository,
|
||||||
|
PartnerInfoFromDb,
|
||||||
} from '../../features/accounts/types/types';
|
} from '../../features/accounts/types/types';
|
||||||
import { AccountNotFoundError } from './errors/types';
|
import { AccountNotFoundError } from './errors/types';
|
||||||
import {
|
import {
|
||||||
@ -685,4 +686,83 @@ export class AccountsRepositoryService {
|
|||||||
await licenseRepo.delete({ order_id: targetOrder.id });
|
await licenseRepo.delete({ order_id: targetOrder.id });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* アカウントIDをもとに、パートナー一覧を取得する
|
||||||
|
* @param id
|
||||||
|
* @param limit
|
||||||
|
* @param offset
|
||||||
|
* @returns total: 総件数
|
||||||
|
* @returns partners: DBから取得できるパートナー一覧情報
|
||||||
|
*/
|
||||||
|
async getPartners(
|
||||||
|
id: number,
|
||||||
|
limit: number,
|
||||||
|
offset: number,
|
||||||
|
): Promise<{
|
||||||
|
total: number;
|
||||||
|
partnersInfo: PartnerInfoFromDb[];
|
||||||
|
}> {
|
||||||
|
return await this.dataSource.transaction(async (entityManager) => {
|
||||||
|
const accountRepo = entityManager.getRepository(Account);
|
||||||
|
|
||||||
|
// limit/offsetによらない総件数を取得する
|
||||||
|
const total = await accountRepo.count({
|
||||||
|
where: {
|
||||||
|
parent_account_id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const partnerAccounts = await accountRepo.find({
|
||||||
|
where: {
|
||||||
|
parent_account_id: id,
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
company_name: 'ASC',
|
||||||
|
},
|
||||||
|
take: limit,
|
||||||
|
skip: offset,
|
||||||
|
});
|
||||||
|
|
||||||
|
// ADB2Cから情報を取得するための外部ユーザIDを取得する(念のためプライマリ管理者IDが存在しない場合を考慮)
|
||||||
|
const primaryUserIds = partnerAccounts.map((x) => {
|
||||||
|
if (x.primary_admin_user_id) {
|
||||||
|
return x.primary_admin_user_id;
|
||||||
|
} else if (x.secondary_admin_user_id) {
|
||||||
|
return x.secondary_admin_user_id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const userRepo = entityManager.getRepository(User);
|
||||||
|
const primaryUsers = await userRepo.find({
|
||||||
|
where: {
|
||||||
|
id: In(primaryUserIds),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// アカウント情報とプライマリ管理者の外部ユーザIDをマージ
|
||||||
|
const partners = partnerAccounts.map((account) => {
|
||||||
|
const primaryUser = primaryUsers.find(
|
||||||
|
(user) =>
|
||||||
|
user.id === account.primary_admin_user_id ||
|
||||||
|
user.id === account.secondary_admin_user_id,
|
||||||
|
);
|
||||||
|
const primaryAccountExternalId = primaryUser
|
||||||
|
? primaryUser.external_id
|
||||||
|
: undefined;
|
||||||
|
return {
|
||||||
|
name: account.company_name,
|
||||||
|
tier: account.tier,
|
||||||
|
accountId: account.id,
|
||||||
|
country: account.country,
|
||||||
|
primaryAccountExternalId: primaryAccountExternalId,
|
||||||
|
dealerManagement: account.delegation_permission,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
total: total,
|
||||||
|
partnersInfo: partners,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user