@develit-services/notification 0.6.2 → 1.0.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.
@@ -66,6 +66,28 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
66
66
  super(ctx, env);
67
67
  this.slackConnector = new webhook_connector.SlackConnector(this.env.SLACK_WEBHOOK);
68
68
  }
69
+ getContactEmail(contact) {
70
+ return typeof contact === "string" ? contact : contact.email;
71
+ }
72
+ isEmailAllowed(email, allowedEmails) {
73
+ return allowedEmails.includes(email.toLowerCase());
74
+ }
75
+ applyEmailWhitelist(email) {
76
+ const whitelist = this.env.EMAIL_WHITELIST;
77
+ if (!whitelist) return email;
78
+ const fallback = this.env.EMAIL_WHITELIST_FALLBACK;
79
+ const allowedEmails = whitelist.split(",").map((e) => e.trim().toLowerCase());
80
+ const toEmail = this.getContactEmail(
81
+ Array.isArray(email.to) ? email.to[0] : email.to
82
+ );
83
+ if (this.isEmailAllowed(toEmail, allowedEmails)) return email;
84
+ if (fallback) return { ...email, to: fallback };
85
+ throw backendSdk.createInternalError(null, {
86
+ message: `Email not on whitelist and no fallback configured: ${toEmail}`,
87
+ code: "SYS-N-03",
88
+ status: 400
89
+ });
90
+ }
69
91
  async queue(batch) {
70
92
  for (const message of batch.messages) {
71
93
  this.logInput({ message });
@@ -116,7 +138,7 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
116
138
  async _sendEmail(input) {
117
139
  return this.handleAction(
118
140
  { data: input, schema: webhook_connector.sendEmailInputSchema },
119
- { successMessage: "Email sent." },
141
+ { successMessage: "Email sent.", sensitiveKeys: ["attachments"] },
120
142
  async (params) => {
121
143
  const {
122
144
  email,
@@ -137,7 +159,8 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
137
159
  this.env.EMAIL_SENDER_NAME
138
160
  );
139
161
  }
140
- await this.emailConnector.sendEmail(email);
162
+ const filteredEmail = this.applyEmailWhitelist(email);
163
+ await this.emailConnector.sendEmail(filteredEmail);
141
164
  try {
142
165
  await this.pushToQueue(this.env.AUDIT_LOGS_QUEUE, {
143
166
  logType: "event",
@@ -152,10 +175,10 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
152
175
  userAgent,
153
176
  outcome: "success",
154
177
  description: `Email sent to ${email.to}`,
155
- details: JSON.stringify({
178
+ details: {
156
179
  subject: email.subject,
157
180
  templateId: email.templateId
158
- })
181
+ }
159
182
  });
160
183
  } catch (e) {
161
184
  console.error("Failed to push email audit log", e);
@@ -206,7 +229,7 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
206
229
  userAgent,
207
230
  outcome: "success",
208
231
  description: `SMS sent to ${to}`,
209
- details: JSON.stringify({ message })
232
+ details: { message }
210
233
  });
211
234
  } catch (e) {
212
235
  console.error("Failed to push sms audit log", e);
@@ -218,7 +241,7 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
218
241
  async sendEmail(input) {
219
242
  return this.handleAction(
220
243
  { data: input, schema: webhook_connector.sendEmailInputSchema },
221
- { successMessage: "Email sent." },
244
+ { successMessage: "Email sent.", sensitiveKeys: ["attachments"] },
222
245
  async (params) => {
223
246
  const { email, metadata } = params;
224
247
  await this.pushToQueue(
@@ -238,7 +261,7 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
238
261
  async sendEmailSync(input) {
239
262
  return this.handleAction(
240
263
  { data: input, schema: webhook_connector.sendEmailInputSchema },
241
- { successMessage: "Email sent." },
264
+ { successMessage: "Email sent.", sensitiveKeys: ["attachments"] },
242
265
  async (params) => {
243
266
  const { email, metadata } = params;
244
267
  return this._sendEmail({
@@ -306,9 +329,9 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
306
329
  userAgent: metadata?.userAgent,
307
330
  outcome: "success",
308
331
  description: "Slack notification sent",
309
- details: JSON.stringify({
332
+ details: {
310
333
  message: slack.message
311
- })
334
+ }
312
335
  });
313
336
  return {};
314
337
  }
@@ -375,9 +398,9 @@ let NotificationServiceBase = class extends backendSdk.develitWorker(
375
398
  userAgent,
376
399
  outcome: "success",
377
400
  description: `Webhook sent to ${webhook.url}`,
378
- details: JSON.stringify({
401
+ details: {
379
402
  url: webhook.url
380
- })
403
+ }
381
404
  });
382
405
  } catch (e) {
383
406
  console.error("Failed to push webhook audit log", e);
@@ -12,6 +12,9 @@ declare class NotificationServiceBase extends NotificationServiceBase_base {
12
12
  protected emailConnector: IEmailConnector;
13
13
  protected smsConnector: ISmsConnector;
14
14
  constructor(ctx: ExecutionContext, env: NotificationEnv);
15
+ private getContactEmail;
16
+ private isEmailAllowed;
17
+ private applyEmailWhitelist;
15
18
  queue(batch: MessageBatch<NotificationQueueMessage>): Promise<void>;
16
19
  protected _sendEmail(input: SendEmailInput): Promise<IRPCResponse<SendEmailOutput>>;
17
20
  protected _sendSms(input: SendSmsInput): Promise<IRPCResponse<SendSmsOutput>>;
@@ -12,6 +12,9 @@ declare class NotificationServiceBase extends NotificationServiceBase_base {
12
12
  protected emailConnector: IEmailConnector;
13
13
  protected smsConnector: ISmsConnector;
14
14
  constructor(ctx: ExecutionContext, env: NotificationEnv);
15
+ private getContactEmail;
16
+ private isEmailAllowed;
17
+ private applyEmailWhitelist;
15
18
  queue(batch: MessageBatch<NotificationQueueMessage>): Promise<void>;
16
19
  protected _sendEmail(input: SendEmailInput): Promise<IRPCResponse<SendEmailOutput>>;
17
20
  protected _sendSms(input: SendSmsInput): Promise<IRPCResponse<SendSmsOutput>>;
@@ -12,6 +12,9 @@ declare class NotificationServiceBase extends NotificationServiceBase_base {
12
12
  protected emailConnector: IEmailConnector;
13
13
  protected smsConnector: ISmsConnector;
14
14
  constructor(ctx: ExecutionContext, env: NotificationEnv);
15
+ private getContactEmail;
16
+ private isEmailAllowed;
17
+ private applyEmailWhitelist;
15
18
  queue(batch: MessageBatch<NotificationQueueMessage>): Promise<void>;
16
19
  protected _sendEmail(input: SendEmailInput): Promise<IRPCResponse<SendEmailOutput>>;
17
20
  protected _sendSms(input: SendSmsInput): Promise<IRPCResponse<SendSmsOutput>>;
@@ -62,6 +62,28 @@ let NotificationServiceBase = class extends develitWorker(
62
62
  super(ctx, env);
63
63
  this.slackConnector = new SlackConnector(this.env.SLACK_WEBHOOK);
64
64
  }
65
+ getContactEmail(contact) {
66
+ return typeof contact === "string" ? contact : contact.email;
67
+ }
68
+ isEmailAllowed(email, allowedEmails) {
69
+ return allowedEmails.includes(email.toLowerCase());
70
+ }
71
+ applyEmailWhitelist(email) {
72
+ const whitelist = this.env.EMAIL_WHITELIST;
73
+ if (!whitelist) return email;
74
+ const fallback = this.env.EMAIL_WHITELIST_FALLBACK;
75
+ const allowedEmails = whitelist.split(",").map((e) => e.trim().toLowerCase());
76
+ const toEmail = this.getContactEmail(
77
+ Array.isArray(email.to) ? email.to[0] : email.to
78
+ );
79
+ if (this.isEmailAllowed(toEmail, allowedEmails)) return email;
80
+ if (fallback) return { ...email, to: fallback };
81
+ throw createInternalError(null, {
82
+ message: `Email not on whitelist and no fallback configured: ${toEmail}`,
83
+ code: "SYS-N-03",
84
+ status: 400
85
+ });
86
+ }
65
87
  async queue(batch) {
66
88
  for (const message of batch.messages) {
67
89
  this.logInput({ message });
@@ -112,7 +134,7 @@ let NotificationServiceBase = class extends develitWorker(
112
134
  async _sendEmail(input) {
113
135
  return this.handleAction(
114
136
  { data: input, schema: sendEmailInputSchema },
115
- { successMessage: "Email sent." },
137
+ { successMessage: "Email sent.", sensitiveKeys: ["attachments"] },
116
138
  async (params) => {
117
139
  const {
118
140
  email,
@@ -133,7 +155,8 @@ let NotificationServiceBase = class extends develitWorker(
133
155
  this.env.EMAIL_SENDER_NAME
134
156
  );
135
157
  }
136
- await this.emailConnector.sendEmail(email);
158
+ const filteredEmail = this.applyEmailWhitelist(email);
159
+ await this.emailConnector.sendEmail(filteredEmail);
137
160
  try {
138
161
  await this.pushToQueue(this.env.AUDIT_LOGS_QUEUE, {
139
162
  logType: "event",
@@ -148,10 +171,10 @@ let NotificationServiceBase = class extends develitWorker(
148
171
  userAgent,
149
172
  outcome: "success",
150
173
  description: `Email sent to ${email.to}`,
151
- details: JSON.stringify({
174
+ details: {
152
175
  subject: email.subject,
153
176
  templateId: email.templateId
154
- })
177
+ }
155
178
  });
156
179
  } catch (e) {
157
180
  console.error("Failed to push email audit log", e);
@@ -202,7 +225,7 @@ let NotificationServiceBase = class extends develitWorker(
202
225
  userAgent,
203
226
  outcome: "success",
204
227
  description: `SMS sent to ${to}`,
205
- details: JSON.stringify({ message })
228
+ details: { message }
206
229
  });
207
230
  } catch (e) {
208
231
  console.error("Failed to push sms audit log", e);
@@ -214,7 +237,7 @@ let NotificationServiceBase = class extends develitWorker(
214
237
  async sendEmail(input) {
215
238
  return this.handleAction(
216
239
  { data: input, schema: sendEmailInputSchema },
217
- { successMessage: "Email sent." },
240
+ { successMessage: "Email sent.", sensitiveKeys: ["attachments"] },
218
241
  async (params) => {
219
242
  const { email, metadata } = params;
220
243
  await this.pushToQueue(
@@ -234,7 +257,7 @@ let NotificationServiceBase = class extends develitWorker(
234
257
  async sendEmailSync(input) {
235
258
  return this.handleAction(
236
259
  { data: input, schema: sendEmailInputSchema },
237
- { successMessage: "Email sent." },
260
+ { successMessage: "Email sent.", sensitiveKeys: ["attachments"] },
238
261
  async (params) => {
239
262
  const { email, metadata } = params;
240
263
  return this._sendEmail({
@@ -302,9 +325,9 @@ let NotificationServiceBase = class extends develitWorker(
302
325
  userAgent: metadata?.userAgent,
303
326
  outcome: "success",
304
327
  description: "Slack notification sent",
305
- details: JSON.stringify({
328
+ details: {
306
329
  message: slack.message
307
- })
330
+ }
308
331
  });
309
332
  return {};
310
333
  }
@@ -371,9 +394,9 @@ let NotificationServiceBase = class extends develitWorker(
371
394
  userAgent,
372
395
  outcome: "success",
373
396
  description: `Webhook sent to ${webhook.url}`,
374
- details: JSON.stringify({
397
+ details: {
375
398
  url: webhook.url
376
- })
399
+ }
377
400
  });
378
401
  } catch (e) {
379
402
  console.error("Failed to push webhook audit log", e);
@@ -1,4 +1,4 @@
1
- import { N as NotificationServiceWranglerConfig } from '../shared/notification.Csi9Hg5K.cjs';
1
+ import { N as NotificationServiceWranglerConfig } from '../shared/notification.mdV1ug8W.cjs';
2
2
 
3
3
  declare function defineNotificationServiceWrangler(config: NotificationServiceWranglerConfig): {
4
4
  vars: {
@@ -9,6 +9,8 @@ declare function defineNotificationServiceWrangler(config: NotificationServiceWr
9
9
  EMAIL_SMTP_HOST: string;
10
10
  SMS_PROVIDER: "twilio";
11
11
  SLACK_WEBHOOK: string;
12
+ EMAIL_WHITELIST?: string;
13
+ EMAIL_WHITELIST_FALLBACK?: string;
12
14
  };
13
15
  services: {
14
16
  binding: string;
@@ -1,4 +1,4 @@
1
- import { N as NotificationServiceWranglerConfig } from '../shared/notification.Csi9Hg5K.mjs';
1
+ import { N as NotificationServiceWranglerConfig } from '../shared/notification.mdV1ug8W.mjs';
2
2
 
3
3
  declare function defineNotificationServiceWrangler(config: NotificationServiceWranglerConfig): {
4
4
  vars: {
@@ -9,6 +9,8 @@ declare function defineNotificationServiceWrangler(config: NotificationServiceWr
9
9
  EMAIL_SMTP_HOST: string;
10
10
  SMS_PROVIDER: "twilio";
11
11
  SLACK_WEBHOOK: string;
12
+ EMAIL_WHITELIST?: string;
13
+ EMAIL_WHITELIST_FALLBACK?: string;
12
14
  };
13
15
  services: {
14
16
  binding: string;
@@ -1,4 +1,4 @@
1
- import { N as NotificationServiceWranglerConfig } from '../shared/notification.Csi9Hg5K.js';
1
+ import { N as NotificationServiceWranglerConfig } from '../shared/notification.mdV1ug8W.js';
2
2
 
3
3
  declare function defineNotificationServiceWrangler(config: NotificationServiceWranglerConfig): {
4
4
  vars: {
@@ -9,6 +9,8 @@ declare function defineNotificationServiceWrangler(config: NotificationServiceWr
9
9
  EMAIL_SMTP_HOST: string;
10
10
  SMS_PROVIDER: "twilio";
11
11
  SLACK_WEBHOOK: string;
12
+ EMAIL_WHITELIST?: string;
13
+ EMAIL_WHITELIST_FALLBACK?: string;
12
14
  };
13
15
  services: {
14
16
  binding: string;
@@ -13,6 +13,8 @@ interface NotificationServiceEnvironmentConfig {
13
13
  EMAIL_SMTP_HOST: string;
14
14
  SMS_PROVIDER: 'twilio';
15
15
  SLACK_WEBHOOK: string;
16
+ EMAIL_WHITELIST?: string;
17
+ EMAIL_WHITELIST_FALLBACK?: string;
16
18
  };
17
19
  }
18
20
  interface NotificationServiceWranglerConfig {
@@ -13,6 +13,8 @@ interface NotificationServiceEnvironmentConfig {
13
13
  EMAIL_SMTP_HOST: string;
14
14
  SMS_PROVIDER: 'twilio';
15
15
  SLACK_WEBHOOK: string;
16
+ EMAIL_WHITELIST?: string;
17
+ EMAIL_WHITELIST_FALLBACK?: string;
16
18
  };
17
19
  }
18
20
  interface NotificationServiceWranglerConfig {
@@ -13,6 +13,8 @@ interface NotificationServiceEnvironmentConfig {
13
13
  EMAIL_SMTP_HOST: string;
14
14
  SMS_PROVIDER: 'twilio';
15
15
  SLACK_WEBHOOK: string;
16
+ EMAIL_WHITELIST?: string;
17
+ EMAIL_WHITELIST_FALLBACK?: string;
16
18
  };
17
19
  }
18
20
  interface NotificationServiceWranglerConfig {
package/dist/types.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { I as IEmailConnector, n as IEmail, o as IContact, a as ISmsConnector, p as ISms } from './shared/notification.BiG4Q650.cjs';
2
2
  export { C as ClearReceivedEmailsInput, m as ClearReceivedEmailsOutput, G as GetReceivedEmailsInput, j as GetReceivedEmailsOutput, q as IAttachment, r as IPushNotification, s as ISlack, t as IWebhook, N as NotificationQueueMessage, R as ReceivedEmail, b as SendEmailInput, c as SendEmailOutput, f as SendSlackInput, g as SendSlackOutput, d as SendSmsInput, e as SendSmsOutput, h as SendWebhookInput, i as SendWebhookOutput, S as SlackConnector, k as WaitForEmailInput, l as WaitForEmailOutput, W as WebhookConnector, u as clearReceivedEmailsInputSchema, v as getReceivedEmailsInputSchema, w as iAttachmentSchema, x as iContactSchema, y as iEmailSchema, z as sendEmailInputSchema, A as sendSlackInputSchema, B as sendSmsInputSchema, D as sendWebhookInputSchema, E as waitForEmailInputSchema } from './shared/notification.BiG4Q650.cjs';
3
3
  import twilio from 'twilio';
4
- export { a as NotificationServiceEnv, b as NotificationServiceEnvironmentConfig, N as NotificationServiceWranglerConfig } from './shared/notification.Csi9Hg5K.cjs';
4
+ export { a as NotificationServiceEnv, b as NotificationServiceEnvironmentConfig, N as NotificationServiceWranglerConfig } from './shared/notification.mdV1ug8W.cjs';
5
5
  import 'zod';
6
6
  import 'zod/v4';
7
7
 
package/dist/types.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { I as IEmailConnector, n as IEmail, o as IContact, a as ISmsConnector, p as ISms } from './shared/notification.BiG4Q650.mjs';
2
2
  export { C as ClearReceivedEmailsInput, m as ClearReceivedEmailsOutput, G as GetReceivedEmailsInput, j as GetReceivedEmailsOutput, q as IAttachment, r as IPushNotification, s as ISlack, t as IWebhook, N as NotificationQueueMessage, R as ReceivedEmail, b as SendEmailInput, c as SendEmailOutput, f as SendSlackInput, g as SendSlackOutput, d as SendSmsInput, e as SendSmsOutput, h as SendWebhookInput, i as SendWebhookOutput, S as SlackConnector, k as WaitForEmailInput, l as WaitForEmailOutput, W as WebhookConnector, u as clearReceivedEmailsInputSchema, v as getReceivedEmailsInputSchema, w as iAttachmentSchema, x as iContactSchema, y as iEmailSchema, z as sendEmailInputSchema, A as sendSlackInputSchema, B as sendSmsInputSchema, D as sendWebhookInputSchema, E as waitForEmailInputSchema } from './shared/notification.BiG4Q650.mjs';
3
3
  import twilio from 'twilio';
4
- export { a as NotificationServiceEnv, b as NotificationServiceEnvironmentConfig, N as NotificationServiceWranglerConfig } from './shared/notification.Csi9Hg5K.mjs';
4
+ export { a as NotificationServiceEnv, b as NotificationServiceEnvironmentConfig, N as NotificationServiceWranglerConfig } from './shared/notification.mdV1ug8W.mjs';
5
5
  import 'zod';
6
6
  import 'zod/v4';
7
7
 
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { I as IEmailConnector, n as IEmail, o as IContact, a as ISmsConnector, p as ISms } from './shared/notification.BiG4Q650.js';
2
2
  export { C as ClearReceivedEmailsInput, m as ClearReceivedEmailsOutput, G as GetReceivedEmailsInput, j as GetReceivedEmailsOutput, q as IAttachment, r as IPushNotification, s as ISlack, t as IWebhook, N as NotificationQueueMessage, R as ReceivedEmail, b as SendEmailInput, c as SendEmailOutput, f as SendSlackInput, g as SendSlackOutput, d as SendSmsInput, e as SendSmsOutput, h as SendWebhookInput, i as SendWebhookOutput, S as SlackConnector, k as WaitForEmailInput, l as WaitForEmailOutput, W as WebhookConnector, u as clearReceivedEmailsInputSchema, v as getReceivedEmailsInputSchema, w as iAttachmentSchema, x as iContactSchema, y as iEmailSchema, z as sendEmailInputSchema, A as sendSlackInputSchema, B as sendSmsInputSchema, D as sendWebhookInputSchema, E as waitForEmailInputSchema } from './shared/notification.BiG4Q650.js';
3
3
  import twilio from 'twilio';
4
- export { a as NotificationServiceEnv, b as NotificationServiceEnvironmentConfig, N as NotificationServiceWranglerConfig } from './shared/notification.Csi9Hg5K.js';
4
+ export { a as NotificationServiceEnv, b as NotificationServiceEnvironmentConfig, N as NotificationServiceWranglerConfig } from './shared/notification.mdV1ug8W.js';
5
5
  import 'zod';
6
6
  import 'zod/v4';
7
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@develit-services/notification",
3
- "version": "0.6.2",
3
+ "version": "1.0.0",
4
4
  "author": "Develit.io s.r.o.",
5
5
  "type": "module",
6
6
  "exports": {