diff --git a/dictation_server/src/gateways/adb2c/adb2c.service.ts b/dictation_server/src/gateways/adb2c/adb2c.service.ts index e7dcce6..f38f5c5 100644 --- a/dictation_server/src/gateways/adb2c/adb2c.service.ts +++ b/dictation_server/src/gateways/adb2c/adb2c.service.ts @@ -6,8 +6,9 @@ import { ConfigService } from '@nestjs/config'; import axios from 'axios'; import { Aadb2cUser, B2cMetadata, JwkSignKey } from '../../common/token'; import { AdB2cResponse, AdB2cUser } from './types/types'; +import { isPromiseRejectedResult } from './utils/utils'; import { Context } from '../../common/log'; -import { ADB2C_SIGN_IN_TYPE } from '../../constants'; +import { ADB2C_SIGN_IN_TYPE, MANUAL_RECOVERY_REQUIRED } from '../../constants'; export type ConflictError = { reason: 'email'; @@ -267,12 +268,33 @@ export class AdB2cService { ); try { - // 複数ユーザーを一括削除する方法が不明なため、rate limitの懸念があるのを承知のうえ単一削除の繰り返しで実装 - // TODO 一括削除する方法が判明したら修正する - // https://learn.microsoft.com/en-us/graph/api/user-delete?view=graph-rest-1.0&tabs=javascript#example - externalIds.map( - async (x) => await this.graphClient.api(`users/${x}`).delete(), + // 複数ユーザーを一括削除する方法がないため、1人ずつで削除を行う(rate limitに大きな影響がないこと確認済) + const results = await Promise.allSettled( + externalIds.map( + async (x) => await this.graphClient.api(`users/${x}`).delete(), + ), ); + + // 失敗したプロミスを抽出 + const failedPromises = results.filter( + (result) => result.status === 'rejected', + ); + + // 失敗したプロミスのエラーをログに記録 + failedPromises.forEach((result, index) => { + const failedId = externalIds[index]; + if (isPromiseRejectedResult(result)) { + const error = result.reason.toString(); + + this.logger.error( + `${MANUAL_RECOVERY_REQUIRED}[${context.trackingId}] Failed to delete user ${failedId}: ${error}`, + ); + } else { + this.logger.error( + `${MANUAL_RECOVERY_REQUIRED}[${context.trackingId}] Failed to delete user ${failedId}`, + ); + } + }); } catch (e) { this.logger.error(`error=${e}`); throw e; diff --git a/dictation_server/src/gateways/adb2c/utils/utils.ts b/dictation_server/src/gateways/adb2c/utils/utils.ts new file mode 100644 index 0000000..1d3b4a9 --- /dev/null +++ b/dictation_server/src/gateways/adb2c/utils/utils.ts @@ -0,0 +1,10 @@ +export const isPromiseRejectedResult = ( + data: unknown, +): data is PromiseRejectedResult => { + return ( + data !== null && + typeof data === 'object' && + 'status' in data && + 'reason' in data + ); +};