Merged PR 653: ユーザー情報変更完了通知 [U-115] の実装

## 概要
[Task3311: ユーザー情報変更完了通知 [U-115] の実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/3311)

- ユーザー情報変更時のメール通知を実装しました。

## レビューポイント
- メールの送信先に不自然な点はないでしょうか?

## UIの変更
- なし

## 動作確認状況
- ローカルで確認
This commit is contained in:
makabe.t 2023-12-22 08:39:11 +00:00
parent 2f2e401ae5
commit f455cd6262
5 changed files with 219 additions and 0 deletions

View File

@ -2011,6 +2011,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
@ -2070,6 +2071,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
@ -2129,6 +2131,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
@ -2188,6 +2191,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
@ -2247,6 +2251,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
@ -2306,6 +2311,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
await expect(
@ -2355,6 +2361,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
@ -2414,6 +2421,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
expect(
@ -2473,6 +2481,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
await expect(
@ -2533,6 +2542,7 @@ describe('UsersService.updateUser', () => {
});
const service = module.get<UsersService>(UsersService);
overrideSendgridService(service, {});
const context = makeContext(`uuidv4`, 'requestId');
await expect(

View File

@ -954,6 +954,51 @@ export class UsersService {
encryptionPassword,
prompt,
);
// メール送信処理
try {
const { adminEmails } = await this.getAccountInformation(
context,
accountId,
);
// 変更ユーザー情報を取得
const { external_id: userExtarnalId } =
await this.usersRepository.findUserById(context, id);
const adb2cUser = await this.adB2cService.getUser(
context,
userExtarnalId,
);
const { displayName: userName, emailAddress: userEmail } =
getUserNameAndMailAddress(adb2cUser);
if (userEmail === undefined) {
throw new Error(`userEmail is null. externalId=${extarnalId}`);
}
// プライマリ管理者を取得
const { external_id: adminExternalId } = await this.getPrimaryAdminUser(
context,
accountId,
);
const adb2cAdminUser = await this.adB2cService.getUser(
context,
adminExternalId,
);
const { displayName: primaryAdminName } =
getUserNameAndMailAddress(adb2cAdminUser);
await this.sendgridService.sendMailWithU115(
context,
userName,
userEmail,
primaryAdminName,
adminEmails,
);
} catch (e) {
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
// メール送信に関する例外はログだけ出して握りつぶす
}
} catch (e) {
this.logger.error(`[${context.getTrackingId()}] error=${e}`);
if (e instanceof Error) {
@ -1295,4 +1340,29 @@ export class UsersService {
adminEmails: adminEmails,
};
}
/**
*
* @param context
* @param accountId
* @returns primary admin user
*/
private async getPrimaryAdminUser(
context: Context,
accountId: number,
): Promise<EntityUser> {
const accountInfo = await this.accountsRepository.findAccountById(
context,
accountId,
);
if (!accountInfo || !accountInfo.primary_admin_user_id) {
throw new Error(`account or primary admin not found. id=${accountId}`);
}
const primaryAdmin = await this.usersRepository.findUserById(
context,
accountInfo.primary_admin_user_id,
);
return primaryAdmin;
}
}

View File

@ -50,6 +50,8 @@ export class SendGridService {
private readonly templateU112NoParentText: string;
private readonly templateU114Html: string;
private readonly templateU114Text: string;
private readonly templateU115Html: string;
private readonly templateU115Text: string;
private readonly templateU117Html: string;
private readonly templateU117Text: string;
@ -163,6 +165,14 @@ export class SendGridService {
path.resolve(__dirname, `../../templates/template_U_114.txt`),
'utf-8',
);
this.templateU115Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_115.html`),
'utf-8',
);
this.templateU115Text = readFileSync(
path.resolve(__dirname, `../../templates/template_U_115.txt`),
'utf-8',
);
this.templateU117Html = readFileSync(
path.resolve(__dirname, `../../templates/template_U_117.html`),
@ -766,6 +776,56 @@ export class SendGridService {
}
}
/**
* U-115使
* @param context
* @param userName
* @param userMail
* @param primaryAdminName (primary)
* @param adminMails (primary/secondary)
* @returns mail with u115
*/
async sendMailWithU115(
context: Context,
userName: string,
userMail: string,
primaryAdminName: string,
adminMails: string[],
): Promise<void> {
this.logger.log(
`[IN] [${context.getTrackingId()}] ${this.sendMailWithU115.name}`,
);
try {
const subject = 'Edit User Notification [U-115]';
// メールの本文を作成する
const html = this.templateU115Html
.replaceAll(USER_NAME, userName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName);
const text = this.templateU115Text
.replaceAll(USER_NAME, userName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName);
// 管理者ユーザーの情報を変更した場合にはTOに管理者のメールアドレスを設定するので、CCには管理者のメールアドレスを設定しない
const ccAdminMails = adminMails.filter((x) => x !== userMail);
// メールを送信する
this.sendMail(
context,
[userMail],
ccAdminMails,
this.mailFrom,
subject,
text,
html,
);
} finally {
this.logger.log(
`[OUT] [${context.getTrackingId()}] ${this.sendMailWithU115.name}`,
);
}
}
/**
* U-117使
* @param context

View File

@ -0,0 +1,53 @@
<html>
<head>
<title>Edit User Notification [U-115]</title>
</head>
<body>
<div>
<h3>&lt;English&gt;</h3>
<p>Dear $USER_NAME$,</p>
<p>
Your user information has been edited. Please contact
$PRIMARY_ADMIN_NAME$, if you have any questions concerning your edited
user information.
</p>
<p>
If you have received this e-mail in error, please delete this e-mail
from your system.<br />
This is an automatically generated e-mail and this mailbox is not
monitored. Please do not reply.
</p>
</div>
<div>
<h3>&lt;Deutsch&gt;</h3>
<p>Sehr geehrte(r) $USER_NAME$,</p>
<p>
Ihre Benutzerinformationen wurden bearbeitet. Bitte wenden Sie sich an
$PRIMARY_ADMIN_NAME$ wenn Sie Fragen zu Ihren bearbeiteten
Benutzerinformationen haben.
</p>
<p>
Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie
diese E-Mail bitte aus Ihrem System.<br />
Dies ist eine automatisch generierte E-Mail und dieses Postfach wird
nicht überwacht. Bitte nicht antworten.
</p>
</div>
<div>
<h3>&lt;Français&gt;</h3>
<p>Chère/Cher $USER_NAME$,</p>
<p>
Vos informations utilisateur ont été modifiées. Veuillez contacter
$PRIMARY_ADMIN_NAME$ si vous avez des questions concernant vos
informations utilisateur modifiées.
</p>
<p>
Si vous avez reçu cet e-mail par erreur, veuillez supprimer cet e-mail
de votre système.<br />
Il s'agit d'un e-mail généré automatiquement et cette boîte aux lettres
n'est pas surveillée. Merci de ne pas répondre.
</p>
</div>
</body>
</html>

View File

@ -0,0 +1,26 @@
<English>
Dear $USER_NAME$,
Your user information has been edited. Please contact $PRIMARY_ADMIN_NAME$, if you have any questions concerning your edited user information.
If you have received this e-mail in error, please delete this e-mail from your system.
This is an automatically generated e-mail and this mailbox is not monitored. Please do not reply.
<Deutsch>
Sehr geehrte(r) $USER_NAME$,
Ihre Benutzerinformationen wurden bearbeitet. Bitte wenden Sie sich an $PRIMARY_ADMIN_NAME$ wenn Sie Fragen zu Ihren bearbeiteten Benutzerinformationen haben.
Wenn Sie diese E-Mail fälschlicherweise erhalten haben, löschen Sie diese E-Mail bitte aus Ihrem System.
Dies ist eine automatisch generierte E-Mail und dieses Postfach wird nicht überwacht. Bitte nicht antworten.
<Français>
Chère/Cher $USER_NAME$,
Vos informations utilisateur ont été modifiées. Veuillez contacter $PRIMARY_ADMIN_NAME$ si vous avez des questions concernant vos informations utilisateur modifiées.
Si vous avez reçu cet e-mail par erreur, veuillez supprimer cet e-mail de votre système.
Il s'agit d'un e-mail généré automatiquement et cette boîte aux lettres n'est pas surveillée. Merci de ne pas répondre.