@memberjunction/communication-sendgrid 5.49.0 → 5.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SendGridProvider.d.ts +111 -4
- package/dist/SendGridProvider.d.ts.map +1 -1
- package/dist/SendGridProvider.js +349 -9
- package/dist/SendGridProvider.js.map +1 -1
- package/dist/__tests__/DryRun.test.js +4 -1
- package/dist/__tests__/DryRun.test.js.map +1 -1
- package/dist/__tests__/SendGridInbound.test.d.ts +2 -0
- package/dist/__tests__/SendGridInbound.test.d.ts.map +1 -0
- package/dist/__tests__/SendGridInbound.test.js +351 -0
- package/dist/__tests__/SendGridInbound.test.js.map +1 -0
- package/dist/__tests__/SendGridProvider.test.js +6 -3
- package/dist/__tests__/SendGridProvider.test.js.map +1 -1
- package/package.json +5 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseCommunicationProvider, CreateDraftParams, CreateDraftResult, ForwardMessageParams, ForwardMessageResult, GetMessagesParams, GetMessagesResult, MessageResult, ProcessedMessage, ProviderCredentialsBase, ReplyToMessageParams, ReplyToMessageResult, ProviderOperation } from "@memberjunction/communication-types";
|
|
1
|
+
import { BaseCommunicationProvider, BaseMessageResult, CreateDraftParams, CreateDraftResult, CreateSubscriptionParams, DeleteSubscriptionParams, ForwardMessageParams, ForwardMessageResult, GetMessagesParams, GetMessagesResult, MessageResult, ParseNotificationResult, ProcessedMessage, ProviderCredentialsBase, ReplyToMessageParams, ReplyToMessageResult, SubscriptionCapabilities, SubscriptionResult, WebhookNotificationInput, ProviderOperation } from "@memberjunction/communication-types";
|
|
2
2
|
/**
|
|
3
3
|
* Credentials for SendGrid email provider.
|
|
4
4
|
*
|
|
@@ -30,13 +30,29 @@ export interface SendGridCredentials extends ProviderCredentialsBase {
|
|
|
30
30
|
* SendGrid is a transactional email service. This provider supports:
|
|
31
31
|
* - Sending single messages
|
|
32
32
|
* - Sending to multiple recipients (via engine)
|
|
33
|
+
* - Inbound email via the SendGrid **Inbound Parse Webhook** (push notifications):
|
|
34
|
+
* - {@link CreateSubscription} / {@link DeleteSubscription} manage the hostname→URL
|
|
35
|
+
* Inbound Parse mapping via SendGrid's REST API
|
|
36
|
+
* (`/v3/user/webhooks/parse/settings`).
|
|
37
|
+
* - {@link ParseNotification} parses the inbound `multipart/form-data` POST that
|
|
38
|
+
* SendGrid delivers to the consumer's URL. This is INLINE delivery: the POST body
|
|
39
|
+
* contains the ENTIRE parsed email, so {@link NormalizedNotification.Message} is
|
|
40
|
+
* populated and there is NO re-fetch (SendGrid has no inbound-retrieval API).
|
|
33
41
|
*
|
|
34
42
|
* It does NOT support:
|
|
35
|
-
* - Fetching messages (no inbox access)
|
|
43
|
+
* - Fetching messages (no inbox access / no inbound-retrieval API)
|
|
36
44
|
* - Forwarding messages
|
|
37
45
|
* - Replying to messages
|
|
38
46
|
* - Creating drafts
|
|
39
47
|
*
|
|
48
|
+
* ## SECURITY CAVEAT (Inbound Parse)
|
|
49
|
+
* SendGrid Inbound Parse is **unsigned** — there is no cryptographic signature on the
|
|
50
|
+
* inbound POST and no expiry on the registration. Because the message is delivered inline
|
|
51
|
+
* (the payload IS the data path), a forged notification is NOT harmless. Consumers MUST
|
|
52
|
+
* protect the notification endpoint out-of-band: use a hard-to-guess URL secret path
|
|
53
|
+
* and/or network controls (IP allow-listing, private ingress). {@link ParseNotification}
|
|
54
|
+
* therefore always returns `SignatureValid: undefined` (no scheme to verify).
|
|
55
|
+
*
|
|
40
56
|
* @example
|
|
41
57
|
* ```typescript
|
|
42
58
|
* // Using environment credentials (default)
|
|
@@ -51,8 +67,10 @@ export interface SendGridCredentials extends ProviderCredentialsBase {
|
|
|
51
67
|
export declare class SendGridProvider extends BaseCommunicationProvider {
|
|
52
68
|
/**
|
|
53
69
|
* Returns the list of operations supported by the SendGrid provider.
|
|
54
|
-
* SendGrid is a transactional email service
|
|
55
|
-
*
|
|
70
|
+
* SendGrid is a transactional email service for OUTBOUND, plus INBOUND via the
|
|
71
|
+
* Inbound Parse Webhook (subscription management + inbound notification parsing).
|
|
72
|
+
* It does NOT support mailbox operations like fetching messages, folders, or
|
|
73
|
+
* attachments (there is no inbound-retrieval API).
|
|
56
74
|
*/
|
|
57
75
|
getSupportedOperations(): ProviderOperation[];
|
|
58
76
|
/**
|
|
@@ -81,5 +99,94 @@ export declare class SendGridProvider extends BaseCommunicationProvider {
|
|
|
81
99
|
* @remarks SendGrid does not support creating drafts (no mailbox access).
|
|
82
100
|
*/
|
|
83
101
|
CreateDraft(params: CreateDraftParams, credentials?: SendGridCredentials): Promise<CreateDraftResult>;
|
|
102
|
+
/** SendGrid REST endpoint for the Inbound Parse settings collection. */
|
|
103
|
+
private static readonly PARSE_SETTINGS_URL;
|
|
104
|
+
/**
|
|
105
|
+
* Resolves and validates the SendGrid API key using the same precedence as
|
|
106
|
+
* {@link SendSingleMessage} (request value overrides env, respecting
|
|
107
|
+
* `disableEnvironmentFallback`). Throws when no key can be resolved; callers invoke
|
|
108
|
+
* this inside a try/catch so a missing key surfaces as a `Success: false` result.
|
|
109
|
+
*/
|
|
110
|
+
private resolveApiKey;
|
|
111
|
+
/**
|
|
112
|
+
* Registers a hostname→URL Inbound Parse mapping with SendGrid so inbound email to
|
|
113
|
+
* `params.Identifier` (the receiving hostname/subdomain, e.g. `parse.example.com`) is
|
|
114
|
+
* POSTed to `params.NotificationUrl`.
|
|
115
|
+
*
|
|
116
|
+
* The returned `SubscriptionID` is the hostname itself — it is the key SendGrid uses
|
|
117
|
+
* for {@link DeleteSubscription}. `ExpiresAt` is always `undefined` (Inbound Parse
|
|
118
|
+
* settings never expire).
|
|
119
|
+
*
|
|
120
|
+
* @param params - Identifier (receiving hostname) and NotificationUrl (https endpoint)
|
|
121
|
+
* @param credentials - Optional SendGrid credentials override for this request
|
|
122
|
+
* @returns Promise<SubscriptionResult> - hostname as SubscriptionID on success
|
|
123
|
+
*/
|
|
124
|
+
CreateSubscription(params: CreateSubscriptionParams, credentials?: SendGridCredentials): Promise<SubscriptionResult>;
|
|
125
|
+
/**
|
|
126
|
+
* Deletes an Inbound Parse mapping by hostname (`params.SubscriptionID`). Idempotent:
|
|
127
|
+
* a 404 (mapping already gone) is treated as success.
|
|
128
|
+
*
|
|
129
|
+
* @param params - SubscriptionID is the hostname returned by {@link CreateSubscription}
|
|
130
|
+
* @param credentials - Optional SendGrid credentials override for this request
|
|
131
|
+
* @returns Promise<BaseMessageResult> - Result of the delete operation
|
|
132
|
+
*/
|
|
133
|
+
DeleteSubscription(params: DeleteSubscriptionParams, credentials?: SendGridCredentials): Promise<BaseMessageResult>;
|
|
134
|
+
/**
|
|
135
|
+
* Parses an inbound SendGrid Inbound Parse notification. PURE: no network calls, and
|
|
136
|
+
* safe on hostile/garbage input — never throws; returns `Success: false` with a 400
|
|
137
|
+
* suggested status on malformed payloads.
|
|
138
|
+
*
|
|
139
|
+
* The body is `multipart/form-data`; the boundary is read from the
|
|
140
|
+
* `content-type` header. The full parsed email is delivered inline, so this populates
|
|
141
|
+
* {@link NormalizedNotification.Message} directly (INLINE mode — no re-fetch).
|
|
142
|
+
*
|
|
143
|
+
* `SignatureValid` is always `undefined`: Inbound Parse has NO signature scheme. See
|
|
144
|
+
* the class-level SECURITY CAVEAT — consumers must protect the endpoint out-of-band.
|
|
145
|
+
*
|
|
146
|
+
* LIMITATION: binary attachment parts are intentionally NOT decoded. When attachment
|
|
147
|
+
* parts are present, only their COUNT is recorded (`RawData.attachmentCount`); the
|
|
148
|
+
* bytes are skipped. Consumers needing attachments must read the raw request directly.
|
|
149
|
+
*
|
|
150
|
+
* @param input - Transport-neutral capture of the inbound webhook request
|
|
151
|
+
* @param _credentials - Unused (no signature scheme to verify)
|
|
152
|
+
* @returns Promise<ParseNotificationResult> - One normalized notification, inline Message populated
|
|
153
|
+
*/
|
|
154
|
+
ParseNotification(input: WebhookNotificationInput, _credentials?: SendGridCredentials): Promise<ParseNotificationResult>;
|
|
155
|
+
/**
|
|
156
|
+
* Returns SendGrid's Inbound Parse subscription capabilities. Inbound Parse settings
|
|
157
|
+
* never expire (no `MaxLifetimeMinutes`), watch only inbound-created messages, need no
|
|
158
|
+
* endpoint validation handshake, are manageable via the REST API, and deliver the full
|
|
159
|
+
* payload inline.
|
|
160
|
+
*/
|
|
161
|
+
GetSubscriptionCapabilities(): SubscriptionCapabilities;
|
|
162
|
+
/**
|
|
163
|
+
* Extracts the multipart boundary from a `content-type` header value. Handles both
|
|
164
|
+
* quoted (`boundary="xyz"`) and unquoted (`boundary=xyz`) forms. Returns `undefined`
|
|
165
|
+
* when no boundary is present.
|
|
166
|
+
*/
|
|
167
|
+
private extractBoundary;
|
|
168
|
+
/**
|
|
169
|
+
* Small, dependency-free `multipart/form-data` parser. Splits the body on the
|
|
170
|
+
* `--<boundary>` delimiter and, for each part, reads the `Content-Disposition` header
|
|
171
|
+
* to get the field `name`, then captures the part body (trimming the single trailing
|
|
172
|
+
* CRLF that precedes the next delimiter).
|
|
173
|
+
*
|
|
174
|
+
* Only TEXT form fields are captured into `Fields`. Parts carrying a `filename=` (file
|
|
175
|
+
* attachments) are counted in `AttachmentCount` and their bytes are skipped — this
|
|
176
|
+
* parser deliberately does not decode binary attachment content.
|
|
177
|
+
*/
|
|
178
|
+
private parseMultipartFormData;
|
|
179
|
+
/**
|
|
180
|
+
* Determines the receiving identifier for an inbound message. Prefers the parsed
|
|
181
|
+
* SendGrid `envelope` JSON (`{ "to": [...], "from": "..." }`) `to` value; falls back to
|
|
182
|
+
* the raw `to` form field. Returns `undefined` when neither is present.
|
|
183
|
+
*/
|
|
184
|
+
private resolveInboundIdentifier;
|
|
185
|
+
/**
|
|
186
|
+
* `JSON.parse` that returns an object or `undefined` — never throws. Used to attach the
|
|
187
|
+
* SendGrid REST response body to {@link SubscriptionResult.Result} without risking a
|
|
188
|
+
* secondary crash on a non-JSON body.
|
|
189
|
+
*/
|
|
190
|
+
private safeParseJsonObject;
|
|
84
191
|
}
|
|
85
192
|
//# sourceMappingURL=SendGridProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SendGridProvider.d.ts","sourceRoot":"","sources":["../src/SendGridProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"SendGridProvider.d.ts","sourceRoot":"","sources":["../src/SendGridProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACxB,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EAEpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EAGb,uBAAuB,EACvB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EAEpB,wBAAwB,EACxB,kBAAkB,EAElB,wBAAwB,EACxB,iBAAiB,EACpB,MAAM,qCAAqC,CAAC;AAM7C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,mBAAoB,SAAQ,uBAAuB;IAChE;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBACa,gBAAiB,SAAQ,yBAAyB;IAC3D;;;;;;OAMG;IACa,sBAAsB,IAAI,iBAAiB,EAAE;IAa7D;;;;OAIG;IACU,iBAAiB,CAC1B,OAAO,EAAE,gBAAgB,EACzB,WAAW,CAAC,EAAE,mBAAmB,GAClC,OAAO,CAAC,aAAa,CAAC;IA4GzB;;;OAGG;IACU,WAAW,CACpB,MAAM,EAAE,iBAAiB,EACzB,WAAW,CAAC,EAAE,mBAAmB,GAClC,OAAO,CAAC,iBAAiB,CAAC;IAI7B;;;OAGG;IACI,cAAc,CACjB,MAAM,EAAE,oBAAoB,EAC5B,WAAW,CAAC,EAAE,mBAAmB,GAClC,OAAO,CAAC,oBAAoB,CAAC;IAIhC;;;OAGG;IACI,cAAc,CACjB,MAAM,EAAE,oBAAoB,EAC5B,WAAW,CAAC,EAAE,mBAAmB,GAClC,OAAO,CAAC,oBAAoB,CAAC;IAIhC;;;OAGG;IACU,WAAW,CACpB,MAAM,EAAE,iBAAiB,EACzB,WAAW,CAAC,EAAE,mBAAmB,GAClC,OAAO,CAAC,iBAAiB,CAAC;IAgB7B,wEAAwE;IACxE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAA8D;IAExG;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAOrB;;;;;;;;;;;;OAYG;IACmB,kBAAkB,CACpC,MAAM,EAAE,wBAAwB,EAChC,WAAW,CAAC,EAAE,mBAAmB,GAClC,OAAO,CAAC,kBAAkB,CAAC;IAiD9B;;;;;;;OAOG;IACmB,kBAAkB,CACpC,MAAM,EAAE,wBAAwB,EAChC,WAAW,CAAC,EAAE,mBAAmB,GAClC,OAAO,CAAC,iBAAiB,CAAC;IA6B7B;;;;;;;;;;;;;;;;;;;OAmBG;IACmB,iBAAiB,CACnC,KAAK,EAAE,wBAAwB,EAC/B,YAAY,CAAC,EAAE,mBAAmB,GACnC,OAAO,CAAC,uBAAuB,CAAC;IA2EnC;;;;;OAKG;IACa,2BAA2B,IAAI,wBAAwB;IAUvE;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAKvB;;;;;;;;;OASG;IACH,OAAO,CAAC,sBAAsB;IA8C9B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAoBhC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;CAW9B"}
|
package/dist/SendGridProvider.js
CHANGED
|
@@ -4,7 +4,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
var SendGridProvider_1;
|
|
8
|
+
import { BaseCommunicationProvider, ParseEmailAddressList, resolveCredentialValue, validateRequiredCredentials } from "@memberjunction/communication-types";
|
|
8
9
|
import { RegisterClass } from "@memberjunction/global";
|
|
9
10
|
import sgMail from '@sendgrid/mail';
|
|
10
11
|
import { __API_KEY } from "./config.js";
|
|
@@ -16,13 +17,29 @@ import { LogError, LogStatus } from "@memberjunction/core";
|
|
|
16
17
|
* SendGrid is a transactional email service. This provider supports:
|
|
17
18
|
* - Sending single messages
|
|
18
19
|
* - Sending to multiple recipients (via engine)
|
|
20
|
+
* - Inbound email via the SendGrid **Inbound Parse Webhook** (push notifications):
|
|
21
|
+
* - {@link CreateSubscription} / {@link DeleteSubscription} manage the hostname→URL
|
|
22
|
+
* Inbound Parse mapping via SendGrid's REST API
|
|
23
|
+
* (`/v3/user/webhooks/parse/settings`).
|
|
24
|
+
* - {@link ParseNotification} parses the inbound `multipart/form-data` POST that
|
|
25
|
+
* SendGrid delivers to the consumer's URL. This is INLINE delivery: the POST body
|
|
26
|
+
* contains the ENTIRE parsed email, so {@link NormalizedNotification.Message} is
|
|
27
|
+
* populated and there is NO re-fetch (SendGrid has no inbound-retrieval API).
|
|
19
28
|
*
|
|
20
29
|
* It does NOT support:
|
|
21
|
-
* - Fetching messages (no inbox access)
|
|
30
|
+
* - Fetching messages (no inbox access / no inbound-retrieval API)
|
|
22
31
|
* - Forwarding messages
|
|
23
32
|
* - Replying to messages
|
|
24
33
|
* - Creating drafts
|
|
25
34
|
*
|
|
35
|
+
* ## SECURITY CAVEAT (Inbound Parse)
|
|
36
|
+
* SendGrid Inbound Parse is **unsigned** — there is no cryptographic signature on the
|
|
37
|
+
* inbound POST and no expiry on the registration. Because the message is delivered inline
|
|
38
|
+
* (the payload IS the data path), a forged notification is NOT harmless. Consumers MUST
|
|
39
|
+
* protect the notification endpoint out-of-band: use a hard-to-guess URL secret path
|
|
40
|
+
* and/or network controls (IP allow-listing, private ingress). {@link ParseNotification}
|
|
41
|
+
* therefore always returns `SignatureValid: undefined` (no scheme to verify).
|
|
42
|
+
*
|
|
26
43
|
* @example
|
|
27
44
|
* ```typescript
|
|
28
45
|
* // Using environment credentials (default)
|
|
@@ -35,17 +52,24 @@ import { LogError, LogStatus } from "@memberjunction/core";
|
|
|
35
52
|
* ```
|
|
36
53
|
*/
|
|
37
54
|
let SendGridProvider = class SendGridProvider extends BaseCommunicationProvider {
|
|
55
|
+
static { SendGridProvider_1 = this; }
|
|
38
56
|
/**
|
|
39
57
|
* Returns the list of operations supported by the SendGrid provider.
|
|
40
|
-
* SendGrid is a transactional email service
|
|
41
|
-
*
|
|
58
|
+
* SendGrid is a transactional email service for OUTBOUND, plus INBOUND via the
|
|
59
|
+
* Inbound Parse Webhook (subscription management + inbound notification parsing).
|
|
60
|
+
* It does NOT support mailbox operations like fetching messages, folders, or
|
|
61
|
+
* attachments (there is no inbound-retrieval API).
|
|
42
62
|
*/
|
|
43
63
|
getSupportedOperations() {
|
|
44
64
|
return [
|
|
45
|
-
'SendSingleMessage'
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
|
|
65
|
+
'SendSingleMessage',
|
|
66
|
+
// Inbound Parse Webhook: register/unregister the hostname→URL mapping and
|
|
67
|
+
// parse the inline multipart/form-data POST SendGrid delivers.
|
|
68
|
+
'CreateSubscription',
|
|
69
|
+
'DeleteSubscription',
|
|
70
|
+
'ParseNotification'
|
|
71
|
+
// Note: no GetMessages/ForwardMessage/ReplyToMessage/CreateDraft (no inbox).
|
|
72
|
+
// No RenewSubscription — Inbound Parse settings never expire.
|
|
49
73
|
];
|
|
50
74
|
}
|
|
51
75
|
/**
|
|
@@ -173,8 +197,324 @@ let SendGridProvider = class SendGridProvider extends BaseCommunicationProvider
|
|
|
173
197
|
ErrorMessage: 'SendGrid does not support creating draft messages. Drafts are only supported by email providers with mailbox access (Gmail, MS Graph).'
|
|
174
198
|
};
|
|
175
199
|
}
|
|
200
|
+
// ========================================================================
|
|
201
|
+
// PUSH-NOTIFICATION SUBSCRIPTIONS (Inbound Parse Webhook)
|
|
202
|
+
// SendGrid Inbound Parse is INLINE-mode: the inbound POST carries the full parsed
|
|
203
|
+
// email, so ParseNotification populates NormalizedNotification.Message and there is
|
|
204
|
+
// no re-fetch. Management (create/delete the hostname→URL mapping) rides SendGrid's
|
|
205
|
+
// REST API via the global fetch. The provider is stateless — the consumer persists
|
|
206
|
+
// the hostname (the DELETE key). No RenewSubscription: settings never expire.
|
|
207
|
+
// ========================================================================
|
|
208
|
+
/** SendGrid REST endpoint for the Inbound Parse settings collection. */
|
|
209
|
+
static { this.PARSE_SETTINGS_URL = 'https://api.sendgrid.com/v3/user/webhooks/parse/settings'; }
|
|
210
|
+
/**
|
|
211
|
+
* Resolves and validates the SendGrid API key using the same precedence as
|
|
212
|
+
* {@link SendSingleMessage} (request value overrides env, respecting
|
|
213
|
+
* `disableEnvironmentFallback`). Throws when no key can be resolved; callers invoke
|
|
214
|
+
* this inside a try/catch so a missing key surfaces as a `Success: false` result.
|
|
215
|
+
*/
|
|
216
|
+
resolveApiKey(credentials) {
|
|
217
|
+
const disableFallback = credentials?.disableEnvironmentFallback ?? false;
|
|
218
|
+
const apiKey = resolveCredentialValue(credentials?.apiKey, __API_KEY, disableFallback);
|
|
219
|
+
validateRequiredCredentials({ apiKey }, ['apiKey'], 'SendGrid');
|
|
220
|
+
return apiKey;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Registers a hostname→URL Inbound Parse mapping with SendGrid so inbound email to
|
|
224
|
+
* `params.Identifier` (the receiving hostname/subdomain, e.g. `parse.example.com`) is
|
|
225
|
+
* POSTed to `params.NotificationUrl`.
|
|
226
|
+
*
|
|
227
|
+
* The returned `SubscriptionID` is the hostname itself — it is the key SendGrid uses
|
|
228
|
+
* for {@link DeleteSubscription}. `ExpiresAt` is always `undefined` (Inbound Parse
|
|
229
|
+
* settings never expire).
|
|
230
|
+
*
|
|
231
|
+
* @param params - Identifier (receiving hostname) and NotificationUrl (https endpoint)
|
|
232
|
+
* @param credentials - Optional SendGrid credentials override for this request
|
|
233
|
+
* @returns Promise<SubscriptionResult> - hostname as SubscriptionID on success
|
|
234
|
+
*/
|
|
235
|
+
async CreateSubscription(params, credentials) {
|
|
236
|
+
// Fail-fast input validation (before any network call).
|
|
237
|
+
if (!params.Identifier) {
|
|
238
|
+
return { Success: false, ErrorMessage: 'CreateSubscription requires Identifier (the receiving hostname, e.g. "parse.example.com")' };
|
|
239
|
+
}
|
|
240
|
+
if (!params.NotificationUrl || !params.NotificationUrl.toLowerCase().startsWith('https://')) {
|
|
241
|
+
return { Success: false, ErrorMessage: 'NotificationUrl must be an https:// URL' };
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const apiKey = this.resolveApiKey(credentials);
|
|
245
|
+
const resp = await fetch(SendGridProvider_1.PARSE_SETTINGS_URL, {
|
|
246
|
+
method: 'POST',
|
|
247
|
+
headers: {
|
|
248
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
249
|
+
'Content-Type': 'application/json'
|
|
250
|
+
},
|
|
251
|
+
body: JSON.stringify({
|
|
252
|
+
hostname: params.Identifier,
|
|
253
|
+
url: params.NotificationUrl,
|
|
254
|
+
spam_check: false,
|
|
255
|
+
send_raw: false
|
|
256
|
+
})
|
|
257
|
+
});
|
|
258
|
+
const text = await resp.text();
|
|
259
|
+
if (!resp.ok) {
|
|
260
|
+
LogError(`SendGrid Inbound Parse create failed for hostname '${params.Identifier}' — status ${resp.status}. Response: ${text}`);
|
|
261
|
+
return {
|
|
262
|
+
Success: false,
|
|
263
|
+
ErrorMessage: `SendGrid Inbound Parse create failed: ${resp.status} ${text}`
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
Success: true,
|
|
268
|
+
SubscriptionID: params.Identifier, // hostname is the DELETE key
|
|
269
|
+
ExpiresAt: undefined, // Inbound Parse settings never expire
|
|
270
|
+
Result: this.safeParseJsonObject(text)
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
catch (ex) {
|
|
274
|
+
LogError('Error creating SendGrid Inbound Parse subscription', undefined, ex);
|
|
275
|
+
return {
|
|
276
|
+
Success: false,
|
|
277
|
+
ErrorMessage: `Error creating subscription: ${ex instanceof Error ? ex.message : String(ex)}`
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Deletes an Inbound Parse mapping by hostname (`params.SubscriptionID`). Idempotent:
|
|
283
|
+
* a 404 (mapping already gone) is treated as success.
|
|
284
|
+
*
|
|
285
|
+
* @param params - SubscriptionID is the hostname returned by {@link CreateSubscription}
|
|
286
|
+
* @param credentials - Optional SendGrid credentials override for this request
|
|
287
|
+
* @returns Promise<BaseMessageResult> - Result of the delete operation
|
|
288
|
+
*/
|
|
289
|
+
async DeleteSubscription(params, credentials) {
|
|
290
|
+
try {
|
|
291
|
+
const apiKey = this.resolveApiKey(credentials);
|
|
292
|
+
const url = `${SendGridProvider_1.PARSE_SETTINGS_URL}/${encodeURIComponent(params.SubscriptionID)}`;
|
|
293
|
+
const resp = await fetch(url, {
|
|
294
|
+
method: 'DELETE',
|
|
295
|
+
headers: { 'Authorization': `Bearer ${apiKey}` }
|
|
296
|
+
});
|
|
297
|
+
if (resp.ok || resp.status === 404) {
|
|
298
|
+
// 404 = already gone; deletion is idempotent from the consumer's perspective.
|
|
299
|
+
return { Success: true };
|
|
300
|
+
}
|
|
301
|
+
const text = await resp.text();
|
|
302
|
+
LogError(`SendGrid Inbound Parse delete failed for hostname '${params.SubscriptionID}' — status ${resp.status}. Response: ${text}`);
|
|
303
|
+
return {
|
|
304
|
+
Success: false,
|
|
305
|
+
ErrorMessage: `SendGrid Inbound Parse delete failed: ${resp.status} ${text}`
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
catch (ex) {
|
|
309
|
+
LogError('Error deleting SendGrid Inbound Parse subscription', undefined, ex);
|
|
310
|
+
return {
|
|
311
|
+
Success: false,
|
|
312
|
+
ErrorMessage: `Error deleting subscription: ${ex instanceof Error ? ex.message : String(ex)}`
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Parses an inbound SendGrid Inbound Parse notification. PURE: no network calls, and
|
|
318
|
+
* safe on hostile/garbage input — never throws; returns `Success: false` with a 400
|
|
319
|
+
* suggested status on malformed payloads.
|
|
320
|
+
*
|
|
321
|
+
* The body is `multipart/form-data`; the boundary is read from the
|
|
322
|
+
* `content-type` header. The full parsed email is delivered inline, so this populates
|
|
323
|
+
* {@link NormalizedNotification.Message} directly (INLINE mode — no re-fetch).
|
|
324
|
+
*
|
|
325
|
+
* `SignatureValid` is always `undefined`: Inbound Parse has NO signature scheme. See
|
|
326
|
+
* the class-level SECURITY CAVEAT — consumers must protect the endpoint out-of-band.
|
|
327
|
+
*
|
|
328
|
+
* LIMITATION: binary attachment parts are intentionally NOT decoded. When attachment
|
|
329
|
+
* parts are present, only their COUNT is recorded (`RawData.attachmentCount`); the
|
|
330
|
+
* bytes are skipped. Consumers needing attachments must read the raw request directly.
|
|
331
|
+
*
|
|
332
|
+
* @param input - Transport-neutral capture of the inbound webhook request
|
|
333
|
+
* @param _credentials - Unused (no signature scheme to verify)
|
|
334
|
+
* @returns Promise<ParseNotificationResult> - One normalized notification, inline Message populated
|
|
335
|
+
*/
|
|
336
|
+
async ParseNotification(input, _credentials) {
|
|
337
|
+
const fail = (msg) => ({
|
|
338
|
+
Success: false,
|
|
339
|
+
ErrorMessage: msg,
|
|
340
|
+
Notifications: [],
|
|
341
|
+
SuggestedResponseStatus: 400
|
|
342
|
+
});
|
|
343
|
+
const contentType = input?.Headers?.['content-type'] ?? '';
|
|
344
|
+
if (!contentType.toLowerCase().includes('multipart/form-data')) {
|
|
345
|
+
return fail('Expected multipart/form-data content-type for SendGrid Inbound Parse');
|
|
346
|
+
}
|
|
347
|
+
const boundary = this.extractBoundary(contentType);
|
|
348
|
+
if (!boundary) {
|
|
349
|
+
return fail('Missing multipart boundary in content-type header');
|
|
350
|
+
}
|
|
351
|
+
const rawBody = input?.RawBody;
|
|
352
|
+
if (!rawBody || rawBody.trim().length === 0) {
|
|
353
|
+
return fail('Empty notification body');
|
|
354
|
+
}
|
|
355
|
+
let fields;
|
|
356
|
+
let attachmentCount;
|
|
357
|
+
try {
|
|
358
|
+
const parsed = this.parseMultipartFormData(rawBody, boundary);
|
|
359
|
+
fields = parsed.Fields;
|
|
360
|
+
attachmentCount = parsed.AttachmentCount;
|
|
361
|
+
}
|
|
362
|
+
catch (ex) {
|
|
363
|
+
return fail(`Failed to parse multipart body: ${ex instanceof Error ? ex.message : String(ex)}`);
|
|
364
|
+
}
|
|
365
|
+
if (Object.keys(fields).length === 0 && attachmentCount === 0) {
|
|
366
|
+
return fail('No form fields found in multipart body');
|
|
367
|
+
}
|
|
368
|
+
const from = fields['from'] ?? '';
|
|
369
|
+
const to = fields['to'] ?? '';
|
|
370
|
+
const cc = fields['cc'] ?? '';
|
|
371
|
+
const subject = fields['subject'] ?? '';
|
|
372
|
+
const text = fields['text'] ?? '';
|
|
373
|
+
const html = fields['html'] ?? '';
|
|
374
|
+
const rawData = { ...fields };
|
|
375
|
+
if (attachmentCount > 0) {
|
|
376
|
+
rawData['attachmentCount'] = attachmentCount;
|
|
377
|
+
}
|
|
378
|
+
const message = {
|
|
379
|
+
From: from,
|
|
380
|
+
To: to,
|
|
381
|
+
ToRecipients: ParseEmailAddressList(to),
|
|
382
|
+
CCRecipients: ParseEmailAddressList(cc),
|
|
383
|
+
Subject: subject,
|
|
384
|
+
Body: text || html || '' // INLINE payload — prefer plain text, fall back to HTML
|
|
385
|
+
};
|
|
386
|
+
const notification = {
|
|
387
|
+
Kind: 'message',
|
|
388
|
+
ChangeType: 'created',
|
|
389
|
+
MessageIDs: [], // no message id and no pull path (SendGrid has no inbound-retrieval API)
|
|
390
|
+
Identifier: this.resolveInboundIdentifier(fields['envelope'], to),
|
|
391
|
+
Message: message,
|
|
392
|
+
RawData: rawData
|
|
393
|
+
};
|
|
394
|
+
return {
|
|
395
|
+
Success: true,
|
|
396
|
+
SignatureValid: undefined, // Inbound Parse is unsigned — no scheme to verify
|
|
397
|
+
Notifications: [notification],
|
|
398
|
+
SuggestedResponseStatus: 200
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Returns SendGrid's Inbound Parse subscription capabilities. Inbound Parse settings
|
|
403
|
+
* never expire (no `MaxLifetimeMinutes`), watch only inbound-created messages, need no
|
|
404
|
+
* endpoint validation handshake, are manageable via the REST API, and deliver the full
|
|
405
|
+
* payload inline.
|
|
406
|
+
*/
|
|
407
|
+
GetSubscriptionCapabilities() {
|
|
408
|
+
return {
|
|
409
|
+
MaxLifetimeMinutes: undefined, // Inbound Parse settings never expire
|
|
410
|
+
SupportedChangeTypes: ['created'],
|
|
411
|
+
RequiresEndpointValidation: false,
|
|
412
|
+
SupportsSubscriptionManagement: true,
|
|
413
|
+
DeliversPayloadInline: true
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Extracts the multipart boundary from a `content-type` header value. Handles both
|
|
418
|
+
* quoted (`boundary="xyz"`) and unquoted (`boundary=xyz`) forms. Returns `undefined`
|
|
419
|
+
* when no boundary is present.
|
|
420
|
+
*/
|
|
421
|
+
extractBoundary(contentType) {
|
|
422
|
+
const match = /boundary=(?:"([^"]+)"|([^;\s]+))/i.exec(contentType);
|
|
423
|
+
return match?.[1] ?? match?.[2] ?? undefined;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Small, dependency-free `multipart/form-data` parser. Splits the body on the
|
|
427
|
+
* `--<boundary>` delimiter and, for each part, reads the `Content-Disposition` header
|
|
428
|
+
* to get the field `name`, then captures the part body (trimming the single trailing
|
|
429
|
+
* CRLF that precedes the next delimiter).
|
|
430
|
+
*
|
|
431
|
+
* Only TEXT form fields are captured into `Fields`. Parts carrying a `filename=` (file
|
|
432
|
+
* attachments) are counted in `AttachmentCount` and their bytes are skipped — this
|
|
433
|
+
* parser deliberately does not decode binary attachment content.
|
|
434
|
+
*/
|
|
435
|
+
parseMultipartFormData(rawBody, boundary) {
|
|
436
|
+
const fields = {};
|
|
437
|
+
let attachmentCount = 0;
|
|
438
|
+
const delimiter = `--${boundary}`;
|
|
439
|
+
for (const segment of rawBody.split(delimiter)) {
|
|
440
|
+
// Drop a single leading CRLF/LF that follows the delimiter.
|
|
441
|
+
const part = segment.replace(/^\r?\n/, '');
|
|
442
|
+
// Skip the preamble (empty) and the closing marker segment (`--` then optional CRLF).
|
|
443
|
+
if (!part || part.startsWith('--')) {
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
// Separate part headers from the part body at the first blank line.
|
|
447
|
+
let sepIdx = part.indexOf('\r\n\r\n');
|
|
448
|
+
let sepLen = 4;
|
|
449
|
+
if (sepIdx === -1) {
|
|
450
|
+
sepIdx = part.indexOf('\n\n');
|
|
451
|
+
sepLen = 2;
|
|
452
|
+
}
|
|
453
|
+
if (sepIdx === -1) {
|
|
454
|
+
continue; // no header/body separator — not a well-formed part
|
|
455
|
+
}
|
|
456
|
+
const headerBlock = part.slice(0, sepIdx);
|
|
457
|
+
const value = part.slice(sepIdx + sepLen).replace(/\r?\n$/, '');
|
|
458
|
+
const disposition = /content-disposition:\s*form-data;([^\r\n]*)/i.exec(headerBlock);
|
|
459
|
+
if (!disposition) {
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
const nameMatch = /name="([^"]*)"/i.exec(disposition[1]);
|
|
463
|
+
if (!nameMatch) {
|
|
464
|
+
continue;
|
|
465
|
+
}
|
|
466
|
+
if (/filename="?/i.test(disposition[1])) {
|
|
467
|
+
attachmentCount++; // attachment part — count it, skip the bytes
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
fields[nameMatch[1]] = value;
|
|
471
|
+
}
|
|
472
|
+
return { Fields: fields, AttachmentCount: attachmentCount };
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Determines the receiving identifier for an inbound message. Prefers the parsed
|
|
476
|
+
* SendGrid `envelope` JSON (`{ "to": [...], "from": "..." }`) `to` value; falls back to
|
|
477
|
+
* the raw `to` form field. Returns `undefined` when neither is present.
|
|
478
|
+
*/
|
|
479
|
+
resolveInboundIdentifier(envelope, toField) {
|
|
480
|
+
if (envelope) {
|
|
481
|
+
try {
|
|
482
|
+
const parsed = JSON.parse(envelope);
|
|
483
|
+
if (parsed && typeof parsed === 'object') {
|
|
484
|
+
const to = parsed.to;
|
|
485
|
+
if (Array.isArray(to) && to.length > 0 && typeof to[0] === 'string') {
|
|
486
|
+
return to[0];
|
|
487
|
+
}
|
|
488
|
+
if (typeof to === 'string') {
|
|
489
|
+
return to;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
catch {
|
|
494
|
+
// fall through to the raw 'to' field
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return toField || undefined;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* `JSON.parse` that returns an object or `undefined` — never throws. Used to attach the
|
|
501
|
+
* SendGrid REST response body to {@link SubscriptionResult.Result} without risking a
|
|
502
|
+
* secondary crash on a non-JSON body.
|
|
503
|
+
*/
|
|
504
|
+
safeParseJsonObject(text) {
|
|
505
|
+
if (!text) {
|
|
506
|
+
return undefined;
|
|
507
|
+
}
|
|
508
|
+
try {
|
|
509
|
+
const parsed = JSON.parse(text);
|
|
510
|
+
return parsed && typeof parsed === 'object' ? parsed : undefined;
|
|
511
|
+
}
|
|
512
|
+
catch {
|
|
513
|
+
return undefined;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
176
516
|
};
|
|
177
|
-
SendGridProvider = __decorate([
|
|
517
|
+
SendGridProvider = SendGridProvider_1 = __decorate([
|
|
178
518
|
RegisterClass(BaseCommunicationProvider, 'SendGrid')
|
|
179
519
|
], SendGridProvider);
|
|
180
520
|
export { SendGridProvider };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SendGridProvider.js","sourceRoot":"","sources":["../src/SendGridProvider.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SendGridProvider.js","sourceRoot":"","sources":["../src/SendGridProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,10 @@ vi.mock('@sendgrid/mail', () => ({
|
|
|
17
17
|
send: mockSgSend,
|
|
18
18
|
},
|
|
19
19
|
}));
|
|
20
|
-
vi.mock('@memberjunction/communication-types', () => ({
|
|
20
|
+
vi.mock('@memberjunction/communication-types', async () => ({
|
|
21
|
+
// Real address-list parser (pure module) — the provider imports it by name, and Vitest
|
|
22
|
+
// rejects named imports missing from a mock factory even when the test never calls them.
|
|
23
|
+
...(await vi.importActual('../../../../base-types/src/AddressUtils')),
|
|
21
24
|
BaseCommunicationProvider: class {
|
|
22
25
|
getSupportedOperations() { return []; }
|
|
23
26
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DryRun.test.js","sourceRoot":"","sources":["../../src/__tests__/DryRun.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,8EAA8E;AAC9E,0CAA0C;AAC1C,8EAA8E;AAE9E,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACtD,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;IACnB,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE;CACvB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,OAAO,EAAE;QACP,SAAS,EAAE,aAAa;QACxB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"DryRun.test.js","sourceRoot":"","sources":["../../src/__tests__/DryRun.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,8EAA8E;AAC9E,0CAA0C;AAC1C,8EAA8E;AAE9E,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACtD,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;IACnB,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE;CACvB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,OAAO,EAAE;QACP,SAAS,EAAE,aAAa;QACxB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IAC1D,uFAAuF;IACvF,yFAAyF;IACzF,GAAG,CAAC,MAAM,EAAE,CAAC,YAAY,CACvB,yCAAyC,CAC1C,CAAC;IACF,yBAAyB,EAAE;QACzB,sBAAsB,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;KACxC;IACD,sBAAsB,EAAE,CAAC,UAA8B,EAAE,MAA0B,EAAE,eAAwB,EAAE,EAAE;QAC/G,IAAI,UAAU;YAAE,OAAO,UAAU,CAAC;QAClC,IAAI,CAAC,eAAe,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC9C,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,2BAA2B,EAAE,CAAC,KAA8B,EAAE,QAAkB,EAAE,QAAgB,EAAE,EAAE;QACpG,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,kCAAkC,GAAG,EAAE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC;IACvC,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC,MAAe,EAAE,EAAE,CAAC,MAAM;CACjD,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;IACrC,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;IACjB,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;CACnB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;IACvB,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE;CAC7B,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1B,SAAS,EAAE,kBAAkB;CAC9B,CAAC,CAAC,CAAC;AAEJ,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGvD,MAAM,aAAa,GAAG,CAAC,YAAuC,EAAE,EAAoB,EAAE,CAAC,CAAC;IACtF,IAAI,EAAE,oBAAoB;IAC1B,QAAQ,EAAE,aAAa;IACvB,EAAE,EAAE,uBAAuB;IAC3B,gBAAgB,EAAE,eAAe;IACjC,aAAa,EAAE,iBAAiB;IAChC,iBAAiB,EAAE,kBAAkB;IACrC,GAAG,SAAS;CACmB,CAAA,CAAC;AAElC,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,IAAI,QAA0B,CAAC;IAE/B,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAEjF,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gHAAgH,EAAE,KAAK,IAAI,EAAE;QAC9H,8FAA8F;QAC9F,MAAM,MAAM,CACV,QAAQ,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,0BAA0B,EAAE,IAAI,EAAE,CAAC,CAClG,CAAC,OAAO,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC;QACjD,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,QAAQ,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAClE,iGAAiG;QACjG,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;QAC/D,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qFAAqF,EAAE,KAAK,IAAI,EAAE;QACnG,UAAU,CAAC,iBAAiB,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAEtE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,iBAAiB,CAAC,aAAa,EAAE,CAAC,CAAC;QAEjE,MAAM,CAAC,UAAU,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SendGridInbound.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/SendGridInbound.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the SendGrid provider's Inbound Parse (push-notification) support:
|
|
3
|
+
* supported operations, subscription capabilities, CreateSubscription/DeleteSubscription
|
|
4
|
+
* (REST via global fetch), and the pure ParseNotification multipart parser.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Mocks
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
const { mockSgSend, mockSetApiKey } = vi.hoisted(() => ({
|
|
11
|
+
mockSgSend: vi.fn(),
|
|
12
|
+
mockSetApiKey: vi.fn(),
|
|
13
|
+
}));
|
|
14
|
+
vi.mock('@sendgrid/mail', () => ({
|
|
15
|
+
default: {
|
|
16
|
+
setApiKey: mockSetApiKey,
|
|
17
|
+
send: mockSgSend,
|
|
18
|
+
},
|
|
19
|
+
}));
|
|
20
|
+
// Mirror the real BaseCommunicationProvider: SupportsPush derives from
|
|
21
|
+
// GetSubscriptionCapabilities() so a subclass opts in simply by overriding it.
|
|
22
|
+
vi.mock('@memberjunction/communication-types', async () => ({
|
|
23
|
+
// Real address-list parser (pure, dependency-free) pulled straight from the base-types
|
|
24
|
+
// source so ParseNotification tests exercise genuine parsing; importing the whole actual
|
|
25
|
+
// package would drag in unmocked heavy dependencies.
|
|
26
|
+
...(await vi.importActual('../../../../base-types/src/AddressUtils')),
|
|
27
|
+
BaseCommunicationProvider: class {
|
|
28
|
+
getSupportedOperations() { return []; }
|
|
29
|
+
GetSubscriptionCapabilities() { return undefined; }
|
|
30
|
+
get SupportsPush() { return this.GetSubscriptionCapabilities() !== undefined; }
|
|
31
|
+
},
|
|
32
|
+
resolveCredentialValue: (requestVal, envVal, disableFallback) => {
|
|
33
|
+
if (requestVal)
|
|
34
|
+
return requestVal;
|
|
35
|
+
if (!disableFallback && envVal)
|
|
36
|
+
return envVal;
|
|
37
|
+
return undefined;
|
|
38
|
+
},
|
|
39
|
+
validateRequiredCredentials: (creds, required, provider) => {
|
|
40
|
+
for (const key of required) {
|
|
41
|
+
if (!creds[key])
|
|
42
|
+
throw new Error(`${provider}: Missing required credential: ${key}`);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
}));
|
|
46
|
+
vi.mock('@memberjunction/global', () => ({
|
|
47
|
+
RegisterClass: () => (target) => target,
|
|
48
|
+
}));
|
|
49
|
+
vi.mock('@memberjunction/core', () => ({
|
|
50
|
+
LogError: vi.fn(),
|
|
51
|
+
LogStatus: vi.fn(),
|
|
52
|
+
}));
|
|
53
|
+
vi.mock('dotenv', () => ({
|
|
54
|
+
default: { config: vi.fn() },
|
|
55
|
+
}));
|
|
56
|
+
vi.mock('../config', () => ({
|
|
57
|
+
__API_KEY: 'env-sendgrid-key',
|
|
58
|
+
}));
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Import after mocks
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
import { SendGridProvider } from '../SendGridProvider.js';
|
|
63
|
+
const PARSE_URL = 'https://api.sendgrid.com/v3/user/webhooks/parse/settings';
|
|
64
|
+
// Build a fetch Response-like stub with just the surface the provider uses.
|
|
65
|
+
const fetchResponse = (opts) => ({
|
|
66
|
+
ok: opts.ok,
|
|
67
|
+
status: opts.status,
|
|
68
|
+
text: vi.fn().mockResolvedValue(opts.text ?? ''),
|
|
69
|
+
});
|
|
70
|
+
// Assemble a realistic multipart/form-data body from name→value pairs.
|
|
71
|
+
const buildMultipart = (boundary, parts) => {
|
|
72
|
+
let body = '';
|
|
73
|
+
for (const p of parts) {
|
|
74
|
+
const disp = p.filename
|
|
75
|
+
? `form-data; name="${p.name}"; filename="${p.filename}"`
|
|
76
|
+
: `form-data; name="${p.name}"`;
|
|
77
|
+
body += `--${boundary}\r\nContent-Disposition: ${disp}\r\n\r\n${p.value}\r\n`;
|
|
78
|
+
}
|
|
79
|
+
body += `--${boundary}--\r\n`;
|
|
80
|
+
return body;
|
|
81
|
+
};
|
|
82
|
+
describe('SendGridProvider Inbound Parse', () => {
|
|
83
|
+
let provider;
|
|
84
|
+
beforeEach(() => {
|
|
85
|
+
vi.clearAllMocks();
|
|
86
|
+
provider = new SendGridProvider();
|
|
87
|
+
});
|
|
88
|
+
// -------------------------------------------------------------------------
|
|
89
|
+
// Capabilities / operations
|
|
90
|
+
// -------------------------------------------------------------------------
|
|
91
|
+
describe('getSupportedOperations', () => {
|
|
92
|
+
it('includes the four supported operations', () => {
|
|
93
|
+
const ops = provider.getSupportedOperations();
|
|
94
|
+
expect(ops).toContain('SendSingleMessage');
|
|
95
|
+
expect(ops).toContain('CreateSubscription');
|
|
96
|
+
expect(ops).toContain('DeleteSubscription');
|
|
97
|
+
expect(ops).toContain('ParseNotification');
|
|
98
|
+
expect(ops).not.toContain('RenewSubscription');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe('SupportsPush', () => {
|
|
102
|
+
it('is true (derived from GetSubscriptionCapabilities)', () => {
|
|
103
|
+
expect(provider.SupportsPush).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('GetSubscriptionCapabilities', () => {
|
|
107
|
+
it('reflects the Inbound Parse model (inline, managed, no expiry)', () => {
|
|
108
|
+
const caps = provider.GetSubscriptionCapabilities();
|
|
109
|
+
expect(caps.DeliversPayloadInline).toBe(true);
|
|
110
|
+
expect(caps.SupportsSubscriptionManagement).toBe(true);
|
|
111
|
+
expect(caps.MaxLifetimeMinutes).toBeUndefined();
|
|
112
|
+
expect(caps.RequiresEndpointValidation).toBe(false);
|
|
113
|
+
expect(caps.SupportedChangeTypes).toEqual(['created']);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
// -------------------------------------------------------------------------
|
|
117
|
+
// CreateSubscription
|
|
118
|
+
// -------------------------------------------------------------------------
|
|
119
|
+
describe('CreateSubscription', () => {
|
|
120
|
+
const baseParams = () => ({
|
|
121
|
+
Identifier: 'parse.example.com',
|
|
122
|
+
NotificationUrl: 'https://api.example.com/inbound',
|
|
123
|
+
ChangeTypes: ['created'],
|
|
124
|
+
ClientState: 'unused-for-sendgrid',
|
|
125
|
+
});
|
|
126
|
+
it('POSTs the hostname→URL mapping and returns hostname as SubscriptionID', async () => {
|
|
127
|
+
const fetchMock = vi.fn().mockResolvedValue(fetchResponse({ ok: true, status: 201, text: '{"result":"ok"}' }));
|
|
128
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
129
|
+
const result = await provider.CreateSubscription(baseParams());
|
|
130
|
+
expect(result.Success).toBe(true);
|
|
131
|
+
expect(result.SubscriptionID).toBe('parse.example.com');
|
|
132
|
+
expect(result.ExpiresAt).toBeUndefined();
|
|
133
|
+
expect(result.Result).toEqual({ result: 'ok' });
|
|
134
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
135
|
+
const [url, init] = fetchMock.mock.calls[0];
|
|
136
|
+
expect(url).toBe(PARSE_URL);
|
|
137
|
+
expect(init.method).toBe('POST');
|
|
138
|
+
expect(init.headers.Authorization).toBe('Bearer env-sendgrid-key');
|
|
139
|
+
expect(JSON.parse(init.body)).toEqual({
|
|
140
|
+
hostname: 'parse.example.com',
|
|
141
|
+
url: 'https://api.example.com/inbound',
|
|
142
|
+
spam_check: false,
|
|
143
|
+
send_raw: false,
|
|
144
|
+
});
|
|
145
|
+
vi.unstubAllGlobals();
|
|
146
|
+
});
|
|
147
|
+
it('uses per-request credentials when provided', async () => {
|
|
148
|
+
const fetchMock = vi.fn().mockResolvedValue(fetchResponse({ ok: true, status: 201, text: '{}' }));
|
|
149
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
150
|
+
await provider.CreateSubscription(baseParams(), { apiKey: 'SG.custom-key' });
|
|
151
|
+
expect(fetchMock.mock.calls[0][1].headers.Authorization).toBe('Bearer SG.custom-key');
|
|
152
|
+
vi.unstubAllGlobals();
|
|
153
|
+
});
|
|
154
|
+
it('returns Success:false with status + body on a non-2xx response', async () => {
|
|
155
|
+
const fetchMock = vi.fn().mockResolvedValue(fetchResponse({ ok: false, status: 400, text: 'hostname already exists' }));
|
|
156
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
157
|
+
const result = await provider.CreateSubscription(baseParams());
|
|
158
|
+
expect(result.Success).toBe(false);
|
|
159
|
+
expect(result.ErrorMessage).toContain('400');
|
|
160
|
+
expect(result.ErrorMessage).toContain('hostname already exists');
|
|
161
|
+
vi.unstubAllGlobals();
|
|
162
|
+
});
|
|
163
|
+
it('fail-fast: rejects a missing hostname without touching fetch', async () => {
|
|
164
|
+
const fetchMock = vi.fn();
|
|
165
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
166
|
+
const result = await provider.CreateSubscription({ ...baseParams(), Identifier: '' });
|
|
167
|
+
expect(result.Success).toBe(false);
|
|
168
|
+
expect(result.ErrorMessage).toContain('Identifier');
|
|
169
|
+
expect(fetchMock).not.toHaveBeenCalled();
|
|
170
|
+
vi.unstubAllGlobals();
|
|
171
|
+
});
|
|
172
|
+
it('fail-fast: rejects a non-https NotificationUrl without touching fetch', async () => {
|
|
173
|
+
const fetchMock = vi.fn();
|
|
174
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
175
|
+
const result = await provider.CreateSubscription({ ...baseParams(), NotificationUrl: 'http://insecure.example.com/inbound' });
|
|
176
|
+
expect(result.Success).toBe(false);
|
|
177
|
+
expect(result.ErrorMessage).toContain('https');
|
|
178
|
+
expect(fetchMock).not.toHaveBeenCalled();
|
|
179
|
+
vi.unstubAllGlobals();
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
// -------------------------------------------------------------------------
|
|
183
|
+
// DeleteSubscription
|
|
184
|
+
// -------------------------------------------------------------------------
|
|
185
|
+
describe('DeleteSubscription', () => {
|
|
186
|
+
const params = () => ({ SubscriptionID: 'parse.example.com' });
|
|
187
|
+
it('DELETEs the hostname-keyed mapping and returns success', async () => {
|
|
188
|
+
const fetchMock = vi.fn().mockResolvedValue(fetchResponse({ ok: true, status: 204 }));
|
|
189
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
190
|
+
const result = await provider.DeleteSubscription(params());
|
|
191
|
+
expect(result.Success).toBe(true);
|
|
192
|
+
const [url, init] = fetchMock.mock.calls[0];
|
|
193
|
+
expect(url).toBe(`${PARSE_URL}/parse.example.com`);
|
|
194
|
+
expect(init.method).toBe('DELETE');
|
|
195
|
+
expect(init.headers.Authorization).toBe('Bearer env-sendgrid-key');
|
|
196
|
+
vi.unstubAllGlobals();
|
|
197
|
+
});
|
|
198
|
+
it('treats a 404 as success (idempotent delete)', async () => {
|
|
199
|
+
const fetchMock = vi.fn().mockResolvedValue(fetchResponse({ ok: false, status: 404 }));
|
|
200
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
201
|
+
const result = await provider.DeleteSubscription({ SubscriptionID: 'already-gone.example.com' });
|
|
202
|
+
expect(result.Success).toBe(true);
|
|
203
|
+
vi.unstubAllGlobals();
|
|
204
|
+
});
|
|
205
|
+
it('returns Success:false on a non-404 error', async () => {
|
|
206
|
+
const fetchMock = vi.fn().mockResolvedValue(fetchResponse({ ok: false, status: 500, text: 'server error' }));
|
|
207
|
+
vi.stubGlobal('fetch', fetchMock);
|
|
208
|
+
const result = await provider.DeleteSubscription(params());
|
|
209
|
+
expect(result.Success).toBe(false);
|
|
210
|
+
expect(result.ErrorMessage).toContain('500');
|
|
211
|
+
vi.unstubAllGlobals();
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
// -------------------------------------------------------------------------
|
|
215
|
+
// ParseNotification (pure — no mocks needed)
|
|
216
|
+
// -------------------------------------------------------------------------
|
|
217
|
+
describe('ParseNotification', () => {
|
|
218
|
+
const boundary = 'xYzBoundary123';
|
|
219
|
+
const input = (body, contentType = `multipart/form-data; boundary=${boundary}`) => ({
|
|
220
|
+
Headers: { 'content-type': contentType },
|
|
221
|
+
QueryParams: {},
|
|
222
|
+
RawBody: body,
|
|
223
|
+
});
|
|
224
|
+
it('normalizes a realistic inbound email with inline Message populated', async () => {
|
|
225
|
+
const body = buildMultipart(boundary, [
|
|
226
|
+
{ name: 'from', value: 'Alice <alice@sender.com>' },
|
|
227
|
+
{ name: 'to', value: 'support@parse.example.com' },
|
|
228
|
+
{ name: 'subject', value: 'Help please' },
|
|
229
|
+
{ name: 'text', value: 'This is the plain body.' },
|
|
230
|
+
{ name: 'html', value: '<p>This is the plain body.</p>' },
|
|
231
|
+
{ name: 'envelope', value: '{"to":["support@parse.example.com"],"from":"alice@sender.com"}' },
|
|
232
|
+
{ name: 'headers', value: 'Received: from mx...' },
|
|
233
|
+
]);
|
|
234
|
+
const result = await provider.ParseNotification(input(body));
|
|
235
|
+
expect(result.Success).toBe(true);
|
|
236
|
+
expect(result.SuggestedResponseStatus).toBe(200);
|
|
237
|
+
expect(result.SignatureValid).toBeUndefined();
|
|
238
|
+
expect(result.Notifications).toHaveLength(1);
|
|
239
|
+
const n = result.Notifications[0];
|
|
240
|
+
expect(n.Kind).toBe('message');
|
|
241
|
+
expect(n.ChangeType).toBe('created');
|
|
242
|
+
expect(n.MessageIDs).toEqual([]);
|
|
243
|
+
expect(n.Identifier).toBe('support@parse.example.com'); // from parsed envelope
|
|
244
|
+
expect(n.Message).toBeDefined();
|
|
245
|
+
expect(n.Message.From).toBe('Alice <alice@sender.com>');
|
|
246
|
+
expect(n.Message.To).toBe('support@parse.example.com');
|
|
247
|
+
expect(n.Message.Subject).toBe('Help please');
|
|
248
|
+
expect(n.Message.Body).toBe('This is the plain body.'); // prefers text over html
|
|
249
|
+
expect(n.Message.ToRecipients).toEqual(['support@parse.example.com']);
|
|
250
|
+
expect(n.Message.CCRecipients).toEqual([]); // no cc field posted
|
|
251
|
+
expect(n.RawData['subject']).toBe('Help please');
|
|
252
|
+
});
|
|
253
|
+
it('populates ToRecipients/CCRecipients as bare addresses from multi-recipient to/cc fields', async () => {
|
|
254
|
+
const body = buildMultipart(boundary, [
|
|
255
|
+
{ name: 'from', value: 'Assistant <assistant@sender.com>' },
|
|
256
|
+
{ name: 'to', value: 'support@parse.example.com, "Doe, Jane" <jane@member.org>' },
|
|
257
|
+
{ name: 'cc', value: 'Leader <leader@member.org>, staff@sender.com' },
|
|
258
|
+
{ name: 'subject', value: 'Multi-party thread' },
|
|
259
|
+
{ name: 'text', value: 'body' },
|
|
260
|
+
]);
|
|
261
|
+
const result = await provider.ParseNotification(input(body));
|
|
262
|
+
expect(result.Success).toBe(true);
|
|
263
|
+
const message = result.Notifications[0].Message;
|
|
264
|
+
expect(message.To).toBe('support@parse.example.com, "Doe, Jane" <jane@member.org>'); // raw, unchanged
|
|
265
|
+
expect(message.ToRecipients).toEqual(['support@parse.example.com', 'jane@member.org']);
|
|
266
|
+
expect(message.CCRecipients).toEqual(['leader@member.org', 'staff@sender.com']);
|
|
267
|
+
});
|
|
268
|
+
it('falls back to the raw "to" field when envelope is absent', async () => {
|
|
269
|
+
const body = buildMultipart(boundary, [
|
|
270
|
+
{ name: 'from', value: 'bob@sender.com' },
|
|
271
|
+
{ name: 'to', value: 'inbox@parse.example.com' },
|
|
272
|
+
{ name: 'subject', value: 'No envelope' },
|
|
273
|
+
{ name: 'text', value: 'body' },
|
|
274
|
+
]);
|
|
275
|
+
const result = await provider.ParseNotification(input(body));
|
|
276
|
+
expect(result.Notifications[0].Identifier).toBe('inbox@parse.example.com');
|
|
277
|
+
});
|
|
278
|
+
it('falls back to html body when text is absent', async () => {
|
|
279
|
+
const body = buildMultipart(boundary, [
|
|
280
|
+
{ name: 'from', value: 'c@sender.com' },
|
|
281
|
+
{ name: 'to', value: 'x@parse.example.com' },
|
|
282
|
+
{ name: 'html', value: '<b>only html</b>' },
|
|
283
|
+
]);
|
|
284
|
+
const result = await provider.ParseNotification(input(body));
|
|
285
|
+
expect(result.Notifications[0].Message.Body).toBe('<b>only html</b>');
|
|
286
|
+
});
|
|
287
|
+
it('counts attachment parts without decoding bytes', async () => {
|
|
288
|
+
const body = buildMultipart(boundary, [
|
|
289
|
+
{ name: 'from', value: 'd@sender.com' },
|
|
290
|
+
{ name: 'to', value: 'y@parse.example.com' },
|
|
291
|
+
{ name: 'text', value: 'see attached' },
|
|
292
|
+
{ name: 'attachment1', value: 'RAWBYTESHERE', filename: 'photo.png' },
|
|
293
|
+
]);
|
|
294
|
+
const result = await provider.ParseNotification(input(body));
|
|
295
|
+
expect(result.Success).toBe(true);
|
|
296
|
+
const raw = result.Notifications[0].RawData;
|
|
297
|
+
expect(raw['attachmentCount']).toBe(1);
|
|
298
|
+
expect(raw['attachment1']).toBeUndefined(); // bytes NOT captured as a field
|
|
299
|
+
});
|
|
300
|
+
it('honors a quoted boundary in the content-type header', async () => {
|
|
301
|
+
const body = buildMultipart(boundary, [
|
|
302
|
+
{ name: 'from', value: 'e@sender.com' },
|
|
303
|
+
{ name: 'to', value: 'z@parse.example.com' },
|
|
304
|
+
{ name: 'text', value: 'quoted boundary' },
|
|
305
|
+
]);
|
|
306
|
+
const result = await provider.ParseNotification(input(body, `multipart/form-data; boundary="${boundary}"`));
|
|
307
|
+
expect(result.Success).toBe(true);
|
|
308
|
+
expect(result.Notifications[0].Message.Body).toBe('quoted boundary');
|
|
309
|
+
});
|
|
310
|
+
// ------------------- hostile / malformed inputs -------------------
|
|
311
|
+
it('returns 400 (no throw) on an empty body', async () => {
|
|
312
|
+
const result = await provider.ParseNotification(input(''));
|
|
313
|
+
expect(result.Success).toBe(false);
|
|
314
|
+
expect(result.SuggestedResponseStatus).toBe(400);
|
|
315
|
+
expect(result.Notifications).toEqual([]);
|
|
316
|
+
});
|
|
317
|
+
it('returns 400 (no throw) when the boundary is missing from content-type', async () => {
|
|
318
|
+
const result = await provider.ParseNotification({
|
|
319
|
+
Headers: { 'content-type': 'multipart/form-data' },
|
|
320
|
+
QueryParams: {},
|
|
321
|
+
RawBody: '--x\r\nContent-Disposition: form-data; name="from"/r/n/r/na@b.com/r/n--x--',
|
|
322
|
+
});
|
|
323
|
+
expect(result.Success).toBe(false);
|
|
324
|
+
expect(result.SuggestedResponseStatus).toBe(400);
|
|
325
|
+
});
|
|
326
|
+
it('returns 400 (no throw) on a plain-JSON (non-multipart) body', async () => {
|
|
327
|
+
const result = await provider.ParseNotification({
|
|
328
|
+
Headers: { 'content-type': 'application/json' },
|
|
329
|
+
QueryParams: {},
|
|
330
|
+
RawBody: '{"from":"a@b.com","to":"c@d.com"}',
|
|
331
|
+
});
|
|
332
|
+
expect(result.Success).toBe(false);
|
|
333
|
+
expect(result.SuggestedResponseStatus).toBe(400);
|
|
334
|
+
expect(result.Notifications).toEqual([]);
|
|
335
|
+
});
|
|
336
|
+
it('never throws on assorted hostile input', async () => {
|
|
337
|
+
const cases = [
|
|
338
|
+
{ Headers: {}, QueryParams: {}, RawBody: '' },
|
|
339
|
+
{ Headers: { 'content-type': 'multipart/form-data; boundary=b' }, QueryParams: {}, RawBody: 'garbage-no-parts' },
|
|
340
|
+
{ Headers: { 'content-type': 'multipart/form-data; boundary=b' }, QueryParams: {}, RawBody: '--b--' },
|
|
341
|
+
{ Headers: { 'content-type': 'text/plain' }, QueryParams: {}, RawBody: 'hello' },
|
|
342
|
+
];
|
|
343
|
+
for (const c of cases) {
|
|
344
|
+
const result = await provider.ParseNotification(c);
|
|
345
|
+
expect(typeof result.Success).toBe('boolean');
|
|
346
|
+
expect(Array.isArray(result.Notifications)).toBe(true);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
});
|
|
351
|
+
//# sourceMappingURL=SendGridInbound.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SendGridInbound.test.js","sourceRoot":"","sources":["../../src/__tests__/SendGridInbound.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,10 @@ vi.mock('@sendgrid/mail', () => ({
|
|
|
16
16
|
send: mockSgSend,
|
|
17
17
|
},
|
|
18
18
|
}));
|
|
19
|
-
vi.mock('@memberjunction/communication-types', () => ({
|
|
19
|
+
vi.mock('@memberjunction/communication-types', async () => ({
|
|
20
|
+
// Real address-list parser (pure module) — the provider imports it by name, and Vitest
|
|
21
|
+
// rejects named imports missing from a mock factory even when the test never calls them.
|
|
22
|
+
...(await vi.importActual('../../../../base-types/src/AddressUtils')),
|
|
20
23
|
BaseCommunicationProvider: class {
|
|
21
24
|
getSupportedOperations() { return []; }
|
|
22
25
|
},
|
|
@@ -62,9 +65,9 @@ describe('SendGridProvider', () => {
|
|
|
62
65
|
provider = new SendGridProvider();
|
|
63
66
|
});
|
|
64
67
|
describe('getSupportedOperations', () => {
|
|
65
|
-
it('should
|
|
68
|
+
it('should support SendSingleMessage plus the Inbound Parse operations', () => {
|
|
66
69
|
const ops = provider.getSupportedOperations();
|
|
67
|
-
expect(ops).toEqual(['SendSingleMessage']);
|
|
70
|
+
expect(ops).toEqual(['SendSingleMessage', 'CreateSubscription', 'DeleteSubscription', 'ParseNotification']);
|
|
68
71
|
});
|
|
69
72
|
});
|
|
70
73
|
describe('SendSingleMessage', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SendGridProvider.test.js","sourceRoot":"","sources":["../../src/__tests__/SendGridProvider.test.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,8EAA8E;AAC9E,QAAQ;AACR,8EAA8E;AAE9E,MAAM,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACtD,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;IACnB,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE;CACvB,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,OAAO,EAAE;QACP,SAAS,EAAE,aAAa;QACxB,IAAI,EAAE,UAAU;KACjB;CACF,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,qCAAqC,EAAE,GAAG,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"SendGridProvider.test.js","sourceRoot":"","sources":["../../src/__tests__/SendGridProvider.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/communication-sendgrid",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.51.0",
|
|
5
5
|
"description": "MemberJunction: SendGrid Provider for the MJ Communication Framework",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
"typescript": "^5.9.3"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@memberjunction/communication-types": "5.
|
|
24
|
-
"@memberjunction/core": "5.
|
|
25
|
-
"@memberjunction/core-entities": "5.
|
|
26
|
-
"@memberjunction/global": "5.
|
|
23
|
+
"@memberjunction/communication-types": "5.51.0",
|
|
24
|
+
"@memberjunction/core": "5.51.0",
|
|
25
|
+
"@memberjunction/core-entities": "5.51.0",
|
|
26
|
+
"@memberjunction/global": "5.51.0",
|
|
27
27
|
"@sendgrid/mail": "^8.1.6",
|
|
28
28
|
"dotenv": "^17.2.4"
|
|
29
29
|
},
|