@hartl-services/medusa-base 1.1.0 → 2.1.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 (50) hide show
  1. package/.medusa/server/src/admin/index.js +3 -1
  2. package/.medusa/server/src/admin/index.mjs +3 -1
  3. package/.medusa/server/src/api/customer-verification-request-throttle.js +50 -0
  4. package/.medusa/server/src/api/middlewares.js +31 -1
  5. package/.medusa/server/src/api/store/customer-verification/resend/route.js +17 -0
  6. package/.medusa/server/src/documents/utils/document-merchant.js +5 -5
  7. package/.medusa/server/src/email/application/handle-customer-verification-event.js +341 -0
  8. package/.medusa/server/src/email/application/resend-customer-verification.js +65 -0
  9. package/.medusa/server/src/email/application/start-customer-verification-snapshot.js +21 -0
  10. package/.medusa/server/src/email/application/throttle-verification-request.js +49 -0
  11. package/.medusa/server/src/email/customer-verification-snapshot.js +144 -0
  12. package/.medusa/server/src/email/domain/business-keys.js +12 -2
  13. package/.medusa/server/src/email/domain/customer-verification-resend.js +37 -0
  14. package/.medusa/server/src/email/domain/event-schemas.js +18 -2
  15. package/.medusa/server/src/email/plugin-features.js +9 -2
  16. package/.medusa/server/src/email/rendering/default-templates.js +20 -1
  17. package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +5 -1
  18. package/.medusa/server/src/email/types/email-kinds.js +14 -2
  19. package/.medusa/server/src/email/types/template-data.js +9 -1
  20. package/.medusa/server/src/modules/documents/domain/merchant.js +2 -33
  21. package/.medusa/server/src/modules/documents/domain/options.js +1 -7
  22. package/.medusa/server/src/modules/email/migrations/Migration20261001090000.js +16 -0
  23. package/.medusa/server/src/modules/email/service.js +30 -8
  24. package/.medusa/server/src/public/shop-master-data.js +6 -6
  25. package/.medusa/server/src/shop-config/build-food-shop-config.js +17 -6
  26. package/.medusa/server/src/shop-config/options.js +1 -15
  27. package/.medusa/server/src/subscribers/customer-verification.js +23 -0
  28. package/.medusa/server/src/workflows/documents/issue-cancellation-after-refund.js +2 -3
  29. package/.medusa/server/src/workflows/documents/issue-document.js +3 -4
  30. package/.medusa/server/src/workflows/documents/issue-packing-list.js +2 -2
  31. package/.medusa/server/src/workflows/email/dispatch-email-message.js +4 -2
  32. package/README.md +154 -49
  33. package/dist/documents/types/documents.d.ts +0 -22
  34. package/dist/email/customer-verification-snapshot.d.ts +53 -0
  35. package/dist/email/customer-verification-snapshot.js +143 -0
  36. package/dist/email/types/email-kinds.d.ts +9 -1
  37. package/dist/email/types/email-kinds.js +13 -1
  38. package/dist/email/types/shop-configuration.d.ts +8 -0
  39. package/dist/email/types/template-data.d.ts +9 -0
  40. package/dist/email/types/template-data.js +8 -0
  41. package/dist/modules/documents/domain/options.d.ts +1 -9
  42. package/dist/modules/documents/domain/options.js +0 -6
  43. package/dist/public/shop-master-data.d.ts +4 -5
  44. package/dist/public/shop-master-data.js +5 -5
  45. package/dist/shop-config/build-food-shop-config.js +16 -5
  46. package/dist/shop-config/options.d.ts +4 -6
  47. package/dist/shop-config/options.js +0 -14
  48. package/package.json +2 -2
  49. package/dist/modules/documents/domain/merchant.d.ts +0 -22
  50. package/dist/modules/documents/domain/merchant.js +0 -85
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resendCustomerVerification = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const core_flows_1 = require("@medusajs/medusa/core-flows");
6
+ const customer_verification_resend_1 = require("../domain/customer-verification-resend");
7
+ /**
8
+ * Requests a new confirmation mail for the customer account registered with
9
+ * `email`, if there is one that is not confirmed yet and was not asked for
10
+ * within the last minute. The caller answers the same way in every case, so
11
+ * the result is for tests and logs only. A failure is logged with a fixed
12
+ * message and the error's class only (its text can carry the address, a
13
+ * unique-index error does) and not rethrown: an error for existing accounts
14
+ * only would reveal them.
15
+ */
16
+ const resendCustomerVerification = async (container, email, now = new Date()) => {
17
+ let requested = 0;
18
+ try {
19
+ const auth = container.resolve(utils_1.Modules.AUTH);
20
+ const providerIdentities = (await Promise.all((0, customer_verification_resend_1.verificationLookupEmails)(email).map((lookupEmail) => auth.listProviderIdentities({ provider: "emailpass", entity_id: lookupEmail }, { relations: ["auth_identity"], take: 1 })))).flat();
21
+ for (const providerIdentity of providerIdentities) {
22
+ const authIdentity = providerIdentity.auth_identity;
23
+ const customerId = authIdentity?.app_metadata?.customer_id;
24
+ // Admin users and identities no customer claimed get no mail.
25
+ if (!authIdentity || typeof customerId !== "string" || !customerId) {
26
+ continue;
27
+ }
28
+ const [verification] = await auth.listAuthVerifications({
29
+ auth_identity_id: authIdentity.id,
30
+ entity_id: providerIdentity.entity_id,
31
+ entity_type: "email",
32
+ }, { take: 1 });
33
+ if ((0, customer_verification_resend_1.decideCustomerVerificationResend)({
34
+ now,
35
+ verification: verification ?? null,
36
+ }) !== "request") {
37
+ continue;
38
+ }
39
+ await (0, core_flows_1.requestVerificationWorkflow)(container).run({
40
+ input: {
41
+ auth_identity_id: authIdentity.id,
42
+ entity_id: providerIdentity.entity_id,
43
+ entity_type: "email",
44
+ code_provider: "token",
45
+ metadata: {},
46
+ },
47
+ });
48
+ requested += 1;
49
+ }
50
+ }
51
+ catch (error) {
52
+ try {
53
+ container
54
+ .resolve(utils_1.ContainerRegistrationKeys.LOGGER)
55
+ .error(`Customer verification could not be requested again (${error instanceof Error ? error.name : "unknown error"}).`);
56
+ }
57
+ catch {
58
+ // The caller runs detached: a broken logger must not become an
59
+ // unhandled rejection.
60
+ }
61
+ }
62
+ return { requested };
63
+ };
64
+ exports.resendCustomerVerification = resendCustomerVerification;
65
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzZW5kLWN1c3RvbWVyLXZlcmlmaWNhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbWFpbC9hcHBsaWNhdGlvbi9yZXNlbmQtY3VzdG9tZXItdmVyaWZpY2F0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUtBLHFEQUErRTtBQUMvRSw0REFBMEU7QUFFMUUseUZBR2dEO0FBT2hEOzs7Ozs7OztHQVFHO0FBQ0ksTUFBTSwwQkFBMEIsR0FBRyxLQUFLLEVBQzdDLFNBQTBCLEVBQzFCLEtBQWEsRUFDYixNQUFZLElBQUksSUFBSSxFQUFFLEVBQ3FCLEVBQUU7SUFDN0MsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2xCLElBQUksQ0FBQztRQUNILE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQXFCLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRSxNQUFNLGtCQUFrQixHQUFHLENBQ3pCLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FDZixJQUFBLHVEQUF3QixFQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQ2xELElBQUksQ0FBQyxzQkFBc0IsQ0FDekIsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsRUFDakQsRUFBRSxTQUFTLEVBQUUsQ0FBQyxlQUFlLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQzFDLENBQ0YsQ0FDRixDQUNGLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVCxLQUFLLE1BQU0sZ0JBQWdCLElBQUksa0JBQWtCLEVBQUUsQ0FBQztZQUNsRCxNQUFNLFlBQVksR0FBRyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUM7WUFDcEQsTUFBTSxVQUFVLEdBQ2QsWUFBWSxFQUFFLFlBQ2YsRUFBRSxXQUFXLENBQUM7WUFDZiw4REFBOEQ7WUFDOUQsSUFBSSxDQUFDLFlBQVksSUFBSSxPQUFPLFVBQVUsS0FBSyxRQUFRLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDbkUsU0FBUztZQUNYLENBQUM7WUFDRCxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQ3JEO2dCQUNFLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxFQUFFO2dCQUNqQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsU0FBUztnQkFDckMsV0FBVyxFQUFFLE9BQU87YUFDckIsRUFDRCxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FDWixDQUFDO1lBQ0YsSUFDRSxJQUFBLCtEQUFnQyxFQUFDO2dCQUMvQixHQUFHO2dCQUNILFlBQVksRUFBRSxZQUFZLElBQUksSUFBSTthQUNuQyxDQUFDLEtBQUssU0FBUyxFQUNoQixDQUFDO2dCQUNELFNBQVM7WUFDWCxDQUFDO1lBQ0QsTUFBTSxJQUFBLHdDQUEyQixFQUFDLFNBQVMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDL0MsS0FBSyxFQUFFO29CQUNMLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxFQUFFO29CQUNqQyxTQUFTLEVBQUUsZ0JBQWdCLENBQUMsU0FBUztvQkFDckMsV0FBVyxFQUFFLE9BQU87b0JBQ3BCLGFBQWEsRUFBRSxPQUFPO29CQUN0QixRQUFRLEVBQUUsRUFBRTtpQkFDYjthQUNGLENBQUMsQ0FBQztZQUNILFNBQVMsSUFBSSxDQUFDLENBQUM7UUFDakIsQ0FBQztJQUNILENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFBSSxDQUFDO1lBQ0gsU0FBUztpQkFDTixPQUFPLENBQVMsaUNBQXlCLENBQUMsTUFBTSxDQUFDO2lCQUNqRCxLQUFLLENBQ0osdURBQ0UsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsZUFDeEMsSUFBSSxDQUNMLENBQUM7UUFDTixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsK0RBQStEO1lBQy9ELHVCQUF1QjtRQUN6QixDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sRUFBRSxTQUFTLEVBQUUsQ0FBQztBQUN2QixDQUFDLENBQUM7QUFyRVcsUUFBQSwwQkFBMEIsOEJBcUVyQyJ9
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startCustomerVerification = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const public_1 = require("../../public");
6
+ const customer_verification_snapshot_1 = require("../customer-verification-snapshot");
7
+ const plugin_features_1 = require("../plugin-features");
8
+ /**
9
+ * Hands the snapshot behind `authVerificationsPerActor` its reader (the
10
+ * effective `customer_verification` toggle) and loads it once. Called when
11
+ * the application has started, with the application container: the config
12
+ * getter that needs the toggle has no container of its own.
13
+ */
14
+ const startCustomerVerification = (container) => (0, customer_verification_snapshot_1.startCustomerVerificationSnapshot)({
15
+ read: () => (0, public_1.isPluginFeatureEnabled)(container, plugin_features_1.emailPluginFeatures, "account_mails", "customer_verification"),
16
+ warn: (message) => container
17
+ .resolve(utils_1.ContainerRegistrationKeys.LOGGER)
18
+ .warn(message),
19
+ });
20
+ exports.startCustomerVerification = startCustomerVerification;
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQtY3VzdG9tZXItdmVyaWZpY2F0aW9uLXNuYXBzaG90LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2VtYWlsL2FwcGxpY2F0aW9uL3N0YXJ0LWN1c3RvbWVyLXZlcmlmaWNhdGlvbi1zbmFwc2hvdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxREFBc0U7QUFFdEUseUNBQXNEO0FBQ3RELHNGQUFzRjtBQUN0Rix3REFBeUQ7QUFFekQ7Ozs7O0dBS0c7QUFDSSxNQUFNLHlCQUF5QixHQUFHLENBQ3ZDLFNBQTBCLEVBQ1gsRUFBRSxDQUNqQixJQUFBLGtFQUFpQyxFQUFDO0lBQ2hDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FDVCxJQUFBLCtCQUFzQixFQUNwQixTQUFTLEVBQ1QscUNBQW1CLEVBQ25CLGVBQWUsRUFDZix1QkFBdUIsQ0FDeEI7SUFDSCxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNoQixTQUFTO1NBQ04sT0FBTyxDQUFTLGlDQUF5QixDQUFDLE1BQU0sQ0FBQztTQUNqRCxJQUFJLENBQUMsT0FBTyxDQUFDO0NBQ25CLENBQUMsQ0FBQztBQWZRLFFBQUEseUJBQXlCLDZCQWVqQyJ9
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findThrottledVerificationRequest = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const customer_verification_resend_1 = require("../domain/customer-verification-resend");
6
+ /**
7
+ * `POST /auth/verification/request` is Medusa's own route and the storefront
8
+ * calls it at every blocked login. Whether the request must be answered
9
+ * without sending a mail: for the identity's own e-mail address of a customer
10
+ * account whose last request is younger than the resend interval. Anything
11
+ * else (another actor, a foreign address, no row, a confirmed address) is
12
+ * left to Medusa. Never answers with the token hash Medusa stores in
13
+ * `provider_metadata`.
14
+ */
15
+ const findThrottledVerificationRequest = async (container, input, now = new Date()) => {
16
+ const auth = container.resolve(utils_1.Modules.AUTH);
17
+ const identity = await auth.retrieveAuthIdentity(input.authIdentityId, {
18
+ select: ["id", "app_metadata"],
19
+ relations: ["provider_identities"],
20
+ });
21
+ const customerId = identity.app_metadata
22
+ ?.customer_id;
23
+ const ownsAddress = (identity.provider_identities ?? []).some((providerIdentity) => providerIdentity.provider === "emailpass" &&
24
+ providerIdentity.entity_id === input.entityId);
25
+ if (!ownsAddress || typeof customerId !== "string" || !customerId) {
26
+ return null;
27
+ }
28
+ const [verification] = await auth.listAuthVerifications({
29
+ auth_identity_id: identity.id,
30
+ entity_id: input.entityId,
31
+ entity_type: "email",
32
+ }, { take: 1 });
33
+ if (!verification ||
34
+ (0, customer_verification_resend_1.decideCustomerVerificationResend)({ now, verification }) !== "throttled") {
35
+ return null;
36
+ }
37
+ return {
38
+ auth_identity_id: identity.id,
39
+ code_provider: verification.code_provider,
40
+ entity_id: verification.entity_id,
41
+ entity_type: verification.entity_type,
42
+ id: verification.id,
43
+ metadata: verification.metadata ?? null,
44
+ requested_at: verification.requested_at,
45
+ verified_at: verification.verified_at ?? null,
46
+ };
47
+ };
48
+ exports.findThrottledVerificationRequest = findThrottledVerificationRequest;
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyb3R0bGUtdmVyaWZpY2F0aW9uLXJlcXVlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZW1haWwvYXBwbGljYXRpb24vdGhyb3R0bGUtdmVyaWZpY2F0aW9uLXJlcXVlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEscURBQW9EO0FBRXBELHlGQUEwRjtBQWMxRjs7Ozs7Ozs7R0FRRztBQUNJLE1BQU0sZ0NBQWdDLEdBQUcsS0FBSyxFQUNuRCxTQUEwQixFQUMxQixLQUdFLEVBQ0YsTUFBWSxJQUFJLElBQUksRUFBRSxFQUNpQixFQUFFO0lBQ3pDLE1BQU0sSUFBSSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQXFCLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqRSxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFO1FBQ3JFLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxjQUFjLENBQUM7UUFDOUIsU0FBUyxFQUFFLENBQUMscUJBQXFCLENBQUM7S0FDbkMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxVQUFVLEdBQUksUUFBUSxDQUFDLFlBQStDO1FBQzFFLEVBQUUsV0FBVyxDQUFDO0lBQ2hCLE1BQU0sV0FBVyxHQUFHLENBQUMsUUFBUSxDQUFDLG1CQUFtQixJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FDM0QsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLENBQ25CLGdCQUFnQixDQUFDLFFBQVEsS0FBSyxXQUFXO1FBQ3pDLGdCQUFnQixDQUFDLFNBQVMsS0FBSyxLQUFLLENBQUMsUUFBUSxDQUNoRCxDQUFDO0lBQ0YsSUFBSSxDQUFDLFdBQVcsSUFBSSxPQUFPLFVBQVUsS0FBSyxRQUFRLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNsRSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQ3JEO1FBQ0UsZ0JBQWdCLEVBQUUsUUFBUSxDQUFDLEVBQUU7UUFDN0IsU0FBUyxFQUFFLEtBQUssQ0FBQyxRQUFRO1FBQ3pCLFdBQVcsRUFBRSxPQUFPO0tBQ3JCLEVBQ0QsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQ1osQ0FBQztJQUNGLElBQ0UsQ0FBQyxZQUFZO1FBQ2IsSUFBQSwrREFBZ0MsRUFBQyxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsQ0FBQyxLQUFLLFdBQVcsRUFDdkUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE9BQU87UUFDTCxnQkFBZ0IsRUFBRSxRQUFRLENBQUMsRUFBRTtRQUM3QixhQUFhLEVBQUUsWUFBWSxDQUFDLGFBQWE7UUFDekMsU0FBUyxFQUFFLFlBQVksQ0FBQyxTQUFTO1FBQ2pDLFdBQVcsRUFBRSxZQUFZLENBQUMsV0FBVztRQUNyQyxFQUFFLEVBQUUsWUFBWSxDQUFDLEVBQVk7UUFDN0IsUUFBUSxFQUFFLFlBQVksQ0FBQyxRQUFRLElBQUksSUFBSTtRQUN2QyxZQUFZLEVBQUUsWUFBWSxDQUFDLFlBQVk7UUFDdkMsV0FBVyxFQUFFLFlBQVksQ0FBQyxXQUFXLElBQUksSUFBSTtLQUM5QyxDQUFDO0FBQ0osQ0FBQyxDQUFDO0FBL0NXLFFBQUEsZ0NBQWdDLG9DQStDM0MifQ==
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setCustomerVerificationEnabledForTests = exports.customerVerificationActors = exports.isCustomerVerificationEnabled = exports.startCustomerVerificationSnapshot = exports.stopCustomerVerificationSnapshot = exports.refreshCustomerVerificationSnapshot = exports.CUSTOMER_VERIFICATION_REFRESH_MS = void 0;
4
+ /**
5
+ * In-memory copy of the effective `customer_verification` toggle for the one
6
+ * place that cannot await it: Medusa reads
7
+ * `projectConfig.http.authVerificationsPerActor.customer` synchronously on
8
+ * every login. The shop preset puts `customerVerificationActors()` behind a
9
+ * getter there, so a toggle change in the Admin takes effect without a
10
+ * restart.
11
+ *
12
+ * - Boot: `startCustomerVerificationSnapshot` loads the toggle once.
13
+ * - Afterwards an unref'd timer refreshes every 30 s, so a change reaches an
14
+ * idle instance too. A read that finds the copy older than 30 s (a blocked
15
+ * timer, say) also starts one refresh in the background
16
+ * (stale-while-revalidate) and still answers from the copy. A change thus
17
+ * reaches a running instance within about 30 s plus the duration of the
18
+ * read.
19
+ * - A failed read keeps the last value (initially "off") and is logged; the
20
+ * next attempt waits another 30 s.
21
+ *
22
+ * The state lives on `globalThis`: the preset (`dist`) and the Medusa-loaded
23
+ * plugin code (`.medusa/server`) are compiled separately and would otherwise
24
+ * each hold their own copy. Login is not on the cart path.
25
+ */
26
+ exports.CUSTOMER_VERIFICATION_REFRESH_MS = 30_000;
27
+ const STATE_KEY = Symbol.for("@hartl-services/medusa-base/customer-verification-snapshot");
28
+ const state = () => {
29
+ const holder = globalThis;
30
+ holder[STATE_KEY] ??= {
31
+ enabled: false,
32
+ refreshedAt: null,
33
+ refreshing: null,
34
+ timer: null,
35
+ read: null,
36
+ warn: null,
37
+ };
38
+ return holder[STATE_KEY];
39
+ };
40
+ const logFailure = (current, error) => {
41
+ try {
42
+ current.warn?.(`Customer verification toggle could not be read, keeping "${current.enabled ? "on" : "off"}": ${error instanceof Error ? error.message : "unknown error"}`);
43
+ }
44
+ catch {
45
+ // A broken logger must not turn a failed refresh into a throw.
46
+ }
47
+ };
48
+ /** Reads the toggle once; never rejects. Concurrent calls share one read. */
49
+ const refreshCustomerVerificationSnapshot = () => {
50
+ const current = state();
51
+ if (!current.read) {
52
+ return Promise.resolve();
53
+ }
54
+ if (current.refreshing) {
55
+ return current.refreshing;
56
+ }
57
+ const read = current.read;
58
+ // Started from a microtask so the assignment below always precedes `finally`.
59
+ const refreshing = Promise.resolve().then(async () => {
60
+ try {
61
+ current.enabled = (await read()) === true;
62
+ }
63
+ catch (error) {
64
+ logFailure(current, error);
65
+ }
66
+ finally {
67
+ current.refreshedAt = Date.now();
68
+ current.refreshing = null;
69
+ }
70
+ });
71
+ current.refreshing = refreshing;
72
+ return refreshing;
73
+ };
74
+ exports.refreshCustomerVerificationSnapshot = refreshCustomerVerificationSnapshot;
75
+ const stopTimer = (current) => {
76
+ if (current.timer) {
77
+ clearInterval(current.timer);
78
+ current.timer = null;
79
+ }
80
+ };
81
+ /** Stops the periodic refresh (application shutdown). The value stays. */
82
+ const stopCustomerVerificationSnapshot = () => {
83
+ stopTimer(state());
84
+ };
85
+ exports.stopCustomerVerificationSnapshot = stopCustomerVerificationSnapshot;
86
+ /**
87
+ * Registers the reader, loads the toggle once and keeps it fresh every 30 s
88
+ * (application start). `read` returns the effective toggle; `warn` is the
89
+ * container logger. Starting again replaces the reader and the timer.
90
+ */
91
+ const startCustomerVerificationSnapshot = (input) => {
92
+ const current = state();
93
+ current.read = input.read;
94
+ current.warn = input.warn;
95
+ stopTimer(current);
96
+ current.timer = setInterval(() => {
97
+ void (0, exports.refreshCustomerVerificationSnapshot)();
98
+ }, exports.CUSTOMER_VERIFICATION_REFRESH_MS);
99
+ // An idle timer must not keep the process (or a test run) alive.
100
+ current.timer.unref();
101
+ return (0, exports.refreshCustomerVerificationSnapshot)();
102
+ };
103
+ exports.startCustomerVerificationSnapshot = startCustomerVerificationSnapshot;
104
+ /** Synchronous; starts a background refresh when the copy is stale. Never throws. */
105
+ const isCustomerVerificationEnabled = () => {
106
+ const current = state();
107
+ if (current.read &&
108
+ !current.refreshing &&
109
+ (current.refreshedAt === null ||
110
+ Date.now() - current.refreshedAt >= exports.CUSTOMER_VERIFICATION_REFRESH_MS)) {
111
+ void (0, exports.refreshCustomerVerificationSnapshot)();
112
+ }
113
+ return current.enabled;
114
+ };
115
+ exports.isCustomerVerificationEnabled = isCustomerVerificationEnabled;
116
+ /**
117
+ * The value of `authVerificationsPerActor.customer`: Medusa's e-mail
118
+ * verification for the `emailpass` provider while the toggle is on, none
119
+ * while it is off. A fresh array per call.
120
+ */
121
+ const customerVerificationActors = () => (0, exports.isCustomerVerificationEnabled)()
122
+ ? [{ auth_provider: "emailpass", entity_type: "email" }]
123
+ : [];
124
+ exports.customerVerificationActors = customerVerificationActors;
125
+ /**
126
+ * Test hook: sets the value and counts as just refreshed, so it holds for
127
+ * 30 s without a reader; `null` forgets reader and value.
128
+ */
129
+ const setCustomerVerificationEnabledForTests = (enabled) => {
130
+ const current = state();
131
+ if (enabled === null) {
132
+ stopTimer(current);
133
+ current.enabled = false;
134
+ current.refreshedAt = null;
135
+ current.refreshing = null;
136
+ current.read = null;
137
+ current.warn = null;
138
+ return;
139
+ }
140
+ current.enabled = enabled;
141
+ current.refreshedAt = Date.now();
142
+ };
143
+ exports.setCustomerVerificationEnabledForTests = setCustomerVerificationEnabledForTests;
144
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXItdmVyaWZpY2F0aW9uLXNuYXBzaG90LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2VtYWlsL2N1c3RvbWVyLXZlcmlmaWNhdGlvbi1zbmFwc2hvdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ1UsUUFBQSxnQ0FBZ0MsR0FBRyxNQUFNLENBQUM7QUFpQnZELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQzFCLDREQUE0RCxDQUM3RCxDQUFDO0FBRUYsTUFBTSxLQUFLLEdBQUcsR0FBa0IsRUFBRTtJQUNoQyxNQUFNLE1BQU0sR0FBRyxVQUFzRCxDQUFDO0lBQ3RFLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSztRQUNwQixPQUFPLEVBQUUsS0FBSztRQUNkLFdBQVcsRUFBRSxJQUFJO1FBQ2pCLFVBQVUsRUFBRSxJQUFJO1FBQ2hCLEtBQUssRUFBRSxJQUFJO1FBQ1gsSUFBSSxFQUFFLElBQUk7UUFDVixJQUFJLEVBQUUsSUFBSTtLQUNYLENBQUM7SUFDRixPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMzQixDQUFDLENBQUM7QUFFRixNQUFNLFVBQVUsR0FBRyxDQUFDLE9BQXNCLEVBQUUsS0FBYyxFQUFRLEVBQUU7SUFDbEUsSUFBSSxDQUFDO1FBQ0gsT0FBTyxDQUFDLElBQUksRUFBRSxDQUNaLDREQUNFLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FDM0IsTUFBTSxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FDakUsQ0FBQztJQUNKLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCwrREFBK0Q7SUFDakUsQ0FBQztBQUNILENBQUMsQ0FBQztBQUVGLDZFQUE2RTtBQUN0RSxNQUFNLG1DQUFtQyxHQUFHLEdBQWtCLEVBQUU7SUFDckUsTUFBTSxPQUFPLEdBQUcsS0FBSyxFQUFFLENBQUM7SUFDeEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQixPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDdkIsT0FBTyxPQUFPLENBQUMsVUFBVSxDQUFDO0lBQzVCLENBQUM7SUFDRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQzFCLDhFQUE4RTtJQUM5RSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFO1FBQ25ELElBQUksQ0FBQztZQUNILE9BQU8sQ0FBQyxPQUFPLEdBQUcsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLEtBQUssSUFBSSxDQUFDO1FBQzVDLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsVUFBVSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM3QixDQUFDO2dCQUFTLENBQUM7WUFDVCxPQUFPLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNqQyxPQUFPLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUM1QixDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztJQUNoQyxPQUFPLFVBQVUsQ0FBQztBQUNwQixDQUFDLENBQUM7QUF0QlcsUUFBQSxtQ0FBbUMsdUNBc0I5QztBQUVGLE1BQU0sU0FBUyxHQUFHLENBQUMsT0FBc0IsRUFBUSxFQUFFO0lBQ2pELElBQUksT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2xCLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsT0FBTyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7SUFDdkIsQ0FBQztBQUNILENBQUMsQ0FBQztBQUVGLDBFQUEwRTtBQUNuRSxNQUFNLGdDQUFnQyxHQUFHLEdBQVMsRUFBRTtJQUN6RCxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztBQUNyQixDQUFDLENBQUM7QUFGVyxRQUFBLGdDQUFnQyxvQ0FFM0M7QUFFRjs7OztHQUlHO0FBQ0ksTUFBTSxpQ0FBaUMsR0FBRyxDQUMvQyxLQUdFLEVBQ2EsRUFBRTtJQUNqQixNQUFNLE9BQU8sR0FBRyxLQUFLLEVBQUUsQ0FBQztJQUN4QixPQUFPLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7SUFDMUIsT0FBTyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQzFCLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNuQixPQUFPLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUU7UUFDL0IsS0FBSyxJQUFBLDJDQUFtQyxHQUFFLENBQUM7SUFDN0MsQ0FBQyxFQUFFLHdDQUFnQyxDQUFDLENBQUM7SUFDckMsaUVBQWlFO0lBQ2pFLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDdEIsT0FBTyxJQUFBLDJDQUFtQyxHQUFFLENBQUM7QUFDL0MsQ0FBQyxDQUFDO0FBaEJXLFFBQUEsaUNBQWlDLHFDQWdCNUM7QUFFRixxRkFBcUY7QUFDOUUsTUFBTSw2QkFBNkIsR0FBRyxHQUFZLEVBQUU7SUFDekQsTUFBTSxPQUFPLEdBQUcsS0FBSyxFQUFFLENBQUM7SUFDeEIsSUFDRSxPQUFPLENBQUMsSUFBSTtRQUNaLENBQUMsT0FBTyxDQUFDLFVBQVU7UUFDbkIsQ0FBQyxPQUFPLENBQUMsV0FBVyxLQUFLLElBQUk7WUFDM0IsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksd0NBQWdDLENBQUMsRUFDdkUsQ0FBQztRQUNELEtBQUssSUFBQSwyQ0FBbUMsR0FBRSxDQUFDO0lBQzdDLENBQUM7SUFDRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUM7QUFDekIsQ0FBQyxDQUFDO0FBWFcsUUFBQSw2QkFBNkIsaUNBV3hDO0FBRUY7Ozs7R0FJRztBQUNJLE1BQU0sMEJBQTBCLEdBQUcsR0FBZ0MsRUFBRSxDQUMxRSxJQUFBLHFDQUE2QixHQUFFO0lBQzdCLENBQUMsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDeEQsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUhJLFFBQUEsMEJBQTBCLDhCQUc5QjtBQUVUOzs7R0FHRztBQUNJLE1BQU0sc0NBQXNDLEdBQUcsQ0FDcEQsT0FBdUIsRUFDakIsRUFBRTtJQUNSLE1BQU0sT0FBTyxHQUFHLEtBQUssRUFBRSxDQUFDO0lBQ3hCLElBQUksT0FBTyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ3JCLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQixPQUFPLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUN4QixPQUFPLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztRQUMzQixPQUFPLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUMxQixPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNwQixPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNwQixPQUFPO0lBQ1QsQ0FBQztJQUNELE9BQU8sQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO0lBQzFCLE9BQU8sQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ25DLENBQUMsQ0FBQztBQWZXLFFBQUEsc0NBQXNDLDBDQWVqRCJ9
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.adminResendBusinessKey = exports.affiliateConsignmentBusinessKey = exports.userInviteBusinessKey = exports.passwordResetBusinessKey = exports.orderRefundedBusinessKey = exports.returnReceivedBusinessKey = exports.returnRequestedBusinessKey = exports.orderCanceledBusinessKey = exports.orderShippedBusinessKey = exports.orderReceivedAdminBusinessKey = exports.orderReceivedBusinessKey = void 0;
3
+ exports.adminResendBusinessKey = exports.affiliateConsignmentBusinessKey = exports.userInviteBusinessKey = exports.customerVerificationBusinessKey = exports.passwordResetBusinessKey = exports.orderRefundedBusinessKey = exports.returnReceivedBusinessKey = exports.returnRequestedBusinessKey = exports.orderCanceledBusinessKey = exports.orderShippedBusinessKey = exports.orderReceivedAdminBusinessKey = exports.orderReceivedBusinessKey = void 0;
4
4
  const node_crypto_1 = require("node:crypto");
5
5
  const affiliate_1 = require("@hartl-services/medusa-food-supplements-contracts/events/affiliate");
6
6
  const normalizedIdentifier = (value, name) => {
@@ -32,6 +32,16 @@ const passwordResetBusinessKey = (token) => {
32
32
  return `password-reset:${tokenHash}`;
33
33
  };
34
34
  exports.passwordResetBusinessKey = passwordResetBusinessKey;
35
+ const customerVerificationBusinessKey = (token) => {
36
+ if (!token) {
37
+ throw new Error("token must not be empty.");
38
+ }
39
+ // Keyed by the token's hash, never the token: every new request issues a
40
+ // new token and must produce a new message, as with password-reset.
41
+ const tokenHash = (0, node_crypto_1.createHash)("sha256").update(token, "utf8").digest("hex");
42
+ return `customer-verification:${tokenHash}`;
43
+ };
44
+ exports.customerVerificationBusinessKey = customerVerificationBusinessKey;
35
45
  const userInviteBusinessKey = (token) => {
36
46
  if (!token) {
37
47
  throw new Error("token must not be empty.");
@@ -47,4 +57,4 @@ const affiliateConsignmentBusinessKey = (affiliateId, periodStart) => (0, affili
47
57
  exports.affiliateConsignmentBusinessKey = affiliateConsignmentBusinessKey;
48
58
  const adminResendBusinessKey = (originalMessageId, requestId) => `admin-resend:${normalizedIdentifier(originalMessageId, "originalMessageId")}:${normalizedIdentifier(requestId, "requestId")}`;
49
59
  exports.adminResendBusinessKey = adminResendBusinessKey;
50
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVzaW5lc3Mta2V5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbWFpbC9kb21haW4vYnVzaW5lc3Mta2V5cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBeUM7QUFFekMsa0dBQTJIO0FBRTNILE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxLQUFhLEVBQUUsSUFBWSxFQUFVLEVBQUU7SUFDbkUsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2hDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsSUFBSSxxQkFBcUIsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFDRCxPQUFPLFVBQVUsQ0FBQztBQUNwQixDQUFDLENBQUM7QUFFSyxNQUFNLHdCQUF3QixHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUUsQ0FDbEUsa0JBQWtCLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDO0FBRGxELFFBQUEsd0JBQXdCLDRCQUMwQjtBQUV4RCxNQUFNLDZCQUE2QixHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUUsQ0FDdkUsd0JBQXdCLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDO0FBRHhELFFBQUEsNkJBQTZCLGlDQUMyQjtBQUU5RCxNQUFNLHVCQUF1QixHQUFHLENBQUMsYUFBcUIsRUFBVSxFQUFFLENBQ3ZFLGlCQUFpQixvQkFBb0IsQ0FBQyxhQUFhLEVBQUUsZUFBZSxDQUFDLEVBQUUsQ0FBQztBQUQ3RCxRQUFBLHVCQUF1QiwyQkFDc0M7QUFFbkUsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLE9BQWUsRUFBVSxFQUFFLENBQ2xFLGtCQUFrQixvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLEVBQUUsQ0FBQztBQURsRCxRQUFBLHdCQUF3Qiw0QkFDMEI7QUFFeEQsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLFFBQWdCLEVBQVUsRUFBRSxDQUNyRSxvQkFBb0Isb0JBQW9CLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUM7QUFEdEQsUUFBQSwwQkFBMEIsOEJBQzRCO0FBRTVELE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxRQUFnQixFQUFVLEVBQUUsQ0FDcEUsbUJBQW1CLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDO0FBRHJELFFBQUEseUJBQXlCLDZCQUM0QjtBQUUzRCxNQUFNLHdCQUF3QixHQUFHLENBQUMsUUFBZ0IsRUFBVSxFQUFFLENBQ25FLFVBQVUsb0JBQW9CLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUM7QUFENUMsUUFBQSx3QkFBd0IsNEJBQ29CO0FBRWxELE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxLQUFhLEVBQVUsRUFBRTtJQUNoRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUNELE1BQU0sU0FBUyxHQUFHLElBQUEsd0JBQVUsRUFBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzRSxPQUFPLGtCQUFrQixTQUFTLEVBQUUsQ0FBQztBQUN2QyxDQUFDLENBQUM7QUFOVyxRQUFBLHdCQUF3Qiw0QkFNbkM7QUFFSyxNQUFNLHFCQUFxQixHQUFHLENBQUMsS0FBYSxFQUFVLEVBQUU7SUFDN0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFDRCx1RUFBdUU7SUFDdkUseUVBQXlFO0lBQ3pFLHdEQUF3RDtJQUN4RCxNQUFNLFNBQVMsR0FBRyxJQUFBLHdCQUFVLEVBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0UsT0FBTyxlQUFlLFNBQVMsRUFBRSxDQUFDO0FBQ3BDLENBQUMsQ0FBQztBQVRXLFFBQUEscUJBQXFCLHlCQVNoQztBQUVLLE1BQU0sK0JBQStCLEdBQUcsQ0FDN0MsV0FBbUIsRUFDbkIsV0FBbUIsRUFDWCxFQUFFLENBQUMsSUFBQSxpREFBcUMsRUFBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLENBQUM7QUFIaEUsUUFBQSwrQkFBK0IsbUNBR2lDO0FBRXRFLE1BQU0sc0JBQXNCLEdBQUcsQ0FDcEMsaUJBQXlCLEVBQ3pCLFNBQWlCLEVBQ1QsRUFBRSxDQUNWLGdCQUFnQixvQkFBb0IsQ0FDbEMsaUJBQWlCLEVBQ2pCLG1CQUFtQixDQUNwQixJQUFJLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxXQUFXLENBQUMsRUFBRSxDQUFDO0FBUHpDLFFBQUEsc0JBQXNCLDBCQU9tQiJ9
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVzaW5lc3Mta2V5cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbWFpbC9kb21haW4vYnVzaW5lc3Mta2V5cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBeUM7QUFFekMsa0dBQTJIO0FBRTNILE1BQU0sb0JBQW9CLEdBQUcsQ0FBQyxLQUFhLEVBQUUsSUFBWSxFQUFVLEVBQUU7SUFDbkUsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2hDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsSUFBSSxxQkFBcUIsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFDRCxPQUFPLFVBQVUsQ0FBQztBQUNwQixDQUFDLENBQUM7QUFFSyxNQUFNLHdCQUF3QixHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUUsQ0FDbEUsa0JBQWtCLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDO0FBRGxELFFBQUEsd0JBQXdCLDRCQUMwQjtBQUV4RCxNQUFNLDZCQUE2QixHQUFHLENBQUMsT0FBZSxFQUFVLEVBQUUsQ0FDdkUsd0JBQXdCLG9CQUFvQixDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDO0FBRHhELFFBQUEsNkJBQTZCLGlDQUMyQjtBQUU5RCxNQUFNLHVCQUF1QixHQUFHLENBQUMsYUFBcUIsRUFBVSxFQUFFLENBQ3ZFLGlCQUFpQixvQkFBb0IsQ0FBQyxhQUFhLEVBQUUsZUFBZSxDQUFDLEVBQUUsQ0FBQztBQUQ3RCxRQUFBLHVCQUF1QiwyQkFDc0M7QUFFbkUsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLE9BQWUsRUFBVSxFQUFFLENBQ2xFLGtCQUFrQixvQkFBb0IsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLEVBQUUsQ0FBQztBQURsRCxRQUFBLHdCQUF3Qiw0QkFDMEI7QUFFeEQsTUFB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
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.decideCustomerVerificationResend = exports.verificationLookupEmails = exports.CUSTOMER_VERIFICATION_RESEND_INTERVAL_MS = void 0;
4
+ /** Shortest time between two confirmation mails for the same account. */
5
+ exports.CUSTOMER_VERIFICATION_RESEND_INTERVAL_MS = 60_000;
6
+ /**
7
+ * Medusa's emailpass provider stores the e-mail exactly as it was registered
8
+ * (no lowercasing) and logs in by exact match, so the account is looked up by
9
+ * the address as typed and by its lowercase form.
10
+ */
11
+ const verificationLookupEmails = (email) => {
12
+ const trimmed = email.trim();
13
+ return [...new Set([trimmed, trimmed.toLowerCase()])].filter(Boolean);
14
+ };
15
+ exports.verificationLookupEmails = verificationLookupEmails;
16
+ /**
17
+ * Whether a new confirmation mail may be requested: not for a confirmed
18
+ * address and not within a minute of the previous request (a missing row
19
+ * means none was requested yet).
20
+ */
21
+ const decideCustomerVerificationResend = (input) => {
22
+ const { now, verification } = input;
23
+ if (!verification) {
24
+ return "request";
25
+ }
26
+ if (verification.verified_at) {
27
+ return "already_verified";
28
+ }
29
+ const requestedAt = new Date(verification.requested_at).getTime();
30
+ if (Number.isFinite(requestedAt) &&
31
+ now.getTime() - requestedAt < exports.CUSTOMER_VERIFICATION_RESEND_INTERVAL_MS) {
32
+ return "throttled";
33
+ }
34
+ return "request";
35
+ };
36
+ exports.decideCustomerVerificationResend = decideCustomerVerificationResend;
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tZXItdmVyaWZpY2F0aW9uLXJlc2VuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbWFpbC9kb21haW4vY3VzdG9tZXItdmVyaWZpY2F0aW9uLXJlc2VuZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5RUFBeUU7QUFDNUQsUUFBQSx3Q0FBd0MsR0FBRyxNQUFNLENBQUM7QUFPL0Q7Ozs7R0FJRztBQUNJLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxLQUFhLEVBQVksRUFBRTtJQUNsRSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDN0IsT0FBTyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN4RSxDQUFDLENBQUM7QUFIVyxRQUFBLHdCQUF3Qiw0QkFHbkM7QUFFRjs7OztHQUlHO0FBQ0ksTUFBTSxnQ0FBZ0MsR0FBRyxDQUM5QyxLQU1FLEVBQ2tDLEVBQUU7SUFDdEMsTUFBTSxFQUFFLEdBQUcsRUFBRSxZQUFZLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFDcEMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xCLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxJQUFJLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM3QixPQUFPLGtCQUFrQixDQUFDO0lBQzVCLENBQUM7SUFDRCxNQUFNLFdBQVcsR0FBRyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbEUsSUFDRSxNQUFNLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztRQUM1QixHQUFHLENBQUMsT0FBTyxFQUFFLEdBQUcsV0FBVyxHQUFHLGdEQUF3QyxFQUN0RSxDQUFDO1FBQ0QsT0FBTyxXQUFXLENBQUM7SUFDckIsQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUMsQ0FBQztBQXhCVyxRQUFBLGdDQUFnQyxvQ0F3QjNDIn0=
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NativeInviteEventSchema = exports.NativePasswordResetEventSchema = exports.NativeShipmentCreatedEventSchema = exports.NativeReturnEventSchema = exports.NativeOrderEventSchema = void 0;
3
+ exports.NativeInviteEventSchema = exports.NativeVerificationRequestedEventSchema = exports.NativePasswordResetEventSchema = exports.NativeShipmentCreatedEventSchema = exports.NativeReturnEventSchema = exports.NativeOrderEventSchema = void 0;
4
4
  const zod_1 = require("@medusajs/framework/zod");
5
5
  const NonEmptyStringSchema = zod_1.z.string().trim().min(1);
6
6
  exports.NativeOrderEventSchema = zod_1.z
@@ -28,9 +28,25 @@ exports.NativePasswordResetEventSchema = zod_1.z
28
28
  metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).optional(),
29
29
  })
30
30
  .strict();
31
+ /**
32
+ * Medusa's `auth.verification_requested`. Not strict: the workflow emits
33
+ * more fields (`code_provider`, `auth_identity_id`, ...) than the mail
34
+ * needs, and a field added by Medusa later must not silence the mail.
35
+ * `code` is absent when the identity is already verified; `expires_at` is a
36
+ * `Date` on the local Event Bus and an ISO string after Redis.
37
+ */
38
+ exports.NativeVerificationRequestedEventSchema = zod_1.z.object({
39
+ entity_id: NonEmptyStringSchema,
40
+ entity_type: NonEmptyStringSchema,
41
+ code_provider: NonEmptyStringSchema,
42
+ auth_identity_id: NonEmptyStringSchema,
43
+ code: NonEmptyStringSchema,
44
+ expires_at: zod_1.z.coerce.date(),
45
+ metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.unknown()).nullish(),
46
+ });
31
47
  exports.NativeInviteEventSchema = zod_1.z
32
48
  .object({
33
49
  id: NonEmptyStringSchema,
34
50
  })
35
51
  .strict();
36
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnQtc2NoZW1hcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbWFpbC9kb21haW4vZXZlbnQtc2NoZW1hcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpREFBNEM7QUFFNUMsTUFBTSxvQkFBb0IsR0FBRyxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRXpDLFFBQUEsc0JBQXNCLEdBQUcsT0FBQztLQUNwQyxNQUFNLENBQUM7SUFDTixFQUFFLEVBQUUsb0JBQW9CO0NBQ3pCLENBQUM7S0FDRCxNQUFNLEVBQUUsQ0FBQztBQUVDLFFBQUEsdUJBQXVCLEdBQUcsT0FBQztLQUNyQyxNQUFNLENBQUM7SUFDTixRQUFRLEVBQUUsb0JBQW9CO0lBQzlCLFNBQVMsRUFBRSxvQkFBb0I7Q0FDaEMsQ0FBQztLQUNELE1BQU0sRUFBRSxDQUFDO0FBRUMsUUFBQSxnQ0FBZ0MsR0FBRyxPQUFDO0tBQzlDLE1BQU0sQ0FBQztJQUNOLEVBQUUsRUFBRSxvQkFBb0I7SUFDeEIsZUFBZSxFQUFFLE9BQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDeEMsQ0FBQztLQUNELE1BQU0sRUFBRSxDQUFDO0FBRUMsUUFBQSw4QkFBOEIsR0FBRyxPQUFDO0tBQzVDLE1BQU0sQ0FBQztJQUNOLFNBQVMsRUFBRSxvQkFBb0I7SUFDL0IsVUFBVSxFQUFFLG9CQUFvQjtJQUNoQyxLQUFLLEVBQUUsb0JBQW9CO0lBQzNCLFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLE9BQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxPQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUU7Q0FDdkQsQ0FBQztLQUNELE1BQU0sRUFBRSxDQUFDO0FBRUMsUUFBQSx1QkFBdUIsR0FBRyxPQUFDO0tBQ3JDLE1BQU0sQ0FBQztJQUNOLEVBQUUsRUFBRSxvQkFBb0I7Q0FDekIsQ0FBQztLQUNELE1BQU0sRUFBRSxDQUFDIn0=
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnQtc2NoZW1hcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbWFpbC9kb21haW4vZXZlbnQtc2NoZW1hcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpREFBNEM7QUFFNUMsTUFBTSxvQkFBb0IsR0FBRyxPQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRXpDLFFBQUEsc0JBQXNCLEdBQUcsT0FBQztLQUNwQyxNQUFNLENBQUM7SUFDTixFQUFFLEVBQUUsb0JBQW9CO0NBQ3pCLENBQUM7S0FDRCxNQUFNLEVBQUUsQ0FBQztBQUVDLFFBQUEsdUJBQXVCLEdBQUcsT0FBQztLQUNyQyxNQUFNLENBQUM7SUFDTixRQUFRLEVBQUUsb0JBQW9CO0lBQzlCLFNBQVMsRUFBRSxvQkFBb0I7Q0FDaEMsQ0FBQztLQUNELE1BQU0sRUFBRSxDQUFDO0FBRUMsUUFBQSxnQ0FBZ0MsR0FBRyxPQUFDO0tBQzlDLE1BQU0sQ0FBQztJQUNOLEVBQUUsRUFBRSxvQkFBb0I7SUFDeEIsZUFBZSxFQUFFLE9BQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLEVBQUU7Q0FDeEMsQ0FBQztLQUNELE1BQU0sRUFBRSxDQUFDO0FBRUMsUUFBQSw4QkFBOEIsR0FBRyxPQUFDO0tBQzVDLE1BQU0sQ0FBQztJQUNOLFNBQVMsRUFBRSxvQkFBb0I7SUFDL0IsVUFBVSxFQUFFLG9CQUFvQjtJQUNoQyxLQUFLLEVBQUUsb0JBQW9CO0lBQzNCLFFBQVEsRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLE9BQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxPQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUU7Q0FDdkQsQ0FBQztLQUNELE1BQU0sRUFBRSxDQUFDO0FBRVo7Ozs7OztHQU1HO0FBQ1UsUUFBQSxzQ0FBc0MsR0FBRyxPQUFDLENBQUMsTUFBTSxDQUFDO0lBQzdELFNBQVMsRUFBRSxvQkFBb0I7SUFDL0IsV0FBVyxFQUFFLG9CQUFvQjtJQUNqQyxhQUFhLEVBQUUsb0JBQW9CO0lBQ25DLGdCQUFnQixFQUFFLG9CQUFvQjtJQUN0QyxJQUFJLEVBQUUsb0JBQW9CO0lBQzFCLFVBQVUsRUFBRSxPQUFDLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRTtJQUMzQixRQUFRLEVBQUUsT0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsT0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFO0NBQ3RELENBQUMsQ0FBQztBQUVVLFFBQUEsdUJBQXVCLEdBQUcsT0FBQztLQUNyQyxNQUFNLENBQUM7SUFDTixFQUFFLEVBQUUsb0JBQW9CO0NBQ3pCLENBQUM7S0FDRCxNQUFNLEVBQUUsQ0FBQyJ9
@@ -16,9 +16,16 @@ exports.emailPluginFeatures = (0, public_1.definePluginFeatures)({
16
16
  {
17
17
  key: "account_mails",
18
18
  label: "Konto-Mails",
19
- description: "Passwort-Zurücksetzen für Kunden und Einladungen neuer Admin-Benutzer. Aus: Für diese Ereignisse wird keine Mail erzeugt.",
19
+ description: "Passwort-Zurücksetzen für Kunden, Einladungen neuer Admin-Benutzer und die Bestätigungsmail der Kontobestätigung. Aus: Für diese Ereignisse wird keine Mail erzeugt.",
20
20
  default_enabled: true,
21
21
  },
22
+ {
23
+ key: "customer_verification",
24
+ label: "Kontobestätigung per E-Mail",
25
+ description: "Neue und bestehende Kundenkonten müssen ihre E-Mail-Adresse über einen Link bestätigen, bevor die erste Anmeldung gelingt; bestehende Konten bekommen die Mail bei der nächsten Anmeldung. Voraussetzung: Konto-Mails sind eingeschaltet, sonst kommt keine Bestätigungsmail an. Eine Änderung wirkt innerhalb von etwa 30 Sekunden. Aus: Kunden melden sich ohne Bestätigung an.",
26
+ default_enabled: false,
27
+ parent_key: "account_mails",
28
+ },
22
29
  {
23
30
  key: "affiliate_reminders",
24
31
  label: "Affiliate-Erinnerungen",
@@ -36,4 +43,4 @@ exports.emailPluginFeatures = (0, public_1.definePluginFeatures)({
36
43
  ],
37
44
  admin_page: "/settings/hartl-services/email",
38
45
  });
39
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWZlYXR1cmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2VtYWlsL3BsdWdpbi1mZWF0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxzQ0FBaUQ7QUFFcEMsUUFBQSxtQkFBbUIsR0FBRyxJQUFBLDZCQUFvQixFQUFDO0lBQ3RELFVBQVUsRUFBRSxPQUFPO0lBQ25CLEtBQUssRUFBRSxRQUFRO0lBQ2YsV0FBVyxFQUNULDZhQUE2YTtJQUMvYSxRQUFRLEVBQUU7UUFDUjtZQUNFLEdBQUcsRUFBRSxhQUFhO1lBQ2xCLEtBQUssRUFBRSxlQUFlO1lBQ3RCLFdBQVcsRUFDVCxvWkFBb1o7WUFDdFosZUFBZSxFQUFFLElBQUk7U0FDdEI7UUFDRDtZQUNFLEdBQUcsRUFBRSxlQUFlO1lBQ3BCLEtBQUssRUFBRSxhQUFhO1lBQ3BCLFdBQVcsRUFDVCwySEFBMkg7WUFDN0gsZUFBZSxFQUFFLElBQUk7U0FDdEI7UUFDRDtZQUNFLEdBQUcsRUFBRSxxQkFBcUI7WUFDMUIsS0FBSyxFQUFFLHdCQUF3QjtZQUMvQixXQUFXLEVBQ1Qsc0hBQXNIO1lBQ3hILGVBQWUsRUFBRSxJQUFJO1NBQ3RCO0tBQ0Y7SUFDRCxRQUFRLEVBQUU7UUFDUjtZQUNFLEdBQUcsRUFBRSxNQUFNO1lBQ1gsS0FBSyxFQUFFLE1BQU07WUFDYixXQUFXLEVBQ1QsK0pBQStKO1lBQ2pLLElBQUksRUFBRSxPQUFPO1NBQ2Q7S0FDRjtJQUNELFVBQVUsRUFBRSxnQ0FBZ0M7Q0FDN0MsQ0FBQyxDQUFDIn0=
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWZlYXR1cmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2VtYWlsL3BsdWdpbi1mZWF0dXJlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxzQ0FBaUQ7QUFFcEMsUUFBQSxtQkFBbUIsR0FBRyxJQUFBLDZCQUFvQixFQUFDO0lBQ3RELFVBQVUsRUFBRSxPQUFPO0lBQ25CLEtBQUssRUFBRSxRQUFRO0lBQ2YsV0FBVyxFQUNULDZhQUE2YTtJQUMvYSxRQUFRLEVBQUU7UUFDUjtZQUNFLEdBQUcsRUFBRSxhQUFhO1lBQ2xCLEtBQUssRUFBRSxlQUFlO1lBQ3RCLFdBQVcsRUFDVCxvWkFBb1o7WUFDdFosZUFBZSxFQUFFLElBQUk7U0FDdEI7UUFDRDtZQUNFLEdBQUcsRUFBRSxlQUFlO1lBQ3BCLEtBQUssRUFBRSxhQUFhO1lBQ3BCLFdBQVcsRUFDVCxzS0FBc0s7WUFDeEssZUFBZSxFQUFFLElBQUk7U0FDdEI7UUFDRDtZQUNFLEdBQUcsRUFBRSx1QkFBdUI7WUFDNUIsS0FBSyxFQUFFLDZCQUE2QjtZQUNwQyxXQUFXLEVBQ1QsbVhBQW1YO1lBQ3JYLGVBQWUsRUFBRSxLQUFLO1lBQ3RCLFVBQVUsRUFBRSxlQUFlO1NBQzVCO1FBQ0Q7WUFDRSxHQUFHLEVBQUUscUJBQXFCO1lBQzFCLEtBQUssRUFBRSx3QkFBd0I7WUFDL0IsV0FBVyxFQUNULHNIQUFzSDtZQUN4SCxlQUFlLEVBQUUsSUFBSTtTQUN0QjtLQUNGO0lBQ0QsUUFBUSxFQUFFO1FBQ1I7WUFDRSxHQUFHLEVBQUUsTUFBTTtZQUNYLEtBQUssRUFBRSxNQUFNO1lBQ2IsV0FBVyxFQUNULCtKQUErSjtZQUNqSyxJQUFJLEVBQUUsT0FBTztTQUNkO0tBQ0Y7SUFDRCxVQUFVLEVBQUUsZ0NBQWdDO0NBQzdDLENBQUMsQ0FBQyJ9