@groundbrick/email-service 1.1.2 → 1.1.4

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 (37) hide show
  1. package/dist/EmailService.d.ts +24 -0
  2. package/dist/EmailService.d.ts.map +1 -0
  3. package/dist/EmailService.js +32 -0
  4. package/dist/EmailService.js.map +1 -0
  5. package/dist/EmailServiceFactory.d.ts +5 -0
  6. package/dist/EmailServiceFactory.d.ts.map +1 -0
  7. package/dist/EmailServiceFactory.js +21 -0
  8. package/dist/EmailServiceFactory.js.map +1 -0
  9. package/dist/index.d.ts +5 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +8 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/interfaces/IEmailProvider.d.ts +103 -0
  14. package/dist/interfaces/IEmailProvider.d.ts.map +1 -0
  15. package/dist/interfaces/IEmailProvider.js +11 -0
  16. package/dist/interfaces/IEmailProvider.js.map +1 -0
  17. package/dist/providers/GatewayApiEmailProvider.d.ts +41 -0
  18. package/dist/providers/GatewayApiEmailProvider.d.ts.map +1 -0
  19. package/dist/providers/GatewayApiEmailProvider.js +270 -0
  20. package/dist/providers/GatewayApiEmailProvider.js.map +1 -0
  21. package/dist/providers/MockEmailProvider.d.ts +49 -0
  22. package/dist/providers/MockEmailProvider.d.ts.map +1 -0
  23. package/dist/providers/MockEmailProvider.js +194 -0
  24. package/dist/providers/MockEmailProvider.js.map +1 -0
  25. package/dist/providers/RedirectEmailProvider.d.ts +28 -0
  26. package/dist/providers/RedirectEmailProvider.d.ts.map +1 -0
  27. package/dist/providers/RedirectEmailProvider.js +108 -0
  28. package/dist/providers/RedirectEmailProvider.js.map +1 -0
  29. package/dist/providers/SweegoEmailProvider.d.ts +36 -0
  30. package/dist/providers/SweegoEmailProvider.d.ts.map +1 -0
  31. package/dist/providers/SweegoEmailProvider.js +379 -0
  32. package/dist/providers/SweegoEmailProvider.js.map +1 -0
  33. package/dist/providers/index.d.ts +5 -0
  34. package/dist/providers/index.d.ts.map +1 -0
  35. package/dist/providers/index.js +5 -0
  36. package/dist/providers/index.js.map +1 -0
  37. package/package.json +8 -9
@@ -0,0 +1,194 @@
1
+ import { EmailStatus } from '../interfaces/IEmailProvider.js';
2
+ export class MockEmailProvider {
3
+ simulateDelay;
4
+ simulateFailures;
5
+ defaultFrom;
6
+ sentEmails = new Map();
7
+ messageIdCounter = 1;
8
+ constructor(config) {
9
+ this.simulateDelay = config.simulateDelay || 0;
10
+ this.simulateFailures = config.simulateFailures || false;
11
+ this.defaultFrom = config.defaultFrom;
12
+ }
13
+ async send(message) {
14
+ // Simulate network delay
15
+ if (this.simulateDelay > 0) {
16
+ await this.delay(this.simulateDelay);
17
+ }
18
+ // Simulate random failures (10% chance)
19
+ if (this.simulateFailures && Math.random() < 0.1) {
20
+ return {
21
+ success: false,
22
+ status: EmailStatus.FAILED,
23
+ timestamp: new Date(),
24
+ error: 'Simulated failure'
25
+ };
26
+ }
27
+ // Generate message ID
28
+ const messageId = `mock-${this.messageIdCounter++}-${Date.now()}`;
29
+ // Store sent email
30
+ const sentEmail = {
31
+ id: messageId,
32
+ message,
33
+ sentAt: new Date(),
34
+ status: EmailStatus.DELIVERED
35
+ };
36
+ this.sentEmails.set(messageId, sentEmail);
37
+ // Log email (useful for debugging)
38
+ this.logEmail(messageId, message);
39
+ return {
40
+ success: true,
41
+ messageId,
42
+ status: EmailStatus.DELIVERED,
43
+ timestamp: new Date(),
44
+ providerResponse: { mock: true, stored: true }
45
+ };
46
+ }
47
+ async getDeliveryReport(messageId) {
48
+ const sentEmail = this.sentEmails.get(messageId);
49
+ if (!sentEmail) {
50
+ return null;
51
+ }
52
+ const recipient = Array.isArray(sentEmail.message.to)
53
+ ? sentEmail.message.to[0].address
54
+ : sentEmail.message.to.address;
55
+ return {
56
+ messageId,
57
+ status: sentEmail.status,
58
+ timestamp: sentEmail.sentAt,
59
+ recipient,
60
+ providerData: { mock: true }
61
+ };
62
+ }
63
+ validateWebhook(payload, signature, _options) {
64
+ // Mock provider doesn't validate webhooks
65
+ return {
66
+ isValid: false,
67
+ error: 'Mock provider does not support webhooks'
68
+ };
69
+ }
70
+ /**
71
+ * Get all sent emails (useful for testing)
72
+ */
73
+ getSentEmails() {
74
+ return Array.from(this.sentEmails.values());
75
+ }
76
+ /**
77
+ * Clear all sent emails (useful for testing)
78
+ */
79
+ clearSentEmails() {
80
+ this.sentEmails.clear();
81
+ this.messageIdCounter = 1;
82
+ }
83
+ /**
84
+ * Get a specific sent email by ID (useful for testing)
85
+ */
86
+ getSentEmail(messageId) {
87
+ return this.sentEmails.get(messageId);
88
+ }
89
+ /**
90
+ * Log email to console (only in development)
91
+ */
92
+ logEmail(messageId, message) {
93
+ const recipients = Array.isArray(message.to)
94
+ ? message.to.map(t => t.address).join(', ')
95
+ : message.to.address;
96
+ console.log('\n' + '='.repeat(80));
97
+ console.log('📧 MOCK EMAIL SENT');
98
+ console.log('='.repeat(80));
99
+ console.log(`Message ID: ${messageId}`);
100
+ console.log(`From: ${message.from?.address || this.defaultFrom.address}`);
101
+ console.log(`To: ${recipients}`);
102
+ if (message.cc && message.cc.length > 0) {
103
+ console.log(`CC: ${message.cc.map(c => c.address).join(', ')}`);
104
+ }
105
+ if (message.bcc && message.bcc.length > 0) {
106
+ console.log(`BCC: ${message.bcc.map(b => b.address).join(', ')}`);
107
+ }
108
+ console.log(`Subject: ${message.subject}`);
109
+ console.log('-'.repeat(80));
110
+ if (message.html) {
111
+ // Extract plain text from HTML for better readability
112
+ const plainText = this.htmlToPlainText(message.html);
113
+ console.log('📄 EMAIL CONTENT (Plain Text):');
114
+ console.log(plainText);
115
+ // Try to extract 2FA code if present
116
+ const code = this.extract2FACode(message.html);
117
+ if (code) {
118
+ console.log('\n' + '🔑 '.repeat(20));
119
+ console.log(`🔐 2FA CODE DETECTED: ${code}`);
120
+ console.log('🔑 '.repeat(20));
121
+ }
122
+ }
123
+ else if (message.text) {
124
+ console.log('📄 EMAIL CONTENT:');
125
+ console.log(message.text);
126
+ // Try to extract 2FA code from text
127
+ const code = this.extract2FACode(message.text);
128
+ if (code) {
129
+ console.log('\n' + '🔑 '.repeat(20));
130
+ console.log(`🔐 2FA CODE DETECTED: ${code}`);
131
+ console.log('🔑 '.repeat(20));
132
+ }
133
+ }
134
+ if (message.attachments && message.attachments.length > 0) {
135
+ console.log(`\n📎 Attachments: ${message.attachments.length} file(s)`);
136
+ message.attachments.forEach((att, i) => {
137
+ console.log(` ${i + 1}. ${att.filename} (${att.contentType})`);
138
+ });
139
+ }
140
+ console.log('='.repeat(80) + '\n');
141
+ }
142
+ /**
143
+ * Convert HTML to plain text (basic implementation)
144
+ */
145
+ htmlToPlainText(html) {
146
+ return html
147
+ // Remove scripts and styles
148
+ .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
149
+ .replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '')
150
+ // Replace block elements with newlines
151
+ .replace(/<\/?(div|p|br|h[1-6]|li|tr)[^>]*>/gi, '\n')
152
+ // Remove all other HTML tags
153
+ .replace(/<[^>]+>/g, '')
154
+ // Decode HTML entities
155
+ .replace(/&nbsp;/g, ' ')
156
+ .replace(/&amp;/g, '&')
157
+ .replace(/&lt;/g, '<')
158
+ .replace(/&gt;/g, '>')
159
+ .replace(/&quot;/g, '"')
160
+ // Clean up whitespace
161
+ .replace(/\n\s*\n/g, '\n\n')
162
+ .trim();
163
+ }
164
+ /**
165
+ * Extract 2FA/verification code from email content
166
+ * Looks for 6-digit codes commonly used in 2FA
167
+ */
168
+ extract2FACode(content) {
169
+ // Try to find 6-digit code in common patterns
170
+ const patterns = [
171
+ /\b(\d{6})\b/, // Simple 6 digits
172
+ /code.*?(\d{6})/i, // "code: 123456"
173
+ /verification.*?(\d{6})/i, // "verification code: 123456"
174
+ /login.*?code.*?(\d{6})/i, // "login code: 123456"
175
+ /<div[^>]*>(\d{6})<\/div>/i, // In a div
176
+ /font-size:\s*32px[^>]*>(\d{6})</i, // Large font (common for codes)
177
+ /letter-spacing[^>]*>(\d{6})</i // Letter-spaced (common for codes)
178
+ ];
179
+ for (const pattern of patterns) {
180
+ const match = content.match(pattern);
181
+ if (match && match[1]) {
182
+ return match[1];
183
+ }
184
+ }
185
+ return null;
186
+ }
187
+ /**
188
+ * Simple delay helper
189
+ */
190
+ delay(ms) {
191
+ return new Promise(resolve => setTimeout(resolve, ms));
192
+ }
193
+ }
194
+ //# sourceMappingURL=MockEmailProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockEmailProvider.js","sourceRoot":"","sources":["../../src/providers/MockEmailProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { IEmailProvider, EmailMessage, EmailResult, DeliveryReport, WebhookValidationResult, RedirectEmailConfig, WebhookValidationOptions } from '../interfaces/IEmailProvider.js';
2
+ /**
3
+ * RedirectEmailProvider wraps another provider and redirects all emails to a specific address.
4
+ * Useful for development/testing to prevent accidentally sending emails to real users.
5
+ */
6
+ export declare class RedirectEmailProvider implements IEmailProvider {
7
+ private redirectTo;
8
+ private defaultFrom;
9
+ private addOriginalToSubject;
10
+ private baseProvider;
11
+ constructor(config: RedirectEmailConfig);
12
+ send(message: EmailMessage): Promise<EmailResult>;
13
+ getDeliveryReport(messageId: string): Promise<DeliveryReport | null>;
14
+ validateWebhook(payload: any, signature?: string, options?: WebhookValidationOptions): WebhookValidationResult;
15
+ /**
16
+ * Extract all original recipients from the message
17
+ */
18
+ private getOriginalRecipients;
19
+ /**
20
+ * Add a notice to the email body about the redirection
21
+ */
22
+ private addRedirectNotice;
23
+ /**
24
+ * Simple HTML escape for security
25
+ */
26
+ private escapeHtml;
27
+ }
28
+ //# sourceMappingURL=RedirectEmailProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedirectEmailProvider.d.ts","sourceRoot":"","sources":["../../src/providers/RedirectEmailProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EAEnB,wBAAwB,EAC3B,MAAM,iCAAiC,CAAC;AAGzC;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IACxD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,oBAAoB,CAAU;IACtC,OAAO,CAAC,YAAY,CAAiB;gBAEzB,MAAM,EAAE,mBAAmB;IAWjC,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA4BjD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAI1E,eAAe,CACX,OAAO,EAAE,GAAG,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,wBAAwB,GACnC,uBAAuB;IAI1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA0BzB;;OAEG;IACH,OAAO,CAAC,UAAU;CAUrB"}
@@ -0,0 +1,108 @@
1
+ import { MockEmailProvider } from './MockEmailProvider.js';
2
+ /**
3
+ * RedirectEmailProvider wraps another provider and redirects all emails to a specific address.
4
+ * Useful for development/testing to prevent accidentally sending emails to real users.
5
+ */
6
+ export class RedirectEmailProvider {
7
+ redirectTo;
8
+ defaultFrom;
9
+ addOriginalToSubject;
10
+ baseProvider;
11
+ constructor(config) {
12
+ this.redirectTo = config.redirectTo;
13
+ this.defaultFrom = config.defaultFrom;
14
+ this.addOriginalToSubject = config.addOriginalToSubject ?? true;
15
+ // Use provided base provider or default to MockEmailProvider
16
+ this.baseProvider = config.baseProvider || new MockEmailProvider({
17
+ defaultFrom: config.defaultFrom
18
+ });
19
+ }
20
+ async send(message) {
21
+ // Build list of original recipients for logging
22
+ const originalRecipients = this.getOriginalRecipients(message);
23
+ // Create modified message that redirects to the configured address
24
+ const redirectedMessage = {
25
+ ...message,
26
+ to: { address: this.redirectTo },
27
+ cc: undefined, // Clear CC
28
+ bcc: undefined, // Clear BCC
29
+ subject: this.addOriginalToSubject
30
+ ? `[REDIRECTED] ${message.subject} (Original: ${originalRecipients})`
31
+ : message.subject
32
+ };
33
+ // Add original recipients info to the email body
34
+ if (message.html) {
35
+ redirectedMessage.html = this.addRedirectNotice(message.html, originalRecipients, 'html');
36
+ }
37
+ if (message.text) {
38
+ redirectedMessage.text = this.addRedirectNotice(message.text, originalRecipients, 'text');
39
+ }
40
+ // Send via base provider
41
+ return this.baseProvider.send(redirectedMessage);
42
+ }
43
+ async getDeliveryReport(messageId) {
44
+ return this.baseProvider.getDeliveryReport(messageId);
45
+ }
46
+ validateWebhook(payload, signature, options) {
47
+ return this.baseProvider.validateWebhook(payload, signature, options);
48
+ }
49
+ /**
50
+ * Extract all original recipients from the message
51
+ */
52
+ getOriginalRecipients(message) {
53
+ const recipients = [];
54
+ // Add 'to' recipients
55
+ const toAddresses = Array.isArray(message.to) ? message.to : [message.to];
56
+ recipients.push(...toAddresses.map(addr => addr.address));
57
+ // Add CC recipients
58
+ if (message.cc && message.cc.length > 0) {
59
+ recipients.push(...message.cc.map(addr => `CC: ${addr.address}`));
60
+ }
61
+ // Add BCC recipients
62
+ if (message.bcc && message.bcc.length > 0) {
63
+ recipients.push(...message.bcc.map(addr => `BCC: ${addr.address}`));
64
+ }
65
+ return recipients.join(', ');
66
+ }
67
+ /**
68
+ * Add a notice to the email body about the redirection
69
+ */
70
+ addRedirectNotice(content, originalRecipients, type) {
71
+ const notice = type === 'html'
72
+ ? `
73
+ <div style="background-color: #fff3cd; border: 1px solid #ffc107; padding: 15px; margin-bottom: 20px; border-radius: 5px;">
74
+ <strong>⚠️ EMAIL REDIRECTED (Development Mode)</strong><br>
75
+ <p style="margin: 5px 0 0 0;">
76
+ This email was redirected from the original recipients:<br>
77
+ <strong>${this.escapeHtml(originalRecipients)}</strong>
78
+ </p>
79
+ </div>
80
+ ${content}
81
+ `
82
+ : `
83
+ ========================================
84
+ ⚠️ EMAIL REDIRECTED (Development Mode)
85
+ ========================================
86
+ This email was redirected from the original recipients:
87
+ ${originalRecipients}
88
+ ========================================
89
+
90
+ ${content}
91
+ `;
92
+ return notice;
93
+ }
94
+ /**
95
+ * Simple HTML escape for security
96
+ */
97
+ escapeHtml(text) {
98
+ const map = {
99
+ '&': '&amp;',
100
+ '<': '&lt;',
101
+ '>': '&gt;',
102
+ '"': '&quot;',
103
+ "'": '&#039;'
104
+ };
105
+ return text.replace(/[&<>"']/g, char => map[char]);
106
+ }
107
+ }
108
+ //# sourceMappingURL=RedirectEmailProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedirectEmailProvider.js","sourceRoot":"","sources":["../../src/providers/RedirectEmailProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { IEmailProvider, EmailMessage, EmailResult, DeliveryReport, WebhookValidationResult, WebhookValidationOptions, SweegoEmailConfig } from '../interfaces/IEmailProvider.js';
2
+ export declare class SweegoEmailProvider implements IEmailProvider {
3
+ private readonly config;
4
+ private readonly apiKey?;
5
+ private readonly accessToken?;
6
+ private readonly baseUrl;
7
+ private readonly providerSlug;
8
+ private readonly defaultFrom;
9
+ private readonly channel;
10
+ private readonly clientId?;
11
+ private readonly webhookSecret?;
12
+ constructor(config: SweegoEmailConfig);
13
+ send(message: EmailMessage): Promise<EmailResult>;
14
+ getDeliveryReport(messageId: string): Promise<DeliveryReport | null>;
15
+ validateWebhook(payload: any, signature?: string, options?: WebhookValidationOptions): WebhookValidationResult;
16
+ private applyMetadata;
17
+ private applyContent;
18
+ private applyAttachments;
19
+ private encodeAttachmentContent;
20
+ private normalizeRecipients;
21
+ private normalizeAddress;
22
+ private extractSweegoMetadata;
23
+ private buildHeaders;
24
+ private extractSweegoIds;
25
+ private mapProviderStatus;
26
+ private mapWebhookPayload;
27
+ private extractSweegoUid;
28
+ private parseTimestamp;
29
+ private normalizeBaseUrl;
30
+ private safeParseResponse;
31
+ private extractProviderError;
32
+ private normalizeHeaders;
33
+ private stringifyPayload;
34
+ private parseWebhookSecret;
35
+ }
36
+ //# sourceMappingURL=SweegoEmailProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SweegoEmailProvider.d.ts","sourceRoot":"","sources":["../../src/providers/SweegoEmailProvider.ts"],"names":[],"mappings":"AACA,OAAO,EACH,cAAc,EACd,YAAY,EACZ,WAAW,EACX,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EAIpB,MAAM,iCAAiC,CAAC;AAmBzC,qBAAa,mBAAoB,YAAW,cAAc;IAU1C,OAAO,CAAC,QAAQ,CAAC,MAAM;IATnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;gBAEX,MAAM,EAAE,iBAAiB;IAgBhD,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA0EjD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAgC1E,eAAe,CACX,OAAO,EAAE,GAAG,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,wBAAwB,GACnC,uBAAuB;IAsC1B,OAAO,CAAC,aAAa;IAwCrB,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,qBAAqB;IAQ7B,OAAO,CAAC,YAAY;IAsBpB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,iBAAiB;IAsBzB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,kBAAkB;CAW7B"}