strapi-plugin-magic-mail 2.3.0 → 2.3.1

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.
@@ -606,7 +606,7 @@ function requireAccounts() {
606
606
  if (!testEmail) {
607
607
  ctx.throw(400, "testEmail is required");
608
608
  }
609
- strapi.log.info("[magic-mail] 🧪 Testing Strapi Email Service integration...");
609
+ strapi.log.info("[magic-mail] [TEST] Testing Strapi Email Service integration...");
610
610
  strapi.log.info('[magic-mail] [EMAIL] Calling strapi.plugin("email").service("email").send()');
611
611
  if (accountName) {
612
612
  strapi.log.info(`[magic-mail] [FORCE] Forcing specific account: ${accountName}`);
@@ -2322,7 +2322,7 @@ function requireTest() {
2322
2322
  async testRelations(ctx) {
2323
2323
  try {
2324
2324
  console.log("\n" + "=".repeat(60));
2325
- console.log("🧪 TEST: Template Version Relations (Document Service API)");
2325
+ console.log("[TEST] Template - Version Relations (Document Service API)");
2326
2326
  console.log("=".repeat(60));
2327
2327
  let test1Success = false;
2328
2328
  let test1ReverseSuccess = false;
@@ -2490,7 +2490,7 @@ function requireTest() {
2490
2490
  } else {
2491
2491
  console.log(` [ERROR] FEHLER: Falsche Anzahl Versionen!`);
2492
2492
  }
2493
- console.log("\n🧹 Cleanup Test 3...");
2493
+ console.log("\n[CLEANUP] Cleanup Test 3...");
2494
2494
  if (afterSecondUpdate.versions) {
2495
2495
  for (const version3 of afterSecondUpdate.versions) {
2496
2496
  await strapi.documents(EMAIL_TEMPLATE_VERSION_UID).delete({ documentId: version3.documentId });
@@ -2508,7 +2508,7 @@ function requireTest() {
2508
2508
  console.log(`
2509
2509
  [INFO] Template: "${finalTemplate.name}" (documentId: ${finalTemplate.documentId})`);
2510
2510
  console.log(` Anzahl Versionen: ${finalTemplate.versions?.length || 0}`);
2511
- console.log("\n🧹 Aufräumen...");
2511
+ console.log("\n[CLEANUP] Aufraumen...");
2512
2512
  await strapi.documents(EMAIL_TEMPLATE_VERSION_UID).delete({ documentId: version1.documentId });
2513
2513
  await strapi.documents(EMAIL_TEMPLATE_VERSION_UID).delete({ documentId: version2.documentId });
2514
2514
  await strapi.documents(EMAIL_TEMPLATE_UID).delete({ documentId: testTemplate.documentId });
@@ -3491,7 +3491,7 @@ function requireEncryption() {
3491
3491
  let encrypted = cipher.update(jsonData, "utf8", "hex");
3492
3492
  encrypted += cipher.final("hex");
3493
3493
  const authTag = cipher.getAuthTag();
3494
- return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`;
3494
+ return { encrypted: `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}` };
3495
3495
  } catch (err) {
3496
3496
  console.error("[magic-mail] Encryption failed:", err);
3497
3497
  throw new Error("Failed to encrypt credentials");
@@ -3501,7 +3501,8 @@ function requireEncryption() {
3501
3501
  if (!encryptedData) return null;
3502
3502
  try {
3503
3503
  const key = getEncryptionKey();
3504
- const parts = encryptedData.split(":");
3504
+ const encryptedString = typeof encryptedData === "object" && encryptedData.encrypted ? encryptedData.encrypted : encryptedData;
3505
+ const parts = encryptedString.split(":");
3505
3506
  if (parts.length !== 3) {
3506
3507
  throw new Error("Invalid encrypted data format");
3507
3508
  }
@@ -3575,7 +3576,7 @@ function requireEmailRouter() {
3575
3576
  let templateRecord = null;
3576
3577
  if (emailData.templateReferenceId) {
3577
3578
  resolvedTemplateReferenceId = String(emailData.templateReferenceId).trim();
3578
- strapi2.log.info(`[magic-mail] 🧩 Using provided templateReferenceId="${resolvedTemplateReferenceId}"`);
3579
+ strapi2.log.info(`[magic-mail] [TEMPLATE] Using provided templateReferenceId="${resolvedTemplateReferenceId}"`);
3579
3580
  }
3580
3581
  if (!resolvedTemplateReferenceId && templateId) {
3581
3582
  const numericTemplateId = Number(templateId);
@@ -3595,7 +3596,7 @@ function requireEmailRouter() {
3595
3596
  );
3596
3597
  } else {
3597
3598
  resolvedTemplateReferenceId = String(templateId).trim();
3598
- strapi2.log.info(`[magic-mail] 🧩 Treating templateId value as referenceId="${resolvedTemplateReferenceId}"`);
3599
+ strapi2.log.info(`[magic-mail] [TEMPLATE] Treating templateId value as referenceId="${resolvedTemplateReferenceId}"`);
3599
3600
  }
3600
3601
  }
3601
3602
  if (!resolvedTemplateReferenceId) {
@@ -3708,7 +3709,7 @@ function requireEmailRouter() {
3708
3709
  }
3709
3710
  const canSend = await this.checkRateLimits(account);
3710
3711
  if (!canSend) {
3711
- const fallbackAccount = await this.selectAccount(type, priority, [account.id], emailData);
3712
+ const fallbackAccount = await this.selectAccount(type, priority, [account.documentId], emailData);
3712
3713
  if (fallbackAccount) {
3713
3714
  strapi2.log.info(`[magic-mail] Rate limit hit on ${account.name}, using fallback: ${fallbackAccount.name}`);
3714
3715
  return await this.sendViaAccount(fallbackAccount, emailData);
@@ -3776,13 +3777,19 @@ ${text || "Email delivery failed. Please check your email settings."}`;
3776
3777
  },
3777
3778
  /**
3778
3779
  * Select best account based on rules
3780
+ * @param {string} type - Email type (transactional, marketing, notification)
3781
+ * @param {string} priority - Priority level (high, normal, low)
3782
+ * @param {Array<string>} excludeDocumentIds - Array of documentIds to exclude from selection
3783
+ * @param {Object} emailData - Email data for routing rule matching
3784
+ * @returns {Promise<Object|null>} Selected account or null
3779
3785
  */
3780
- async selectAccount(type, priority, excludeIds = [], emailData = {}) {
3786
+ async selectAccount(type, priority, excludeDocumentIds = [], emailData = {}) {
3787
+ const filters = { isActive: true };
3788
+ if (excludeDocumentIds.length > 0) {
3789
+ filters.documentId = { $notIn: excludeDocumentIds };
3790
+ }
3781
3791
  const accounts2 = await strapi2.documents("plugin::magic-mail.email-account").findMany({
3782
- filters: {
3783
- isActive: true,
3784
- id: { $notIn: excludeIds }
3785
- },
3792
+ filters,
3786
3793
  sort: [{ priority: "desc" }]
3787
3794
  });
3788
3795
  if (!accounts2 || accounts2.length === 0) {
@@ -5537,7 +5544,7 @@ function requireOauth() {
5537
5544
  });
5538
5545
  return oauth;
5539
5546
  }
5540
- const version = "2.4.0";
5547
+ const version = "2.3.0";
5541
5548
  const require$$2 = {
5542
5549
  version
5543
5550
  };
@@ -6705,7 +6712,7 @@ function requireAnalytics() {
6705
6712
  const randomToken = crypto.randomBytes(8).toString("hex");
6706
6713
  const trackingUrl = `${baseUrl}/api/magic-mail/track/open/${emailId}/${recipientHash}?r=${randomToken}`;
6707
6714
  const trackingPixel = `<img src="${trackingUrl}" width="1" height="1" style="display:none;" alt="" />`;
6708
- strapi2.log.info(`[magic-mail] 📍 Tracking pixel URL: ${trackingUrl}`);
6715
+ strapi2.log.info(`[magic-mail] [PIXEL] Tracking pixel URL: ${trackingUrl}`);
6709
6716
  if (html.includes("</body>")) {
6710
6717
  return html.replace("</body>", `${trackingPixel}</body>`);
6711
6718
  }
@@ -596,7 +596,7 @@ function requireAccounts() {
596
596
  if (!testEmail) {
597
597
  ctx.throw(400, "testEmail is required");
598
598
  }
599
- strapi.log.info("[magic-mail] 🧪 Testing Strapi Email Service integration...");
599
+ strapi.log.info("[magic-mail] [TEST] Testing Strapi Email Service integration...");
600
600
  strapi.log.info('[magic-mail] [EMAIL] Calling strapi.plugin("email").service("email").send()');
601
601
  if (accountName) {
602
602
  strapi.log.info(`[magic-mail] [FORCE] Forcing specific account: ${accountName}`);
@@ -2312,7 +2312,7 @@ function requireTest() {
2312
2312
  async testRelations(ctx) {
2313
2313
  try {
2314
2314
  console.log("\n" + "=".repeat(60));
2315
- console.log("🧪 TEST: Template Version Relations (Document Service API)");
2315
+ console.log("[TEST] Template - Version Relations (Document Service API)");
2316
2316
  console.log("=".repeat(60));
2317
2317
  let test1Success = false;
2318
2318
  let test1ReverseSuccess = false;
@@ -2480,7 +2480,7 @@ function requireTest() {
2480
2480
  } else {
2481
2481
  console.log(` [ERROR] FEHLER: Falsche Anzahl Versionen!`);
2482
2482
  }
2483
- console.log("\n🧹 Cleanup Test 3...");
2483
+ console.log("\n[CLEANUP] Cleanup Test 3...");
2484
2484
  if (afterSecondUpdate.versions) {
2485
2485
  for (const version3 of afterSecondUpdate.versions) {
2486
2486
  await strapi.documents(EMAIL_TEMPLATE_VERSION_UID).delete({ documentId: version3.documentId });
@@ -2498,7 +2498,7 @@ function requireTest() {
2498
2498
  console.log(`
2499
2499
  [INFO] Template: "${finalTemplate.name}" (documentId: ${finalTemplate.documentId})`);
2500
2500
  console.log(` Anzahl Versionen: ${finalTemplate.versions?.length || 0}`);
2501
- console.log("\n🧹 Aufräumen...");
2501
+ console.log("\n[CLEANUP] Aufraumen...");
2502
2502
  await strapi.documents(EMAIL_TEMPLATE_VERSION_UID).delete({ documentId: version1.documentId });
2503
2503
  await strapi.documents(EMAIL_TEMPLATE_VERSION_UID).delete({ documentId: version2.documentId });
2504
2504
  await strapi.documents(EMAIL_TEMPLATE_UID).delete({ documentId: testTemplate.documentId });
@@ -3481,7 +3481,7 @@ function requireEncryption() {
3481
3481
  let encrypted = cipher.update(jsonData, "utf8", "hex");
3482
3482
  encrypted += cipher.final("hex");
3483
3483
  const authTag = cipher.getAuthTag();
3484
- return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`;
3484
+ return { encrypted: `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}` };
3485
3485
  } catch (err) {
3486
3486
  console.error("[magic-mail] Encryption failed:", err);
3487
3487
  throw new Error("Failed to encrypt credentials");
@@ -3491,7 +3491,8 @@ function requireEncryption() {
3491
3491
  if (!encryptedData) return null;
3492
3492
  try {
3493
3493
  const key = getEncryptionKey();
3494
- const parts = encryptedData.split(":");
3494
+ const encryptedString = typeof encryptedData === "object" && encryptedData.encrypted ? encryptedData.encrypted : encryptedData;
3495
+ const parts = encryptedString.split(":");
3495
3496
  if (parts.length !== 3) {
3496
3497
  throw new Error("Invalid encrypted data format");
3497
3498
  }
@@ -3565,7 +3566,7 @@ function requireEmailRouter() {
3565
3566
  let templateRecord = null;
3566
3567
  if (emailData.templateReferenceId) {
3567
3568
  resolvedTemplateReferenceId = String(emailData.templateReferenceId).trim();
3568
- strapi2.log.info(`[magic-mail] 🧩 Using provided templateReferenceId="${resolvedTemplateReferenceId}"`);
3569
+ strapi2.log.info(`[magic-mail] [TEMPLATE] Using provided templateReferenceId="${resolvedTemplateReferenceId}"`);
3569
3570
  }
3570
3571
  if (!resolvedTemplateReferenceId && templateId) {
3571
3572
  const numericTemplateId = Number(templateId);
@@ -3585,7 +3586,7 @@ function requireEmailRouter() {
3585
3586
  );
3586
3587
  } else {
3587
3588
  resolvedTemplateReferenceId = String(templateId).trim();
3588
- strapi2.log.info(`[magic-mail] 🧩 Treating templateId value as referenceId="${resolvedTemplateReferenceId}"`);
3589
+ strapi2.log.info(`[magic-mail] [TEMPLATE] Treating templateId value as referenceId="${resolvedTemplateReferenceId}"`);
3589
3590
  }
3590
3591
  }
3591
3592
  if (!resolvedTemplateReferenceId) {
@@ -3698,7 +3699,7 @@ function requireEmailRouter() {
3698
3699
  }
3699
3700
  const canSend = await this.checkRateLimits(account);
3700
3701
  if (!canSend) {
3701
- const fallbackAccount = await this.selectAccount(type, priority, [account.id], emailData);
3702
+ const fallbackAccount = await this.selectAccount(type, priority, [account.documentId], emailData);
3702
3703
  if (fallbackAccount) {
3703
3704
  strapi2.log.info(`[magic-mail] Rate limit hit on ${account.name}, using fallback: ${fallbackAccount.name}`);
3704
3705
  return await this.sendViaAccount(fallbackAccount, emailData);
@@ -3766,13 +3767,19 @@ ${text || "Email delivery failed. Please check your email settings."}`;
3766
3767
  },
3767
3768
  /**
3768
3769
  * Select best account based on rules
3770
+ * @param {string} type - Email type (transactional, marketing, notification)
3771
+ * @param {string} priority - Priority level (high, normal, low)
3772
+ * @param {Array<string>} excludeDocumentIds - Array of documentIds to exclude from selection
3773
+ * @param {Object} emailData - Email data for routing rule matching
3774
+ * @returns {Promise<Object|null>} Selected account or null
3769
3775
  */
3770
- async selectAccount(type, priority, excludeIds = [], emailData = {}) {
3776
+ async selectAccount(type, priority, excludeDocumentIds = [], emailData = {}) {
3777
+ const filters = { isActive: true };
3778
+ if (excludeDocumentIds.length > 0) {
3779
+ filters.documentId = { $notIn: excludeDocumentIds };
3780
+ }
3771
3781
  const accounts2 = await strapi2.documents("plugin::magic-mail.email-account").findMany({
3772
- filters: {
3773
- isActive: true,
3774
- id: { $notIn: excludeIds }
3775
- },
3782
+ filters,
3776
3783
  sort: [{ priority: "desc" }]
3777
3784
  });
3778
3785
  if (!accounts2 || accounts2.length === 0) {
@@ -5527,7 +5534,7 @@ function requireOauth() {
5527
5534
  });
5528
5535
  return oauth;
5529
5536
  }
5530
- const version = "2.4.0";
5537
+ const version = "2.3.0";
5531
5538
  const require$$2 = {
5532
5539
  version
5533
5540
  };
@@ -6695,7 +6702,7 @@ function requireAnalytics() {
6695
6702
  const randomToken = crypto.randomBytes(8).toString("hex");
6696
6703
  const trackingUrl = `${baseUrl}/api/magic-mail/track/open/${emailId}/${recipientHash}?r=${randomToken}`;
6697
6704
  const trackingPixel = `<img src="${trackingUrl}" width="1" height="1" style="display:none;" alt="" />`;
6698
- strapi2.log.info(`[magic-mail] 📍 Tracking pixel URL: ${trackingUrl}`);
6705
+ strapi2.log.info(`[magic-mail] [PIXEL] Tracking pixel URL: ${trackingUrl}`);
6699
6706
  if (html.includes("</body>")) {
6700
6707
  return html.replace("</body>", `${trackingPixel}</body>`);
6701
6708
  }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.3.0",
2
+ "version": "2.3.1",
3
3
  "keywords": [
4
4
  "strapi",
5
5
  "strapi-plugin",