@hartl-services/medusa-base 2.8.0 → 2.9.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.
Files changed (38) hide show
  1. package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginSettingsForm.js +4 -5
  2. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.d.ts +0 -5
  3. package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.js +0 -5
  4. package/.medusa/server/src/admin/admin-components/i18n/texts.d.ts +1 -2
  5. package/.medusa/server/src/admin/admin-components/i18n/texts.js +1 -2
  6. package/.medusa/server/src/admin/index.js +106 -69
  7. package/.medusa/server/src/admin/index.mjs +107 -70
  8. package/.medusa/server/src/api/admin/email/templates/[kind]/send-test/route.js +7 -1
  9. package/.medusa/server/src/email/application/warn-credential-expiry.js +77 -0
  10. package/.medusa/server/src/email/config/index.js +8 -2
  11. package/.medusa/server/src/email/config/notification-module.js +28 -2
  12. package/.medusa/server/src/email/domain/business-keys.js +5 -2
  13. package/.medusa/server/src/email/domain/failure-classification.js +9 -1
  14. package/.medusa/server/src/email/plugin-features.js +123 -1
  15. package/.medusa/server/src/email/rendering/default-templates.js +16 -1
  16. package/.medusa/server/src/email/rendering/render-email.js +2 -1
  17. package/.medusa/server/src/email/types/email-kinds.js +2 -1
  18. package/.medusa/server/src/email/types/template-data.js +8 -1
  19. package/.medusa/server/src/jobs/email-credential-expiry.js +27 -0
  20. package/.medusa/server/src/modules/email/domain/message-state.js +3 -1
  21. package/.medusa/server/src/modules/email/migrations/Migration20261011120000.js +20 -0
  22. package/.medusa/server/src/providers/smtp/delivery-settings.js +75 -0
  23. package/.medusa/server/src/providers/smtp/graph-transport.js +150 -0
  24. package/.medusa/server/src/providers/smtp/service.js +105 -37
  25. package/.medusa/server/src/providers/smtp/types.js +7 -1
  26. package/.medusa/server/src/shop-config/build-food-shop-config.js +3 -5
  27. package/README.md +100 -65
  28. package/dist/email/config/index.d.ts +6 -1
  29. package/dist/email/config/index.js +7 -1
  30. package/dist/email/config/notification-module.d.ts +25 -0
  31. package/dist/email/config/notification-module.js +27 -1
  32. package/dist/email/types/email-kinds.d.ts +2 -1
  33. package/dist/email/types/email-kinds.js +1 -0
  34. package/dist/email/types/template-data.d.ts +10 -0
  35. package/dist/email/types/template-data.js +7 -0
  36. package/dist/shop-config/build-food-shop-config.d.ts +1 -1
  37. package/dist/shop-config/build-food-shop-config.js +2 -4
  38. package/package.json +2 -2
package/README.md CHANGED
@@ -50,7 +50,7 @@ packing lists) and S3 file storage, and the turnkey `medusa-config.ts` preset
50
50
  `@hartl-services/medusa-base/config` and Sentry's `register()` from
51
51
  `@hartl-services/medusa-base/instrumentation` (see "Config helpers" and
52
52
  "Sentry instrumentation").
53
- - Sends the shop's transactional e-mails over SMTP (module `email`, see
53
+ - Sends the shop's transactional e-mails over SMTP or Microsoft 365, chosen in the Admin (module `email`, see
54
54
  "E-Mail"), issues invoices, cancellation documents and packing lists as
55
55
  private PDFs (module `documents`, see "Dokumente") and stores files in
56
56
  S3-compatible storage behind the `/files` gateway (see "Dateispeicher (S3)").
@@ -234,13 +234,18 @@ All optional; the Admin response always carries them (`null`, `[]` or
234
234
  unchanged, e.g. by the plugin switch of a switchable plugin). The Admin locks
235
235
  the switch of the last enabled top-level feature with a hint. The Admin DTO
236
236
  field is `require_enabled_feature: boolean` (`false` when not declared).
237
- - `setting_groups`: `{ name, description?, note?, requires_feature? }` per
237
+ - `setting_groups`: `{ name, description?, note?, requires_feature?, visible_when? }` per
238
238
  settings group. `name` equals the `group` of at least one setting and is
239
239
  unique; `requires_feature` is a declared feature key, the Admin dims the group
240
240
  (still editable) while that feature is not effectively enabled.
241
+ `visible_when: { setting, equals }` names a `select` or `boolean` setting
242
+ outside the group and one of its values: the group applies only while that
243
+ setting has the value. The Admin hides it otherwise (by the form's current
244
+ value), and its required settings do not count as `missing`; stored values
245
+ are kept. The Admin DTO carries `visible_when` or `null`.
241
246
  - Per setting: `hint` (short text under the field, shown instead of
242
247
  `description`), `placeholder` (not for `boolean`, `select`, `image`,
243
- `color`), `width` (`"full"` default or `"half"`: consecutive half settings
248
+ `color`, `date`), `width` (`"full"` default or `"half"`: consecutive half settings
244
249
  share a two-column row; not for `boolean`) and `section` (sub-heading inside
245
250
  the group, shared by consecutive settings with the same value).
246
251
 
@@ -338,7 +343,7 @@ in-memory copy of the toggle (see "Kontobestätigung per E-Mail").
338
343
 
339
344
  Configuration a plugin reads at RUN time (for example an external system's
340
345
  URL and API key) is declared in the descriptor and edited on the plugin's
341
- Admin page. Boot-time provider configuration (SMTP, S3, Sentry, Redis) and
346
+ Admin page. Boot-time provider configuration (S3, Sentry, Redis) and
342
347
  function-valued options stay in `medusa-config.ts`.
343
348
 
344
349
  ```ts
@@ -383,7 +388,8 @@ class DemoModuleService extends MedusaService({ /* models */ }) {
383
388
  through Medusa's `/admin/uploads` into the public File Module storage and
384
389
  previews; replacing or removing it leaves the old file in storage), `color`
385
390
  (a hex color `#rrggbb`, stored lowercase; the Admin shows a hex field with a
386
- color picker and checks the format before saving). An optional `group`
391
+ color picker and checks the format before saving), `date` (a calendar day
392
+ `YYYY-MM-DD`; the Admin shows `AdminDatePicker`). An optional `group`
387
393
  (non-empty text) is a section heading: the Admin starts a new section with
388
394
  that heading whenever the group changes from one setting to the next. Keys
389
395
  follow the feature key format and are unique. A `secret` has no default;
@@ -394,8 +400,8 @@ class DemoModuleService extends MedusaService({ /* models */ }) {
394
400
  `api_url` so a stored key is never sent to a new host. `definePluginFeatures`
395
401
  throws at import time otherwise (also for an `invalidates` entry that is not
396
402
  a secret of the plugin). The Admin renders a `select` as a dropdown, gives
397
- number inputs their bounds and shows "Beim Ändern muss … neu eingegeben
398
- werden" under a setting with `invalidates`.
403
+ number inputs their bounds and shows "Wird gelöscht, wenn … sich ändert"
404
+ under each secret named in an `invalidates`.
399
405
  - Precedence per key: stored in the Admin > `pluginSettingsFallback`
400
406
  (medusa-config) > declared default > not set. A value that does not fit the
401
407
  declared type is skipped. A plugin is `configured` when every required
@@ -1326,7 +1332,7 @@ have no dependency on Medusa; the subpath does not load `@sentry/node`.
1326
1332
  | `resolvePublicOrigin(value, name, allowHttp)`, `shopUrl(origin, path)` | Validate a bare HTTP(S) origin; build an absolute URL that cannot leave the origin |
1327
1333
  | `resolveStripe(values)` | Checks the `sk_` key and the `whsec_` webhook secret |
1328
1334
  | `resolveRedisEventBus(environment, phase)` | `{ url } \| undefined`: optional in development, required at runtime elsewhere, never used in a build, authenticated `rediss://` in production |
1329
- | `createSmtpNotificationModuleConfig`, `resolveSmtp`, `SMTP_ENVIRONMENT_VARIABLES`, `SMTP_BUILD_PLACEHOLDERS`, `defineShopEmailConfiguration` | SMTP notification provider and E-Mail configuration (see "E-Mail") |
1335
+ | `createEmailNotificationModuleConfig`, `defineShopEmailConfiguration` (deprecated: `createSmtpNotificationModuleConfig`, `resolveSmtp`, `SMTP_ENVIRONMENT_VARIABLES`, `SMTP_BUILD_PLACEHOLDERS`) | Mail notification provider and E-Mail configuration (see "E-Mail") |
1330
1336
  | `createS3CacheStorageConfig`, `createS3CacheFileModuleConfig`, `resolveS3Credentials`, `resolveExpirationStrategy`, `S3_BUILD_PLACEHOLDERS` | S3 file storage (see "Dateispeicher (S3)") |
1331
1337
  | `createDefaultDocumentHtmlFactory`, `DOCUMENTS_BUILD_PLACEHOLDERS` | Documents markup and build placeholder (see "Dokumente") |
1332
1338
 
@@ -1373,36 +1379,32 @@ this export (or `sentry-logger`) lists `@sentry/node` in its own
1373
1379
  ## E-Mail
1374
1380
 
1375
1381
  The base owns transactional e-mail for the shop: logical email messages,
1376
- attempts, rendering, the Medusa Notification integration, SMTP transport,
1377
- retries and e-mail-specific Admin operations. It is the `email` module, its
1378
- SMTP notification provider (`providers/smtp`), its subscribers, jobs and
1382
+ attempts, rendering, the Medusa Notification integration, the SMTP and
1383
+ Microsoft 365 transports, retries and e-mail-specific Admin operations. It is
1384
+ the `email` module, its notification provider (`providers/smtp`, id `smtp`),
1385
+ its subscribers, jobs and
1379
1386
  workflows, and the Admin page `/settings/hartl-services/email`. There is no
1380
1387
  separate e-mail package since 1.0.0.
1381
1388
 
1382
1389
  ### Configuration
1383
1390
 
1384
- The SMTP notification provider is a `modules` entry built by
1385
- `createSmtpNotificationModuleConfig` (from
1386
- `@hartl-services/medusa-base/config`); the branding and rendering
1391
+ The notification provider is a `modules` entry built by
1392
+ `createEmailNotificationModuleConfig` (from
1393
+ `@hartl-services/medusa-base/config`); which service it sends through and the
1394
+ credentials are set in the Admin (see "Versand"). The branding and rendering
1387
1395
  configuration goes into the `email` namespace of the base options:
1388
1396
 
1389
1397
  ```ts
1390
- import {
1391
- createSmtpNotificationModuleConfig,
1392
- resolveSmtp,
1393
- SMTP_ENVIRONMENT_VARIABLES,
1394
- } from "@hartl-services/medusa-base/config";
1395
-
1396
- // Validates the seven SMTP_* variables (see "SMTP environment helpers").
1397
- const smtp = resolveSmtp(
1398
- Object.fromEntries(
1399
- SMTP_ENVIRONMENT_VARIABLES.map((name) => [name, process.env[name] ?? ""]),
1400
- ) as Record<(typeof SMTP_ENVIRONMENT_VARIABLES)[number], string>,
1401
- process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test",
1402
- );
1398
+ import { createEmailNotificationModuleConfig } from "@hartl-services/medusa-base/config";
1403
1399
 
1404
1400
  export default defineConfig({
1405
- modules: [createSmtpNotificationModuleConfig(smtp)],
1401
+ modules: [
1402
+ createEmailNotificationModuleConfig({
1403
+ // Permits "Verschlüsselung: Keine" (a local SMTP server); never in production.
1404
+ allowInsecure:
1405
+ process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test",
1406
+ }),
1407
+ ],
1406
1408
  plugins: [
1407
1409
  {
1408
1410
  resolve: "@hartl-services/medusa-base",
@@ -1456,24 +1458,73 @@ affiliate-reminder and partner-application e-mails come from
1456
1458
  `@hartl-services/medusa-food-supplements-contracts/events/documents` and
1457
1459
  `/events/affiliate`, so installing the base does not pull in Affiliate.
1458
1460
 
1459
- Environment variables (all seven required outside development/test; at least
1460
- one of `SMTP_SECURE`/`SMTP_REQUIRE_TLS` must be `true` outside
1461
- development/test):
1462
-
1463
- ```text
1464
- SMTP_HOST=
1465
- SMTP_PORT=
1466
- SMTP_SECURE=
1467
- SMTP_REQUIRE_TLS=
1468
- SMTP_USER=
1469
- SMTP_PASSWORD=
1470
- SMTP_FROM=
1471
- ```
1461
+ The provider reads no environment variables (since 2.9.0; the former
1462
+ `SMTP_*` variables are ignored).
1472
1463
 
1473
1464
  Set `REDIS_URL` to use `@medusajs/event-bus-redis` instead of Medusa's local
1474
1465
  Event Bus; production requires an authenticated `rediss://` URL. See "Event
1475
1466
  Bus" below for retry/backoff behavior.
1476
1467
 
1468
+ ### Versand
1469
+
1470
+ The page E-Mail → "Versand" (`/settings/hartl-services/email/delivery`, linked
1471
+ under "Verwaltung") edits the plugin's settings. It stays reachable while the
1472
+ E-Mail plugin is off, because the login-code mail is still sent then.
1473
+
1474
+ | Key | Type | Required |
1475
+ |---|---|---|
1476
+ | `provider` (Versand über, group "Anbieter") | select `smtp` \| `microsoft365` | yes |
1477
+ | `smtp_host`, `smtp_port` (default 587), `smtp_security` (`starttls` default, `tls`, `none`), `smtp_from` (Absender, `Name <address>` allowed) | string / number / select / string | yes, while SMTP |
1478
+ | `smtp_user`, `smtp_password` (secret) | string / secret | no (no login without a user) |
1479
+ | `microsoft_tenant_id`, `microsoft_client_id`, `microsoft_client_secret` (secret), `microsoft_client_secret_expires_on` (date), `microsoft_mailbox` (Postfach) | string / secret / date | yes, while Microsoft 365 |
1480
+
1481
+ The groups "SMTP" and "Microsoft 365" are shown and required only for the
1482
+ selected provider (`visible_when`). Changing the host deletes the SMTP
1483
+ password; changing tenant or client id deletes the client secret.
1484
+
1485
+ The provider reads the settings on every send, never at boot; a shop without
1486
+ them boots and its mails fail as `not_configured` (retried like a connection
1487
+ failure, then `failed`; a log warning names the missing keys). `none`
1488
+ encryption is accepted only with `allowInsecure`. A rejected login (SMTP
1489
+ `EAUTH`, a Graph token or 401/403 error) is `auth_failed` and not retried.
1490
+ The test mail of the template editor shows both as their own message.
1491
+
1492
+ **Microsoft 365** sends with Microsoft Graph `POST /users/{mailbox}/sendMail`
1493
+ and an app-only token (client credentials, cached in memory per tenant,
1494
+ client and secret). Graph has one body, so the mail goes out as HTML; it is
1495
+ saved to the mailbox's Sent Items. A request above 4 MB (large PDF
1496
+ attachments) fails as `invalid_content`. 429 and 5xx are temporary, other 4xx
1497
+ permanent. Setup:
1498
+
1499
+ 1. Microsoft Entra admin center → App registrations → New registration
1500
+ (single tenant, no redirect URI). Note the Application (client) ID and
1501
+ Directory (tenant) ID.
1502
+ 2. Certificates & secrets → New client secret (at most 24 months); copy the
1503
+ value and its expiry date.
1504
+ 3. Do **not** grant the Graph application permission `Mail.Send` in Entra: it
1505
+ would allow sending as every mailbox. Grant it in Exchange Online, limited
1506
+ to the shop's mailbox (RBAC for Applications), in Exchange Online
1507
+ PowerShell:
1508
+
1509
+ ```powershell
1510
+ New-ServicePrincipal -AppId <client-id> -ObjectId <enterprise-app-object-id> -DisplayName "Shop Mail"
1511
+ New-ManagementScope -Name "Shop Mailbox" -RecipientRestrictionFilter "PrimarySmtpAddress -eq 'shop@example.com'"
1512
+ New-ManagementRoleAssignment -App <client-id> -Role "Application Mail.Send" -CustomResourceScope "Shop Mailbox"
1513
+ ```
1514
+
1515
+ (`<enterprise-app-object-id>` is the object id under Enterprise
1516
+ applications, not the one of the app registration.)
1517
+ 4. In the Admin: E-Mail → Versand → Anbieter "Microsoft 365", enter tenant
1518
+ id, client id, secret, its expiry date and the mailbox; send a test mail
1519
+ from a template.
1520
+
1521
+ Seven days before "Secret gültig bis" (shop time zone) the daily job
1522
+ `email-credential-expiry` (07:00 server time, while the E-Mail plugin is on
1523
+ and Microsoft 365 is selected) sends the mail `system.credential_expiry.admin`
1524
+ to the e-mail of the Shop-Stammdaten, once per client id and expiry date (a
1525
+ log warning when the Shop-Stammdaten have no e-mail). A new secret with a new
1526
+ date warns again.
1527
+
1477
1528
  ### Feature toggles
1478
1529
 
1479
1530
  The E-Mail module declares its toggles to `@hartl-services/medusa-base` under the
@@ -1996,30 +2047,14 @@ configuration (blank `displayName`, a non-function `layout` or renderer, an
1996
2047
  unknown renderer kind) fails at startup and not at the first send. Custom
1997
2048
  renderers must escape dynamic values in `bodyHtml` themselves.
1998
2049
 
1999
- ### SMTP environment helpers
2000
-
2001
- `@hartl-services/medusa-base/config` exports helpers for the SMTP
2002
- deployment variables:
2003
-
2004
- - `SMTP_ENVIRONMENT_VARIABLES` — the seven variable names.
2005
- - `SMTP_BUILD_PLACEHOLDERS` — placeholder values for all seven variables so
2006
- `medusa build` can load `medusa-config.ts` without deployment secrets. Use
2007
- them only while building.
2008
- - `resolveSmtp(values, allowInsecure)` — validates the values and returns the
2009
- `ResolvedSmtpConfiguration` for `createSmtpNotificationModuleConfig`. It
2010
- rejects a port outside 1–65535, a non-`"true"`/`"false"` boolean and an
2011
- invalid `SMTP_FROM`. `allowInsecure` permits plain SMTP (development, test,
2012
- build); otherwise `SMTP_SECURE` or `SMTP_REQUIRE_TLS` must be `true`.
2013
-
2014
- Runtime requires `SMTP_HOST`, `SMTP_PORT`, `SMTP_SECURE`, `SMTP_REQUIRE_TLS`,
2015
- `SMTP_USER`, `SMTP_PASSWORD`, and `SMTP_FROM`. `SMTP_FROM` is a bare address
2016
- or carries the sender's display name: `Example GmbH <info@example.com>` (quote
2017
- the value in a `.env` file). `SMTP_SECURE=true` selects
2018
- implicit TLS; `SMTP_REQUIRE_TLS=true` requires STARTTLS. Outside development
2019
- and test, at least one must be true. Certificate verification is never
2020
- disabled. Development and test may set both to `false` for an isolated local
2021
- SMTP server. SMTP endpoints and credentials never belong in the shop
2022
- configuration.
2050
+ ### Deprecated SMTP helpers
2051
+
2052
+ `createSmtpNotificationModuleConfig(smtp)`, `resolveSmtp`,
2053
+ `SMTP_ENVIRONMENT_VARIABLES` and `SMTP_BUILD_PLACEHOLDERS` remain exported
2054
+ for shops that still read `SMTP_*` in their `medusa-config.ts`. The values
2055
+ given to `createSmtpNotificationModuleConfig` only fill SMTP settings that are
2056
+ not stored in the Admin (the Admin status does not count them as configured).
2057
+ Use `createEmailNotificationModuleConfig` and the "Versand" page instead.
2023
2058
 
2024
2059
  ### Delivery Semantics
2025
2060
 
@@ -1,15 +1,20 @@
1
1
  import type { ResolvedSmtpConfiguration, ShopEmailConfiguration } from "../types";
2
- export { createSmtpNotificationModuleConfig } from "./notification-module";
2
+ export { createEmailNotificationModuleConfig, createSmtpNotificationModuleConfig, } from "./notification-module";
3
3
  export declare const defineShopEmailConfiguration: <Configuration extends ShopEmailConfiguration>(configuration: Configuration) => Configuration;
4
4
  export type { ResolvedSmtpConfiguration, ShopEmailConfiguration, } from "../types";
5
+ /** @deprecated The provider is set in the Admin (E-Mail > Versand). */
5
6
  export declare const SMTP_ENVIRONMENT_VARIABLES: readonly ["SMTP_HOST", "SMTP_PORT", "SMTP_SECURE", "SMTP_USER", "SMTP_PASSWORD", "SMTP_FROM", "SMTP_REQUIRE_TLS"];
6
7
  /**
8
+ * @deprecated The provider is set in the Admin (E-Mail > Versand).
9
+ *
7
10
  * `medusa build` loads the configuration without deployment secrets. These
8
11
  * placeholders only satisfy the required-variable checks of a build; they
9
12
  * never reach a running server.
10
13
  */
11
14
  export declare const SMTP_BUILD_PLACEHOLDERS: Readonly<Record<string, string>>;
12
15
  /**
16
+ * @deprecated The provider is set in the Admin (E-Mail > Versand).
17
+ *
13
18
  * Validates the SMTP environment values and returns the transport
14
19
  * configuration. `allowInsecure` permits plain SMTP for development, tests
15
20
  * and builds; otherwise `SMTP_SECURE` or `SMTP_REQUIRE_TLS` must be `true`.
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveSmtp = exports.SMTP_BUILD_PLACEHOLDERS = exports.SMTP_ENVIRONMENT_VARIABLES = exports.defineShopEmailConfiguration = exports.createSmtpNotificationModuleConfig = void 0;
3
+ exports.resolveSmtp = exports.SMTP_BUILD_PLACEHOLDERS = exports.SMTP_ENVIRONMENT_VARIABLES = exports.defineShopEmailConfiguration = exports.createSmtpNotificationModuleConfig = exports.createEmailNotificationModuleConfig = void 0;
4
4
  const config_1 = require("../../public/config");
5
5
  const sender_1 = require("../domain/sender");
6
6
  var notification_module_1 = require("./notification-module");
7
+ Object.defineProperty(exports, "createEmailNotificationModuleConfig", { enumerable: true, get: function () { return notification_module_1.createEmailNotificationModuleConfig; } });
7
8
  Object.defineProperty(exports, "createSmtpNotificationModuleConfig", { enumerable: true, get: function () { return notification_module_1.createSmtpNotificationModuleConfig; } });
8
9
  const defineShopEmailConfiguration = (configuration) => configuration;
9
10
  exports.defineShopEmailConfiguration = defineShopEmailConfiguration;
11
+ /** @deprecated The provider is set in the Admin (E-Mail > Versand). */
10
12
  exports.SMTP_ENVIRONMENT_VARIABLES = [
11
13
  "SMTP_HOST",
12
14
  "SMTP_PORT",
@@ -17,6 +19,8 @@ exports.SMTP_ENVIRONMENT_VARIABLES = [
17
19
  "SMTP_REQUIRE_TLS",
18
20
  ];
19
21
  /**
22
+ * @deprecated The provider is set in the Admin (E-Mail > Versand).
23
+ *
20
24
  * `medusa build` loads the configuration without deployment secrets. These
21
25
  * placeholders only satisfy the required-variable checks of a build; they
22
26
  * never reach a running server.
@@ -31,6 +35,8 @@ exports.SMTP_BUILD_PLACEHOLDERS = {
31
35
  SMTP_USER: "build-user",
32
36
  };
33
37
  /**
38
+ * @deprecated The provider is set in the Admin (E-Mail > Versand).
39
+ *
34
40
  * Validates the SMTP environment values and returns the transport
35
41
  * configuration. `allowInsecure` permits plain SMTP for development, tests
36
42
  * and builds; otherwise `SMTP_SECURE` or `SMTP_REQUIRE_TLS` must be `true`.
@@ -1,4 +1,29 @@
1
1
  import type { ResolvedSmtpConfiguration } from "../types";
2
+ /**
3
+ * The Notification Module with the shop's mail provider. Provider and
4
+ * credentials are set in the Admin (E-Mail > Versand); `allowInsecure`
5
+ * (development and tests only) permits SMTP without encryption there.
6
+ */
7
+ export declare const createEmailNotificationModuleConfig: (options?: Readonly<{
8
+ allowInsecure?: boolean;
9
+ }>) => {
10
+ resolve: string;
11
+ options: {
12
+ providers: {
13
+ id: string;
14
+ options: {
15
+ allowInsecure: boolean;
16
+ channels: string[];
17
+ };
18
+ resolve: string;
19
+ }[];
20
+ };
21
+ };
22
+ /**
23
+ * @deprecated Use `createEmailNotificationModuleConfig` and set the provider
24
+ * in the Admin (E-Mail > Versand). The SMTP values given here only fill the
25
+ * SMTP settings that are not stored in the Admin.
26
+ */
2
27
  export declare const createSmtpNotificationModuleConfig: (smtp: ResolvedSmtpConfiguration) => {
3
28
  resolve: string;
4
29
  options: {
@@ -1,6 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createSmtpNotificationModuleConfig = void 0;
3
+ exports.createSmtpNotificationModuleConfig = exports.createEmailNotificationModuleConfig = void 0;
4
+ /**
5
+ * The Notification Module with the shop's mail provider. Provider and
6
+ * credentials are set in the Admin (E-Mail > Versand); `allowInsecure`
7
+ * (development and tests only) permits SMTP without encryption there.
8
+ */
9
+ const createEmailNotificationModuleConfig = (options = {}) => ({
10
+ resolve: "@medusajs/medusa/notification",
11
+ options: {
12
+ providers: [
13
+ {
14
+ id: "smtp",
15
+ options: {
16
+ allowInsecure: options.allowInsecure === true,
17
+ channels: ["email"],
18
+ },
19
+ resolve: "@hartl-services/medusa-base/providers/smtp",
20
+ },
21
+ ],
22
+ },
23
+ });
24
+ exports.createEmailNotificationModuleConfig = createEmailNotificationModuleConfig;
25
+ /**
26
+ * @deprecated Use `createEmailNotificationModuleConfig` and set the provider
27
+ * in the Admin (E-Mail > Versand). The SMTP values given here only fill the
28
+ * SMTP settings that are not stored in the Admin.
29
+ */
4
30
  const createSmtpNotificationModuleConfig = (smtp) => ({
5
31
  resolve: "@medusajs/medusa/notification",
6
32
  options: {
@@ -1,5 +1,5 @@
1
1
  import { z } from "@medusajs/framework/zod";
2
- export declare const EMAIL_KINDS: readonly ["order.received", "order.received.admin", "order.shipped", "order.canceled", "order.return_requested", "order.return_received", "order.refunded", "auth.password_reset", "affiliate.consignment_report_due", "affiliate.application_submitted.admin", "user.invite", "auth.verification", "auth.login_code"];
2
+ export declare const EMAIL_KINDS: readonly ["order.received", "order.received.admin", "order.shipped", "order.canceled", "order.return_requested", "order.return_received", "order.refunded", "auth.password_reset", "affiliate.consignment_report_due", "affiliate.application_submitted.admin", "user.invite", "auth.verification", "auth.login_code", "system.credential_expiry.admin"];
3
3
  export declare const EmailKindSchema: z.ZodEnum<{
4
4
  "order.received": "order.received";
5
5
  "order.received.admin": "order.received.admin";
@@ -14,6 +14,7 @@ export declare const EmailKindSchema: z.ZodEnum<{
14
14
  "user.invite": "user.invite";
15
15
  "auth.verification": "auth.verification";
16
16
  "auth.login_code": "auth.login_code";
17
+ "system.credential_expiry.admin": "system.credential_expiry.admin";
17
18
  }>;
18
19
  export type EmailKind = (typeof EMAIL_KINDS)[number];
19
20
  /**
@@ -16,6 +16,7 @@ exports.EMAIL_KINDS = [
16
16
  "user.invite",
17
17
  "auth.verification",
18
18
  "auth.login_code",
19
+ "system.credential_expiry.admin",
19
20
  ];
20
21
  exports.EmailKindSchema = zod_1.z.enum(exports.EMAIL_KINDS);
21
22
  /**
@@ -376,6 +376,11 @@ export declare const EmailPersistedDataSchemas: {
376
376
  locale: z.ZodNullable<z.ZodString>;
377
377
  }, z.core.$strict>;
378
378
  readonly "auth.login_code": z.ZodObject<{}, z.core.$strict>;
379
+ readonly "system.credential_expiry.admin": z.ZodObject<{
380
+ provider: z.ZodLiteral<"microsoft365">;
381
+ client_id: z.ZodString;
382
+ expires_on: z.ZodString;
383
+ }, z.core.$strict>;
379
384
  };
380
385
  export declare const EmailRenderDataSchemas: {
381
386
  readonly "auth.password_reset": z.ZodObject<{
@@ -619,6 +624,11 @@ export declare const EmailRenderDataSchemas: {
619
624
  company_name: z.ZodNullable<z.ZodString>;
620
625
  message: z.ZodNullable<z.ZodString>;
621
626
  }, z.core.$strict>;
627
+ readonly "system.credential_expiry.admin": z.ZodObject<{
628
+ provider: z.ZodLiteral<"microsoft365">;
629
+ client_id: z.ZodString;
630
+ expires_on: z.ZodString;
631
+ }, z.core.$strict>;
622
632
  };
623
633
  export type EmailPersistedDataMap = {
624
634
  readonly [Kind in EmailKind]: Readonly<z.infer<(typeof EmailPersistedDataSchemas)[Kind]>>;
@@ -233,6 +233,13 @@ exports.EmailPersistedDataSchemas = {
233
233
  .strict(),
234
234
  // The code itself is never stored: it only exists in the render context.
235
235
  "auth.login_code": zod_1.z.object({}).strict(),
236
+ "system.credential_expiry.admin": zod_1.z
237
+ .object({
238
+ provider: zod_1.z.literal("microsoft365"),
239
+ client_id: NonEmptyStringSchema,
240
+ expires_on: affiliate_1.CalendarDateSchema,
241
+ })
242
+ .strict(),
236
243
  };
237
244
  exports.EmailRenderDataSchemas = {
238
245
  ...exports.EmailPersistedDataSchemas,
@@ -31,7 +31,7 @@ export type FoodShopConfigInput = {
31
31
  };
32
32
  /**
33
33
  * Builds the plain `medusa-config.ts` input of a food shop: Medusa core
34
- * settings, the Redis event bus, SMTP notifications, S3 file storage, tax and
34
+ * settings, the Redis event bus, the mail provider (set up in the Admin), S3 file storage, tax and
35
35
  * Stripe payment providers, and the Hartl Services plugins (the base plugin
36
36
  * with its E-Mail, Documents and file storage modules plus five feature
37
37
  * plugins). Deployment
@@ -12,7 +12,7 @@ const sentry_logger_1 = require("../public/sentry-logger");
12
12
  const options_1 = require("./options");
13
13
  /**
14
14
  * Builds the plain `medusa-config.ts` input of a food shop: Medusa core
15
- * settings, the Redis event bus, SMTP notifications, S3 file storage, tax and
15
+ * settings, the Redis event bus, the mail provider (set up in the Admin), S3 file storage, tax and
16
16
  * Stripe payment providers, and the Hartl Services plugins (the base plugin
17
17
  * with its E-Mail, Documents and file storage modules plus five feature
18
18
  * plugins). Deployment
@@ -35,7 +35,6 @@ function buildFoodShopConfig(options, environment = process.env) {
35
35
  "COOKIE_SECRET",
36
36
  "MEDUSA_BACKEND_URL",
37
37
  "STOREFRONT_URL",
38
- ...config_1.SMTP_ENVIRONMENT_VARIABLES,
39
38
  "STRIPE_API_KEY",
40
39
  "STRIPE_WEBHOOK_SECRET",
41
40
  "S3_CACHE_STORAGE_BUCKET",
@@ -43,7 +42,6 @@ function buildFoodShopConfig(options, environment = process.env) {
43
42
  "DOCUMENT_PDF_EXECUTABLE",
44
43
  ], phase, {
45
44
  ...config_1.MEDUSA_BUILD_PLACEHOLDERS,
46
- ...config_1.SMTP_BUILD_PLACEHOLDERS,
47
45
  ...config_1.S3_BUILD_PLACEHOLDERS,
48
46
  ...config_1.DOCUMENTS_BUILD_PLACEHOLDERS,
49
47
  });
@@ -101,7 +99,7 @@ function buildFoodShopConfig(options, environment = process.env) {
101
99
  },
102
100
  ]
103
101
  : []),
104
- (0, config_1.createSmtpNotificationModuleConfig)((0, config_1.resolveSmtp)(env, allowInsecure)),
102
+ (0, config_1.createEmailNotificationModuleConfig)({ allowInsecure }),
105
103
  s3CacheStorage.fileModule,
106
104
  {
107
105
  // Replaces Medusa's default auth entry (same module key): the same
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hartl-services/medusa-base",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
4
4
  "description": "Base plugin for Hartl Services Medusa shops: per-plugin feature toggles with a generic Admin settings page, a Store endpoint for storefronts, enforcement helpers, the complete-cart hook composition, the root redirect, cart-promotion link repair, the built-in E-Mail, Documents and S3 file storage modules, config helpers with the turnkey food-shop preset, and the Sentry logger wrapper and instrumentation.",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -101,7 +101,7 @@
101
101
  "mime-types": "3.0.1",
102
102
  "nodemailer": "6.10.1",
103
103
  "ulid": "^2.4.0",
104
- "@hartl-services/medusa-food-supplements-contracts": "^0.28.0"
104
+ "@hartl-services/medusa-food-supplements-contracts": "^0.29.0"
105
105
  },
106
106
  "devDependencies": {
107
107
  "@medusajs/admin-sdk": "2.19.0",