strapi-plugin-magic-mail 2.6.5 → 2.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/index.js +62 -10
- package/dist/server/index.mjs +62 -10
- package/package.json +1 -1
package/dist/server/index.js
CHANGED
|
@@ -4009,6 +4009,37 @@ var emailRouter$1 = ({ strapi: strapi2 }) => ({
|
|
|
4009
4009
|
if (!templateData && data) {
|
|
4010
4010
|
templateData = data;
|
|
4011
4011
|
}
|
|
4012
|
+
if (!to || typeof to === "string" && to.trim().length === 0) {
|
|
4013
|
+
throw new Error("Recipient email address (to) is required");
|
|
4014
|
+
}
|
|
4015
|
+
const normalizeAddr = (addr) => {
|
|
4016
|
+
if (!addr) return addr;
|
|
4017
|
+
if (typeof addr === "string") {
|
|
4018
|
+
if (addr.includes("<") && addr.includes(">")) {
|
|
4019
|
+
return addr.replace(/<([^>]+)>/, (_, email) => `<${email.trim().toLowerCase()}>`);
|
|
4020
|
+
}
|
|
4021
|
+
return addr.trim().toLowerCase();
|
|
4022
|
+
}
|
|
4023
|
+
return addr;
|
|
4024
|
+
};
|
|
4025
|
+
const normalizeAddrs = (val) => {
|
|
4026
|
+
if (!val) return val;
|
|
4027
|
+
if (Array.isArray(val)) {
|
|
4028
|
+
return val.map((a) => normalizeAddr(a));
|
|
4029
|
+
}
|
|
4030
|
+
if (typeof val === "string" && val.includes(",")) {
|
|
4031
|
+
return val.split(",").map((a) => normalizeAddr(a)).join(", ");
|
|
4032
|
+
}
|
|
4033
|
+
return normalizeAddr(val);
|
|
4034
|
+
};
|
|
4035
|
+
to = normalizeAddrs(to);
|
|
4036
|
+
from = normalizeAddr(from);
|
|
4037
|
+
replyTo = normalizeAddr(replyTo);
|
|
4038
|
+
emailData.to = to;
|
|
4039
|
+
emailData.from = from;
|
|
4040
|
+
emailData.replyTo = replyTo;
|
|
4041
|
+
if (emailData.cc) emailData.cc = normalizeAddrs(emailData.cc);
|
|
4042
|
+
if (emailData.bcc) emailData.bcc = normalizeAddrs(emailData.bcc);
|
|
4012
4043
|
if (skipLinkTracking) {
|
|
4013
4044
|
strapi2.log.info(`[magic-mail] [SKIP-TRACK] skipLinkTracking=true received for email to: ${to}`);
|
|
4014
4045
|
}
|
|
@@ -4275,7 +4306,7 @@ ${text || "Email delivery failed. Please check your email settings."}`;
|
|
|
4275
4306
|
break;
|
|
4276
4307
|
}
|
|
4277
4308
|
if (matches) {
|
|
4278
|
-
const account = accounts2.find((a) => a.name === rule.accountName);
|
|
4309
|
+
const account = accounts2.find((a) => a.name.toLowerCase() === rule.accountName.toLowerCase());
|
|
4279
4310
|
if (account) {
|
|
4280
4311
|
strapi2.log.info(`[magic-mail] [ROUTE] Routing rule matched: ${rule.name} -> ${account.name}`);
|
|
4281
4312
|
return account;
|
|
@@ -5073,8 +5104,28 @@ ${text || "Email delivery failed. Please check your email settings."}`;
|
|
|
5073
5104
|
validateEmailSecurity(emailData) {
|
|
5074
5105
|
const { to, subject, html, text } = emailData;
|
|
5075
5106
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
5076
|
-
|
|
5077
|
-
|
|
5107
|
+
const extractEmail = (addr) => {
|
|
5108
|
+
if (!addr || typeof addr !== "string") return "";
|
|
5109
|
+
if (addr.includes("<")) {
|
|
5110
|
+
const match = addr.match(/<([^>]+)>/);
|
|
5111
|
+
return match ? match[1].trim() : addr.trim();
|
|
5112
|
+
}
|
|
5113
|
+
return addr.trim();
|
|
5114
|
+
};
|
|
5115
|
+
const validateAddr = (addr) => emailRegex.test(extractEmail(addr));
|
|
5116
|
+
if (Array.isArray(to)) {
|
|
5117
|
+
for (const addr of to) {
|
|
5118
|
+
if (!validateAddr(addr)) {
|
|
5119
|
+
throw new Error(`Invalid recipient email format: ${addr}`);
|
|
5120
|
+
}
|
|
5121
|
+
}
|
|
5122
|
+
} else if (typeof to === "string") {
|
|
5123
|
+
const addresses = to.includes(",") ? to.split(",") : [to];
|
|
5124
|
+
for (const addr of addresses) {
|
|
5125
|
+
if (!validateAddr(addr.trim())) {
|
|
5126
|
+
throw new Error(`Invalid recipient email format: ${addr.trim()}`);
|
|
5127
|
+
}
|
|
5128
|
+
}
|
|
5078
5129
|
}
|
|
5079
5130
|
if (!subject || subject.trim().length === 0) {
|
|
5080
5131
|
throw new Error("Email subject is required for security and deliverability");
|
|
@@ -5964,10 +6015,9 @@ var oauth$1 = ({ strapi: strapi2 }) => ({
|
|
|
5964
6015
|
// OAuth app credentials
|
|
5965
6016
|
oauth: encryptedOAuth,
|
|
5966
6017
|
// OAuth tokens
|
|
5967
|
-
fromEmail: tokenData.email,
|
|
5968
|
-
// [SUCCESS] Use email from Google, not from accountDetails
|
|
6018
|
+
fromEmail: tokenData.email ? tokenData.email.trim().toLowerCase() : tokenData.email,
|
|
5969
6019
|
fromName: accountDetails.fromName || tokenData.email.split("@")[0],
|
|
5970
|
-
replyTo: accountDetails.replyTo || tokenData.email,
|
|
6020
|
+
replyTo: (accountDetails.replyTo || tokenData.email || "").trim().toLowerCase(),
|
|
5971
6021
|
isActive: true,
|
|
5972
6022
|
isPrimary: accountDetails.isPrimary || false,
|
|
5973
6023
|
priority: accountDetails.priority || 1,
|
|
@@ -5982,7 +6032,7 @@ var oauth$1 = ({ strapi: strapi2 }) => ({
|
|
|
5982
6032
|
return account;
|
|
5983
6033
|
}
|
|
5984
6034
|
});
|
|
5985
|
-
const version = "2.6.
|
|
6035
|
+
const version = "2.6.6";
|
|
5986
6036
|
const require$$2 = {
|
|
5987
6037
|
version
|
|
5988
6038
|
};
|
|
@@ -6992,18 +7042,20 @@ var analytics$1 = ({ strapi: strapi2 }) => ({
|
|
|
6992
7042
|
* Generate secure hash for recipient (for tracking URLs)
|
|
6993
7043
|
*/
|
|
6994
7044
|
generateRecipientHash(emailId, recipient) {
|
|
6995
|
-
|
|
7045
|
+
const normalized = (recipient || "").trim().toLowerCase();
|
|
7046
|
+
return crypto.createHash("sha256").update(`${emailId}-${normalized}-${process.env.APP_KEYS || "secret"}`).digest("hex").substring(0, 16);
|
|
6996
7047
|
},
|
|
6997
7048
|
/**
|
|
6998
7049
|
* Create email log entry
|
|
6999
7050
|
*/
|
|
7000
7051
|
async createEmailLog(data) {
|
|
7001
7052
|
const emailId = this.generateEmailId();
|
|
7053
|
+
const normalizedRecipient = data.to ? String(data.to).trim().toLowerCase() : data.to;
|
|
7002
7054
|
const logEntry = await strapi2.documents(EMAIL_LOG_UID).create({
|
|
7003
7055
|
data: {
|
|
7004
7056
|
emailId,
|
|
7005
7057
|
user: data.userId || null,
|
|
7006
|
-
recipient:
|
|
7058
|
+
recipient: normalizedRecipient,
|
|
7007
7059
|
recipientName: data.recipientName || null,
|
|
7008
7060
|
subject: data.subject,
|
|
7009
7061
|
templateId: data.templateId || null,
|
|
@@ -7868,7 +7920,7 @@ var pluginSettings$1 = ({ strapi: strapi2 }) => ({
|
|
|
7868
7920
|
...data,
|
|
7869
7921
|
trackingBaseUrl: data.trackingBaseUrl?.trim() || null,
|
|
7870
7922
|
defaultFromName: data.defaultFromName?.trim() || null,
|
|
7871
|
-
defaultFromEmail: data.defaultFromEmail?.trim() || null,
|
|
7923
|
+
defaultFromEmail: data.defaultFromEmail?.trim()?.toLowerCase() || null,
|
|
7872
7924
|
unsubscribeUrl: data.unsubscribeUrl?.trim() || null
|
|
7873
7925
|
};
|
|
7874
7926
|
let settings = await strapi2.documents(SETTINGS_UID).findFirst({});
|
package/dist/server/index.mjs
CHANGED
|
@@ -3999,6 +3999,37 @@ var emailRouter$1 = ({ strapi: strapi2 }) => ({
|
|
|
3999
3999
|
if (!templateData && data) {
|
|
4000
4000
|
templateData = data;
|
|
4001
4001
|
}
|
|
4002
|
+
if (!to || typeof to === "string" && to.trim().length === 0) {
|
|
4003
|
+
throw new Error("Recipient email address (to) is required");
|
|
4004
|
+
}
|
|
4005
|
+
const normalizeAddr = (addr) => {
|
|
4006
|
+
if (!addr) return addr;
|
|
4007
|
+
if (typeof addr === "string") {
|
|
4008
|
+
if (addr.includes("<") && addr.includes(">")) {
|
|
4009
|
+
return addr.replace(/<([^>]+)>/, (_, email) => `<${email.trim().toLowerCase()}>`);
|
|
4010
|
+
}
|
|
4011
|
+
return addr.trim().toLowerCase();
|
|
4012
|
+
}
|
|
4013
|
+
return addr;
|
|
4014
|
+
};
|
|
4015
|
+
const normalizeAddrs = (val) => {
|
|
4016
|
+
if (!val) return val;
|
|
4017
|
+
if (Array.isArray(val)) {
|
|
4018
|
+
return val.map((a) => normalizeAddr(a));
|
|
4019
|
+
}
|
|
4020
|
+
if (typeof val === "string" && val.includes(",")) {
|
|
4021
|
+
return val.split(",").map((a) => normalizeAddr(a)).join(", ");
|
|
4022
|
+
}
|
|
4023
|
+
return normalizeAddr(val);
|
|
4024
|
+
};
|
|
4025
|
+
to = normalizeAddrs(to);
|
|
4026
|
+
from = normalizeAddr(from);
|
|
4027
|
+
replyTo = normalizeAddr(replyTo);
|
|
4028
|
+
emailData.to = to;
|
|
4029
|
+
emailData.from = from;
|
|
4030
|
+
emailData.replyTo = replyTo;
|
|
4031
|
+
if (emailData.cc) emailData.cc = normalizeAddrs(emailData.cc);
|
|
4032
|
+
if (emailData.bcc) emailData.bcc = normalizeAddrs(emailData.bcc);
|
|
4002
4033
|
if (skipLinkTracking) {
|
|
4003
4034
|
strapi2.log.info(`[magic-mail] [SKIP-TRACK] skipLinkTracking=true received for email to: ${to}`);
|
|
4004
4035
|
}
|
|
@@ -4265,7 +4296,7 @@ ${text || "Email delivery failed. Please check your email settings."}`;
|
|
|
4265
4296
|
break;
|
|
4266
4297
|
}
|
|
4267
4298
|
if (matches) {
|
|
4268
|
-
const account = accounts2.find((a) => a.name === rule.accountName);
|
|
4299
|
+
const account = accounts2.find((a) => a.name.toLowerCase() === rule.accountName.toLowerCase());
|
|
4269
4300
|
if (account) {
|
|
4270
4301
|
strapi2.log.info(`[magic-mail] [ROUTE] Routing rule matched: ${rule.name} -> ${account.name}`);
|
|
4271
4302
|
return account;
|
|
@@ -5063,8 +5094,28 @@ ${text || "Email delivery failed. Please check your email settings."}`;
|
|
|
5063
5094
|
validateEmailSecurity(emailData) {
|
|
5064
5095
|
const { to, subject, html, text } = emailData;
|
|
5065
5096
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
5066
|
-
|
|
5067
|
-
|
|
5097
|
+
const extractEmail = (addr) => {
|
|
5098
|
+
if (!addr || typeof addr !== "string") return "";
|
|
5099
|
+
if (addr.includes("<")) {
|
|
5100
|
+
const match = addr.match(/<([^>]+)>/);
|
|
5101
|
+
return match ? match[1].trim() : addr.trim();
|
|
5102
|
+
}
|
|
5103
|
+
return addr.trim();
|
|
5104
|
+
};
|
|
5105
|
+
const validateAddr = (addr) => emailRegex.test(extractEmail(addr));
|
|
5106
|
+
if (Array.isArray(to)) {
|
|
5107
|
+
for (const addr of to) {
|
|
5108
|
+
if (!validateAddr(addr)) {
|
|
5109
|
+
throw new Error(`Invalid recipient email format: ${addr}`);
|
|
5110
|
+
}
|
|
5111
|
+
}
|
|
5112
|
+
} else if (typeof to === "string") {
|
|
5113
|
+
const addresses = to.includes(",") ? to.split(",") : [to];
|
|
5114
|
+
for (const addr of addresses) {
|
|
5115
|
+
if (!validateAddr(addr.trim())) {
|
|
5116
|
+
throw new Error(`Invalid recipient email format: ${addr.trim()}`);
|
|
5117
|
+
}
|
|
5118
|
+
}
|
|
5068
5119
|
}
|
|
5069
5120
|
if (!subject || subject.trim().length === 0) {
|
|
5070
5121
|
throw new Error("Email subject is required for security and deliverability");
|
|
@@ -5954,10 +6005,9 @@ var oauth$1 = ({ strapi: strapi2 }) => ({
|
|
|
5954
6005
|
// OAuth app credentials
|
|
5955
6006
|
oauth: encryptedOAuth,
|
|
5956
6007
|
// OAuth tokens
|
|
5957
|
-
fromEmail: tokenData.email,
|
|
5958
|
-
// [SUCCESS] Use email from Google, not from accountDetails
|
|
6008
|
+
fromEmail: tokenData.email ? tokenData.email.trim().toLowerCase() : tokenData.email,
|
|
5959
6009
|
fromName: accountDetails.fromName || tokenData.email.split("@")[0],
|
|
5960
|
-
replyTo: accountDetails.replyTo || tokenData.email,
|
|
6010
|
+
replyTo: (accountDetails.replyTo || tokenData.email || "").trim().toLowerCase(),
|
|
5961
6011
|
isActive: true,
|
|
5962
6012
|
isPrimary: accountDetails.isPrimary || false,
|
|
5963
6013
|
priority: accountDetails.priority || 1,
|
|
@@ -5972,7 +6022,7 @@ var oauth$1 = ({ strapi: strapi2 }) => ({
|
|
|
5972
6022
|
return account;
|
|
5973
6023
|
}
|
|
5974
6024
|
});
|
|
5975
|
-
const version = "2.6.
|
|
6025
|
+
const version = "2.6.6";
|
|
5976
6026
|
const require$$2 = {
|
|
5977
6027
|
version
|
|
5978
6028
|
};
|
|
@@ -6982,18 +7032,20 @@ var analytics$1 = ({ strapi: strapi2 }) => ({
|
|
|
6982
7032
|
* Generate secure hash for recipient (for tracking URLs)
|
|
6983
7033
|
*/
|
|
6984
7034
|
generateRecipientHash(emailId, recipient) {
|
|
6985
|
-
|
|
7035
|
+
const normalized = (recipient || "").trim().toLowerCase();
|
|
7036
|
+
return crypto.createHash("sha256").update(`${emailId}-${normalized}-${process.env.APP_KEYS || "secret"}`).digest("hex").substring(0, 16);
|
|
6986
7037
|
},
|
|
6987
7038
|
/**
|
|
6988
7039
|
* Create email log entry
|
|
6989
7040
|
*/
|
|
6990
7041
|
async createEmailLog(data) {
|
|
6991
7042
|
const emailId = this.generateEmailId();
|
|
7043
|
+
const normalizedRecipient = data.to ? String(data.to).trim().toLowerCase() : data.to;
|
|
6992
7044
|
const logEntry = await strapi2.documents(EMAIL_LOG_UID).create({
|
|
6993
7045
|
data: {
|
|
6994
7046
|
emailId,
|
|
6995
7047
|
user: data.userId || null,
|
|
6996
|
-
recipient:
|
|
7048
|
+
recipient: normalizedRecipient,
|
|
6997
7049
|
recipientName: data.recipientName || null,
|
|
6998
7050
|
subject: data.subject,
|
|
6999
7051
|
templateId: data.templateId || null,
|
|
@@ -7858,7 +7910,7 @@ var pluginSettings$1 = ({ strapi: strapi2 }) => ({
|
|
|
7858
7910
|
...data,
|
|
7859
7911
|
trackingBaseUrl: data.trackingBaseUrl?.trim() || null,
|
|
7860
7912
|
defaultFromName: data.defaultFromName?.trim() || null,
|
|
7861
|
-
defaultFromEmail: data.defaultFromEmail?.trim() || null,
|
|
7913
|
+
defaultFromEmail: data.defaultFromEmail?.trim()?.toLowerCase() || null,
|
|
7862
7914
|
unsubscribeUrl: data.unsubscribeUrl?.trim() || null
|
|
7863
7915
|
};
|
|
7864
7916
|
let settings = await strapi2.documents(SETTINGS_UID).findFirst({});
|
package/package.json
CHANGED