特別な文字列をエスケープしてからreplaceAllするように修正

This commit is contained in:
SAITO-PC-3\saito.k 2024-12-11 14:07:39 +09:00
parent af56f8ccad
commit b71ec627d7
3 changed files with 336 additions and 216 deletions

View File

@ -636,15 +636,15 @@ export async function sendMailWithU108(
"utf-8"
);
html = templateU108NoParentHtml
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
text = templateU108NoParentText
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
} else {
const templateU108Html = readFileSync(
path.resolve(__dirname, `../templates/template_U_108.html`),
@ -655,17 +655,17 @@ export async function sendMailWithU108(
"utf-8"
);
html = templateU108Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
text = templateU108Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
}
const uniqueCustomerAdminMails = [...new Set(customerAdminMails)];
const ccMails = uniqueCustomerAdminMails.includes(userMail) ? [] : [userMail];
@ -694,3 +694,10 @@ class autoAllocationList {
accountId: number;
userIds: number[];
}
/**
* $ $$
* @param str -
* @returns
*/
export const escapeDollar = (str: string): string => str.replace(/\$/g, "$$$$");

View File

@ -379,11 +379,11 @@ export class SendGridService {
const subject = 'Account Registered Notification [U-101]';
const url = new URL(this.appDomain).href;
const html = this.templateU101Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(TOP_URL, escapeDollar(url));
const text = this.templateU101Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(TOP_URL, escapeDollar(url));
await this.sendMail(
context,
@ -434,8 +434,8 @@ export class SendGridService {
const verifyUrl = `${url}?verify=${token}`;
const subject = 'User Registration Notification [U-102]';
const html = this.templateU102Html.replaceAll(VERIFY_LINK, verifyUrl);
const text = this.templateU102Text.replaceAll(VERIFY_LINK, verifyUrl);
const html = this.templateU102Html.replaceAll(VERIFY_LINK, escapeDollar(verifyUrl));
const text = this.templateU102Text.replaceAll(VERIFY_LINK, escapeDollar(verifyUrl));
await this.sendMail(
context,
@ -481,15 +481,15 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU105Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
const text = this.templateU105Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
// メールを送信する
await this.sendMail(
@ -536,15 +536,15 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU106Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
const text = this.templateU106Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
// メールを送信する
await this.sendMail(
@ -591,15 +591,15 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU107Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY,escapeDollar(`${lisenceCount}`));
const text = this.templateU107Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY,escapeDollar(`${lisenceCount}`));
// メールを送信する
await this.sendMail(
@ -648,28 +648,28 @@ export class SendGridService {
if (dealerAccountName === null) {
html = this.templateU108NoParentHtml
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
text = this.templateU108NoParentText
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
} else {
html = this.templateU108Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
text = this.templateU108Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(USER_NAME, userName)
.replaceAll(USER_EMAIL, userMail)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(USER_EMAIL, escapeDollar(userMail))
.replaceAll(TOP_URL, escapeDollar(url));
}
const ccAddress = customerAdminMails.includes(userMail) ? [] : [userMail];
@ -719,15 +719,15 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU109Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
const text = this.templateU109Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PO_NUMBER, poNumber)
.replaceAll(LICENSE_QUANTITY, `${lisenceCount}`);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PO_NUMBER, escapeDollar(poNumber))
.replaceAll(LICENSE_QUANTITY, escapeDollar(`${lisenceCount}`));
// メールを送信する
await this.sendMail(
@ -769,14 +769,14 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU111Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
const text = this.templateU111Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
// メールを送信する
await this.sendMail(
@ -825,24 +825,24 @@ export class SendGridService {
if (dealerAccountName === null) {
// メールの本文を作成する
html = this.templateU112NoParentHtml
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
text = this.templateU112NoParentText
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
} else {
html = this.templateU112Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
text = this.templateU112Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TOP_URL, escapeDollar(url));
}
// メールを送信する
@ -884,11 +884,11 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU113Html
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TEMPORARY_PASSWORD, temporaryPassword);
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TEMPORARY_PASSWORD, escapeDollar(temporaryPassword));
const text = this.templateU113Text
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(TEMPORARY_PASSWORD, temporaryPassword);
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(TEMPORARY_PASSWORD, escapeDollar(temporaryPassword));
// メールを送信する
await this.sendMail(
@ -947,11 +947,11 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU114Html
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(VERIFY_LINK, verifyUrl);
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(VERIFY_LINK, escapeDollar(verifyUrl));
const text = this.templateU114Text
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName)
.replaceAll(VERIFY_LINK, verifyUrl);
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName))
.replaceAll(VERIFY_LINK, escapeDollar(verifyUrl));
// メールを送信する
await this.sendMail(
@ -994,11 +994,11 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU115Html
.replaceAll(USER_NAME, userName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName);
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName));
const text = this.templateU115Text
.replaceAll(USER_NAME, userName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName);
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName));
// 管理者ユーザーの情報を変更した場合にはTOに管理者のメールアドレスを設定するので、CCには管理者のメールアドレスを設定しない
const ccAdminMails = adminMails.filter((x) => x !== userMail);
@ -1044,11 +1044,11 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU116Html
.replaceAll(USER_NAME, userName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName);
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName));
const text = this.templateU116Text
.replaceAll(USER_NAME, userName)
.replaceAll(PRIMARY_ADMIN_NAME, primaryAdminName);
.replaceAll(USER_NAME, escapeDollar(userName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(primaryAdminName));
// メールを送信する
await this.sendMail(
@ -1094,15 +1094,15 @@ export class SendGridService {
// メールの本文を作成する
const html = this.templateU117Html
.replaceAll(AUTHOR_NAME, authorName)
.replaceAll(FILE_NAME, fileName)
.replaceAll(TYPIST_NAME, typistName)
.replaceAll(PRIMARY_ADMIN_NAME, adminName);
.replaceAll(AUTHOR_NAME, escapeDollar(authorName))
.replaceAll(FILE_NAME, escapeDollar(fileName))
.replaceAll(TYPIST_NAME, escapeDollar(typistName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(adminName));
const text = this.templateU117Text
.replaceAll(AUTHOR_NAME, authorName)
.replaceAll(FILE_NAME, fileName)
.replaceAll(TYPIST_NAME, typistName)
.replaceAll(PRIMARY_ADMIN_NAME, adminName);
.replaceAll(AUTHOR_NAME, escapeDollar(authorName))
.replaceAll(FILE_NAME, escapeDollar(fileName))
.replaceAll(TYPIST_NAME, escapeDollar(typistName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(adminName));
// OMDS_IS-380 Dictation Workflow完了通知 [U-117]  をTypistには送信しないようにしたいの対応のため送信先からtypistEmailを削除 2024年8月7日
const to = [authorEmail].filter((x): x is string => x !== null);
@ -1144,20 +1144,19 @@ export class SendGridService {
if (!dealerAccountName) {
html = this.templateU118NoParentHtml.replaceAll(
CUSTOMER_NAME,
customerAccountName,
CUSTOMER_NAME,escapeDollar( customerAccountName),
);
text = this.templateU118NoParentText.replaceAll(
CUSTOMER_NAME,
customerAccountName,
escapeDollar(customerAccountName),
);
} else {
html = this.templateU118Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
text = this.templateU118Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
}
// メールを送信する
@ -1205,19 +1204,19 @@ export class SendGridService {
if (!dealerAccountName) {
html = this.templateU119NoParentHtml.replaceAll(
CUSTOMER_NAME,
customerAccountName,
escapeDollar(customerAccountName),
);
text = this.templateU119NoParentText.replaceAll(
CUSTOMER_NAME,
customerAccountName,
escapeDollar(customerAccountName),
);
} else {
html = this.templateU119Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
text = this.templateU119Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
}
// メールを送信する
@ -1266,24 +1265,24 @@ export class SendGridService {
if (!dealerAccountName) {
html = this.templateU120NoParentHtml
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(REQUEST_TIME, requestTime)
.replaceAll(FILE_NAME, fileName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
text = this.templateU120NoParentText
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(REQUEST_TIME, requestTime)
.replaceAll(FILE_NAME, fileName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
} else {
html = this.templateU120Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(REQUEST_TIME, requestTime)
.replaceAll(FILE_NAME, fileName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
text = this.templateU120Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(REQUEST_TIME, requestTime)
.replaceAll(FILE_NAME, fileName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
}
// メールを送信する
@ -1332,24 +1331,24 @@ export class SendGridService {
if (!dealerAccountName) {
html = this.templateU121NoParentHtml
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(REQUEST_TIME, requestTime)
.replaceAll(FILE_NAME, fileName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
text = this.templateU121NoParentText
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(REQUEST_TIME, requestTime)
.replaceAll(FILE_NAME, fileName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
} else {
html = this.templateU121Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(REQUEST_TIME, requestTime)
.replaceAll(FILE_NAME, fileName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
text = this.templateU121Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(REQUEST_TIME, requestTime)
.replaceAll(FILE_NAME, fileName);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(REQUEST_TIME, escapeDollar(requestTime))
.replaceAll(FILE_NAME, escapeDollar(fileName));
}
// メールを送信する
@ -1432,52 +1431,52 @@ export class SendGridService {
if (!dealerAccountName) {
html = this.templateU122NoParentHtml
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(EMAIL_DUPLICATION_EN, duplicateEmailsMsgEn)
.replaceAll(EMAIL_DUPLICATION_DE, duplicateEmailsMsgDe)
.replaceAll(EMAIL_DUPLICATION_FR, duplicateEmailsMsgFr)
.replaceAll(AUTHOR_ID_DUPLICATION_EN, duplicateAuthorIdsMsgEn)
.replaceAll(AUTHOR_ID_DUPLICATION_DE, duplicateAuthorIdsMsgDe)
.replaceAll(AUTHOR_ID_DUPLICATION_FR, duplicateAuthorIdsMsgFr)
.replaceAll(UNEXPECTED_ERROR_EN, otherErrorsMsgEn)
.replaceAll(UNEXPECTED_ERROR_DE, otherErrorsMsgDe)
.replaceAll(UNEXPECTED_ERROR_FR, otherErrorsMsgFr);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(EMAIL_DUPLICATION_EN, escapeDollar(duplicateEmailsMsgEn))
.replaceAll(EMAIL_DUPLICATION_DE, escapeDollar(duplicateEmailsMsgDe))
.replaceAll(EMAIL_DUPLICATION_FR, escapeDollar(duplicateEmailsMsgFr))
.replaceAll(AUTHOR_ID_DUPLICATION_EN, escapeDollar(duplicateAuthorIdsMsgEn))
.replaceAll(AUTHOR_ID_DUPLICATION_DE, escapeDollar(duplicateAuthorIdsMsgDe))
.replaceAll(AUTHOR_ID_DUPLICATION_FR, escapeDollar(duplicateAuthorIdsMsgFr))
.replaceAll(UNEXPECTED_ERROR_EN, escapeDollar(otherErrorsMsgEn))
.replaceAll(UNEXPECTED_ERROR_DE, escapeDollar(otherErrorsMsgDe))
.replaceAll(UNEXPECTED_ERROR_FR, escapeDollar(otherErrorsMsgFr));
text = this.templateU122NoParentText
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(EMAIL_DUPLICATION_EN, duplicateEmailsMsgEn)
.replaceAll(EMAIL_DUPLICATION_DE, duplicateEmailsMsgDe)
.replaceAll(EMAIL_DUPLICATION_FR, duplicateEmailsMsgFr)
.replaceAll(AUTHOR_ID_DUPLICATION_EN, duplicateAuthorIdsMsgEn)
.replaceAll(AUTHOR_ID_DUPLICATION_DE, duplicateAuthorIdsMsgDe)
.replaceAll(AUTHOR_ID_DUPLICATION_FR, duplicateAuthorIdsMsgFr)
.replaceAll(UNEXPECTED_ERROR_EN, otherErrorsMsgEn)
.replaceAll(UNEXPECTED_ERROR_DE, otherErrorsMsgDe)
.replaceAll(UNEXPECTED_ERROR_FR, otherErrorsMsgFr);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(EMAIL_DUPLICATION_EN, escapeDollar(duplicateEmailsMsgEn))
.replaceAll(EMAIL_DUPLICATION_DE, escapeDollar(duplicateEmailsMsgDe))
.replaceAll(EMAIL_DUPLICATION_FR, escapeDollar(duplicateEmailsMsgFr))
.replaceAll(AUTHOR_ID_DUPLICATION_EN, escapeDollar(duplicateAuthorIdsMsgEn))
.replaceAll(AUTHOR_ID_DUPLICATION_DE, escapeDollar(duplicateAuthorIdsMsgDe))
.replaceAll(AUTHOR_ID_DUPLICATION_FR, escapeDollar(duplicateAuthorIdsMsgFr))
.replaceAll(UNEXPECTED_ERROR_EN, escapeDollar(otherErrorsMsgEn))
.replaceAll(UNEXPECTED_ERROR_DE, escapeDollar(otherErrorsMsgDe))
.replaceAll(UNEXPECTED_ERROR_FR, escapeDollar(otherErrorsMsgFr));
} else {
html = this.templateU122Html
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(EMAIL_DUPLICATION_EN, duplicateEmailsMsgEn)
.replaceAll(EMAIL_DUPLICATION_DE, duplicateEmailsMsgDe)
.replaceAll(EMAIL_DUPLICATION_FR, duplicateEmailsMsgFr)
.replaceAll(AUTHOR_ID_DUPLICATION_EN, duplicateAuthorIdsMsgEn)
.replaceAll(AUTHOR_ID_DUPLICATION_DE, duplicateAuthorIdsMsgDe)
.replaceAll(AUTHOR_ID_DUPLICATION_FR, duplicateAuthorIdsMsgFr)
.replaceAll(UNEXPECTED_ERROR_EN, otherErrorsMsgEn)
.replaceAll(UNEXPECTED_ERROR_DE, otherErrorsMsgDe)
.replaceAll(UNEXPECTED_ERROR_FR, otherErrorsMsgFr);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(EMAIL_DUPLICATION_EN, escapeDollar(duplicateEmailsMsgEn))
.replaceAll(EMAIL_DUPLICATION_DE, escapeDollar(duplicateEmailsMsgDe))
.replaceAll(EMAIL_DUPLICATION_FR, escapeDollar(duplicateEmailsMsgFr))
.replaceAll(AUTHOR_ID_DUPLICATION_EN, escapeDollar(duplicateAuthorIdsMsgEn))
.replaceAll(AUTHOR_ID_DUPLICATION_DE, escapeDollar(duplicateAuthorIdsMsgDe))
.replaceAll(AUTHOR_ID_DUPLICATION_FR, escapeDollar(duplicateAuthorIdsMsgFr))
.replaceAll(UNEXPECTED_ERROR_EN, escapeDollar(otherErrorsMsgEn))
.replaceAll(UNEXPECTED_ERROR_DE, escapeDollar(otherErrorsMsgDe))
.replaceAll(UNEXPECTED_ERROR_FR, escapeDollar(otherErrorsMsgFr));
text = this.templateU122Text
.replaceAll(CUSTOMER_NAME, customerAccountName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(EMAIL_DUPLICATION_EN, duplicateEmailsMsgEn)
.replaceAll(EMAIL_DUPLICATION_DE, duplicateEmailsMsgDe)
.replaceAll(EMAIL_DUPLICATION_FR, duplicateEmailsMsgFr)
.replaceAll(AUTHOR_ID_DUPLICATION_EN, duplicateAuthorIdsMsgEn)
.replaceAll(AUTHOR_ID_DUPLICATION_DE, duplicateAuthorIdsMsgDe)
.replaceAll(AUTHOR_ID_DUPLICATION_FR, duplicateAuthorIdsMsgFr)
.replaceAll(UNEXPECTED_ERROR_EN, otherErrorsMsgEn)
.replaceAll(UNEXPECTED_ERROR_DE, otherErrorsMsgDe)
.replaceAll(UNEXPECTED_ERROR_FR, otherErrorsMsgFr);
.replaceAll(CUSTOMER_NAME, escapeDollar(customerAccountName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(EMAIL_DUPLICATION_EN, escapeDollar(duplicateEmailsMsgEn))
.replaceAll(EMAIL_DUPLICATION_DE, escapeDollar(duplicateEmailsMsgDe))
.replaceAll(EMAIL_DUPLICATION_FR, escapeDollar(duplicateEmailsMsgFr))
.replaceAll(AUTHOR_ID_DUPLICATION_EN, escapeDollar(duplicateAuthorIdsMsgEn))
.replaceAll(AUTHOR_ID_DUPLICATION_DE, escapeDollar(duplicateAuthorIdsMsgDe))
.replaceAll(AUTHOR_ID_DUPLICATION_FR, escapeDollar(duplicateAuthorIdsMsgFr))
.replaceAll(UNEXPECTED_ERROR_EN, escapeDollar(otherErrorsMsgEn))
.replaceAll(UNEXPECTED_ERROR_DE, escapeDollar(otherErrorsMsgDe))
.replaceAll(UNEXPECTED_ERROR_FR, escapeDollar(otherErrorsMsgFr));
}
// メールを送信する
@ -1522,13 +1521,13 @@ export class SendGridService {
const subject = 'Partner Account Deleted Notification [U-123]';
const html = this.templateU123Html
.replaceAll(CUSTOMER_NAME, partnerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, partnerPrimaryName)
.replaceAll(DEALER_NAME, dealerAccountName);
.replaceAll(CUSTOMER_NAME, escapeDollar(partnerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(partnerPrimaryName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
const text = this.templateU123Text
.replaceAll(CUSTOMER_NAME, partnerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, partnerPrimaryName)
.replaceAll(DEALER_NAME, dealerAccountName);
.replaceAll(CUSTOMER_NAME, escapeDollar(partnerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(partnerPrimaryName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName));
// メールを送信する
await this.sendMail(
@ -1573,15 +1572,15 @@ export class SendGridService {
const url = new URL(this.appDomain).href;
const html = this.templateU124Html
.replaceAll(CUSTOMER_NAME, partnerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, partnerPrimaryName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(partnerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(partnerPrimaryName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(TOP_URL, escapeDollar(url));
const text = this.templateU124Text
.replaceAll(CUSTOMER_NAME, partnerAccountName)
.replaceAll(PRIMARY_ADMIN_NAME, partnerPrimaryName)
.replaceAll(DEALER_NAME, dealerAccountName)
.replaceAll(TOP_URL, url);
.replaceAll(CUSTOMER_NAME, escapeDollar(partnerAccountName))
.replaceAll(PRIMARY_ADMIN_NAME, escapeDollar(partnerPrimaryName))
.replaceAll(DEALER_NAME, escapeDollar(dealerAccountName))
.replaceAll(TOP_URL, escapeDollar(url));
// メールを送信する
await this.sendMail(
@ -1657,3 +1656,9 @@ export class SendGridService {
}
}
}
/**
* $ $$
* @param str -
* @returns
*/
export const escapeDollar = (str: string): string => str.replace(/\$/g, "$$$$");

View File

@ -1,5 +1,5 @@
import sendgrid from '@sendgrid/mail';
import { SendGridService } from './sendgrid.service';
import { escapeDollar, SendGridService } from './sendgrid.service';
import { Context, makeContext } from '../../common/log';
// sendgridのsend関数をモック化
@ -131,3 +131,111 @@ describe('SendGridService', () => {
).rejects.toThrow('Send failed');
});
});
describe('escapeDollar', () => {
test('文字列に$が含まれていない場合はそのまま返す', () => {
expect(escapeDollar('Hello World')).toBe('Hello World');
expect(escapeDollar('No dollars here!')).toBe('No dollars here!');
expect(escapeDollar('')).toBe('');
});
test('$が文字列の先頭にある場合、エスケープされる', () => {
expect(escapeDollar('$Hello')).toBe('$$Hello');
});
test('$が文字列の末尾にある場合、エスケープされる', () => {
expect(escapeDollar('World$')).toBe('World$$');
});
test('$が文字列の途中にある場合、エスケープされる', () => {
expect(escapeDollar('Hello$World')).toBe('Hello$$World');
});
test('複数の$が文字列に含まれる場合、すべてエスケープされる', () => {
expect(escapeDollar('$$Hello$$World$$')).toBe('$$$$Hello$$$$World$$$$');
expect(escapeDollar('$1$2$3')).toBe('$$1$$2$$3');
});
test('特殊文字と$が混在する場合でも$が正しくエスケープされる', () => {
expect(escapeDollar('Price: $5, Tax: $0.50')).toBe(
'Price: $$5, Tax: $$0.50',
);
expect(escapeDollar('Special.$World$^$')).toBe('Special.$$World$$^$$');
});
test('文字列が$だけの場合、すべてエスケープされる', () => {
expect(escapeDollar('$')).toBe('$$');
expect(escapeDollar('$$$')).toBe('$$$$$$');
});
test('すでにエスケープされた$が含まれる場合、さらにエスケープされる', () => {
expect(escapeDollar('$$Already$$Escaped$$')).toBe(
'$$$$Already$$$$Escaped$$$$',
);
});
test('空白や改行、タブ文字を含む文字列でも$がエスケープされる', () => {
expect(escapeDollar(' $Leading$Trailing$ ')).toBe(
' $$Leading$$Trailing$$ ',
);
expect(escapeDollar('Line1$\nLine2$\tEnd$')).toBe(
'Line1$$\nLine2$$\tEnd$$',
);
});
});
describe('特殊文字を含む置き換え処理でescapeDollarを使用するテスト', () => {
test('escapeDollarを使わない場合と使った場合の置き換え結果を比較', () => {
const input = 'This is $TEMPORARY_PASSWORD$ for you.';
const replacement = 'T$&AS$123$';
// escapeDollarを使わない場合
const resultWithoutEscape = input.replaceAll(
'$TEMPORARY_PASSWORD$',
replacement,
);
// escapeDollarを使った場合
const safeReplacement = escapeDollar(replacement);
const resultWithEscape = input.replaceAll(
'$TEMPORARY_PASSWORD$',
safeReplacement,
);
// 意図しない結果になることを確認
expect(resultWithoutEscape).not.toBe('This is T$&AS$123$ for you.');
expect(resultWithoutEscape).toContain('$TEMPORARY_PASSWORD$'); // 意図通りに置換されていない場合が含まれる
// escapeDollarを使用した結果が意図通りであることを確認
expect(resultWithEscape).toBe('This is T$&AS$123$ for you.');
});
test("特殊文字 ($1, $`, $') を含む場合の置換処理を確認", () => {
const input = 'This is $TEMPORARY_PASSWORD$ for you.';
const replacementWithGroup = 'Group-$1-Value';
const replacementWithBacktick = 'Backtick-$`-Value';
const replacementWithSingleQuote = "Single-$'-Value";
// $1: キャプチャグループ
const resultWithGroup = input.replaceAll(
'$TEMPORARY_PASSWORD$',
escapeDollar(replacementWithGroup),
);
expect(resultWithGroup).toBe('This is Group-$1-Value for you.');
// $`: 置換対象文字列の先頭部分
const resultWithBacktick = input.replaceAll(
'$TEMPORARY_PASSWORD$',
escapeDollar(replacementWithBacktick),
);
expect(resultWithBacktick).toBe('This is Backtick-$`-Value for you.');
// $': 置換対象文字列の後続部分
const resultWithSingleQuote = input.replaceAll(
'$TEMPORARY_PASSWORD$',
escapeDollar(replacementWithSingleQuote),
);
expect(resultWithSingleQuote).toBe("This is Single-$'-Value for you.");
});
});