strapi-plugin-magic-mail 1.0.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.
Files changed (91) hide show
  1. package/COPYRIGHT_NOTICE.txt +13 -0
  2. package/LICENSE +22 -0
  3. package/README.md +1420 -0
  4. package/admin/jsconfig.json +10 -0
  5. package/admin/src/components/AddAccountModal.jsx +1943 -0
  6. package/admin/src/components/Initializer.jsx +14 -0
  7. package/admin/src/components/LicenseGuard.jsx +475 -0
  8. package/admin/src/components/PluginIcon.jsx +5 -0
  9. package/admin/src/hooks/useAuthRefresh.js +44 -0
  10. package/admin/src/hooks/useLicense.js +158 -0
  11. package/admin/src/index.js +86 -0
  12. package/admin/src/pages/Analytics.jsx +762 -0
  13. package/admin/src/pages/App.jsx +111 -0
  14. package/admin/src/pages/EmailDesigner/EditorPage.jsx +1405 -0
  15. package/admin/src/pages/EmailDesigner/TemplateList.jsx +1807 -0
  16. package/admin/src/pages/HomePage.jsx +1233 -0
  17. package/admin/src/pages/LicensePage.jsx +424 -0
  18. package/admin/src/pages/RoutingRules.jsx +1141 -0
  19. package/admin/src/pages/Settings.jsx +603 -0
  20. package/admin/src/pluginId.js +3 -0
  21. package/admin/src/translations/de.json +71 -0
  22. package/admin/src/translations/en.json +70 -0
  23. package/admin/src/translations/es.json +71 -0
  24. package/admin/src/translations/fr.json +71 -0
  25. package/admin/src/translations/pt.json +71 -0
  26. package/admin/src/utils/fetchWithRetry.js +123 -0
  27. package/admin/src/utils/getTranslation.js +5 -0
  28. package/dist/_chunks/App-B-Gp4Vbr.js +7568 -0
  29. package/dist/_chunks/App-BymMjoGM.mjs +7543 -0
  30. package/dist/_chunks/LicensePage-Bl02myMx.mjs +342 -0
  31. package/dist/_chunks/LicensePage-CJXwPnEe.js +344 -0
  32. package/dist/_chunks/Settings-C_TmKwcz.mjs +400 -0
  33. package/dist/_chunks/Settings-zuFQ3pnn.js +402 -0
  34. package/dist/_chunks/de-CN-G9j1S.js +64 -0
  35. package/dist/_chunks/de-DS04rP54.mjs +64 -0
  36. package/dist/_chunks/en-BDc7Jk8u.js +64 -0
  37. package/dist/_chunks/en-BEFQJXvR.mjs +64 -0
  38. package/dist/_chunks/es-BpV1MIdm.js +64 -0
  39. package/dist/_chunks/es-DQHwzPpP.mjs +64 -0
  40. package/dist/_chunks/fr-BG1WfEVm.mjs +64 -0
  41. package/dist/_chunks/fr-vpziIpRp.js +64 -0
  42. package/dist/_chunks/pt-CMoGrOib.mjs +64 -0
  43. package/dist/_chunks/pt-ODpAhDNa.js +64 -0
  44. package/dist/admin/index.js +89 -0
  45. package/dist/admin/index.mjs +90 -0
  46. package/dist/server/index.js +6214 -0
  47. package/dist/server/index.mjs +6208 -0
  48. package/package.json +113 -0
  49. package/server/jsconfig.json +10 -0
  50. package/server/src/bootstrap.js +153 -0
  51. package/server/src/config/features.js +260 -0
  52. package/server/src/config/index.js +6 -0
  53. package/server/src/content-types/email-account/schema.json +93 -0
  54. package/server/src/content-types/email-event/index.js +8 -0
  55. package/server/src/content-types/email-event/schema.json +57 -0
  56. package/server/src/content-types/email-link/index.js +8 -0
  57. package/server/src/content-types/email-link/schema.json +49 -0
  58. package/server/src/content-types/email-log/index.js +8 -0
  59. package/server/src/content-types/email-log/schema.json +106 -0
  60. package/server/src/content-types/email-template/schema.json +74 -0
  61. package/server/src/content-types/email-template-version/schema.json +60 -0
  62. package/server/src/content-types/index.js +33 -0
  63. package/server/src/content-types/routing-rule/schema.json +59 -0
  64. package/server/src/controllers/accounts.js +220 -0
  65. package/server/src/controllers/analytics.js +347 -0
  66. package/server/src/controllers/controller.js +26 -0
  67. package/server/src/controllers/email-designer.js +474 -0
  68. package/server/src/controllers/index.js +21 -0
  69. package/server/src/controllers/license.js +267 -0
  70. package/server/src/controllers/oauth.js +474 -0
  71. package/server/src/controllers/routing-rules.js +122 -0
  72. package/server/src/controllers/test.js +383 -0
  73. package/server/src/destroy.js +23 -0
  74. package/server/src/index.js +25 -0
  75. package/server/src/middlewares/index.js +3 -0
  76. package/server/src/policies/index.js +3 -0
  77. package/server/src/register.js +5 -0
  78. package/server/src/routes/admin.js +469 -0
  79. package/server/src/routes/content-api.js +37 -0
  80. package/server/src/routes/index.js +9 -0
  81. package/server/src/services/account-manager.js +277 -0
  82. package/server/src/services/analytics.js +496 -0
  83. package/server/src/services/email-designer.js +870 -0
  84. package/server/src/services/email-router.js +1420 -0
  85. package/server/src/services/index.js +17 -0
  86. package/server/src/services/license-guard.js +418 -0
  87. package/server/src/services/oauth.js +515 -0
  88. package/server/src/services/service.js +7 -0
  89. package/server/src/utils/encryption.js +81 -0
  90. package/strapi-admin.js +4 -0
  91. package/strapi-server.js +4 -0
package/README.md ADDED
@@ -0,0 +1,1420 @@
1
+ # 📧 MagicMail - Email Business Suite for Strapi v5
2
+
3
+ > **Enterprise-grade multi-account email management with smart routing, OAuth 2.0 support, and complete security compliance**
4
+
5
+ [![NPM Version](https://img.shields.io/npm/v/strapi-plugin-magic-mail.svg)](https://www.npmjs.com/package/strapi-plugin-magic-mail)
6
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+ [![Strapi Version](https://img.shields.io/badge/Strapi-v5.30.1-blue.svg)](https://strapi.io)
8
+
9
+ ---
10
+
11
+ ## 🌟 Why MagicMail?
12
+
13
+ **Stop fighting with .env files and email configuration!** MagicMail brings enterprise email management to Strapi v5 with:
14
+
15
+ - ✅ **6 Email Providers** - Gmail, Microsoft 365, Yahoo, SMTP, SendGrid, Mailgun
16
+ - ✅ **OAuth 2.0 Authentication** - No passwords needed for Gmail, Microsoft, Yahoo
17
+ - ✅ **Smart Routing Rules** - Route emails by type, recipient, subject, or custom conditions
18
+ - ✅ **Automatic Failover** - Never lose an email when rate limits hit
19
+ - ✅ **Beautiful Admin UI** - Manage everything from Strapi Admin Panel
20
+ - ✅ **Zero Configuration** - No .env files, everything in the database
21
+ - ✅ **Email Designer Compatible** - Works seamlessly with strapi-plugin-email-designer-5
22
+ - ✅ **GDPR/CAN-SPAM Compliant** - Built-in List-Unsubscribe headers
23
+ - ✅ **Enterprise Security** - TLS 1.2+, DKIM, SPF, DMARC validation
24
+
25
+ ---
26
+
27
+ ## 📸 Screenshots
28
+
29
+ ### Email Accounts Dashboard
30
+ ![Email Accounts](pics/email-accounts-dashboard.png)
31
+ *Manage unlimited email accounts with live stats and real-time monitoring*
32
+
33
+ ### Routing Rules
34
+ ![Routing Rules](pics/routing-rules.png)
35
+ *Define intelligent routing rules based on email type, recipient, subject*
36
+
37
+ ### Account Setup - OAuth
38
+ ![OAuth Setup](pics/oauth-setup.png)
39
+ *Connect Gmail, Microsoft 365, or Yahoo with secure OAuth 2.0*
40
+
41
+ ---
42
+
43
+ ## 🚀 Quick Start
44
+
45
+ ### Installation
46
+
47
+ ```bash
48
+ npm install strapi-plugin-magic-mail
49
+ # or
50
+ yarn add strapi-plugin-magic-mail
51
+ ```
52
+
53
+ ### Enable Plugin
54
+
55
+ Create or update `config/plugins.ts`:
56
+
57
+ ```typescript
58
+ export default () => ({
59
+ 'magic-mail': {
60
+ enabled: true,
61
+ },
62
+ });
63
+ ```
64
+
65
+ ### Build & Start
66
+
67
+ ```bash
68
+ npm run build
69
+ npm run develop
70
+ ```
71
+
72
+ ### Add Your First Email Account
73
+
74
+ 1. Navigate to **Admin Panel → MagicMail → Email Accounts**
75
+ 2. Click **"Add Account"**
76
+ 3. Choose your provider (Gmail OAuth, SMTP, etc.)
77
+ 4. Fill in credentials
78
+ 5. Click **"Test"** to verify
79
+ 6. Done! 🎉
80
+
81
+ ---
82
+
83
+ ## 📧 Supported Email Providers
84
+
85
+ | Provider | Type | Authentication | Features |
86
+ |----------|------|----------------|----------|
87
+ | **Gmail** | OAuth 2.0 | Google OAuth | Gmail API, Attachments, Auto DKIM |
88
+ | **Microsoft 365** | OAuth 2.0 | Azure AD | Graph API, Attachments, Tenant Support |
89
+ | **Yahoo Mail** | OAuth 2.0 | Yahoo OAuth | SMTP OAuth2, Attachments |
90
+ | **SMTP** | Credentials | Username/Password | Universal, DKIM Optional, Custom Servers |
91
+ | **SendGrid** | API Key | SendGrid API | Transactional, Marketing, Templates |
92
+ | **Mailgun** | API Key | Mailgun API | Bulk Sending, Analytics |
93
+
94
+ ---
95
+
96
+ ## 💡 How to Send Emails
97
+
98
+ ### Method 1: Strapi Native Email Service (Recommended!)
99
+
100
+ MagicMail **automatically intercepts** Strapi's email service - no code changes needed!
101
+
102
+ ```javascript
103
+ // This works in ANY Strapi plugin or controller:
104
+ await strapi.plugin('email').service('email').send({
105
+ to: 'user@example.com',
106
+ subject: 'Welcome to Our Platform!',
107
+ text: 'Plain text version',
108
+ html: '<h1>Welcome!</h1><p>Thanks for signing up!</p>',
109
+ });
110
+
111
+ // ✅ MagicMail automatically:
112
+ // - Selects best account (via routing rules or priority)
113
+ // - Checks rate limits
114
+ // - Handles failover if needed
115
+ // - Logs the email
116
+ // - Updates statistics
117
+ ```
118
+
119
+ **Benefits:**
120
+ - ✅ **Zero code changes** - Existing plugins work automatically
121
+ - ✅ **Email Designer compatible** - Works with strapi-plugin-email-designer-5
122
+ - ✅ **Fallback safe** - Falls back to original email service if MagicMail fails
123
+ - ✅ **Drop-in replacement** - Just enable and go!
124
+
125
+ ### Method 2: Direct MagicMail API
126
+
127
+ For explicit control over account selection:
128
+
129
+ ```javascript
130
+ // Force a specific account
131
+ await strapi.plugin('magic-mail').service('email-router').send({
132
+ to: 'customer@example.com',
133
+ subject: 'Order Confirmation',
134
+ html: '<h1>Your Order #12345</h1>',
135
+ accountName: 'SendGrid Marketing', // Force this account
136
+ type: 'transactional',
137
+ priority: 'high',
138
+ });
139
+ ```
140
+
141
+ ### Sending with Attachments
142
+
143
+ ```javascript
144
+ await strapi.plugin('email').service('email').send({
145
+ to: 'customer@example.com',
146
+ subject: 'Invoice #12345',
147
+ html: '<h1>Invoice Attached</h1>',
148
+ attachments: [
149
+ {
150
+ filename: 'invoice.pdf',
151
+ path: './uploads/invoice-12345.pdf',
152
+ },
153
+ {
154
+ filename: 'receipt.pdf',
155
+ content: Buffer.from(pdfData),
156
+ contentType: 'application/pdf',
157
+ },
158
+ ],
159
+ });
160
+ ```
161
+
162
+ **Supported attachment formats:**
163
+ - ✅ PDF, Word, Excel, PowerPoint
164
+ - ✅ Images (PNG, JPG, GIF, WebP)
165
+ - ✅ Text files (TXT, CSV, JSON)
166
+ - ✅ Archives (ZIP, RAR)
167
+ - ✅ Any file type!
168
+
169
+ ### Advanced: Priority & Marketing Emails
170
+
171
+ ```javascript
172
+ // High priority email
173
+ await strapi.plugin('magic-mail').service('email-router').send({
174
+ to: 'vip@example.com',
175
+ subject: 'Urgent: Action Required',
176
+ html: '<h1>Important Update</h1>',
177
+ priority: 'high', // Adds X-Priority and Importance headers
178
+ });
179
+
180
+ // Marketing email with unsubscribe (GDPR/CAN-SPAM compliant)
181
+ await strapi.plugin('magic-mail').service('email-router').send({
182
+ to: 'subscriber@example.com',
183
+ subject: 'Weekly Newsletter',
184
+ html: '<h1>This Week's Updates</h1>',
185
+ type: 'marketing',
186
+ unsubscribeUrl: 'https://yoursite.com/unsubscribe?id=123',
187
+ // Automatically adds List-Unsubscribe header!
188
+ });
189
+ ```
190
+
191
+ ---
192
+
193
+ ## 🎨 Email Designer Suite (NEW!)
194
+
195
+ **Design beautiful emails visually with the integrated email designer!**
196
+
197
+ ### ✨ Features
198
+
199
+ | Feature | FREE | PREMIUM | ADVANCED | ENTERPRISE |
200
+ |---------|------|---------|----------|------------|
201
+ | **Visual Designer** | ✅ (3 templates) | ✅ (10 templates) | ✅ (Unlimited) | ✅ (Unlimited) |
202
+ | **Drag & Drop Editor** | ✅ | ✅ | ✅ | ✅ |
203
+ | **Mustache Variables** | ✅ | ✅ | ✅ | ✅ |
204
+ | **Template Versioning** | ❌ | ❌ | ✅ | ✅ |
205
+ | **Import/Export** | ❌ | ❌ | ✅ | ✅ |
206
+ | **Custom Blocks** | ❌ | ❌ | ❌ | ✅ |
207
+ | **Team Library** | ❌ | ❌ | ❌ | ✅ |
208
+ | **A/B Testing** | ❌ | ❌ | ❌ | ✅ |
209
+
210
+ ### 📧 Creating Email Templates
211
+
212
+ **1. Navigate to Email Templates Tab**
213
+
214
+ Go to **MagicMail → Email Templates** in the admin panel.
215
+
216
+ **2. Create New Template**
217
+
218
+ Click **"Create Template"** and use the visual designer to build your email.
219
+
220
+ **3. Add Variables with Mustache**
221
+
222
+ Use Mustache syntax for dynamic content:
223
+
224
+ ```html
225
+ <h1>Welcome {{user.firstName}}!</h1>
226
+ <p>Thanks for joining {{company.name}}</p>
227
+ ```
228
+
229
+ **4. Save & Use**
230
+
231
+ Each template gets a unique **Reference ID** (e.g., `100`) that you use when sending.
232
+
233
+ ### 💌 Sending Templated Emails
234
+
235
+ **Method 1: Using Template ID**
236
+
237
+ ```javascript
238
+ // Send email using template
239
+ await strapi.plugin('magic-mail').service('email-router').send({
240
+ to: 'user@example.com',
241
+ templateId: 100, // Your template reference ID
242
+ templateData: {
243
+ user: {
244
+ firstName: 'John',
245
+ lastName: 'Doe',
246
+ email: 'john@example.com',
247
+ },
248
+ company: {
249
+ name: 'ACME Corp',
250
+ url: 'https://acme.com',
251
+ },
252
+ orderNumber: '12345',
253
+ orderTotal: '$199.99',
254
+ },
255
+ });
256
+
257
+ // ✅ MagicMail will:
258
+ // - Load template #100
259
+ // - Render it with your data (Mustache)
260
+ // - Route via smart routing
261
+ // - Send via best account
262
+ ```
263
+
264
+ **Method 2: Via Strapi Email Service**
265
+
266
+ ```javascript
267
+ // Also works with standard Strapi email service!
268
+ await strapi.plugin('email').service('email').send({
269
+ to: 'user@example.com',
270
+ templateId: 100,
271
+ templateData: {
272
+ user: { firstName: 'Jane' },
273
+ resetUrl: 'https://yoursite.com/reset?token=xyz',
274
+ },
275
+ });
276
+ ```
277
+
278
+ ### 🎯 Template Categories
279
+
280
+ Templates can be categorized for automatic routing:
281
+
282
+ - **transactional** - Order confirmations, receipts
283
+ - **marketing** - Newsletters, promotions
284
+ - **notification** - System alerts, updates
285
+ - **custom** - Anything else
286
+
287
+ **Automatic Routing by Category:**
288
+
289
+ ```javascript
290
+ // Create routing rule: All marketing templates → SendGrid
291
+ // Then just send:
292
+ await strapi.plugin('magic-mail').service('email-router').send({
293
+ to: 'subscriber@example.com',
294
+ templateId: 200, // Marketing category template
295
+ templateData: { offer: '50% OFF' },
296
+ });
297
+ // ✅ Automatically routes via SendGrid (based on category)
298
+ ```
299
+
300
+ ### 🔄 Template Versioning (ADVANCED+)
301
+
302
+ Every time you save a template, a new version is created automatically:
303
+
304
+ ```javascript
305
+ // Get all versions
306
+ const versions = await strapi
307
+ .plugin('magic-mail')
308
+ .service('email-designer')
309
+ .getVersions(templateId);
310
+
311
+ // Restore old version
312
+ await strapi
313
+ .plugin('magic-mail')
314
+ .service('email-designer')
315
+ .restoreVersion(templateId, versionId);
316
+ ```
317
+
318
+ ### 📦 Import/Export Templates (ADVANCED+)
319
+
320
+ **Export all templates:**
321
+
322
+ ```javascript
323
+ const templates = await strapi
324
+ .plugin('magic-mail')
325
+ .service('email-designer')
326
+ .exportTemplates();
327
+
328
+ // Save to file
329
+ fs.writeFileSync('templates.json', JSON.stringify(templates, null, 2));
330
+ ```
331
+
332
+ **Import templates:**
333
+
334
+ ```javascript
335
+ const templates = JSON.parse(fs.readFileSync('templates.json'));
336
+
337
+ const results = await strapi
338
+ .plugin('magic-mail')
339
+ .service('email-designer')
340
+ .importTemplates(templates);
341
+
342
+ console.log(`Imported ${results.filter(r => r.success).length} templates`);
343
+ ```
344
+
345
+ ### 🎨 Visual Designer Features
346
+
347
+ **Powered by Unlayer Email Editor:**
348
+
349
+ - ✅ Drag & Drop Interface
350
+ - ✅ Pre-built Content Blocks
351
+ - ✅ Image Upload & Management
352
+ - ✅ Custom Fonts & Colors
353
+ - ✅ Responsive Design
354
+ - ✅ Mobile Preview
355
+ - ✅ HTML/Text Editor
356
+ - ✅ Merge Tags Support
357
+ - ✅ Save/Load Designs
358
+
359
+ ### 📊 Template Statistics
360
+
361
+ ```javascript
362
+ const stats = await strapi
363
+ .plugin('magic-mail')
364
+ .service('email-designer')
365
+ .getStats();
366
+
367
+ console.log(stats);
368
+ // {
369
+ // total: 15,
370
+ // active: 12,
371
+ // inactive: 3,
372
+ // byCategory: [
373
+ // { category: 'transactional', count: 8 },
374
+ // { category: 'marketing', count: 4 },
375
+ // { category: 'notification', count: 3 }
376
+ // ],
377
+ // maxTemplates: 3, // FREE tier limit
378
+ // remaining: 0 // Upgrade needed!
379
+ // }
380
+ ```
381
+
382
+ ### 🚀 Best Practices
383
+
384
+ **1. Use Template Categories**
385
+ ```javascript
386
+ // Set category when creating template
387
+ category: 'marketing' // Auto-routes to marketing account
388
+ ```
389
+
390
+ **2. Test Templates Before Using**
391
+ ```javascript
392
+ // Test render before sending
393
+ const rendered = await strapi
394
+ .plugin('magic-mail')
395
+ .service('email-designer')
396
+ .renderTemplate(100, { user: { firstName: 'Test' } });
397
+
398
+ console.log(rendered.html); // Preview HTML
399
+ ```
400
+
401
+ **3. Version Control**
402
+ ```javascript
403
+ // ADVANCED+: Keep version history
404
+ // Automatically enabled for ADVANCED and ENTERPRISE licenses
405
+ ```
406
+
407
+ **4. Organize with Tags**
408
+ ```javascript
409
+ // Add tags to templates
410
+ tags: ['onboarding', 'welcome-series', 'v2']
411
+ ```
412
+
413
+ ---
414
+
415
+ ## 🎯 Smart Routing Rules
416
+
417
+ Create intelligent routing rules to send emails through specific accounts based on conditions.
418
+
419
+ ### Example Use Cases
420
+
421
+ **1. Route Marketing Emails via SendGrid:**
422
+ ```
423
+ Match Type: Email Type
424
+ Match Value: marketing
425
+ Target Account: SendGrid Marketing
426
+ Priority: 10
427
+ ```
428
+
429
+ **2. Route VIP Customers via Premium SMTP:**
430
+ ```
431
+ Match Type: Recipient
432
+ Match Value: @vip-customers.com
433
+ Target Account: Premium SMTP
434
+ Fallback Account: Gmail OAuth
435
+ Priority: 9
436
+ ```
437
+
438
+ **3. Route Password Reset Emails:**
439
+ ```
440
+ Match Type: Subject
441
+ Match Value: Password Reset
442
+ Target Account: Transactional SMTP
443
+ Priority: 8
444
+ ```
445
+
446
+ ### Routing Priority
447
+
448
+ Rules are evaluated from **highest to lowest priority** (1-10):
449
+ - Priority 10 = Evaluated first (most specific rules)
450
+ - Priority 1 = Evaluated last (catch-all rules)
451
+
452
+ If no rule matches, the **Primary Account** is used.
453
+
454
+ ---
455
+
456
+ ## 🔐 Provider Setup Guides
457
+
458
+ ### Gmail OAuth Setup
459
+
460
+ **1. Google Cloud Console**
461
+ 1. Go to [console.cloud.google.com](https://console.cloud.google.com)
462
+ 2. Create a new project or select existing
463
+ 3. Enable Gmail API
464
+ 4. Create OAuth 2.0 Client ID
465
+ 5. Add redirect URI: `http://localhost:1337/magic-mail/oauth/gmail/callback`
466
+ 6. Copy Client ID and Client Secret
467
+
468
+ **2. In MagicMail**
469
+ 1. Choose "Gmail OAuth" provider
470
+ 2. Paste Client ID and Client Secret
471
+ 3. Click "Connect with Google"
472
+ 4. Authorize in popup
473
+ 5. Done! ✅
474
+
475
+ **Required Scopes:**
476
+ - `https://www.googleapis.com/auth/gmail.send`
477
+ - `https://www.googleapis.com/auth/userinfo.email`
478
+
479
+ ---
480
+
481
+ ### Microsoft 365 OAuth Setup
482
+
483
+ **1. Azure Portal**
484
+ 1. Go to [portal.azure.com](https://portal.azure.com)
485
+ 2. Navigate to **Azure Active Directory → App registrations**
486
+ 3. Click **"New registration"**
487
+ 4. Name: "MagicMail"
488
+ 5. Account type: **"Accounts in this organizational directory only"**
489
+ 6. Copy **Application (client) ID** AND **Directory (tenant) ID**
490
+
491
+ **2. Add Redirect URI**
492
+ ```
493
+ http://localhost:1337/magic-mail/oauth/microsoft/callback
494
+ ```
495
+
496
+ **3. API Permissions**
497
+
498
+ Add these **Delegated permissions** under Microsoft Graph:
499
+ - ✅ `Mail.Send` - Send emails as the signed-in user
500
+ - ✅ `User.Read` - Read user profile
501
+ - ✅ `offline_access` - Maintain access (refresh tokens)
502
+ - ✅ `openid` - Sign users in
503
+ - ✅ `email` - View users' email address
504
+
505
+ **4. Grant Admin Consent** (Required!)
506
+
507
+ **5. Create Client Secret**
508
+ 1. **Certificates & secrets** → **New client secret**
509
+ 2. Copy the **VALUE** (not the Secret ID)
510
+ 3. Store it securely!
511
+
512
+ **6. In MagicMail**
513
+ 1. Choose "Microsoft OAuth" provider
514
+ 2. Paste **Tenant ID**, **Client ID**, and **Client Secret**
515
+ 3. Click "Connect with Microsoft"
516
+ 4. Authorize
517
+ 5. Done! ✅
518
+
519
+ ---
520
+
521
+ ### Yahoo Mail OAuth Setup
522
+
523
+ **1. Yahoo Developer Console**
524
+ 1. Go to [developer.yahoo.com/apps](https://developer.yahoo.com/apps)
525
+ 2. Click **"Create an App"**
526
+ 3. Fill in app details
527
+
528
+ **2. Add Redirect URI**
529
+ ```
530
+ http://localhost:1337/magic-mail/oauth/yahoo/callback
531
+ ```
532
+
533
+ **3. API Permissions**
534
+ - ✅ `Mail` - Send and manage emails
535
+ - ✅ `OpenID Connect` - User authentication
536
+
537
+ **4. In MagicMail**
538
+ 1. Choose "Yahoo Mail OAuth" provider
539
+ 2. Paste Client ID and Client Secret
540
+ 3. Click "Connect with Yahoo"
541
+ 4. Done! ✅
542
+
543
+ ---
544
+
545
+ ### SMTP Setup (Universal)
546
+
547
+ **Works with ANY SMTP server:**
548
+
549
+ ```
550
+ Host: smtp.gmail.com (or your SMTP server)
551
+ Port: 587 (STARTTLS) or 465 (SSL/TLS)
552
+ Username: your-email@domain.com
553
+ Password: your-password (or App Password)
554
+ ```
555
+
556
+ **Popular SMTP Servers:**
557
+ - **Gmail:** `smtp.gmail.com:587` (use App Password!)
558
+ - **Outlook:** `smtp-mail.outlook.com:587`
559
+ - **Office365:** `smtp.office365.com:587`
560
+ - **Custom:** Your own mail server
561
+
562
+ **Gmail App Password:**
563
+ 1. Google Account → Security → 2-Step Verification
564
+ 2. App passwords → Generate
565
+ 3. Use the 16-character password in MagicMail
566
+
567
+ **Optional: DKIM Signing**
568
+
569
+ For custom domains, you can add DKIM:
570
+ ```javascript
571
+ // In config field (advanced users):
572
+ {
573
+ dkim: {
574
+ domainName: 'yourdomain.com',
575
+ keySelector: 'default',
576
+ privateKey: '-----BEGIN PRIVATE KEY-----\n...'
577
+ }
578
+ }
579
+ ```
580
+
581
+ ---
582
+
583
+ ### SendGrid Setup
584
+
585
+ **1. Get API Key**
586
+ 1. Go to [app.sendgrid.com](https://app.sendgrid.com)
587
+ 2. Settings → API Keys → Create API Key
588
+ 3. Scope: **Mail Send** (Full Access)
589
+ 4. Copy the API key
590
+
591
+ **2. In MagicMail**
592
+ 1. Choose "SendGrid" provider
593
+ 2. Paste API Key
594
+ 3. Done! ✅
595
+
596
+ ---
597
+
598
+ ### Mailgun Setup
599
+
600
+ **1. Get API Key & Domain**
601
+ 1. Go to [app.mailgun.com](https://app.mailgun.com)
602
+ 2. Settings → API Security → Copy **Private API Key**
603
+ 3. Sending → Domains → Copy your verified domain
604
+
605
+ **2. In MagicMail**
606
+ 1. Choose "Mailgun" provider
607
+ 2. Enter **Domain** (e.g., `mg.yourdomain.com`)
608
+ 3. Paste **Private API Key**
609
+ 4. Done! ✅
610
+
611
+ ---
612
+
613
+ ## 🛡️ Security Features
614
+
615
+ ### Encryption
616
+ - ✅ **AES-256-GCM** encryption for all credentials
617
+ - ✅ **No plain text passwords** in database
618
+ - ✅ **OAuth tokens encrypted** at rest
619
+ - ✅ **Secure token refresh** mechanism
620
+
621
+ ### Transport Security
622
+ - ✅ **TLS 1.2+ enforced** (SMTP)
623
+ - ✅ **Certificate verification** enabled
624
+ - ✅ **HTTPS only** for API providers
625
+
626
+ ### Email Authentication
627
+ - ✅ **DKIM signing** (optional for SMTP, automatic for OAuth)
628
+ - ✅ **SPF validation** support
629
+ - ✅ **DMARC compliance** - All providers pass DMARC checks
630
+ - ✅ **Proper Message-ID** generation (RFC 5322)
631
+
632
+ ### Content Security
633
+ - ✅ **XSS prevention** - No `<script>` tags allowed
634
+ - ✅ **Input validation** - Email format, subject length
635
+ - ✅ **Spam trigger detection** - Warns about suspicious patterns
636
+ - ✅ **MIME type validation**
637
+
638
+ ### Compliance Headers
639
+ - ✅ **List-Unsubscribe** (RFC 8058) - GDPR/CAN-SPAM compliant
640
+ - ✅ **Auto-Submitted** (RFC 3834) - Prevents auto-responder loops
641
+ - ✅ **Precedence: bulk** for marketing emails
642
+ - ✅ **X-Priority** and **Importance** headers
643
+
644
+ ---
645
+
646
+ ## 📊 Features Overview
647
+
648
+ ### Multi-Account Management
649
+ - Unlimited email accounts
650
+ - Provider-specific configuration
651
+ - Active/Inactive status
652
+ - Primary account designation
653
+ - Per-account priority (1-10)
654
+ - Daily and hourly rate limits
655
+
656
+ ### Smart Routing Engine
657
+ - **Email Type Routing** - transactional, marketing, notification
658
+ - **Recipient Matching** - Route by email domain or address
659
+ - **Subject Matching** - Route by subject keywords
660
+ - **Template Matching** - Route by template name
661
+ - **Custom Field Matching** - Flexible custom conditions
662
+ - **Priority-based evaluation** - Higher priority rules match first
663
+ - **Fallback accounts** - Automatic failover per rule
664
+
665
+ ### Rate Limiting & Failover
666
+ - Per-account daily limits
667
+ - Per-account hourly limits
668
+ - Automatic counter reset (hourly/daily)
669
+ - Smart failover to backup accounts
670
+ - Rate limit hit detection
671
+ - Account health monitoring
672
+
673
+ ### Analytics & Monitoring
674
+ - Real-time statistics dashboard
675
+ - Emails sent today (per account and total)
676
+ - Total emails sent (lifetime)
677
+ - Active/Inactive account count
678
+ - Success/Failure tracking
679
+ - Last used timestamps
680
+ - Visual progress bars for rate limits
681
+
682
+ ### Testing Features
683
+ - **Test Direct** - Test specific account directly
684
+ - **Test Strapi Service** - Verify Email Designer compatibility
685
+ - **Priority Testing** - Test high/normal priority headers
686
+ - **Marketing Email Testing** - Test List-Unsubscribe headers
687
+ - **Detailed test results** - Shows all security features applied
688
+
689
+ ---
690
+
691
+ ## 🔧 Configuration
692
+
693
+ ### Basic Setup (No .env Required!)
694
+
695
+ All configuration is done via the Admin Panel. However, for production deployments, you can set:
696
+
697
+ ```env
698
+ # Optional - Base URL for OAuth callbacks
699
+ URL=https://yourdomain.com
700
+
701
+ # Optional - Encryption key (auto-generated if not provided)
702
+ ENCRYPTION_KEY=your-32-character-secret-key
703
+ ```
704
+
705
+ ### Account Configuration
706
+
707
+ Each account can have:
708
+
709
+ **Basic Settings:**
710
+ - Name (unique identifier)
711
+ - Description
712
+ - Provider type
713
+ - From Email
714
+ - From Name
715
+ - Reply-To Email
716
+
717
+ **Security:**
718
+ - OAuth credentials (encrypted)
719
+ - SMTP credentials (encrypted)
720
+ - API keys (encrypted)
721
+ - DKIM configuration (optional)
722
+
723
+ **Rate Limiting:**
724
+ - Daily email limit (0 = unlimited)
725
+ - Hourly email limit (0 = unlimited)
726
+ - Priority (1-10, higher = preferred)
727
+
728
+ **Status:**
729
+ - Active/Inactive
730
+ - Primary account designation
731
+
732
+ ---
733
+
734
+ ## 🎨 API Reference
735
+
736
+ ### Send Email (Standard Method)
737
+
738
+ ```javascript
739
+ await strapi.plugin('email').service('email').send({
740
+ to: 'recipient@example.com',
741
+ from: 'sender@example.com', // Optional - uses account default
742
+ subject: 'Email Subject',
743
+ text: 'Plain text content',
744
+ html: '<h1>HTML content</h1>',
745
+
746
+ // Optional advanced options:
747
+ replyTo: 'reply@example.com',
748
+ type: 'transactional', // or 'marketing', 'notification'
749
+ priority: 'normal', // or 'high'
750
+ accountName: 'Specific Account', // Force specific account
751
+ unsubscribeUrl: 'https://site.com/unsubscribe', // For marketing emails
752
+
753
+ attachments: [
754
+ {
755
+ filename: 'document.pdf',
756
+ path: './path/to/file.pdf',
757
+ contentType: 'application/pdf',
758
+ },
759
+ ],
760
+ });
761
+ ```
762
+
763
+ ### Send Email (Direct MagicMail API)
764
+
765
+ ```javascript
766
+ await strapi.plugin('magic-mail').service('email-router').send({
767
+ to: 'user@example.com',
768
+ subject: 'Test Email',
769
+ html: '<p>Content</p>',
770
+ accountName: 'Gmail OAuth', // Optional - force specific account
771
+ type: 'transactional',
772
+ priority: 'normal',
773
+ });
774
+ ```
775
+
776
+ ### Get All Accounts
777
+
778
+ ```javascript
779
+ const accounts = await strapi.plugin('magic-mail').service('account-manager').getAllAccounts();
780
+ ```
781
+
782
+ ### Test Account
783
+
784
+ ```javascript
785
+ const result = await strapi.plugin('magic-mail').service('account-manager').testAccount(
786
+ accountId,
787
+ 'test@example.com',
788
+ {
789
+ priority: 'high',
790
+ type: 'marketing',
791
+ unsubscribeUrl: 'https://example.com/unsubscribe',
792
+ }
793
+ );
794
+ ```
795
+
796
+ ---
797
+
798
+ ## 🧪 Testing Your Setup
799
+
800
+ ### Test via Admin UI
801
+
802
+ 1. Go to **Email Accounts**
803
+ 2. Click **Test** button on any account
804
+ 3. Enter recipient email
805
+ 4. Select test options:
806
+ - **Priority:** Normal / High
807
+ - **Email Type:** Transactional / Marketing / Notification
808
+ - **Unsubscribe URL:** (for marketing emails)
809
+ 5. Choose test method:
810
+ - **Test Direct** - Direct send via account
811
+ - **Test Strapi Service** - Via Strapi email service (tests Email Designer compatibility)
812
+
813
+ ### Test via Code
814
+
815
+ ```javascript
816
+ // Test email with all security features
817
+ await strapi.plugin('magic-mail').service('account-manager').testAccount(
818
+ accountId,
819
+ 'your-email@example.com',
820
+ {
821
+ priority: 'high',
822
+ type: 'marketing',
823
+ unsubscribeUrl: 'https://yoursite.com/unsubscribe',
824
+ }
825
+ );
826
+ ```
827
+
828
+ ### Verify Headers
829
+
830
+ **To verify security headers are applied:**
831
+
832
+ **In Gmail:**
833
+ 1. Open email → Click ⋮ (three dots)
834
+ 2. "Show original"
835
+ 3. Look for:
836
+ ```
837
+ X-Mailer: MagicMail/1.0
838
+ X-Priority: 1 (Highest)
839
+ Importance: high
840
+ List-Unsubscribe: <https://...>
841
+ Message-ID: <...>
842
+ DKIM-Signature: ...
843
+ ```
844
+
845
+ **In Outlook/Microsoft:**
846
+ 1. Email → File → Properties
847
+ 2. View "Internet headers"
848
+ 3. Should show "High Importance" with red exclamation mark
849
+
850
+ ---
851
+
852
+ ## 🔒 Security Compliance
853
+
854
+ ### Email Authentication
855
+
856
+ | Standard | Status | Description |
857
+ |----------|--------|-------------|
858
+ | **DKIM** | ✅ | DomainKeys Identified Mail - Signature validation |
859
+ | **SPF** | ✅ | Sender Policy Framework - Sender verification |
860
+ | **DMARC** | ✅ | Domain-based Authentication - Policy enforcement |
861
+ | **TLS 1.2+** | ✅ | Transport Layer Security - Encrypted transmission |
862
+ | **AES-256-GCM** | ✅ | Credential encryption at rest |
863
+
864
+ ### Regulatory Compliance
865
+
866
+ | Regulation | Status | Implementation |
867
+ |------------|--------|----------------|
868
+ | **GDPR** | ✅ | List-Unsubscribe header for marketing emails |
869
+ | **CAN-SPAM** | ✅ | One-click unsubscribe mechanism (RFC 8058) |
870
+ | **RFC 5322** | ✅ | Proper email format and headers |
871
+ | **RFC 3834** | ✅ | Auto-Submitted header prevents loops |
872
+ | **RFC 2156** | ✅ | Priority and Importance headers |
873
+
874
+ ### Security Validation
875
+
876
+ **Every email is validated for:**
877
+ - ✅ Valid recipient email format
878
+ - ✅ Non-empty subject line
879
+ - ✅ Subject length (warns if > 200 chars)
880
+ - ✅ Content presence (text or html required)
881
+ - ✅ No `<script>` tags in HTML
882
+ - ✅ No `javascript:` protocol in links
883
+ - ✅ Spam trigger detection (warns only)
884
+
885
+ ---
886
+
887
+ ## 📈 Analytics & Monitoring
888
+
889
+ ### Dashboard Stats
890
+
891
+ **Global Stats:**
892
+ - Emails sent today (all accounts)
893
+ - Total emails sent (lifetime)
894
+ - Active accounts count
895
+
896
+ **Per-Account Stats:**
897
+ - Emails sent today
898
+ - Total emails sent
899
+ - Rate limit usage (visual progress bars)
900
+ - Last used timestamp
901
+ - Success/failure rate
902
+
903
+ ### Email Logging
904
+
905
+ Every email is logged with:
906
+ - Recipient
907
+ - Sender
908
+ - Subject
909
+ - Account used
910
+ - Status (sent/failed)
911
+ - Timestamp
912
+ - Email type
913
+ - Error message (if failed)
914
+
915
+ Access logs via:
916
+ ```javascript
917
+ const logs = await strapi.entityService.findMany('plugin::magic-mail.email-log', {
918
+ filters: { status: 'sent' },
919
+ sort: { createdAt: 'desc' },
920
+ limit: 100,
921
+ });
922
+ ```
923
+
924
+ ---
925
+
926
+ ## 🔄 Integration with Email Designer
927
+
928
+ **MagicMail is fully compatible with [strapi-plugin-email-designer-5](https://www.npmjs.com/package/strapi-plugin-email-designer-5)!**
929
+
930
+ ### How It Works
931
+
932
+ 1. Install Email Designer:
933
+ ```bash
934
+ npm install strapi-plugin-email-designer-5
935
+ ```
936
+
937
+ 2. Create email templates in Email Designer
938
+
939
+ 3. Send via template:
940
+ ```javascript
941
+ // Email Designer internally uses strapi.plugin('email').service('email').send()
942
+ // MagicMail automatically intercepts it!
943
+ ```
944
+
945
+ 4. Your email is automatically:
946
+ - ✅ Routed through MagicMail's smart routing
947
+ - ✅ Sent via the best account (based on rules)
948
+ - ✅ Rate limited and failover protected
949
+ - ✅ Logged and tracked
950
+
951
+ **No configuration needed - it just works!** 🎉
952
+
953
+ ---
954
+
955
+ ## 🚨 Troubleshooting
956
+
957
+ ### Email Not Received
958
+
959
+ **1. Check Logs**
960
+ ```bash
961
+ # Look for errors in Strapi console
962
+ [magic-mail] ❌ Email send failed: ...
963
+ ```
964
+
965
+ **2. Check Account Status**
966
+ - Is the account marked as "Active"?
967
+ - Test the account using the Test button
968
+ - Check rate limits haven't been exceeded
969
+
970
+ **3. Check Spam Folder**
971
+ - First emails from new accounts may land in spam
972
+ - Check spam/junk folders
973
+ - Mark as "Not Spam" to train filters
974
+
975
+ **4. Verify Credentials**
976
+ - SMTP: Username and password correct?
977
+ - Gmail: Using App Password (not regular password)?
978
+ - OAuth: Tokens may have expired - reconnect
979
+
980
+ ### DMARC Failures
981
+
982
+ **For Custom Domains:**
983
+ 1. Set up SPF record:
984
+ ```
985
+ v=spf1 include:_spf.google.com ~all
986
+ ```
987
+
988
+ 2. Set up DKIM:
989
+ - Generate DKIM key pair
990
+ - Add public key to DNS
991
+ - Add private key to MagicMail SMTP config
992
+
993
+ 3. Set up DMARC:
994
+ ```
995
+ v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com
996
+ ```
997
+
998
+ **For OAuth Providers (Gmail, Microsoft, Yahoo):**
999
+ - ✅ DKIM handled automatically
1000
+ - ✅ SPF handled automatically
1001
+ - ✅ DMARC should pass automatically
1002
+
1003
+ ### Rate Limit Errors
1004
+
1005
+ **If you hit rate limits:**
1006
+ - Increase daily/hourly limits in account settings
1007
+ - Add more accounts for load balancing
1008
+ - Set up routing rules to distribute load
1009
+ - Check provider-specific limits:
1010
+ - Gmail: 500/day (free), 2000/day (workspace)
1011
+ - SendGrid: Varies by plan
1012
+ - Mailgun: Varies by plan
1013
+
1014
+ ### OAuth Connection Issues
1015
+
1016
+ **Gmail OAuth:**
1017
+ - Ensure Gmail API is enabled
1018
+ - Check redirect URI matches exactly
1019
+ - Clear browser cookies and try again
1020
+
1021
+ **Microsoft OAuth:**
1022
+ - Verify all 5 permissions are granted
1023
+ - **Grant admin consent** (required!)
1024
+ - Use correct Tenant ID
1025
+ - Check Client Secret hasn't expired
1026
+
1027
+ **Yahoo OAuth:**
1028
+ - Verify app is approved by Yahoo
1029
+ - Check API permissions are enabled
1030
+
1031
+ ---
1032
+
1033
+ ## 🏗️ Architecture
1034
+
1035
+ ### Plugin Structure
1036
+
1037
+ ```
1038
+ magic-mail/
1039
+ ├── admin/ # React Admin UI
1040
+ │ └── src/
1041
+ │ ├── components/
1042
+ │ │ ├── AddAccountModal.jsx # Multi-step account setup
1043
+ │ │ └── PluginIcon.jsx # Sidebar icon
1044
+ │ └── pages/
1045
+ │ ├── App.jsx # Main app with tabs
1046
+ │ ├── HomePage.jsx # Email accounts page
1047
+ │ └── RoutingRules.jsx # Routing rules page
1048
+ ├── server/ # Backend
1049
+ │ └── src/
1050
+ │ ├── bootstrap.js # Overrides Strapi email service
1051
+ │ ├── controllers/
1052
+ │ │ ├── accounts.js # CRUD for accounts
1053
+ │ │ ├── oauth.js # OAuth flows
1054
+ │ │ └── routing-rules.js # CRUD for routing rules
1055
+ │ ├── services/
1056
+ │ │ ├── email-router.js # Core routing logic
1057
+ │ │ ├── account-manager.js # Account management
1058
+ │ │ └── oauth.js # OAuth token exchange
1059
+ │ ├── content-types/
1060
+ │ │ ├── email-account/ # Account schema
1061
+ │ │ ├── email-log/ # Email log schema
1062
+ │ │ └── routing-rule/ # Routing rule schema
1063
+ │ └── utils/
1064
+ │ └── encryption.js # AES-256-GCM encryption
1065
+ └── package.json
1066
+ ```
1067
+
1068
+ ### Data Flow
1069
+
1070
+ ```
1071
+ Email Request
1072
+
1073
+ Strapi Email Service (intercepted!)
1074
+
1075
+ MagicMail Email Router
1076
+
1077
+ Routing Rules Engine
1078
+
1079
+ Account Selection (priority/rules)
1080
+
1081
+ Rate Limit Check
1082
+
1083
+ Provider-Specific Sender
1084
+
1085
+ Email Log & Stats Update
1086
+
1087
+ Response
1088
+ ```
1089
+
1090
+ ---
1091
+
1092
+ ## 🎯 Use Cases
1093
+
1094
+ ### Multi-Tenant SaaS
1095
+
1096
+ ```javascript
1097
+ // Each tenant gets their own email account
1098
+ // Route by custom field:
1099
+
1100
+ // Routing Rule:
1101
+ // Match Type: Custom Field
1102
+ // Match Value: tenant-123
1103
+ // Target Account: Tenant 123 Gmail
1104
+
1105
+ await strapi.plugin('email').service('email').send({
1106
+ to: 'customer@example.com',
1107
+ subject: 'Order Confirmation',
1108
+ html: '<h1>Order #456</h1>',
1109
+ customField: 'tenant-123', // Matches routing rule
1110
+ });
1111
+ ```
1112
+
1113
+ ### High-Volume Email Sending
1114
+
1115
+ ```javascript
1116
+ // Distribute load across multiple accounts
1117
+ // Account 1: Priority 10, Limit 500/day
1118
+ // Account 2: Priority 9, Limit 500/day
1119
+ // Account 3: Priority 8, Limit 500/day
1120
+ // → Total: 1500 emails/day with automatic load balancing!
1121
+ ```
1122
+
1123
+ ### Marketing Campaigns
1124
+
1125
+ ```javascript
1126
+ // Route marketing emails via SendGrid
1127
+ // Routing Rule:
1128
+ // Match Type: Email Type
1129
+ // Match Value: marketing
1130
+ // Target Account: SendGrid Marketing
1131
+
1132
+ await strapi.plugin('email').service('email').send({
1133
+ to: 'subscriber@example.com',
1134
+ subject: 'Weekly Newsletter',
1135
+ html: template,
1136
+ type: 'marketing',
1137
+ unsubscribeUrl: 'https://yoursite.com/unsubscribe?id=123',
1138
+ });
1139
+ // ✅ Automatically routes via SendGrid
1140
+ // ✅ Adds List-Unsubscribe header
1141
+ // ✅ GDPR/CAN-SPAM compliant
1142
+ ```
1143
+
1144
+ ### VIP Customer Emails
1145
+
1146
+ ```javascript
1147
+ // Route VIP customers via premium account
1148
+ // Routing Rule:
1149
+ // Match Type: Recipient
1150
+ // Match Value: @vip-domain.com
1151
+ // Target Account: Premium SMTP
1152
+ // Fallback Account: Gmail OAuth
1153
+
1154
+ await strapi.plugin('email').service('email').send({
1155
+ to: 'ceo@vip-domain.com',
1156
+ subject: 'Exclusive Offer',
1157
+ html: content,
1158
+ priority: 'high',
1159
+ });
1160
+ // ✅ Routes via Premium SMTP
1161
+ // ✅ High priority headers added
1162
+ // ✅ Automatic fallback if premium account unavailable
1163
+ ```
1164
+
1165
+ ---
1166
+
1167
+ ## 🔌 Email Provider Comparison
1168
+
1169
+ | Feature | Gmail OAuth | Microsoft OAuth | Yahoo OAuth | SMTP | SendGrid | Mailgun |
1170
+ |---------|-------------|-----------------|-------------|------|----------|---------|
1171
+ | **Auth Method** | OAuth 2.0 | OAuth 2.0 | OAuth 2.0 | Password | API Key | API Key |
1172
+ | **Free Tier** | 500/day | Varies | Limited | Varies | 100/day | 5000/month |
1173
+ | **Attachments** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1174
+ | **HTML Emails** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1175
+ | **DKIM Auto** | ✅ | ✅ | ✅ | Optional | ✅ | ✅ |
1176
+ | **Custom Headers** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1177
+ | **Priority Headers** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
1178
+ | **Security** | Excellent | Excellent | Good | Good | Excellent | Excellent |
1179
+ | **Deliverability** | Excellent | Excellent | Good | Varies | Excellent | Excellent |
1180
+ | **Best For** | Personal/Small | Enterprise | Personal | Custom | Marketing | Bulk/Dev |
1181
+
1182
+ ---
1183
+
1184
+ ## 🌍 Production Deployment
1185
+
1186
+ ### Environment Variables
1187
+
1188
+ ```env
1189
+ # Base URL (required for OAuth callbacks in production)
1190
+ URL=https://yourdomain.com
1191
+
1192
+ # Database (Strapi default)
1193
+ DATABASE_CLIENT=postgres
1194
+ DATABASE_HOST=127.0.0.1
1195
+ DATABASE_PORT=5432
1196
+ DATABASE_NAME=strapi
1197
+ DATABASE_USERNAME=strapi
1198
+ DATABASE_PASSWORD=password
1199
+
1200
+ # Optional - Custom encryption key
1201
+ ENCRYPTION_KEY=your-32-byte-secret-key-here
1202
+ ```
1203
+
1204
+ ### OAuth Callback URLs
1205
+
1206
+ **Update redirect URIs in your OAuth apps:**
1207
+
1208
+ **Gmail:**
1209
+ ```
1210
+ https://yourdomain.com/magic-mail/oauth/gmail/callback
1211
+ ```
1212
+
1213
+ **Microsoft:**
1214
+ ```
1215
+ https://yourdomain.com/magic-mail/oauth/microsoft/callback
1216
+ ```
1217
+
1218
+ **Yahoo:**
1219
+ ```
1220
+ https://yourdomain.com/magic-mail/oauth/yahoo/callback
1221
+ ```
1222
+
1223
+ ### Recommended Provider Settings
1224
+
1225
+ **For Production Apps:**
1226
+
1227
+ | Use Case | Recommended Provider | Configuration |
1228
+ |----------|---------------------|---------------|
1229
+ | **Transactional** | SendGrid or Mailgun | High daily limit, dedicated IP |
1230
+ | **Marketing** | SendGrid | List management, analytics |
1231
+ | **Notifications** | SMTP or Gmail OAuth | Medium limits, reliable |
1232
+ | **Internal** | Microsoft 365 | Company domain, OAuth |
1233
+ | **Development** | Mailgun Sandbox | Free testing |
1234
+
1235
+ ---
1236
+
1237
+ ## 📚 Advanced Topics
1238
+
1239
+ ### Custom Routing Logic
1240
+
1241
+ Create complex routing rules:
1242
+
1243
+ ```javascript
1244
+ // Rule 1: VIP customers via premium account
1245
+ {
1246
+ name: "VIP Customer Emails",
1247
+ matchType: "recipient",
1248
+ matchValue: "@vip-customers.com",
1249
+ accountName: "Premium SMTP",
1250
+ fallbackAccountName: "Gmail OAuth",
1251
+ priority: 10,
1252
+ isActive: true
1253
+ }
1254
+
1255
+ // Rule 2: Password resets via fast account
1256
+ {
1257
+ name: "Password Reset Emails",
1258
+ matchType: "subject",
1259
+ matchValue: "Password Reset",
1260
+ accountName: "Fast Gmail",
1261
+ priority: 9,
1262
+ isActive: true
1263
+ }
1264
+
1265
+ // Rule 3: Marketing via SendGrid
1266
+ {
1267
+ name: "Marketing Campaigns",
1268
+ matchType: "emailType",
1269
+ matchValue: "marketing",
1270
+ accountName: "SendGrid Marketing",
1271
+ priority: 8,
1272
+ isActive: true
1273
+ }
1274
+ ```
1275
+
1276
+ ### DKIM Configuration (Advanced)
1277
+
1278
+ For custom domains with SMTP:
1279
+
1280
+ **1. Generate DKIM Keys:**
1281
+ ```bash
1282
+ openssl genrsa -out dkim_private.pem 1024
1283
+ openssl rsa -in dkim_private.pem -pubout -out dkim_public.pem
1284
+ ```
1285
+
1286
+ **2. Add to DNS:**
1287
+ ```
1288
+ default._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA..."
1289
+ ```
1290
+
1291
+ **3. Add to MagicMail SMTP Account:**
1292
+ ```javascript
1293
+ // In account config (edit account → credentials):
1294
+ {
1295
+ host: "smtp.yourdomain.com",
1296
+ port: 587,
1297
+ user: "...",
1298
+ pass: "...",
1299
+ dkim: {
1300
+ domainName: "yourdomain.com",
1301
+ keySelector: "default",
1302
+ privateKey: "-----BEGIN PRIVATE KEY-----\n..."
1303
+ }
1304
+ }
1305
+ ```
1306
+
1307
+ ### Rate Limit Strategy
1308
+
1309
+ **Best practices for high-volume sending:**
1310
+
1311
+ ```javascript
1312
+ // Account Setup:
1313
+ // Account A: Priority 10, Daily Limit: 500
1314
+ // Account B: Priority 9, Daily Limit: 500
1315
+ // Account C: Priority 8, Daily Limit: 500
1316
+ // → Total capacity: 1500 emails/day
1317
+
1318
+ // MagicMail automatically:
1319
+ // 1. Uses Account A until limit hit
1320
+ // 2. Switches to Account B
1321
+ // 3. Switches to Account C
1322
+ // 4. All transparent to your code!
1323
+ ```
1324
+
1325
+ ---
1326
+
1327
+ ## 🤝 Contributing
1328
+
1329
+ We welcome contributions!
1330
+
1331
+ **Found a bug?** [Open an issue](https://github.com/Schero94/MagicMail/issues)
1332
+
1333
+ **Have a feature idea?** [Start a discussion](https://github.com/Schero94/MagicMail/discussions)
1334
+
1335
+ **Want to contribute code?**
1336
+ 1. Fork the repo
1337
+ 2. Create a feature branch
1338
+ 3. Make your changes
1339
+ 4. Submit a pull request
1340
+
1341
+ ---
1342
+
1343
+ ## 📝 Changelog
1344
+
1345
+ ### v1.0.0 (2025-11-13)
1346
+
1347
+ **Initial Release** 🎉
1348
+
1349
+ **Features:**
1350
+ - ✅ 6 Email Providers (Gmail, Microsoft, Yahoo OAuth + SMTP, SendGrid, Mailgun)
1351
+ - ✅ OAuth 2.0 Support (Gmail, Microsoft 365, Yahoo Mail)
1352
+ - ✅ Smart Routing Rules Engine
1353
+ - ✅ Automatic Failover & Rate Limiting
1354
+ - ✅ Beautiful Admin UI with Heroicons
1355
+ - ✅ Email Analytics Dashboard
1356
+ - ✅ Strapi Email Service Override (Email Designer compatible)
1357
+ - ✅ Comprehensive Security (TLS 1.2+, DKIM, SPF, DMARC)
1358
+ - ✅ GDPR/CAN-SPAM Compliance
1359
+ - ✅ Test Features (Direct & Strapi Service)
1360
+ - ✅ Encrypted Credential Storage (AES-256-GCM)
1361
+ - ✅ Attachment Support (all providers)
1362
+ - ✅ Priority Email Headers
1363
+ - ✅ List-Unsubscribe Headers
1364
+ - ✅ Security Validation
1365
+ - ✅ Hourly/Daily Counter Resets
1366
+
1367
+ ---
1368
+
1369
+ ## 📄 License
1370
+
1371
+ **MIT License**
1372
+
1373
+ Copyright © 2025 Schero D.
1374
+
1375
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
1376
+
1377
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1378
+
1379
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1380
+
1381
+ ---
1382
+
1383
+ ## 🙏 Credits
1384
+
1385
+ **Built with:**
1386
+ - [Strapi v5](https://strapi.io) - Headless CMS
1387
+ - [Nodemailer](https://nodemailer.com) - SMTP client
1388
+ - [Heroicons](https://heroicons.com) - Beautiful icons
1389
+ - [styled-components](https://styled-components.com) - CSS-in-JS
1390
+
1391
+ **Inspired by:**
1392
+ - Enterprise email requirements
1393
+ - Multi-tenant application needs
1394
+ - Developer experience first
1395
+
1396
+ ---
1397
+
1398
+ ## 💬 Support
1399
+
1400
+ **Need help?**
1401
+ - 📖 [Documentation](https://github.com/Schero94/MagicMail#readme)
1402
+ - 🐛 [Report Issues](https://github.com/Schero94/MagicMail/issues)
1403
+ - 💡 [Feature Requests](https://github.com/Schero94/MagicMail/discussions)
1404
+ - 📧 [Email Support](mailto:support@magicmail.dev)
1405
+
1406
+ ---
1407
+
1408
+ ## ⭐ Show Your Support
1409
+
1410
+ If MagicMail helps your project, please:
1411
+ - ⭐ Star the repo on [GitHub](https://github.com/Schero94/MagicMail)
1412
+ - 📢 Share with your team
1413
+ - 🐦 Tweet about it
1414
+ - ☕ [Buy me a coffee](https://www.buymeacoffee.com/schero)
1415
+
1416
+ ---
1417
+
1418
+ **Made with ❤️ for the Strapi Community**
1419
+
1420
+ **MagicMail - Because email management should be magical, not painful.** ✨