@stamhoofd/models 2.1.1
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/assets/Metropolis-Black.woff2 +0 -0
- package/dist/src/assets/Metropolis-BlackItalic.woff2 +0 -0
- package/dist/src/assets/Metropolis-Bold.woff2 +0 -0
- package/dist/src/assets/Metropolis-BoldItalic.woff2 +0 -0
- package/dist/src/assets/Metropolis-ExtraBold.woff2 +0 -0
- package/dist/src/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
- package/dist/src/assets/Metropolis-ExtraLight.woff2 +0 -0
- package/dist/src/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
- package/dist/src/assets/Metropolis-Light.woff2 +0 -0
- package/dist/src/assets/Metropolis-LightItalic.woff2 +0 -0
- package/dist/src/assets/Metropolis-Medium.woff2 +0 -0
- package/dist/src/assets/Metropolis-MediumItalic.woff2 +0 -0
- package/dist/src/assets/Metropolis-Regular.woff2 +0 -0
- package/dist/src/assets/Metropolis-RegularItalic.woff2 +0 -0
- package/dist/src/assets/Metropolis-SemiBold.woff2 +0 -0
- package/dist/src/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
- package/dist/src/assets/Metropolis-Thin.woff2 +0 -0
- package/dist/src/assets/Metropolis-ThinItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-Black.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-BlackItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-Bold.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-BoldItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-ExtraBold.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-ExtraLight.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-Light.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-LightItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-Medium.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-MediumItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-Regular.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-RegularItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-SemiBold.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-Thin.woff2 +0 -0
- package/dist/src/assets/assets/Metropolis-ThinItalic.woff2 +0 -0
- package/dist/src/assets/assets/logo.png +0 -0
- package/dist/src/assets/logo.png +0 -0
- package/dist/src/factories/AddressFactory.d.ts +10 -0
- package/dist/src/factories/AddressFactory.d.ts.map +1 -0
- package/dist/src/factories/AddressFactory.js +42 -0
- package/dist/src/factories/AddressFactory.js.map +1 -0
- package/dist/src/factories/EmergencyContactFactory.d.ts +9 -0
- package/dist/src/factories/EmergencyContactFactory.d.ts.map +1 -0
- package/dist/src/factories/EmergencyContactFactory.js +42 -0
- package/dist/src/factories/EmergencyContactFactory.js.map +1 -0
- package/dist/src/factories/GroupFactory.d.ts +19 -0
- package/dist/src/factories/GroupFactory.d.ts.map +1 -0
- package/dist/src/factories/GroupFactory.js +52 -0
- package/dist/src/factories/GroupFactory.js.map +1 -0
- package/dist/src/factories/MemberFactory.d.ts +16 -0
- package/dist/src/factories/MemberFactory.d.ts.map +1 -0
- package/dist/src/factories/MemberFactory.js +98 -0
- package/dist/src/factories/MemberFactory.js.map +1 -0
- package/dist/src/factories/OrganizationFactory.d.ts +16 -0
- package/dist/src/factories/OrganizationFactory.d.ts.map +1 -0
- package/dist/src/factories/OrganizationFactory.js +40 -0
- package/dist/src/factories/OrganizationFactory.js.map +1 -0
- package/dist/src/factories/ParentFactory.d.ts +10 -0
- package/dist/src/factories/ParentFactory.d.ts.map +1 -0
- package/dist/src/factories/ParentFactory.js +44 -0
- package/dist/src/factories/ParentFactory.js.map +1 -0
- package/dist/src/factories/RecordFactory.d.ts +10 -0
- package/dist/src/factories/RecordFactory.d.ts.map +1 -0
- package/dist/src/factories/RecordFactory.js +14 -0
- package/dist/src/factories/RecordFactory.js.map +1 -0
- package/dist/src/factories/RegisterCodeFactory.d.ts +18 -0
- package/dist/src/factories/RegisterCodeFactory.d.ts.map +1 -0
- package/dist/src/factories/RegisterCodeFactory.js +19 -0
- package/dist/src/factories/RegisterCodeFactory.js.map +1 -0
- package/dist/src/factories/RegistrationFactory.d.ts +14 -0
- package/dist/src/factories/RegistrationFactory.d.ts.map +1 -0
- package/dist/src/factories/RegistrationFactory.js +26 -0
- package/dist/src/factories/RegistrationFactory.js.map +1 -0
- package/dist/src/factories/UserFactory.d.ts +21 -0
- package/dist/src/factories/UserFactory.d.ts.map +1 -0
- package/dist/src/factories/UserFactory.js +41 -0
- package/dist/src/factories/UserFactory.js.map +1 -0
- package/dist/src/factories/WebshopFactory.d.ts +16 -0
- package/dist/src/factories/WebshopFactory.d.ts.map +1 -0
- package/dist/src/factories/WebshopFactory.js +35 -0
- package/dist/src/factories/WebshopFactory.js.map +1 -0
- package/dist/src/helpers/DNSValidator.d.ts +6 -0
- package/dist/src/helpers/DNSValidator.d.ts.map +1 -0
- package/dist/src/helpers/DNSValidator.js +144 -0
- package/dist/src/helpers/DNSValidator.js.map +1 -0
- package/dist/src/helpers/EmailBuilder.d.ts +22 -0
- package/dist/src/helpers/EmailBuilder.d.ts.map +1 -0
- package/dist/src/helpers/EmailBuilder.js +100 -0
- package/dist/src/helpers/EmailBuilder.js.map +1 -0
- package/dist/src/helpers/GroupBuilder.d.ts +9 -0
- package/dist/src/helpers/GroupBuilder.d.ts.map +1 -0
- package/dist/src/helpers/GroupBuilder.js +382 -0
- package/dist/src/helpers/GroupBuilder.js.map +1 -0
- package/dist/src/helpers/Handlebars.d.ts +2 -0
- package/dist/src/helpers/Handlebars.d.ts.map +1 -0
- package/dist/src/helpers/Handlebars.js +192 -0
- package/dist/src/helpers/Handlebars.js.map +1 -0
- package/dist/src/helpers/InvoiceBuilder.d.ts +29 -0
- package/dist/src/helpers/InvoiceBuilder.d.ts.map +1 -0
- package/dist/src/helpers/InvoiceBuilder.js +406 -0
- package/dist/src/helpers/InvoiceBuilder.js.map +1 -0
- package/dist/src/helpers/InvoiceBuilder.test.d.ts +2 -0
- package/dist/src/helpers/InvoiceBuilder.test.d.ts.map +1 -0
- package/dist/src/helpers/InvoiceBuilder.test.js +52 -0
- package/dist/src/helpers/InvoiceBuilder.test.js.map +1 -0
- package/dist/src/helpers/RateLimiter.d.ts +27 -0
- package/dist/src/helpers/RateLimiter.d.ts.map +1 -0
- package/dist/src/helpers/RateLimiter.js +57 -0
- package/dist/src/helpers/RateLimiter.js.map +1 -0
- package/dist/src/helpers/WebshopCounter.d.ts +6 -0
- package/dist/src/helpers/WebshopCounter.d.ts.map +1 -0
- package/dist/src/helpers/WebshopCounter.js +36 -0
- package/dist/src/helpers/WebshopCounter.js.map +1 -0
- package/dist/src/helpers/WebshopCounter.test.d.ts +2 -0
- package/dist/src/helpers/WebshopCounter.test.d.ts.map +1 -0
- package/dist/src/helpers/WebshopCounter.test.js +17 -0
- package/dist/src/helpers/WebshopCounter.test.js.map +1 -0
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +23 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/migrations/1593773929-create-initial-tables.sql +634 -0
- package/dist/src/migrations/1605261999-gemeenten-tmp.sql +2820 -0
- package/dist/src/migrations/1605262045-import-postcodes.d.ts +16 -0
- package/dist/src/migrations/1605262045-import-postcodes.d.ts.map +1 -0
- package/dist/src/migrations/1605262045-import-postcodes.js +116 -0
- package/dist/src/migrations/1605262045-import-postcodes.js.map +1 -0
- package/dist/src/migrations/1605262046-import-postcodes-nl.d.ts +4 -0
- package/dist/src/migrations/1605262046-import-postcodes-nl.d.ts.map +1 -0
- package/dist/src/migrations/1605262046-import-postcodes-nl.js +83 -0
- package/dist/src/migrations/1605262046-import-postcodes-nl.js.map +1 -0
- package/dist/src/migrations/1605279038-drop-gemeenten-tmp.sql +1 -0
- package/dist/src/migrations/1648392491-default-templates.sql +9 -0
- package/dist/src/migrations/1651245707-default-templates-reminders.sql +6 -0
- package/dist/src/migrations/1708607340-tickets-deleted-at.sql +1 -0
- package/dist/src/migrations/1710459176-register-code-invoices.sql +3 -0
- package/dist/src/migrations/1712158247-discount-codes.sql +17 -0
- package/dist/src/migrations/1713178665-drop-invites.sql +1 -0
- package/dist/src/migrations/1713178666-drop-keychain.sql +1 -0
- package/dist/src/migrations/1713178667-drop-challenges.sql +1 -0
- package/dist/src/migrations/1713178668-drop-user-keys.sql +7 -0
- package/dist/src/migrations/1713178669-drop-organization-key.sql +2 -0
- package/dist/src/migrations/data/postcodes/nl/Drenthe +291 -0
- package/dist/src/migrations/data/postcodes/nl/Flevoland +107 -0
- package/dist/src/migrations/data/postcodes/nl/Friesland +518 -0
- package/dist/src/migrations/data/postcodes/nl/Gelderland +601 -0
- package/dist/src/migrations/data/postcodes/nl/Groningen +279 -0
- package/dist/src/migrations/data/postcodes/nl/Limburg +324 -0
- package/dist/src/migrations/data/postcodes/nl/Noord-Brabant +620 -0
- package/dist/src/migrations/data/postcodes/nl/Noord-Holland +566 -0
- package/dist/src/migrations/data/postcodes/nl/Overrijsel +344 -0
- package/dist/src/migrations/data/postcodes/nl/Utrecht +278 -0
- package/dist/src/migrations/data/postcodes/nl/Zeeland +179 -0
- package/dist/src/migrations/data/postcodes/nl/Zuid-Holland +662 -0
- package/dist/src/models/BalanceItem.d.ts +57 -0
- package/dist/src/models/BalanceItem.d.ts.map +1 -0
- package/dist/src/models/BalanceItem.js +346 -0
- package/dist/src/models/BalanceItem.js.map +1 -0
- package/dist/src/models/BalanceItemPayment.d.ts +31 -0
- package/dist/src/models/BalanceItemPayment.d.ts.map +1 -0
- package/dist/src/models/BalanceItemPayment.js +101 -0
- package/dist/src/models/BalanceItemPayment.js.map +1 -0
- package/dist/src/models/BuckarooPayment.d.ts +8 -0
- package/dist/src/models/BuckarooPayment.d.ts.map +1 -0
- package/dist/src/models/BuckarooPayment.js +24 -0
- package/dist/src/models/BuckarooPayment.js.map +1 -0
- package/dist/src/models/Document.d.ts +44 -0
- package/dist/src/models/Document.d.ts.map +1 -0
- package/dist/src/models/Document.js +194 -0
- package/dist/src/models/Document.js.map +1 -0
- package/dist/src/models/DocumentTemplate.d.ts +45 -0
- package/dist/src/models/DocumentTemplate.d.ts.map +1 -0
- package/dist/src/models/DocumentTemplate.js +533 -0
- package/dist/src/models/DocumentTemplate.js.map +1 -0
- package/dist/src/models/EmailTemplate.d.ts +22 -0
- package/dist/src/models/EmailTemplate.d.ts.map +1 -0
- package/dist/src/models/EmailTemplate.js +70 -0
- package/dist/src/models/EmailTemplate.js.map +1 -0
- package/dist/src/models/EmailVerificationCode.d.ts +60 -0
- package/dist/src/models/EmailVerificationCode.d.ts.map +1 -0
- package/dist/src/models/EmailVerificationCode.js +307 -0
- package/dist/src/models/EmailVerificationCode.js.map +1 -0
- package/dist/src/models/Group.d.ts +36 -0
- package/dist/src/models/Group.d.ts.map +1 -0
- package/dist/src/models/Group.js +231 -0
- package/dist/src/models/Group.js.map +1 -0
- package/dist/src/models/Image.d.ts +12 -0
- package/dist/src/models/Image.d.ts.map +1 -0
- package/dist/src/models/Image.js +137 -0
- package/dist/src/models/Image.js.map +1 -0
- package/dist/src/models/Member.d.ts +66 -0
- package/dist/src/models/Member.d.ts.map +1 -0
- package/dist/src/models/Member.js +309 -0
- package/dist/src/models/Member.js.map +1 -0
- package/dist/src/models/MemberResponsibilityRecord.d.ts +11 -0
- package/dist/src/models/MemberResponsibilityRecord.d.ts.map +1 -0
- package/dist/src/models/MemberResponsibilityRecord.js +47 -0
- package/dist/src/models/MemberResponsibilityRecord.js.map +1 -0
- package/dist/src/models/MolliePayment.d.ts +8 -0
- package/dist/src/models/MolliePayment.d.ts.map +1 -0
- package/dist/src/models/MolliePayment.js +24 -0
- package/dist/src/models/MolliePayment.js.map +1 -0
- package/dist/src/models/MollieToken.d.ts +45 -0
- package/dist/src/models/MollieToken.d.ts.map +1 -0
- package/dist/src/models/MollieToken.js +333 -0
- package/dist/src/models/MollieToken.js.map +1 -0
- package/dist/src/models/OneTimeToken.d.ts +38 -0
- package/dist/src/models/OneTimeToken.d.ts.map +1 -0
- package/dist/src/models/OneTimeToken.js +126 -0
- package/dist/src/models/OneTimeToken.js.map +1 -0
- package/dist/src/models/Order.d.ts +99 -0
- package/dist/src/models/Order.d.ts.map +1 -0
- package/dist/src/models/Order.js +912 -0
- package/dist/src/models/Order.js.map +1 -0
- package/dist/src/models/Organization.d.ts +119 -0
- package/dist/src/models/Organization.d.ts.map +1 -0
- package/dist/src/models/Organization.js +900 -0
- package/dist/src/models/Organization.js.map +1 -0
- package/dist/src/models/OrganizationRegistrationPeriod.d.ts +14 -0
- package/dist/src/models/OrganizationRegistrationPeriod.d.ts.map +1 -0
- package/dist/src/models/OrganizationRegistrationPeriod.js +62 -0
- package/dist/src/models/OrganizationRegistrationPeriod.js.map +1 -0
- package/dist/src/models/PasswordToken.d.ts +29 -0
- package/dist/src/models/PasswordToken.d.ts.map +1 -0
- package/dist/src/models/PasswordToken.js +118 -0
- package/dist/src/models/PasswordToken.js.map +1 -0
- package/dist/src/models/PayconiqPayment.d.ts +18 -0
- package/dist/src/models/PayconiqPayment.d.ts.map +1 -0
- package/dist/src/models/PayconiqPayment.js +216 -0
- package/dist/src/models/PayconiqPayment.js.map +1 -0
- package/dist/src/models/Payment.d.ts +62 -0
- package/dist/src/models/Payment.d.ts.map +1 -0
- package/dist/src/models/Payment.js +199 -0
- package/dist/src/models/Payment.js.map +1 -0
- package/dist/src/models/Platform.d.ts +15 -0
- package/dist/src/models/Platform.d.ts.map +1 -0
- package/dist/src/models/Platform.js +77 -0
- package/dist/src/models/Platform.js.map +1 -0
- package/dist/src/models/RegisterCode.d.ts +27 -0
- package/dist/src/models/RegisterCode.d.ts.map +1 -0
- package/dist/src/models/RegisterCode.js +162 -0
- package/dist/src/models/RegisterCode.js.map +1 -0
- package/dist/src/models/Registration.d.ts +47 -0
- package/dist/src/models/Registration.d.ts.map +1 -0
- package/dist/src/models/Registration.js +369 -0
- package/dist/src/models/Registration.js.map +1 -0
- package/dist/src/models/RegistrationPeriod.d.ts +15 -0
- package/dist/src/models/RegistrationPeriod.d.ts.map +1 -0
- package/dist/src/models/RegistrationPeriod.js +64 -0
- package/dist/src/models/RegistrationPeriod.js.map +1 -0
- package/dist/src/models/STCredit.d.ts +20 -0
- package/dist/src/models/STCredit.d.ts.map +1 -0
- package/dist/src/models/STCredit.js +129 -0
- package/dist/src/models/STCredit.js.map +1 -0
- package/dist/src/models/STInvoice.d.ts +51 -0
- package/dist/src/models/STInvoice.d.ts.map +1 -0
- package/dist/src/models/STInvoice.js +453 -0
- package/dist/src/models/STInvoice.js.map +1 -0
- package/dist/src/models/STPackage.d.ts +36 -0
- package/dist/src/models/STPackage.d.ts.map +1 -0
- package/dist/src/models/STPackage.js +300 -0
- package/dist/src/models/STPackage.js.map +1 -0
- package/dist/src/models/STPendingInvoice.d.ts +45 -0
- package/dist/src/models/STPendingInvoice.d.ts.map +1 -0
- package/dist/src/models/STPendingInvoice.js +284 -0
- package/dist/src/models/STPendingInvoice.js.map +1 -0
- package/dist/src/models/StripeAccount.d.ts +17 -0
- package/dist/src/models/StripeAccount.d.ts.map +1 -0
- package/dist/src/models/StripeAccount.js +81 -0
- package/dist/src/models/StripeAccount.js.map +1 -0
- package/dist/src/models/StripeCheckoutSession.d.ts +9 -0
- package/dist/src/models/StripeCheckoutSession.d.ts.map +1 -0
- package/dist/src/models/StripeCheckoutSession.js +31 -0
- package/dist/src/models/StripeCheckoutSession.js.map +1 -0
- package/dist/src/models/StripePaymentIntent.d.ts +9 -0
- package/dist/src/models/StripePaymentIntent.d.ts.map +1 -0
- package/dist/src/models/StripePaymentIntent.js +31 -0
- package/dist/src/models/StripePaymentIntent.js.map +1 -0
- package/dist/src/models/Ticket.d.ts +61 -0
- package/dist/src/models/Ticket.d.ts.map +1 -0
- package/dist/src/models/Ticket.js +143 -0
- package/dist/src/models/Ticket.js.map +1 -0
- package/dist/src/models/Token.d.ts +49 -0
- package/dist/src/models/Token.d.ts.map +1 -0
- package/dist/src/models/Token.js +218 -0
- package/dist/src/models/Token.js.map +1 -0
- package/dist/src/models/Token.test.d.ts +2 -0
- package/dist/src/models/Token.test.d.ts.map +1 -0
- package/dist/src/models/Token.test.js +60 -0
- package/dist/src/models/Token.test.js.map +1 -0
- package/dist/src/models/UsedRegisterCode.d.ts +22 -0
- package/dist/src/models/UsedRegisterCode.d.ts.map +1 -0
- package/dist/src/models/UsedRegisterCode.js +158 -0
- package/dist/src/models/UsedRegisterCode.js.map +1 -0
- package/dist/src/models/User.d.ts +55 -0
- package/dist/src/models/User.d.ts.map +1 -0
- package/dist/src/models/User.js +314 -0
- package/dist/src/models/User.js.map +1 -0
- package/dist/src/models/UserPermissions.d.ts +15 -0
- package/dist/src/models/UserPermissions.d.ts.map +1 -0
- package/dist/src/models/UserPermissions.js +57 -0
- package/dist/src/models/UserPermissions.js.map +1 -0
- package/dist/src/models/Webshop.d.ts +44 -0
- package/dist/src/models/Webshop.d.ts.map +1 -0
- package/dist/src/models/Webshop.js +184 -0
- package/dist/src/models/Webshop.js.map +1 -0
- package/dist/src/models/WebshopDiscountCode.d.ts +18 -0
- package/dist/src/models/WebshopDiscountCode.d.ts.map +1 -0
- package/dist/src/models/WebshopDiscountCode.js +88 -0
- package/dist/src/models/WebshopDiscountCode.js.map +1 -0
- package/dist/src/models/addresses/City.d.ts +14 -0
- package/dist/src/models/addresses/City.d.ts.map +1 -0
- package/dist/src/models/addresses/City.js +37 -0
- package/dist/src/models/addresses/City.js.map +1 -0
- package/dist/src/models/addresses/PostalCode.d.ts +20 -0
- package/dist/src/models/addresses/PostalCode.d.ts.map +1 -0
- package/dist/src/models/addresses/PostalCode.js +138 -0
- package/dist/src/models/addresses/PostalCode.js.map +1 -0
- package/dist/src/models/addresses/PostalCode.test.d.ts +2 -0
- package/dist/src/models/addresses/PostalCode.test.d.ts.map +1 -0
- package/dist/src/models/addresses/PostalCode.test.js +98 -0
- package/dist/src/models/addresses/PostalCode.test.js.map +1 -0
- package/dist/src/models/addresses/Province.d.ts +9 -0
- package/dist/src/models/addresses/Province.d.ts.map +1 -0
- package/dist/src/models/addresses/Province.js +24 -0
- package/dist/src/models/addresses/Province.js.map +1 -0
- package/dist/src/models/addresses/Street.d.ts +10 -0
- package/dist/src/models/addresses/Street.d.ts.map +1 -0
- package/dist/src/models/addresses/Street.js +26 -0
- package/dist/src/models/addresses/Street.js.map +1 -0
- package/dist/src/models/index.d.ts +37 -0
- package/dist/src/models/index.d.ts.map +1 -0
- package/dist/src/models/index.js +53 -0
- package/dist/src/models/index.js.map +1 -0
- package/dist/src/structures/OrganizationServerMetaData.d.ts +43 -0
- package/dist/src/structures/OrganizationServerMetaData.d.ts.map +1 -0
- package/dist/src/structures/OrganizationServerMetaData.js +128 -0
- package/dist/src/structures/OrganizationServerMetaData.js.map +1 -0
- package/dist/tests/jest.global.setup.d.ts +3 -0
- package/dist/tests/jest.global.setup.d.ts.map +1 -0
- package/dist/tests/jest.global.setup.js +20 -0
- package/dist/tests/jest.global.setup.js.map +1 -0
- package/dist/tests/jest.setup.d.ts +2 -0
- package/dist/tests/jest.setup.d.ts.map +1 -0
- package/dist/tests/jest.setup.js +15 -0
- package/dist/tests/jest.setup.js.map +1 -0
- package/package.json +30 -0
- package/src/assets/Metropolis-Black.woff2 +0 -0
- package/src/assets/Metropolis-BlackItalic.woff2 +0 -0
- package/src/assets/Metropolis-Bold.woff2 +0 -0
- package/src/assets/Metropolis-BoldItalic.woff2 +0 -0
- package/src/assets/Metropolis-ExtraBold.woff2 +0 -0
- package/src/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
- package/src/assets/Metropolis-ExtraLight.woff2 +0 -0
- package/src/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
- package/src/assets/Metropolis-Light.woff2 +0 -0
- package/src/assets/Metropolis-LightItalic.woff2 +0 -0
- package/src/assets/Metropolis-Medium.woff2 +0 -0
- package/src/assets/Metropolis-MediumItalic.woff2 +0 -0
- package/src/assets/Metropolis-Regular.woff2 +0 -0
- package/src/assets/Metropolis-RegularItalic.woff2 +0 -0
- package/src/assets/Metropolis-SemiBold.woff2 +0 -0
- package/src/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
- package/src/assets/Metropolis-Thin.woff2 +0 -0
- package/src/assets/Metropolis-ThinItalic.woff2 +0 -0
- package/src/assets/logo.png +0 -0
- package/src/factories/AddressFactory.ts +42 -0
- package/src/factories/EmergencyContactFactory.ts +43 -0
- package/src/factories/GroupFactory.ts +66 -0
- package/src/factories/MemberFactory.ts +122 -0
- package/src/factories/OrganizationFactory.ts +45 -0
- package/src/factories/ParentFactory.ts +49 -0
- package/src/factories/RecordFactory.ts +12 -0
- package/src/factories/RegisterCodeFactory.ts +25 -0
- package/src/factories/RegistrationFactory.ts +32 -0
- package/src/factories/UserFactory.ts +66 -0
- package/src/factories/WebshopFactory.ts +43 -0
- package/src/helpers/DNSValidator.ts +153 -0
- package/src/helpers/EmailBuilder.ts +127 -0
- package/src/helpers/GroupBuilder.ts +438 -0
- package/src/helpers/Handlebars.ts +203 -0
- package/src/helpers/InvoiceBuilder.test.ts +57 -0
- package/src/helpers/InvoiceBuilder.ts +501 -0
- package/src/helpers/RateLimiter.ts +75 -0
- package/src/helpers/WebshopCounter.test.ts +16 -0
- package/src/helpers/WebshopCounter.ts +36 -0
- package/src/index.ts +21 -0
- package/src/migrations/1593773929-create-initial-tables.sql +634 -0
- package/src/migrations/1605261999-gemeenten-tmp.sql +2820 -0
- package/src/migrations/1605262045-import-postcodes.ts +132 -0
- package/src/migrations/1605262046-import-postcodes-nl.ts +97 -0
- package/src/migrations/1605279038-drop-gemeenten-tmp.sql +1 -0
- package/src/migrations/1648392491-default-templates.sql +9 -0
- package/src/migrations/1651245707-default-templates-reminders.sql +6 -0
- package/src/migrations/1708607340-tickets-deleted-at.sql +1 -0
- package/src/migrations/1710459176-register-code-invoices.sql +3 -0
- package/src/migrations/1712158247-discount-codes.sql +17 -0
- package/src/migrations/1713178665-drop-invites.sql +1 -0
- package/src/migrations/1713178666-drop-keychain.sql +1 -0
- package/src/migrations/1713178667-drop-challenges.sql +1 -0
- package/src/migrations/1713178668-drop-user-keys.sql +7 -0
- package/src/migrations/1713178669-drop-organization-key.sql +2 -0
- package/src/migrations/1714985451-user-nullable-organization-id.sql +2 -0
- package/src/migrations/1714985452-email-verification-code-nullable-organization-id.sql +2 -0
- package/src/migrations/1714985453-user-organization-permissions.sql +2 -0
- package/src/migrations/1714985454-user-organization-permissions.sql +2 -0
- package/src/migrations/1715079362-platform.sql +6 -0
- package/src/migrations/1715181649-registrations-organization-id.sql +2 -0
- package/src/migrations/1715181650-registrations-organization-id-fill.sql +1 -0
- package/src/migrations/1715181651-registrations-organization-id-drop-null.sql +2 -0
- package/src/migrations/1716117067-members-nullable-organization-id.sql +2 -0
- package/src/migrations/1719567581-registration-periods.sql +13 -0
- package/src/migrations/1719567582-organization-registration-periods.sql +13 -0
- package/src/migrations/1719567881-organization-periodId.sql +2 -0
- package/src/migrations/1719567882-groups-periodId.sql +2 -0
- package/src/migrations/1719567883-platform-periodId.sql +2 -0
- package/src/migrations/1719568079-default-period.sql +2 -0
- package/src/migrations/1719568080-set-default-period-platform.sql +1 -0
- package/src/migrations/1719568081-set-default-period-organizations.sql +1 -0
- package/src/migrations/1719568082-set-default-period-groups.sql +1 -0
- package/src/migrations/1719580828-registrations-periodId.sql +2 -0
- package/src/migrations/1719580829-set-default-period-registrations.sql +1 -0
- package/src/migrations/data/postcodes/nl/Drenthe +291 -0
- package/src/migrations/data/postcodes/nl/Flevoland +107 -0
- package/src/migrations/data/postcodes/nl/Friesland +518 -0
- package/src/migrations/data/postcodes/nl/Gelderland +601 -0
- package/src/migrations/data/postcodes/nl/Groningen +279 -0
- package/src/migrations/data/postcodes/nl/Limburg +324 -0
- package/src/migrations/data/postcodes/nl/Noord-Brabant +620 -0
- package/src/migrations/data/postcodes/nl/Noord-Holland +566 -0
- package/src/migrations/data/postcodes/nl/Overrijsel +344 -0
- package/src/migrations/data/postcodes/nl/Utrecht +278 -0
- package/src/migrations/data/postcodes/nl/Zeeland +179 -0
- package/src/migrations/data/postcodes/nl/Zuid-Holland +662 -0
- package/src/models/BalanceItem.ts +392 -0
- package/src/models/BalanceItemPayment.ts +106 -0
- package/src/models/BuckarooPayment.ts +19 -0
- package/src/models/Document.ts +203 -0
- package/src/models/DocumentTemplate.ts +583 -0
- package/src/models/EmailTemplate.ts +64 -0
- package/src/models/EmailVerificationCode.ts +352 -0
- package/src/models/Group.ts +293 -0
- package/src/models/Image.ts +147 -0
- package/src/models/Member.ts +386 -0
- package/src/models/MemberResponsibilityRecord.ts +39 -0
- package/src/models/MolliePayment.ts +19 -0
- package/src/models/MollieToken.ts +369 -0
- package/src/models/OneTimeToken.ts +131 -0
- package/src/models/Order.ts +1030 -0
- package/src/models/Organization.ts +1085 -0
- package/src/models/OrganizationRegistrationPeriod.ts +54 -0
- package/src/models/PasswordToken.ts +139 -0
- package/src/models/PayconiqPayment.ts +241 -0
- package/src/models/Payment.ts +216 -0
- package/src/models/Platform.ts +76 -0
- package/src/models/RegisterCode.ts +164 -0
- package/src/models/Registration.ts +405 -0
- package/src/models/RegistrationPeriod.ts +55 -0
- package/src/models/STCredit.ts +134 -0
- package/src/models/STInvoice.ts +507 -0
- package/src/models/STPackage.ts +324 -0
- package/src/models/STPendingInvoice.ts +308 -0
- package/src/models/StripeAccount.ts +71 -0
- package/src/models/StripeCheckoutSession.ts +22 -0
- package/src/models/StripePaymentIntent.ts +22 -0
- package/src/models/Ticket.ts +145 -0
- package/src/models/Token.test.ts +69 -0
- package/src/models/Token.ts +269 -0
- package/src/models/UsedRegisterCode.ts +166 -0
- package/src/models/User.ts +445 -0
- package/src/models/UserPermissions.ts +54 -0
- package/src/models/Webshop.ts +206 -0
- package/src/models/WebshopDiscountCode.ts +81 -0
- package/src/models/addresses/City.ts +31 -0
- package/src/models/addresses/PostalCode.test.ts +117 -0
- package/src/models/addresses/PostalCode.ts +164 -0
- package/src/models/addresses/Province.ts +20 -0
- package/src/models/addresses/Street.ts +25 -0
- package/src/models/index.ts +49 -0
- package/src/structures/OrganizationServerMetaData.ts +117 -0
|
@@ -0,0 +1,900 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Organization = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const simple_database_1 = require("@simonbackx/simple-database");
|
|
6
|
+
const simple_errors_1 = require("@simonbackx/simple-errors");
|
|
7
|
+
const backend_i18n_1 = require("@stamhoofd/backend-i18n");
|
|
8
|
+
const email_1 = require("@stamhoofd/email");
|
|
9
|
+
const structures_1 = require("@stamhoofd/structures");
|
|
10
|
+
const utility_1 = require("@stamhoofd/utility");
|
|
11
|
+
const sesv2_1 = tslib_1.__importDefault(require("aws-sdk/clients/sesv2"));
|
|
12
|
+
const uuid_1 = require("uuid");
|
|
13
|
+
const DNSValidator_1 = require("../helpers/DNSValidator");
|
|
14
|
+
const EmailBuilder_1 = require("../helpers/EmailBuilder");
|
|
15
|
+
const OrganizationServerMetaData_1 = require("../structures/OrganizationServerMetaData");
|
|
16
|
+
const _1 = require("./");
|
|
17
|
+
class Organization extends simple_database_1.Model {
|
|
18
|
+
constructor() {
|
|
19
|
+
super(...arguments);
|
|
20
|
+
/// URL to a website page or a Facebook page (including http)
|
|
21
|
+
this.website = null;
|
|
22
|
+
/// A custom domain name that is used to host the register application (should be unique)
|
|
23
|
+
// E.g. inschrijven.scoutswetteren.be
|
|
24
|
+
this.registerDomain = null;
|
|
25
|
+
/**
|
|
26
|
+
* Data only accessible by the owners / users with special permissions
|
|
27
|
+
*/
|
|
28
|
+
this.privateMeta = structures_1.OrganizationPrivateMetaData.create({});
|
|
29
|
+
/**
|
|
30
|
+
* Data only accessible by the server
|
|
31
|
+
*/
|
|
32
|
+
this.serverMeta = OrganizationServerMetaData_1.OrganizationServerMetaData.create({});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Return default locale confiruation
|
|
36
|
+
*/
|
|
37
|
+
get i18n() {
|
|
38
|
+
return new backend_i18n_1.I18n("nl", this.address.country);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Makes sure empty name is replaced with organization name
|
|
42
|
+
*/
|
|
43
|
+
get mappedTransferSettings() {
|
|
44
|
+
return this.meta.transferSettings.fillMissing(structures_1.TransferSettings.create({ creditor: this.name }));
|
|
45
|
+
}
|
|
46
|
+
// Methods
|
|
47
|
+
static async getByURI(uri) {
|
|
48
|
+
const [rows] = await simple_database_1.Database.select(`SELECT ${this.getDefaultSelect()} FROM ${this.table} WHERE \`uri\` = ? LIMIT 1`, [uri]);
|
|
49
|
+
if (rows.length == 0) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
// Read member + address from first row
|
|
53
|
+
return this.fromRow(rows[0][this.table]);
|
|
54
|
+
}
|
|
55
|
+
// Methods
|
|
56
|
+
static async getByEmail(email) {
|
|
57
|
+
if (["hallo@stamhoofd.be", "hallo@stamhoofd.nl"].includes(email)) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (email.startsWith('noreply-')) {
|
|
61
|
+
// Trim
|
|
62
|
+
email = email.substring("noreply-".length);
|
|
63
|
+
}
|
|
64
|
+
if (email.endsWith("@stamhoofd.email")) {
|
|
65
|
+
const uri = email.substring(0, email.length - "@stamhoofd.email".length);
|
|
66
|
+
return await Organization.getByURI(uri);
|
|
67
|
+
}
|
|
68
|
+
if (email.endsWith("@stamhoofd.be")) {
|
|
69
|
+
const uri = email.substring(0, email.length - "@stamhoofd.be".length);
|
|
70
|
+
return await Organization.getByURI(uri);
|
|
71
|
+
}
|
|
72
|
+
if (email.endsWith("@stamhoofd.nl")) {
|
|
73
|
+
const uri = email.substring(0, email.length - "@stamhoofd.nl".length);
|
|
74
|
+
return await Organization.getByURI(uri);
|
|
75
|
+
}
|
|
76
|
+
const at = email.indexOf("@");
|
|
77
|
+
const domain = email.substring(at + 1);
|
|
78
|
+
const [rows] = await simple_database_1.Database.select(`SELECT ${this.getDefaultSelect()} FROM ${this.table} WHERE privateMeta->"$.value.mailDomain" = ? LIMIT 1`, [domain]);
|
|
79
|
+
if (rows.length == 0) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
// Read member + address from first row
|
|
83
|
+
return this.fromRow(rows[0][this.table]);
|
|
84
|
+
}
|
|
85
|
+
// Methods
|
|
86
|
+
static async getByRegisterDomain(host) {
|
|
87
|
+
const [rows] = await simple_database_1.Database.select(`SELECT ${this.getDefaultSelect()} FROM ${this.table} WHERE \`registerDomain\` = ? LIMIT 1`, [host]);
|
|
88
|
+
if (rows.length == 0) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
// Read member + address from first row
|
|
92
|
+
return this.fromRow(rows[0][this.table]);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get an Organization by looking at the host of a request
|
|
96
|
+
* Format is 2331c59a-0cbe-4279-871c-ea9d0474cd54.api.stamhoofd.app
|
|
97
|
+
* + switch country if needed
|
|
98
|
+
*/
|
|
99
|
+
static async getFromRequest(request) {
|
|
100
|
+
const organization = await Organization.fromApiHost(request.host);
|
|
101
|
+
const i18n = backend_i18n_1.I18n.fromRequest(request);
|
|
102
|
+
i18n.switchToLocale({ country: organization.address.country });
|
|
103
|
+
return organization;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get an Organization by looking at the host of a request
|
|
107
|
+
* Format is 2331c59a-0cbe-4279-871c-ea9d0474cd54.api.stamhoofd.app
|
|
108
|
+
*/
|
|
109
|
+
static async fromApiHost(host) {
|
|
110
|
+
const splitted = host.split('.');
|
|
111
|
+
if (splitted.length < 2) {
|
|
112
|
+
throw new simple_errors_1.SimpleError({
|
|
113
|
+
code: "invalid_host",
|
|
114
|
+
message: "Please specify the organization in the hostname",
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const id = splitted[0];
|
|
118
|
+
const organization = await this.getByID(id);
|
|
119
|
+
if (!organization) {
|
|
120
|
+
throw new simple_errors_1.SimpleError({
|
|
121
|
+
code: "invalid_organization",
|
|
122
|
+
message: "No organization known for host " + host,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return organization;
|
|
126
|
+
}
|
|
127
|
+
getHost() {
|
|
128
|
+
if (this.registerDomain) {
|
|
129
|
+
return this.registerDomain;
|
|
130
|
+
}
|
|
131
|
+
return this.getDefaultHost();
|
|
132
|
+
}
|
|
133
|
+
getDefaultHost() {
|
|
134
|
+
var _a;
|
|
135
|
+
const defaultDomain = (_a = STAMHOOFD.domains.registration[this.address.country]) !== null && _a !== void 0 ? _a : STAMHOOFD.domains.registration[""];
|
|
136
|
+
return this.uri + "." + defaultDomain;
|
|
137
|
+
}
|
|
138
|
+
get marketingDomain() {
|
|
139
|
+
var _a;
|
|
140
|
+
return (_a = STAMHOOFD.domains.marketing[this.address.country]) !== null && _a !== void 0 ? _a : STAMHOOFD.domains.marketing[""];
|
|
141
|
+
}
|
|
142
|
+
getApiHost() {
|
|
143
|
+
const defaultDomain = STAMHOOFD.domains.api;
|
|
144
|
+
if (!defaultDomain) {
|
|
145
|
+
throw new Error("Missing hostname in environment");
|
|
146
|
+
}
|
|
147
|
+
return this.id + "." + defaultDomain;
|
|
148
|
+
}
|
|
149
|
+
async getStructure({ emptyGroups } = { emptyGroups: false }) {
|
|
150
|
+
var _a, _b;
|
|
151
|
+
const groups = emptyGroups ? [] : (await (await Promise.resolve().then(() => tslib_1.__importStar(require("./Group")))).Group.getAll(this.id));
|
|
152
|
+
const struct = structures_1.Organization.create({
|
|
153
|
+
id: this.id,
|
|
154
|
+
name: this.name,
|
|
155
|
+
meta: this.meta,
|
|
156
|
+
address: this.address,
|
|
157
|
+
registerDomain: this.registerDomain,
|
|
158
|
+
uri: this.uri,
|
|
159
|
+
website: this.website,
|
|
160
|
+
groups: groups.map(g => g.getStructure())
|
|
161
|
+
});
|
|
162
|
+
if (this.meta.modules.disableActivities) {
|
|
163
|
+
// Only show groups that are in a given category
|
|
164
|
+
struct.groups = (_b = (_a = struct.categoryTree.categories[0]) === null || _a === void 0 ? void 0 : _a.groups) !== null && _b !== void 0 ? _b : [];
|
|
165
|
+
}
|
|
166
|
+
if (emptyGroups) {
|
|
167
|
+
// Reduce data
|
|
168
|
+
struct.meta = struct.meta.clone();
|
|
169
|
+
struct.meta.categories = [];
|
|
170
|
+
struct.meta.recordsConfiguration = structures_1.OrganizationRecordsConfiguration.create({});
|
|
171
|
+
}
|
|
172
|
+
return struct;
|
|
173
|
+
}
|
|
174
|
+
async cleanCategories(groups) {
|
|
175
|
+
const reachable = new Map();
|
|
176
|
+
const queue = [this.meta.rootCategoryId];
|
|
177
|
+
reachable.set(this.meta.rootCategoryId, true);
|
|
178
|
+
let shouldSave = false;
|
|
179
|
+
const usedGroupIds = new Set();
|
|
180
|
+
while (queue.length > 0) {
|
|
181
|
+
const id = queue.shift();
|
|
182
|
+
if (!id) {
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
const category = this.meta.categories.find(c => c.id === id);
|
|
186
|
+
if (!category) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
for (const i of category.categoryIds) {
|
|
190
|
+
if (!reachable.get(i)) {
|
|
191
|
+
reachable.set(i, true);
|
|
192
|
+
queue.push(i);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Remove groupIds that no longer exist or are in a different category already
|
|
196
|
+
let filtered = category.groupIds.filter(id => !!groups.find(g => g.id === id) && !usedGroupIds.has(id));
|
|
197
|
+
// Remove duplicate groups
|
|
198
|
+
filtered = utility_1.Formatter.uniqueArray(filtered);
|
|
199
|
+
if (filtered.length !== category.groupIds.length) {
|
|
200
|
+
shouldSave = true;
|
|
201
|
+
console.log("Deleted " + (category.groupIds.length - filtered.length) + " group ids from category " + category.id + ", in organization " + this.id);
|
|
202
|
+
category.groupIds = filtered;
|
|
203
|
+
}
|
|
204
|
+
for (const groupId of category.groupIds) {
|
|
205
|
+
usedGroupIds.add(groupId);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const reachableCategoryIds = [...reachable.keys()];
|
|
209
|
+
// Delete all categories that are not reachable anymore
|
|
210
|
+
const beforeCount = this.meta.categories.length;
|
|
211
|
+
this.meta.categories = this.meta.categories.filter(c => reachableCategoryIds.includes(c.id));
|
|
212
|
+
if (this.meta.categories.length !== beforeCount) {
|
|
213
|
+
console.log("Deleted " + (beforeCount - this.meta.categories.length) + " categories from organization " + this.id);
|
|
214
|
+
await this.save();
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
if (shouldSave) {
|
|
218
|
+
await this.save();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async updateDNSRecords() {
|
|
223
|
+
var _a, _b, _c, _d;
|
|
224
|
+
const organization = this;
|
|
225
|
+
// Check initial status
|
|
226
|
+
let isValidRecords = true;
|
|
227
|
+
for (const record of organization.privateMeta.dnsRecords) {
|
|
228
|
+
if (record.status != structures_1.DNSRecordStatus.Valid) {
|
|
229
|
+
isValidRecords = false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
const { allValid } = await (0, DNSValidator_1.validateDNSRecords)(organization.privateMeta.dnsRecords);
|
|
233
|
+
if ((_a = organization.registerDomain) !== null && _a !== void 0 ? _a : organization.privateMeta.pendingRegisterDomain) {
|
|
234
|
+
const registerDomainRecord = ((_b = organization.privateMeta.pendingRegisterDomain) !== null && _b !== void 0 ? _b : organization.registerDomain) + ".";
|
|
235
|
+
const records = organization.privateMeta.dnsRecords.filter(r => r.name === registerDomainRecord);
|
|
236
|
+
const areRegisterDomainRecordsValid = records.length === 0 || records.every(r => r.status === structures_1.DNSRecordStatus.Valid);
|
|
237
|
+
if (areRegisterDomainRecordsValid) {
|
|
238
|
+
// We can setup the register domain if needed
|
|
239
|
+
if (organization.privateMeta.pendingRegisterDomain !== null) {
|
|
240
|
+
organization.registerDomain = organization.privateMeta.pendingRegisterDomain;
|
|
241
|
+
organization.privateMeta.pendingRegisterDomain = null;
|
|
242
|
+
console.log("Did set register domain for " + this.id + " to " + organization.registerDomain);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
// Clear register domain
|
|
247
|
+
if (organization.registerDomain) {
|
|
248
|
+
// We need to clear it, to prevent sending e-mails with invalid links
|
|
249
|
+
organization.privateMeta.pendingRegisterDomain = (_c = organization.privateMeta.pendingRegisterDomain) !== null && _c !== void 0 ? _c : organization.registerDomain;
|
|
250
|
+
organization.registerDomain = null;
|
|
251
|
+
console.log("Cleared register domain for " + this.id + " because of invalid non txt records");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (allValid) {
|
|
256
|
+
if (organization.privateMeta.pendingMailDomain !== null) {
|
|
257
|
+
organization.privateMeta.mailDomain = organization.privateMeta.pendingMailDomain;
|
|
258
|
+
organization.privateMeta.pendingMailDomain = null;
|
|
259
|
+
}
|
|
260
|
+
const wasUnstable = organization.serverMeta.isDNSUnstable;
|
|
261
|
+
organization.serverMeta.markDNSValid();
|
|
262
|
+
const didSendDomainSetupMail = organization.serverMeta.didSendDomainSetupMail;
|
|
263
|
+
const didSendWarning = organization.serverMeta.DNSRecordWarningCount > 0;
|
|
264
|
+
organization.serverMeta.DNSRecordWarningCount = 0;
|
|
265
|
+
const wasActive = this.privateMeta.mailDomainActive;
|
|
266
|
+
await this.updateAWSMailIdenitity();
|
|
267
|
+
// yay! Do not Save until after doing AWS changes
|
|
268
|
+
await organization.save();
|
|
269
|
+
if (wasUnstable && !organization.serverMeta.isDNSUnstable) {
|
|
270
|
+
console.warn('DNS settings became stable for ' + this.name + ' ' + this.id);
|
|
271
|
+
await this.sendEmailTemplate({
|
|
272
|
+
type: structures_1.EmailTemplateType.OrganizationStableDNS,
|
|
273
|
+
bcc: true
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
else if (!wasActive && this.privateMeta.mailDomainActive && (!didSendDomainSetupMail || didSendWarning) && !organization.serverMeta.isDNSUnstable) {
|
|
277
|
+
organization.serverMeta.didSendDomainSetupMail = true;
|
|
278
|
+
await organization.save();
|
|
279
|
+
if (!didSendDomainSetupMail) {
|
|
280
|
+
await this.sendEmailTemplate({
|
|
281
|
+
type: structures_1.EmailTemplateType.OrganizationDNSSetupComplete
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
await this.sendEmailTemplate({
|
|
286
|
+
type: structures_1.EmailTemplateType.OrganizationValidDNS
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
// DNS settings gone broken
|
|
293
|
+
if (organization.privateMeta.mailDomain) {
|
|
294
|
+
organization.privateMeta.pendingMailDomain = (_d = organization.privateMeta.pendingMailDomain) !== null && _d !== void 0 ? _d : organization.privateMeta.mailDomain;
|
|
295
|
+
organization.privateMeta.mailDomain = null;
|
|
296
|
+
}
|
|
297
|
+
const wasDNSUnstable = organization.serverMeta.isDNSUnstable;
|
|
298
|
+
organization.serverMeta.markDNSFailure();
|
|
299
|
+
// disable AWS emails
|
|
300
|
+
this.privateMeta.mailDomainActive = false;
|
|
301
|
+
// save
|
|
302
|
+
await organization.save();
|
|
303
|
+
if (!wasDNSUnstable && organization.serverMeta.isDNSUnstable) {
|
|
304
|
+
// DNS became instable
|
|
305
|
+
console.warn('DNS settings became instable for ' + this.name + ' ' + this.id);
|
|
306
|
+
await this.sendEmailTemplate({
|
|
307
|
+
type: structures_1.EmailTemplateType.OrganizationUnstableDNS,
|
|
308
|
+
bcc: true
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
else if (!organization.serverMeta.isDNSUnstable && organization.serverMeta.didSendDomainSetupMail && organization.serverMeta.DNSRecordWarningCount == 0) {
|
|
312
|
+
organization.serverMeta.DNSRecordWarningCount += 1;
|
|
313
|
+
await organization.save();
|
|
314
|
+
await this.sendEmailTemplate({
|
|
315
|
+
type: structures_1.EmailTemplateType.OrganizationInvalidDNS
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async sendEmailTemplate(data) {
|
|
321
|
+
var _a, _b;
|
|
322
|
+
// First fetch template
|
|
323
|
+
const templates = (await _1.EmailTemplate.where({ type: data.type, organizationId: null }));
|
|
324
|
+
if (templates.length == 0) {
|
|
325
|
+
console.error("Could not find email template for type " + data.type);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const template = templates[0];
|
|
329
|
+
const recipients = await this.getAdminRecipients();
|
|
330
|
+
const defaultI18n = new backend_i18n_1.I18n("nl", structures_1.Country.Belgium);
|
|
331
|
+
const i18n = this.i18n;
|
|
332
|
+
const replacementStrings = [
|
|
333
|
+
{
|
|
334
|
+
from: defaultI18n.$t("shared.domains.marketing"),
|
|
335
|
+
to: i18n.$t("shared.domains.marketing")
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
from: defaultI18n.$t("shared.emails.general"),
|
|
339
|
+
to: i18n.$t("shared.emails.general")
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
from: defaultI18n.$t("shared.domains.email"),
|
|
343
|
+
to: i18n.$t("shared.domains.email")
|
|
344
|
+
}
|
|
345
|
+
];
|
|
346
|
+
let html = template.html;
|
|
347
|
+
for (const s of replacementStrings) {
|
|
348
|
+
html = html.replaceAll(s.from, s.to);
|
|
349
|
+
}
|
|
350
|
+
// Create e-mail builder
|
|
351
|
+
const builder = await (0, EmailBuilder_1.getEmailBuilder)(this, {
|
|
352
|
+
recipients,
|
|
353
|
+
subject: template.subject,
|
|
354
|
+
html,
|
|
355
|
+
from: data.personal ? email_1.Email.getPersonalEmailFor(this.i18n) : email_1.Email.getInternalEmailFor(this.i18n),
|
|
356
|
+
singleBcc: data.bcc ? 'simon@stamhoofd.be' : undefined,
|
|
357
|
+
replyTo: data.replyTo,
|
|
358
|
+
type: 'transactional',
|
|
359
|
+
defaultReplacements: [
|
|
360
|
+
structures_1.Replacement.create({
|
|
361
|
+
token: 'mailDomain',
|
|
362
|
+
value: (_b = (_a = this.privateMeta.mailDomain) !== null && _a !== void 0 ? _a : this.privateMeta.pendingMailDomain) !== null && _b !== void 0 ? _b : ''
|
|
363
|
+
})
|
|
364
|
+
],
|
|
365
|
+
unsubscribeType: 'marketing',
|
|
366
|
+
fromStamhoofd: true
|
|
367
|
+
});
|
|
368
|
+
email_1.Email.schedule(builder);
|
|
369
|
+
}
|
|
370
|
+
async deleteAWSMailIdenitity(mailDomain) {
|
|
371
|
+
// Protect specific domain names
|
|
372
|
+
if (["stamhoofd.be", "stamhoofd.nl", "stamhoofd.shop", "stamhoofd.app", "stamhoofd.email"].includes(mailDomain)) {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
if (STAMHOOFD.environment != "production") {
|
|
376
|
+
// Temporary ignore this
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
const sesv2 = new sesv2_1.default();
|
|
380
|
+
// Check if mail identitiy already exists..
|
|
381
|
+
let exists = false;
|
|
382
|
+
let existing = undefined;
|
|
383
|
+
try {
|
|
384
|
+
existing = await sesv2.getEmailIdentity({
|
|
385
|
+
EmailIdentity: mailDomain
|
|
386
|
+
}).promise();
|
|
387
|
+
exists = true;
|
|
388
|
+
// Check if DKIM keys are the same
|
|
389
|
+
if (existing.VerifiedForSendingStatus === true) {
|
|
390
|
+
console.log("Cant delete AWS mail idenitiy @" + this.id + " for " + mailDomain + ": already validated and might be in use by other organizations");
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
console.log("Deleting AWS mail idenitiy @" + this.id + " for " + mailDomain);
|
|
394
|
+
await sesv2.deleteEmailIdentity({
|
|
395
|
+
EmailIdentity: mailDomain
|
|
396
|
+
}).promise();
|
|
397
|
+
console.log("Deleted AWS mail idenitiy @" + this.id + " for " + this.privateMeta.mailDomain);
|
|
398
|
+
}
|
|
399
|
+
catch (e) {
|
|
400
|
+
console.error("Could not delete AWS email identitiy @" + this.id + " for " + this.privateMeta.mailDomain);
|
|
401
|
+
console.error(e);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Create or update the AWS mail idenitiy and also update the active state of the mailDomain
|
|
406
|
+
*/
|
|
407
|
+
async updateAWSMailIdenitity() {
|
|
408
|
+
var _a, _b, _c, _d;
|
|
409
|
+
if (this.privateMeta.mailDomain === null) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
// Protect specific domain names
|
|
413
|
+
if (["stamhoofd.be", "stamhoofd.nl", "stamhoofd.shop", "stamhoofd.app", "stamhoofd.email"].includes(this.privateMeta.mailDomain)) {
|
|
414
|
+
console.error("Tried to validate AWS mail identity with protected domains @" + this.id);
|
|
415
|
+
this.privateMeta.mailDomainActive = false;
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (STAMHOOFD.environment != "production") {
|
|
419
|
+
// Temporary ignore this
|
|
420
|
+
this.privateMeta.mailDomainActive = true;
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
const sesv2 = new sesv2_1.default();
|
|
424
|
+
// Check if mail identitiy already exists..
|
|
425
|
+
let exists = false;
|
|
426
|
+
let existing = undefined;
|
|
427
|
+
try {
|
|
428
|
+
existing = await sesv2.getEmailIdentity({
|
|
429
|
+
EmailIdentity: this.privateMeta.mailDomain
|
|
430
|
+
}).promise();
|
|
431
|
+
exists = true;
|
|
432
|
+
console.log("AWS mail idenitiy exists already: just checking the verification status in AWS @" + this.id);
|
|
433
|
+
if (existing.ConfigurationSetName !== "stamhoofd-domains") {
|
|
434
|
+
// Not allowed to use this identity
|
|
435
|
+
this.privateMeta.mailDomainActive = false;
|
|
436
|
+
console.error("Organization is not allowed to use email identity " + this.privateMeta.mailDomain + " @" + this.id + ", got " + existing.ConfigurationSetName);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
this.privateMeta.mailDomainActive = (_a = existing.VerifiedForSendingStatus) !== null && _a !== void 0 ? _a : false;
|
|
440
|
+
if (existing.VerifiedForSendingStatus !== true) {
|
|
441
|
+
console.error("Not validated @" + this.id);
|
|
442
|
+
}
|
|
443
|
+
if (existing.VerifiedForSendingStatus !== true && ((_b = existing.DkimAttributes) === null || _b === void 0 ? void 0 : _b.Status) === "FAILED") {
|
|
444
|
+
console.error("AWS failed to verify DKIM records. Triggering a forced recheck @" + this.id);
|
|
445
|
+
await sesv2.deleteEmailIdentity({
|
|
446
|
+
EmailIdentity: this.privateMeta.mailDomain
|
|
447
|
+
}).promise();
|
|
448
|
+
// Recreate it immediately
|
|
449
|
+
exists = false;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
catch (e) {
|
|
453
|
+
console.error(e);
|
|
454
|
+
}
|
|
455
|
+
if (!exists) {
|
|
456
|
+
console.log("Creating email identity in AWS SES...");
|
|
457
|
+
const result = await sesv2.createEmailIdentity({
|
|
458
|
+
EmailIdentity: this.privateMeta.mailDomain,
|
|
459
|
+
ConfigurationSetName: "stamhoofd-domains",
|
|
460
|
+
DkimSigningAttributes: {
|
|
461
|
+
DomainSigningPrivateKey: this.serverMeta.privateDKIMKey,
|
|
462
|
+
DomainSigningSelector: "stamhoofd"
|
|
463
|
+
},
|
|
464
|
+
Tags: [
|
|
465
|
+
{
|
|
466
|
+
"Key": "OrganizationId",
|
|
467
|
+
"Value": this.id
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
"Key": "Environment",
|
|
471
|
+
"Value": (_c = STAMHOOFD.environment) !== null && _c !== void 0 ? _c : "Unknown"
|
|
472
|
+
}
|
|
473
|
+
]
|
|
474
|
+
}).promise();
|
|
475
|
+
this.privateMeta.mailDomainActive = (_d = result.VerifiedForSendingStatus) !== null && _d !== void 0 ? _d : false;
|
|
476
|
+
// Disable email forwarding of bounces and complaints
|
|
477
|
+
// We handle this now with the configuration set
|
|
478
|
+
await sesv2.putEmailIdentityFeedbackAttributes({
|
|
479
|
+
EmailIdentity: this.privateMeta.mailDomain,
|
|
480
|
+
EmailForwardingEnabled: false
|
|
481
|
+
}).promise();
|
|
482
|
+
}
|
|
483
|
+
if (this.privateMeta.mailFromDomain && (!exists || (existing && (!existing.MailFromAttributes || existing.MailFromAttributes.MailFromDomain !== this.privateMeta.mailFromDomain)))) {
|
|
484
|
+
// Also set a from domain, to fix SPF
|
|
485
|
+
console.log("Setting mail from domain: " + this.privateMeta.mailFromDomain + " for " + this.id);
|
|
486
|
+
const params = {
|
|
487
|
+
EmailIdentity: this.privateMeta.mailDomain,
|
|
488
|
+
BehaviorOnMxFailure: "USE_DEFAULT_VALUE",
|
|
489
|
+
MailFromDomain: this.privateMeta.mailFromDomain,
|
|
490
|
+
};
|
|
491
|
+
await sesv2.putEmailIdentityMailFromAttributes(params).promise();
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
async checkDrips() {
|
|
495
|
+
const days7 = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
|
|
496
|
+
// Welcome drip
|
|
497
|
+
// Created maximum 7 days ago
|
|
498
|
+
if (this.createdAt > days7 && !this.serverMeta.hasEmail(structures_1.EmailTemplateType.OrganizationDripWelcome)) {
|
|
499
|
+
await this.sendEmailTemplate({
|
|
500
|
+
type: structures_1.EmailTemplateType.OrganizationDripWelcome,
|
|
501
|
+
personal: true
|
|
502
|
+
});
|
|
503
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripWelcome);
|
|
504
|
+
await this.save();
|
|
505
|
+
return; // Never send more than 1 drip email on the same day
|
|
506
|
+
}
|
|
507
|
+
// Webshop trial checkin
|
|
508
|
+
if (!this.serverMeta.hasEmail(structures_1.EmailTemplateType.OrganizationDripWebshopTrialCheckin)) {
|
|
509
|
+
if (this.meta.packages.isWebshopsTrial) {
|
|
510
|
+
const activeTime = this.meta.packages.getActiveTime(structures_1.STPackageType.TrialWebshops);
|
|
511
|
+
if (activeTime !== null && activeTime > 4 * 24 * 60 * 60 * 1000) {
|
|
512
|
+
// 7 days checkin
|
|
513
|
+
await this.sendEmailTemplate({
|
|
514
|
+
type: structures_1.EmailTemplateType.OrganizationDripWebshopTrialCheckin,
|
|
515
|
+
personal: true
|
|
516
|
+
});
|
|
517
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripWebshopTrialCheckin);
|
|
518
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripMembersTrialCheckin); // also mark members checkin
|
|
519
|
+
await this.save();
|
|
520
|
+
return; // Never send more than 1 drip email on the same day
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
// Members trial checkin
|
|
525
|
+
if (!this.serverMeta.hasEmail(structures_1.EmailTemplateType.OrganizationDripMembersTrialCheckin)) {
|
|
526
|
+
if (this.meta.packages.isMembersTrial) {
|
|
527
|
+
const activeTime = this.meta.packages.getActiveTime(structures_1.STPackageType.TrialMembers);
|
|
528
|
+
if (activeTime !== null && activeTime > 4 * 24 * 60 * 60 * 1000) {
|
|
529
|
+
// 7 days checkin
|
|
530
|
+
await this.sendEmailTemplate({
|
|
531
|
+
type: structures_1.EmailTemplateType.OrganizationDripMembersTrialCheckin,
|
|
532
|
+
personal: true
|
|
533
|
+
});
|
|
534
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripMembersTrialCheckin);
|
|
535
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripWebshopTrialCheckin); // Also mark webshop trial checkin
|
|
536
|
+
await this.save();
|
|
537
|
+
return; // Never send more than 1 drip email on the same day
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
// Webshop trial expired after 1 week
|
|
542
|
+
if (!this.serverMeta.hasEmail(structures_1.EmailTemplateType.OrganizationDripWebshopTrialExpired)) {
|
|
543
|
+
if (!this.meta.packages.useWebshops) {
|
|
544
|
+
const deactivatedTime = this.meta.packages.getDeactivatedTime(structures_1.STPackageType.TrialWebshops);
|
|
545
|
+
if (deactivatedTime !== null && deactivatedTime < 14 * 24 * 60 * 60 * 1000 && deactivatedTime > 7 * 24 * 60 * 60 * 1000) {
|
|
546
|
+
await this.sendEmailTemplate({
|
|
547
|
+
type: structures_1.EmailTemplateType.OrganizationDripWebshopTrialExpired,
|
|
548
|
+
personal: true
|
|
549
|
+
});
|
|
550
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripWebshopTrialExpired);
|
|
551
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripMembersTrialExpired); // also mark members
|
|
552
|
+
await this.save();
|
|
553
|
+
return; // Never send more than 1 drip email on the same day
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
if (!this.serverMeta.hasEmail(structures_1.EmailTemplateType.OrganizationDripMembersTrialExpired)) {
|
|
558
|
+
if (!this.meta.packages.useMembers) {
|
|
559
|
+
const deactivatedTime = this.meta.packages.getDeactivatedTime(structures_1.STPackageType.TrialMembers);
|
|
560
|
+
if (deactivatedTime !== null && deactivatedTime < 14 * 24 * 60 * 60 * 1000 && deactivatedTime > 7 * 24 * 60 * 60 * 1000) {
|
|
561
|
+
await this.sendEmailTemplate({
|
|
562
|
+
type: structures_1.EmailTemplateType.OrganizationDripMembersTrialExpired,
|
|
563
|
+
personal: true
|
|
564
|
+
});
|
|
565
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripMembersTrialExpired);
|
|
566
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripWebshopTrialExpired); // also mark webshops
|
|
567
|
+
await this.save();
|
|
568
|
+
return; // Never send more than 1 drip email on the same day
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
// trial expired reminder (after 10 months)
|
|
573
|
+
if (!this.serverMeta.hasEmail(structures_1.EmailTemplateType.OrganizationDripTrialExpiredReminder)) {
|
|
574
|
+
if (!this.meta.packages.isPaid && !this.meta.packages.wasPaid) {
|
|
575
|
+
const deactivatedTime1 = this.meta.packages.getDeactivatedTime(structures_1.STPackageType.TrialWebshops);
|
|
576
|
+
const deactivatedTime2 = this.meta.packages.getDeactivatedTime(structures_1.STPackageType.TrialMembers);
|
|
577
|
+
const deactivatedTime = deactivatedTime1 && deactivatedTime2 ? Math.max(deactivatedTime1, deactivatedTime2) : (deactivatedTime1 ? deactivatedTime1 : deactivatedTime2);
|
|
578
|
+
if (deactivatedTime !== null && deactivatedTime > 10 * 30 * 24 * 60 * 60 * 1000 && deactivatedTime < 13 * 31 * 24 * 60 * 60 * 1000) {
|
|
579
|
+
await this.sendEmailTemplate({
|
|
580
|
+
type: structures_1.EmailTemplateType.OrganizationDripTrialExpiredReminder,
|
|
581
|
+
personal: true,
|
|
582
|
+
bcc: true
|
|
583
|
+
});
|
|
584
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripTrialExpiredReminder);
|
|
585
|
+
await this.save();
|
|
586
|
+
return; // Never send more than 1 drip email on the same day
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
if (!this.serverMeta.hasEmail(structures_1.EmailTemplateType.OrganizationDripWebshopNotRenewed)) {
|
|
591
|
+
if (!this.meta.packages.useWebshops) {
|
|
592
|
+
const deactivatedTime = this.meta.packages.getDeactivatedTime(structures_1.STPackageType.Webshops);
|
|
593
|
+
if (deactivatedTime !== null && deactivatedTime > 30 * 24 * 60 * 60 * 1000 && deactivatedTime < 30 * 3 * 24 * 60 * 60 * 1000) {
|
|
594
|
+
await this.sendEmailTemplate({
|
|
595
|
+
type: structures_1.EmailTemplateType.OrganizationDripWebshopNotRenewed,
|
|
596
|
+
personal: true,
|
|
597
|
+
bcc: true
|
|
598
|
+
});
|
|
599
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripWebshopNotRenewed);
|
|
600
|
+
await this.save();
|
|
601
|
+
return; // Never send more than 1 drip email on the same day
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
if (!this.serverMeta.hasEmail(structures_1.EmailTemplateType.OrganizationDripMembersNotRenewed)) {
|
|
606
|
+
if (!this.meta.packages.useMembers) {
|
|
607
|
+
const deactivatedTime = this.meta.packages.getDeactivatedTime(structures_1.STPackageType.Members);
|
|
608
|
+
if (deactivatedTime !== null && deactivatedTime > 30 * 24 * 60 * 60 * 1000 && deactivatedTime < 30 * 3 * 24 * 60 * 60 * 1000) {
|
|
609
|
+
await this.sendEmailTemplate({
|
|
610
|
+
type: structures_1.EmailTemplateType.OrganizationDripMembersNotRenewed,
|
|
611
|
+
personal: true,
|
|
612
|
+
bcc: true
|
|
613
|
+
});
|
|
614
|
+
this.serverMeta.addEmail(structures_1.EmailTemplateType.OrganizationDripMembersNotRenewed);
|
|
615
|
+
await this.save();
|
|
616
|
+
return; // Never send more than 1 drip email on the same day
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* E-mail address when we receive replies for organization@stamhoofd.email.
|
|
623
|
+
* Note that this sould be private because it can contain personal e-mail addresses if the organization is not configured correctly
|
|
624
|
+
*/
|
|
625
|
+
async getReplyEmails() {
|
|
626
|
+
var _a;
|
|
627
|
+
const sender = (_a = this.privateMeta.emails.find(e => e.default)) !== null && _a !== void 0 ? _a : this.privateMeta.emails[0];
|
|
628
|
+
if (sender) {
|
|
629
|
+
return [
|
|
630
|
+
{
|
|
631
|
+
name: sender.name,
|
|
632
|
+
email: sender.email
|
|
633
|
+
}
|
|
634
|
+
];
|
|
635
|
+
}
|
|
636
|
+
return await this.getAdminToEmails();
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* These email addresess are private
|
|
640
|
+
*/
|
|
641
|
+
async getFullAdmins() {
|
|
642
|
+
// Circular reference fix
|
|
643
|
+
const User = (await Promise.resolve().then(() => tslib_1.__importStar(require('./User')))).User;
|
|
644
|
+
const admins = await User.getAdmins([this.id], { verified: true });
|
|
645
|
+
// Only full access
|
|
646
|
+
return admins.filter(a => a.permissions && a.permissions.hasFullAccess(this.privateMeta.roles));
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* These email addresess are private
|
|
650
|
+
*/
|
|
651
|
+
async getAdminToEmails() {
|
|
652
|
+
const filtered = await this.getFullAdmins();
|
|
653
|
+
if (STAMHOOFD.environment === "production") {
|
|
654
|
+
if (filtered.length > 1) {
|
|
655
|
+
// remove stamhoofd email addresses
|
|
656
|
+
const f = filtered.flatMap(f => f.getEmailTo()).filter(e => !e.email.endsWith("@stamhoofd.be") && !e.email.endsWith("@stamhoofd.nl"));
|
|
657
|
+
if (f.length > 0) {
|
|
658
|
+
return f;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return filtered.flatMap(f => f.getEmailTo());
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* These email addresess are private
|
|
666
|
+
*/
|
|
667
|
+
async getAdminRecipients() {
|
|
668
|
+
let filtered = await this.getFullAdmins();
|
|
669
|
+
if (STAMHOOFD.environment === "production") {
|
|
670
|
+
if (filtered.length > 1) {
|
|
671
|
+
// remove stamhoofd email addresses
|
|
672
|
+
filtered = filtered.filter(e => !e.email.endsWith("@stamhoofd.be") && !e.email.endsWith("@stamhoofd.nl"));
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return filtered.flatMap(f => {
|
|
676
|
+
var _a, _b;
|
|
677
|
+
return structures_1.Recipient.create({
|
|
678
|
+
firstName: f.firstName,
|
|
679
|
+
lastName: f.lastName,
|
|
680
|
+
email: f.email,
|
|
681
|
+
replacements: [
|
|
682
|
+
structures_1.Replacement.create({
|
|
683
|
+
token: "firstName",
|
|
684
|
+
value: (_a = f.firstName) !== null && _a !== void 0 ? _a : ""
|
|
685
|
+
}),
|
|
686
|
+
structures_1.Replacement.create({
|
|
687
|
+
token: "lastName",
|
|
688
|
+
value: (_b = f.lastName) !== null && _b !== void 0 ? _b : ""
|
|
689
|
+
}),
|
|
690
|
+
structures_1.Replacement.create({
|
|
691
|
+
token: "email",
|
|
692
|
+
value: f.email
|
|
693
|
+
}),
|
|
694
|
+
structures_1.Replacement.create({
|
|
695
|
+
token: "organizationName",
|
|
696
|
+
value: this.name
|
|
697
|
+
})
|
|
698
|
+
]
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* These email addresess are private
|
|
704
|
+
*/
|
|
705
|
+
async getInvoicingToEmails() {
|
|
706
|
+
// Circular reference fix
|
|
707
|
+
const User = (await Promise.resolve().then(() => tslib_1.__importStar(require('./User')))).User;
|
|
708
|
+
const admins = await User.where({ organizationId: this.id, permissions: { sign: "!=", value: null } });
|
|
709
|
+
const filtered = admins.filter(a => a.permissions && (a.permissions.hasFullAccess(this.privateMeta.roles) || a.permissions.hasFinanceAccess(this.privateMeta.roles)));
|
|
710
|
+
if (filtered.length > 0) {
|
|
711
|
+
return filtered.map(f => f.getEmailTo()).join(", ");
|
|
712
|
+
}
|
|
713
|
+
return undefined;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Return default e-mail address for important e-mails that should have the highest deliverability
|
|
717
|
+
*/
|
|
718
|
+
getStrongEmail(i18n, withName = true) {
|
|
719
|
+
if (!withName) {
|
|
720
|
+
return ('noreply-' + this.uri + "@" + i18n.$t("shared.domains.email"));
|
|
721
|
+
}
|
|
722
|
+
return '"' + this.name.replaceAll("\"", "\\\"") + '" <' + ('noreply-' + this.uri + "@" + i18n.$t("shared.domains.email")) + '>';
|
|
723
|
+
}
|
|
724
|
+
getEmail(id, strongDefault = false) {
|
|
725
|
+
if (id === null) {
|
|
726
|
+
return this.getDefaultEmail(strongDefault);
|
|
727
|
+
}
|
|
728
|
+
// Send confirmation e-mail
|
|
729
|
+
let from = strongDefault ? this.getStrongEmail(this.i18n, false) : this.uri + "@stamhoofd.email";
|
|
730
|
+
const sender = this.privateMeta.emails.find(e => e.id === id);
|
|
731
|
+
let replyTo = undefined;
|
|
732
|
+
if (sender) {
|
|
733
|
+
replyTo = sender.email;
|
|
734
|
+
// Can we send from this e-mail or reply-to?
|
|
735
|
+
if (replyTo && this.privateMeta.mailDomain && this.privateMeta.mailDomainActive && sender.email.endsWith("@" + this.privateMeta.mailDomain)) {
|
|
736
|
+
from = sender.email;
|
|
737
|
+
replyTo = undefined;
|
|
738
|
+
}
|
|
739
|
+
// Include name in form field
|
|
740
|
+
if (sender.name) {
|
|
741
|
+
from = '"' + sender.name.replaceAll("\"", "\\\"") + "\" <" + from + ">";
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
from = '"' + this.name.replaceAll("\"", "\\\"") + "\" <" + from + ">";
|
|
745
|
+
}
|
|
746
|
+
if (replyTo) {
|
|
747
|
+
if (sender.name) {
|
|
748
|
+
replyTo = '"' + sender.name.replaceAll("\"", "\\\"") + "\" <" + replyTo + ">";
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
replyTo = '"' + this.name.replaceAll("\"", "\\\"") + "\" <" + replyTo + ">";
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
return { from, replyTo };
|
|
755
|
+
}
|
|
756
|
+
return this.getDefaultEmail(strongDefault);
|
|
757
|
+
}
|
|
758
|
+
getGroupEmail(group) {
|
|
759
|
+
return this.getEmail(group.privateSettings.defaultEmailId);
|
|
760
|
+
}
|
|
761
|
+
getDefaultEmail(strongDefault = false) {
|
|
762
|
+
var _a;
|
|
763
|
+
// Send confirmation e-mail
|
|
764
|
+
let from = strongDefault ? this.getStrongEmail(this.i18n, false) : this.uri + "@stamhoofd.email";
|
|
765
|
+
const sender = (_a = this.privateMeta.emails.find(e => e.default)) !== null && _a !== void 0 ? _a : this.privateMeta.emails[0];
|
|
766
|
+
let replyTo = undefined;
|
|
767
|
+
if (sender) {
|
|
768
|
+
replyTo = sender.email;
|
|
769
|
+
// Can we send from this e-mail or reply-to?
|
|
770
|
+
if (replyTo && this.privateMeta.mailDomain && this.privateMeta.mailDomainActive && sender.email.endsWith("@" + this.privateMeta.mailDomain)) {
|
|
771
|
+
from = sender.email;
|
|
772
|
+
replyTo = undefined;
|
|
773
|
+
}
|
|
774
|
+
// Include name in form field
|
|
775
|
+
if (sender.name) {
|
|
776
|
+
from = '"' + sender.name.replaceAll("\"", "\\\"") + "\" <" + from + ">";
|
|
777
|
+
}
|
|
778
|
+
else {
|
|
779
|
+
from = '"' + this.name.replaceAll("\"", "\\\"") + "\" <" + from + ">";
|
|
780
|
+
}
|
|
781
|
+
if (replyTo) {
|
|
782
|
+
if (sender.name) {
|
|
783
|
+
replyTo = '"' + sender.name.replaceAll("\"", "\\\"") + "\" <" + replyTo + ">";
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
replyTo = '"' + this.name.replaceAll("\"", "\\\"") + "\" <" + replyTo + ">";
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
from = '"' + this.name.replaceAll("\"", "\\\"") + "\" <" + from + ">";
|
|
792
|
+
}
|
|
793
|
+
return {
|
|
794
|
+
from, replyTo
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
async getPaymentProviderFor(method, config) {
|
|
798
|
+
var _a;
|
|
799
|
+
let stripeAccount = (_a = (config.stripeAccountId ? (await _1.StripeAccount.getByID(config.stripeAccountId)) : null)) !== null && _a !== void 0 ? _a : null;
|
|
800
|
+
if (stripeAccount && stripeAccount.organizationId !== this.id) {
|
|
801
|
+
console.warn('Stripe account ' + stripeAccount.id + ' is not linked to organization ' + this.id);
|
|
802
|
+
stripeAccount = null;
|
|
803
|
+
}
|
|
804
|
+
const provider = this.privateMeta.getPaymentProviderFor(method, stripeAccount === null || stripeAccount === void 0 ? void 0 : stripeAccount.meta);
|
|
805
|
+
if (provider === null && ![structures_1.PaymentMethod.Unknown, structures_1.PaymentMethod.Transfer, structures_1.PaymentMethod.PointOfSale].includes(method)) {
|
|
806
|
+
if (!stripeAccount && config.stripeAccountId) {
|
|
807
|
+
console.warn('Missing stripe account id ' + config.stripeAccountId);
|
|
808
|
+
}
|
|
809
|
+
throw new simple_errors_1.SimpleError({
|
|
810
|
+
code: 'payment_provider_not_configured',
|
|
811
|
+
message: 'Payment provider not configured for ' + method,
|
|
812
|
+
human: 'Deze betaalmethode werd helaas niet volledig geconfigureerd. Probeer later even opnieuw, neem contact met ons op of kies een andere betaalmethode.'
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
return {
|
|
816
|
+
provider,
|
|
817
|
+
stripeAccount
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
async getConnectedPaymentProviders() {
|
|
821
|
+
const allPaymentMethods = Object.values(structures_1.PaymentMethod);
|
|
822
|
+
const providers = [];
|
|
823
|
+
let stripeAccounts = await _1.StripeAccount.where({ organizationId: this.id, status: 'active' });
|
|
824
|
+
if (stripeAccounts.length === 0) {
|
|
825
|
+
stripeAccounts = [null];
|
|
826
|
+
}
|
|
827
|
+
for (const account of stripeAccounts) {
|
|
828
|
+
for (const method of allPaymentMethods) {
|
|
829
|
+
const provider = this.privateMeta.getPaymentProviderFor(method, account === null || account === void 0 ? void 0 : account.meta);
|
|
830
|
+
if (provider && !providers.includes(provider)) {
|
|
831
|
+
providers.push(provider);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
return providers;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
exports.Organization = Organization;
|
|
839
|
+
Organization.table = "organizations";
|
|
840
|
+
tslib_1.__decorate([
|
|
841
|
+
(0, simple_database_1.column)({
|
|
842
|
+
primary: true, type: "string", beforeSave(value) {
|
|
843
|
+
return value !== null && value !== void 0 ? value : (0, uuid_1.v4)();
|
|
844
|
+
}
|
|
845
|
+
})
|
|
846
|
+
], Organization.prototype, "id", void 0);
|
|
847
|
+
tslib_1.__decorate([
|
|
848
|
+
(0, simple_database_1.column)({ type: "string" })
|
|
849
|
+
], Organization.prototype, "name", void 0);
|
|
850
|
+
tslib_1.__decorate([
|
|
851
|
+
(0, simple_database_1.column)({ type: "string", nullable: true })
|
|
852
|
+
], Organization.prototype, "website", void 0);
|
|
853
|
+
tslib_1.__decorate([
|
|
854
|
+
(0, simple_database_1.column)({ type: "string", nullable: true })
|
|
855
|
+
], Organization.prototype, "registerDomain", void 0);
|
|
856
|
+
tslib_1.__decorate([
|
|
857
|
+
(0, simple_database_1.column)({ type: "string" })
|
|
858
|
+
], Organization.prototype, "uri", void 0);
|
|
859
|
+
tslib_1.__decorate([
|
|
860
|
+
(0, simple_database_1.column)({ type: "json", decoder: structures_1.OrganizationMetaData })
|
|
861
|
+
], Organization.prototype, "meta", void 0);
|
|
862
|
+
tslib_1.__decorate([
|
|
863
|
+
(0, simple_database_1.column)({ type: "json", decoder: structures_1.OrganizationPrivateMetaData })
|
|
864
|
+
], Organization.prototype, "privateMeta", void 0);
|
|
865
|
+
tslib_1.__decorate([
|
|
866
|
+
(0, simple_database_1.column)({ type: "json", decoder: OrganizationServerMetaData_1.OrganizationServerMetaData })
|
|
867
|
+
], Organization.prototype, "serverMeta", void 0);
|
|
868
|
+
tslib_1.__decorate([
|
|
869
|
+
(0, simple_database_1.column)({ type: "json", decoder: structures_1.Address })
|
|
870
|
+
], Organization.prototype, "address", void 0);
|
|
871
|
+
tslib_1.__decorate([
|
|
872
|
+
(0, simple_database_1.column)({
|
|
873
|
+
type: "string", beforeSave: function () {
|
|
874
|
+
return this.name + "\n" + this.address.toString();
|
|
875
|
+
}
|
|
876
|
+
})
|
|
877
|
+
], Organization.prototype, "searchIndex", void 0);
|
|
878
|
+
tslib_1.__decorate([
|
|
879
|
+
(0, simple_database_1.column)({
|
|
880
|
+
type: "datetime", beforeSave(old) {
|
|
881
|
+
if (old !== undefined) {
|
|
882
|
+
return old;
|
|
883
|
+
}
|
|
884
|
+
const date = new Date();
|
|
885
|
+
date.setMilliseconds(0);
|
|
886
|
+
return date;
|
|
887
|
+
}
|
|
888
|
+
})
|
|
889
|
+
], Organization.prototype, "createdAt", void 0);
|
|
890
|
+
tslib_1.__decorate([
|
|
891
|
+
(0, simple_database_1.column)({
|
|
892
|
+
type: "datetime", beforeSave() {
|
|
893
|
+
const date = new Date();
|
|
894
|
+
date.setMilliseconds(0);
|
|
895
|
+
return date;
|
|
896
|
+
},
|
|
897
|
+
skipUpdate: true
|
|
898
|
+
})
|
|
899
|
+
], Organization.prototype, "updatedAt", void 0);
|
|
900
|
+
//# sourceMappingURL=Organization.js.map
|