@stamhoofd/models 2.39.0 → 2.40.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/dist/src/factories/AddressFactory.d.ts +3 -4
- package/dist/src/factories/AddressFactory.d.ts.map +1 -1
- package/dist/src/factories/AddressFactory.js +13 -13
- package/dist/src/factories/EmergencyContactFactory.d.ts +3 -4
- package/dist/src/factories/EmergencyContactFactory.d.ts.map +1 -1
- package/dist/src/factories/EmergencyContactFactory.js +27 -27
- package/dist/src/factories/EmergencyContactFactory.js.map +1 -1
- package/dist/src/factories/GroupFactory.d.ts +4 -4
- package/dist/src/factories/GroupFactory.d.ts.map +1 -1
- package/dist/src/factories/GroupFactory.js +8 -8
- package/dist/src/factories/GroupFactory.js.map +1 -1
- package/dist/src/factories/MemberFactory.d.ts +4 -4
- package/dist/src/factories/MemberFactory.d.ts.map +1 -1
- package/dist/src/factories/MemberFactory.js +17 -17
- package/dist/src/factories/MemberFactory.js.map +1 -1
- package/dist/src/factories/OrganizationFactory.d.ts +4 -4
- package/dist/src/factories/OrganizationFactory.js +8 -8
- package/dist/src/factories/OrganizationFactory.js.map +1 -1
- package/dist/src/factories/ParentFactory.d.ts +1 -1
- package/dist/src/factories/ParentFactory.js +19 -19
- package/dist/src/factories/ParentFactory.js.map +1 -1
- package/dist/src/factories/RecordFactory.d.ts +2 -3
- package/dist/src/factories/RecordFactory.d.ts.map +1 -1
- package/dist/src/factories/RecordFactory.js +1 -1
- package/dist/src/factories/RecordFactory.js.map +1 -1
- package/dist/src/factories/RegisterCodeFactory.d.ts +2 -2
- package/dist/src/factories/RegisterCodeFactory.d.ts.map +1 -1
- package/dist/src/factories/RegisterCodeFactory.js +2 -2
- package/dist/src/factories/RegistrationFactory.d.ts +3 -3
- package/dist/src/factories/RegistrationFactory.d.ts.map +1 -1
- package/dist/src/factories/RegistrationFactory.js.map +1 -1
- package/dist/src/factories/RegistrationPeriodFactory.d.ts +2 -2
- package/dist/src/factories/RegistrationPeriodFactory.js.map +1 -1
- package/dist/src/factories/UserFactory.d.ts +3 -3
- package/dist/src/factories/UserFactory.d.ts.map +1 -1
- package/dist/src/factories/UserFactory.js +3 -3
- package/dist/src/factories/UserFactory.js.map +1 -1
- package/dist/src/factories/WebshopFactory.d.ts +4 -4
- package/dist/src/factories/WebshopFactory.d.ts.map +1 -1
- package/dist/src/factories/WebshopFactory.js +1 -1
- package/dist/src/factories/WebshopFactory.js.map +1 -1
- package/dist/src/helpers/DNSValidator.d.ts +1 -1
- package/dist/src/helpers/DNSValidator.d.ts.map +1 -1
- package/dist/src/helpers/DNSValidator.js +33 -33
- package/dist/src/helpers/DNSValidator.js.map +1 -1
- package/dist/src/helpers/EmailBuilder.d.ts +10 -10
- package/dist/src/helpers/EmailBuilder.d.ts.map +1 -1
- package/dist/src/helpers/EmailBuilder.js +34 -34
- package/dist/src/helpers/EmailBuilder.js.map +1 -1
- package/dist/src/helpers/GroupBuilder.d.ts.map +1 -1
- package/dist/src/helpers/GroupBuilder.js +57 -57
- package/dist/src/helpers/GroupBuilder.js.map +1 -1
- package/dist/src/helpers/Handlebars.d.ts.map +1 -1
- package/dist/src/helpers/Handlebars.js +29 -29
- package/dist/src/helpers/Handlebars.js.map +1 -1
- package/dist/src/helpers/MemberMerger.d.ts +1 -1
- package/dist/src/helpers/MemberMerger.d.ts.map +1 -1
- package/dist/src/helpers/MemberMerger.js +33 -33
- package/dist/src/helpers/MemberMerger.js.map +1 -1
- package/dist/src/helpers/MemberMerger.test.js +194 -194
- package/dist/src/helpers/MemberMerger.test.js.map +1 -1
- package/dist/src/helpers/RateLimiter.d.ts.map +1 -1
- package/dist/src/helpers/RateLimiter.js +2 -2
- package/dist/src/helpers/RateLimiter.js.map +1 -1
- package/dist/src/helpers/SetupStepsUpdater.d.ts +22 -0
- package/dist/src/helpers/SetupStepsUpdater.d.ts.map +1 -0
- package/dist/src/helpers/SetupStepsUpdater.js +255 -0
- package/dist/src/helpers/SetupStepsUpdater.js.map +1 -0
- package/dist/src/helpers/WebshopCounter.d.ts +1 -1
- package/dist/src/helpers/WebshopCounter.d.ts.map +1 -1
- package/dist/src/helpers/WebshopCounter.js +1 -1
- package/dist/src/helpers/WebshopCounter.js.map +1 -1
- package/dist/src/helpers/WebshopCounter.test.js +6 -6
- package/dist/src/helpers/WebshopCounter.test.js.map +1 -1
- package/dist/src/index.d.ts +20 -19
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/migrations/1605262045-import-postcodes.js +12 -12
- package/dist/src/migrations/1605262046-import-postcodes-nl.js +10 -10
- package/dist/src/models/BalanceItem.d.ts.map +1 -1
- package/dist/src/models/BalanceItem.js +37 -37
- package/dist/src/models/BalanceItem.js.map +1 -1
- package/dist/src/models/BalanceItemPayment.d.ts.map +1 -1
- package/dist/src/models/BalanceItemPayment.js +13 -13
- package/dist/src/models/BalanceItemPayment.js.map +1 -1
- package/dist/src/models/BuckarooPayment.d.ts +1 -1
- package/dist/src/models/BuckarooPayment.d.ts.map +1 -1
- package/dist/src/models/BuckarooPayment.js +5 -5
- package/dist/src/models/BuckarooPayment.js.map +1 -1
- package/dist/src/models/CachedOutstandingBalance.d.ts.map +1 -1
- package/dist/src/models/CachedOutstandingBalance.js +37 -37
- package/dist/src/models/CachedOutstandingBalance.js.map +1 -1
- package/dist/src/models/Document.d.ts +4 -4
- package/dist/src/models/Document.d.ts.map +1 -1
- package/dist/src/models/Document.js +27 -27
- package/dist/src/models/Document.js.map +1 -1
- package/dist/src/models/DocumentTemplate.d.ts +4 -4
- package/dist/src/models/DocumentTemplate.d.ts.map +1 -1
- package/dist/src/models/DocumentTemplate.js +72 -72
- package/dist/src/models/DocumentTemplate.js.map +1 -1
- package/dist/src/models/Email.d.ts.map +1 -1
- package/dist/src/models/Email.js +63 -64
- package/dist/src/models/Email.js.map +1 -1
- package/dist/src/models/EmailRecipient.d.ts.map +1 -1
- package/dist/src/models/EmailRecipient.js +20 -20
- package/dist/src/models/EmailRecipient.js.map +1 -1
- package/dist/src/models/EmailTemplate.d.ts +3 -3
- package/dist/src/models/EmailTemplate.d.ts.map +1 -1
- package/dist/src/models/EmailTemplate.js +16 -16
- package/dist/src/models/EmailTemplate.js.map +1 -1
- package/dist/src/models/EmailVerificationCode.d.ts +2 -2
- package/dist/src/models/EmailVerificationCode.d.ts.map +1 -1
- package/dist/src/models/EmailVerificationCode.js +57 -55
- package/dist/src/models/EmailVerificationCode.js.map +1 -1
- package/dist/src/models/Event.d.ts +2 -2
- package/dist/src/models/Event.d.ts.map +1 -1
- package/dist/src/models/Event.js +15 -15
- package/dist/src/models/Event.js.map +1 -1
- package/dist/src/models/Group.d.ts +3 -1
- package/dist/src/models/Group.d.ts.map +1 -1
- package/dist/src/models/Group.js +46 -35
- package/dist/src/models/Group.js.map +1 -1
- package/dist/src/models/Image.d.ts +1 -1
- package/dist/src/models/Image.d.ts.map +1 -1
- package/dist/src/models/Image.js +26 -26
- package/dist/src/models/Image.js.map +1 -1
- package/dist/src/models/Member.d.ts +8 -8
- package/dist/src/models/Member.d.ts.map +1 -1
- package/dist/src/models/Member.js +60 -60
- package/dist/src/models/Member.js.map +1 -1
- package/dist/src/models/MemberPlatformMembership.d.ts +3 -3
- package/dist/src/models/MemberPlatformMembership.d.ts.map +1 -1
- package/dist/src/models/MemberPlatformMembership.js +26 -26
- package/dist/src/models/MemberPlatformMembership.js.map +1 -1
- package/dist/src/models/MemberResponsibilityRecord.d.ts.map +1 -1
- package/dist/src/models/MemberResponsibilityRecord.js +13 -13
- package/dist/src/models/MemberResponsibilityRecord.js.map +1 -1
- package/dist/src/models/MergedMember.d.ts +3 -3
- package/dist/src/models/MergedMember.d.ts.map +1 -1
- package/dist/src/models/MergedMember.js +19 -19
- package/dist/src/models/MergedMember.js.map +1 -1
- package/dist/src/models/MolliePayment.d.ts +1 -1
- package/dist/src/models/MolliePayment.d.ts.map +1 -1
- package/dist/src/models/MolliePayment.js +5 -5
- package/dist/src/models/MolliePayment.js.map +1 -1
- package/dist/src/models/MollieToken.d.ts.map +1 -1
- package/dist/src/models/MollieToken.js +60 -60
- package/dist/src/models/MollieToken.js.map +1 -1
- package/dist/src/models/OneTimeToken.d.ts +2 -2
- package/dist/src/models/OneTimeToken.d.ts.map +1 -1
- package/dist/src/models/OneTimeToken.js +13 -13
- package/dist/src/models/OneTimeToken.js.map +1 -1
- package/dist/src/models/Order.d.ts +1 -1
- package/dist/src/models/Order.d.ts.map +1 -1
- package/dist/src/models/Order.js +70 -70
- package/dist/src/models/Order.js.map +1 -1
- package/dist/src/models/Organization.d.ts +5 -5
- package/dist/src/models/Organization.d.ts.map +1 -1
- package/dist/src/models/Organization.js +127 -127
- package/dist/src/models/Organization.js.map +1 -1
- package/dist/src/models/OrganizationRegistrationPeriod.d.ts.map +1 -1
- package/dist/src/models/OrganizationRegistrationPeriod.js +15 -15
- package/dist/src/models/OrganizationRegistrationPeriod.js.map +1 -1
- package/dist/src/models/PasswordToken.d.ts +3 -3
- package/dist/src/models/PasswordToken.d.ts.map +1 -1
- package/dist/src/models/PasswordToken.js +17 -17
- package/dist/src/models/PasswordToken.js.map +1 -1
- package/dist/src/models/PayconiqPayment.d.ts +1 -1
- package/dist/src/models/PayconiqPayment.d.ts.map +1 -1
- package/dist/src/models/PayconiqPayment.js +49 -49
- package/dist/src/models/PayconiqPayment.js.map +1 -1
- package/dist/src/models/Payment.d.ts +3 -3
- package/dist/src/models/Payment.d.ts.map +1 -1
- package/dist/src/models/Payment.js +36 -36
- package/dist/src/models/Payment.js.map +1 -1
- package/dist/src/models/Platform.d.ts +2 -2
- package/dist/src/models/Platform.d.ts.map +1 -1
- package/dist/src/models/Platform.js +8 -8
- package/dist/src/models/Platform.js.map +1 -1
- package/dist/src/models/RegisterCode.d.ts +1 -1
- package/dist/src/models/RegisterCode.d.ts.map +1 -1
- package/dist/src/models/RegisterCode.js +11 -11
- package/dist/src/models/RegisterCode.js.map +1 -1
- package/dist/src/models/Registration.d.ts +1 -1
- package/dist/src/models/Registration.d.ts.map +1 -1
- package/dist/src/models/Registration.js +88 -88
- package/dist/src/models/Registration.js.map +1 -1
- package/dist/src/models/RegistrationPeriod.d.ts.map +1 -1
- package/dist/src/models/RegistrationPeriod.js +12 -12
- package/dist/src/models/RegistrationPeriod.js.map +1 -1
- package/dist/src/models/STCredit.d.ts +1 -1
- package/dist/src/models/STCredit.d.ts.map +1 -1
- package/dist/src/models/STCredit.js +12 -12
- package/dist/src/models/STCredit.js.map +1 -1
- package/dist/src/models/STInvoice.d.ts +1 -1
- package/dist/src/models/STInvoice.d.ts.map +1 -1
- package/dist/src/models/STInvoice.js +16 -16
- package/dist/src/models/STInvoice.js.map +1 -1
- package/dist/src/models/STPackage.d.ts +1 -1
- package/dist/src/models/STPackage.d.ts.map +1 -1
- package/dist/src/models/STPackage.js +39 -39
- package/dist/src/models/STPackage.js.map +1 -1
- package/dist/src/models/STPendingInvoice.d.ts +1 -1
- package/dist/src/models/STPendingInvoice.d.ts.map +1 -1
- package/dist/src/models/STPendingInvoice.js +11 -11
- package/dist/src/models/STPendingInvoice.js.map +1 -1
- package/dist/src/models/StripeAccount.d.ts.map +1 -1
- package/dist/src/models/StripeAccount.js +13 -13
- package/dist/src/models/StripeAccount.js.map +1 -1
- package/dist/src/models/StripeCheckoutSession.d.ts +1 -1
- package/dist/src/models/StripeCheckoutSession.d.ts.map +1 -1
- package/dist/src/models/StripeCheckoutSession.js +7 -7
- package/dist/src/models/StripeCheckoutSession.js.map +1 -1
- package/dist/src/models/StripePaymentIntent.d.ts +1 -1
- package/dist/src/models/StripePaymentIntent.d.ts.map +1 -1
- package/dist/src/models/StripePaymentIntent.js +7 -7
- package/dist/src/models/StripePaymentIntent.js.map +1 -1
- package/dist/src/models/Ticket.d.ts +2 -2
- package/dist/src/models/Ticket.d.ts.map +1 -1
- package/dist/src/models/Ticket.js +23 -23
- package/dist/src/models/Ticket.js.map +1 -1
- package/dist/src/models/Token.d.ts +3 -3
- package/dist/src/models/Token.d.ts.map +1 -1
- package/dist/src/models/Token.js +27 -27
- package/dist/src/models/Token.js.map +1 -1
- package/dist/src/models/Token.test.js +11 -11
- package/dist/src/models/UsedRegisterCode.d.ts +1 -1
- package/dist/src/models/UsedRegisterCode.d.ts.map +1 -1
- package/dist/src/models/UsedRegisterCode.js +10 -10
- package/dist/src/models/UsedRegisterCode.js.map +1 -1
- package/dist/src/models/User.d.ts +4 -4
- package/dist/src/models/User.d.ts.map +1 -1
- package/dist/src/models/User.js +53 -51
- package/dist/src/models/User.js.map +1 -1
- package/dist/src/models/UserPermissions.d.ts +3 -3
- package/dist/src/models/UserPermissions.d.ts.map +1 -1
- package/dist/src/models/UserPermissions.js +12 -12
- package/dist/src/models/UserPermissions.js.map +1 -1
- package/dist/src/models/Webshop.d.ts +1 -1
- package/dist/src/models/Webshop.d.ts.map +1 -1
- package/dist/src/models/Webshop.js +23 -23
- package/dist/src/models/Webshop.js.map +1 -1
- package/dist/src/models/WebshopDiscountCode.d.ts +1 -1
- package/dist/src/models/WebshopDiscountCode.d.ts.map +1 -1
- package/dist/src/models/WebshopDiscountCode.js +16 -16
- package/dist/src/models/WebshopDiscountCode.js.map +1 -1
- package/dist/src/models/addresses/City.d.ts.map +1 -1
- package/dist/src/models/addresses/City.js +9 -9
- package/dist/src/models/addresses/City.js.map +1 -1
- package/dist/src/models/addresses/PostalCode.d.ts.map +1 -1
- package/dist/src/models/addresses/PostalCode.js +11 -11
- package/dist/src/models/addresses/PostalCode.js.map +1 -1
- package/dist/src/models/addresses/PostalCode.test.js +22 -22
- package/dist/src/models/addresses/PostalCode.test.js.map +1 -1
- package/dist/src/models/addresses/Province.d.ts.map +1 -1
- package/dist/src/models/addresses/Province.js +5 -5
- package/dist/src/models/addresses/Province.js.map +1 -1
- package/dist/src/models/addresses/Street.d.ts.map +1 -1
- package/dist/src/models/addresses/Street.js +6 -6
- package/dist/src/models/addresses/Street.js.map +1 -1
- package/dist/src/models/index.d.ts +46 -46
- package/dist/src/models/index.d.ts.map +1 -1
- package/dist/src/models/index.js +0 -1
- package/dist/src/models/index.js.map +1 -1
- package/dist/src/structures/OrganizationServerMetaData.d.ts.map +1 -1
- package/dist/src/structures/OrganizationServerMetaData.js +4 -4
- package/dist/src/structures/OrganizationServerMetaData.js.map +1 -1
- package/dist/tests/jest.global.setup.d.ts.map +1 -1
- package/dist/tests/jest.global.setup.js +15 -13
- package/dist/tests/jest.global.setup.js.map +1 -1
- package/dist/tests/jest.setup.js +3 -1
- package/dist/tests/jest.setup.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +3 -3
- package/src/factories/AddressFactory.ts +17 -17
- package/src/factories/EmergencyContactFactory.ts +30 -31
- package/src/factories/GroupFactory.ts +30 -30
- package/src/factories/MemberFactory.ts +41 -38
- package/src/factories/OrganizationFactory.ts +15 -15
- package/src/factories/ParentFactory.ts +24 -24
- package/src/factories/RecordFactory.ts +5 -4
- package/src/factories/RegisterCodeFactory.ts +7 -7
- package/src/factories/RegistrationFactory.ts +16 -16
- package/src/factories/RegistrationPeriodFactory.ts +5 -5
- package/src/factories/UserFactory.ts +20 -19
- package/src/factories/WebshopFactory.ts +14 -14
- package/src/helpers/DNSValidator.ts +89 -84
- package/src/helpers/EmailBuilder.ts +141 -135
- package/src/helpers/GroupBuilder.ts +181 -181
- package/src/helpers/Handlebars.ts +57 -54
- package/src/helpers/MemberMerger.test.ts +702 -702
- package/src/helpers/MemberMerger.ts +83 -77
- package/src/helpers/RateLimiter.ts +25 -27
- package/src/helpers/SetupStepsUpdater.ts +402 -0
- package/src/helpers/WebshopCounter.test.ts +12 -12
- package/src/helpers/WebshopCounter.ts +20 -19
- package/src/index.ts +20 -19
- package/src/migrations/1605262045-import-postcodes.ts +59 -63
- package/src/migrations/1605262046-import-postcodes-nl.ts +41 -43
- package/src/models/BalanceItem.ts +173 -172
- package/src/models/BalanceItemPayment.ts +32 -33
- package/src/models/BuckarooPayment.ts +7 -7
- package/src/models/CachedOutstandingBalance.ts +98 -99
- package/src/models/Document.ts +90 -87
- package/src/models/DocumentTemplate.ts +207 -198
- package/src/models/Email.ts +198 -200
- package/src/models/EmailRecipient.ts +38 -39
- package/src/models/EmailTemplate.ts +36 -37
- package/src/models/EmailVerificationCode.ts +146 -142
- package/src/models/Event.ts +53 -53
- package/src/models/Group.ts +136 -123
- package/src/models/Image.ts +48 -48
- package/src/models/Member.ts +277 -275
- package/src/models/MemberPlatformMembership.ts +71 -71
- package/src/models/MemberResponsibilityRecord.ts +32 -32
- package/src/models/MergedMember.ts +77 -77
- package/src/models/MolliePayment.ts +7 -7
- package/src/models/MollieToken.ts +131 -126
- package/src/models/OneTimeToken.ts +40 -39
- package/src/models/Order.ts +379 -372
- package/src/models/Organization.ts +332 -325
- package/src/models/OrganizationRegistrationPeriod.ts +50 -50
- package/src/models/PasswordToken.ts +42 -42
- package/src/models/PayconiqPayment.ts +80 -76
- package/src/models/Payment.ts +86 -86
- package/src/models/Platform.ts +21 -22
- package/src/models/RegisterCode.ts +26 -26
- package/src/models/Registration.ts +167 -168
- package/src/models/RegistrationPeriod.ts +29 -29
- package/src/models/STCredit.ts +24 -25
- package/src/models/STInvoice.ts +34 -34
- package/src/models/STPackage.ts +143 -136
- package/src/models/STPendingInvoice.ts +26 -26
- package/src/models/StripeAccount.ts +27 -27
- package/src/models/StripeCheckoutSession.ts +10 -10
- package/src/models/StripePaymentIntent.ts +10 -10
- package/src/models/Ticket.ts +51 -52
- package/src/models/Token.test.ts +13 -13
- package/src/models/Token.ts +64 -63
- package/src/models/UsedRegisterCode.ts +20 -21
- package/src/models/User.ts +148 -144
- package/src/models/UserPermissions.ts +25 -28
- package/src/models/Webshop.ts +53 -53
- package/src/models/WebshopDiscountCode.ts +33 -33
- package/src/models/addresses/City.ts +12 -12
- package/src/models/addresses/PostalCode.test.ts +68 -69
- package/src/models/addresses/PostalCode.ts +57 -57
- package/src/models/addresses/Province.ts +8 -8
- package/src/models/addresses/Street.ts +10 -12
- package/src/models/index.ts +54 -55
- package/src/structures/OrganizationServerMetaData.ts +36 -36
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { Email, EmailAddress, EmailBuilder } from
|
|
2
|
-
import { EmailTemplateType, OrganizationEmail, Recipient, Replacement } from
|
|
3
|
-
import { Formatter } from
|
|
1
|
+
import { Email, EmailAddress, EmailBuilder } from '@stamhoofd/email';
|
|
2
|
+
import { EmailTemplateType, OrganizationEmail, Recipient, Replacement } from '@stamhoofd/structures';
|
|
3
|
+
import { Formatter } from '@stamhoofd/utility';
|
|
4
4
|
|
|
5
|
-
import { SimpleError } from
|
|
6
|
-
import { EmailTemplate, Group, Organization, Platform, User, Webshop } from
|
|
7
|
-
import { I18n } from
|
|
5
|
+
import { SimpleError } from '@simonbackx/simple-errors';
|
|
6
|
+
import { EmailTemplate, Group, Organization, Platform, User, Webshop } from '../models';
|
|
7
|
+
import { I18n } from '@stamhoofd/backend-i18n';
|
|
8
8
|
|
|
9
9
|
export type EmailTemplateOptions = {
|
|
10
|
-
type: EmailTemplateType
|
|
11
|
-
webshop?: Webshop | null
|
|
12
|
-
group?: Group | null
|
|
13
|
-
organizationId?: string | null
|
|
14
|
-
}
|
|
10
|
+
type: EmailTemplateType;
|
|
11
|
+
webshop?: Webshop | null;
|
|
12
|
+
group?: Group | null;
|
|
13
|
+
organizationId?: string | null;
|
|
14
|
+
};
|
|
15
15
|
|
|
16
16
|
export async function getEmailTemplate(data: EmailTemplateOptions) {
|
|
17
17
|
// Most specific template: for specific group
|
|
18
18
|
const q = EmailTemplate.select()
|
|
19
|
-
.where('type', data.type)
|
|
19
|
+
.where('type', data.type);
|
|
20
20
|
|
|
21
21
|
if (data.group) {
|
|
22
|
-
q.where('groupId', data.group.id)
|
|
22
|
+
q.where('groupId', data.group.id);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
if (data.organizationId) {
|
|
26
|
-
q.where('organizationId', data.organizationId)
|
|
26
|
+
q.where('organizationId', data.organizationId);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (data.webshop) {
|
|
30
|
-
q.where('webshopId', data.webshop.id)
|
|
30
|
+
q.where('webshopId', data.webshop.id);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
let templates = await q.limit(1).fetch()
|
|
34
|
-
|
|
33
|
+
let templates = await q.limit(1).fetch();
|
|
34
|
+
|
|
35
35
|
// Specific for organization
|
|
36
36
|
if (templates.length == 0 && (data.group?.id || data.webshop?.id) && data.organizationId) {
|
|
37
37
|
templates = await EmailTemplate.select()
|
|
@@ -40,7 +40,7 @@ export async function getEmailTemplate(data: EmailTemplateOptions) {
|
|
|
40
40
|
.where('groupId', null)
|
|
41
41
|
.where('webshopId', null)
|
|
42
42
|
.limit(1)
|
|
43
|
-
.fetch()
|
|
43
|
+
.fetch();
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
// Default for platform
|
|
@@ -51,176 +51,181 @@ export async function getEmailTemplate(data: EmailTemplateOptions) {
|
|
|
51
51
|
.where('groupId', null)
|
|
52
52
|
.where('webshopId', null)
|
|
53
53
|
.limit(1)
|
|
54
|
-
.fetch()
|
|
54
|
+
.fetch();
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
if (templates.length == 0) {
|
|
58
|
-
console.error(
|
|
59
|
-
return
|
|
58
|
+
console.error('Could not find email template for type ' + data.type);
|
|
59
|
+
return;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
return templates[0]
|
|
62
|
+
return templates[0];
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
export async function getDefaultEmailFrom(organization: Organization|null, options: Pick<EmailBuilderOptions,
|
|
65
|
+
export async function getDefaultEmailFrom(organization: Organization | null, options: Pick<EmailBuilderOptions, 'type'> & { template: Omit<EmailTemplateOptions, 'organizationId' | 'type'> }) {
|
|
66
66
|
// When choosing sending domain, prefer using the one with the highest reputation
|
|
67
67
|
let preferEmailId: string | null = null;
|
|
68
68
|
|
|
69
69
|
if (options.template.group) {
|
|
70
|
-
preferEmailId = options.template.group.privateSettings.defaultEmailId
|
|
70
|
+
preferEmailId = options.template.group.privateSettings.defaultEmailId;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
if (options.template.webshop) {
|
|
74
|
-
preferEmailId = options.template.webshop.privateMeta.defaultEmailId
|
|
74
|
+
preferEmailId = options.template.webshop.privateMeta.defaultEmailId;
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
|
|
77
77
|
if (organization) {
|
|
78
78
|
// Default email address for the chosen email type
|
|
79
79
|
let from = organization.getDefaultFrom(organization.i18n, false, options.type ?? 'broadcast');
|
|
80
80
|
|
|
81
81
|
const sender: OrganizationEmail | undefined = (preferEmailId ? organization.privateMeta.emails.find(e => e.id === preferEmailId) : null) ?? organization.privateMeta.emails.find(e => e.default) ?? organization.privateMeta.emails[0];
|
|
82
|
-
let replyTo: string | undefined = undefined
|
|
82
|
+
let replyTo: string | undefined = undefined;
|
|
83
83
|
|
|
84
84
|
if (sender) {
|
|
85
|
-
replyTo = sender.email
|
|
85
|
+
replyTo = sender.email;
|
|
86
86
|
|
|
87
87
|
// Can we send from this e-mail or reply-to?
|
|
88
|
-
if (replyTo && organization.privateMeta.mailDomain && organization.privateMeta.mailDomainActive && sender.email.endsWith(
|
|
89
|
-
from = sender.email
|
|
90
|
-
replyTo = undefined
|
|
88
|
+
if (replyTo && organization.privateMeta.mailDomain && organization.privateMeta.mailDomainActive && sender.email.endsWith('@' + organization.privateMeta.mailDomain)) {
|
|
89
|
+
from = sender.email;
|
|
90
|
+
replyTo = undefined;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// Include name in form field
|
|
94
94
|
if (sender.name) {
|
|
95
|
-
from = '"'+sender.name.replaceAll("
|
|
96
|
-
}
|
|
97
|
-
|
|
95
|
+
from = '"' + sender.name.replaceAll('"', '\\"') + '" <' + from + '>';
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
from = '"' + organization.name.replaceAll('"', '\\"') + '" <' + from + '>';
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
if (replyTo) {
|
|
101
102
|
if (sender.name) {
|
|
102
|
-
replyTo = '"'+sender.name.replaceAll("
|
|
103
|
-
}
|
|
104
|
-
|
|
103
|
+
replyTo = '"' + sender.name.replaceAll('"', '\\"') + '" <' + replyTo + '>';
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
replyTo = '"' + organization.name.replaceAll('"', '\\"') + '" <' + replyTo + '>';
|
|
105
107
|
}
|
|
106
108
|
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
from = '"' + organization.name.replaceAll('"', '\\"') + '" <' + from + '>';
|
|
109
112
|
}
|
|
110
113
|
|
|
111
114
|
return {
|
|
112
|
-
from, replyTo
|
|
113
|
-
}
|
|
115
|
+
from, replyTo,
|
|
116
|
+
};
|
|
114
117
|
}
|
|
115
118
|
|
|
116
|
-
const platform = await Platform.getSharedPrivateStruct()
|
|
119
|
+
const platform = await Platform.getSharedPrivateStruct();
|
|
117
120
|
|
|
118
121
|
// Default e-mail if no email addresses are configured
|
|
119
|
-
const i18n = new I18n(
|
|
120
|
-
const transactionalDomain = i18n.localizedDomains.defaultTransactionalEmail()
|
|
121
|
-
const broadcastDomain = i18n.localizedDomains.defaultBroadcastEmail()
|
|
122
|
-
const domain = (options.type === 'transactional' ?transactionalDomain : broadcastDomain)
|
|
123
|
-
let from = 'hallo@' + domain
|
|
124
|
-
|
|
122
|
+
const i18n = new I18n('nl', 'BE');
|
|
123
|
+
const transactionalDomain = i18n.localizedDomains.defaultTransactionalEmail();
|
|
124
|
+
const broadcastDomain = i18n.localizedDomains.defaultBroadcastEmail();
|
|
125
|
+
const domain = (options.type === 'transactional' ? transactionalDomain : broadcastDomain);
|
|
126
|
+
let from = 'hallo@' + domain;
|
|
127
|
+
|
|
125
128
|
// Platform
|
|
126
129
|
const sender: OrganizationEmail | undefined = (preferEmailId ? platform.privateConfig.emails.find(e => e.id === preferEmailId) : null) ?? platform.privateConfig.emails.find(e => e.default) ?? platform.privateConfig.emails[0];
|
|
127
|
-
let replyTo: string | undefined = undefined
|
|
130
|
+
let replyTo: string | undefined = undefined;
|
|
128
131
|
|
|
129
132
|
if (sender) {
|
|
130
|
-
replyTo = sender.email
|
|
133
|
+
replyTo = sender.email;
|
|
131
134
|
|
|
132
135
|
// Are we allowed to send an e-mail from this domain?
|
|
133
|
-
if (sender.email.endsWith(
|
|
136
|
+
if (sender.email.endsWith('@' + transactionalDomain) || sender.email.endsWith('@' + broadcastDomain)) {
|
|
134
137
|
// Allowed to send from
|
|
135
|
-
from = sender.email
|
|
136
|
-
replyTo = undefined
|
|
138
|
+
from = sender.email;
|
|
139
|
+
replyTo = undefined;
|
|
137
140
|
}
|
|
138
141
|
|
|
139
142
|
// Include name in form field
|
|
140
143
|
if (sender.name) {
|
|
141
|
-
from = '"'+sender.name.replaceAll("
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
+
from = '"' + sender.name.replaceAll('"', '\\"') + '" <' + from + '>';
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
from = '"' + platform.config.name.replaceAll('"', '\\"') + '" <' + from + '>';
|
|
144
148
|
}
|
|
145
149
|
|
|
146
150
|
if (replyTo) {
|
|
147
151
|
if (sender.name) {
|
|
148
|
-
replyTo = '"'+sender.name.replaceAll("
|
|
149
|
-
}
|
|
150
|
-
|
|
152
|
+
replyTo = '"' + sender.name.replaceAll('"', '\\"') + '" <' + replyTo + '>';
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
replyTo = '"' + platform.config.name.replaceAll('"', '\\"') + '" <' + replyTo + '>';
|
|
151
156
|
}
|
|
152
157
|
}
|
|
153
|
-
}
|
|
154
|
-
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
from = '"' + platform.config.name.replaceAll('"', '\\"') + '" <' + from + '>';
|
|
155
161
|
}
|
|
156
162
|
|
|
157
163
|
return {
|
|
158
|
-
from, replyTo
|
|
159
|
-
}
|
|
164
|
+
from, replyTo,
|
|
165
|
+
};
|
|
160
166
|
}
|
|
161
167
|
|
|
162
|
-
|
|
163
|
-
export async function sendEmailTemplate(organization: Organization|null, options: Omit<EmailBuilderOptions, "subject" | "html" | "from" | "replyTo"> & { template: Omit<EmailTemplateOptions, "organizationId"> }) {
|
|
168
|
+
export async function sendEmailTemplate(organization: Organization | null, options: Omit<EmailBuilderOptions, 'subject' | 'html' | 'from' | 'replyTo'> & { template: Omit<EmailTemplateOptions, 'organizationId'> }) {
|
|
164
169
|
if (options.template.webshop) {
|
|
165
|
-
options.defaultReplacements = [...(options.defaultReplacements ?? []), ...options.template.webshop.meta.getEmailReplacements()]
|
|
170
|
+
options.defaultReplacements = [...(options.defaultReplacements ?? []), ...options.template.webshop.meta.getEmailReplacements()];
|
|
166
171
|
}
|
|
167
172
|
const builder = await getEmailBuilderForTemplate(organization, {
|
|
168
173
|
...options,
|
|
169
|
-
...(await getDefaultEmailFrom(organization, options))
|
|
174
|
+
...(await getDefaultEmailFrom(organization, options)),
|
|
170
175
|
});
|
|
171
176
|
if (builder) {
|
|
172
|
-
Email.schedule(builder)
|
|
177
|
+
Email.schedule(builder);
|
|
173
178
|
}
|
|
174
179
|
}
|
|
175
180
|
|
|
176
|
-
export async function getEmailBuilderForTemplate(organization: Organization|null, options: Omit<EmailBuilderOptions,
|
|
181
|
+
export async function getEmailBuilderForTemplate(organization: Organization | null, options: Omit<EmailBuilderOptions, 'subject' | 'html'> & { template: Omit<EmailTemplateOptions, 'organizationId'> }) {
|
|
177
182
|
const template = await getEmailTemplate({
|
|
178
183
|
...options.template,
|
|
179
|
-
organizationId: organization?.id ?? null
|
|
180
|
-
})
|
|
184
|
+
organizationId: organization?.id ?? null,
|
|
185
|
+
});
|
|
181
186
|
|
|
182
187
|
if (!template) {
|
|
183
|
-
return undefined
|
|
188
|
+
return undefined;
|
|
184
189
|
}
|
|
185
190
|
|
|
186
191
|
return await getEmailBuilder(organization, {
|
|
187
192
|
...options,
|
|
188
193
|
subject: template.subject,
|
|
189
|
-
html: template.html
|
|
190
|
-
})
|
|
194
|
+
html: template.html,
|
|
195
|
+
});
|
|
191
196
|
}
|
|
192
197
|
|
|
193
198
|
export type EmailBuilderOptions = {
|
|
194
|
-
defaultReplacements?: Replacement[]
|
|
195
|
-
recipients: Recipient[]
|
|
196
|
-
from: string
|
|
197
|
-
replyTo?: string|null
|
|
198
|
-
subject: string
|
|
199
|
-
html: string
|
|
199
|
+
defaultReplacements?: Replacement[];
|
|
200
|
+
recipients: Recipient[];
|
|
201
|
+
from: string;
|
|
202
|
+
replyTo?: string | null;
|
|
203
|
+
subject: string;
|
|
204
|
+
html: string;
|
|
200
205
|
attachments?: {
|
|
201
206
|
filename: string;
|
|
202
207
|
content: string;
|
|
203
208
|
contentType: string | undefined;
|
|
204
209
|
encoding: string;
|
|
205
|
-
}[]
|
|
206
|
-
type?:
|
|
207
|
-
unsubscribeType?: 'all'|'marketing'
|
|
208
|
-
fromStamhoofd?: boolean
|
|
209
|
-
singleBcc?: string
|
|
210
|
-
replaceAll?: {from: string
|
|
211
|
-
callback?: (error: Error|null) => void; // for each email
|
|
212
|
-
}
|
|
210
|
+
}[];
|
|
211
|
+
type?: 'transactional' | 'broadcast';
|
|
212
|
+
unsubscribeType?: 'all' | 'marketing';
|
|
213
|
+
fromStamhoofd?: boolean;
|
|
214
|
+
singleBcc?: string;
|
|
215
|
+
replaceAll?: { from: string; to: string }[]; // replace in all e-mails, not recipient dependent
|
|
216
|
+
callback?: (error: Error | null) => void; // for each email
|
|
217
|
+
};
|
|
213
218
|
|
|
214
219
|
/**
|
|
215
220
|
* @param organization defines replacements and unsubsribe behaviour
|
|
216
221
|
*/
|
|
217
|
-
export async function getEmailBuilder(organization: Organization|null, email: EmailBuilderOptions) {
|
|
218
|
-
const platform = await Platform.getSharedStruct()
|
|
222
|
+
export async function getEmailBuilder(organization: Organization | null, email: EmailBuilderOptions) {
|
|
223
|
+
const platform = await Platform.getSharedStruct();
|
|
219
224
|
// Update recipients
|
|
220
|
-
const cleaned: Recipient[] = []
|
|
225
|
+
const cleaned: Recipient[] = [];
|
|
221
226
|
for (const recipient of email.recipients) {
|
|
222
227
|
try {
|
|
223
|
-
const unsubscribe = await EmailAddress.getOrCreate(recipient.email, email.fromStamhoofd || !organization ? null : organization.id)
|
|
228
|
+
const unsubscribe = await EmailAddress.getOrCreate(recipient.email, email.fromStamhoofd || !organization ? null : organization.id);
|
|
224
229
|
|
|
225
230
|
if (unsubscribe.unsubscribedAll || unsubscribe.hardBounce || unsubscribe.markedAsSpam || !unsubscribe.token || (unsubscribe.unsubscribedMarketing && email.unsubscribeType === 'marketing')) {
|
|
226
231
|
// Ignore
|
|
@@ -228,86 +233,87 @@ export async function getEmailBuilder(organization: Organization|null, email: Em
|
|
|
228
233
|
email.callback(
|
|
229
234
|
new SimpleError({
|
|
230
235
|
code: 'email_unsubscribed',
|
|
231
|
-
message: unsubscribe.unsubscribedAll ?
|
|
232
|
-
})
|
|
233
|
-
)
|
|
236
|
+
message: unsubscribe.unsubscribedAll ? 'Recipient has unsubscribed' : (unsubscribe.hardBounce ? 'Recipient has hard bounced' : (unsubscribe.markedAsSpam ? 'Recipient has marked as spam' : 'Recipient has unsubscribed from marketing')),
|
|
237
|
+
}),
|
|
238
|
+
);
|
|
234
239
|
}
|
|
235
|
-
continue
|
|
240
|
+
continue;
|
|
236
241
|
}
|
|
237
242
|
|
|
238
|
-
const unsubscribeUrl =
|
|
243
|
+
const unsubscribeUrl = 'https://' + STAMHOOFD.domains.dashboard + '/' + (organization ? (organization.i18n.locale + '/') : '') + 'unsubscribe?id=' + encodeURIComponent(unsubscribe.id) + '&token=' + encodeURIComponent(unsubscribe.token) + '&type=' + encodeURIComponent(email.unsubscribeType ?? 'all');
|
|
239
244
|
recipient.replacements.push(Replacement.create({
|
|
240
|
-
token:
|
|
241
|
-
value: unsubscribeUrl
|
|
242
|
-
}))
|
|
245
|
+
token: 'unsubscribeUrl',
|
|
246
|
+
value: unsubscribeUrl,
|
|
247
|
+
}));
|
|
243
248
|
|
|
244
249
|
// Override headers
|
|
245
250
|
recipient.headers = {
|
|
246
251
|
'List-Unsubscribe': `<${unsubscribeUrl}>`,
|
|
247
|
-
'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click'
|
|
248
|
-
}
|
|
249
|
-
cleaned.push(recipient)
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
+
'List-Unsubscribe-Post': 'List-Unsubscribe=One-Click',
|
|
253
|
+
};
|
|
254
|
+
cleaned.push(recipient);
|
|
255
|
+
}
|
|
256
|
+
catch (e) {
|
|
257
|
+
console.error(e);
|
|
252
258
|
}
|
|
253
259
|
}
|
|
254
|
-
email.recipients = cleaned
|
|
260
|
+
email.recipients = cleaned;
|
|
255
261
|
|
|
256
262
|
// Update recipients
|
|
257
263
|
for (const recipient of email.recipients) {
|
|
258
|
-
recipient.replacements = recipient.replacements.slice()
|
|
264
|
+
recipient.replacements = recipient.replacements.slice();
|
|
259
265
|
|
|
260
266
|
// Default signInUrl
|
|
261
|
-
let signInUrl =
|
|
267
|
+
let signInUrl = 'https://' + (organization && STAMHOOFD.userMode === 'organization' ? organization.getHost() : STAMHOOFD.domains.dashboard) + '/login?email=' + encodeURIComponent(recipient.email);
|
|
262
268
|
|
|
263
|
-
const recipientUser = await User.getForAuthentication(organization?.id ?? null, recipient.email)
|
|
269
|
+
const recipientUser = await User.getForAuthentication(organization?.id ?? null, recipient.email);
|
|
264
270
|
if (!recipientUser) {
|
|
265
271
|
// We can create a special token
|
|
266
|
-
signInUrl =
|
|
272
|
+
signInUrl = 'https://' + (organization && STAMHOOFD.userMode === 'organization' ? organization.getHost() : STAMHOOFD.domains.dashboard) + '/account-aanmaken?email=' + encodeURIComponent(recipient.email);
|
|
267
273
|
}
|
|
268
274
|
|
|
269
275
|
recipient.replacements.push(Replacement.create({
|
|
270
|
-
token:
|
|
271
|
-
value: signInUrl
|
|
272
|
-
}))
|
|
273
|
-
|
|
276
|
+
token: 'signInUrl',
|
|
277
|
+
value: signInUrl,
|
|
278
|
+
}));
|
|
279
|
+
|
|
274
280
|
if (email.defaultReplacements) {
|
|
275
|
-
recipient.replacements.push(...email.defaultReplacements)
|
|
281
|
+
recipient.replacements.push(...email.defaultReplacements);
|
|
276
282
|
}
|
|
277
283
|
|
|
278
|
-
recipient.replacements.push(...recipient.getDefaultReplacements())
|
|
284
|
+
recipient.replacements.push(...recipient.getDefaultReplacements());
|
|
279
285
|
|
|
280
286
|
if (organization) {
|
|
281
|
-
const extra = organization.meta.getEmailReplacements()
|
|
282
|
-
recipient.replacements.push(...extra)
|
|
283
|
-
}
|
|
287
|
+
const extra = organization.meta.getEmailReplacements();
|
|
288
|
+
recipient.replacements.push(...extra);
|
|
289
|
+
}
|
|
284
290
|
|
|
285
291
|
// Defaults
|
|
286
|
-
const extra = platform.config.getEmailReplacements()
|
|
287
|
-
recipient.replacements.push(...extra)
|
|
292
|
+
const extra = platform.config.getEmailReplacements();
|
|
293
|
+
recipient.replacements.push(...extra);
|
|
288
294
|
}
|
|
289
295
|
|
|
290
|
-
const queue = email.recipients.slice()
|
|
296
|
+
const queue = email.recipients.slice();
|
|
291
297
|
|
|
292
298
|
let emailIndex = 0;
|
|
293
299
|
|
|
294
300
|
for (const s of email.replaceAll ?? []) {
|
|
295
|
-
email.html = email.html.replaceAll(s.from, s.to)
|
|
301
|
+
email.html = email.html.replaceAll(s.from, s.to);
|
|
296
302
|
}
|
|
297
303
|
|
|
298
304
|
// Create e-mail builder
|
|
299
305
|
const builder: EmailBuilder = () => {
|
|
300
|
-
const recipient = queue.shift()
|
|
306
|
+
const recipient = queue.shift();
|
|
301
307
|
if (!recipient) {
|
|
302
|
-
return undefined
|
|
308
|
+
return undefined;
|
|
303
309
|
}
|
|
304
310
|
|
|
305
|
-
let replacedHtml = email.html
|
|
306
|
-
let replacedSubject = email.subject
|
|
311
|
+
let replacedHtml = email.html;
|
|
312
|
+
let replacedSubject = email.subject;
|
|
307
313
|
|
|
308
314
|
for (const replacement of recipient.replacements) {
|
|
309
|
-
replacedHtml = replacedHtml.replaceAll(
|
|
310
|
-
replacedSubject = replacedSubject.replaceAll(
|
|
315
|
+
replacedHtml = replacedHtml.replaceAll('{{' + replacement.token + '}}', replacement.html ?? Formatter.escapeHtml(replacement.value));
|
|
316
|
+
replacedSubject = replacedSubject.replaceAll('{{' + replacement.token + '}}', replacement.value);
|
|
311
317
|
}
|
|
312
318
|
|
|
313
319
|
emailIndex += 1;
|
|
@@ -319,17 +325,17 @@ export async function getEmailBuilder(organization: Organization|null, email: Em
|
|
|
319
325
|
to: [
|
|
320
326
|
{
|
|
321
327
|
// Name will get cleaned by email service
|
|
322
|
-
name: (recipient.firstName??'')+
|
|
323
|
-
email: recipient.email
|
|
324
|
-
}
|
|
328
|
+
name: (recipient.firstName ?? '') + ' ' + (recipient.lastName ?? ''),
|
|
329
|
+
email: recipient.email,
|
|
330
|
+
},
|
|
325
331
|
],
|
|
326
332
|
subject: replacedSubject,
|
|
327
333
|
html: replacedHtml ?? undefined,
|
|
328
334
|
attachments: email.attachments,
|
|
329
335
|
headers: recipient.headers,
|
|
330
336
|
type: email.type,
|
|
331
|
-
callback: email.callback
|
|
332
|
-
}
|
|
333
|
-
}
|
|
337
|
+
callback: email.callback,
|
|
338
|
+
};
|
|
339
|
+
};
|
|
334
340
|
return builder;
|
|
335
341
|
}
|