@hartl-services/medusa-base 2.0.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.
- package/.medusa/server/src/admin/index.js +3 -1
- package/.medusa/server/src/admin/index.mjs +3 -1
- package/.medusa/server/src/api/customer-verification-request-throttle.js +50 -0
- package/.medusa/server/src/api/middlewares.js +31 -1
- package/.medusa/server/src/api/store/customer-verification/resend/route.js +17 -0
- package/.medusa/server/src/email/application/handle-customer-verification-event.js +341 -0
- package/.medusa/server/src/email/application/resend-customer-verification.js +65 -0
- package/.medusa/server/src/email/application/start-customer-verification-snapshot.js +21 -0
- package/.medusa/server/src/email/application/throttle-verification-request.js +49 -0
- package/.medusa/server/src/email/customer-verification-snapshot.js +144 -0
- package/.medusa/server/src/email/domain/business-keys.js +12 -2
- package/.medusa/server/src/email/domain/customer-verification-resend.js +37 -0
- package/.medusa/server/src/email/domain/event-schemas.js +18 -2
- package/.medusa/server/src/email/plugin-features.js +9 -2
- package/.medusa/server/src/email/rendering/default-templates.js +20 -1
- package/.medusa/server/src/email/rendering/resolve-shop-configuration.js +5 -1
- package/.medusa/server/src/email/types/email-kinds.js +14 -2
- package/.medusa/server/src/email/types/template-data.js +9 -1
- package/.medusa/server/src/modules/email/migrations/Migration20261001090000.js +16 -0
- package/.medusa/server/src/modules/email/service.js +30 -8
- package/.medusa/server/src/shop-config/build-food-shop-config.js +16 -1
- package/.medusa/server/src/subscribers/customer-verification.js +23 -0
- package/.medusa/server/src/workflows/email/dispatch-email-message.js +4 -2
- package/README.md +140 -15
- package/dist/email/customer-verification-snapshot.d.ts +53 -0
- package/dist/email/customer-verification-snapshot.js +143 -0
- package/dist/email/types/email-kinds.d.ts +9 -1
- package/dist/email/types/email-kinds.js +13 -1
- package/dist/email/types/shop-configuration.d.ts +8 -0
- package/dist/email/types/template-data.d.ts +9 -0
- package/dist/email/types/template-data.js +8 -0
- package/dist/shop-config/build-food-shop-config.js +15 -0
- package/package.json +2 -2
|
@@ -156,7 +156,9 @@ const deliverEmailClaim = async (container, claim, clock) => {
|
|
|
156
156
|
const email = resolveEmailService(container);
|
|
157
157
|
const logger = container.resolve(utils_1.ContainerRegistrationKeys.LOGGER);
|
|
158
158
|
const message = claim.message;
|
|
159
|
-
|
|
159
|
+
// Reset and verification links exist only in their subscriber; the code keeps
|
|
160
|
+
// its original name because it is a published safe status code.
|
|
161
|
+
if ((0, types_1.isEphemeralEmailKind)(message.kind)) {
|
|
160
162
|
return await failPreparation(email, logger, claim, "password_reset_requires_ephemeral_context", getNow());
|
|
161
163
|
}
|
|
162
164
|
if (!message.recipient || !emailAddressPattern.test(message.recipient)) {
|
|
@@ -298,4 +300,4 @@ const dispatchEmailMessageStep = (0, workflows_sdk_1.createStep)("email-dispatch
|
|
|
298
300
|
return new workflows_sdk_1.StepResponse(await (0, exports.deliverEmailClaim)(container, claim, clock));
|
|
299
301
|
});
|
|
300
302
|
exports.dispatchEmailMessageWorkflow = (0, workflows_sdk_1.createWorkflow)("email-dispatch-message", (input) => new workflows_sdk_1.WorkflowResponse(dispatchEmailMessageStep(input)));
|
|
301
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzcGF0Y2gtZW1haWwtbWVzc2FnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvZW1haWwvZGlzcGF0Y2gtZW1haWwtbWVzc2FnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBeUM7QUFRekMscURBSW1DO0FBQ25DLHFFQUsyQztBQUUzQyxzRkFNbUQ7QUFDbkQsK0NBQW1EO0FBQ25ELHNFQUcrQztBQUcvQywyRkFBcUY7QUFDckYscUVBQWlFO0FBQ2pFLDZDQUE4RDtBQUU5RCxNQUFNLG1CQUFtQixHQUFHLDRCQUE0QixDQUFDO0FBRXpELE1BQU0sNkJBQThCLFNBQVEsS0FBSztDQUFHO0FBOEJwRCxNQUFNLG1CQUFtQixHQUFHLENBQUMsU0FBMEIsRUFBc0IsRUFBRSxDQUM3RSxTQUFTLENBQUMsT0FBTyxDQUFxQixvQkFBWSxDQUFDLENBQUM7QUFFdEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFjLEVBQVEsRUFBRTtJQUMxQyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO0lBQ2xELElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sSUFBSSxTQUFTLENBQUMsMENBQTBDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDLENBQUM7QUFFRixNQUFNLG9CQUFvQixHQUFHLENBQUMsS0FBYyxFQUE2QixFQUFFO0lBQ3pFLElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDeEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsS0FBZ0MsQ0FBQztJQUNoRCxJQUNFLE9BQU8sTUFBTSxDQUFDLEVBQUUsS0FBSyxRQUFRO1FBQzdCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDakIsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLFNBQVM7WUFDMUIsTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTO1lBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLEVBQzlCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxPQUFPO1FBQ0wsV0FBVyxFQUNULE9BQU8sTUFBTSxDQUFDLFdBQVcsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUk7UUFDcEUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1FBQ2IsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO0tBQ3RCLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLHdCQUF3QixHQUFHLENBQUMsS0FBYyxFQUFXLEVBQUU7SUFDM0QsSUFDRSxtQkFBVyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7UUFDaEMsS0FBSyxDQUFDLElBQUksS0FBSyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQzFDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxJQUFJLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3hDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLEtBQWdDLENBQUM7SUFDaEQsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQzVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7SUFDbEMsT0FBTyxDQUNMLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDakIsT0FBTyxRQUFRLEtBQUssUUFBUTtRQUMzQixRQUFvQyxDQUFDLGNBQWMsS0FBSyxHQUFHLENBQzdELENBQUM7QUFDSixDQUFDLENBQUM7QUFFSyxNQUFNLHVCQUF1QixHQUFHLEtBQUssRUFDMUMsU0FBMEIsRUFDMUIsU0FBaUIsRUFDbUIsRUFBRTtJQUN0QyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsT0FBTyxDQUM3QixpQ0FBeUIsQ0FBQyxLQUFLLENBQ2hDLENBQUM7SUFDRixNQUFNLE1BQU0sR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDL0IsTUFBTSxFQUFFLGNBQWM7UUFDdEIsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUM7UUFDdkMsT0FBTyxFQUFFLEVBQUUsZUFBZSxFQUFFLElBQUEsb0RBQTJCLEVBQUMsU0FBUyxDQUFDLEVBQUU7S0FDckUsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUNELE9BQU8sb0JBQW9CLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlDLENBQUMsQ0FBQztBQWhCVyxRQUFBLHVCQUF1QiwyQkFnQmxDO0FBRUYsTUFBTSxVQUFVLEdBQUcsQ0FDakIsS0FBd0IsRUFDeEIsTUFBNEMsRUFDNUMsVUFHSyxFQUFFLEVBQ3FCLEVBQUUsQ0FBQyxDQUFDO0lBQ2hDLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7SUFDNUIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3JFLElBQUksRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUk7SUFDeEIsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtJQUM1QixHQUFHLENBQUMsT0FBTyxDQUFDLGNBQWM7UUFDeEIsQ0FBQyxDQUFDLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxjQUFjLEVBQUU7UUFDN0MsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNQLE1BQU07Q0FDUCxDQUFDLENBQUM7QUFFSCxNQUFNLFVBQVUsR0FBRyxDQUNqQixNQUFjLEVBQ2QsS0FBd0IsRUFDeEIsSUFBWSxFQUNOLEVBQUU7SUFDUixNQUFNLENBQUMsSUFBSSxDQUNULGtCQUFrQixLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsU0FBUyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksWUFBWSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsU0FBUyxJQUFJLEVBQUUsQ0FDekcsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGLE1BQU0sZUFBZSxHQUFHLEtBQUssRUFDM0IsS0FBeUIsRUFDekIsTUFBYyxFQUNkLEtBQXdCLEVBQ3hCLElBQVksRUFDWixHQUFTLEVBQzRCLEVBQUU7SUFDdkMsTUFBTSxLQUFLLENBQUMsaUJBQWlCLENBQUM7UUFDNUIsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUM1QixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7UUFDbEMsWUFBWSxFQUFFLElBQUk7UUFDbEIsV0FBVyxFQUFFLEdBQUc7S0FDakIsQ0FBQyxDQUFDO0lBQ0gsVUFBVSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEMsT0FBTyxVQUFVLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzVELENBQUMsQ0FBQztBQUVGLE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxFQUNuQyxLQUF5QixFQUN6QixNQUFjLEVBQ2QsS0FBd0IsRUFDeEIsT0FBNkIsRUFDN0IsY0FBNkIsRUFDN0IsR0FBUyxFQUM0QixFQUFFO0lBQ3ZDLElBQ0UsT0FBTyxDQUFDLE9BQU8sS0FBSyxXQUFXO1FBQy9CLElBQUEsOENBQXFCLEVBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFDbkQsQ0FBQztRQUNELE1BQU0sS0FBSyxDQUFDLG9CQUFvQixDQUFDO1lBQy9CLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDNUIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ2xDLFlBQVksRUFBRSxPQUFPLENBQUMsSUFBSTtZQUMxQixXQUFXLEVBQUUsR0FBRztZQUNoQixlQUFlLEVBQUUsSUFBQSw2Q0FBb0IsRUFBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUM7WUFDeEUsZUFBZSxFQUFFLGNBQWM7U0FDaEMsQ0FBQyxDQUFDO1FBQ0gsVUFBVSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLE9BQU8sVUFBVSxDQUFDLEtBQUssRUFBRSxlQUFlLEVBQUU7WUFDeEMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxJQUFJO1lBQ3pCLGNBQWM7U0FDZixDQUFDLENBQUM7SUFDTCxDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsT0FBTyxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDO1FBQy9CLE1BQU0sS0FBSyxDQUFDLGlCQUFpQixDQUFDO1lBQzVCLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDNUIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ2xDLFlBQVksRUFBRSxJQUFJO1lBQ2xCLFdBQVcsRUFBRSxHQUFHO1lBQ2hCLGVBQWUsRUFBRSxjQUFjO1NBQ2hDLENBQUMsQ0FBQztRQUNILFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUU7WUFDakMsV0FBVyxFQUFFLElBQUk7WUFDakIsY0FBYztTQUNmLENBQUMsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDakMsTUFBTSxLQUFLLENBQUMsaUJBQWlCLENBQUM7WUFDNUIsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUM1QixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7WUFDbEMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxJQUFJO1lBQzFCLFdBQVcsRUFBRSxHQUFHO1lBQ2hCLGVBQWUsRUFBRSxjQUFjO1NBQ2hDLENBQUMsQ0FBQztRQUNILFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxPQUFPLFVBQVUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFO1lBQ2pDLFdBQVcsRUFBRSxPQUFPLENBQUMsSUFBSTtZQUN6QixjQUFjO1NBQ2YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE1BQU0sS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBQzdCLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDNUIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1FBQ2xDLFlBQVksRUFBRSxPQUFPLENBQUMsSUFBSTtRQUMxQixXQUFXLEVBQUUsR0FBRztRQUNoQixlQUFlLEVBQUUsY0FBYztLQUNoQyxDQUFDLENBQUM7SUFDSCxVQUFVLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEMsT0FBTyxVQUFVLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRTtRQUNsQyxXQUFXLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDekIsY0FBYztLQUNmLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQztBQUVLLE1BQU0saUJBQWlCLEdBQUcsS0FBSyxFQUNwQyxTQUEwQixFQUMxQixLQUF3QixFQUN4QixLQUEwQixFQUNXLEVBQUU7SUFDdkMsTUFBTSxNQUFNLEdBQUcsS0FBSyxZQUFZLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDM0QsTUFBTSxLQUFLLEdBQUcsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBUyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzRSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzlCLElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxxQkFBcUIsRUFBRSxDQUFDO1FBQzNDLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLDJDQUEyQyxFQUMzQyxNQUFNLEVBQUUsQ0FDVCxDQUFDO0lBQ0osQ0FBQztJQUNELElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ3ZFLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLG1CQUFtQixFQUNuQixNQUFNLEVBQUUsQ0FDVCxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sWUFBWSxHQUFHLGlDQUF5QixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQ3BFLE9BQU8sQ0FBQyxhQUFhLENBQ3RCLENBQUM7SUFDRixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzFCLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLHVCQUF1QixFQUN2QixNQUFNLEVBQUUsQ0FDVCxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0scUJBQXFCLEdBQUcsa0NBQXFCLENBQUMsS0FBSyxFQUFFLENBQUMsU0FBUyxDQUNuRSxPQUFPLENBQUMsV0FBVyxDQUNwQixDQUFDO0lBQ0YsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25DLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLG9CQUFvQixFQUNwQixNQUFNLEVBQUUsQ0FDVCxDQUFDO0lBQ0osQ0FBQztJQUVELElBQUksV0FBVyxDQUFDO0lBQ2hCLElBQUksQ0FBQztRQUNILE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQXFCLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsRSxXQUFXLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUM3QixxQkFBcUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtZQUNsRCxNQUFNLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVELElBQ0UsUUFBUSxJQUFJLFVBQVU7Z0JBQ3RCLENBQUMsT0FBTyxDQUFDLFVBQVUsS0FBSyxVQUFVLENBQUMsU0FBUztvQkFDMUMsSUFBQSx3QkFBVSxFQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO3dCQUNoRCxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQ3RCLENBQUM7Z0JBQ0QsTUFBTSxJQUFJLDZCQUE2QixFQUFFLENBQUM7WUFDNUMsQ0FBQztZQUNELE9BQU87Z0JBQ0wsT0FBTyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUNuQyxZQUFZLEVBQUUsVUFBVSxDQUFDLFlBQVk7Z0JBQ3JDLFdBQVcsRUFBRSxZQUFxQjtnQkFDbEMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFRO2dCQUM3QixFQUFFLEVBQUUsSUFBQSw4QkFBaUIsRUFBQyxVQUFVLENBQUM7YUFDbEMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLElBQUksS0FBSyxZQUFZLDZCQUE2QixFQUFFLENBQUM7WUFDbkQsT0FBTyxNQUFNLGVBQWUsQ0FDMUIsS0FBSyxFQUNMLE1BQU0sRUFDTixLQUFLLEVBQ0wsb0JBQW9CLEVBQ3BCLE1BQU0sRUFBRSxDQUNULENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3BDLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLHdCQUF3QixFQUN4QixNQUFNLEVBQUUsQ0FDVCxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sTUFBTSx1QkFBdUIsQ0FDbEMsS0FBSyxFQUNMLE1BQU0sRUFDTixLQUFLLEVBQ0wsRUFBRSxJQUFJLEVBQUUsc0JBQXNCLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxFQUN0RCxJQUFJLEVBQ0osTUFBTSxFQUFFLENBQ1QsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUEsOENBQW9CLEVBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkQsSUFBSSxRQUFRLENBQUM7SUFDYixJQUFJLENBQUM7UUFDSCxRQUFRLEdBQUcsSUFBQSwwQkFBVyxFQUNwQixLQUFLLENBQUMsd0JBQXdCLEVBQUUsRUFDaEM7WUFDRSxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsSUFBSSxFQUFFLFlBQVksQ0FBQyxJQUFJO1NBQ2YsRUFDVixJQUFJLENBQ0wsQ0FBQztJQUNKLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLE1BQU0sZUFBZSxDQUMxQixLQUFLLEVBQ0wsTUFBTSxFQUNOLEtBQUssRUFDTCxlQUFlLEVBQ2YsTUFBTSxFQUFFLENBQ1QsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztZQUM1QixVQUFVLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzVCLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtZQUNsQyxHQUFHLEVBQUUsTUFBTSxFQUFFO1NBQ2QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE1BQU0sSUFBSSxHQUFHLG9CQUFvQixDQUFDO1FBQ2xDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sVUFBVSxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRUQsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FDckMsZUFBTyxDQUFDLFlBQVksQ0FDckIsQ0FBQztJQUNGLE1BQU0sUUFBUSxHQUFHO1FBQ2YsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUM1QixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxFQUFFO0tBQ3ZCLENBQUM7SUFDRixJQUFJLGFBQXNCLENBQUM7SUFDM0IsSUFBSSxPQUFPLEdBQThCLElBQUksQ0FBQztJQUM5QyxJQUFJLENBQUM7UUFDSCxPQUFPLEdBQUcsb0JBQW9CLENBQzVCLE1BQU0sYUFBYSxDQUFDLG1CQUFtQixDQUFDO1lBQ3RDLFdBQVc7WUFDWCxPQUFPLEVBQUUsT0FBTztZQUNoQixPQUFPLEVBQUU7Z0JBQ1AsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJO2dCQUNuQixPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87Z0JBQ3pCLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTthQUNwQjtZQUNELElBQUksRUFBRSxRQUFRO1lBQ2QsZUFBZSxFQUFFLElBQUEsb0RBQTJCLEVBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDOUQsR0FBRyxDQUFDLEtBQUssQ0FBQyx3QkFBd0I7Z0JBQ2hDLENBQUMsQ0FBQyxFQUFFLHdCQUF3QixFQUFFLEtBQUssQ0FBQyx3QkFBd0IsRUFBRTtnQkFDOUQsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNQLGFBQWEsRUFBRSxRQUFRO1lBQ3ZCLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxFQUFFO1lBQzlDLGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYTtZQUNwQyxRQUFRLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDdEIsRUFBRSxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQ3JCLFlBQVksRUFBRSx3QkFBd0I7U0FDdkMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksU0FBUyxHQUE4QixJQUFJLENBQUM7SUFDaEQsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLElBQUksQ0FBQyxPQUFPLElBQUksYUFBYSxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDO1lBQ0gsU0FBUyxHQUFHLE1BQU0sSUFBQSwrQkFBdUIsRUFBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sWUFBWSxHQUFHLE9BQU8sSUFBSSxTQUFTLENBQUM7SUFDMUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxFQUFFLENBQUM7SUFDNUIsSUFBSSxZQUFZLEVBQUUsTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sS0FBSyxDQUFDLGVBQWUsQ0FBQztZQUMxQixVQUFVLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzVCLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtZQUNsQyxXQUFXLEVBQUUsVUFBVTtZQUN2QixlQUFlLEVBQUUsWUFBWSxDQUFDLEVBQUU7U0FDakMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxVQUFVLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQ1gsYUFBYSxJQUFJLFlBQVksRUFBRSxNQUFNLEtBQUssU0FBUyxJQUFJLENBQUMsWUFBWTtRQUNsRSxDQUFDLENBQUMsSUFBQSxvREFBMkIsRUFBQyxhQUFhLENBQUM7UUFDNUMsQ0FBQyxDQUFFLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQVksQ0FBQztJQUNqRSxPQUFPLE1BQU0sdUJBQXVCLENBQ2xDLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLE9BQU8sRUFDUCxZQUFZLEVBQUUsRUFBRSxJQUFJLElBQUksRUFDeEIsVUFBVSxDQUNYLENBQUM7QUFDSixDQUFDLENBQUM7QUEvTVcsUUFBQSxpQkFBaUIscUJBK001QjtBQUVGLE1BQU0sd0JBQXdCLEdBQUcsSUFBQSwwQkFBVSxFQUl6Qyx3QkFBd0IsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtJQUN6RCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDMUQsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7SUFDM0QsTUFBTSxLQUFLLEdBQUcsTUFBTSxtQkFBbUIsQ0FDckMsU0FBUyxDQUNWLENBQUMscUNBQXFDLENBQUM7UUFDdEMsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO1FBQzVCLEdBQUcsRUFBRSxLQUFLLEVBQUU7S0FDYixDQUFDLENBQUM7SUFDSCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxPQUFPLElBQUksNEJBQVksQ0FBQztZQUN0QixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7WUFDNUIsTUFBTSxFQUFFLGFBQWE7U0FDdEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU8sSUFBSSw0QkFBWSxDQUFDLE1BQU0sSUFBQSx5QkFBaUIsRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDNUUsQ0FBQyxDQUFDLENBQUM7QUFFVSxRQUFBLDRCQUE0QixHQUFHLElBQUEsOEJBQWMsRUFDeEQsd0JBQXdCLEVBQ3hCLENBQUMsS0FBZ0MsRUFBRSxFQUFFLENBQ25DLElBQUksZ0NBQWdCLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FDeEQsQ0FBQyJ9
|
|
303
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzcGF0Y2gtZW1haWwtbWVzc2FnZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy93b3JrZmxvd3MvZW1haWwvZGlzcGF0Y2gtZW1haWwtbWVzc2FnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBeUM7QUFRekMscURBSW1DO0FBQ25DLHFFQUsyQztBQUUzQyxzRkFNbUQ7QUFDbkQsK0NBQW1EO0FBQ25ELHNFQUcrQztBQUcvQywyRkFBcUY7QUFDckYscUVBQWlFO0FBQ2pFLDZDQUcyQjtBQUUzQixNQUFNLG1CQUFtQixHQUFHLDRCQUE0QixDQUFDO0FBRXpELE1BQU0sNkJBQThCLFNBQVEsS0FBSztDQUFHO0FBOEJwRCxNQUFNLG1CQUFtQixHQUFHLENBQUMsU0FBMEIsRUFBc0IsRUFBRSxDQUM3RSxTQUFTLENBQUMsT0FBTyxDQUFxQixvQkFBWSxDQUFDLENBQUM7QUFFdEQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFjLEVBQVEsRUFBRTtJQUMxQyxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO0lBQ2xELElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2pDLE1BQU0sSUFBSSxTQUFTLENBQUMsMENBQTBDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDLENBQUM7QUFFRixNQUFNLG9CQUFvQixHQUFHLENBQUMsS0FBYyxFQUE2QixFQUFFO0lBQ3pFLElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDeEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsS0FBZ0MsQ0FBQztJQUNoRCxJQUNFLE9BQU8sTUFBTSxDQUFDLEVBQUUsS0FBSyxRQUFRO1FBQzdCLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDakIsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLFNBQVM7WUFDMUIsTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTO1lBQzNCLE1BQU0sQ0FBQyxNQUFNLEtBQUssU0FBUyxDQUFDLEVBQzlCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxPQUFPO1FBQ0wsV0FBVyxFQUNULE9BQU8sTUFBTSxDQUFDLFdBQVcsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUk7UUFDcEUsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFO1FBQ2IsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO0tBQ3RCLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLHdCQUF3QixHQUFHLENBQUMsS0FBYyxFQUFXLEVBQUU7SUFDM0QsSUFDRSxtQkFBVyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7UUFDaEMsS0FBSyxDQUFDLElBQUksS0FBSyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQzFDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxJQUFJLENBQUMsS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3hDLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLEtBQWdDLENBQUM7SUFDaEQsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQzVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUM7SUFDbEMsT0FBTyxDQUNMLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDakIsT0FBTyxRQUFRLEtBQUssUUFBUTtRQUMzQixRQUFvQyxDQUFDLGNBQWMsS0FBSyxHQUFHLENBQzdELENBQUM7QUFDSixDQUFDLENBQUM7QUFFSyxNQUFNLHVCQUF1QixHQUFHLEtBQUssRUFDMUMsU0FBMEIsRUFDMUIsU0FBaUIsRUFDbUIsRUFBRTtJQUN0QyxNQUFNLEtBQUssR0FBRyxTQUFTLENBQUMsT0FBTyxDQUM3QixpQ0FBeUIsQ0FBQyxLQUFLLENBQ2hDLENBQUM7SUFDRixNQUFNLE1BQU0sR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDL0IsTUFBTSxFQUFFLGNBQWM7UUFDdEIsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUM7UUFDdkMsT0FBTyxFQUFFLEVBQUUsZUFBZSxFQUFFLElBQUEsb0RBQTJCLEVBQUMsU0FBUyxDQUFDLEVBQUU7S0FDckUsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUNELE9BQU8sb0JBQW9CLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlDLENBQUMsQ0FBQztBQWhCVyxRQUFBLHVCQUF1QiwyQkFnQmxDO0FBRUYsTUFBTSxVQUFVLEdBQUcsQ0FDakIsS0FBd0IsRUFDeEIsTUFBNEMsRUFDNUMsVUFHSyxFQUFFLEVBQ3FCLEVBQUUsQ0FBQyxDQUFDO0lBQ2hDLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7SUFDNUIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3JFLElBQUksRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUk7SUFDeEIsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtJQUM1QixHQUFHLENBQUMsT0FBTyxDQUFDLGNBQWM7UUFDeEIsQ0FBQyxDQUFDLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxjQUFjLEVBQUU7UUFDN0MsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNQLE1BQU07Q0FDUCxDQUFDLENBQUM7QUFFSCxNQUFNLFVBQVUsR0FBRyxDQUNqQixNQUFjLEVBQ2QsS0FBd0IsRUFDeEIsSUFBWSxFQUNOLEVBQUU7SUFDUixNQUFNLENBQUMsSUFBSSxDQUNULGtCQUFrQixLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsU0FBUyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksWUFBWSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsU0FBUyxJQUFJLEVBQUUsQ0FDekcsQ0FBQztBQUNKLENBQUMsQ0FBQztBQUVGLE1BQU0sZUFBZSxHQUFHLEtBQUssRUFDM0IsS0FBeUIsRUFDekIsTUFBYyxFQUNkLEtBQXdCLEVBQ3hCLElBQVksRUFDWixHQUFTLEVBQzRCLEVBQUU7SUFDdkMsTUFBTSxLQUFLLENBQUMsaUJBQWlCLENBQUM7UUFDNUIsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUM1QixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7UUFDbEMsWUFBWSxFQUFFLElBQUk7UUFDbEIsV0FBVyxFQUFFLEdBQUc7S0FDakIsQ0FBQyxDQUFDO0lBQ0gsVUFBVSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEMsT0FBTyxVQUFVLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzVELENBQUMsQ0FBQztBQUVGLE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxFQUNuQyxLQUF5QixFQUN6QixNQUFjLEVBQ2QsS0FBd0IsRUFDeEIsT0FBNkIsRUFDN0IsY0FBNkIsRUFDN0IsR0FBUyxFQUM0QixFQUFFO0lBQ3ZDLElBQ0UsT0FBTyxDQUFDLE9BQU8sS0FBSyxXQUFXO1FBQy9CLElBQUEsOENBQXFCLEVBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFDbkQsQ0FBQztRQUNELE1BQU0sS0FBSyxDQUFDLG9CQUFvQixDQUFDO1lBQy9CLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDNUIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ2xDLFlBQVksRUFBRSxPQUFPLENBQUMsSUFBSTtZQUMxQixXQUFXLEVBQUUsR0FBRztZQUNoQixlQUFlLEVBQUUsSUFBQSw2Q0FBb0IsRUFBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUM7WUFDeEUsZUFBZSxFQUFFLGNBQWM7U0FDaEMsQ0FBQyxDQUFDO1FBQ0gsVUFBVSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLE9BQU8sVUFBVSxDQUFDLEtBQUssRUFBRSxlQUFlLEVBQUU7WUFDeEMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxJQUFJO1lBQ3pCLGNBQWM7U0FDZixDQUFDLENBQUM7SUFDTCxDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsT0FBTyxLQUFLLFdBQVcsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDO1FBQy9CLE1BQU0sS0FBSyxDQUFDLGlCQUFpQixDQUFDO1lBQzVCLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDNUIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1lBQ2xDLFlBQVksRUFBRSxJQUFJO1lBQ2xCLFdBQVcsRUFBRSxHQUFHO1lBQ2hCLGVBQWUsRUFBRSxjQUFjO1NBQ2hDLENBQUMsQ0FBQztRQUNILFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUU7WUFDakMsV0FBVyxFQUFFLElBQUk7WUFDakIsY0FBYztTQUNmLENBQUMsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUFJLE9BQU8sQ0FBQyxPQUFPLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDakMsTUFBTSxLQUFLLENBQUMsaUJBQWlCLENBQUM7WUFDNUIsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUM1QixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7WUFDbEMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxJQUFJO1lBQzFCLFdBQVcsRUFBRSxHQUFHO1lBQ2hCLGVBQWUsRUFBRSxjQUFjO1NBQ2hDLENBQUMsQ0FBQztRQUNILFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxPQUFPLFVBQVUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFO1lBQ2pDLFdBQVcsRUFBRSxPQUFPLENBQUMsSUFBSTtZQUN6QixjQUFjO1NBQ2YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE1BQU0sS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBQzdCLFVBQVUsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDNUIsYUFBYSxFQUFFLEtBQUssQ0FBQyxhQUFhO1FBQ2xDLFlBQVksRUFBRSxPQUFPLENBQUMsSUFBSTtRQUMxQixXQUFXLEVBQUUsR0FBRztRQUNoQixlQUFlLEVBQUUsY0FBYztLQUNoQyxDQUFDLENBQUM7SUFDSCxVQUFVLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEMsT0FBTyxVQUFVLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRTtRQUNsQyxXQUFXLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDekIsY0FBYztLQUNmLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQztBQUVLLE1BQU0saUJBQWlCLEdBQUcsS0FBSyxFQUNwQyxTQUEwQixFQUMxQixLQUF3QixFQUN4QixLQUEwQixFQUNXLEVBQUU7SUFDdkMsTUFBTSxNQUFNLEdBQUcsS0FBSyxZQUFZLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDM0QsTUFBTSxLQUFLLEdBQUcsbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBUyxpQ0FBeUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzRSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzlCLDhFQUE4RTtJQUM5RSxnRUFBZ0U7SUFDaEUsSUFBSSxJQUFBLDRCQUFvQixFQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3ZDLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLDJDQUEyQyxFQUMzQyxNQUFNLEVBQUUsQ0FDVCxDQUFDO0lBQ0osQ0FBQztJQUNELElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ3ZFLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLG1CQUFtQixFQUNuQixNQUFNLEVBQUUsQ0FDVCxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sWUFBWSxHQUFHLGlDQUF5QixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQ3BFLE9BQU8sQ0FBQyxhQUFhLENBQ3RCLENBQUM7SUFDRixJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzFCLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLHVCQUF1QixFQUN2QixNQUFNLEVBQUUsQ0FDVCxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0scUJBQXFCLEdBQUcsa0NBQXFCLENBQUMsS0FBSyxFQUFFLENBQUMsU0FBUyxDQUNuRSxPQUFPLENBQUMsV0FBVyxDQUNwQixDQUFDO0lBQ0YsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25DLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLG9CQUFvQixFQUNwQixNQUFNLEVBQUUsQ0FDVCxDQUFDO0lBQ0osQ0FBQztJQUVELElBQUksV0FBVyxDQUFDO0lBQ2hCLElBQUksQ0FBQztRQUNILE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQXFCLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsRSxXQUFXLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUM3QixxQkFBcUIsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtZQUNsRCxNQUFNLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVELElBQ0UsUUFBUSxJQUFJLFVBQVU7Z0JBQ3RCLENBQUMsT0FBTyxDQUFDLFVBQVUsS0FBSyxVQUFVLENBQUMsU0FBUztvQkFDMUMsSUFBQSx3QkFBVSxFQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO3dCQUNoRCxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQ3RCLENBQUM7Z0JBQ0QsTUFBTSxJQUFJLDZCQUE2QixFQUFFLENBQUM7WUFDNUMsQ0FBQztZQUNELE9BQU87Z0JBQ0wsT0FBTyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUNuQyxZQUFZLEVBQUUsVUFBVSxDQUFDLFlBQVk7Z0JBQ3JDLFdBQVcsRUFBRSxZQUFxQjtnQkFDbEMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxRQUFRO2dCQUM3QixFQUFFLEVBQUUsSUFBQSw4QkFBaUIsRUFBQyxVQUFVLENBQUM7YUFDbEMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLElBQUksS0FBSyxZQUFZLDZCQUE2QixFQUFFLENBQUM7WUFDbkQsT0FBTyxNQUFNLGVBQWUsQ0FDMUIsS0FBSyxFQUNMLE1BQU0sRUFDTixLQUFLLEVBQ0wsb0JBQW9CLEVBQ3BCLE1BQU0sRUFBRSxDQUNULENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSx3QkFBd0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3BDLE9BQU8sTUFBTSxlQUFlLENBQzFCLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLHdCQUF3QixFQUN4QixNQUFNLEVBQUUsQ0FDVCxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sTUFBTSx1QkFBdUIsQ0FDbEMsS0FBSyxFQUNMLE1BQU0sRUFDTixLQUFLLEVBQ0wsRUFBRSxJQUFJLEVBQUUsc0JBQXNCLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxFQUN0RCxJQUFJLEVBQ0osTUFBTSxFQUFFLENBQ1QsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUEsOENBQW9CLEVBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkQsSUFBSSxRQUFRLENBQUM7SUFDYixJQUFJLENBQUM7UUFDSCxRQUFRLEdBQUcsSUFBQSwwQkFBVyxFQUNwQixLQUFLLENBQUMsd0JBQXdCLEVBQUUsRUFDaEM7WUFDRSxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsSUFBSSxFQUFFLFlBQVksQ0FBQyxJQUFJO1NBQ2YsRUFDVixJQUFJLENBQ0wsQ0FBQztJQUNKLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLE1BQU0sZUFBZSxDQUMxQixLQUFLLEVBQ0wsTUFBTSxFQUNOLEtBQUssRUFDTCxlQUFlLEVBQ2YsTUFBTSxFQUFFLENBQ1QsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFJLENBQUM7UUFDSCxNQUFNLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztZQUM1QixVQUFVLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzVCLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtZQUNsQyxHQUFHLEVBQUUsTUFBTSxFQUFFO1NBQ2QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE1BQU0sSUFBSSxHQUFHLG9CQUFvQixDQUFDO1FBQ2xDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sVUFBVSxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNqRSxDQUFDO0lBRUQsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FDckMsZUFBTyxDQUFDLFlBQVksQ0FDckIsQ0FBQztJQUNGLE1BQU0sUUFBUSxHQUFHO1FBQ2YsVUFBVSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUM1QixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxFQUFFO0tBQ3ZCLENBQUM7SUFDRixJQUFJLGFBQXNCLENBQUM7SUFDM0IsSUFBSSxPQUFPLEdBQThCLElBQUksQ0FBQztJQUM5QyxJQUFJLENBQUM7UUFDSCxPQUFPLEdBQUcsb0JBQW9CLENBQzVCLE1BQU0sYUFBYSxDQUFDLG1CQUFtQixDQUFDO1lBQ3RDLFdBQVc7WUFDWCxPQUFPLEVBQUUsT0FBTztZQUNoQixPQUFPLEVBQUU7Z0JBQ1AsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJO2dCQUNuQixPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87Z0JBQ3pCLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTthQUNwQjtZQUNELElBQUksRUFBRSxRQUFRO1lBQ2QsZUFBZSxFQUFFLElBQUEsb0RBQTJCLEVBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDOUQsR0FBRyxDQUFDLEtBQUssQ0FBQyx3QkFBd0I7Z0JBQ2hDLENBQUMsQ0FBQyxFQUFFLHdCQUF3QixFQUFFLEtBQUssQ0FBQyx3QkFBd0IsRUFBRTtnQkFDOUQsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNQLGFBQWEsRUFBRSxRQUFRO1lBQ3ZCLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxFQUFFO1lBQzlDLGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYTtZQUNwQyxRQUFRLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDdEIsRUFBRSxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQ3JCLFlBQVksRUFBRSx3QkFBd0I7U0FDdkMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksU0FBUyxHQUE4QixJQUFJLENBQUM7SUFDaEQsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLElBQUksQ0FBQyxPQUFPLElBQUksYUFBYSxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDO1lBQ0gsU0FBUyxHQUFHLE1BQU0sSUFBQSwrQkFBdUIsRUFBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6RSxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN0QixDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sWUFBWSxHQUFHLE9BQU8sSUFBSSxTQUFTLENBQUM7SUFDMUMsTUFBTSxVQUFVLEdBQUcsTUFBTSxFQUFFLENBQUM7SUFDNUIsSUFBSSxZQUFZLEVBQUUsTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sS0FBSyxDQUFDLGVBQWUsQ0FBQztZQUMxQixVQUFVLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzVCLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtZQUNsQyxXQUFXLEVBQUUsVUFBVTtZQUN2QixlQUFlLEVBQUUsWUFBWSxDQUFDLEVBQUU7U0FDakMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxVQUFVLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxFQUFFLGNBQWMsRUFBRSxZQUFZLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQ1gsYUFBYSxJQUFJLFlBQVksRUFBRSxNQUFNLEtBQUssU0FBUyxJQUFJLENBQUMsWUFBWTtRQUNsRSxDQUFDLENBQUMsSUFBQSxvREFBMkIsRUFBQyxhQUFhLENBQUM7UUFDNUMsQ0FBQyxDQUFFLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQVksQ0FBQztJQUNqRSxPQUFPLE1BQU0sdUJBQXVCLENBQ2xDLEtBQUssRUFDTCxNQUFNLEVBQ04sS0FBSyxFQUNMLE9BQU8sRUFDUCxZQUFZLEVBQUUsRUFBRSxJQUFJLElBQUksRUFDeEIsVUFBVSxDQUNYLENBQUM7QUFDSixDQUFDLENBQUM7QUFqTlcsUUFBQSxpQkFBaUIscUJBaU41QjtBQUVGLE1BQU0sd0JBQXdCLEdBQUcsSUFBQSwwQkFBVSxFQUl6Qyx3QkFBd0IsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRTtJQUN6RCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDMUQsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7SUFDM0QsTUFBTSxLQUFLLEdBQUcsTUFBTSxtQkFBbUIsQ0FDckMsU0FBUyxDQUNWLENBQUMscUNBQXFDLENBQUM7UUFDdEMsVUFBVSxFQUFFLEtBQUssQ0FBQyxVQUFVO1FBQzVCLEdBQUcsRUFBRSxLQUFLLEVBQUU7S0FDYixDQUFDLENBQUM7SUFDSCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxPQUFPLElBQUksNEJBQVksQ0FBQztZQUN0QixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7WUFDNUIsTUFBTSxFQUFFLGFBQWE7U0FDdEIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU8sSUFBSSw0QkFBWSxDQUFDLE1BQU0sSUFBQSx5QkFBaUIsRUFBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDNUUsQ0FBQyxDQUFDLENBQUM7QUFFVSxRQUFBLDRCQUE0QixHQUFHLElBQUEsOEJBQWMsRUFDeEQsd0JBQXdCLEVBQ3hCLENBQUMsS0FBZ0MsRUFBRSxFQUFFLENBQ25DLElBQUksZ0NBQWdCLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FDeEQsQ0FBQyJ9
|
package/README.md
CHANGED
|
@@ -125,6 +125,7 @@ dashboard uses.
|
|
|
125
125
|
| `POST` | `/admin/plugin-features/:plugin_key/settings` | Admin user | `AdminPluginFeaturesResponse` |
|
|
126
126
|
| `POST` | `/admin/plugin-features/:plugin_key/actions/:action_key` | Admin user | `AdminPluginActionRunResponse` (200 sync, 202 background), 409 `AdminPluginActionConflictResponse` while it runs |
|
|
127
127
|
| `GET` | `/admin/plugin-features/:plugin_key/actions/:action_key/runs` | Admin user | `AdminPluginActionRunsResponse` (`?limit=`, default 1, max 20) |
|
|
128
|
+
| `POST` | `/store/customer-verification/resend` | publishable key | 202 `ResendCustomerVerificationResponse` (`{ accepted: true }`) for every address, 404 while `customer_verification` is off; see "Kontobestätigung per E-Mail" |
|
|
128
129
|
|
|
129
130
|
Every authenticated Admin user may change toggles and settings and run
|
|
130
131
|
actions (no RBAC by design). Admin plugin DTOs carry the toggles plus
|
|
@@ -272,7 +273,9 @@ Code on the cart and checkout hot path (cart middlewares, cart workflow hooks,
|
|
|
272
273
|
`orderCreated` handling, cart subscribers) must never read toggles. It stays
|
|
273
274
|
fail-safe and independent of the database state of this plugin. Toggles
|
|
274
275
|
control visibility and reachability of features, not the integrity of
|
|
275
|
-
existing data.
|
|
276
|
+
existing data. Login is not the cart path: the E-Mail plugin's
|
|
277
|
+
`customer_verification` toggle does switch customer logins, through an
|
|
278
|
+
in-memory copy of the toggle (see "Kontobestätigung per E-Mail").
|
|
276
279
|
|
|
277
280
|
## Runtime settings
|
|
278
281
|
|
|
@@ -832,8 +835,11 @@ Options of the `email` namespace:
|
|
|
832
835
|
`projectConfig.http.jwtSecret`.
|
|
833
836
|
- `shop` — a `ShopEmailConfiguration` object: `displayName`,
|
|
834
837
|
`affiliatePortalUrl`, the `passwordResetUrl`/`inviteUrl` builders and the
|
|
835
|
-
`orderNotificationEmail` mailbox. `
|
|
836
|
-
|
|
838
|
+
`orderNotificationEmail` mailbox. `verifyAccountUrl` (optional builder,
|
|
839
|
+
like `passwordResetUrl`; the mail appends `#token=`) is the storefront page
|
|
840
|
+
that confirms an account, needed while `customer_verification` is on.
|
|
841
|
+
`layout` and `renderers` are optional overrides, see "Shop configuration and
|
|
842
|
+
default templates".
|
|
837
843
|
|
|
838
844
|
Without `email.shop` the module still boots, but it cannot dispatch: no mail
|
|
839
845
|
is sent (the dispatch configuration is requested lazily and fails with
|
|
@@ -882,7 +888,8 @@ feature is switched on again.
|
|
|
882
888
|
| --------------------- | ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------- |
|
|
883
889
|
| (plugin switch) | E-Mail | on | every route under `/admin/email/*` (mail log, resends, terms versions; 404); jobs `email-reconcile-attempts`, `email-reconcile-pending-messages`, `email-retry-messages`; every feature below | checkout and orders; already queued messages stay stored |
|
|
884
890
|
| `order_mails` | Bestell-Mails | on | subscribers `order-placed`, `email-shipment-created`, `email-order-canceled`, `return-requested`, `return-received`, `documents-shipment-invoice-assignment-decided`, `documents-order-cancellation-ready`, `documents-refund-ready` | jobs, Admin routes, already created messages |
|
|
885
|
-
| `account_mails` | Konto-Mails | on | subscribers `password-reset`, `user-invite`
|
|
891
|
+
| `account_mails` | Konto-Mails | on | subscribers `password-reset`, `user-invite`, `customer-verification` (the last one only with `customer_verification` on as well) | jobs, Admin routes, already created messages |
|
|
892
|
+
| `customer_verification` | Kontobestätigung per E-Mail | off | Medusa's e-mail verification of customer logins (see "Kontobestätigung per E-Mail"), route `POST /store/customer-verification/resend` (404 while off), subscriber `customer-verification`; child of `account_mails` | checkout and orders; confirmed accounts stay confirmed, already created messages |
|
|
886
893
|
| `affiliate_reminders` | Affiliate-Erinnerungen | on | subscriber `affiliate-consignment-reminder-due` | jobs, Admin routes, already created messages |
|
|
887
894
|
|
|
888
895
|
With the plugin switched off the three jobs return immediately, so nothing
|
|
@@ -902,6 +909,111 @@ and gates the Terms PDF versions and mail log sections below it on the
|
|
|
902
909
|
plugin switch, showing `PluginFeatureDisabledNotice` in their place while it
|
|
903
910
|
is off.
|
|
904
911
|
|
|
912
|
+
### Kontobestätigung per E-Mail
|
|
913
|
+
|
|
914
|
+
Feature `customer_verification` (child of `account_mails`, default **off**)
|
|
915
|
+
makes customers confirm their e-mail address through a link before their
|
|
916
|
+
first login. It builds on Medusa 2.19's own e-mail verification
|
|
917
|
+
(`projectConfig.http.authVerificationsPerActor`) and adds the mail, the
|
|
918
|
+
toggle and a resend route.
|
|
919
|
+
|
|
920
|
+
How it works while the feature is on:
|
|
921
|
+
|
|
922
|
+
1. A login (`POST /auth/customer/emailpass`) of an account whose address is
|
|
923
|
+
not confirmed answers `200 { verification_required: true, verification,
|
|
924
|
+
token }`. `token` is an actorless JWT, valid only for the verification
|
|
925
|
+
calls.
|
|
926
|
+
2. The storefront calls Medusa's `POST /auth/verification/request`
|
|
927
|
+
(`{ code_provider: "token", entity_id: <e-mail>, entity_type: "email" }`)
|
|
928
|
+
with that token. Medusa emits `auth.verification_requested`; the
|
|
929
|
+
`customer-verification` subscriber sends the mail "Bestätige deine
|
|
930
|
+
E-Mail-Adresse" (kind `auth.verification`) to `entity_id`.
|
|
931
|
+
3. The link is `<STOREFRONT_URL>/<cc>/verify-account#token=<token>`
|
|
932
|
+
(`verifyAccountUrl` plus the fragment, never a query string). The
|
|
933
|
+
storefront page calls `POST /auth/verification/confirm`
|
|
934
|
+
(`{ code: <token>, code_provider: "token" }`); the next login returns a
|
|
935
|
+
normal token.
|
|
936
|
+
4. The token is valid for 15 minutes (Medusa's default `ttl_seconds` of the
|
|
937
|
+
token provider). Every new request issues a new token and invalidates the
|
|
938
|
+
previous one.
|
|
939
|
+
5. `POST /store/customer-verification/resend` (`{ email }`, publishable key)
|
|
940
|
+
asks for a new mail without a login. It always answers 202
|
|
941
|
+
`{ accepted: true }`, whether or not an account exists, is confirmed or
|
|
942
|
+
was asked too recently, so addresses cannot be probed. The answer is sent
|
|
943
|
+
before any lookup (equal timing), the work runs detached. A mail follows
|
|
944
|
+
only for an existing, unconfirmed customer account whose last request is
|
|
945
|
+
older than 60 seconds. Admin users and addresses without a customer
|
|
946
|
+
account are ignored. A failure is logged with a fixed message and the
|
|
947
|
+
error class only (never the address), not answered. While the feature is
|
|
948
|
+
off the route answers 404.
|
|
949
|
+
6. The same 60-second limit per account applies to Medusa's own
|
|
950
|
+
`POST /auth/verification/request`, which the storefront calls at every
|
|
951
|
+
blocked login: a base middleware answers a request within a minute of the
|
|
952
|
+
previous one with `201 { verification }` (Medusa's shape, without the
|
|
953
|
+
stored token hash) and sends nothing, so repeated logins cannot mail-bomb
|
|
954
|
+
an address; the earlier link stays valid. It applies only to the customer
|
|
955
|
+
account's own `emailpass` address while the feature is on, and fails open
|
|
956
|
+
(the request goes on to Medusa) if the check itself fails.
|
|
957
|
+
|
|
958
|
+
Accounts that exist before the feature is switched on need no migration: they
|
|
959
|
+
have no confirmation row, so their next login is answered with
|
|
960
|
+
`verification_required` and the storefront sends them the mail. Social or
|
|
961
|
+
other providers are not affected, only `emailpass` for `customer`.
|
|
962
|
+
|
|
963
|
+
The mail is sent only while the plugin switch, `account_mails` and
|
|
964
|
+
`customer_verification` are on. It is built from the event like the
|
|
965
|
+
password-reset mail: only the token's hash (the business key) is stored, never
|
|
966
|
+
the token or the link, and neither the generic retry job nor an Admin resend
|
|
967
|
+
can touch it (the Event Bus retry and the 60-second resend are the retry paths).
|
|
968
|
+
Medusa takes `entity_id` of the verification request from the request body
|
|
969
|
+
without comparing it, so the subscriber sends only to an address that is the
|
|
970
|
+
identity's own `emailpass` address and only for a customer actor.
|
|
971
|
+
|
|
972
|
+
**Switching at run time.** The preset sets
|
|
973
|
+
`projectConfig.http.authVerificationsPerActor` to an object whose `customer`
|
|
974
|
+
is a getter: Medusa reads it on every login, and the getter answers from an
|
|
975
|
+
in-memory copy of the effective toggle. The copy is loaded when the
|
|
976
|
+
application starts (the E-Mail module's `onApplicationStart`) and, while
|
|
977
|
+
an unref'd timer refreshes it every 30 seconds, also without traffic (stopped
|
|
978
|
+
at shutdown); a read that finds the copy older than 30 seconds additionally
|
|
979
|
+
starts a background refresh (stale-while-revalidate; the getter is synchronous
|
|
980
|
+
and never throws). A change in the Admin therefore reaches a running instance
|
|
981
|
+
within about 30 seconds plus the read (each instance has its own copy); the
|
|
982
|
+
resend route, the request throttle and the subscriber read
|
|
983
|
+
the toggle itself and follow at once. A failed read keeps the last value and
|
|
984
|
+
logs a warning; before the first successful read the copy is off. The copy
|
|
985
|
+
lives on `globalThis` because the preset (`dist`) and the plugin code Medusa
|
|
986
|
+
loads (`.medusa/server`) are compiled separately. Only the preset
|
|
987
|
+
(`buildFoodShopConfig` / `defineFoodShopConfig`) sets the getter; a shop with a
|
|
988
|
+
hand-written config must set `authVerificationsPerActor` itself (a fixed list,
|
|
989
|
+
changed by a restart) for the toggle to have any effect on logins.
|
|
990
|
+
|
|
991
|
+
Login is not on the cart path, so the cart rule above is not affected.
|
|
992
|
+
|
|
993
|
+
Things to know when switching it on:
|
|
994
|
+
|
|
995
|
+
- Customers who are already logged in stay logged in until their session or
|
|
996
|
+
JWT expires: Medusa checks the confirmation at login and token generation
|
|
997
|
+
without an actor, and a token refresh of an existing actor skips it.
|
|
998
|
+
Only their next login asks for the confirmation.
|
|
999
|
+
- A password reset does not confirm the address; the customer still
|
|
1000
|
+
confirms through the link at the next login.
|
|
1001
|
+
- The storefront must not store the actorless `token` of a
|
|
1002
|
+
`verification_required` response as the customer session. It is only for
|
|
1003
|
+
the verification request, and it carries no customer.
|
|
1004
|
+
|
|
1005
|
+
Storefront contract (DTOs, schema and path from the Contracts package,
|
|
1006
|
+
`types/customer-verification-store`, `schemas/customer-verification`,
|
|
1007
|
+
`paths/customer-verification`):
|
|
1008
|
+
|
|
1009
|
+
- Read `GET /store/plugin-features/email` and show the confirmation flow only
|
|
1010
|
+
while `features.customer_verification` is `true`.
|
|
1011
|
+
- Handle `verification_required` on login and registration: request the mail
|
|
1012
|
+
with the actorless token, show "check your inbox" and offer "Bestätigungsmail
|
|
1013
|
+
erneut senden" (`customerVerificationStorePaths.post.resend`).
|
|
1014
|
+
- Serve `/<cc>/verify-account`, read `token` from `location.hash`, confirm it
|
|
1015
|
+
and then send the customer to the login.
|
|
1016
|
+
|
|
905
1017
|
### Ownership
|
|
906
1018
|
|
|
907
1019
|
- Documents owns document issuance and publishes immutable document facts.
|
|
@@ -944,6 +1056,7 @@ installed Medusa 2.19 exports:
|
|
|
944
1056
|
| `order.return_requested` | `{ order_id: string; return_id: string }` |
|
|
945
1057
|
| `order.return_received` | `{ order_id: string; return_id: string }` |
|
|
946
1058
|
| `auth.password_reset` | `{ entity_id: string; actor_type: string; token: string; metadata?: Record<string, unknown> }` |
|
|
1059
|
+
| `auth.verification_requested` | `{ entity_id: string; entity_type: string; code_provider: string; auth_identity_id: string; code: string; expires_at: Date \| string; metadata?: Record<string, unknown> }`; not strict, `code` is missing for an already confirmed identity (ignored) |
|
|
947
1060
|
|
|
948
1061
|
The shared immutable Documents artifact is:
|
|
949
1062
|
|
|
@@ -1037,8 +1150,8 @@ has at most 35 characters. Email runtime-validates every contract before use.
|
|
|
1037
1150
|
|
|
1038
1151
|
- The accepted kinds are exactly `order.received`, `order.received.admin`, `order.shipped`,
|
|
1039
1152
|
`order.canceled`, `order.return_requested`, `order.return_received`,
|
|
1040
|
-
`order.refunded`, `auth.password_reset`,
|
|
1041
|
-
`affiliate.consignment_report_due`.
|
|
1153
|
+
`order.refunded`, `auth.password_reset`, `auth.verification`,
|
|
1154
|
+
`affiliate.consignment_report_due` and `user.invite`.
|
|
1042
1155
|
- Every automatic message has a deterministic business key.
|
|
1043
1156
|
- Every placed Order creates independent customer and Shop intents. The customer
|
|
1044
1157
|
intent honors `no_notification`; the Shop intent always targets the static
|
|
@@ -1060,10 +1173,11 @@ has at most 35 characters. Email runtime-validates every contract before use.
|
|
|
1060
1173
|
including any invoice attachment; refund email has no Documents-disabled
|
|
1061
1174
|
native fallback.
|
|
1062
1175
|
- Recipients, rendered content, attachment bytes, SMTP responses, credentials,
|
|
1063
|
-
reset tokens, and
|
|
1064
|
-
- Reset tokens and
|
|
1065
|
-
|
|
1066
|
-
|
|
1176
|
+
reset and verification tokens, and their URLs are never logged.
|
|
1177
|
+
- Reset and verification tokens and URLs are never persisted by Email or
|
|
1178
|
+
Notification.
|
|
1179
|
+
- Password-reset and account-confirmation messages cannot be retried by the
|
|
1180
|
+
generic retry job or resent by an Admin.
|
|
1067
1181
|
- Unknown transport outcomes are never automatically resent.
|
|
1068
1182
|
- Shop branding is the configured `displayName` plus the `logo` setting of
|
|
1069
1183
|
the E-Mail plugin and the company details of the Shop-Stammdaten; a shop overrides the default layout or
|
|
@@ -1172,6 +1286,14 @@ without `iat`) and a note that the mail can be ignored. The lifetime is
|
|
|
1172
1286
|
passed as the ephemeral `valid_minutes` next to `reset_url` and is never
|
|
1173
1287
|
persisted.
|
|
1174
1288
|
|
|
1289
|
+
The account confirmation (`auth.verification`) has the subject "Bestätige
|
|
1290
|
+
deine E-Mail-Adresse", a "E-Mail-Adresse bestätigen" button, the link as
|
|
1291
|
+
copyable text, a note that the link is only valid for a limited time (a new
|
|
1292
|
+
one comes with the next login or "Bestätigungsmail erneut senden") and a note
|
|
1293
|
+
that the mail can be ignored. The link comes from `verifyAccountUrl` plus
|
|
1294
|
+
`#token=`; without that builder the message fails with `render_failed`. See
|
|
1295
|
+
"Kontobestätigung per E-Mail".
|
|
1296
|
+
|
|
1175
1297
|
The affiliate reminder (`affiliate.consignment_report_due`) greets the
|
|
1176
1298
|
affiliate by `affiliate_display_name`, names the report month ("September
|
|
1177
1299
|
2026", Austrian month names) and the due date ("10.10.2026") as calendar
|
|
@@ -1258,9 +1380,10 @@ process persists success, and a conscious resend can produce a duplicate.
|
|
|
1258
1380
|
|
|
1259
1381
|
Email transport retries and Event Bus retries are separate. Once an ordinary
|
|
1260
1382
|
message outcome is persisted, its subscriber completes and the Email retry job
|
|
1261
|
-
owns any `retry_pending` work. Password-reset token and URL
|
|
1262
|
-
ephemeral;
|
|
1263
|
-
resend, and retryable handling stays bounded by the original Event Bus
|
|
1383
|
+
owns any `retry_pending` work. Password-reset and verification token and URL
|
|
1384
|
+
data remain ephemeral; both kinds are excluded from the generic retry job and
|
|
1385
|
+
Admin resend, and retryable handling stays bounded by the original Event Bus
|
|
1386
|
+
event.
|
|
1264
1387
|
|
|
1265
1388
|
### Admin API
|
|
1266
1389
|
|
|
@@ -2342,7 +2465,7 @@ validate the environment; a missing variable fails with the variable's name.
|
|
|
2342
2465
|
| `displayName` | Shop name in the default e-mail templates (a shop's initial seed may use it as store name). Company name, address and UID are no options: documents and tax compliance read them only from the Shop-Stammdaten (Admin, "Hartl Services Plugins"). |
|
|
2343
2466
|
| `orderNotificationEmail` | Receives order notification e-mails; must look like an e-mail address. |
|
|
2344
2467
|
| `timeZone` | IANA time zone (validated with `Intl`). Chooses the annual document-number period, the printed dates on documents and the affiliate consignment reminder time zone. |
|
|
2345
|
-
| `storefrontCountryCode` | 2-letter lowercase country code of the storefront route. Links: `<STOREFRONT_URL>/<cc>/partnerportal` (affiliate portal), `<STOREFRONT_URL>/<cc>/reset-password` (the e-mail plugin appends `#token=`), referral base `<STOREFRONT_URL>/<cc>`. The Admin invite link is `<MEDUSA_BACKEND_URL>/app/invite?token=`. |
|
|
2468
|
+
| `storefrontCountryCode` | 2-letter lowercase country code of the storefront route. Links: `<STOREFRONT_URL>/<cc>/partnerportal` (affiliate portal), `<STOREFRONT_URL>/<cc>/reset-password` and `<STOREFRONT_URL>/<cc>/verify-account` (the e-mail plugin appends `#token=`), referral base `<STOREFRONT_URL>/<cc>`. The Admin invite link is `<MEDUSA_BACKEND_URL>/app/invite?token=`. |
|
|
2346
2469
|
| `documentHtmlFactory` | Optional `DocumentHtmlFactory` that replaces the default document markup, typically `createDefaultDocumentHtmlFactory({ timeZone, theme })` from `/config` with the shop's CSS and watermark (see "Layout, logo, payment terms and shop theme"). Must be a function. |
|
|
2347
2470
|
| `loadEnvFile` | Default `true`: calls `loadEnv(NODE_ENV \|\| "development", process.cwd())`. Pass `false` when the environment is already complete (tests, isolated child processes). |
|
|
2348
2471
|
|
|
@@ -2382,4 +2505,6 @@ Not configurable on purpose: the plugin order (base first), the Redis event
|
|
|
2382
2505
|
bus job policy (3 attempts, exponential backoff from 1 s), S3 cache defaults
|
|
2383
2506
|
(15 min cleanup, 1 h TTL, absolute expiration), Stripe immediate capture with
|
|
2384
2507
|
automatic payment methods, the 24 h session lifetime, Admin path `/app`,
|
|
2385
|
-
consignment reminders due on day 10,
|
|
2508
|
+
consignment reminders due on day 10, the Documents module always being part of the base, and
|
|
2509
|
+
`http.authVerificationsPerActor.customer` (a getter that follows the E-Mail `customer_verification` toggle, see
|
|
2510
|
+
"Kontobestätigung per E-Mail").
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory copy of the effective `customer_verification` toggle for the one
|
|
3
|
+
* place that cannot await it: Medusa reads
|
|
4
|
+
* `projectConfig.http.authVerificationsPerActor.customer` synchronously on
|
|
5
|
+
* every login. The shop preset puts `customerVerificationActors()` behind a
|
|
6
|
+
* getter there, so a toggle change in the Admin takes effect without a
|
|
7
|
+
* restart.
|
|
8
|
+
*
|
|
9
|
+
* - Boot: `startCustomerVerificationSnapshot` loads the toggle once.
|
|
10
|
+
* - Afterwards an unref'd timer refreshes every 30 s, so a change reaches an
|
|
11
|
+
* idle instance too. A read that finds the copy older than 30 s (a blocked
|
|
12
|
+
* timer, say) also starts one refresh in the background
|
|
13
|
+
* (stale-while-revalidate) and still answers from the copy. A change thus
|
|
14
|
+
* reaches a running instance within about 30 s plus the duration of the
|
|
15
|
+
* read.
|
|
16
|
+
* - A failed read keeps the last value (initially "off") and is logged; the
|
|
17
|
+
* next attempt waits another 30 s.
|
|
18
|
+
*
|
|
19
|
+
* The state lives on `globalThis`: the preset (`dist`) and the Medusa-loaded
|
|
20
|
+
* plugin code (`.medusa/server`) are compiled separately and would otherwise
|
|
21
|
+
* each hold their own copy. Login is not on the cart path.
|
|
22
|
+
*/
|
|
23
|
+
export declare const CUSTOMER_VERIFICATION_REFRESH_MS = 30000;
|
|
24
|
+
export type CustomerVerificationActor = Readonly<{
|
|
25
|
+
auth_provider: string;
|
|
26
|
+
entity_type: string;
|
|
27
|
+
}>;
|
|
28
|
+
/** Reads the toggle once; never rejects. Concurrent calls share one read. */
|
|
29
|
+
export declare const refreshCustomerVerificationSnapshot: () => Promise<void>;
|
|
30
|
+
/** Stops the periodic refresh (application shutdown). The value stays. */
|
|
31
|
+
export declare const stopCustomerVerificationSnapshot: () => void;
|
|
32
|
+
/**
|
|
33
|
+
* Registers the reader, loads the toggle once and keeps it fresh every 30 s
|
|
34
|
+
* (application start). `read` returns the effective toggle; `warn` is the
|
|
35
|
+
* container logger. Starting again replaces the reader and the timer.
|
|
36
|
+
*/
|
|
37
|
+
export declare const startCustomerVerificationSnapshot: (input: Readonly<{
|
|
38
|
+
read: () => Promise<boolean>;
|
|
39
|
+
warn: (message: string) => void;
|
|
40
|
+
}>) => Promise<void>;
|
|
41
|
+
/** Synchronous; starts a background refresh when the copy is stale. Never throws. */
|
|
42
|
+
export declare const isCustomerVerificationEnabled: () => boolean;
|
|
43
|
+
/**
|
|
44
|
+
* The value of `authVerificationsPerActor.customer`: Medusa's e-mail
|
|
45
|
+
* verification for the `emailpass` provider while the toggle is on, none
|
|
46
|
+
* while it is off. A fresh array per call.
|
|
47
|
+
*/
|
|
48
|
+
export declare const customerVerificationActors: () => CustomerVerificationActor[];
|
|
49
|
+
/**
|
|
50
|
+
* Test hook: sets the value and counts as just refreshed, so it holds for
|
|
51
|
+
* 30 s without a reader; `null` forgets reader and value.
|
|
52
|
+
*/
|
|
53
|
+
export declare const setCustomerVerificationEnabledForTests: (enabled: boolean | null) => void;
|
|
@@ -0,0 +1,143 @@
|
|
|
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;
|
|
@@ -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", "user.invite"];
|
|
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", "user.invite", "auth.verification"];
|
|
3
3
|
export declare const EmailKindSchema: z.ZodEnum<{
|
|
4
4
|
"order.received": "order.received";
|
|
5
5
|
"order.received.admin": "order.received.admin";
|
|
@@ -11,5 +11,13 @@ export declare const EmailKindSchema: z.ZodEnum<{
|
|
|
11
11
|
"auth.password_reset": "auth.password_reset";
|
|
12
12
|
"affiliate.consignment_report_due": "affiliate.consignment_report_due";
|
|
13
13
|
"user.invite": "user.invite";
|
|
14
|
+
"auth.verification": "auth.verification";
|
|
14
15
|
}>;
|
|
15
16
|
export type EmailKind = (typeof EMAIL_KINDS)[number];
|
|
17
|
+
/**
|
|
18
|
+
* Kinds whose link carries a one-time token that is never persisted: the
|
|
19
|
+
* subscriber builds the mail from the event, so neither the generic retry
|
|
20
|
+
* job, the automatic dispatch nor an Admin resend may touch them.
|
|
21
|
+
*/
|
|
22
|
+
export declare const EPHEMERAL_EMAIL_KINDS: readonly ["auth.password_reset", "auth.verification"];
|
|
23
|
+
export declare const isEphemeralEmailKind: (kind: EmailKind) => boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EmailKindSchema = exports.EMAIL_KINDS = void 0;
|
|
3
|
+
exports.isEphemeralEmailKind = exports.EPHEMERAL_EMAIL_KINDS = exports.EmailKindSchema = exports.EMAIL_KINDS = void 0;
|
|
4
4
|
const zod_1 = require("@medusajs/framework/zod");
|
|
5
5
|
exports.EMAIL_KINDS = [
|
|
6
6
|
"order.received",
|
|
@@ -13,5 +13,17 @@ exports.EMAIL_KINDS = [
|
|
|
13
13
|
"auth.password_reset",
|
|
14
14
|
"affiliate.consignment_report_due",
|
|
15
15
|
"user.invite",
|
|
16
|
+
"auth.verification",
|
|
16
17
|
];
|
|
17
18
|
exports.EmailKindSchema = zod_1.z.enum(exports.EMAIL_KINDS);
|
|
19
|
+
/**
|
|
20
|
+
* Kinds whose link carries a one-time token that is never persisted: the
|
|
21
|
+
* subscriber builds the mail from the event, so neither the generic retry
|
|
22
|
+
* job, the automatic dispatch nor an Admin resend may touch them.
|
|
23
|
+
*/
|
|
24
|
+
exports.EPHEMERAL_EMAIL_KINDS = [
|
|
25
|
+
"auth.password_reset",
|
|
26
|
+
"auth.verification",
|
|
27
|
+
];
|
|
28
|
+
const isEphemeralEmailKind = (kind) => exports.EPHEMERAL_EMAIL_KINDS.includes(kind);
|
|
29
|
+
exports.isEphemeralEmailKind = isEphemeralEmailKind;
|
|
@@ -49,6 +49,14 @@ export type ShopEmailConfiguration = Readonly<{
|
|
|
49
49
|
passwordResetUrl: (input: Readonly<{
|
|
50
50
|
locale: string | null;
|
|
51
51
|
}>) => string;
|
|
52
|
+
/**
|
|
53
|
+
* Storefront page that confirms an account's e-mail address; the mail
|
|
54
|
+
* appends `#token=<token>`. Only needed while the E-Mail plugin's
|
|
55
|
+
* `customer_verification` feature is used; a mail cannot be built without it.
|
|
56
|
+
*/
|
|
57
|
+
verifyAccountUrl?: (input: Readonly<{
|
|
58
|
+
locale: string | null;
|
|
59
|
+
}>) => string;
|
|
52
60
|
renderers?: Partial<EmailRendererMap>;
|
|
53
61
|
/**
|
|
54
62
|
* IANA time zone of dates in the default templates (e.g. the order time in
|
|
@@ -363,6 +363,9 @@ export declare const EmailPersistedDataSchemas: {
|
|
|
363
363
|
locale: z.ZodNullable<z.ZodString>;
|
|
364
364
|
}, z.core.$strict>;
|
|
365
365
|
readonly "user.invite": z.ZodObject<{}, z.core.$strict>;
|
|
366
|
+
readonly "auth.verification": z.ZodObject<{
|
|
367
|
+
locale: z.ZodNullable<z.ZodString>;
|
|
368
|
+
}, z.core.$strict>;
|
|
366
369
|
};
|
|
367
370
|
export declare const EmailRenderDataSchemas: {
|
|
368
371
|
readonly "auth.password_reset": z.ZodObject<{
|
|
@@ -374,6 +377,10 @@ export declare const EmailRenderDataSchemas: {
|
|
|
374
377
|
invite_url: z.ZodString;
|
|
375
378
|
expires_at: z.ZodOptional<z.ZodString>;
|
|
376
379
|
}, z.core.$strict>;
|
|
380
|
+
readonly "auth.verification": z.ZodObject<{
|
|
381
|
+
locale: z.ZodNullable<z.ZodString>;
|
|
382
|
+
verify_url: z.ZodString;
|
|
383
|
+
}, z.core.$strict>;
|
|
377
384
|
readonly "order.received": z.ZodObject<{
|
|
378
385
|
order_id: z.ZodString;
|
|
379
386
|
summary: z.ZodOptional<z.ZodObject<{
|
|
@@ -601,6 +608,8 @@ export type EmailEphemeralRenderContextMap = {
|
|
|
601
608
|
}> : Kind extends "user.invite" ? Readonly<{
|
|
602
609
|
invite_url: string;
|
|
603
610
|
expires_at?: string;
|
|
611
|
+
}> : Kind extends "auth.verification" ? Readonly<{
|
|
612
|
+
verify_url: string;
|
|
604
613
|
}> : EmptyRenderContext;
|
|
605
614
|
};
|
|
606
615
|
export type EmailRenderDataMap = {
|
|
@@ -215,6 +215,11 @@ exports.EmailPersistedDataSchemas = {
|
|
|
215
215
|
})
|
|
216
216
|
.strict(),
|
|
217
217
|
"user.invite": zod_1.z.object({}).strict(),
|
|
218
|
+
"auth.verification": zod_1.z
|
|
219
|
+
.object({
|
|
220
|
+
locale: NullableLocaleSchema,
|
|
221
|
+
})
|
|
222
|
+
.strict(),
|
|
218
223
|
};
|
|
219
224
|
exports.EmailRenderDataSchemas = {
|
|
220
225
|
...exports.EmailPersistedDataSchemas,
|
|
@@ -228,4 +233,7 @@ exports.EmailRenderDataSchemas = {
|
|
|
228
233
|
/** When the invite expires (ISO 8601), from the current invite. */
|
|
229
234
|
expires_at: zod_1.z.string().datetime().optional(),
|
|
230
235
|
}),
|
|
236
|
+
"auth.verification": exports.EmailPersistedDataSchemas["auth.verification"].extend({
|
|
237
|
+
verify_url: zod_1.z.string().url(),
|
|
238
|
+
}),
|
|
231
239
|
};
|