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.
- package/COPYRIGHT_NOTICE.txt +13 -0
- package/LICENSE +22 -0
- package/README.md +1420 -0
- package/admin/jsconfig.json +10 -0
- package/admin/src/components/AddAccountModal.jsx +1943 -0
- package/admin/src/components/Initializer.jsx +14 -0
- package/admin/src/components/LicenseGuard.jsx +475 -0
- package/admin/src/components/PluginIcon.jsx +5 -0
- package/admin/src/hooks/useAuthRefresh.js +44 -0
- package/admin/src/hooks/useLicense.js +158 -0
- package/admin/src/index.js +86 -0
- package/admin/src/pages/Analytics.jsx +762 -0
- package/admin/src/pages/App.jsx +111 -0
- package/admin/src/pages/EmailDesigner/EditorPage.jsx +1405 -0
- package/admin/src/pages/EmailDesigner/TemplateList.jsx +1807 -0
- package/admin/src/pages/HomePage.jsx +1233 -0
- package/admin/src/pages/LicensePage.jsx +424 -0
- package/admin/src/pages/RoutingRules.jsx +1141 -0
- package/admin/src/pages/Settings.jsx +603 -0
- package/admin/src/pluginId.js +3 -0
- package/admin/src/translations/de.json +71 -0
- package/admin/src/translations/en.json +70 -0
- package/admin/src/translations/es.json +71 -0
- package/admin/src/translations/fr.json +71 -0
- package/admin/src/translations/pt.json +71 -0
- package/admin/src/utils/fetchWithRetry.js +123 -0
- package/admin/src/utils/getTranslation.js +5 -0
- package/dist/_chunks/App-B-Gp4Vbr.js +7568 -0
- package/dist/_chunks/App-BymMjoGM.mjs +7543 -0
- package/dist/_chunks/LicensePage-Bl02myMx.mjs +342 -0
- package/dist/_chunks/LicensePage-CJXwPnEe.js +344 -0
- package/dist/_chunks/Settings-C_TmKwcz.mjs +400 -0
- package/dist/_chunks/Settings-zuFQ3pnn.js +402 -0
- package/dist/_chunks/de-CN-G9j1S.js +64 -0
- package/dist/_chunks/de-DS04rP54.mjs +64 -0
- package/dist/_chunks/en-BDc7Jk8u.js +64 -0
- package/dist/_chunks/en-BEFQJXvR.mjs +64 -0
- package/dist/_chunks/es-BpV1MIdm.js +64 -0
- package/dist/_chunks/es-DQHwzPpP.mjs +64 -0
- package/dist/_chunks/fr-BG1WfEVm.mjs +64 -0
- package/dist/_chunks/fr-vpziIpRp.js +64 -0
- package/dist/_chunks/pt-CMoGrOib.mjs +64 -0
- package/dist/_chunks/pt-ODpAhDNa.js +64 -0
- package/dist/admin/index.js +89 -0
- package/dist/admin/index.mjs +90 -0
- package/dist/server/index.js +6214 -0
- package/dist/server/index.mjs +6208 -0
- package/package.json +113 -0
- package/server/jsconfig.json +10 -0
- package/server/src/bootstrap.js +153 -0
- package/server/src/config/features.js +260 -0
- package/server/src/config/index.js +6 -0
- package/server/src/content-types/email-account/schema.json +93 -0
- package/server/src/content-types/email-event/index.js +8 -0
- package/server/src/content-types/email-event/schema.json +57 -0
- package/server/src/content-types/email-link/index.js +8 -0
- package/server/src/content-types/email-link/schema.json +49 -0
- package/server/src/content-types/email-log/index.js +8 -0
- package/server/src/content-types/email-log/schema.json +106 -0
- package/server/src/content-types/email-template/schema.json +74 -0
- package/server/src/content-types/email-template-version/schema.json +60 -0
- package/server/src/content-types/index.js +33 -0
- package/server/src/content-types/routing-rule/schema.json +59 -0
- package/server/src/controllers/accounts.js +220 -0
- package/server/src/controllers/analytics.js +347 -0
- package/server/src/controllers/controller.js +26 -0
- package/server/src/controllers/email-designer.js +474 -0
- package/server/src/controllers/index.js +21 -0
- package/server/src/controllers/license.js +267 -0
- package/server/src/controllers/oauth.js +474 -0
- package/server/src/controllers/routing-rules.js +122 -0
- package/server/src/controllers/test.js +383 -0
- package/server/src/destroy.js +23 -0
- package/server/src/index.js +25 -0
- package/server/src/middlewares/index.js +3 -0
- package/server/src/policies/index.js +3 -0
- package/server/src/register.js +5 -0
- package/server/src/routes/admin.js +469 -0
- package/server/src/routes/content-api.js +37 -0
- package/server/src/routes/index.js +9 -0
- package/server/src/services/account-manager.js +277 -0
- package/server/src/services/analytics.js +496 -0
- package/server/src/services/email-designer.js +870 -0
- package/server/src/services/email-router.js +1420 -0
- package/server/src/services/index.js +17 -0
- package/server/src/services/license-guard.js +418 -0
- package/server/src/services/oauth.js +515 -0
- package/server/src/services/service.js +7 -0
- package/server/src/utils/encryption.js +81 -0
- package/strapi-admin.js +4 -0
- 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
|
+
[](https://www.npmjs.com/package/strapi-plugin-magic-mail)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](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
|
+

|
|
31
|
+
*Manage unlimited email accounts with live stats and real-time monitoring*
|
|
32
|
+
|
|
33
|
+
### Routing Rules
|
|
34
|
+

|
|
35
|
+
*Define intelligent routing rules based on email type, recipient, subject*
|
|
36
|
+
|
|
37
|
+
### Account Setup - OAuth
|
|
38
|
+

|
|
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.** ✨
|