Merged PR 580: [Sp20]既存APIのログを強化(外部連携API以外)

## 概要
[Task2295: [Sp20]既存APIのログを強化(外部連携API以外)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2295)

- 何をどう変更したか、追加したライブラリなど
誰が操作したのかを追えるようにログを強化

## レビューポイント
- 特にレビューしてほしい箇所
特になし

## 動作確認状況
- ユニットテスト
This commit is contained in:
水本 祐希 2023-11-17 02:54:18 +00:00
parent 50e3684423
commit d7bb56af54
28 changed files with 1250 additions and 524 deletions

View File

@ -4,8 +4,5 @@ export const makeContext = (
externalId: string, externalId: string,
delegationId?: string, delegationId?: string,
): Context => { ): Context => {
return { return new Context(externalId, delegationId);
trackingId: externalId,
delegationId: delegationId,
};
}; };

View File

@ -7,4 +7,19 @@ export class Context {
* APIの代行操作ユーザーを追跡するためのID * APIの代行操作ユーザーを追跡するためのID
*/ */
delegationId?: string | undefined; delegationId?: string | undefined;
constructor(externalId: string, delegationId?: string) {
this.trackingId = externalId;
this.delegationId = delegationId;
}
/**
*
*/
getTrackingId(): string {
if (this.delegationId) {
return `${this.trackingId} by ${this.delegationId}`;
} else {
return this.trackingId;
}
}
} }

View File

@ -76,9 +76,9 @@ import { retrieveAuthorizationToken } from '../../common/http/helper';
import { AccessToken } from '../../common/token'; import { AccessToken } from '../../common/token';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import { makeContext } from '../../common/log'; import { makeContext } from '../../common/log';
import { v4 as uuidv4 } from 'uuid';
import { AuthService } from '../auth/auth.service'; import { AuthService } from '../auth/auth.service';
import { makeErrorResponse } from '../../common/error/makeErrorResponse'; import { makeErrorResponse } from '../../common/error/makeErrorResponse';
import { v4 as uuidv4 } from 'uuid';
@ApiTags('accounts') @ApiTags('accounts')
@Controller('accounts') @Controller('accounts')
@ -167,7 +167,24 @@ export class AccountsController {
@Req() req: Request, @Req() req: Request,
@Body() body: GetLicenseSummaryRequest, @Body() body: GetLicenseSummaryRequest,
): Promise<GetLicenseSummaryResponse> { ): Promise<GetLicenseSummaryResponse> {
const accessToken = retrieveAuthorizationToken(req);
if (!accessToken) {
throw new HttpException(
makeErrorResponse('E000107'),
HttpStatus.UNAUTHORIZED,
);
}
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);
const response = await this.accountService.getLicenseSummary( const response = await this.accountService.getLicenseSummary(
context,
body.accountId, body.accountId,
); );
return response; return response;
@ -317,8 +334,9 @@ export class AccountsController {
); );
} }
const { userId } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId);
const typists = await this.accountService.getTypists(userId); const typists = await this.accountService.getTypists(context, userId);
return { typists }; return { typists };
} }
@ -363,8 +381,12 @@ export class AccountsController {
); );
} }
const { userId } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId);
const typistGroups = await this.accountService.getTypistGroups(userId); const typistGroups = await this.accountService.getTypistGroups(
context,
userId,
);
return { typistGroups }; return { typistGroups };
} }
@ -666,8 +688,31 @@ export class AccountsController {
): Promise<GetPartnerLicensesResponse> { ): Promise<GetPartnerLicensesResponse> {
const { limit, offset, accountId } = body; const { limit, offset, accountId } = body;
const accessToken = retrieveAuthorizationToken(req);
if (!accessToken) {
throw new HttpException(
makeErrorResponse('E000107'),
HttpStatus.UNAUTHORIZED,
);
}
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);
const getPartnerLicensesResponse = const getPartnerLicensesResponse =
await this.accountService.getPartnerLicenses(limit, offset, accountId); await this.accountService.getPartnerLicenses(
context,
limit,
offset,
accountId,
);
return getPartnerLicensesResponse; return getPartnerLicensesResponse;
} }
@ -703,8 +748,31 @@ export class AccountsController {
): Promise<GetOrderHistoriesResponse> { ): Promise<GetOrderHistoriesResponse> {
const { limit, offset, accountId } = body; const { limit, offset, accountId } = body;
const accessToken = retrieveAuthorizationToken(req);
if (!accessToken) {
throw new HttpException(
makeErrorResponse('E000107'),
HttpStatus.UNAUTHORIZED,
);
}
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);
const getOrderHistoriesResponse = const getOrderHistoriesResponse =
await this.accountService.getOrderHistories(limit, offset, accountId); await this.accountService.getOrderHistories(
context,
limit,
offset,
accountId,
);
return getOrderHistoriesResponse; return getOrderHistoriesResponse;
} }
@ -786,7 +854,8 @@ export class AccountsController {
}) })
@ApiOperation({ operationId: 'getDealers' }) @ApiOperation({ operationId: 'getDealers' })
async getDealers(): Promise<GetDealersResponse> { async getDealers(): Promise<GetDealersResponse> {
return await this.accountService.getDealers(); const context = makeContext(uuidv4());
return await this.accountService.getDealers(context);
} }
@Post('/issue/cancel') @Post('/issue/cancel')
@ -1460,9 +1529,14 @@ export class AccountsController {
async getAccountInfoMinimalAccess( async getAccountInfoMinimalAccess(
@Body() body: GetAccountInfoMinimalAccessRequest, @Body() body: GetAccountInfoMinimalAccessRequest,
): Promise<GetAccountInfoMinimalAccessResponse> { ): Promise<GetAccountInfoMinimalAccessResponse> {
const context = makeContext(uuidv4());
// IDトークンの検証 // IDトークンの検証
const idToken = await this.authService.getVerifiedIdToken(body.idToken); const idToken = await this.authService.getVerifiedIdToken(
const isVerified = await this.authService.isVerifiedUser(idToken); context,
body.idToken,
);
const isVerified = await this.authService.isVerifiedUser(context, idToken);
if (!isVerified) { if (!isVerified) {
throw new HttpException( throw new HttpException(
makeErrorResponse('E010201'), makeErrorResponse('E010201'),
@ -1470,8 +1544,6 @@ export class AccountsController {
); );
} }
const context = makeContext(idToken.sub);
const tier = await this.accountService.getAccountInfoMinimalAccess( const tier = await this.accountService.getAccountInfoMinimalAccess(
context, context,
idToken.sub, idToken.sub,

View File

@ -1587,7 +1587,8 @@ describe('AccountsService', () => {
licensesRepositoryMockValue, licensesRepositoryMockValue,
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
expect(await service.getLicenseSummary(accountId)).toEqual( const context = makeContext(`uuidv4`);
expect(await service.getLicenseSummary(context, accountId)).toEqual(
expectedAccountLisenceCounts, expectedAccountLisenceCounts,
); );
}); });
@ -1619,7 +1620,8 @@ describe('AccountsService', () => {
licensesRepositoryMockValue, licensesRepositoryMockValue,
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
await expect(service.getLicenseSummary(accountId)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getLicenseSummary(context, accountId)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -1653,7 +1655,8 @@ describe('AccountsService', () => {
licensesRepositoryMockValue, licensesRepositoryMockValue,
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
expect(await service.getTypists(externalId)).toEqual([ const context = makeContext(`uuidv4`);
expect(await service.getTypists(context, externalId)).toEqual([
{ id: 1, name: 'Typist1' }, { id: 1, name: 'Typist1' },
{ id: 2, name: 'Typist2' }, { id: 2, name: 'Typist2' },
{ id: 3, name: 'Typist3' }, { id: 3, name: 'Typist3' },
@ -1686,7 +1689,8 @@ describe('AccountsService', () => {
licensesRepositoryMockValue, licensesRepositoryMockValue,
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
await expect(service.getTypists(externalId)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getTypists(context, externalId)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -1720,7 +1724,8 @@ describe('AccountsService', () => {
licensesRepositoryMockValue, licensesRepositoryMockValue,
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
await expect(service.getTypists(externalId)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getTypists(context, externalId)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -1755,7 +1760,8 @@ describe('AccountsService', () => {
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
expect(await service.getTypistGroups(externalId)).toEqual([ const context = makeContext(`uuidv4`);
expect(await service.getTypistGroups(context, externalId)).toEqual([
{ id: 1, name: 'GroupA' }, { id: 1, name: 'GroupA' },
{ id: 2, name: 'GroupB' }, { id: 2, name: 'GroupB' },
]); ]);
@ -1788,7 +1794,8 @@ describe('AccountsService', () => {
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
await expect(service.getTypistGroups(externalId)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getTypistGroups(context, externalId)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -1823,7 +1830,8 @@ describe('AccountsService', () => {
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
await expect(service.getTypistGroups(externalId)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getTypistGroups(context, externalId)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -2005,7 +2013,13 @@ describe('getPartnerAccount', () => {
const offset = 0; const offset = 0;
const limit = 20; const limit = 20;
const response = await service.getPartnerLicenses(limit, offset, accountId); const context = makeContext(`uuidv4`);
const response = await service.getPartnerLicenses(
context,
limit,
offset,
accountId,
);
expect(response.total).toBe(2); expect(response.total).toBe(2);
@ -2146,7 +2160,13 @@ describe('getPartnerAccount', () => {
const offset = 0; const offset = 0;
const limit = 20; const limit = 20;
const response = await service.getPartnerLicenses(limit, offset, accountId); const context = makeContext(`uuidv4`);
const response = await service.getPartnerLicenses(
context,
limit,
offset,
accountId,
);
// 有効期限間近5件 有効期限間近でない3件'Unallocated', 'Allocated', 'Reusable' 有効期限未設定1件  9件 // 有効期限間近5件 有効期限間近でない3件'Unallocated', 'Allocated', 'Reusable' 有効期限未設定1件  9件
expect(response.childrenPartnerLicenses[0].stockLicense).toBe(9); expect(response.childrenPartnerLicenses[0].stockLicense).toBe(9);
@ -2239,7 +2259,13 @@ describe('getOrderHistories', () => {
const offset = 1; const offset = 1;
const limit = 2; const limit = 2;
const response = await service.getOrderHistories(limit, offset, accountId); const context = makeContext(`uuidv4`);
const response = await service.getOrderHistories(
context,
limit,
offset,
accountId,
);
expect(response.total).toBe(5); expect(response.total).toBe(5);
@ -2278,8 +2304,9 @@ describe('getOrderHistories', () => {
licensesRepositoryMockValue, licensesRepositoryMockValue,
worktypesRepositoryMockValue, worktypesRepositoryMockValue,
); );
const context = makeContext(`uuidv4`);
await expect( await expect(
service.getOrderHistories(limit, offset, accountId), service.getOrderHistories(context, limit, offset, accountId),
).rejects.toEqual( ).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -2640,8 +2667,9 @@ describe('getDealers', () => {
}) })
).account; ).account;
const service = module.get<AccountsService>(AccountsService); const service = module.get<AccountsService>(AccountsService);
const context = makeContext(`uuidv4`);
expect(await service.getDealers()).toEqual({ expect(await service.getDealers(context)).toEqual({
dealers: [ dealers: [
{ {
country: 'JP', country: 'JP',
@ -2668,7 +2696,8 @@ describe('getDealers', () => {
const service = module.get<AccountsService>(AccountsService); const service = module.get<AccountsService>(AccountsService);
expect(await service.getDealers()).toEqual({ const context = makeContext(`uuidv4`);
expect(await service.getDealers(context)).toEqual({
dealers: [], dealers: [],
}); });
}); });
@ -6019,7 +6048,8 @@ describe('getTypists', () => {
], ],
}); });
const typists = await service.getTypists(admin.external_id); const context = makeContext(`uuidv4`);
const typists = await service.getTypists(context, admin.external_id);
//実行結果を確認 //実行結果を確認
{ {
@ -6046,7 +6076,8 @@ describe('getTypists', () => {
overrideAdB2cService(service, { overrideAdB2cService(service, {
getUsers: async () => [{ id: admin.external_id, displayName: '' }], getUsers: async () => [{ id: admin.external_id, displayName: '' }],
}); });
const typists = await service.getTypists(admin.external_id); const context = makeContext(`uuidv4`);
const typists = await service.getTypists(context, admin.external_id);
//実行結果を確認 //実行結果を確認
{ {
@ -6094,7 +6125,8 @@ describe('getTypists', () => {
], ],
}); });
const typists = await service.getTypists(admin.external_id); const context = makeContext(`uuidv4`);
const typists = await service.getTypists(context, admin.external_id);
//実行結果を確認 //実行結果を確認
{ {
@ -6120,10 +6152,11 @@ describe('getTypists', () => {
UsersRepositoryService, UsersRepositoryService,
); );
usersService.findTypistUsers = jest.fn().mockRejectedValue('DB failed'); usersService.findTypistUsers = jest.fn().mockRejectedValue('DB failed');
const context = makeContext(`uuidv4`);
//実行結果を確認 //実行結果を確認
try { try {
await service.getTypists(admin.external_id); await service.getTypists(context, admin.external_id);
fail(); fail();
} catch (e) { } catch (e) {
if (e instanceof HttpException) { if (e instanceof HttpException) {

View File

@ -93,9 +93,14 @@ export class AccountsService {
* @returns LicenseSummary * @returns LicenseSummary
*/ */
async getLicenseSummary( async getLicenseSummary(
context: Context,
accountId: number, accountId: number,
): Promise<GetLicenseSummaryResponse> { ): Promise<GetLicenseSummaryResponse> {
this.logger.log(`[IN] ${this.getLicenseSummary.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getLicenseSummary.name
} | params: { ` + `accountId: ${accountId}, };`,
);
try { try {
const currentDate = new DateWithZeroTime(); const currentDate = new DateWithZeroTime();
@ -139,8 +144,10 @@ export class AccountsService {
}; };
return licenseSummaryResponse; return licenseSummaryResponse;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('get licenseSummary failed'); this.logger.error(
`[${context.getTrackingId()}] get licenseSummary failed`,
);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -167,8 +174,9 @@ export class AccountsService {
acceptedDpaVersion: string, acceptedDpaVersion: string,
): Promise<{ accountId: number; userId: number; externalUserId: string }> { ): Promise<{ accountId: number; userId: number; externalUserId: string }> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.createAccount.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
`country: ${country}, ` + this.createAccount.name
} | params: { ` +
`dealerAccountId: ${dealerAccountId}, ` + `dealerAccountId: ${dealerAccountId}, ` +
`role: ${role}, ` + `role: ${role}, ` +
`acceptedEulaVersion: ${acceptedEulaVersion} }, ` + `acceptedEulaVersion: ${acceptedEulaVersion} }, ` +
@ -185,8 +193,10 @@ export class AccountsService {
username, username,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create externalUser failed'); this.logger.error(
`[${context.getTrackingId()}] create externalUser failed`,
);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -196,7 +206,9 @@ export class AccountsService {
// メールアドレス重複エラー // メールアドレス重複エラー
if (isConflictError(externalUser)) { if (isConflictError(externalUser)) {
this.logger.error(`email conflict. externalUser: ${externalUser}`); this.logger.error(
`[${context.getTrackingId()}] email conflict. externalUser: ${externalUser}`,
);
throw new HttpException( throw new HttpException(
makeErrorResponse('E010301'), makeErrorResponse('E010301'),
HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST,
@ -221,11 +233,13 @@ export class AccountsService {
account = newAccount; account = newAccount;
user = adminUser; user = adminUser;
this.logger.log( this.logger.log(
`[${context.trackingId}] adminUser.external_id: ${user.external_id}`, `[${context.getTrackingId()}] adminUser.external_id: ${
user.external_id
}`,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create account failed'); this.logger.error(`[${context.getTrackingId()}] create account failed`);
//リカバリ処理 //リカバリ処理
// idpのユーザーを削除 // idpのユーザーを削除
await this.deleteAdB2cUser(externalUser.sub, context); await this.deleteAdB2cUser(externalUser.sub, context);
@ -244,8 +258,10 @@ export class AccountsService {
country, country,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create container failed'); this.logger.error(
`[${context.getTrackingId()}] create container failed`,
);
//リカバリ処理 //リカバリ処理
// idpのユーザーを削除 // idpのユーザーを削除
await this.deleteAdB2cUser(externalUser.sub, context); await this.deleteAdB2cUser(externalUser.sub, context);
@ -279,8 +295,8 @@ export class AccountsService {
html, html,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('send E-mail failed'); this.logger.error(`[${context.getTrackingId()}] send E-mail failed`);
//リカバリ処理 //リカバリ処理
// idpのユーザーを削除 // idpのユーザーを削除
await this.deleteAdB2cUser(externalUser.sub, context); await this.deleteAdB2cUser(externalUser.sub, context);
@ -306,7 +322,7 @@ export class AccountsService {
throw e; throw e;
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.createAccount.name}`, `[OUT] [${context.getTrackingId()}] ${this.createAccount.name}`,
); );
} }
} }
@ -320,12 +336,13 @@ export class AccountsService {
try { try {
await this.adB2cService.deleteUser(externalUserId, context); await this.adB2cService.deleteUser(externalUserId, context);
this.logger.log( this.logger.log(
`[${context.trackingId}] delete externalUser: ${externalUserId}`, `[${context.getTrackingId()}] delete externalUser: ${externalUserId} | params: { ` +
`externalUserId: ${externalUserId}, };`,
); );
} catch (error) { } catch (error) {
this.logger.error(`error=${error}`); this.logger.error(`[${context.getTrackingId()}] error=${error}`);
this.logger.error( this.logger.error(
`${MANUAL_RECOVERY_REQUIRED} [${context.trackingId}] Failed to delete externalUser: ${externalUserId}`, `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete externalUser: ${externalUserId}`,
); );
} }
} }
@ -336,15 +353,20 @@ export class AccountsService {
userId: number, userId: number,
context: Context, context: Context,
): Promise<void> { ): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.deleteAccount.name
} | params: { accountId: ${accountId}, userId: ${userId} };`,
);
try { try {
await this.accountRepository.deleteAccount(accountId, userId); await this.accountRepository.deleteAccount(accountId, userId);
this.logger.log( this.logger.log(
`[${context.trackingId}] delete account: ${accountId}, user: ${userId}`, `[${context.getTrackingId()}] delete account: ${accountId}, user: ${userId}`,
); );
} catch (error) { } catch (error) {
this.logger.error(`error=${error}`); this.logger.error(`[${context.getTrackingId()}] error=${error}`);
this.logger.error( this.logger.error(
`${MANUAL_RECOVERY_REQUIRED} [${context.trackingId}] Failed to delete account: ${accountId}, user: ${userId}`, `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete account: ${accountId}, user: ${userId}`,
); );
} }
} }
@ -356,6 +378,11 @@ export class AccountsService {
country: string, country: string,
context: Context, context: Context,
): Promise<void> { ): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.deleteBlobContainer.name
} | params: { accountId: ${accountId} };`,
);
try { try {
await this.blobStorageService.deleteContainer( await this.blobStorageService.deleteContainer(
context, context,
@ -363,11 +390,11 @@ export class AccountsService {
country, country,
); );
this.logger.log( this.logger.log(
`[${context.trackingId}] delete container: ${accountId}, country: ${country}`, `[${context.getTrackingId()}] delete container: ${accountId}, country: ${country}`,
); );
} catch (error) { } catch (error) {
this.logger.error( this.logger.error(
`${MANUAL_RECOVERY_REQUIRED} [${context.trackingId}] Failed to delete container: ${accountId}, country: ${country}`, `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete container: ${accountId}, country: ${country}`,
); );
} }
} }
@ -382,8 +409,9 @@ export class AccountsService {
externalId: string, externalId: string,
): Promise<GetMyAccountResponse> { ): Promise<GetMyAccountResponse> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getAccountInfo.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
`name: ${externalId}, };`, this.getAccountInfo.name
} | params: { ` + `externalId: ${externalId}, };`,
); );
try { try {
let userInfo: User; let userInfo: User;
@ -415,7 +443,7 @@ export class AccountsService {
}, },
}; };
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
throw new HttpException( throw new HttpException(
@ -435,13 +463,20 @@ export class AccountsService {
} }
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getAccountInfo.name}`, `[OUT] [${context.getTrackingId()}] ${this.getAccountInfo.name}`,
); );
} }
} }
async getTypistGroups(externalId: string): Promise<TypistGroup[]> { async getTypistGroups(
this.logger.log(`[IN] ${this.getTypistGroups.name}`); context: Context,
externalId: string,
): Promise<TypistGroup[]> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getTypistGroups.name
} | params: { externalId: ${externalId} };`,
);
// TypistGroup取得 // TypistGroup取得
try { try {
@ -452,13 +487,15 @@ export class AccountsService {
return userGroups.map((x) => ({ id: x.id, name: x.name })); return userGroups.map((x) => ({ id: x.id, name: x.name }));
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.getTypistGroups.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getTypistGroups.name}`,
);
} }
} }
/** /**
@ -474,7 +511,9 @@ export class AccountsService {
typistGroupId: number, typistGroupId: number,
): Promise<GetTypistGroupResponse> { ): Promise<GetTypistGroupResponse> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getTypistGroup.name} | params: { externalId: ${externalId}, typistGroupId: ${typistGroupId} };`, `[IN] [${context.getTrackingId()}] ${
this.getTypistGroup.name
} | params: { externalId: ${externalId}, typistGroupId: ${typistGroupId} };`,
); );
try { try {
@ -497,7 +536,7 @@ export class AccountsService {
typistIds: userGroupMembers.map((x) => x.user_id), typistIds: userGroupMembers.map((x) => x.user_id),
}; };
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TypistGroupNotExistError: case TypistGroupNotExistError:
@ -518,7 +557,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getTypistGroup.name}`, `[OUT] [${context.getTrackingId()}] ${this.getTypistGroup.name}`,
); );
} }
} }
@ -528,8 +567,12 @@ export class AccountsService {
* @param externalId * @param externalId
* @returns typists * @returns typists
*/ */
async getTypists(externalId: string): Promise<Typist[]> { async getTypists(context: Context, externalId: string): Promise<Typist[]> {
this.logger.log(`[IN] ${this.getTypists.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getTypists.name
} | params: { externalId: ${externalId} };`,
);
// Typist取得 // Typist取得
try { try {
@ -539,9 +582,9 @@ export class AccountsService {
const externalIds = typistUsers.map((x) => x.external_id); const externalIds = typistUsers.map((x) => x.external_id);
// B2Cからユーザー名を取得する // B2Cからユーザー名を取得する
const trackingId = new Context(context.trackingId);
const adb2cUsers = await this.adB2cService.getUsers( const adb2cUsers = await this.adB2cService.getUsers(
// TODO: 外部連携以外のログ強化時に、ContollerからContextを取得するように修正する trackingId,
{ trackingId: 'dummy' },
externalIds, externalIds,
); );
@ -560,13 +603,15 @@ export class AccountsService {
return typists; return typists;
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.getTypists.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getTypists.name}`,
);
} }
} }
@ -578,7 +623,9 @@ export class AccountsService {
*/ */
async getAuthors(context: Context, externalId: string): Promise<Author[]> { async getAuthors(context: Context, externalId: string): Promise<Author[]> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getAuthors.name} | params: { externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.getAuthors.name
} | params: { externalId: ${externalId} };`,
); );
try { try {
@ -609,7 +656,7 @@ export class AccountsService {
}); });
return authors; return authors;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case AccountNotFoundError: case AccountNotFoundError:
@ -629,7 +676,9 @@ export class AccountsService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.getAuthors.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getAuthors.name}`,
);
} }
} }
@ -652,7 +701,9 @@ export class AccountsService {
creatorAccountTier: number, creatorAccountTier: number,
): Promise<{ accountId: number }> { ): Promise<{ accountId: number }> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.createPartnerAccount.name} | params: { creatorUserId: ${creatorUserId}, creatorAccountTier: ${creatorAccountTier} };`, `[IN] [${context.getTrackingId()}] ${
this.createPartnerAccount.name
} | params: { creatorUserId: ${creatorUserId}, creatorAccountTier: ${creatorAccountTier} };`,
); );
try { try {
@ -664,7 +715,7 @@ export class AccountsService {
await this.usersRepository.findUserByExternalId(creatorUserId) await this.usersRepository.findUserByExternalId(creatorUserId)
).account_id; ).account_id;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof UserNotFoundError) { if (e instanceof UserNotFoundError) {
throw new HttpException( throw new HttpException(
makeErrorResponse('E010204'), makeErrorResponse('E010204'),
@ -691,7 +742,7 @@ export class AccountsService {
adminName, adminName,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -723,8 +774,10 @@ export class AccountsService {
account = newAccount; account = newAccount;
user = adminUser; user = adminUser;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create partner account failed'); this.logger.error(
`[${context.getTrackingId()}] create partner account failed`,
);
//リカバリ処理 //リカバリ処理
// idpのユーザーを削除 // idpのユーザーを削除
await this.deleteAdB2cUser(externalUser.sub, context); await this.deleteAdB2cUser(externalUser.sub, context);
@ -743,8 +796,10 @@ export class AccountsService {
country, country,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create partner container failed'); this.logger.error(
`[${context.getTrackingId()}] create partner container failed`,
);
//リカバリ処理 //リカバリ処理
// idpのユーザーを削除 // idpのユーザーを削除
await this.deleteAdB2cUser(externalUser.sub, context); await this.deleteAdB2cUser(externalUser.sub, context);
@ -761,6 +816,7 @@ export class AccountsService {
try { try {
const { subject, text, html } = const { subject, text, html } =
await this.sendgridService.createMailContentFromEmailConfirmForNormalUser( await this.sendgridService.createMailContentFromEmailConfirmForNormalUser(
context,
account.id, account.id,
user.id, user.id,
email, email,
@ -775,8 +831,10 @@ export class AccountsService {
); );
return { accountId: account.id }; return { accountId: account.id };
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create partner account send mail failed'); this.logger.error(
`[${context.getTrackingId()}] create partner account send mail failed`,
);
//リカバリ処理 //リカバリ処理
// idpのユーザーを削除 // idpのユーザーを削除
await this.deleteAdB2cUser(externalUser.sub, context); await this.deleteAdB2cUser(externalUser.sub, context);
@ -796,7 +854,7 @@ export class AccountsService {
throw e; throw e;
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.createPartnerAccount.name}`, `[OUT] [${context.getTrackingId()}] ${this.createPartnerAccount.name}`,
); );
} }
} }
@ -809,11 +867,16 @@ export class AccountsService {
* @returns getPartnerLicensesResponse * @returns getPartnerLicensesResponse
*/ */
async getPartnerLicenses( async getPartnerLicenses(
context: Context,
limit: number, limit: number,
offset: number, offset: number,
accountId: number, accountId: number,
): Promise<GetPartnerLicensesResponse> { ): Promise<GetPartnerLicensesResponse> {
this.logger.log(`[IN] ${this.getPartnerLicenses.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getPartnerLicenses.name
} | params: { limit: ${limit}, offset: ${offset}, accountId: ${accountId} };`,
);
try { try {
const currentDate = new DateWithZeroTime(); const currentDate = new DateWithZeroTime();
@ -891,13 +954,15 @@ export class AccountsService {
return getPartnerLicensesResponse; return getPartnerLicensesResponse;
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.getPartnerLicenses.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getPartnerLicenses.name}`,
);
} }
} }
/** /**
@ -908,11 +973,16 @@ export class AccountsService {
* @returns getOrderHistoriesResponse * @returns getOrderHistoriesResponse
*/ */
async getOrderHistories( async getOrderHistories(
context: Context,
limit: number, limit: number,
offset: number, offset: number,
accountId: number, accountId: number,
): Promise<GetOrderHistoriesResponse> { ): Promise<GetOrderHistoriesResponse> {
this.logger.log(`[IN] ${this.getOrderHistories.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getOrderHistories.name
} | params: { limit: ${limit}, offset: ${offset}, accountId: ${accountId} };`,
);
try { try {
const licenseHistoryInfo = const licenseHistoryInfo =
@ -949,13 +1019,15 @@ export class AccountsService {
}; };
return getOrderHistoriesResponse; return getOrderHistoriesResponse;
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.getOrderHistories.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getOrderHistories.name}`,
);
} }
} }
@ -975,7 +1047,9 @@ export class AccountsService {
poNumber: string, poNumber: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.issueLicense.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.issueLicense.name
} | params: { ` +
`orderedAccountId: ${orderedAccountId}, ` + `orderedAccountId: ${orderedAccountId}, ` +
`userId: ${userId}, ` + `userId: ${userId}, ` +
`tier: ${tier}, ` + `tier: ${tier}, ` +
@ -993,7 +1067,7 @@ export class AccountsService {
poNumber, poNumber,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case OrderNotFoundError: case OrderNotFoundError:
@ -1020,14 +1094,16 @@ export class AccountsService {
} }
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.issueLicense.name}`, `[OUT] [${context.getTrackingId()}] ${this.issueLicense.name}`,
); );
} }
} }
// dealersのアカウント情報を取得する // dealersのアカウント情報を取得する
async getDealers(): Promise<GetDealersResponse> { async getDealers(context: Context): Promise<GetDealersResponse> {
this.logger.log(`[IN] ${this.getDealers.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.getDealers.name}`,
);
try { try {
const dealerAccounts = await this.accountRepository.findDealerAccounts(); const dealerAccounts = await this.accountRepository.findDealerAccounts();
@ -1044,13 +1120,15 @@ export class AccountsService {
return dealers; return dealers;
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.getDealers.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getDealers.name}`,
);
} }
} }
/** /**
@ -1068,7 +1146,9 @@ export class AccountsService {
typistIds: number[], typistIds: number[],
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.createTypistGroup.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.createTypistGroup.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`typistGroupName: ${typistGroupName}, ` + `typistGroupName: ${typistGroupName}, ` +
`typistIds: ${typistIds} };`, `typistIds: ${typistIds} };`,
@ -1085,7 +1165,7 @@ export class AccountsService {
account_id, account_id,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TypistIdInvalidError: case TypistIdInvalidError:
@ -1124,7 +1204,13 @@ export class AccountsService {
typistIds: number[], typistIds: number[],
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateTypistGroup.name} | params: { typistGroupId: ${typistGroupId}, typistGroupName: ${typistGroupName}, typistIds: ${typistIds} };`, `[IN] [${context.getTrackingId()}] ${
this.updateTypistGroup.name
} | params: { ` +
`externalId: ${externalId}, ` +
`typistGroupId: ${typistGroupId}, ` +
`typistGroupName: ${typistGroupName}, ` +
`typistIds: ${typistIds} };`,
); );
try { try {
// 外部IDをもとにユーザー情報を取得する // 外部IDをもとにユーザー情報を取得する
@ -1140,7 +1226,7 @@ export class AccountsService {
typistIds, typistIds,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
// タイピストIDが存在しない場合は400エラーを返す // タイピストIDが存在しない場合は400エラーを返す
@ -1168,7 +1254,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.updateTypistGroup.name}`, `[OUT] [${context.getTrackingId()}] ${this.updateTypistGroup.name}`,
); );
} }
} }
@ -1187,7 +1273,9 @@ export class AccountsService {
orderedAccountId: number, orderedAccountId: number,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.cancelIssue.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.cancelIssue.name
} | params: { ` +
`extarnalId: ${extarnalId}, ` + `extarnalId: ${extarnalId}, ` +
`poNumber: ${poNumber}, ` + `poNumber: ${poNumber}, ` +
`orderedAccountId: ${orderedAccountId}, };`, `orderedAccountId: ${orderedAccountId}, };`,
@ -1200,7 +1288,7 @@ export class AccountsService {
await this.usersRepository.findUserByExternalId(extarnalId) await this.usersRepository.findUserByExternalId(extarnalId)
).account_id; ).account_id;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
default: default:
throw new HttpException( throw new HttpException(
@ -1209,7 +1297,9 @@ export class AccountsService {
); );
} }
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancelIssue.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.cancelIssue.name}`,
);
} }
// 注文元アカウントIDの親世代を取得 // 注文元アカウントIDの親世代を取得
@ -1218,7 +1308,9 @@ export class AccountsService {
); );
// 自身が存在しない場合、エラー // 自身が存在しない場合、エラー
if (!parentAccountIds.includes(myAccountId)) { if (!parentAccountIds.includes(myAccountId)) {
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancelIssue.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.cancelIssue.name}`,
);
throw new HttpException( throw new HttpException(
makeErrorResponse('E000108'), makeErrorResponse('E000108'),
HttpStatus.UNAUTHORIZED, HttpStatus.UNAUTHORIZED,
@ -1229,7 +1321,7 @@ export class AccountsService {
// 発行キャンセル処理 // 発行キャンセル処理
await this.accountRepository.cancelIssue(orderedAccountId, poNumber); await this.accountRepository.cancelIssue(orderedAccountId, poNumber);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case AlreadyLicenseStatusChangedError: case AlreadyLicenseStatusChangedError:
throw new HttpException( throw new HttpException(
@ -1253,7 +1345,9 @@ export class AccountsService {
); );
} }
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancelIssue.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.cancelIssue.name}`,
);
} }
} }
@ -1267,7 +1361,11 @@ export class AccountsService {
context: Context, context: Context,
externalId: string, externalId: string,
): Promise<GetWorktypesResponse> { ): Promise<GetWorktypesResponse> {
this.logger.log(`[IN] [${context.trackingId}] ${this.getWorktypes.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getWorktypes.name
} | params: { externalId: ${externalId} };`,
);
try { try {
// 外部IDをもとにユーザー情報を取得する // 外部IDをもとにユーザー情報を取得する
const { account_id: accountId } = const { account_id: accountId } =
@ -1286,7 +1384,7 @@ export class AccountsService {
active: active_worktype_id, active: active_worktype_id,
}; };
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case AccountNotFoundError: case AccountNotFoundError:
@ -1307,7 +1405,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getWorktypes.name}`, `[OUT] [${context.getTrackingId()}] ${this.getWorktypes.name}`,
); );
} }
} }
@ -1325,7 +1423,11 @@ export class AccountsService {
worktypeId: string, worktypeId: string,
description?: string, description?: string,
): Promise<void> { ): Promise<void> {
this.logger.log(`[IN] [${context.trackingId}] ${this.createWorktype.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.createWorktype.name
} | params: { externalId: ${externalId}, worktypeId: ${worktypeId}, description: ${description} };`,
);
try { try {
// 外部IDをもとにユーザー情報を取得する // 外部IDをもとにユーザー情報を取得する
@ -1338,7 +1440,7 @@ export class AccountsService {
description, description,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
// WorktypeIDが既に存在する場合は400エラーを返す // WorktypeIDが既に存在する場合は400エラーを返す
@ -1366,7 +1468,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.createWorktype.name}`, `[OUT] [${context.getTrackingId()}] ${this.createWorktype.name}`,
); );
} }
} }
@ -1388,7 +1490,9 @@ export class AccountsService {
description?: string, description?: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateWorktype.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.updateWorktype.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`id: ${id}, ` + `id: ${id}, ` +
`worktypeId: ${worktypeId}, ` + `worktypeId: ${worktypeId}, ` +
@ -1408,7 +1512,7 @@ export class AccountsService {
description, description,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
// ユーザーが設定したWorktypeIDが既存WorktypeのWorktypeIDと重複する場合は400エラーを返す // ユーザーが設定したWorktypeIDが既存WorktypeのWorktypeIDと重複する場合は400エラーを返す
@ -1436,7 +1540,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.updateWorktype.name}`, `[OUT] [${context.getTrackingId()}] ${this.updateWorktype.name}`,
); );
} }
} }
@ -1454,7 +1558,9 @@ export class AccountsService {
id: number, id: number,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.deleteWorktype.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.deleteWorktype.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`id: ${id} };`, `id: ${id} };`,
); );
@ -1473,7 +1579,7 @@ export class AccountsService {
// ワークタイプを削除する // ワークタイプを削除する
await this.worktypesRepository.deleteWorktype(accountId, id); await this.worktypesRepository.deleteWorktype(accountId, id);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
@ -1511,7 +1617,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.deleteWorktype.name}`, `[OUT] [${context.getTrackingId()}] ${this.deleteWorktype.name}`,
); );
} }
} }
@ -1529,7 +1635,9 @@ export class AccountsService {
id: number, id: number,
): Promise<GetOptionItemsResponse> { ): Promise<GetOptionItemsResponse> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getOptionItems.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.getOptionItems.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`id: ${id} };`, `id: ${id} };`,
); );
@ -1553,7 +1661,7 @@ export class AccountsService {
})), })),
}; };
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
// 内部IDで指定されたWorktypeが存在しない場合は400エラーを返す // 内部IDで指定されたWorktypeが存在しない場合は400エラーを返す
@ -1575,7 +1683,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getOptionItems.name}`, `[OUT] [${context.getTrackingId()}] ${this.getOptionItems.name}`,
); );
} }
} }
@ -1595,7 +1703,9 @@ export class AccountsService {
optionItems: PostWorktypeOptionItem[], optionItems: PostWorktypeOptionItem[],
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateOptionItems.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.updateOptionItems.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`id: ${id}, ` + `id: ${id}, ` +
`optionItems: ${JSON.stringify(optionItems)} };`, `optionItems: ${JSON.stringify(optionItems)} };`,
@ -1620,7 +1730,7 @@ export class AccountsService {
})), })),
); );
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
// 内部IDで指定されたWorktypeが存在しない場合は400エラーを返す // 内部IDで指定されたWorktypeが存在しない場合は400エラーを返す
@ -1642,7 +1752,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.updateOptionItems.name}`, `[OUT] [${context.getTrackingId()}] ${this.updateOptionItems.name}`,
); );
} }
} }
@ -1660,7 +1770,9 @@ export class AccountsService {
id: number | undefined, id: number | undefined,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateActiveWorktype.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.updateActiveWorktype.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`id: ${id} };`, `id: ${id} };`,
); );
@ -1672,7 +1784,7 @@ export class AccountsService {
// ActiveWorktypeを更新する // ActiveWorktypeを更新する
await this.accountRepository.updateActiveWorktypeId(accountId, id); await this.accountRepository.updateActiveWorktypeId(accountId, id);
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
// 内部IDで指定されたWorktypeが存在しない場合は400エラーを返す // 内部IDで指定されたWorktypeが存在しない場合は400エラーを返す
@ -1694,7 +1806,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.updateActiveWorktype.name}`, `[OUT] [${context.getTrackingId()}] ${this.updateActiveWorktype.name}`,
); );
} }
} }
@ -1714,7 +1826,9 @@ export class AccountsService {
offset: number, offset: number,
): Promise<GetPartnersResponse> { ): Promise<GetPartnersResponse> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getPartners.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.getPartners.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`limit: ${limit}, ` + `limit: ${limit}, ` +
`offset: ${offset}, };`, `offset: ${offset}, };`,
@ -1774,13 +1888,15 @@ export class AccountsService {
partners: partners, partners: partners,
}; };
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.getPartners.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getPartners.name}`,
);
} }
} }
@ -1805,8 +1921,11 @@ export class AccountsService {
secondryAdminUserId?: number, secondryAdminUserId?: number,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateAccountInfo.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.updateAccountInfo.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`tier: ${tier}, ` +
`delegationPermission: ${delegationPermission}, ` + `delegationPermission: ${delegationPermission}, ` +
`primaryAdminUserId: ${primaryAdminUserId}, ` + `primaryAdminUserId: ${primaryAdminUserId}, ` +
`parentAccountId: ${parentAccountId}, ` + `parentAccountId: ${parentAccountId}, ` +
@ -1825,7 +1944,7 @@ export class AccountsService {
secondryAdminUserId, secondryAdminUserId,
); );
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case DealerAccountNotFoundError: case DealerAccountNotFoundError:
@ -1847,7 +1966,7 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.updateAccountInfo.name}`, `[OUT] [${context.getTrackingId()}] ${this.updateAccountInfo.name}`,
); );
} }
} }
@ -1864,7 +1983,9 @@ export class AccountsService {
accountId: number, accountId: number,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.deleteAccountAndData.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.deleteAccountAndData.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`accountId: ${accountId}, };`, `accountId: ${accountId}, };`,
); );
@ -1889,13 +2010,15 @@ export class AccountsService {
dbUsers = await this.accountRepository.deleteAccountAndInsertArchives( dbUsers = await this.accountRepository.deleteAccountAndInsertArchives(
accountId, accountId,
); );
this.logger.log(`[${context.trackingId}] delete account: ${accountId}`); this.logger.log(
`[${context.getTrackingId()}] delete account: ${accountId}`,
);
country = targetAccount.country; country = targetAccount.country;
} catch (e) { } catch (e) {
// アカウントの削除に失敗した場合はエラーを返す // アカウントの削除に失敗した場合はエラーを返す
this.logger.log(`[${context.trackingId}] ${e}`); this.logger.log(`[${context.getTrackingId()}] ${e}`);
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.deleteAccountAndData.name}`, `[OUT] [${context.getTrackingId()}] ${this.deleteAccountAndData.name}`,
); );
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -1910,19 +2033,15 @@ export class AccountsService {
context, context,
); );
this.logger.log( this.logger.log(
`[${ `[${context.getTrackingId()}] delete ADB2C users: ${accountId}, users_id: ${dbUsers.map(
context.trackingId
}] delete ADB2C users: ${accountId}, users_id: ${dbUsers.map(
(x) => x.external_id, (x) => x.external_id,
)}`, )}`,
); );
} catch (e) { } catch (e) {
// ADB2Cユーザーの削除失敗時は、MANUAL_RECOVERY_REQUIREDを出して処理続行 // ADB2Cユーザーの削除失敗時は、MANUAL_RECOVERY_REQUIREDを出して処理続行
this.logger.log(`[${context.trackingId}] ${e}`); this.logger.log(`[${context.getTrackingId()}] ${e}`);
this.logger.log( this.logger.log(
`${MANUAL_RECOVERY_REQUIRED} [${ `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete ADB2C users: ${accountId}, users_id: ${dbUsers.map(
context.trackingId
}] Failed to delete ADB2C users: ${accountId}, users_id: ${dbUsers.map(
(x) => x.external_id, (x) => x.external_id,
)}`, )}`,
); );
@ -1932,18 +2051,18 @@ export class AccountsService {
// blobstorageコンテナを削除する // blobstorageコンテナを削除する
await this.deleteBlobContainer(accountId, country, context); await this.deleteBlobContainer(accountId, country, context);
this.logger.log( this.logger.log(
`[${context.trackingId}] delete blob container: ${accountId}-${country}`, `[${context.getTrackingId()}] delete blob container: ${accountId}-${country}`,
); );
} catch (e) { } catch (e) {
// blobstorageコンテナを削除で失敗した場合は、MANUAL_RECOVERY_REQUIRED出して正常終了 // blobstorageコンテナを削除で失敗した場合は、MANUAL_RECOVERY_REQUIRED出して正常終了
this.logger.log(`[${context.trackingId}] ${e}`); this.logger.log(`[${context.getTrackingId()}] ${e}`);
this.logger.log( this.logger.log(
`${MANUAL_RECOVERY_REQUIRED}[${context.trackingId}] Failed to delete blob container: ${accountId}, country: ${country}`, `${MANUAL_RECOVERY_REQUIRED}[${context.getTrackingId()}] Failed to delete blob container: ${accountId}, country: ${country}`,
); );
} }
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.deleteAccountAndData.name}`, `[OUT] [${context.getTrackingId()}] ${this.deleteAccountAndData.name}`,
); );
} }
@ -1958,7 +2077,9 @@ export class AccountsService {
externalId: string, externalId: string,
): Promise<number> { ): Promise<number> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getAccountInfoMinimalAccess.name} | params: { externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.getAccountInfoMinimalAccess.name
} | params: { externalId: ${externalId} };`,
); );
try { try {
@ -1973,7 +2094,7 @@ export class AccountsService {
return account.tier; return account.tier;
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
@ -1999,7 +2120,9 @@ export class AccountsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getAccountInfoMinimalAccess.name}`, `[OUT] [${context.getTrackingId()}] ${
this.getAccountInfoMinimalAccess.name
}`,
); );
} }
} }

View File

@ -66,9 +66,13 @@ export class AuthController {
operationId: 'token', operationId: 'token',
}) })
async token(@Body() body: TokenRequest): Promise<TokenResponse> { async token(@Body() body: TokenRequest): Promise<TokenResponse> {
const idToken = await this.authService.getVerifiedIdToken(body.idToken); const context = makeContext(uuidv4());
const idToken = await this.authService.getVerifiedIdToken(
context,
body.idToken,
);
const isVerified = await this.authService.isVerifiedUser(idToken); const isVerified = await this.authService.isVerifiedUser(context, idToken);
if (!isVerified) { if (!isVerified) {
throw new HttpException( throw new HttpException(
makeErrorResponse('E010201'), makeErrorResponse('E010201'),
@ -76,10 +80,8 @@ export class AuthController {
); );
} }
const context = makeContext(idToken.sub);
const key = makeIDTokenKey(body.idToken); const key = makeIDTokenKey(body.idToken);
const isTokenExists = await this.redisService.get<boolean>(key); const isTokenExists = await this.redisService.get<boolean>(context, key);
if (isTokenExists) { if (isTokenExists) {
// IDトークンがキャッシュに存在する場合エラー // IDトークンがキャッシュに存在する場合エラー
throw new HttpException( throw new HttpException(
@ -101,7 +103,7 @@ export class AuthController {
} }
// IDトークンをキャッシュに保存(idTokenの有効期限をADB2Cの有効期限と合わせる(300秒)) // IDトークンをキャッシュに保存(idTokenの有効期限をADB2Cの有効期限と合わせる(300秒))
await this.redisService.set(key, true, 300); await this.redisService.set(context, key, true, 300);
const refreshToken = await this.authService.generateRefreshToken( const refreshToken = await this.authService.generateRefreshToken(
context, context,

View File

@ -31,7 +31,10 @@ describe('AuthService', () => {
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.RyieW-VHsHPQOjXbbhRc307AYJOc1sq2hrcu4SW1-K0pvLlkplepxvx02a3vCwQrnBYrIP5w6HExG-S_JgW5nYyWr6DeY11mA484n9KA8GeAcAXV37StH1gfWUJvfGb4C8BaMbMM9Ix4Z9NGwKA9vjNwevfmBZnz9lQUePgv6BJNmyvCt8ElJ01O-1WODbZuojJ4xXymA1OqluzfbphPOsqWTSNmTn0emkLjjnlMQf1iwM4C_kvvr8dUCFg0_UGDfQVJnzPEKB38UqnhLnC5WacrddDwQ0kBuGKZgZ_63Q_7fOvqAZivqLK7BPmbPxi6mx3R1S9Eq2ugzpY1LfJOjA'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.RyieW-VHsHPQOjXbbhRc307AYJOc1sq2hrcu4SW1-K0pvLlkplepxvx02a3vCwQrnBYrIP5w6HExG-S_JgW5nYyWr6DeY11mA484n9KA8GeAcAXV37StH1gfWUJvfGb4C8BaMbMM9Ix4Z9NGwKA9vjNwevfmBZnz9lQUePgv6BJNmyvCt8ElJ01O-1WODbZuojJ4xXymA1OqluzfbphPOsqWTSNmTn0emkLjjnlMQf1iwM4C_kvvr8dUCFg0_UGDfQVJnzPEKB38UqnhLnC5WacrddDwQ0kBuGKZgZ_63Q_7fOvqAZivqLK7BPmbPxi6mx3R1S9Eq2ugzpY1LfJOjA';
expect(await service.getVerifiedIdToken(token)).toEqual(idTokenPayload); const context = makeContext(`uuidv4`);
expect(await service.getVerifiedIdToken(context, token)).toEqual(
idTokenPayload,
);
}); });
it('IDトークンの形式が不正な場合、形式不正エラーとなる。', async () => { it('IDトークンの形式が不正な場合、形式不正エラーとなる。', async () => {
@ -40,7 +43,8 @@ describe('AuthService', () => {
const service = await makeAuthServiceMock(adb2cParam, configMockValue); const service = await makeAuthServiceMock(adb2cParam, configMockValue);
const token = 'invalid.id.token'; const token = 'invalid.id.token';
await expect(service.getVerifiedIdToken(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getVerifiedIdToken(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED), new HttpException(makeErrorResponse('E000101'), HttpStatus.UNAUTHORIZED),
); );
}); });
@ -54,7 +58,8 @@ describe('AuthService', () => {
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjEwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.r9x61Mf1S2qFgU_QDKB6tRFBmTQXyOEtpoacOlL_bQzFz1t3GsxMy6SJIvQQ-LtDgylQ1UCdMFiRuy4V8nyLuME0fR-9IkKsboGvwllHB_Isai3XFoja0jpDHMVby1m0B3Z9xOTb7YsaQGyEH-qs1TtnRm6Ny98h4Po80nK8HGefQZHBOlfQN_B1LiHwI3nLXV18NL-4olKXj2NloNRYtnWM0PaqDQcGvZFaSNvtrSYpo9ddD906QWDGVOQ7WvGSUgdNCoxX8Lb3r2-VSj6n84jpb-Y1Fz-GhLluNglAsBhasnJfUIvCIO3iG5pRyTYjHFAVHmzjr8xMOmhS3s41Jw'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjEwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.r9x61Mf1S2qFgU_QDKB6tRFBmTQXyOEtpoacOlL_bQzFz1t3GsxMy6SJIvQQ-LtDgylQ1UCdMFiRuy4V8nyLuME0fR-9IkKsboGvwllHB_Isai3XFoja0jpDHMVby1m0B3Z9xOTb7YsaQGyEH-qs1TtnRm6Ny98h4Po80nK8HGefQZHBOlfQN_B1LiHwI3nLXV18NL-4olKXj2NloNRYtnWM0PaqDQcGvZFaSNvtrSYpo9ddD906QWDGVOQ7WvGSUgdNCoxX8Lb3r2-VSj6n84jpb-Y1Fz-GhLluNglAsBhasnJfUIvCIO3iG5pRyTYjHFAVHmzjr8xMOmhS3s41Jw';
await expect(service.getVerifiedIdToken(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getVerifiedIdToken(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E000102'), HttpStatus.UNAUTHORIZED), new HttpException(makeErrorResponse('E000102'), HttpStatus.UNAUTHORIZED),
); );
}); });
@ -68,7 +73,8 @@ describe('AuthService', () => {
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6OTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.fX2Gbd7fDPNE3Lw-xbum_5CVqQYqEmMhv_v5u8A-U81pmPD2P5rsJEJx66ns1taFLVaE3j9_OzotxrqjqqQqbACkagGcN5wvA3_ZIxyqmhrKYFJc53ZcO7d0pFWiQlluNBI_pnFNDlSMB2Ut8Th5aiPy2uamBM9wC99bcjo7HkHvTKBf6ljU6rPKoD51qGDWqNxjoH-hdSJ29wprvyxyk_yX6dp-cxXUj5DIgXYQuIZF71rdiPtGlAiyTBns8rS2QlEEXapZVlvYrK4mkpUXVDA7ifD8q6gAC2BStqHeys7CGp2MbV4ZwKCVbAUbMs6Tboh8rADZvQhuTEq7qlhZ-w'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6OTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.fX2Gbd7fDPNE3Lw-xbum_5CVqQYqEmMhv_v5u8A-U81pmPD2P5rsJEJx66ns1taFLVaE3j9_OzotxrqjqqQqbACkagGcN5wvA3_ZIxyqmhrKYFJc53ZcO7d0pFWiQlluNBI_pnFNDlSMB2Ut8Th5aiPy2uamBM9wC99bcjo7HkHvTKBf6ljU6rPKoD51qGDWqNxjoH-hdSJ29wprvyxyk_yX6dp-cxXUj5DIgXYQuIZF71rdiPtGlAiyTBns8rS2QlEEXapZVlvYrK4mkpUXVDA7ifD8q6gAC2BStqHeys7CGp2MbV4ZwKCVbAUbMs6Tboh8rADZvQhuTEq7qlhZ-w';
await expect(service.getVerifiedIdToken(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getVerifiedIdToken(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E000103'), HttpStatus.UNAUTHORIZED), new HttpException(makeErrorResponse('E000103'), HttpStatus.UNAUTHORIZED),
); );
}); });
@ -80,7 +86,8 @@ describe('AuthService', () => {
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdXNlciIsInN1YiI6InN1YiIsImF1ZCI6ImF1ZCIsIm5vbmNlIjoiZGVmYXVsdE5vbmNlIiwiaWF0IjoxMDAwMDAwMDAwLCJhdXRoX3RpbWUiOjEwMDAwMDAwMDAsImVtYWlscyI6WyJ4eHhAeHguY29tIl0sInRmcCI6InNpZ25pbl91c2VyZmxvdyJ9.sign'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdXNlciIsInN1YiI6InN1YiIsImF1ZCI6ImF1ZCIsIm5vbmNlIjoiZGVmYXVsdE5vbmNlIiwiaWF0IjoxMDAwMDAwMDAwLCJhdXRoX3RpbWUiOjEwMDAwMDAwMDAsImVtYWlscyI6WyJ4eHhAeHguY29tIl0sInRmcCI6InNpZ25pbl91c2VyZmxvdyJ9.sign';
await expect(service.getVerifiedIdToken(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getVerifiedIdToken(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E000104'), HttpStatus.UNAUTHORIZED), new HttpException(makeErrorResponse('E000104'), HttpStatus.UNAUTHORIZED),
); );
}); });
@ -94,7 +101,8 @@ describe('AuthService', () => {
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaW52bGlkX2lzc3VlciIsInN1YiI6InN1YiIsImF1ZCI6ImF1ZCIsIm5vbmNlIjoiZGVmYXVsdE5vbmNlIiwiaWF0IjoxMDAwMDAwMDAwLCJhdXRoX3RpbWUiOjEwMDAwMDAwMDAsImVtYWlscyI6WyJ4eHhAeHguY29tIl0sInRmcCI6InNpZ25pbl91c2VyZmxvdyJ9.0bp3e1mDG78PX3lo8zgOLXGenIqG_Vi6kw7CbwauAQM-cnUZ_aVCoJ_dAv_QmPElOQKcCkRrAvAZ91FwuHDlBGuuDqx8OwqN0VaD-4NPouoAswj-9HNvBm8gUn-pGaXkvWt_72UdCJavZJjDj_RHur8y8kFt5Qeab3mUP2x-uNcV2Q2x3M_IIfcRiIZkRZm_azKfiVIy7tzoUFLDss97y938aR8imMVxazoSQvj7RWIWylgeRr9yVt7qYl18cnEVL0IGtslFbqhfNsiEmRCMsttm5kXs7E9B0bhhUe_xbJW9VumQ6G7dgMrswevp_jRgbpWJoZsgErtqIRl9Tc9ikA'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaW52bGlkX2lzc3VlciIsInN1YiI6InN1YiIsImF1ZCI6ImF1ZCIsIm5vbmNlIjoiZGVmYXVsdE5vbmNlIiwiaWF0IjoxMDAwMDAwMDAwLCJhdXRoX3RpbWUiOjEwMDAwMDAwMDAsImVtYWlscyI6WyJ4eHhAeHguY29tIl0sInRmcCI6InNpZ25pbl91c2VyZmxvdyJ9.0bp3e1mDG78PX3lo8zgOLXGenIqG_Vi6kw7CbwauAQM-cnUZ_aVCoJ_dAv_QmPElOQKcCkRrAvAZ91FwuHDlBGuuDqx8OwqN0VaD-4NPouoAswj-9HNvBm8gUn-pGaXkvWt_72UdCJavZJjDj_RHur8y8kFt5Qeab3mUP2x-uNcV2Q2x3M_IIfcRiIZkRZm_azKfiVIy7tzoUFLDss97y938aR8imMVxazoSQvj7RWIWylgeRr9yVt7qYl18cnEVL0IGtslFbqhfNsiEmRCMsttm5kXs7E9B0bhhUe_xbJW9VumQ6G7dgMrswevp_jRgbpWJoZsgErtqIRl9Tc9ikA';
await expect(service.getVerifiedIdToken(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getVerifiedIdToken(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E000105'), HttpStatus.UNAUTHORIZED), new HttpException(makeErrorResponse('E000105'), HttpStatus.UNAUTHORIZED),
); );
}); });
@ -107,7 +115,8 @@ describe('AuthService', () => {
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.RyieW-VHsHPQOjXbbhRc307AYJOc1sq2hrcu4SW1-K0pvLlkplepxvx02a3vCwQrnBYrIP5w6HExG-S_JgW5nYyWr6DeY11mA484n9KA8GeAcAXV37StH1gfWUJvfGb4C8BaMbMM9Ix4Z9NGwKA9vjNwevfmBZnz9lQUePgv6BJNmyvCt8ElJ01O-1WODbZuojJ4xXymA1OqluzfbphPOsqWTSNmTn0emkLjjnlMQf1iwM4C_kvvr8dUCFg0_UGDfQVJnzPEKB38UqnhLnC5WacrddDwQ0kBuGKZgZ_63Q_7fOvqAZivqLK7BPmbPxi6mx3R1S9Eq2ugzpY1LfJOjA'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.RyieW-VHsHPQOjXbbhRc307AYJOc1sq2hrcu4SW1-K0pvLlkplepxvx02a3vCwQrnBYrIP5w6HExG-S_JgW5nYyWr6DeY11mA484n9KA8GeAcAXV37StH1gfWUJvfGb4C8BaMbMM9Ix4Z9NGwKA9vjNwevfmBZnz9lQUePgv6BJNmyvCt8ElJ01O-1WODbZuojJ4xXymA1OqluzfbphPOsqWTSNmTn0emkLjjnlMQf1iwM4C_kvvr8dUCFg0_UGDfQVJnzPEKB38UqnhLnC5WacrddDwQ0kBuGKZgZ_63Q_7fOvqAZivqLK7BPmbPxi6mx3R1S9Eq2ugzpY1LfJOjA';
await expect(service.getVerifiedIdToken(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getVerifiedIdToken(context, token)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -122,7 +131,8 @@ describe('AuthService', () => {
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.RyieW-VHsHPQOjXbbhRc307AYJOc1sq2hrcu4SW1-K0pvLlkplepxvx02a3vCwQrnBYrIP5w6HExG-S_JgW5nYyWr6DeY11mA484n9KA8GeAcAXV37StH1gfWUJvfGb4C8BaMbMM9Ix4Z9NGwKA9vjNwevfmBZnz9lQUePgv6BJNmyvCt8ElJ01O-1WODbZuojJ4xXymA1OqluzfbphPOsqWTSNmTn0emkLjjnlMQf1iwM4C_kvvr8dUCFg0_UGDfQVJnzPEKB38UqnhLnC5WacrddDwQ0kBuGKZgZ_63Q_7fOvqAZivqLK7BPmbPxi6mx3R1S9Eq2ugzpY1LfJOjA'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.RyieW-VHsHPQOjXbbhRc307AYJOc1sq2hrcu4SW1-K0pvLlkplepxvx02a3vCwQrnBYrIP5w6HExG-S_JgW5nYyWr6DeY11mA484n9KA8GeAcAXV37StH1gfWUJvfGb4C8BaMbMM9Ix4Z9NGwKA9vjNwevfmBZnz9lQUePgv6BJNmyvCt8ElJ01O-1WODbZuojJ4xXymA1OqluzfbphPOsqWTSNmTn0emkLjjnlMQf1iwM4C_kvvr8dUCFg0_UGDfQVJnzPEKB38UqnhLnC5WacrddDwQ0kBuGKZgZ_63Q_7fOvqAZivqLK7BPmbPxi6mx3R1S9Eq2ugzpY1LfJOjA';
await expect(service.getVerifiedIdToken(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getVerifiedIdToken(context, token)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -140,7 +150,8 @@ describe('AuthService', () => {
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.RyieW-VHsHPQOjXbbhRc307AYJOc1sq2hrcu4SW1-K0pvLlkplepxvx02a3vCwQrnBYrIP5w6HExG-S_JgW5nYyWr6DeY11mA484n9KA8GeAcAXV37StH1gfWUJvfGb4C8BaMbMM9Ix4Z9NGwKA9vjNwevfmBZnz9lQUePgv6BJNmyvCt8ElJ01O-1WODbZuojJ4xXymA1OqluzfbphPOsqWTSNmTn0emkLjjnlMQf1iwM4C_kvvr8dUCFg0_UGDfQVJnzPEKB38UqnhLnC5WacrddDwQ0kBuGKZgZ_63Q_7fOvqAZivqLK7BPmbPxi6mx3R1S9Eq2ugzpY1LfJOjA'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtpZCJ9.eyJleHAiOjkwMDAwMDAwMDAsIm5iZiI6MTAwMDAwMDAwMCwidmVyIjoiMS4wIiwiaXNzIjoiaXNzdWVyIiwic3ViIjoic3ViIiwiYXVkIjoiYXVkIiwibm9uY2UiOiJkZWZhdWx0Tm9uY2UiLCJpYXQiOjEwMDAwMDAwMDAsImF1dGhfdGltZSI6MTAwMDAwMDAwMCwiZW1haWxzIjpbInh4eEB4eC5jb20iXSwidGZwIjoic2lnbmluX3VzZXJmbG93In0.RyieW-VHsHPQOjXbbhRc307AYJOc1sq2hrcu4SW1-K0pvLlkplepxvx02a3vCwQrnBYrIP5w6HExG-S_JgW5nYyWr6DeY11mA484n9KA8GeAcAXV37StH1gfWUJvfGb4C8BaMbMM9Ix4Z9NGwKA9vjNwevfmBZnz9lQUePgv6BJNmyvCt8ElJ01O-1WODbZuojJ4xXymA1OqluzfbphPOsqWTSNmTn0emkLjjnlMQf1iwM4C_kvvr8dUCFg0_UGDfQVJnzPEKB38UqnhLnC5WacrddDwQ0kBuGKZgZ_63Q_7fOvqAZivqLK7BPmbPxi6mx3R1S9Eq2ugzpY1LfJOjA';
await expect(service.getVerifiedIdToken(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.getVerifiedIdToken(context, token)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,

View File

@ -55,21 +55,25 @@ export class AuthService {
* @param idToken AzureAD B2Cにより発行されたIDトークン * @param idToken AzureAD B2Cにより発行されたIDトークン
* @returns verified user * @returns verified user
*/ */
async isVerifiedUser(idToken: IDToken): Promise<boolean> { async isVerifiedUser(context: Context, idToken: IDToken): Promise<boolean> {
this.logger.log(`[IN] ${this.isVerifiedUser.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.isVerifiedUser.name}`,
);
try { try {
// IDトークンのユーザーがDBに登録されていてメール認証が完了しているユーザーか検証 // IDトークンのユーザーがDBに登録されていてメール認証が完了しているユーザーか検証
const user = await this.usersRepository.findVerifiedUser(idToken.sub); const user = await this.usersRepository.findVerifiedUser(idToken.sub);
return user !== undefined; return user !== undefined;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.isVerifiedUser.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.isVerifiedUser.name}`,
);
} }
} }
@ -85,7 +89,9 @@ export class AuthService {
type: string, type: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.generateRefreshToken.name}`, `[IN] [${context.getTrackingId()}] ${
this.generateRefreshToken.name
} | params: { type: ${type} };`,
); );
// ユーザー情報とユーザーが属しているアカウント情報を取得 // ユーザー情報とユーザーが属しているアカウント情報を取得
@ -133,7 +139,7 @@ export class AuthService {
return token; return token;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TierUnexpectedError: case TierUnexpectedError:
@ -156,7 +162,7 @@ export class AuthService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.generateRefreshToken.name}`, `[OUT] [${context.getTrackingId()}] ${this.generateRefreshToken.name}`,
); );
} }
} }
@ -171,7 +177,7 @@ export class AuthService {
refreshToken: string, refreshToken: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.generateAccessToken.name}`, `[IN] [${context.getTrackingId()}] ${this.generateAccessToken.name}`,
); );
const privateKey = getPrivateKey(this.configService); const privateKey = getPrivateKey(this.configService);
@ -179,9 +185,11 @@ export class AuthService {
const token = verify<RefreshToken>(refreshToken, pubkey); const token = verify<RefreshToken>(refreshToken, pubkey);
if (isVerifyError(token)) { if (isVerifyError(token)) {
this.logger.error(`${token.reason} | ${token.message}`); this.logger.error(
`[${context.getTrackingId()}] ${token.reason} | ${token.message}`,
);
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.generateAccessToken.name}`, `[OUT] [${context.getTrackingId()}] ${this.generateAccessToken.name}`,
); );
throw new HttpException( throw new HttpException(
makeErrorResponse('E000101'), makeErrorResponse('E000101'),
@ -200,7 +208,7 @@ export class AuthService {
); );
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.generateAccessToken.name}`, `[OUT] [${context.getTrackingId()}] ${this.generateAccessToken.name}`,
); );
return accessToken; return accessToken;
} }
@ -218,7 +226,9 @@ export class AuthService {
originAccountId: number, originAccountId: number,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.generateDelegationRefreshToken.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.generateDelegationRefreshToken.name
} | params: { ` +
`delegateUserExternalId: ${delegateUserExternalId}, ` + `delegateUserExternalId: ${delegateUserExternalId}, ` +
`originAccountId: ${originAccountId}, };`, `originAccountId: ${originAccountId}, };`,
); );
@ -255,7 +265,7 @@ export class AuthService {
return token; return token;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case AccountNotFoundError: case AccountNotFoundError:
@ -284,7 +294,9 @@ export class AuthService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.generateDelegationRefreshToken.name}`, `[OUT] [${context.getTrackingId()}] ${
this.generateDelegationRefreshToken.name
}`,
); );
} }
} }
@ -300,7 +312,9 @@ export class AuthService {
refreshToken: string, refreshToken: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.generateDelegationAccessToken.name}`, `[IN] [${context.getTrackingId()}] ${
this.generateDelegationAccessToken.name
}`,
); );
const privateKey = getPrivateKey(this.configService); const privateKey = getPrivateKey(this.configService);
@ -308,9 +322,13 @@ export class AuthService {
const token = verify<RefreshToken>(refreshToken, pubkey); const token = verify<RefreshToken>(refreshToken, pubkey);
if (isVerifyError(token)) { if (isVerifyError(token)) {
this.logger.error(`${token.reason} | ${token.message}`); this.logger.error(
`[${context.getTrackingId()}] ${token.reason} | ${token.message}`,
);
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.generateDelegationAccessToken.name}`, `[OUT] [${context.getTrackingId()}] ${
this.generateDelegationAccessToken.name
}`,
); );
throw new HttpException( throw new HttpException(
makeErrorResponse('E000101'), makeErrorResponse('E000101'),
@ -330,7 +348,9 @@ export class AuthService {
); );
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.generateDelegationAccessToken.name}`, `[OUT] [${context.getTrackingId()}] ${
this.generateDelegationAccessToken.name
}`,
); );
return accessToken; return accessToken;
} }
@ -350,7 +370,9 @@ export class AuthService {
refreshToken: string, refreshToken: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateDelegationAccessToken.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.updateDelegationAccessToken.name
} | params: { ` +
`delegateUserExternalId: ${delegateUserExternalId}, ` + `delegateUserExternalId: ${delegateUserExternalId}, ` +
`originUserExternalId: ${originUserExternalId}, };`, `originUserExternalId: ${originUserExternalId}, };`,
); );
@ -407,7 +429,7 @@ export class AuthService {
return accessToken; return accessToken;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof HttpException) { if (e instanceof HttpException) {
throw e; throw e;
} }
@ -440,7 +462,9 @@ export class AuthService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.updateDelegationAccessToken.name}`, `[OUT] [${context.getTrackingId()}] ${
this.updateDelegationAccessToken.name
}`,
); );
} }
} }
@ -450,8 +474,10 @@ export class AuthService {
* @param token * @param token
* @returns id token * @returns id token
*/ */
async getVerifiedIdToken(token: string): Promise<IDToken> { async getVerifiedIdToken(context: Context, token: string): Promise<IDToken> {
this.logger.log(`[IN] ${this.getVerifiedIdToken.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.getVerifiedIdToken.name}`,
);
let kid: string | undefined = ''; let kid: string | undefined = '';
try { try {
@ -462,7 +488,7 @@ export class AuthService {
throw new Error('kid not found'); throw new Error('kid not found');
} }
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E000101'), makeErrorResponse('E000101'),
HttpStatus.UNAUTHORIZED, HttpStatus.UNAUTHORIZED,
@ -471,8 +497,8 @@ export class AuthService {
let issuer = ''; let issuer = '';
try { try {
const metadata = await this.adB2cService.getMetaData(); const metadata = await this.adB2cService.getMetaData(context);
const keySets = await this.adB2cService.getSignKeySets(); const keySets = await this.adB2cService.getSignKeySets(context);
issuer = metadata.issuer; issuer = metadata.issuer;
@ -482,7 +508,7 @@ export class AuthService {
throw new Error('Public Key Not Found.'); throw new Error('Public Key Not Found.');
} }
const publicKey = this.getPublicKeyFromJwk(jwkKey); const publicKey = this.getPublicKeyFromJwk(context, jwkKey);
const verifiedToken = jwt.verify(token, publicKey, { const verifiedToken = jwt.verify(token, publicKey, {
algorithms: ['RS256'], algorithms: ['RS256'],
@ -496,7 +522,9 @@ export class AuthService {
} catch (e) { } catch (e) {
if (e instanceof Error) { if (e instanceof Error) {
const { name, message } = e; const { name, message } = e;
this.logger.error(`error=${name}: ${message}`); this.logger.error(
`[${context.getTrackingId()}] error=${name}: ${message}`,
);
switch (e.constructor) { switch (e.constructor) {
case jwt.TokenExpiredError: case jwt.TokenExpiredError:
@ -519,18 +547,20 @@ export class AuthService {
break; break;
} }
} else { } else {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
} }
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.getVerifiedIdToken.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getVerifiedIdToken.name}`,
);
} }
} }
getPublicKeyFromJwk(jwkKey: JwkSignKey): string { getPublicKeyFromJwk(context: Context, jwkKey: JwkSignKey): string {
try { try {
// JWK形式のJSONなのでJWTの公開鍵として使えるようにPEM形式に変換 // JWK形式のJSONなのでJWTの公開鍵として使えるようにPEM形式に変換
const publicKey = jwkToPem({ const publicKey = jwkToPem({
@ -541,10 +571,12 @@ export class AuthService {
return publicKey; return publicKey;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] ${this.getPublicKeyFromJwk.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getPublicKeyFromJwk.name}`,
);
} }
} }
@ -613,8 +645,9 @@ export class AuthService {
idToken: IDToken, idToken: IDToken,
): Promise<boolean> { ): Promise<boolean> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.isAcceptedLatestVersion.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
`idToken.sub: ${idToken.sub}, };`, this.isAcceptedLatestVersion.name
} | params: { ` + `idToken.sub: ${idToken.sub}, };`,
); );
try { try {
@ -646,14 +679,16 @@ export class AuthService {
return eulaAccepted && dpaAccepted; return eulaAccepted && dpaAccepted;
} }
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.isAcceptedLatestVersion.name}`, `[OUT] [${context.getTrackingId()}] ${
this.isAcceptedLatestVersion.name
}`,
); );
} }
} }

View File

@ -4,6 +4,7 @@ import { JwkSignKey, B2cMetadata } from '../../../common/token';
import { AuthService } from '../auth.service'; import { AuthService } from '../auth.service';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import { UsersRepositoryService } from '../../../repositories/users/users.repository.service'; import { UsersRepositoryService } from '../../../repositories/users/users.repository.service';
import { Context } from '../../../common/log';
export type AdB2cMockValue = { export type AdB2cMockValue = {
getMetaData: B2cMetadata | Error; getMetaData: B2cMetadata | Error;
@ -71,7 +72,10 @@ export const makeAdB2cServiceMock = (value: AdB2cMockValue) => {
}; };
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
export const makeDefaultGetPublicKeyFromJwk = (jwkKey: JwkSignKey): string => { export const makeDefaultGetPublicKeyFromJwk = (
context: Context,
jwkKey: JwkSignKey,
): string => {
return [ return [
'-----BEGIN PUBLIC KEY-----', '-----BEGIN PUBLIC KEY-----',
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5IZZNgDew9eGmuFTezwd', 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5IZZNgDew9eGmuFTezwd',

View File

@ -87,7 +87,10 @@ export class FilesService {
isEncrypted: boolean, isEncrypted: boolean,
): Promise<AudioUploadFinishedResponse> { ): Promise<AudioUploadFinishedResponse> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.uploadFinished.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.uploadFinished.name
} | params: { ` +
`userId: ${userId}, ` +
`url: ${url}, ` + `url: ${url}, ` +
`authorId: ${authorId}, ` + `authorId: ${authorId}, ` +
`fileName: ${fileName}, ` + `fileName: ${fileName}, ` +
@ -120,21 +123,21 @@ export class FilesService {
) { ) {
if (isInvalidCreatedDate) { if (isInvalidCreatedDate) {
this.logger.error( this.logger.error(
`param createdDate is invalid format:[createdDate=${createdDate}]`, `[${context.getTrackingId()}] param createdDate is invalid format:[createdDate=${createdDate}]`,
); );
} }
if (isInvalidFinishedDate) { if (isInvalidFinishedDate) {
this.logger.error( this.logger.error(
`param finishedDate is invalid format:[finishedDate=${finishedDate}]`, `[${context.getTrackingId()}] param finishedDate is invalid format:[finishedDate=${finishedDate}]`,
); );
} }
if (isInvalidUploadedDate) { if (isInvalidUploadedDate) {
this.logger.error( this.logger.error(
`param uploadedDate is invalid format:[uploadedDate=${uploadedDate}]`, `[${context.getTrackingId()}] param uploadedDate is invalid format:[uploadedDate=${uploadedDate}]`,
); );
} }
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.uploadFinished.name}`, `[OUT] [${context.getTrackingId()}] ${this.uploadFinished.name}`,
); );
throw new HttpException( throw new HttpException(
@ -146,10 +149,12 @@ export class FilesService {
// オプションアイテムが10個ない場合はパラメータ不正 // オプションアイテムが10個ない場合はパラメータ不正
if (optionItemList.length !== OPTION_ITEM_NUM) { if (optionItemList.length !== OPTION_ITEM_NUM) {
this.logger.error( this.logger.error(
`param optionItemList expects ${OPTION_ITEM_NUM} items, but has ${optionItemList.length} items`, `[${context.getTrackingId()}] param optionItemList expects ${OPTION_ITEM_NUM} items, but has ${
optionItemList.length
} items`,
); );
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.uploadFinished.name}`, `[OUT] [${context.getTrackingId()}] ${this.uploadFinished.name}`,
); );
throw new HttpException( throw new HttpException(
makeErrorResponse('E010001'), makeErrorResponse('E010001'),
@ -162,9 +167,9 @@ export class FilesService {
// ユーザー取得 // ユーザー取得
user = await this.usersRepository.findUserByExternalId(userId); user = await this.usersRepository.findUserByExternalId(userId);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.uploadFinished.name}`, `[OUT] [${context.getTrackingId()}] ${this.uploadFinished.name}`,
); );
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -177,7 +182,9 @@ export class FilesService {
const urlObj = new URL(url); const urlObj = new URL(url);
urlObj.search = ''; urlObj.search = '';
const fileUrl = urlObj.toString(); const fileUrl = urlObj.toString();
this.logger.log(`Request URL: ${url}, Without param URL${fileUrl}`); this.logger.log(
`[${context.getTrackingId()}] Request URL: ${url}, Without param URL${fileUrl}`,
);
// 文字起こしタスク追加(音声ファイルとオプションアイテムも同時に追加) // 文字起こしタスク追加(音声ファイルとオプションアイテムも同時に追加)
// 追加時に末尾のJOBナンバーにインクリメントする // 追加時に末尾のJOBナンバーにインクリメントする
@ -200,7 +207,7 @@ export class FilesService {
optionItemList, optionItemList,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -227,13 +234,13 @@ export class FilesService {
// 割り当てられたユーザーがいない場合は通知不要 // 割り当てられたユーザーがいない場合は通知不要
if (distinctUserIds.length === 0) { if (distinctUserIds.length === 0) {
this.logger.log('No user assigned.'); this.logger.log(`[${context.getTrackingId()}] No user assigned.`);
return { jobNumber: task.job_number }; return { jobNumber: task.job_number };
} }
// タグを生成 // タグを生成
const tags = distinctUserIds.map((x) => `user_${x}`); const tags = distinctUserIds.map((x) => `user_${x}`);
this.logger.log(`tags: ${tags}`); this.logger.log(`[${context.getTrackingId()}] tags: ${tags}`);
// タグ対象に通知送信 // タグ対象に通知送信
await this.notificationhubService.notify(context, tags, { await this.notificationhubService.notify(context, tags, {
@ -247,12 +254,14 @@ export class FilesService {
return { jobNumber: task.job_number }; return { jobNumber: task.job_number };
} catch (error) { } catch (error) {
// 処理の本筋はタスク生成のため自動ルーティングに失敗してもエラーにしない // 処理の本筋はタスク生成のため自動ルーティングに失敗してもエラーにしない
this.logger.error(`Automatic routing or notification failed.`); this.logger.error(
this.logger.error(`error=${error}`); `[${context.getTrackingId()}] Automatic routing or notification failed.`,
);
this.logger.error(`[${context.getTrackingId()}] error=${error}`);
return { jobNumber: task.job_number }; return { jobNumber: task.job_number };
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.uploadFinished.name}`, `[OUT] [${context.getTrackingId()}] ${this.uploadFinished.name}`,
); );
} }
} }
@ -267,7 +276,9 @@ export class FilesService {
externalId: string, externalId: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.publishUploadSas.name} | params: { externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.publishUploadSas.name
} | params: { externalId: ${externalId} };`,
); );
//DBから国情報とアカウントIDを取得する //DBから国情報とアカウントIDを取得する
@ -286,6 +297,7 @@ export class FilesService {
} }
// ライセンスの有効性をチェック // ライセンスの有効性をチェック
const { licenseError } = await this.checkLicenseValidityByUserId( const { licenseError } = await this.checkLicenseValidityByUserId(
context,
user.id, user.id,
); );
if (licenseError) { if (licenseError) {
@ -307,7 +319,7 @@ export class FilesService {
); );
return url; return url;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case AccountLockedError: case AccountLockedError:
throw new HttpException( throw new HttpException(
@ -332,7 +344,7 @@ export class FilesService {
} }
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishUploadSas.name}`, `[OUT] [${context.getTrackingId()}] ${this.publishUploadSas.name}`,
); );
} }
} }
@ -349,7 +361,9 @@ export class FilesService {
audioFileId: number, audioFileId: number,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.publishAudioFileDownloadSas.name} | params: { externalId: ${externalId}, audioFileId: ${audioFileId} };`, `[IN] [${context.getTrackingId()}] ${
this.publishAudioFileDownloadSas.name
} | params: { externalId: ${externalId}, audioFileId: ${audioFileId} };`,
); );
//DBから国情報とアカウントID,ユーザーIDを取得する //DBから国情報とアカウントID,ユーザーIDを取得する
@ -367,6 +381,7 @@ export class FilesService {
if (user.account.tier === TIERS.TIER5) { if (user.account.tier === TIERS.TIER5) {
// ライセンスの有効性をチェック // ライセンスの有効性をチェック
const { licenseError } = await this.checkLicenseValidityByUserId( const { licenseError } = await this.checkLicenseValidityByUserId(
context,
user.id, user.id,
); );
if (licenseError) { if (licenseError) {
@ -379,9 +394,11 @@ export class FilesService {
isTypist = user.role === USER_ROLES.TYPIST; isTypist = user.role === USER_ROLES.TYPIST;
authorId = user.author_id ?? undefined; authorId = user.author_id ?? undefined;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishAudioFileDownloadSas.name}`, `[OUT] [${context.getTrackingId()}] ${
this.publishAudioFileDownloadSas.name
}`,
); );
switch (e.constructor) { switch (e.constructor) {
case LicenseExpiredError: case LicenseExpiredError:
@ -446,7 +463,7 @@ export class FilesService {
); );
if (!isFileExist) { if (!isFileExist) {
this.logger.log(`filePath:${filePath}`); this.logger.log(`[${context.getTrackingId()}] filePath:${filePath}`);
throw new AudioFileNotFoundError( throw new AudioFileNotFoundError(
`Audio file is not exists in blob storage. audio_file_id:${audioFileId}, url:${file.url}, fileName:${file.file_name}`, `Audio file is not exists in blob storage. audio_file_id:${audioFileId}, url:${file.url}, fileName:${file.file_name}`,
); );
@ -461,7 +478,7 @@ export class FilesService {
); );
return url; return url;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TasksNotFoundError: case TasksNotFoundError:
@ -491,7 +508,9 @@ export class FilesService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishAudioFileDownloadSas.name}`, `[OUT] [${context.getTrackingId()}] ${
this.publishAudioFileDownloadSas.name
}`,
); );
} }
} }
@ -508,7 +527,9 @@ export class FilesService {
audioFileId: number, audioFileId: number,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.publishTemplateFileDownloadSas.name} | params: { externalId: ${externalId}, audioFileId: ${audioFileId} };`, `[IN] [${context.getTrackingId()}] ${
this.publishTemplateFileDownloadSas.name
} | params: { externalId: ${externalId}, audioFileId: ${audioFileId} };`,
); );
//DBから国情報とアカウントID,ユーザーIDを取得する //DBから国情報とアカウントID,ユーザーIDを取得する
@ -526,6 +547,7 @@ export class FilesService {
if (user.account.tier === TIERS.TIER5) { if (user.account.tier === TIERS.TIER5) {
// ライセンスの有効性をチェック // ライセンスの有効性をチェック
const { licenseError } = await this.checkLicenseValidityByUserId( const { licenseError } = await this.checkLicenseValidityByUserId(
context,
user.id, user.id,
); );
if (licenseError) { if (licenseError) {
@ -538,9 +560,11 @@ export class FilesService {
isTypist = user.role === USER_ROLES.TYPIST; isTypist = user.role === USER_ROLES.TYPIST;
authorId = user.author_id ?? undefined; authorId = user.author_id ?? undefined;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishTemplateFileDownloadSas.name}`, `[OUT] [${context.getTrackingId()}] ${
this.publishTemplateFileDownloadSas.name
}`,
); );
switch (e.constructor) { switch (e.constructor) {
case LicenseExpiredError: case LicenseExpiredError:
@ -629,7 +653,7 @@ export class FilesService {
); );
return url; return url;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TasksNotFoundError: case TasksNotFoundError:
@ -661,7 +685,9 @@ export class FilesService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishTemplateFileDownloadSas.name}`, `[OUT] [${context.getTrackingId()}] ${
this.publishTemplateFileDownloadSas.name
}`,
); );
} }
} }
@ -677,7 +703,9 @@ export class FilesService {
externalId: string, externalId: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.publishTemplateFileUploadSas.name} | params: { externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.publishTemplateFileUploadSas.name
} | params: { externalId: ${externalId} };`,
); );
try { try {
const { account } = await this.usersRepository.findUserByExternalId( const { account } = await this.usersRepository.findUserByExternalId(
@ -706,14 +734,16 @@ export class FilesService {
return url; return url;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishTemplateFileUploadSas.name}`, `[OUT] [${context.getTrackingId()}] ${
this.publishTemplateFileUploadSas.name
}`,
); );
} }
} }
@ -733,7 +763,9 @@ export class FilesService {
fileName: string, fileName: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.templateUploadFinished.name} | params: { externalId: ${externalId}, url: ${url}, fileName: ${fileName} };`, `[IN] [${context.getTrackingId()}] ${
this.templateUploadFinished.name
} | params: { externalId: ${externalId}, url: ${url}, fileName: ${fileName} };`,
); );
try { try {
@ -745,7 +777,9 @@ export class FilesService {
const urlObj = new URL(url); const urlObj = new URL(url);
urlObj.search = ''; urlObj.search = '';
const fileUrl = urlObj.toString(); const fileUrl = urlObj.toString();
this.logger.log(`Request URL: ${url}, Without param URL${fileUrl}`); this.logger.log(
`[${context.getTrackingId()}] Request URL: ${url}, Without param URL${fileUrl}`,
);
// テンプレートファイル情報をDBに登録 // テンプレートファイル情報をDBに登録
await this.templateFilesRepository.upsertTemplateFile( await this.templateFilesRepository.upsertTemplateFile(
@ -754,14 +788,16 @@ export class FilesService {
fileUrl, fileUrl,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.templateUploadFinished.name}`, `[OUT] [${context.getTrackingId()}] ${
this.templateUploadFinished.name
}`,
); );
} }
} }
@ -774,8 +810,14 @@ export class FilesService {
*/ */
// TODO: TASK3084で共通部品化する // TODO: TASK3084で共通部品化する
private async checkLicenseValidityByUserId( private async checkLicenseValidityByUserId(
context: Context,
userId: number, userId: number,
): Promise<{ licenseError?: Error }> { ): Promise<{ licenseError?: Error }> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.checkLicenseValidityByUserId.name
} | params: { userId: ${userId} };`,
);
try { try {
const allocatedLicense = await this.usersRepository.findLicenseByUserId( const allocatedLicense = await this.usersRepository.findLicenseByUserId(
userId, userId,

View File

@ -91,9 +91,11 @@ export class LicensesController {
); );
} }
const { userId } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId);
// ライセンス注文処理 // ライセンス注文処理
await this.licensesService.licenseOrders( await this.licensesService.licenseOrders(
context,
userId, userId,
body.poNumber, body.poNumber,
body.orderCount, body.orderCount,
@ -142,8 +144,10 @@ export class LicensesController {
); );
} }
const { userId } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId);
const cardLicenseKeys = await this.licensesService.issueCardLicenseKeys( const cardLicenseKeys = await this.licensesService.issueCardLicenseKeys(
context,
userId, userId,
body.createCount, body.createCount,
); );
@ -202,8 +206,10 @@ export class LicensesController {
); );
} }
const { userId } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId);
await this.licensesService.activateCardLicenseKey( await this.licensesService.activateCardLicenseKey(
context,
userId, userId,
body.cardLicenseKey, body.cardLicenseKey,
); );

View File

@ -59,8 +59,14 @@ describe('LicensesService', () => {
const userId = '0001'; const userId = '0001';
body.orderCount = 1000; body.orderCount = 1000;
body.poNumber = '1'; body.poNumber = '1';
const context = makeContext(`uuidv4`);
expect( expect(
await service.licenseOrders(userId, body.poNumber, body.orderCount), await service.licenseOrders(
context,
userId,
body.poNumber,
body.orderCount,
),
).toEqual(undefined); ).toEqual(undefined);
}); });
it('ユーザID取得できなかった場合、エラーとなる', async () => { it('ユーザID取得できなかった場合、エラーとなる', async () => {
@ -81,8 +87,9 @@ describe('LicensesService', () => {
const userId = ''; const userId = '';
body.orderCount = 1000; body.orderCount = 1000;
body.poNumber = '1'; body.poNumber = '1';
const context = makeContext(`uuidv4`);
await expect( await expect(
service.licenseOrders(userId, body.poNumber, body.orderCount), service.licenseOrders(context, userId, body.poNumber, body.orderCount),
).rejects.toEqual( ).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -108,8 +115,9 @@ describe('LicensesService', () => {
const userId = '0001'; const userId = '0001';
body.orderCount = 1000; body.orderCount = 1000;
body.poNumber = '1'; body.poNumber = '1';
const context = makeContext(`uuidv4`);
await expect( await expect(
service.licenseOrders(userId, body.poNumber, body.orderCount), service.licenseOrders(context, userId, body.poNumber, body.orderCount),
).rejects.toEqual( ).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -133,8 +141,9 @@ describe('LicensesService', () => {
const userId = '0001'; const userId = '0001';
body.orderCount = 1000; body.orderCount = 1000;
body.poNumber = '1'; body.poNumber = '1';
const context = makeContext(`uuidv4`);
await expect( await expect(
service.licenseOrders(userId, body.poNumber, body.orderCount), service.licenseOrders(context, userId, body.poNumber, body.orderCount),
).rejects.toEqual( ).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E010401'), makeErrorResponse('E010401'),
@ -170,8 +179,9 @@ describe('LicensesService', () => {
'AEJWRFFSWRQYQQJ6WVLV', 'AEJWRFFSWRQYQQJ6WVLV',
], ],
}; };
const context = makeContext(`uuidv4`);
expect( expect(
await service.issueCardLicenseKeys(userId, body.createCount), await service.issueCardLicenseKeys(context, userId, body.createCount),
).toEqual(issueCardLicensesResponse); ).toEqual(issueCardLicensesResponse);
}); });
it('カードライセンス発行に失敗した場合、エラーになる', async () => { it('カードライセンス発行に失敗した場合、エラーになる', async () => {
@ -189,8 +199,9 @@ describe('LicensesService', () => {
const body = new IssueCardLicensesRequest(); const body = new IssueCardLicensesRequest();
const userId = '0001'; const userId = '0001';
body.createCount = 1000; body.createCount = 1000;
const context = makeContext(`uuidv4`);
await expect( await expect(
service.issueCardLicenseKeys(userId, body.createCount), service.issueCardLicenseKeys(context, userId, body.createCount),
).rejects.toEqual( ).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -212,8 +223,13 @@ describe('LicensesService', () => {
const body = new ActivateCardLicensesRequest(); const body = new ActivateCardLicensesRequest();
const userId = '0001'; const userId = '0001';
body.cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY'; body.cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY';
const context = makeContext(`uuidv4`);
expect( expect(
await service.activateCardLicenseKey(userId, body.cardLicenseKey), await service.activateCardLicenseKey(
context,
userId,
body.cardLicenseKey,
),
).toEqual(undefined); ).toEqual(undefined);
}); });
it('カードライセンス取り込みに失敗した場合、エラーになるDBエラー', async () => { it('カードライセンス取り込みに失敗した場合、エラーになるDBエラー', async () => {
@ -231,8 +247,9 @@ describe('LicensesService', () => {
const body = new ActivateCardLicensesRequest(); const body = new ActivateCardLicensesRequest();
const userId = '0001'; const userId = '0001';
body.cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY'; body.cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY';
const context = makeContext(`uuidv4`);
await expect( await expect(
service.activateCardLicenseKey(userId, body.cardLicenseKey), service.activateCardLicenseKey(context, userId, body.cardLicenseKey),
).rejects.toEqual( ).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -256,8 +273,9 @@ describe('LicensesService', () => {
const body = new ActivateCardLicensesRequest(); const body = new ActivateCardLicensesRequest();
const userId = '0001'; const userId = '0001';
body.cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY'; body.cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY';
const context = makeContext(`uuidv4`);
await expect( await expect(
service.activateCardLicenseKey(userId, body.cardLicenseKey), service.activateCardLicenseKey(context, userId, body.cardLicenseKey),
).rejects.toEqual( ).rejects.toEqual(
new HttpException(makeErrorResponse('E010801'), HttpStatus.BAD_REQUEST), new HttpException(makeErrorResponse('E010801'), HttpStatus.BAD_REQUEST),
); );
@ -278,8 +296,9 @@ describe('LicensesService', () => {
const body = new ActivateCardLicensesRequest(); const body = new ActivateCardLicensesRequest();
const userId = '0001'; const userId = '0001';
body.cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY'; body.cardLicenseKey = 'WZCETXC0Z9PQZ9GKRGGY';
const context = makeContext(`uuidv4`);
await expect( await expect(
service.activateCardLicenseKey(userId, body.cardLicenseKey), service.activateCardLicenseKey(context, userId, body.cardLicenseKey),
).rejects.toEqual( ).rejects.toEqual(
new HttpException(makeErrorResponse('E010802'), HttpStatus.BAD_REQUEST), new HttpException(makeErrorResponse('E010802'), HttpStatus.BAD_REQUEST),
); );
@ -320,7 +339,8 @@ describe('DBテスト', () => {
const service = module.get<LicensesService>(LicensesService); const service = module.get<LicensesService>(LicensesService);
const issueCount = 500; const issueCount = 500;
await service.issueCardLicenseKeys(externalId, issueCount); const context = makeContext(`uuidv4`);
await service.issueCardLicenseKeys(context, externalId, issueCount);
const dbSelectResult = await selectCardLicensesCount(source); const dbSelectResult = await selectCardLicensesCount(source);
expect(dbSelectResult.count).toEqual(issueCount); expect(dbSelectResult.count).toEqual(issueCount);
}); });
@ -359,8 +379,9 @@ describe('DBテスト', () => {
await createCardLicenseIssue(source, issueId); await createCardLicenseIssue(source, issueId);
const service = module.get<LicensesService>(LicensesService); const service = module.get<LicensesService>(LicensesService);
const context = makeContext(`uuidv4`);
await service.activateCardLicenseKey(externalId, cardLicenseKey); await service.activateCardLicenseKey(context, externalId, cardLicenseKey);
const dbSelectResultFromCardLicense = await selectCardLicense( const dbSelectResultFromCardLicense = await selectCardLicense(
source, source,
cardLicenseKey, cardLicenseKey,

View File

@ -33,12 +33,17 @@ export class LicensesService {
* @param body * @param body
*/ */
async licenseOrders( async licenseOrders(
context: Context,
externalId: string, externalId: string,
poNumber: string, poNumber: string,
orderCount: number, orderCount: number,
): Promise<void> { ): Promise<void> {
//アクセストークンからユーザーIDを取得する //アクセストークンからユーザーIDを取得する
this.logger.log(`[IN] ${this.licenseOrders.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.licenseOrders.name
} | params: { externalId: ${externalId}, poNumber: ${poNumber}, orderCount: ${orderCount} };`,
);
let myAccountId: number; let myAccountId: number;
let parentAccountId: number | undefined; let parentAccountId: number | undefined;
@ -48,7 +53,7 @@ export class LicensesService {
await this.usersRepository.findUserByExternalId(externalId) await this.usersRepository.findUserByExternalId(externalId)
).account_id; ).account_id;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
throw new HttpException( throw new HttpException(
@ -73,7 +78,7 @@ export class LicensesService {
throw new Error('parent account id is undefined'); throw new Error('parent account id is undefined');
} }
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case AccountNotFoundError: case AccountNotFoundError:
throw new HttpException( throw new HttpException(
@ -111,9 +116,15 @@ export class LicensesService {
} }
} }
async issueCardLicenseKeys( async issueCardLicenseKeys(
context: Context,
externalId: string, externalId: string,
createCount: number, createCount: number,
): Promise<IssueCardLicensesResponse> { ): Promise<IssueCardLicensesResponse> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.issueCardLicenseKeys.name
} | params: { externalId: ${externalId}, createCount: ${createCount} };`,
);
const issueCardLicensesResponse = new IssueCardLicensesResponse(); const issueCardLicensesResponse = new IssueCardLicensesResponse();
let myAccountId: number; let myAccountId: number;
@ -123,7 +134,7 @@ export class LicensesService {
await this.usersRepository.findUserByExternalId(externalId) await this.usersRepository.findUserByExternalId(externalId)
).account_id; ).account_id;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
throw new HttpException( throw new HttpException(
@ -145,8 +156,10 @@ export class LicensesService {
issueCardLicensesResponse.cardLicenseKeys = licenseKeys; issueCardLicensesResponse.cardLicenseKeys = licenseKeys;
return issueCardLicensesResponse; return issueCardLicensesResponse;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('get cardlicensekeys failed'); this.logger.error(
`[${context.getTrackingId()}] get cardlicensekeys failed`,
);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -160,11 +173,14 @@ export class LicensesService {
* @param cardLicenseKey * @param cardLicenseKey
*/ */
async activateCardLicenseKey( async activateCardLicenseKey(
context: Context,
externalId: string, externalId: string,
cardLicenseKey: string, cardLicenseKey: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] ${this.activateCardLicenseKey.name}, argCardLicenseKey: ${cardLicenseKey}`, `[IN] [${context.getTrackingId()}] ${
this.activateCardLicenseKey.name
} | params: { externalId: ${externalId}, argCardLicenseKey: ${cardLicenseKey} };`,
); );
let myAccountId: number; let myAccountId: number;
@ -174,7 +190,7 @@ export class LicensesService {
await this.usersRepository.findUserByExternalId(externalId) await this.usersRepository.findUserByExternalId(externalId)
).account_id; ).account_id;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
throw new HttpException( throw new HttpException(
@ -196,8 +212,10 @@ export class LicensesService {
cardLicenseKey, cardLicenseKey,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('cardLicenseKey activate failed'); this.logger.error(
`[${context.getTrackingId()}] cardLicenseKey activate failed`,
);
switch (e.constructor) { switch (e.constructor) {
case LicenseNotExistError: case LicenseNotExistError:
@ -217,7 +235,9 @@ export class LicensesService {
); );
} }
} }
this.logger.log(`[OUT] ${this.activateCardLicenseKey.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.activateCardLicenseKey.name}`,
);
return; return;
} }
@ -232,8 +252,9 @@ export class LicensesService {
userId: string, userId: string,
): Promise<GetAllocatableLicensesResponse> { ): Promise<GetAllocatableLicensesResponse> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getAllocatableLicenses.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
`userId: ${userId}, `, this.getAllocatableLicenses.name
} | params: { ` + `userId: ${userId}, `,
); );
// ユーザIDからアカウントIDを取得する // ユーザIDからアカウントIDを取得する
try { try {
@ -248,15 +269,19 @@ export class LicensesService {
allocatableLicenses, allocatableLicenses,
}; };
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('get allocatable lisences failed'); this.logger.error(
`[${context.getTrackingId()}] get allocatable lisences failed`,
);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getAllocatableLicenses.name}`, `[OUT] [${context.getTrackingId()}] ${
this.getAllocatableLicenses.name
}`,
); );
} }
} }
@ -273,7 +298,9 @@ export class LicensesService {
poNumber: string, poNumber: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.cancelOrder.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.cancelOrder.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`poNumber: ${poNumber}, };`, `poNumber: ${poNumber}, };`,
); );
@ -287,7 +314,7 @@ export class LicensesService {
// 注文キャンセル処理 // 注文キャンセル処理
await this.licensesRepository.cancelOrder(myAccountId, poNumber); await this.licensesRepository.cancelOrder(myAccountId, poNumber);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
throw new HttpException( throw new HttpException(
@ -306,7 +333,9 @@ export class LicensesService {
); );
} }
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancelOrder.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.cancelOrder.name}`,
);
} }
return; return;
} }

View File

@ -26,7 +26,9 @@ export class NotificationService {
pnsHandler: string, pnsHandler: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.register.name} | params: { externalId: ${externalId}, pns: ${pns}, pnsHandler: ${pnsHandler} }`, `[IN] [${context.getTrackingId()}] ${
this.register.name
} | params: { externalId: ${externalId}, pns: ${pns}, pnsHandler: ${pnsHandler} }`,
); );
// ユーザIDからアカウントIDを取得する // ユーザIDからアカウントIDを取得する
@ -34,7 +36,7 @@ export class NotificationService {
try { try {
userId = (await this.usersRepository.findUserByExternalId(externalId)).id; userId = (await this.usersRepository.findUserByExternalId(externalId)).id;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
throw new HttpException( throw new HttpException(
@ -53,7 +55,7 @@ export class NotificationService {
// TODO: 登録毎に新規登録する想定でUUIDを付与している // TODO: 登録毎に新規登録する想定でUUIDを付与している
// もしデバイスごとに登録を上書きするようであればUUID部分にデバイス識別子を設定 // もしデバイスごとに登録を上書きするようであればUUID部分にデバイス識別子を設定
const installationId = `${pns}_${userId}_${uuidv4()}`; const installationId = `${pns}_${userId}_${uuidv4()}`;
this.logger.log(installationId); this.logger.log(`[${context.getTrackingId()}] ${installationId}`);
await this.notificationhubService.register( await this.notificationhubService.register(
context, context,
@ -63,13 +65,15 @@ export class NotificationService {
installationId, installationId,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.register.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.register.name}`,
);
} }
} }
} }

View File

@ -318,7 +318,7 @@ export class TasksController {
HttpStatus.UNAUTHORIZED, HttpStatus.UNAUTHORIZED,
); );
} }
const { userId, role } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId); const context = makeContext(userId);

View File

@ -57,7 +57,14 @@ export class TasksService {
direction?: SortDirection, direction?: SortDirection,
): Promise<{ tasks: Task[]; total: number }> { ): Promise<{ tasks: Task[]; total: number }> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getTasks.name} | params: { offset: ${offset}, limit: ${limit}, status: ${status}, paramName: ${paramName}, direction: ${direction} };`, `[IN] [${context.getTrackingId()}] ${this.getTasks.name} | params: { ` +
`userId: ${userId}, ` +
`roles: ${roles}, ` +
`offset: ${offset},` +
`limit: ${limit}, ` +
`status: ${status}, ` +
`paramName: ${paramName}, ` +
`direction: ${direction} };`,
); );
// パラメータが省略された場合のデフォルト値: 保存するソート条件の値の初期値と揃える // パラメータが省略された場合のデフォルト値: 保存するソート条件の値の初期値と揃える
@ -141,7 +148,7 @@ export class TasksService {
throw new Error(`invalid roles: ${roles.join(',')}`); throw new Error(`invalid roles: ${roles.join(',')}`);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
if (e.constructor === Adb2cTooManyRequestsError) { if (e.constructor === Adb2cTooManyRequestsError) {
throw new HttpException( throw new HttpException(
@ -155,7 +162,9 @@ export class TasksService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.getTasks.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getTasks.name}`,
);
} }
} }
@ -172,7 +181,9 @@ export class TasksService {
fileId: number, fileId: number,
): Promise<number | undefined> { ): Promise<number | undefined> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getNextTask.name} | params: { externalId: ${externalId}, fileId: ${fileId} };`, `[IN] [${context.getTrackingId()}] ${
this.getNextTask.name
} | params: { externalId: ${externalId}, fileId: ${fileId} };`,
); );
try { try {
@ -211,7 +222,7 @@ export class TasksService {
? undefined ? undefined
: nextTask.audio_file_id; : nextTask.audio_file_id;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TasksNotFoundError: case TasksNotFoundError:
@ -231,7 +242,9 @@ export class TasksService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.getNextTask.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getNextTask.name}`,
);
} }
} }
@ -250,7 +263,9 @@ export class TasksService {
): Promise<void> { ): Promise<void> {
try { try {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.checkout.name} | params: { audioFileId: ${audioFileId}, roles: ${roles}, externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.checkout.name
} | params: { audioFileId: ${audioFileId}, roles: ${roles}, externalId: ${externalId} };`,
); );
const { id, account_id, author_id } = const { id, account_id, author_id } =
@ -279,7 +294,7 @@ export class TasksService {
throw new InvalidRoleError(`invalid roles: ${roles.join(',')}`); throw new InvalidRoleError(`invalid roles: ${roles.join(',')}`);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case CheckoutPermissionNotFoundError: case CheckoutPermissionNotFoundError:
@ -313,7 +328,9 @@ export class TasksService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.checkout.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.checkout.name}`,
);
} }
} }
@ -330,7 +347,9 @@ export class TasksService {
): Promise<void> { ): Promise<void> {
try { try {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.checkin.name} | params: { audioFileId: ${audioFileId}, externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.checkin.name
} | params: { audioFileId: ${audioFileId}, externalId: ${externalId} };`,
); );
const { id } = await this.usersRepository.findUserByExternalId( const { id } = await this.usersRepository.findUserByExternalId(
externalId, externalId,
@ -342,7 +361,7 @@ export class TasksService {
TASK_STATUS.IN_PROGRESS, TASK_STATUS.IN_PROGRESS,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TasksNotFoundError: case TasksNotFoundError:
@ -368,7 +387,9 @@ export class TasksService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.checkin.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.checkin.name}`,
);
} }
} }
/** /**
@ -385,15 +406,17 @@ export class TasksService {
role: Roles[], role: Roles[],
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.cancel.name} | params: { audioFileId: ${audioFileId}, externalId: ${externalId}, role: ${role} };`, `[IN] [${context.getTrackingId()}] ${
this.cancel.name
} | params: { audioFileId: ${audioFileId}, externalId: ${externalId}, role: ${role} };`,
); );
let user: User; let user: User;
try { try {
// ユーザー取得 // ユーザー取得
user = await this.usersRepository.findUserByExternalId(externalId); user = await this.usersRepository.findUserByExternalId(externalId);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancel.name}`); this.logger.log(`[OUT] [${context.getTrackingId()}] ${this.cancel.name}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -409,7 +432,7 @@ export class TasksService {
role.includes(ADMIN_ROLES.ADMIN) ? undefined : user.id, role.includes(ADMIN_ROLES.ADMIN) ? undefined : user.id,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TasksNotFoundError: case TasksNotFoundError:
@ -455,10 +478,12 @@ export class TasksService {
); );
} catch (e) { } catch (e) {
// 処理の本筋はタスクキャンセルのため自動ルーティングに失敗してもエラーにしない // 処理の本筋はタスクキャンセルのため自動ルーティングに失敗してもエラーにしない
this.logger.error(`Automatic routing or notification failed.`); this.logger.error(
this.logger.error(`error=${e}`); `[${context.getTrackingId()}] Automatic routing or notification failed.`,
);
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.cancel.name}`); this.logger.log(`[OUT] [${context.getTrackingId()}] ${this.cancel.name}`);
} }
} }
@ -475,7 +500,9 @@ export class TasksService {
): Promise<void> { ): Promise<void> {
try { try {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.suspend.name} | params: { audioFileId: ${audioFileId}, externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.suspend.name
} | params: { audioFileId: ${audioFileId}, externalId: ${externalId} };`,
); );
const { id } = await this.usersRepository.findUserByExternalId( const { id } = await this.usersRepository.findUserByExternalId(
externalId, externalId,
@ -487,7 +514,7 @@ export class TasksService {
TASK_STATUS.IN_PROGRESS, TASK_STATUS.IN_PROGRESS,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TasksNotFoundError: case TasksNotFoundError:
@ -513,7 +540,9 @@ export class TasksService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.suspend.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.suspend.name}`,
);
} }
} }
@ -522,6 +551,11 @@ export class TasksService {
tasks: TaskEntity[], tasks: TaskEntity[],
permissions: CheckoutPermission[], permissions: CheckoutPermission[],
): Promise<AdB2cUser[]> { ): Promise<AdB2cUser[]> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getB2cUsers.name
} | params: { tasks: ${tasks}, permissions: ${permissions} };`,
);
// 割り当て候補の外部IDを列挙 // 割り当て候補の外部IDを列挙
const assigneesExternalIds = permissions.flatMap((permission) => const assigneesExternalIds = permissions.flatMap((permission) =>
permission.user ? [permission.user.external_id] : [], permission.user ? [permission.user.external_id] : [],
@ -554,7 +588,9 @@ export class TasksService {
): Promise<void> { ): Promise<void> {
try { try {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.changeCheckoutPermission.name} | params: { audioFileId: ${audioFileId}, assignees: ${assignees}, externalId: ${externalId}, role: ${role} };`, `[IN] [${context.getTrackingId()}] ${
this.changeCheckoutPermission.name
} | params: { audioFileId: ${audioFileId}, assignees: ${assignees}, externalId: ${externalId}, role: ${role} };`,
); );
const { author_id, account_id } = const { author_id, account_id } =
await this.usersRepository.findUserByExternalId(externalId); await this.usersRepository.findUserByExternalId(externalId);
@ -592,7 +628,7 @@ export class TasksService {
account_id, account_id,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case TypistUserNotFoundError: case TypistUserNotFoundError:
@ -619,7 +655,9 @@ export class TasksService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.changeCheckoutPermission.name}`, `[OUT] [${context.getTrackingId()}] ${
this.changeCheckoutPermission.name
}`,
); );
} }
} }
@ -632,6 +670,13 @@ export class TasksService {
audioFileId: number, audioFileId: number,
accountId: number, accountId: number,
): Promise<void> { ): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendNotify.name} | params: { ` +
`typistUserIds: ${typistUserIds}, ` +
`typistGroupIds: ${typistGroupIds}, ` +
`audioFileId: ${audioFileId}, ` +
`accountId: ${accountId} };`,
);
const groupMembers = const groupMembers =
await this.userGroupsRepositoryService.getGroupMembersFromGroupIds( await this.userGroupsRepositoryService.getGroupMembersFromGroupIds(
typistGroupIds, typistGroupIds,
@ -644,13 +689,13 @@ export class TasksService {
// 割り当てられたユーザーがいない場合は通知不要 // 割り当てられたユーザーがいない場合は通知不要
if (distinctUserIds.length === 0) { if (distinctUserIds.length === 0) {
this.logger.log('No user assigned.'); this.logger.log(`[${context.getTrackingId()}] No user assigned.`);
return; return;
} }
// タグを生成 // タグを生成
const tags = distinctUserIds.map((x) => `user_${x}`); const tags = distinctUserIds.map((x) => `user_${x}`);
this.logger.log(`tags: ${tags}`); this.logger.log(`[${context.getTrackingId()}] tags: ${tags}`);
// 通知内容に含む音声ファイル情報を取得 // 通知内容に含む音声ファイル情報を取得
const { file } = await this.taskRepository.getTaskAndAudioFile( const { file } = await this.taskRepository.getTaskAndAudioFile(

View File

@ -24,7 +24,9 @@ export class TemplatesService {
externalId: string, externalId: string,
): Promise<TemplateFile[]> { ): Promise<TemplateFile[]> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getTemplates.name} | params: { externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.getTemplates.name
} | params: { externalId: ${externalId} };`,
); );
try { try {
@ -42,14 +44,14 @@ export class TemplatesService {
return resTemplates; return resTemplates;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getTemplates.name}`, `[OUT] [${context.getTrackingId()}] ${this.getTemplates.name}`,
); );
} }
} }

View File

@ -3,8 +3,8 @@ import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { TermsService } from '../terms/terms.service'; import { TermsService } from '../terms/terms.service';
import { ErrorResponse } from '../../common/error/types/types'; import { ErrorResponse } from '../../common/error/types/types';
import { makeContext } from '../../common/log'; import { makeContext } from '../../common/log';
import { GetTermsInfoResponse } from './types/types';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { GetTermsInfoResponse, TermInfo } from './types/types';
@ApiTags('terms') @ApiTags('terms')
@Controller('terms') @Controller('terms')

View File

@ -15,7 +15,9 @@ export class TermsService {
* return termsInfo * return termsInfo
*/ */
async getTermsInfo(context: Context): Promise<TermInfo[]> { async getTermsInfo(context: Context): Promise<TermInfo[]> {
this.logger.log(`[IN] [${context.trackingId}] ${this.getTermsInfo.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.getTermsInfo.name}`,
);
try { try {
const { eulaVersion, dpaVersion } = const { eulaVersion, dpaVersion } =
await this.termsRepository.getLatestTermsInfo(); await this.termsRepository.getLatestTermsInfo();
@ -30,14 +32,14 @@ export class TermsService {
}, },
]; ];
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getTermsInfo.name}`, `[OUT] [${context.getTrackingId()}] ${this.getTermsInfo.name}`,
); );
} }
} }

View File

@ -81,7 +81,9 @@ export class UsersController {
@ApiOperation({ operationId: 'confirmUser' }) @ApiOperation({ operationId: 'confirmUser' })
@Post('confirm') @Post('confirm')
async confirmUser(@Body() body: ConfirmRequest): Promise<ConfirmResponse> { async confirmUser(@Body() body: ConfirmRequest): Promise<ConfirmResponse> {
await this.usersService.confirmUser(body.token); const context = makeContext(uuidv4());
await this.usersService.confirmUser(context, body.token);
return {}; return {};
} }
@ -148,8 +150,9 @@ export class UsersController {
); );
} }
const { userId } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId);
const users = await this.usersService.getUsers(userId); const users = await this.usersService.getUsers(context, userId);
return { users }; return { users };
} }
@ -325,6 +328,7 @@ export class UsersController {
); );
} }
const { userId } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId);
//型チェック //型チェック
if ( if (
@ -336,7 +340,12 @@ export class UsersController {
HttpStatus.BAD_REQUEST, HttpStatus.BAD_REQUEST,
); );
} }
await this.usersService.updateSortCriteria(paramName, direction, userId); await this.usersService.updateSortCriteria(
context,
paramName,
direction,
userId,
);
return {}; return {};
} }
@ -383,8 +392,10 @@ export class UsersController {
); );
} }
const { userId } = decodedAccessToken as AccessToken; const { userId } = decodedAccessToken as AccessToken;
const context = makeContext(userId);
const { direction, paramName } = await this.usersService.getSortCriteria( const { direction, paramName } = await this.usersService.getSortCriteria(
context,
userId, userId,
); );
return { direction, paramName }; return { direction, paramName };
@ -618,10 +629,17 @@ export class UsersController {
): Promise<UpdateAcceptedVersionResponse> { ): Promise<UpdateAcceptedVersionResponse> {
const { idToken, acceptedEULAVersion, acceptedDPAVersion } = body; const { idToken, acceptedEULAVersion, acceptedDPAVersion } = body;
const verifiedIdToken = await this.authService.getVerifiedIdToken(idToken); const context = makeContext(uuidv4());
const context = makeContext(verifiedIdToken.sub);
const isVerified = await this.authService.isVerifiedUser(verifiedIdToken); const verifiedIdToken = await this.authService.getVerifiedIdToken(
context,
idToken,
);
const isVerified = await this.authService.isVerifiedUser(
context,
verifiedIdToken,
);
if (!isVerified) { if (!isVerified) {
throw new HttpException( throw new HttpException(
makeErrorResponse('E010201'), makeErrorResponse('E010201'),

View File

@ -97,7 +97,8 @@ describe('UsersService.confirmUser', () => {
// account id:1, user id: 2のトークン // account id:1, user id: 2のトークン
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
await service.confirmUser(token); const context = makeContext(`uuidv4`);
await service.confirmUser(context, token);
//result //result
const resultUser = await getUser(source, userId); const resultUser = await getUser(source, userId);
const resultLicenses = await getLicenses(source, accountId); const resultLicenses = await getLicenses(source, accountId);
@ -140,7 +141,8 @@ describe('UsersService.confirmUser', () => {
if (!module) fail(); if (!module) fail();
const token = 'invalid.id.token'; const token = 'invalid.id.token';
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
await expect(service.confirmUser(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.confirmUser(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E000101'), HttpStatus.BAD_REQUEST), new HttpException(makeErrorResponse('E000101'), HttpStatus.BAD_REQUEST),
); );
}); });
@ -175,7 +177,8 @@ describe('UsersService.confirmUser', () => {
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
await expect(service.confirmUser(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.confirmUser(context, token)).rejects.toEqual(
new HttpException(makeErrorResponse('E010202'), HttpStatus.BAD_REQUEST), new HttpException(makeErrorResponse('E010202'), HttpStatus.BAD_REQUEST),
); );
}); });
@ -186,7 +189,8 @@ describe('UsersService.confirmUser', () => {
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const token = const token =
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw'; 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50SWQiOjEsInVzZXJJZCI6MiwiZW1haWwiOiJ4eHhAeHh4Lnh4eCIsImlhdCI6MTAwMDAwMDAwMCwiZXhwIjo5MDAwMDAwMDAwfQ.26L6BdNg-3TbyKT62PswlJ6RPMkcTtHzlDXW2Uo9XbMPVSrl2ObcuS6EcXjFFN2DEfNTKbqX_zevIWMpHOAdLNgGhk528nLrBrNvPASqtTjvW9muxMXpjUdjRVkmVbOylBHWW3YpWL9JEbJQ7rAzWDfaIdPhMovdaxumnZt_UwnlnrdaVPLACW7tkH_laEcAU507iSiM4mqxxG8FuTs34t6PEdwRuzZAQPN2IOPYNSvGNdJYryPacSeSNZ_z1xeBYXLOLQfOBZzyTReYDOhXdikhrNUbxjgnZQlSXBCVMlZ9PH42bHfp-LJIeJzW0yqnF6oLklvJP-fo8eW0k5iDOw';
await expect(service.confirmUser(token)).rejects.toEqual( const context = makeContext(`uuidv4`);
await expect(service.confirmUser(context, token)).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -1626,7 +1630,10 @@ describe('UsersService.getUsers', () => {
}, },
]; ];
expect(await service.getUsers(externalId_author)).toEqual(expectedUsers); const context = makeContext(`uuidv4`);
expect(await service.getUsers(context, externalId_author)).toEqual(
expectedUsers,
);
}); });
it('ユーザーの一覧を取得できること(ライセンス割当済み)', async () => { it('ユーザーの一覧を取得できること(ライセンス割当済み)', async () => {
@ -1742,7 +1749,10 @@ describe('UsersService.getUsers', () => {
}, },
]; ];
expect(await service.getUsers(external_id1)).toEqual(expectedUsers); const context = makeContext(`uuidv4`);
expect(await service.getUsers(context, external_id1)).toEqual(
expectedUsers,
);
}); });
it('DBからのユーザーの取得に失敗した場合、エラーとなる', async () => { it('DBからのユーザーの取得に失敗した場合、エラーとなる', async () => {
@ -1763,8 +1773,11 @@ describe('UsersService.getUsers', () => {
prompt: false, prompt: false,
}); });
const context = makeContext(`uuidv4`);
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
await expect(service.getUsers('externalId_failed')).rejects.toEqual( await expect(
service.getUsers(context, 'externalId_failed'),
).rejects.toEqual(
new HttpException(makeErrorResponse('E009999'), HttpStatus.NOT_FOUND), new HttpException(makeErrorResponse('E009999'), HttpStatus.NOT_FOUND),
); );
}); });
@ -1788,8 +1801,9 @@ describe('UsersService.getUsers', () => {
prompt: false, prompt: false,
}); });
const context = makeContext(`uuidv4`);
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
await expect(service.getUsers(externalId_author)).rejects.toEqual( await expect(service.getUsers(context, externalId_author)).rejects.toEqual(
new HttpException(makeErrorResponse('E009999'), HttpStatus.NOT_FOUND), new HttpException(makeErrorResponse('E009999'), HttpStatus.NOT_FOUND),
); );
}); });
@ -1812,9 +1826,15 @@ describe('UsersService.updateSortCriteria', () => {
configMockValue, configMockValue,
sortCriteriaRepositoryMockValue, sortCriteriaRepositoryMockValue,
); );
const context = makeContext(`uuidv4`);
expect( expect(
await service.updateSortCriteria('AUTHOR_ID', 'ASC', 'external_id'), await service.updateSortCriteria(
context,
'AUTHOR_ID',
'ASC',
'external_id',
),
).toEqual(undefined); ).toEqual(undefined);
}); });
@ -1837,9 +1857,10 @@ describe('UsersService.updateSortCriteria', () => {
configMockValue, configMockValue,
sortCriteriaRepositoryMockValue, sortCriteriaRepositoryMockValue,
); );
const context = makeContext(`uuidv4`);
await expect( await expect(
service.updateSortCriteria('AUTHOR_ID', 'ASC', 'external_id'), service.updateSortCriteria(context, 'AUTHOR_ID', 'ASC', 'external_id'),
).rejects.toEqual( ).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -1868,9 +1889,10 @@ describe('UsersService.updateSortCriteria', () => {
configMockValue, configMockValue,
sortCriteriaRepositoryMockValue, sortCriteriaRepositoryMockValue,
); );
const context = makeContext(`uuidv4`);
await expect( await expect(
service.updateSortCriteria('AUTHOR_ID', 'ASC', 'external_id'), service.updateSortCriteria(context, 'AUTHOR_ID', 'ASC', 'external_id'),
).rejects.toEqual( ).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -1897,8 +1919,9 @@ describe('UsersService.getSortCriteria', () => {
configMockValue, configMockValue,
sortCriteriaRepositoryMockValue, sortCriteriaRepositoryMockValue,
); );
const context = makeContext(`uuidv4`);
expect(await service.getSortCriteria('external_id')).toEqual({ expect(await service.getSortCriteria(context, 'external_id')).toEqual({
direction: 'ASC', direction: 'ASC',
paramName: 'JOB_NUMBER', paramName: 'JOB_NUMBER',
}); });
@ -1925,8 +1948,11 @@ describe('UsersService.getSortCriteria', () => {
configMockValue, configMockValue,
sortCriteriaRepositoryMockValue, sortCriteriaRepositoryMockValue,
); );
const context = makeContext(`uuidv4`);
await expect(service.getSortCriteria('external_id')).rejects.toEqual( await expect(
service.getSortCriteria(context, 'external_id'),
).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -1957,8 +1983,11 @@ describe('UsersService.getSortCriteria', () => {
configMockValue, configMockValue,
sortCriteriaRepositoryMockValue, sortCriteriaRepositoryMockValue,
); );
const context = makeContext(`uuidv4`);
await expect(service.getSortCriteria('external_id')).rejects.toEqual( await expect(
service.getSortCriteria(context, 'external_id'),
).rejects.toEqual(
new HttpException( new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -2014,10 +2043,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
expect( expect(
await service.updateUser( await service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.NONE, USER_ROLES.NONE,
@ -2072,10 +2102,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
expect( expect(
await service.updateUser( await service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.TYPIST, USER_ROLES.TYPIST,
@ -2130,10 +2161,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
expect( expect(
await service.updateUser( await service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.AUTHOR, USER_ROLES.AUTHOR,
@ -2188,10 +2220,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
expect( expect(
await service.updateUser( await service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.TYPIST, USER_ROLES.TYPIST,
@ -2246,10 +2279,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
expect( expect(
await service.updateUser( await service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.AUTHOR, USER_ROLES.AUTHOR,
@ -2304,10 +2338,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
await expect( await expect(
service.updateUser( service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.NONE, USER_ROLES.NONE,
@ -2352,10 +2387,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
expect( expect(
await service.updateUser( await service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.AUTHOR, USER_ROLES.AUTHOR,
@ -2410,10 +2446,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
expect( expect(
await service.updateUser( await service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.AUTHOR, USER_ROLES.AUTHOR,
@ -2468,10 +2505,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
await expect( await expect(
service.updateUser( service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.AUTHOR, USER_ROLES.AUTHOR,
@ -2527,10 +2565,11 @@ describe('UsersService.updateUser', () => {
}); });
const service = module.get<UsersService>(UsersService); const service = module.get<UsersService>(UsersService);
const context = makeContext(`uuidv4`);
await expect( await expect(
service.updateUser( service.updateUser(
{ trackingId: 'trackingId' }, context,
external_id, external_id,
user1, user1,
USER_ROLES.AUTHOR, USER_ROLES.AUTHOR,

View File

@ -72,8 +72,10 @@ export class UsersService {
* Confirms user * Confirms user
* @param token * @param token
*/ */
async confirmUser(token: string): Promise<void> { async confirmUser(context: Context, token: string): Promise<void> {
this.logger.log(`[IN] ${this.confirmUser.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.confirmUser.name}`,
);
const pubKey = getPublicKey(this.configService); const pubKey = getPublicKey(this.configService);
const decodedToken = verify<{ const decodedToken = verify<{
@ -95,7 +97,7 @@ export class UsersService {
userId, userId,
); );
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case EmailAlreadyVerifiedError: case EmailAlreadyVerifiedError:
@ -147,14 +149,23 @@ export class UsersService {
encryptionPassword?: string | undefined, encryptionPassword?: string | undefined,
prompt?: boolean | undefined, prompt?: boolean | undefined,
): Promise<void> { ): Promise<void> {
this.logger.log(`[IN] [${context.trackingId}] ${this.createUser.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.createUser.name} | params: { ` +
`externalId: ${externalId}, ` +
`role: ${role}, ` +
`autoRenew: ${autoRenew}, ` +
`licenseAlert: ${licenseAlert}, ` +
`notification: ${notification}, ` +
`authorId: ${authorId}, ` +
`encryption: ${encryption}, ` +
`prompt: ${prompt} };`,
);
//DBよりアクセス者の所属するアカウントIDを取得する //DBよりアクセス者の所属するアカウントIDを取得する
let adminUser: EntityUser; let adminUser: EntityUser;
try { try {
adminUser = await this.usersRepository.findUserByExternalId(externalId); adminUser = await this.usersRepository.findUserByExternalId(externalId);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -172,7 +183,7 @@ export class UsersService {
authorId, authorId,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -200,8 +211,10 @@ export class UsersService {
name, name,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create externalUser failed'); this.logger.error(
`[${context.getTrackingId()}] create externalUser failed`,
);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -222,6 +235,7 @@ export class UsersService {
try { try {
//roleに応じてユーザー情報を作成する //roleに応じてユーザー情報を作成する
const newUserInfo = this.createNewUserInfo( const newUserInfo = this.createNewUserInfo(
context,
role, role,
accountId, accountId,
externalUser.sub, externalUser.sub,
@ -236,8 +250,8 @@ export class UsersService {
// ユーザ作成 // ユーザ作成
newUser = await this.usersRepository.createNormalUser(newUserInfo); newUser = await this.usersRepository.createNormalUser(newUserInfo);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create user failed'); this.logger.error(`[${context.getTrackingId()}]create user failed`);
//リカバリー処理 //リカバリー処理
//Azure AD B2Cに登録したユーザー情報を削除する //Azure AD B2Cに登録したユーザー情報を削除する
await this.deleteB2cUser(externalUser.sub, context); await this.deleteB2cUser(externalUser.sub, context);
@ -262,6 +276,7 @@ export class UsersService {
// メールの内容を構成 // メールの内容を構成
const { subject, text, html } = const { subject, text, html } =
await this.sendgridService.createMailContentFromEmailConfirmForNormalUser( await this.sendgridService.createMailContentFromEmailConfirmForNormalUser(
context,
accountId, accountId,
newUser.id, newUser.id,
email, email,
@ -277,8 +292,8 @@ export class UsersService {
html, html,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.error('create user failed'); this.logger.error(`[${context.getTrackingId()}] create user failed`);
//リカバリー処理 //リカバリー処理
//Azure AD B2Cに登録したユーザー情報を削除する //Azure AD B2Cに登録したユーザー情報を削除する
await this.deleteB2cUser(externalUser.sub, context); await this.deleteB2cUser(externalUser.sub, context);
@ -289,7 +304,9 @@ export class UsersService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} }
this.logger.log(`[OUT] ${this.createUser.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.createUser.name}`,
);
return; return;
} }
@ -299,12 +316,12 @@ export class UsersService {
try { try {
await this.adB2cService.deleteUser(externalUserId, context); await this.adB2cService.deleteUser(externalUserId, context);
this.logger.log( this.logger.log(
`[${context.trackingId}] delete externalUser: ${externalUserId}`, `[${context.getTrackingId()}] delete externalUser: ${externalUserId}`,
); );
} catch (error) { } catch (error) {
this.logger.error(`error=${error}`); this.logger.error(`[${context.getTrackingId()}] error=${error}`);
this.logger.error( this.logger.error(
`${MANUAL_RECOVERY_REQUIRED} [${context.trackingId}] Failed to delete externalUser: ${externalUserId}`, `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete externalUser: ${externalUserId}`,
); );
} }
} }
@ -313,17 +330,18 @@ export class UsersService {
private async deleteUser(userId: number, context: Context) { private async deleteUser(userId: number, context: Context) {
try { try {
await this.usersRepository.deleteNormalUser(userId); await this.usersRepository.deleteNormalUser(userId);
this.logger.log(`[${context.trackingId}] delete user: ${userId}`); this.logger.log(`[${context.getTrackingId()}] delete user: ${userId}`);
} catch (error) { } catch (error) {
this.logger.error(`error=${error}`); this.logger.error(`[${context.getTrackingId()}] error=${error}`);
this.logger.error( this.logger.error(
`${MANUAL_RECOVERY_REQUIRED} [${context.trackingId}] Failed to delete user: ${userId}`, `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete user: ${userId}`,
); );
} }
} }
// roleを受け取って、roleに応じたnewUserを作成して返却する // roleを受け取って、roleに応じたnewUserを作成して返却する
private createNewUserInfo( private createNewUserInfo(
context: Context,
role: UserRoles, role: UserRoles,
accountId: number, accountId: number,
externalId: string, externalId: string,
@ -335,6 +353,21 @@ export class UsersService {
encryptionPassword?: string | undefined, encryptionPassword?: string | undefined,
prompt?: boolean | undefined, prompt?: boolean | undefined,
): newUser { ): newUser {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.createNewUserInfo.name
} | params: { ` +
`role: ${role}, ` +
`accountId: ${accountId}, ` +
`authorId: ${authorId}, ` +
`externalId: ${externalId}, ` +
`autoRenew: ${autoRenew}, ` +
`licenseAlert: ${licenseAlert}, ` +
`notification: ${notification}, ` +
`authorId: ${authorId}, ` +
`encryption: ${encryption}, ` +
`prompt: ${prompt} };`,
);
switch (role) { switch (role) {
case USER_ROLES.NONE: case USER_ROLES.NONE:
case USER_ROLES.TYPIST: case USER_ROLES.TYPIST:
@ -369,7 +402,9 @@ export class UsersService {
}; };
default: default:
//不正なroleが指定された場合はログを出力してエラーを返す //不正なroleが指定された場合はログを出力してエラーを返す
this.logger.error(`[NOT IMPLEMENT] [RECOVER] role: ${role}`); this.logger.error(
`[${context.getTrackingId()}] [NOT IMPLEMENT] [RECOVER] role: ${role}`,
);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
@ -386,7 +421,9 @@ export class UsersService {
token: string, token: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.confirmUserAndInitPassword.name}`, `[IN] [${context.getTrackingId()}] ${
this.confirmUserAndInitPassword.name
}`,
); );
const pubKey = getPublicKey(this.configService); const pubKey = getPublicKey(this.configService);
@ -412,7 +449,11 @@ export class UsersService {
const user = await this.usersRepository.findUserById(userId); const user = await this.usersRepository.findUserById(userId);
const extarnalId = user.external_id; const extarnalId = user.external_id;
// パスワードを変更する // パスワードを変更する
await this.adB2cService.changePassword(extarnalId, ramdomPassword); await this.adB2cService.changePassword(
context,
extarnalId,
ramdomPassword,
);
// ユーザを認証済みにする // ユーザを認証済みにする
await this.usersRepository.updateUserVerified(userId); await this.usersRepository.updateUserVerified(userId);
// TODO [Task2163] ODMS側が正式にメッセージを決めるまで仮のメール内容とする // TODO [Task2163] ODMS側が正式にメッセージを決めるまで仮のメール内容とする
@ -430,7 +471,7 @@ export class UsersService {
html, html,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case EmailAlreadyVerifiedError: case EmailAlreadyVerifiedError:
@ -453,8 +494,8 @@ export class UsersService {
* @param accessToken * @param accessToken
* @returns users * @returns users
*/ */
async getUsers(externalId: string): Promise<User[]> { async getUsers(context: Context, externalId: string): Promise<User[]> {
this.logger.log(`[IN] ${this.getUsers.name}`); this.logger.log(`[IN] [${context.getTrackingId()}] ${this.getUsers.name}`);
try { try {
// DBから同一アカウントのユーザ一覧を取得する // DBから同一アカウントのユーザ一覧を取得する
@ -464,9 +505,10 @@ export class UsersService {
// DBから取得したユーザーの外部IDをもとにADB2Cからユーザーを取得する // DBから取得したユーザーの外部IDをもとにADB2Cからユーザーを取得する
const externalIds = dbUsers.map((x) => x.external_id); const externalIds = dbUsers.map((x) => x.external_id);
const trackingId = new Context(context.trackingId);
const adb2cUsers = await this.adB2cService.getUsers( const adb2cUsers = await this.adB2cService.getUsers(
// TODO: 外部連携以外のログ強化時に、ContollerからContextを取得するように修正する // TODO: 外部連携以外のログ強化時に、ContollerからContextを取得するように修正する
{ trackingId: 'dummy' }, trackingId,
externalIds, externalIds,
); );
@ -554,13 +596,15 @@ export class UsersService {
return users; return users;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.getUsers.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getUsers.name}`,
);
} }
} }
/** /**
@ -571,17 +615,22 @@ export class UsersService {
* @returns sort criteria * @returns sort criteria
*/ */
async updateSortCriteria( async updateSortCriteria(
context: Context,
paramName: TaskListSortableAttribute, paramName: TaskListSortableAttribute,
direction: SortDirection, direction: SortDirection,
externalId: string, externalId: string,
): Promise<void> { ): Promise<void> {
this.logger.log(`[IN] ${this.updateSortCriteria.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.updateSortCriteria.name
} | params: { paramName: ${paramName}, direction: ${direction}, externalId: ${externalId} };`,
);
let user: EntityUser; let user: EntityUser;
try { try {
// ユーザー情報を取得 // ユーザー情報を取得
user = await this.usersRepository.findUserByExternalId(externalId); user = await this.usersRepository.findUserByExternalId(externalId);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -597,13 +646,15 @@ export class UsersService {
direction, direction,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.updateSortCriteria.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.updateSortCriteria.name}`,
);
} }
} }
/** /**
@ -611,17 +662,24 @@ export class UsersService {
* @param token * @param token
* @returns sort criteria * @returns sort criteria
*/ */
async getSortCriteria(externalId: string): Promise<{ async getSortCriteria(
context: Context,
externalId: string,
): Promise<{
paramName: TaskListSortableAttribute; paramName: TaskListSortableAttribute;
direction: SortDirection; direction: SortDirection;
}> { }> {
this.logger.log(`[IN] ${this.getSortCriteria.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getSortCriteria.name
} | params: { externalId: ${externalId} };`,
);
let user: EntityUser; let user: EntityUser;
try { try {
// ユーザー情報を取得 // ユーザー情報を取得
user = await this.usersRepository.findUserByExternalId(externalId); user = await this.usersRepository.findUserByExternalId(externalId);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
@ -644,13 +702,15 @@ export class UsersService {
} }
return { direction, paramName: parameter }; return { direction, paramName: parameter };
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] ${this.getSortCriteria.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getSortCriteria.name}`,
);
} }
} }
@ -663,7 +723,11 @@ export class UsersService {
context: Context, context: Context,
userId: string, userId: string,
): Promise<GetRelationsResponse> { ): Promise<GetRelationsResponse> {
this.logger.log(`[IN] [${context.trackingId}] ${this.getRelations.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getRelations.name
} | params: { userId: ${userId} };`,
);
try { try {
const { id } = await this.usersRepository.findUserByExternalId(userId); const { id } = await this.usersRepository.findUserByExternalId(userId);
@ -710,7 +774,7 @@ export class UsersService {
prompt: user.prompt, prompt: user.prompt,
}; };
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
@ -733,7 +797,7 @@ export class UsersService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getRelations.name}`, `[OUT] [${context.getTrackingId()}] ${this.getRelations.name}`,
); );
} }
} }
@ -768,14 +832,17 @@ export class UsersService {
): Promise<void> { ): Promise<void> {
try { try {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateUser.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.updateUser.name
} | params: { ` +
`extarnalId: ${extarnalId}, ` +
`id: ${id}, ` +
`role: ${role}, ` + `role: ${role}, ` +
`authorId: ${authorId}, ` + `authorId: ${authorId}, ` +
`autoRenew: ${autoRenew}, ` + `autoRenew: ${autoRenew}, ` +
`licenseAlart: ${licenseAlart}, ` + `licenseAlart: ${licenseAlart}, ` +
`notification: ${notification}, ` + `notification: ${notification}, ` +
`encryption: ${encryption}, ` + `encryption: ${encryption}, ` +
`encryptionPassword: ********, ` +
`prompt: ${prompt} }`, `prompt: ${prompt} }`,
); );
@ -798,7 +865,7 @@ export class UsersService {
prompt, prompt,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
@ -833,7 +900,9 @@ export class UsersService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.updateUser.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.updateUser.name}`,
);
} }
} }
@ -849,7 +918,9 @@ export class UsersService {
newLicenseId: number, newLicenseId: number,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.allocateLicense.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.allocateLicense.name
} | params: { ` +
`userId: ${userId}, ` + `userId: ${userId}, ` +
`newLicenseId: ${newLicenseId}, };`, `newLicenseId: ${newLicenseId}, };`,
); );
@ -864,7 +935,7 @@ export class UsersService {
accountId, accountId,
); );
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case LicenseExpiredError: case LicenseExpiredError:
@ -886,7 +957,7 @@ export class UsersService {
} }
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.allocateLicense.name}`, `[OUT] [${context.getTrackingId()}] ${this.allocateLicense.name}`,
); );
} }
} }
@ -898,8 +969,9 @@ export class UsersService {
*/ */
async deallocateLicense(context: Context, userId: number): Promise<void> { async deallocateLicense(context: Context, userId: number): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.deallocateLicense.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
`userId: ${userId}, };`, this.deallocateLicense.name
} | params: { ` + `userId: ${userId}, };`,
); );
try { try {
@ -908,7 +980,7 @@ export class UsersService {
await this.licensesRepository.deallocateLicense(userId, accountId); await this.licensesRepository.deallocateLicense(userId, accountId);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case LicenseAlreadyDeallocatedError: case LicenseAlreadyDeallocatedError:
@ -925,7 +997,7 @@ export class UsersService {
} }
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.deallocateLicense.name}`, `[OUT] [${context.getTrackingId()}] ${this.deallocateLicense.name}`,
); );
} }
} }
@ -944,7 +1016,9 @@ export class UsersService {
dpaVersion?: string, dpaVersion?: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateAcceptedVersion.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.updateAcceptedVersion.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`eulaVersion: ${eulaVersion}, ` + `eulaVersion: ${eulaVersion}, ` +
`dpaVersion: ${dpaVersion}, };`, `dpaVersion: ${dpaVersion}, };`,
@ -957,7 +1031,7 @@ export class UsersService {
dpaVersion, dpaVersion,
); );
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
@ -984,7 +1058,7 @@ export class UsersService {
} }
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.updateAcceptedVersion.name}`, `[OUT] [${context.getTrackingId()}] ${this.updateAcceptedVersion.name}`,
); );
} }
} }
@ -994,16 +1068,20 @@ export class UsersService {
* @param externalId * @param externalId
*/ */
async getUserName(context: Context, externalId: string): Promise<string> { async getUserName(context: Context, externalId: string): Promise<string> {
this.logger.log(`[IN] [${context.trackingId}] ${this.getUserName.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getUserName.name
} | params: { externalId: ${externalId} };`,
);
try { try {
// extarnalIdの存在チェックを行う // extarnalIdの存在チェックを行う
await this.usersRepository.findUserByExternalId(externalId); await this.usersRepository.findUserByExternalId(externalId);
// ADB2Cからユーザー名を取得する // ADB2Cからユーザー名を取得する
const adb2cUser = await this.adB2cService.getUser(externalId); const adb2cUser = await this.adB2cService.getUser(context, externalId);
return adb2cUser.displayName; return adb2cUser.displayName;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
@ -1023,7 +1101,9 @@ export class UsersService {
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.getUserName.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getUserName.name}`,
);
} }
} }
} }

View File

@ -35,7 +35,9 @@ export class WorkflowsService {
externalId: string, externalId: string,
): Promise<Workflow[]> { ): Promise<Workflow[]> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.getWorkflows.name} | params: { externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.getWorkflows.name
} | params: { externalId: ${externalId} };`,
); );
try { try {
const { account_id: accountId } = const { account_id: accountId } =
@ -121,14 +123,14 @@ export class WorkflowsService {
return workflows; return workflows;
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw new HttpException( throw new HttpException(
makeErrorResponse('E009999'), makeErrorResponse('E009999'),
HttpStatus.INTERNAL_SERVER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR,
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.getWorkflows.name}`, `[OUT] [${context.getTrackingId()}] ${this.getWorkflows.name}`,
); );
} }
} }
@ -152,7 +154,9 @@ export class WorkflowsService {
templateId?: number | undefined, templateId?: number | undefined,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.createWorkflow.name} | | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.createWorkflow.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`authorId: ${authorId}, ` + `authorId: ${authorId}, ` +
`worktypeId: ${worktypeId}, ` + `worktypeId: ${worktypeId}, ` +
@ -171,7 +175,7 @@ export class WorkflowsService {
templateId, templateId,
); );
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
@ -212,7 +216,7 @@ export class WorkflowsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.createWorkflow.name}`, `[OUT] [${context.getTrackingId()}] ${this.createWorkflow.name}`,
); );
} }
} }
@ -237,7 +241,9 @@ export class WorkflowsService {
templateId?: number | undefined, templateId?: number | undefined,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.updateWorkflow.name} | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.updateWorkflow.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`workflowId: ${workflowId}, ` + `workflowId: ${workflowId}, ` +
`authorId: ${authorId}, ` + `authorId: ${authorId}, ` +
@ -258,7 +264,7 @@ export class WorkflowsService {
templateId, templateId,
); );
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case WorkflowNotFoundError: case WorkflowNotFoundError:
@ -304,7 +310,7 @@ export class WorkflowsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.updateWorkflow.name}`, `[OUT] [${context.getTrackingId()}] ${this.updateWorkflow.name}`,
); );
} }
} }
@ -322,7 +328,9 @@ export class WorkflowsService {
workflowId: number, workflowId: number,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.deleteWorkflow.name} | | params: { ` + `[IN] [${context.getTrackingId()}] ${
this.deleteWorkflow.name
} | params: { ` +
`externalId: ${externalId}, ` + `externalId: ${externalId}, ` +
`workflowId: ${workflowId} };`, `workflowId: ${workflowId} };`,
); );
@ -339,7 +347,7 @@ export class WorkflowsService {
await this.workflowsRepository.deleteWorkflow(account.id, workflowId); await this.workflowsRepository.deleteWorkflow(account.id, workflowId);
} catch (e) { } catch (e) {
this.logger.error(`[${context.trackingId}] error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) { if (e instanceof Error) {
switch (e.constructor) { switch (e.constructor) {
case UserNotFoundError: case UserNotFoundError:
@ -370,7 +378,7 @@ export class WorkflowsService {
); );
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.deleteWorkflow.name}`, `[OUT] [${context.getTrackingId()}] ${this.deleteWorkflow.name}`,
); );
} }
} }

View File

@ -1,7 +1,7 @@
import { ClientSecretCredential } from '@azure/identity'; import { ClientSecretCredential } from '@azure/identity';
import { Client } from '@microsoft/microsoft-graph-client'; import { Client } from '@microsoft/microsoft-graph-client';
import { TokenCredentialAuthenticationProvider } from '@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials'; import { TokenCredentialAuthenticationProvider } from '@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials';
import { CACHE_MANAGER, Inject, Injectable, Logger } from '@nestjs/common'; import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config'; import { ConfigService } from '@nestjs/config';
import axios from 'axios'; import axios from 'axios';
import { B2cMetadata, JwkSignKey } from '../../common/token'; import { B2cMetadata, JwkSignKey } from '../../common/token';
@ -71,7 +71,9 @@ export class AdB2cService {
password: string, password: string,
username: string, username: string,
): Promise<{ sub: string } | ConflictError> { ): Promise<{ sub: string } | ConflictError> {
this.logger.log(`[IN] [${context.trackingId}] ${this.createUser.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.createUser.name}`,
);
try { try {
// ユーザをADB2Cに登録 // ユーザをADB2Cに登録
const newUser = await this.graphClient.api('users/').post({ const newUser = await this.graphClient.api('users/').post({
@ -92,7 +94,7 @@ export class AdB2cService {
}); });
return { sub: newUser.id }; return { sub: newUser.id };
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e?.statusCode === 400 && e?.body) { if (e?.statusCode === 400 && e?.body) {
const error = JSON.parse(e.body); const error = JSON.parse(e.body);
@ -104,7 +106,9 @@ export class AdB2cService {
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.createUser.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.createUser.name}`,
);
} }
} }
@ -112,8 +116,10 @@ export class AdB2cService {
* ADB2Cのメタデータを取得する * ADB2Cのメタデータを取得する
* @returns meta data * @returns meta data
*/ */
async getMetaData(): Promise<B2cMetadata> { async getMetaData(context: Context): Promise<B2cMetadata> {
this.logger.log(`[IN] ${this.getMetaData.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.getMetaData.name}`,
);
try { try {
// Azure AD B2Cのメタデータを取得する。 以下のURLから取得できる。 // Azure AD B2Cのメタデータを取得する。 以下のURLから取得できる。
// https://<テナント名>.b2clogin.com/<テナント名>.onmicrosoft.com/<ユーザーフロー名>/v2.0/.well-known/openid-configuration // https://<テナント名>.b2clogin.com/<テナント名>.onmicrosoft.com/<ユーザーフロー名>/v2.0/.well-known/openid-configuration
@ -125,10 +131,12 @@ export class AdB2cService {
return metaData; return metaData;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] ${this.getMetaData.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getMetaData.name}`,
);
} }
} }
@ -136,8 +144,10 @@ export class AdB2cService {
* IDトークンの署名キーセットを取得する * IDトークンの署名キーセットを取得する
* @returns sign key sets * @returns sign key sets
*/ */
async getSignKeySets(): Promise<JwkSignKey[]> { async getSignKeySets(context: Context): Promise<JwkSignKey[]> {
this.logger.log(`[IN] ${this.getSignKeySets.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.getSignKeySets.name}`,
);
try { try {
// 署名キーのキーセット配列を取得する。 以下のURLから取得できる。 // 署名キーのキーセット配列を取得する。 以下のURLから取得できる。
const keySets = await axios const keySets = await axios
@ -148,10 +158,12 @@ export class AdB2cService {
return keySets; return keySets;
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] ${this.getSignKeySets.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getSignKeySets.name}`,
);
} }
} }
@ -160,8 +172,16 @@ export class AdB2cService {
* @param externalId * @param externalId
* @param password * @param password
*/ */
async changePassword(externalId: string, password: string): Promise<void> { async changePassword(
this.logger.log(`[IN] ${this.changePassword.name}`); context: Context,
externalId: string,
password: string,
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.changePassword.name
} | params: { ` + `externalId: ${externalId}, };`,
);
try { try {
// ADB2Cのユーザのパスワードを変更する // ADB2Cのユーザのパスワードを変更する
await this.graphClient.api(`/users/${externalId}`).patch({ await this.graphClient.api(`/users/${externalId}`).patch({
@ -171,10 +191,12 @@ export class AdB2cService {
}, },
}); });
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] ${this.changePassword.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.changePassword.name}`,
);
} }
} }
@ -183,16 +205,21 @@ export class AdB2cService {
* @param externalId ID * @param externalId ID
* @returns * @returns
*/ */
async getUser(externalId: string): Promise<AdB2cUser> { async getUser(context: Context, externalId: string): Promise<AdB2cUser> {
this.logger.log(`[IN] ${this.getUser.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.getUser.name} | params: { ` +
`externalId: ${externalId} };`,
);
try { try {
const key = makeADB2CKey(externalId); const key = makeADB2CKey(externalId);
// キャッシュ上に存在していれば、キャッシュから取得する // キャッシュ上に存在していれば、キャッシュから取得する
const cachedUser = await this.redisService.get<AdB2cUser>(key); const cachedUser = await this.redisService.get<AdB2cUser>(context, key);
if (cachedUser) { if (cachedUser) {
this.logger.log(`[CACHE HIT] id: ${externalId}`); this.logger.log(
`[${context.getTrackingId()}] [CACHE HIT] id: ${externalId}`,
);
return cachedUser; return cachedUser;
} }
@ -201,15 +228,19 @@ export class AdB2cService {
.api(`users/${externalId}`) .api(`users/${externalId}`)
.select(['id', 'displayName', 'identities']) .select(['id', 'displayName', 'identities'])
.get(); .get();
await this.redisService.set(key, user, this.ttl); await this.redisService.set(context, key, user, this.ttl);
this.logger.log(`[ADB2C GET] externalId: ${externalId}`); this.logger.log(
`[${context.getTrackingId()}] [ADB2C GET] externalId: ${externalId}`,
);
return user; return user;
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] ${this.getUser.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getUser.name}`,
);
} }
} }
/** /**
@ -222,19 +253,21 @@ export class AdB2cService {
externalIds: string[], externalIds: string[],
): Promise<AdB2cUser[]> { ): Promise<AdB2cUser[]> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${ `[IN] [${context.getTrackingId()}] ${
this.getUsers.name this.getUsers.name
} | params: { externalIds:[${externalIds.join(',')}] };`, } | params: { externalIds:[${externalIds.join(',')}] };`,
); );
const keys = externalIds.map((externalId) => makeADB2CKey(externalId)); const keys = externalIds.map((externalId) => makeADB2CKey(externalId));
const cache = await this.redisService.mget<AdB2cUser>(keys); const cache = await this.redisService.mget<AdB2cUser>(context, keys);
// キャッシュ上に存在していれば、キャッシュから取得する // キャッシュ上に存在していれば、キャッシュから取得する
const cachedUsers = cache.flatMap((x) => (x.value ? [x.value] : [])); const cachedUsers = cache.flatMap((x) => (x.value ? [x.value] : []));
if (cachedUsers.length > 0) { if (cachedUsers.length > 0) {
this.logger.log( this.logger.log(
`[CACHE HIT] ids: ${cachedUsers.map((x) => x.id).join(',')}`, `[${context.getTrackingId()}] [CACHE HIT] ids: ${cachedUsers
.map((x) => x.id)
.join(',')}`,
); );
} }
@ -265,15 +298,17 @@ export class AdB2cService {
value: user, value: user,
}; };
}); });
await this.redisService.mset(users, this.ttl); await this.redisService.mset(context, users, this.ttl);
this.logger.log( this.logger.log(
`[ADB2C GET] externalIds: ${res.value?.map((x) => x.id).join(',')}`, `[${context.getTrackingId()}] [ADB2C GET] externalIds: ${res.value
?.map((x) => x.id)
.join(',')}`,
); );
} }
return [...cachedUsers, ...b2cUsers]; return [...cachedUsers, ...b2cUsers];
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
const { statusCode } = e; const { statusCode } = e;
if (statusCode === 429) { if (statusCode === 429) {
throw new Adb2cTooManyRequestsError(); throw new Adb2cTooManyRequestsError();
@ -281,7 +316,9 @@ export class AdB2cService {
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.getUsers.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.getUsers.name}`,
);
} }
} }
/** /**
@ -291,26 +328,32 @@ export class AdB2cService {
*/ */
async deleteUser(externalId: string, context: Context): Promise<void> { async deleteUser(externalId: string, context: Context): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.deleteUser.name} | params: { externalId: ${externalId} };`, `[IN] [${context.getTrackingId()}] ${
this.deleteUser.name
} | params: { externalId: ${externalId} };`,
); );
try { try {
// https://learn.microsoft.com/en-us/graph/api/user-delete?view=graph-rest-1.0&tabs=javascript#example // https://learn.microsoft.com/en-us/graph/api/user-delete?view=graph-rest-1.0&tabs=javascript#example
await this.graphClient.api(`users/${externalId}`).delete(); await this.graphClient.api(`users/${externalId}`).delete();
this.logger.log(`[ADB2C DELETE] externalId: ${externalId}`); this.logger.log(
`[${context.getTrackingId()}] [ADB2C DELETE] externalId: ${externalId}`,
);
// キャッシュからも削除する // キャッシュからも削除する
try { try {
await this.redisService.del(makeADB2CKey(externalId)); await this.redisService.del(context, makeADB2CKey(externalId));
} catch (e) { } catch (e) {
// キャッシュからの削除に失敗しても、ADB2Cからの削除は成功しているため例外はスローしない // キャッシュからの削除に失敗しても、ADB2Cからの削除は成功しているため例外はスローしない
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
} }
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.deleteUser.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.deleteUser.name}`,
);
} }
} }
@ -321,7 +364,9 @@ export class AdB2cService {
*/ */
async deleteUsers(externalIds: string[], context: Context): Promise<void> { async deleteUsers(externalIds: string[], context: Context): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.deleteUsers.name} | params: { externalIds: ${externalIds} };`, `[IN] [${context.getTrackingId()}] ${
this.deleteUsers.name
} | params: { externalIds: ${externalIds} };`,
); );
try { try {
@ -329,14 +374,16 @@ export class AdB2cService {
const results = await Promise.allSettled( const results = await Promise.allSettled(
externalIds.map(async (externalId) => { externalIds.map(async (externalId) => {
await this.graphClient.api(`users/${externalId}`).delete(); await this.graphClient.api(`users/${externalId}`).delete();
this.logger.log(`[ADB2C DELETE] externalId: ${externalId}`); this.logger.log(
`[${context.getTrackingId()}] [ADB2C DELETE] externalId: ${externalId}`,
);
// キャッシュからも削除する // キャッシュからも削除する
try { try {
await this.redisService.del(makeADB2CKey(externalId)); await this.redisService.del(context, makeADB2CKey(externalId));
} catch (e) { } catch (e) {
// キャッシュからの削除に失敗しても、ADB2Cからの削除は成功しているため例外はスローしない // キャッシュからの削除に失敗しても、ADB2Cからの削除は成功しているため例外はスローしない
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
} }
}), }),
); );
@ -353,19 +400,21 @@ export class AdB2cService {
const error = result.reason.toString(); const error = result.reason.toString();
this.logger.error( this.logger.error(
`${MANUAL_RECOVERY_REQUIRED}[${context.trackingId}] Failed to delete user ${failedId}: ${error}`, `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete user ${failedId}: ${error}`,
); );
} else { } else {
this.logger.error( this.logger.error(
`${MANUAL_RECOVERY_REQUIRED}[${context.trackingId}] Failed to delete user ${failedId}`, `${MANUAL_RECOVERY_REQUIRED} [${context.getTrackingId()}] Failed to delete user ${failedId}`,
); );
} }
}); });
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.deleteUsers.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.deleteUsers.name}`,
);
} }
} }
} }

View File

@ -69,21 +69,27 @@ export class BlobstorageService {
country: string, country: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.createContainer.name}`, `[IN] [${context.getTrackingId()}] ${
this.createContainer.name
} | params: { ` + `accountId: ${accountId} };`,
); );
// 国に応じたリージョンでコンテナ名を指定してClientを取得 // 国に応じたリージョンでコンテナ名を指定してClientを取得
const containerClient = this.getContainerClient(accountId, country); const containerClient = this.getContainerClient(
context,
accountId,
country,
);
try { try {
// コンテナ作成 // コンテナ作成
await containerClient.create(); await containerClient.create();
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.createContainer.name}`, `[OUT] [${context.getTrackingId()}] ${this.createContainer.name}`,
); );
} }
} }
@ -100,16 +106,22 @@ export class BlobstorageService {
country: string, country: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.deleteContainer.name}`, `[IN] [${context.getTrackingId()}] ${
this.deleteContainer.name
} | params: { ` + `accountId: ${accountId} };`,
); );
try { try {
// 国に応じたリージョンでコンテナ名を指定してClientを取得 // 国に応じたリージョンでコンテナ名を指定してClientを取得
const containerClient = this.getContainerClient(accountId, country); const containerClient = this.getContainerClient(
context,
accountId,
country,
);
const { succeeded, errorCode, date } = const { succeeded, errorCode, date } =
await containerClient.deleteIfExists(); await containerClient.deleteIfExists();
this.logger.log( this.logger.log(
`succeeded: ${succeeded}, errorCode: ${errorCode}, date: ${date}`, `[${context.getTrackingId()}] succeeded: ${succeeded}, errorCode: ${errorCode}, date: ${date}`,
); );
// 失敗時、コンテナが存在しない場合以外はエラーとして例外をスローする // 失敗時、コンテナが存在しない場合以外はエラーとして例外をスローする
@ -121,11 +133,11 @@ export class BlobstorageService {
); );
} }
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.deleteContainer.name}`, `[OUT] [${context.getTrackingId()}] ${this.deleteContainer.name}`,
); );
} }
} }
@ -142,14 +154,20 @@ export class BlobstorageService {
country: string, country: string,
): Promise<boolean> { ): Promise<boolean> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.containerExists.name}`, `[IN] [${context.getTrackingId()}] ${
this.containerExists.name
} | params: { ` + `accountId: ${accountId} };`,
); );
// 国に応じたリージョンでコンテナ名を指定してClientを取得 // 国に応じたリージョンでコンテナ名を指定してClientを取得
const containerClient = this.getContainerClient(accountId, country); const containerClient = this.getContainerClient(
context,
accountId,
country,
);
const exists = await containerClient.exists(); const exists = await containerClient.exists();
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.containerExists.name}`, `[OUT] [${context.getTrackingId()}] ${this.containerExists.name}`,
); );
return exists; return exists;
} }
@ -169,13 +187,23 @@ export class BlobstorageService {
country: string, country: string,
filePath: string, filePath: string,
): Promise<boolean> { ): Promise<boolean> {
this.logger.log(`[IN] [${context.trackingId}] ${this.fileExists.name}`); this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.fileExists.name} | params: { ` +
`accountId: ${accountId},` +
`filePath: ${filePath} };`,
);
const containerClient = this.getContainerClient(accountId, country); const containerClient = this.getContainerClient(
context,
accountId,
country,
);
const blob = containerClient.getBlobClient(`${filePath}`); const blob = containerClient.getBlobClient(`${filePath}`);
const exists = await blob.exists(); const exists = await blob.exists();
this.logger.log(`[OUT] [${context.trackingId}] ${this.fileExists.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.fileExists.name}`,
);
return exists; return exists;
} }
@ -191,19 +219,21 @@ export class BlobstorageService {
country: string, country: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.publishUploadSas.name}`, `[IN] [${context.getTrackingId()}] ${
this.publishUploadSas.name
} | params: { ` + `accountId: ${accountId} };`,
); );
let containerClient: ContainerClient; let containerClient: ContainerClient;
let sharedKeyCredential: StorageSharedKeyCredential; let sharedKeyCredential: StorageSharedKeyCredential;
try { try {
// コンテナ名を指定してClientを取得 // コンテナ名を指定してClientを取得
containerClient = this.getContainerClient(accountId, country); containerClient = this.getContainerClient(context, accountId, country);
// 国に対応したリージョンの接続情報を取得する // 国に対応したリージョンの接続情報を取得する
sharedKeyCredential = this.getSharedKeyCredential(country); sharedKeyCredential = this.getSharedKeyCredential(country);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishUploadSas.name}`, `[OUT] [${context.getTrackingId()}] ${this.publishUploadSas.name}`,
); );
throw e; throw e;
} }
@ -231,7 +261,7 @@ export class BlobstorageService {
url.search = `${sasToken}`; url.search = `${sasToken}`;
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${ `[OUT] [${context.getTrackingId()}] ${
this.publishUploadSas.name this.publishUploadSas.name
} url=${url.toString()}`, } url=${url.toString()}`,
); );
@ -250,12 +280,18 @@ export class BlobstorageService {
country: string, country: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.publishTemplateUploadSas.name}`, `[IN] [${context.getTrackingId()}] ${
this.publishTemplateUploadSas.name
} | params: { ` + `accountId: ${accountId} };`,
); );
try { try {
// コンテナ名を指定してClientを取得 // コンテナ名を指定してClientを取得
const containerClient = this.getContainerClient(accountId, country); const containerClient = this.getContainerClient(
context,
accountId,
country,
);
// 国に対応したリージョンの接続情報を取得する // 国に対応したリージョンの接続情報を取得する
const sharedKeyCredential = this.getSharedKeyCredential(country); const sharedKeyCredential = this.getSharedKeyCredential(country);
//SASの有効期限を設定 //SASの有効期限を設定
@ -282,11 +318,13 @@ export class BlobstorageService {
return url.toString(); return url.toString();
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishTemplateUploadSas.name}`, `[OUT] [${context.getTrackingId()}] ${
this.publishTemplateUploadSas.name
}`,
); );
} }
} }
@ -306,22 +344,26 @@ export class BlobstorageService {
filePath: string, filePath: string,
): Promise<string> { ): Promise<string> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.publishDownloadSas.name}`, `[IN] [${context.getTrackingId()}] ${
this.publishDownloadSas.name
}| params: { ` +
`accountId: ${accountId},` +
`filePath: ${filePath} };`,
); );
let containerClient: ContainerClient; let containerClient: ContainerClient;
let blobClient: BlobClient; let blobClient: BlobClient;
let sharedKeyCredential: StorageSharedKeyCredential; let sharedKeyCredential: StorageSharedKeyCredential;
try { try {
// コンテナ名を指定してClientを取得 // コンテナ名を指定してClientを取得
containerClient = this.getContainerClient(accountId, country); containerClient = this.getContainerClient(context, accountId, country);
// コンテナ内のBlobパス名を指定してClientを取得 // コンテナ内のBlobパス名を指定してClientを取得
blobClient = containerClient.getBlobClient(`${filePath}`); blobClient = containerClient.getBlobClient(`${filePath}`);
// 国に対応したリージョンの接続情報を取得する // 国に対応したリージョンの接続情報を取得する
sharedKeyCredential = this.getSharedKeyCredential(country); sharedKeyCredential = this.getSharedKeyCredential(country);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.publishDownloadSas.name}`, `[OUT] [${context.getTrackingId()}] ${this.publishDownloadSas.name}`,
); );
throw e; throw e;
} }
@ -350,7 +392,7 @@ export class BlobstorageService {
url.search = `${sasToken}`; url.search = `${sasToken}`;
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${ `[OUT] [${context.getTrackingId()}] ${
this.publishDownloadSas.name this.publishDownloadSas.name
}, url=${url.toString()}`, }, url=${url.toString()}`,
); );
@ -363,9 +405,16 @@ export class BlobstorageService {
* @returns container client * @returns container client
*/ */
private getContainerClient( private getContainerClient(
context: Context,
accountId: number, accountId: number,
country: string, country: string,
): ContainerClient { ): ContainerClient {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.getContainerClient.name
} | params: { ` + `accountId: ${accountId} };`,
);
const containerName = `account-${accountId}`; const containerName = `account-${accountId}`;
if (BLOB_STORAGE_REGION_US.includes(country)) { if (BLOB_STORAGE_REGION_US.includes(country)) {
return this.blobServiceClientUS.getContainerClient(containerName); return this.blobServiceClientUS.getContainerClient(containerName);

View File

@ -39,7 +39,9 @@ export class NotificationhubService {
installationId: string, installationId: string,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.register.name} | params: { userId: ${userId}, pns: ${pns}, pnsHandler: ${pnsHandler}, installationId: ${installationId} }`, `[IN] [${context.getTrackingId()}] ${
this.register.name
} | params: { userId: ${userId}, pns: ${pns}, pnsHandler: ${pnsHandler}, installationId: ${installationId} }`,
); );
const tag = `user_${userId}`; const tag = `user_${userId}`;
@ -69,10 +71,12 @@ export class NotificationhubService {
throw new Error('invalid pns'); throw new Error('invalid pns');
} }
} catch (e) { } catch (e) {
this.logger.error(`error=${e.message}`); this.logger.error(`[${context.getTrackingId()}] error=${e.message}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.register.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.register.name}`,
);
} }
} }
@ -89,7 +93,7 @@ export class NotificationhubService {
bodyContent: NotificationBody, bodyContent: NotificationBody,
): Promise<void> { ): Promise<void> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${ `[IN] [${context.getTrackingId()}] ${
this.notify.name this.notify.name
} | params: { tags: ${tags}, bodyContent: ${JSON.stringify( } | params: { tags: ${tags}, bodyContent: ${JSON.stringify(
bodyContent, bodyContent,
@ -118,9 +122,9 @@ export class NotificationhubService {
const result = await this.client.sendNotification(notification, { const result = await this.client.sendNotification(notification, {
tagExpression, tagExpression,
}); });
this.logger.log(result); this.logger.log(`[${context.getTrackingId()}] ${result}`);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
} }
// Apple // Apple
try { try {
@ -134,15 +138,15 @@ export class NotificationhubService {
const result = await this.client.sendNotification(notification, { const result = await this.client.sendNotification(notification, {
tagExpression, tagExpression,
}); });
this.logger.log(result); this.logger.log(`[${context.getTrackingId()}] ${result}`);
} catch (e) { } catch (e) {
this.logger.error(`error=${e}`); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
} }
} }
} catch (e) { } catch (e) {
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] ${this.notify.name}`); this.logger.log(`[OUT] [${context.getTrackingId()}] ${this.notify.name}`);
} }
} }
} }

View File

@ -1,11 +1,6 @@
import { import { CACHE_MANAGER, Inject, Injectable, Logger } from '@nestjs/common';
CACHE_MANAGER,
Inject,
Injectable,
InternalServerErrorException,
Logger,
} from '@nestjs/common';
import { Cache } from 'cache-manager'; import { Cache } from 'cache-manager';
import { Context } from '../../common/log';
@Injectable() @Injectable()
export class RedisService { export class RedisService {
@ -20,10 +15,17 @@ export class RedisService {
* @param ttl * @param ttl
*/ */
async set( async set(
context: Context,
key: string, key: string,
value: unknown, value: unknown,
ttl?: number | undefined, ttl?: number | undefined,
): Promise<void> { ): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.set.name} | params: { ` +
`ttl: ${ttl}
};`,
);
try { try {
// cache-manager-redis-store がcache-managerのset形式と不一致な値の渡し方を採用しているため、 // cache-manager-redis-store がcache-managerのset形式と不一致な値の渡し方を採用しているため、
// @types/cache-managerのset形式を使用すると、redisに値が保存されない。 // @types/cache-managerのset形式を使用すると、redisに値が保存されない。
@ -31,7 +33,7 @@ export class RedisService {
// https://www.npmjs.com/package/cache-manager // https://www.npmjs.com/package/cache-manager
await this.cacheManager.set(key, value, { ttl: ttl } as any); await this.cacheManager.set(key, value, { ttl: ttl } as any);
} catch (error) { } catch (error) {
this.logger.error(error); this.logger.error(`[${context.getTrackingId()}] ${error}`);
} }
} }
@ -42,17 +44,24 @@ export class RedisService {
* @param ttl * @param ttl
*/ */
async mset<T>( async mset<T>(
context: Context,
records: { key: string; value: T }[], records: { key: string; value: T }[],
ttl?: number | undefined, ttl?: number | undefined,
): Promise<void> { ): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.mset.name} | params: { ` +
`ttl: ${ttl}
};`,
);
try { try {
// cache-manager-redis-store のmsetが壊れており、利用できないため、 // cache-manager-redis-store のmsetが壊れており、利用できないため、
// 一つずつsetする。 // 一つずつsetする。
for await (const record of records) { for await (const record of records) {
await this.set(record.key, record.value, ttl); await this.set(context, record.key, record.value, ttl);
} }
} catch (error) { } catch (error) {
this.logger.error(error); this.logger.error(`[${context.getTrackingId()}] ${error}`);
} }
} }
@ -62,12 +71,14 @@ export class RedisService {
* @param key * @param key
* @returns * @returns
*/ */
async get<T>(key: string): Promise<T | undefined> { async get<T>(context: Context, key: string): Promise<T | undefined> {
this.logger.log(`[IN] [${context.getTrackingId()}] ${this.get.name};`);
try { try {
const value = await this.cacheManager.get<T>(key); const value = await this.cacheManager.get<T>(key);
return value; return value;
} catch (error) { } catch (error) {
this.logger.error(error); this.logger.error(`[${context.getTrackingId()}] ${error}`);
return undefined; return undefined;
} }
} }
@ -78,7 +89,12 @@ export class RedisService {
* @param keys * @param keys
* @returns * @returns
*/ */
async mget<T>(keys: string[]): Promise<{ key: string; value: T | null }[]> { async mget<T>(
context: Context,
keys: string[],
): Promise<{ key: string; value: T | null }[]> {
this.logger.log(`[IN] [${context.getTrackingId()}] ${this.mget.name};`);
if (keys.length === 0) return []; // mget操作は0件の時エラーとなるため、0件は特別扱いする if (keys.length === 0) return []; // mget操作は0件の時エラーとなるため、0件は特別扱いする
try { try {
@ -91,7 +107,7 @@ export class RedisService {
}; };
}); });
} catch (error) { } catch (error) {
this.logger.error(error); this.logger.error(`[${context.getTrackingId()}] ${error}`);
return []; return [];
} }
} }
@ -100,11 +116,13 @@ export class RedisService {
* *
* @param key * @param key
*/ */
async del(key: string): Promise<void> { async del(context: Context, key: string): Promise<void> {
this.logger.log(`[IN] [${context.getTrackingId()}] ${this.del.name};`);
try { try {
await this.cacheManager.del(key); await this.cacheManager.del(key);
} catch (error) { } catch (error) {
this.logger.error(error); this.logger.error(`[${context.getTrackingId()}] ${error}`);
} }
} }
} }

View File

@ -23,7 +23,7 @@ export class SendGridService {
* Email認証用のメールコンテンツを作成する * Email認証用のメールコンテンツを作成する
* @param accountId ID * @param accountId ID
* @param userId ID * @param userId ID
* @param email * @param email
* @returns * @returns
*/ */
async createMailContentFromEmailConfirm( async createMailContentFromEmailConfirm(
@ -33,7 +33,11 @@ export class SendGridService {
email: string, email: string,
): Promise<{ subject: string; text: string; html: string }> { ): Promise<{ subject: string; text: string; html: string }> {
this.logger.log( this.logger.log(
`[IN] [${context.trackingId}] ${this.createMailContentFromEmailConfirm.name}`, `[IN] [${context.getTrackingId()}] ${
this.createMailContentFromEmailConfirm.name
} | params: { ` +
`accountId: ${accountId},` +
`userId: ${userId} };`,
); );
const privateKey = getPrivateKey(this.configService); const privateKey = getPrivateKey(this.configService);
@ -49,7 +53,9 @@ export class SendGridService {
const path = 'mail-confirm/'; const path = 'mail-confirm/';
this.logger.log( this.logger.log(
`[OUT] [${context.trackingId}] ${this.createMailContentFromEmailConfirm.name}`, `[OUT] [${context.getTrackingId()}] ${
this.createMailContentFromEmailConfirm.name
}`,
); );
return { return {
subject: 'Verify your new account', subject: 'Verify your new account',
@ -62,15 +68,23 @@ export class SendGridService {
* Email認証用のメールコンテンツを作成する() * Email認証用のメールコンテンツを作成する()
* @param accountId ID * @param accountId ID
* @param userId ID * @param userId ID
* @param email * @param email
* @returns * @returns
*/ */
//TODO [Task2163] 中身が管理ユーザ向けのままなので、修正の必要あり //TODO [Task2163] 中身が管理ユーザ向けのままなので、修正の必要あり
async createMailContentFromEmailConfirmForNormalUser( async createMailContentFromEmailConfirmForNormalUser(
context: Context,
accountId: number, accountId: number,
userId: number, userId: number,
email: string, email: string,
): Promise<{ subject: string; text: string; html: string }> { ): Promise<{ subject: string; text: string; html: string }> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${
this.createMailContentFromEmailConfirmForNormalUser.name
} | params: { ` +
`accountId: ${accountId},` +
`userId: ${userId} };`,
);
const privateKey = getPrivateKey(this.configService); const privateKey = getPrivateKey(this.configService);
const token = sign<{ accountId: number; userId: number; email: string }>( const token = sign<{ accountId: number; userId: number; email: string }>(
@ -109,7 +123,7 @@ export class SendGridService {
text: string, text: string,
html: string, html: string,
): Promise<void> { ): Promise<void> {
this.logger.log(`[IN] [${context.trackingId}] ${this.sendMail.name}`); this.logger.log(`[IN] [${context.getTrackingId()}] ${this.sendMail.name}`);
try { try {
const res = await sendgrid const res = await sendgrid
.send({ .send({
@ -125,13 +139,17 @@ export class SendGridService {
}) })
.then((v) => v[0]); .then((v) => v[0]);
this.logger.log( this.logger.log(
`status code: ${res.statusCode} body: ${JSON.stringify(res.body)}`, `[${context.getTrackingId()}] status code: ${
res.statusCode
} body: ${JSON.stringify(res.body)}`,
); );
} catch (e) { } catch (e) {
this.logger.error(e); this.logger.error(`[${context.getTrackingId()}] error=${e}`);
throw e; throw e;
} finally { } finally {
this.logger.log(`[OUT] [${context.trackingId}] ${this.sendMail.name}`); this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMail.name}`,
);
} }
} }
} }