@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.
@@ -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 (send-only) and does not support
55
- * mailbox operations like fetching messages, folders, or attachments.
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,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EAGpB,iBAAiB,EACpB,MAAM,qCAAqC,CAAC;AAM7C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,mBAAoB,SAAQ,uBAAuB;IAChE;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBACa,gBAAiB,SAAQ,yBAAyB;IAC3D;;;;OAIG;IACa,sBAAsB,IAAI,iBAAiB,EAAE;IAS7D;;;;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;CAMhC"}
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"}
@@ -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
- import { BaseCommunicationProvider, resolveCredentialValue, validateRequiredCredentials } from "@memberjunction/communication-types";
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 (send-only) and does not support
41
- * mailbox operations like fetching messages, folders, or attachments.
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
- // Note: SendGrid is send-only - no inbox access, no fetching, no drafts
47
- // GetMessages, ForwardMessage, ReplyToMessage throw errors
48
- // CreateDraft returns not supported
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":"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"}
1
+ {"version":3,"file":"DryRun.test.js","sourceRoot":"","sources":["../../src/__tests__/DryRun.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=SendGridInbound.test.d.ts.map
@@ -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 only support SendSingleMessage', () => {
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":"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"}
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.49.0",
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.49.0",
24
- "@memberjunction/core": "5.49.0",
25
- "@memberjunction/core-entities": "5.49.0",
26
- "@memberjunction/global": "5.49.0",
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
  },