@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.
Files changed (352) hide show
  1. package/dist/src/factories/AddressFactory.d.ts +3 -4
  2. package/dist/src/factories/AddressFactory.d.ts.map +1 -1
  3. package/dist/src/factories/AddressFactory.js +13 -13
  4. package/dist/src/factories/EmergencyContactFactory.d.ts +3 -4
  5. package/dist/src/factories/EmergencyContactFactory.d.ts.map +1 -1
  6. package/dist/src/factories/EmergencyContactFactory.js +27 -27
  7. package/dist/src/factories/EmergencyContactFactory.js.map +1 -1
  8. package/dist/src/factories/GroupFactory.d.ts +4 -4
  9. package/dist/src/factories/GroupFactory.d.ts.map +1 -1
  10. package/dist/src/factories/GroupFactory.js +8 -8
  11. package/dist/src/factories/GroupFactory.js.map +1 -1
  12. package/dist/src/factories/MemberFactory.d.ts +4 -4
  13. package/dist/src/factories/MemberFactory.d.ts.map +1 -1
  14. package/dist/src/factories/MemberFactory.js +17 -17
  15. package/dist/src/factories/MemberFactory.js.map +1 -1
  16. package/dist/src/factories/OrganizationFactory.d.ts +4 -4
  17. package/dist/src/factories/OrganizationFactory.js +8 -8
  18. package/dist/src/factories/OrganizationFactory.js.map +1 -1
  19. package/dist/src/factories/ParentFactory.d.ts +1 -1
  20. package/dist/src/factories/ParentFactory.js +19 -19
  21. package/dist/src/factories/ParentFactory.js.map +1 -1
  22. package/dist/src/factories/RecordFactory.d.ts +2 -3
  23. package/dist/src/factories/RecordFactory.d.ts.map +1 -1
  24. package/dist/src/factories/RecordFactory.js +1 -1
  25. package/dist/src/factories/RecordFactory.js.map +1 -1
  26. package/dist/src/factories/RegisterCodeFactory.d.ts +2 -2
  27. package/dist/src/factories/RegisterCodeFactory.d.ts.map +1 -1
  28. package/dist/src/factories/RegisterCodeFactory.js +2 -2
  29. package/dist/src/factories/RegistrationFactory.d.ts +3 -3
  30. package/dist/src/factories/RegistrationFactory.d.ts.map +1 -1
  31. package/dist/src/factories/RegistrationFactory.js.map +1 -1
  32. package/dist/src/factories/RegistrationPeriodFactory.d.ts +2 -2
  33. package/dist/src/factories/RegistrationPeriodFactory.js.map +1 -1
  34. package/dist/src/factories/UserFactory.d.ts +3 -3
  35. package/dist/src/factories/UserFactory.d.ts.map +1 -1
  36. package/dist/src/factories/UserFactory.js +3 -3
  37. package/dist/src/factories/UserFactory.js.map +1 -1
  38. package/dist/src/factories/WebshopFactory.d.ts +4 -4
  39. package/dist/src/factories/WebshopFactory.d.ts.map +1 -1
  40. package/dist/src/factories/WebshopFactory.js +1 -1
  41. package/dist/src/factories/WebshopFactory.js.map +1 -1
  42. package/dist/src/helpers/DNSValidator.d.ts +1 -1
  43. package/dist/src/helpers/DNSValidator.d.ts.map +1 -1
  44. package/dist/src/helpers/DNSValidator.js +33 -33
  45. package/dist/src/helpers/DNSValidator.js.map +1 -1
  46. package/dist/src/helpers/EmailBuilder.d.ts +10 -10
  47. package/dist/src/helpers/EmailBuilder.d.ts.map +1 -1
  48. package/dist/src/helpers/EmailBuilder.js +34 -34
  49. package/dist/src/helpers/EmailBuilder.js.map +1 -1
  50. package/dist/src/helpers/GroupBuilder.d.ts.map +1 -1
  51. package/dist/src/helpers/GroupBuilder.js +57 -57
  52. package/dist/src/helpers/GroupBuilder.js.map +1 -1
  53. package/dist/src/helpers/Handlebars.d.ts.map +1 -1
  54. package/dist/src/helpers/Handlebars.js +29 -29
  55. package/dist/src/helpers/Handlebars.js.map +1 -1
  56. package/dist/src/helpers/MemberMerger.d.ts +1 -1
  57. package/dist/src/helpers/MemberMerger.d.ts.map +1 -1
  58. package/dist/src/helpers/MemberMerger.js +33 -33
  59. package/dist/src/helpers/MemberMerger.js.map +1 -1
  60. package/dist/src/helpers/MemberMerger.test.js +194 -194
  61. package/dist/src/helpers/MemberMerger.test.js.map +1 -1
  62. package/dist/src/helpers/RateLimiter.d.ts.map +1 -1
  63. package/dist/src/helpers/RateLimiter.js +2 -2
  64. package/dist/src/helpers/RateLimiter.js.map +1 -1
  65. package/dist/src/helpers/SetupStepsUpdater.d.ts +22 -0
  66. package/dist/src/helpers/SetupStepsUpdater.d.ts.map +1 -0
  67. package/dist/src/helpers/SetupStepsUpdater.js +255 -0
  68. package/dist/src/helpers/SetupStepsUpdater.js.map +1 -0
  69. package/dist/src/helpers/WebshopCounter.d.ts +1 -1
  70. package/dist/src/helpers/WebshopCounter.d.ts.map +1 -1
  71. package/dist/src/helpers/WebshopCounter.js +1 -1
  72. package/dist/src/helpers/WebshopCounter.js.map +1 -1
  73. package/dist/src/helpers/WebshopCounter.test.js +6 -6
  74. package/dist/src/helpers/WebshopCounter.test.js.map +1 -1
  75. package/dist/src/index.d.ts +20 -19
  76. package/dist/src/index.d.ts.map +1 -1
  77. package/dist/src/index.js +1 -0
  78. package/dist/src/index.js.map +1 -1
  79. package/dist/src/migrations/1605262045-import-postcodes.js +12 -12
  80. package/dist/src/migrations/1605262046-import-postcodes-nl.js +10 -10
  81. package/dist/src/models/BalanceItem.d.ts.map +1 -1
  82. package/dist/src/models/BalanceItem.js +37 -37
  83. package/dist/src/models/BalanceItem.js.map +1 -1
  84. package/dist/src/models/BalanceItemPayment.d.ts.map +1 -1
  85. package/dist/src/models/BalanceItemPayment.js +13 -13
  86. package/dist/src/models/BalanceItemPayment.js.map +1 -1
  87. package/dist/src/models/BuckarooPayment.d.ts +1 -1
  88. package/dist/src/models/BuckarooPayment.d.ts.map +1 -1
  89. package/dist/src/models/BuckarooPayment.js +5 -5
  90. package/dist/src/models/BuckarooPayment.js.map +1 -1
  91. package/dist/src/models/CachedOutstandingBalance.d.ts.map +1 -1
  92. package/dist/src/models/CachedOutstandingBalance.js +37 -37
  93. package/dist/src/models/CachedOutstandingBalance.js.map +1 -1
  94. package/dist/src/models/Document.d.ts +4 -4
  95. package/dist/src/models/Document.d.ts.map +1 -1
  96. package/dist/src/models/Document.js +27 -27
  97. package/dist/src/models/Document.js.map +1 -1
  98. package/dist/src/models/DocumentTemplate.d.ts +4 -4
  99. package/dist/src/models/DocumentTemplate.d.ts.map +1 -1
  100. package/dist/src/models/DocumentTemplate.js +72 -72
  101. package/dist/src/models/DocumentTemplate.js.map +1 -1
  102. package/dist/src/models/Email.d.ts.map +1 -1
  103. package/dist/src/models/Email.js +63 -64
  104. package/dist/src/models/Email.js.map +1 -1
  105. package/dist/src/models/EmailRecipient.d.ts.map +1 -1
  106. package/dist/src/models/EmailRecipient.js +20 -20
  107. package/dist/src/models/EmailRecipient.js.map +1 -1
  108. package/dist/src/models/EmailTemplate.d.ts +3 -3
  109. package/dist/src/models/EmailTemplate.d.ts.map +1 -1
  110. package/dist/src/models/EmailTemplate.js +16 -16
  111. package/dist/src/models/EmailTemplate.js.map +1 -1
  112. package/dist/src/models/EmailVerificationCode.d.ts +2 -2
  113. package/dist/src/models/EmailVerificationCode.d.ts.map +1 -1
  114. package/dist/src/models/EmailVerificationCode.js +57 -55
  115. package/dist/src/models/EmailVerificationCode.js.map +1 -1
  116. package/dist/src/models/Event.d.ts +2 -2
  117. package/dist/src/models/Event.d.ts.map +1 -1
  118. package/dist/src/models/Event.js +15 -15
  119. package/dist/src/models/Event.js.map +1 -1
  120. package/dist/src/models/Group.d.ts +3 -1
  121. package/dist/src/models/Group.d.ts.map +1 -1
  122. package/dist/src/models/Group.js +46 -35
  123. package/dist/src/models/Group.js.map +1 -1
  124. package/dist/src/models/Image.d.ts +1 -1
  125. package/dist/src/models/Image.d.ts.map +1 -1
  126. package/dist/src/models/Image.js +26 -26
  127. package/dist/src/models/Image.js.map +1 -1
  128. package/dist/src/models/Member.d.ts +8 -8
  129. package/dist/src/models/Member.d.ts.map +1 -1
  130. package/dist/src/models/Member.js +60 -60
  131. package/dist/src/models/Member.js.map +1 -1
  132. package/dist/src/models/MemberPlatformMembership.d.ts +3 -3
  133. package/dist/src/models/MemberPlatformMembership.d.ts.map +1 -1
  134. package/dist/src/models/MemberPlatformMembership.js +26 -26
  135. package/dist/src/models/MemberPlatformMembership.js.map +1 -1
  136. package/dist/src/models/MemberResponsibilityRecord.d.ts.map +1 -1
  137. package/dist/src/models/MemberResponsibilityRecord.js +13 -13
  138. package/dist/src/models/MemberResponsibilityRecord.js.map +1 -1
  139. package/dist/src/models/MergedMember.d.ts +3 -3
  140. package/dist/src/models/MergedMember.d.ts.map +1 -1
  141. package/dist/src/models/MergedMember.js +19 -19
  142. package/dist/src/models/MergedMember.js.map +1 -1
  143. package/dist/src/models/MolliePayment.d.ts +1 -1
  144. package/dist/src/models/MolliePayment.d.ts.map +1 -1
  145. package/dist/src/models/MolliePayment.js +5 -5
  146. package/dist/src/models/MolliePayment.js.map +1 -1
  147. package/dist/src/models/MollieToken.d.ts.map +1 -1
  148. package/dist/src/models/MollieToken.js +60 -60
  149. package/dist/src/models/MollieToken.js.map +1 -1
  150. package/dist/src/models/OneTimeToken.d.ts +2 -2
  151. package/dist/src/models/OneTimeToken.d.ts.map +1 -1
  152. package/dist/src/models/OneTimeToken.js +13 -13
  153. package/dist/src/models/OneTimeToken.js.map +1 -1
  154. package/dist/src/models/Order.d.ts +1 -1
  155. package/dist/src/models/Order.d.ts.map +1 -1
  156. package/dist/src/models/Order.js +70 -70
  157. package/dist/src/models/Order.js.map +1 -1
  158. package/dist/src/models/Organization.d.ts +5 -5
  159. package/dist/src/models/Organization.d.ts.map +1 -1
  160. package/dist/src/models/Organization.js +127 -127
  161. package/dist/src/models/Organization.js.map +1 -1
  162. package/dist/src/models/OrganizationRegistrationPeriod.d.ts.map +1 -1
  163. package/dist/src/models/OrganizationRegistrationPeriod.js +15 -15
  164. package/dist/src/models/OrganizationRegistrationPeriod.js.map +1 -1
  165. package/dist/src/models/PasswordToken.d.ts +3 -3
  166. package/dist/src/models/PasswordToken.d.ts.map +1 -1
  167. package/dist/src/models/PasswordToken.js +17 -17
  168. package/dist/src/models/PasswordToken.js.map +1 -1
  169. package/dist/src/models/PayconiqPayment.d.ts +1 -1
  170. package/dist/src/models/PayconiqPayment.d.ts.map +1 -1
  171. package/dist/src/models/PayconiqPayment.js +49 -49
  172. package/dist/src/models/PayconiqPayment.js.map +1 -1
  173. package/dist/src/models/Payment.d.ts +3 -3
  174. package/dist/src/models/Payment.d.ts.map +1 -1
  175. package/dist/src/models/Payment.js +36 -36
  176. package/dist/src/models/Payment.js.map +1 -1
  177. package/dist/src/models/Platform.d.ts +2 -2
  178. package/dist/src/models/Platform.d.ts.map +1 -1
  179. package/dist/src/models/Platform.js +8 -8
  180. package/dist/src/models/Platform.js.map +1 -1
  181. package/dist/src/models/RegisterCode.d.ts +1 -1
  182. package/dist/src/models/RegisterCode.d.ts.map +1 -1
  183. package/dist/src/models/RegisterCode.js +11 -11
  184. package/dist/src/models/RegisterCode.js.map +1 -1
  185. package/dist/src/models/Registration.d.ts +1 -1
  186. package/dist/src/models/Registration.d.ts.map +1 -1
  187. package/dist/src/models/Registration.js +88 -88
  188. package/dist/src/models/Registration.js.map +1 -1
  189. package/dist/src/models/RegistrationPeriod.d.ts.map +1 -1
  190. package/dist/src/models/RegistrationPeriod.js +12 -12
  191. package/dist/src/models/RegistrationPeriod.js.map +1 -1
  192. package/dist/src/models/STCredit.d.ts +1 -1
  193. package/dist/src/models/STCredit.d.ts.map +1 -1
  194. package/dist/src/models/STCredit.js +12 -12
  195. package/dist/src/models/STCredit.js.map +1 -1
  196. package/dist/src/models/STInvoice.d.ts +1 -1
  197. package/dist/src/models/STInvoice.d.ts.map +1 -1
  198. package/dist/src/models/STInvoice.js +16 -16
  199. package/dist/src/models/STInvoice.js.map +1 -1
  200. package/dist/src/models/STPackage.d.ts +1 -1
  201. package/dist/src/models/STPackage.d.ts.map +1 -1
  202. package/dist/src/models/STPackage.js +39 -39
  203. package/dist/src/models/STPackage.js.map +1 -1
  204. package/dist/src/models/STPendingInvoice.d.ts +1 -1
  205. package/dist/src/models/STPendingInvoice.d.ts.map +1 -1
  206. package/dist/src/models/STPendingInvoice.js +11 -11
  207. package/dist/src/models/STPendingInvoice.js.map +1 -1
  208. package/dist/src/models/StripeAccount.d.ts.map +1 -1
  209. package/dist/src/models/StripeAccount.js +13 -13
  210. package/dist/src/models/StripeAccount.js.map +1 -1
  211. package/dist/src/models/StripeCheckoutSession.d.ts +1 -1
  212. package/dist/src/models/StripeCheckoutSession.d.ts.map +1 -1
  213. package/dist/src/models/StripeCheckoutSession.js +7 -7
  214. package/dist/src/models/StripeCheckoutSession.js.map +1 -1
  215. package/dist/src/models/StripePaymentIntent.d.ts +1 -1
  216. package/dist/src/models/StripePaymentIntent.d.ts.map +1 -1
  217. package/dist/src/models/StripePaymentIntent.js +7 -7
  218. package/dist/src/models/StripePaymentIntent.js.map +1 -1
  219. package/dist/src/models/Ticket.d.ts +2 -2
  220. package/dist/src/models/Ticket.d.ts.map +1 -1
  221. package/dist/src/models/Ticket.js +23 -23
  222. package/dist/src/models/Ticket.js.map +1 -1
  223. package/dist/src/models/Token.d.ts +3 -3
  224. package/dist/src/models/Token.d.ts.map +1 -1
  225. package/dist/src/models/Token.js +27 -27
  226. package/dist/src/models/Token.js.map +1 -1
  227. package/dist/src/models/Token.test.js +11 -11
  228. package/dist/src/models/UsedRegisterCode.d.ts +1 -1
  229. package/dist/src/models/UsedRegisterCode.d.ts.map +1 -1
  230. package/dist/src/models/UsedRegisterCode.js +10 -10
  231. package/dist/src/models/UsedRegisterCode.js.map +1 -1
  232. package/dist/src/models/User.d.ts +4 -4
  233. package/dist/src/models/User.d.ts.map +1 -1
  234. package/dist/src/models/User.js +53 -51
  235. package/dist/src/models/User.js.map +1 -1
  236. package/dist/src/models/UserPermissions.d.ts +3 -3
  237. package/dist/src/models/UserPermissions.d.ts.map +1 -1
  238. package/dist/src/models/UserPermissions.js +12 -12
  239. package/dist/src/models/UserPermissions.js.map +1 -1
  240. package/dist/src/models/Webshop.d.ts +1 -1
  241. package/dist/src/models/Webshop.d.ts.map +1 -1
  242. package/dist/src/models/Webshop.js +23 -23
  243. package/dist/src/models/Webshop.js.map +1 -1
  244. package/dist/src/models/WebshopDiscountCode.d.ts +1 -1
  245. package/dist/src/models/WebshopDiscountCode.d.ts.map +1 -1
  246. package/dist/src/models/WebshopDiscountCode.js +16 -16
  247. package/dist/src/models/WebshopDiscountCode.js.map +1 -1
  248. package/dist/src/models/addresses/City.d.ts.map +1 -1
  249. package/dist/src/models/addresses/City.js +9 -9
  250. package/dist/src/models/addresses/City.js.map +1 -1
  251. package/dist/src/models/addresses/PostalCode.d.ts.map +1 -1
  252. package/dist/src/models/addresses/PostalCode.js +11 -11
  253. package/dist/src/models/addresses/PostalCode.js.map +1 -1
  254. package/dist/src/models/addresses/PostalCode.test.js +22 -22
  255. package/dist/src/models/addresses/PostalCode.test.js.map +1 -1
  256. package/dist/src/models/addresses/Province.d.ts.map +1 -1
  257. package/dist/src/models/addresses/Province.js +5 -5
  258. package/dist/src/models/addresses/Province.js.map +1 -1
  259. package/dist/src/models/addresses/Street.d.ts.map +1 -1
  260. package/dist/src/models/addresses/Street.js +6 -6
  261. package/dist/src/models/addresses/Street.js.map +1 -1
  262. package/dist/src/models/index.d.ts +46 -46
  263. package/dist/src/models/index.d.ts.map +1 -1
  264. package/dist/src/models/index.js +0 -1
  265. package/dist/src/models/index.js.map +1 -1
  266. package/dist/src/structures/OrganizationServerMetaData.d.ts.map +1 -1
  267. package/dist/src/structures/OrganizationServerMetaData.js +4 -4
  268. package/dist/src/structures/OrganizationServerMetaData.js.map +1 -1
  269. package/dist/tests/jest.global.setup.d.ts.map +1 -1
  270. package/dist/tests/jest.global.setup.js +15 -13
  271. package/dist/tests/jest.global.setup.js.map +1 -1
  272. package/dist/tests/jest.setup.js +3 -1
  273. package/dist/tests/jest.setup.js.map +1 -1
  274. package/dist/tsconfig.tsbuildinfo +1 -0
  275. package/package.json +3 -3
  276. package/src/factories/AddressFactory.ts +17 -17
  277. package/src/factories/EmergencyContactFactory.ts +30 -31
  278. package/src/factories/GroupFactory.ts +30 -30
  279. package/src/factories/MemberFactory.ts +41 -38
  280. package/src/factories/OrganizationFactory.ts +15 -15
  281. package/src/factories/ParentFactory.ts +24 -24
  282. package/src/factories/RecordFactory.ts +5 -4
  283. package/src/factories/RegisterCodeFactory.ts +7 -7
  284. package/src/factories/RegistrationFactory.ts +16 -16
  285. package/src/factories/RegistrationPeriodFactory.ts +5 -5
  286. package/src/factories/UserFactory.ts +20 -19
  287. package/src/factories/WebshopFactory.ts +14 -14
  288. package/src/helpers/DNSValidator.ts +89 -84
  289. package/src/helpers/EmailBuilder.ts +141 -135
  290. package/src/helpers/GroupBuilder.ts +181 -181
  291. package/src/helpers/Handlebars.ts +57 -54
  292. package/src/helpers/MemberMerger.test.ts +702 -702
  293. package/src/helpers/MemberMerger.ts +83 -77
  294. package/src/helpers/RateLimiter.ts +25 -27
  295. package/src/helpers/SetupStepsUpdater.ts +402 -0
  296. package/src/helpers/WebshopCounter.test.ts +12 -12
  297. package/src/helpers/WebshopCounter.ts +20 -19
  298. package/src/index.ts +20 -19
  299. package/src/migrations/1605262045-import-postcodes.ts +59 -63
  300. package/src/migrations/1605262046-import-postcodes-nl.ts +41 -43
  301. package/src/models/BalanceItem.ts +173 -172
  302. package/src/models/BalanceItemPayment.ts +32 -33
  303. package/src/models/BuckarooPayment.ts +7 -7
  304. package/src/models/CachedOutstandingBalance.ts +98 -99
  305. package/src/models/Document.ts +90 -87
  306. package/src/models/DocumentTemplate.ts +207 -198
  307. package/src/models/Email.ts +198 -200
  308. package/src/models/EmailRecipient.ts +38 -39
  309. package/src/models/EmailTemplate.ts +36 -37
  310. package/src/models/EmailVerificationCode.ts +146 -142
  311. package/src/models/Event.ts +53 -53
  312. package/src/models/Group.ts +136 -123
  313. package/src/models/Image.ts +48 -48
  314. package/src/models/Member.ts +277 -275
  315. package/src/models/MemberPlatformMembership.ts +71 -71
  316. package/src/models/MemberResponsibilityRecord.ts +32 -32
  317. package/src/models/MergedMember.ts +77 -77
  318. package/src/models/MolliePayment.ts +7 -7
  319. package/src/models/MollieToken.ts +131 -126
  320. package/src/models/OneTimeToken.ts +40 -39
  321. package/src/models/Order.ts +379 -372
  322. package/src/models/Organization.ts +332 -325
  323. package/src/models/OrganizationRegistrationPeriod.ts +50 -50
  324. package/src/models/PasswordToken.ts +42 -42
  325. package/src/models/PayconiqPayment.ts +80 -76
  326. package/src/models/Payment.ts +86 -86
  327. package/src/models/Platform.ts +21 -22
  328. package/src/models/RegisterCode.ts +26 -26
  329. package/src/models/Registration.ts +167 -168
  330. package/src/models/RegistrationPeriod.ts +29 -29
  331. package/src/models/STCredit.ts +24 -25
  332. package/src/models/STInvoice.ts +34 -34
  333. package/src/models/STPackage.ts +143 -136
  334. package/src/models/STPendingInvoice.ts +26 -26
  335. package/src/models/StripeAccount.ts +27 -27
  336. package/src/models/StripeCheckoutSession.ts +10 -10
  337. package/src/models/StripePaymentIntent.ts +10 -10
  338. package/src/models/Ticket.ts +51 -52
  339. package/src/models/Token.test.ts +13 -13
  340. package/src/models/Token.ts +64 -63
  341. package/src/models/UsedRegisterCode.ts +20 -21
  342. package/src/models/User.ts +148 -144
  343. package/src/models/UserPermissions.ts +25 -28
  344. package/src/models/Webshop.ts +53 -53
  345. package/src/models/WebshopDiscountCode.ts +33 -33
  346. package/src/models/addresses/City.ts +12 -12
  347. package/src/models/addresses/PostalCode.test.ts +68 -69
  348. package/src/models/addresses/PostalCode.ts +57 -57
  349. package/src/models/addresses/Province.ts +8 -8
  350. package/src/models/addresses/Street.ts +10 -12
  351. package/src/models/index.ts +54 -55
  352. package/src/structures/OrganizationServerMetaData.ts +36 -36
@@ -1,123 +1,122 @@
1
- import { column, Database, Model } from "@simonbackx/simple-database";
1
+ import { column, Database, Model } from '@simonbackx/simple-database';
2
2
  import { DecodedRequest } from '@simonbackx/simple-endpoints';
3
3
  import { SimpleError } from '@simonbackx/simple-errors';
4
- import { I18n } from "@stamhoofd/backend-i18n";
5
- import { Email, EmailInterfaceRecipient } from "@stamhoofd/email";
6
- import { Address, Country, DNSRecordStatus, EmailTemplateType, OrganizationEmail, OrganizationMetaData, OrganizationPrivateMetaData, Organization as OrganizationStruct, PaymentMethod, PaymentProvider, PrivatePaymentConfiguration, Recipient, Replacement, STPackageType, TransferSettings } from "@stamhoofd/structures";
4
+ import { I18n } from '@stamhoofd/backend-i18n';
5
+ import { Email, EmailInterfaceRecipient } from '@stamhoofd/email';
6
+ import { Address, Country, DNSRecordStatus, EmailTemplateType, OrganizationEmail, OrganizationMetaData, OrganizationPrivateMetaData, Organization as OrganizationStruct, PaymentMethod, PaymentProvider, PrivatePaymentConfiguration, Recipient, Replacement, STPackageType, TransferSettings } from '@stamhoofd/structures';
7
7
  import { AWSError } from 'aws-sdk';
8
8
  import SES from 'aws-sdk/clients/sesv2';
9
9
  import { PromiseResult } from 'aws-sdk/lib/request';
10
- import { v4 as uuidv4 } from "uuid";
10
+ import { v4 as uuidv4 } from 'uuid';
11
11
 
12
- import { QueueHandler } from "@stamhoofd/queues";
13
- import { validateDNSRecords } from "../helpers/DNSValidator";
14
- import { getEmailBuilderForTemplate } from "../helpers/EmailBuilder";
12
+ import { QueueHandler } from '@stamhoofd/queues';
13
+ import { validateDNSRecords } from '../helpers/DNSValidator';
14
+ import { getEmailBuilderForTemplate } from '../helpers/EmailBuilder';
15
15
  import { OrganizationServerMetaData } from '../structures/OrganizationServerMetaData';
16
- import { OrganizationRegistrationPeriod, StripeAccount } from "./";
16
+ import { OrganizationRegistrationPeriod, StripeAccount } from './';
17
17
 
18
18
  export class Organization extends Model {
19
- static table = "organizations";
19
+ static table = 'organizations';
20
20
 
21
21
  @column({
22
- primary: true, type: "string", beforeSave(value) {
22
+ primary: true, type: 'string', beforeSave(value) {
23
23
  return value ?? uuidv4();
24
- }
24
+ },
25
25
  })
26
26
  id!: string;
27
27
 
28
- @column({ type: "string" })
28
+ @column({ type: 'string' })
29
29
  name: string;
30
30
 
31
31
  /// URL to a website page or a Facebook page (including http)
32
- @column({ type: "string", nullable: true })
32
+ @column({ type: 'string', nullable: true })
33
33
  website: string | null = null;
34
34
 
35
35
  /// A custom domain name that is used to host the register application (should be unique)
36
36
  // E.g. inschrijven.scoutswetteren.be
37
- @column({ type: "string", nullable: true })
37
+ @column({ type: 'string', nullable: true })
38
38
  registerDomain: string | null = null;
39
39
 
40
40
  // Unique representation of this organization from a string, that is used to provide the default domains
41
41
  // in uri.stamhoofd.be
42
- @column({ type: "string" })
42
+ @column({ type: 'string' })
43
43
  uri: string;
44
44
 
45
- @column({ type: "string" })
45
+ @column({ type: 'string' })
46
46
  periodId: string;
47
47
 
48
48
  /**
49
49
  * Public meta data
50
50
  */
51
- @column({ type: "json", decoder: OrganizationMetaData })
51
+ @column({ type: 'json', decoder: OrganizationMetaData })
52
52
  meta: OrganizationMetaData;
53
53
 
54
54
  /**
55
55
  * Data only accessible by the owners / users with special permissions
56
56
  */
57
- @column({ type: "json", decoder: OrganizationPrivateMetaData })
58
- privateMeta: OrganizationPrivateMetaData = OrganizationPrivateMetaData.create({})
57
+ @column({ type: 'json', decoder: OrganizationPrivateMetaData })
58
+ privateMeta: OrganizationPrivateMetaData = OrganizationPrivateMetaData.create({});
59
59
 
60
60
  /**
61
61
  * Data only accessible by the server
62
62
  */
63
- @column({ type: "json", decoder: OrganizationServerMetaData })
64
- serverMeta: OrganizationServerMetaData = OrganizationServerMetaData.create({})
63
+ @column({ type: 'json', decoder: OrganizationServerMetaData })
64
+ serverMeta: OrganizationServerMetaData = OrganizationServerMetaData.create({});
65
65
 
66
- @column({ type: "json", decoder: Address })
66
+ @column({ type: 'json', decoder: Address })
67
67
  address: Address;
68
68
 
69
69
  @column({
70
- type: "string", beforeSave: function (this: Organization) {
71
- return this.name+"\n"+this.address.toString()
72
- }
70
+ type: 'string', beforeSave: function (this: Organization) {
71
+ return this.name + '\n' + this.address.toString();
72
+ },
73
73
  })
74
- searchIndex: string
74
+ searchIndex: string;
75
75
 
76
76
  @column({
77
- type: "datetime", beforeSave(old?: any) {
77
+ type: 'datetime', beforeSave(old?: any) {
78
78
  if (old !== undefined) {
79
79
  return old;
80
80
  }
81
- const date = new Date()
82
- date.setMilliseconds(0)
83
- return date
84
- }
81
+ const date = new Date();
82
+ date.setMilliseconds(0);
83
+ return date;
84
+ },
85
85
  })
86
- createdAt: Date
86
+ createdAt: Date;
87
87
 
88
88
  @column({
89
- type: "datetime", beforeSave() {
90
- const date = new Date()
91
- date.setMilliseconds(0)
92
- return date
89
+ type: 'datetime', beforeSave() {
90
+ const date = new Date();
91
+ date.setMilliseconds(0);
92
+ return date;
93
93
  },
94
- skipUpdate: true
94
+ skipUpdate: true,
95
95
  })
96
- updatedAt: Date
96
+ updatedAt: Date;
97
97
 
98
- @column({type: 'boolean'})
98
+ @column({ type: 'boolean' })
99
99
  active = true;
100
100
 
101
101
  /**
102
102
  * Return default locale confiruation
103
103
  */
104
104
  get i18n() {
105
- return new I18n("nl", this.address.country)
105
+ return new I18n('nl', this.address.country);
106
106
  }
107
107
 
108
108
  /**
109
109
  * Makes sure empty name is replaced with organization name
110
110
  */
111
111
  get mappedTransferSettings(): TransferSettings {
112
- return this.meta.transferSettings.fillMissing(TransferSettings.create({creditor: this.name}));
112
+ return this.meta.transferSettings.fillMissing(TransferSettings.create({ creditor: this.name }));
113
113
  }
114
114
 
115
-
116
115
  // Methods
117
116
  static async getByURI(uri: string): Promise<Organization | undefined> {
118
117
  const [rows] = await Database.select(
119
118
  `SELECT ${this.getDefaultSelect()} FROM ${this.table} WHERE \`uri\` = ? LIMIT 1`,
120
- [uri]
119
+ [uri],
121
120
  );
122
121
 
123
122
  if (rows.length == 0) {
@@ -132,25 +131,25 @@ export class Organization extends Model {
132
131
  static async getByEmail(email: string): Promise<Organization | undefined> {
133
132
  if (email.startsWith('noreply-')) {
134
133
  // Trim
135
- email = email.substring("noreply-".length)
134
+ email = email.substring('noreply-'.length);
136
135
  }
137
-
136
+
138
137
  for (const domain of [
139
138
  ...Object.values(STAMHOOFD.domains.defaultBroadcastEmail ?? {}),
140
139
  ...Object.values(STAMHOOFD.domains.defaultTransactionalEmail ?? {}),
141
140
  ]) {
142
- if (email.endsWith("@" + domain)) {
143
- const uri = email.substring(0, email.length - ("@" + domain).length)
144
- return await Organization.getByURI(uri)
141
+ if (email.endsWith('@' + domain)) {
142
+ const uri = email.substring(0, email.length - ('@' + domain).length);
143
+ return await Organization.getByURI(uri);
145
144
  }
146
145
  }
147
146
 
148
- const at = email.indexOf("@");
149
- const domain = email.substring(at+1)
147
+ const at = email.indexOf('@');
148
+ const domain = email.substring(at + 1);
150
149
 
151
150
  const [rows] = await Database.select(
152
151
  `SELECT ${this.getDefaultSelect()} FROM ${this.table} WHERE privateMeta->"$.value.mailDomain" = ? LIMIT 1`,
153
- [domain]
152
+ [domain],
154
153
  );
155
154
 
156
155
  if (rows.length == 0) {
@@ -161,13 +160,11 @@ export class Organization extends Model {
161
160
  return this.fromRow(rows[0][this.table]);
162
161
  }
163
162
 
164
-
165
-
166
163
  // Methods
167
164
  static async getByRegisterDomain(host: string): Promise<Organization | undefined> {
168
165
  const [rows] = await Database.select(
169
166
  `SELECT ${this.getDefaultSelect()} FROM ${this.table} WHERE \`registerDomain\` = ? LIMIT 1`,
170
- [host]
167
+ [host],
171
168
  );
172
169
 
173
170
  if (rows.length == 0) {
@@ -186,38 +183,38 @@ export class Organization extends Model {
186
183
  static async getFromRequest(request: DecodedRequest<any, any, any>): Promise<Organization> {
187
184
  const organization = await Organization.fromApiHost(request.host);
188
185
 
189
- const i18n = I18n.fromRequest(request)
190
- i18n.switchToLocale({ country: organization.address.country })
186
+ const i18n = I18n.fromRequest(request);
187
+ i18n.switchToLocale({ country: organization.address.country });
191
188
 
192
- return organization
189
+ return organization;
193
190
  }
194
191
 
195
192
  /**
196
193
  * Get an Organization by looking at the host of a request
197
194
  * Format is 2331c59a-0cbe-4279-871c-ea9d0474cd54.api.stamhoofd.app
198
195
  */
199
- static async fromApiHost(host: string, options?: {allowInactive?: boolean}): Promise<Organization> {
200
- const splitted = host.split('.')
196
+ static async fromApiHost(host: string, options?: { allowInactive?: boolean }): Promise<Organization> {
197
+ const splitted = host.split('.');
201
198
  if (splitted.length < 2) {
202
199
  throw new SimpleError({
203
- code: "invalid_host",
204
- message: "Please specify the organization in the hostname",
200
+ code: 'invalid_host',
201
+ message: 'Please specify the organization in the hostname',
205
202
  });
206
203
  }
207
- const id = splitted[0]
204
+ const id = splitted[0];
208
205
  const organization = await this.getByID(id);
209
206
  if (!organization) {
210
207
  throw new SimpleError({
211
- code: "invalid_organization",
212
- message: "No organization known for host " + host,
208
+ code: 'invalid_organization',
209
+ message: 'No organization known for host ' + host,
213
210
  });
214
211
  }
215
212
 
216
213
  if (!organization.active && !options?.allowInactive) {
217
214
  throw new SimpleError({
218
- code: "archived",
219
- message: "This organization is archived",
220
- human: 'Deze groep is gearchiveerd'
215
+ code: 'archived',
216
+ message: 'This organization is archived',
217
+ human: 'Deze groep is gearchiveerd',
221
218
  });
222
219
  }
223
220
  return organization;
@@ -230,73 +227,74 @@ export class Organization extends Model {
230
227
  if (this.registerDomain) {
231
228
  let d = this.registerDomain;
232
229
 
233
- if (i18n && i18n.language != this.i18n.language) {
234
- d += "/"+i18n.language
230
+ if (i18n && i18n.language !== this.i18n.language) {
231
+ d += '/' + i18n.language;
235
232
  }
236
233
 
237
234
  return d;
238
235
  }
239
- return this.getDefaultHost(i18n)
236
+ return this.getDefaultHost(i18n);
240
237
  }
241
238
 
242
239
  getDefaultHost(i18n?: I18n): string {
243
240
  if (!STAMHOOFD.domains.registration) {
244
241
  return STAMHOOFD.domains.dashboard + '/' + (i18n?.locale ?? this.i18n.locale) + '/leden/' + this.uri;
245
242
  }
246
- let defaultDomain = STAMHOOFD.domains.registration[this.address.country] ?? STAMHOOFD.domains.registration[""];
243
+ let defaultDomain = STAMHOOFD.domains.registration[this.address.country] ?? STAMHOOFD.domains.registration[''];
247
244
 
248
- if (i18n && i18n.language != this.i18n.language) {
249
- defaultDomain += "/"+i18n.language
245
+ if (i18n && i18n.language !== this.i18n.language) {
246
+ defaultDomain += '/' + i18n.language;
250
247
  }
251
248
 
252
- return this.uri + "." + defaultDomain;
249
+ return this.uri + '.' + defaultDomain;
253
250
  }
254
251
 
255
252
  get marketingDomain(): string {
256
- return STAMHOOFD.domains.marketing[this.address.country] ?? STAMHOOFD.domains.marketing[""];
253
+ return STAMHOOFD.domains.marketing[this.address.country] ?? STAMHOOFD.domains.marketing[''];
257
254
  }
258
255
 
259
256
  getApiHost(): string {
260
257
  const defaultDomain = STAMHOOFD.domains.api;
261
258
  if (!defaultDomain) {
262
- throw new Error("Missing hostname in environment")
259
+ throw new Error('Missing hostname in environment');
263
260
  }
264
- return this.id+"." + defaultDomain;
261
+ return this.id + '.' + defaultDomain;
265
262
  }
266
263
 
267
- private _cachedPeriod?: OrganizationRegistrationPeriod
264
+ private _cachedPeriod?: OrganizationRegistrationPeriod;
268
265
 
269
266
  async getPeriod() {
270
267
  if (this._cachedPeriod) {
271
268
  return this._cachedPeriod;
272
269
  }
273
270
 
274
- const oPeriods = await OrganizationRegistrationPeriod.where({ periodId: this.periodId, organizationId: this.id }, {limit: 1})
275
-
271
+ const oPeriods = await OrganizationRegistrationPeriod.where({ periodId: this.periodId, organizationId: this.id }, { limit: 1 });
272
+
276
273
  let oPeriod: OrganizationRegistrationPeriod;
277
274
  if (oPeriods.length == 0) {
278
275
  // Automatically create a period
279
276
  oPeriod = await QueueHandler.schedule('create-missing-organization-period', async () => {
280
277
  // Race condition check
281
- const updatedPeriods = await OrganizationRegistrationPeriod.where({ periodId: this.periodId, organizationId: this.id }, {limit: 1})
278
+ const updatedPeriods = await OrganizationRegistrationPeriod.where({ periodId: this.periodId, organizationId: this.id }, { limit: 1 });
282
279
 
283
280
  if (updatedPeriods.length) {
284
- return updatedPeriods[0]
281
+ return updatedPeriods[0];
285
282
  }
286
283
 
287
- console.log('Automatically creating new organization registration period for organization ' + this.id + ' and period ' + this.periodId + ' - organization period is missing')
288
- const created = new OrganizationRegistrationPeriod()
289
- created.organizationId = this.id
290
- created.periodId = this.periodId
291
- await created.save()
292
- return created
293
- })
294
- } else {
284
+ console.log('Automatically creating new organization registration period for organization ' + this.id + ' and period ' + this.periodId + ' - organization period is missing');
285
+ const created = new OrganizationRegistrationPeriod();
286
+ created.organizationId = this.id;
287
+ created.periodId = this.periodId;
288
+ await created.save();
289
+ return created;
290
+ });
291
+ }
292
+ else {
295
293
  oPeriod = oPeriods[0];
296
294
  }
297
295
 
298
- this._cachedPeriod = oPeriod
299
- return oPeriod
296
+ this._cachedPeriod = oPeriod;
297
+ return oPeriod;
300
298
  }
301
299
 
302
300
  getBaseStructure(): OrganizationStruct {
@@ -310,147 +308,151 @@ export class Organization extends Model {
310
308
  uri: this.uri,
311
309
  website: this.website,
312
310
  createdAt: this.createdAt,
313
- })
311
+ });
314
312
  }
315
313
 
316
314
  async updateDNSRecords() {
317
315
  const organization = this;
318
316
 
319
317
  // Check initial status
320
- let isValidRecords = true
318
+ let isValidRecords = true;
321
319
  for (const record of organization.privateMeta.dnsRecords) {
322
- if (record.status != DNSRecordStatus.Valid) {
323
- isValidRecords = false
320
+ if (record.status !== DNSRecordStatus.Valid) {
321
+ isValidRecords = false;
324
322
  }
325
323
  }
326
-
327
- const { allValid } = await validateDNSRecords(organization.privateMeta.dnsRecords)
328
324
 
329
- if (organization.registerDomain ?? organization.privateMeta.pendingRegisterDomain) {
330
- const registerDomainRecord = (organization.privateMeta.pendingRegisterDomain ?? organization.registerDomain)+"."
331
- const records = organization.privateMeta.dnsRecords.filter(r => r.name === registerDomainRecord)
332
- const areRegisterDomainRecordsValid = records.length === 0 || records.every(r => r.status === DNSRecordStatus.Valid)
325
+ const { allValid } = await validateDNSRecords(organization.privateMeta.dnsRecords);
326
+
327
+ if (organization.registerDomain ?? organization.privateMeta.pendingRegisterDomain) {
328
+ const registerDomainRecord = (organization.privateMeta.pendingRegisterDomain ?? organization.registerDomain) + '.';
329
+ const records = organization.privateMeta.dnsRecords.filter(r => r.name === registerDomainRecord);
330
+ const areRegisterDomainRecordsValid = records.length === 0 || records.every(r => r.status === DNSRecordStatus.Valid);
333
331
 
334
332
  if (areRegisterDomainRecordsValid) {
335
333
  // We can setup the register domain if needed
336
334
  if (organization.privateMeta.pendingRegisterDomain !== null) {
337
- organization.registerDomain = organization.privateMeta.pendingRegisterDomain
335
+ organization.registerDomain = organization.privateMeta.pendingRegisterDomain;
338
336
  organization.privateMeta.pendingRegisterDomain = null;
339
337
 
340
- console.log("Did set register domain for "+this.id+" to "+organization.registerDomain)
338
+ console.log('Did set register domain for ' + this.id + ' to ' + organization.registerDomain);
341
339
  }
342
- } else {
340
+ }
341
+ else {
343
342
  // Clear register domain
344
343
  if (organization.registerDomain) {
345
344
  // We need to clear it, to prevent sending e-mails with invalid links
346
- organization.privateMeta.pendingRegisterDomain = organization.privateMeta.pendingRegisterDomain ?? organization.registerDomain
347
- organization.registerDomain = null
345
+ organization.privateMeta.pendingRegisterDomain = organization.privateMeta.pendingRegisterDomain ?? organization.registerDomain;
346
+ organization.registerDomain = null;
348
347
 
349
- console.log("Cleared register domain for "+this.id+" because of invalid non txt records")
348
+ console.log('Cleared register domain for ' + this.id + ' because of invalid non txt records');
350
349
  }
351
350
  }
352
351
  }
353
352
 
354
353
  if (allValid) {
355
354
  if (organization.privateMeta.pendingMailDomain !== null) {
356
- organization.privateMeta.mailDomain = organization.privateMeta.pendingMailDomain
355
+ organization.privateMeta.mailDomain = organization.privateMeta.pendingMailDomain;
357
356
  organization.privateMeta.pendingMailDomain = null;
358
357
  }
359
358
 
360
- const wasUnstable = organization.serverMeta.isDNSUnstable
361
- organization.serverMeta.markDNSValid()
359
+ const wasUnstable = organization.serverMeta.isDNSUnstable;
360
+ organization.serverMeta.markDNSValid();
362
361
 
363
- const didSendDomainSetupMail = organization.serverMeta.didSendDomainSetupMail
364
- const didSendWarning = organization.serverMeta.DNSRecordWarningCount > 0
365
- organization.serverMeta.DNSRecordWarningCount = 0
362
+ const didSendDomainSetupMail = organization.serverMeta.didSendDomainSetupMail;
363
+ const didSendWarning = organization.serverMeta.DNSRecordWarningCount > 0;
364
+ organization.serverMeta.DNSRecordWarningCount = 0;
366
365
 
367
- const wasActive = this.privateMeta.mailDomainActive
368
- await this.updateAWSMailIdenitity()
366
+ const wasActive = this.privateMeta.mailDomainActive;
367
+ await this.updateAWSMailIdenitity();
369
368
 
370
369
  // yay! Do not Save until after doing AWS changes
371
- await organization.save()
370
+ await organization.save();
372
371
 
373
372
  if (wasUnstable && !organization.serverMeta.isDNSUnstable) {
374
- console.warn('DNS settings became stable for ' + this.name + ' '+this.id)
373
+ console.warn('DNS settings became stable for ' + this.name + ' ' + this.id);
375
374
 
376
375
  await this.sendEmailTemplate({
377
376
  type: EmailTemplateType.OrganizationStableDNS,
378
- bcc: true
379
- })
380
-
381
- } else if (!wasActive && this.privateMeta.mailDomainActive && (!didSendDomainSetupMail || didSendWarning) && !organization.serverMeta.isDNSUnstable) {
382
- organization.serverMeta.didSendDomainSetupMail = true
383
- await organization.save()
377
+ bcc: true,
378
+ });
379
+ }
380
+ else if (!wasActive && this.privateMeta.mailDomainActive && (!didSendDomainSetupMail || didSendWarning) && !organization.serverMeta.isDNSUnstable) {
381
+ organization.serverMeta.didSendDomainSetupMail = true;
382
+ await organization.save();
384
383
 
385
384
  if (!didSendDomainSetupMail) {
386
385
  await this.sendEmailTemplate({
387
- type: EmailTemplateType.OrganizationDNSSetupComplete
388
- })
389
- } else {
386
+ type: EmailTemplateType.OrganizationDNSSetupComplete,
387
+ });
388
+ }
389
+ else {
390
390
  await this.sendEmailTemplate({
391
- type: EmailTemplateType.OrganizationValidDNS
392
- })
391
+ type: EmailTemplateType.OrganizationValidDNS,
392
+ });
393
393
  }
394
394
  }
395
- } else {
395
+ }
396
+ else {
396
397
  // DNS settings gone broken
397
398
  if (organization.privateMeta.mailDomain) {
398
- organization.privateMeta.pendingMailDomain = organization.privateMeta.pendingMailDomain ?? organization.privateMeta.mailDomain
399
- organization.privateMeta.mailDomain = null
399
+ organization.privateMeta.pendingMailDomain = organization.privateMeta.pendingMailDomain ?? organization.privateMeta.mailDomain;
400
+ organization.privateMeta.mailDomain = null;
400
401
  }
401
402
 
402
- const wasDNSUnstable = organization.serverMeta.isDNSUnstable
403
+ const wasDNSUnstable = organization.serverMeta.isDNSUnstable;
403
404
 
404
- organization.serverMeta.markDNSFailure()
405
+ organization.serverMeta.markDNSFailure();
405
406
 
406
407
  // disable AWS emails
407
- this.privateMeta.mailDomainActive = false
408
+ this.privateMeta.mailDomainActive = false;
408
409
 
409
410
  // save
410
- await organization.save()
411
+ await organization.save();
411
412
 
412
413
  if (!wasDNSUnstable && organization.serverMeta.isDNSUnstable) {
413
414
  // DNS became instable
414
- console.warn('DNS settings became instable for ' + this.name + ' '+this.id)
415
+ console.warn('DNS settings became instable for ' + this.name + ' ' + this.id);
415
416
 
416
417
  await this.sendEmailTemplate({
417
418
  type: EmailTemplateType.OrganizationUnstableDNS,
418
- bcc: true
419
- })
420
- } else if (!organization.serverMeta.isDNSUnstable && organization.serverMeta.didSendDomainSetupMail && organization.serverMeta.DNSRecordWarningCount == 0) {
421
- organization.serverMeta.DNSRecordWarningCount += 1
422
- await organization.save()
419
+ bcc: true,
420
+ });
421
+ }
422
+ else if (!organization.serverMeta.isDNSUnstable && organization.serverMeta.didSendDomainSetupMail && organization.serverMeta.DNSRecordWarningCount == 0) {
423
+ organization.serverMeta.DNSRecordWarningCount += 1;
424
+ await organization.save();
423
425
 
424
426
  await this.sendEmailTemplate({
425
- type: EmailTemplateType.OrganizationInvalidDNS
426
- })
427
+ type: EmailTemplateType.OrganizationInvalidDNS,
428
+ });
427
429
  }
428
430
  }
429
431
  }
430
432
 
431
433
  async sendEmailTemplate(data: {
432
- type: EmailTemplateType,
433
- personal?: boolean,
434
- replyTo?: string,
435
- bcc?: boolean
434
+ type: EmailTemplateType;
435
+ personal?: boolean;
436
+ replyTo?: string;
437
+ bcc?: boolean;
436
438
  }) {
437
439
  const recipients = await this.getAdminRecipients();
438
- const defaultI18n = new I18n("nl", Country.Belgium)
440
+ const defaultI18n = new I18n('nl', Country.Belgium);
439
441
  const i18n = this.i18n;
440
442
 
441
443
  const replaceAll = [
442
444
  {
443
445
  from: defaultI18n.localizedDomains.marketing(),
444
- to: i18n.localizedDomains.marketing()
446
+ to: i18n.localizedDomains.marketing(),
445
447
  },
446
448
  {
447
- from: defaultI18n.$t("59b85264-c4c3-4cf6-8923-9b43282b2787"),
448
- to: i18n.$t("59b85264-c4c3-4cf6-8923-9b43282b2787")
449
+ from: defaultI18n.$t('59b85264-c4c3-4cf6-8923-9b43282b2787'),
450
+ to: i18n.$t('59b85264-c4c3-4cf6-8923-9b43282b2787'),
449
451
  },
450
452
  {
451
- from: defaultI18n.$t("6b3555a2-ace4-4f37-a1fd-18921552f2b5"),
452
- to: i18n.$t("6b3555a2-ace4-4f37-a1fd-18921552f2b5")
453
- }
453
+ from: defaultI18n.$t('6b3555a2-ace4-4f37-a1fd-18921552f2b5'),
454
+ to: i18n.$t('6b3555a2-ace4-4f37-a1fd-18921552f2b5'),
455
+ },
454
456
  ];
455
457
 
456
458
  // Create e-mail builder
@@ -458,7 +460,7 @@ export class Organization extends Model {
458
460
  replaceAll,
459
461
  recipients,
460
462
  template: {
461
- type: data.type
463
+ type: data.type,
462
464
  },
463
465
  from: data.personal ? Email.getPersonalEmailFor(this.i18n) : Email.getInternalEmailFor(this.i18n),
464
466
  singleBcc: data.bcc ? 'simon@stamhoofd.be' : undefined,
@@ -467,26 +469,25 @@ export class Organization extends Model {
467
469
  defaultReplacements: [
468
470
  Replacement.create({
469
471
  token: 'mailDomain',
470
- value: this.privateMeta.mailDomain ?? this.privateMeta.pendingMailDomain ?? ''
471
- })
472
+ value: this.privateMeta.mailDomain ?? this.privateMeta.pendingMailDomain ?? '',
473
+ }),
472
474
  ],
473
475
  unsubscribeType: 'marketing',
474
- fromStamhoofd: true
475
- })
476
+ fromStamhoofd: true,
477
+ });
476
478
 
477
479
  if (builder) {
478
- Email.schedule(builder)
480
+ Email.schedule(builder);
479
481
  }
480
482
  }
481
483
 
482
484
  async deleteAWSMailIdenitity(mailDomain: string) {
483
-
484
485
  // Protect specific domain names
485
- if (["stamhoofd.be", "stamhoofd.nl", "stamhoofd.shop", "stamhoofd.app", "stamhoofd.email"].includes(mailDomain)) {
486
- return
486
+ if (['stamhoofd.be', 'stamhoofd.nl', 'stamhoofd.shop', 'stamhoofd.app', 'stamhoofd.email'].includes(mailDomain)) {
487
+ return;
487
488
  }
488
489
 
489
- if (STAMHOOFD.environment != "production") {
490
+ if (STAMHOOFD.environment !== 'production') {
490
491
  // Temporary ignore this
491
492
  return;
492
493
  }
@@ -494,30 +495,30 @@ export class Organization extends Model {
494
495
  const sesv2 = new SES();
495
496
 
496
497
  // Check if mail identitiy already exists..
497
- let exists = false
498
- let existing: PromiseResult<SES.GetEmailIdentityResponse, AWSError> | undefined = undefined
498
+ let exists = false;
499
+ let existing: PromiseResult<SES.GetEmailIdentityResponse, AWSError> | undefined = undefined;
499
500
  try {
500
501
  existing = await sesv2.getEmailIdentity({
501
- EmailIdentity: mailDomain
502
- }).promise()
503
- exists = true
502
+ EmailIdentity: mailDomain,
503
+ }).promise();
504
+ exists = true;
504
505
 
505
506
  // Check if DKIM keys are the same
506
507
  if (existing.VerifiedForSendingStatus === true) {
507
- console.log("Cant delete AWS mail idenitiy @"+this.id+" for "+mailDomain+": already validated and might be in use by other organizations")
508
- return
508
+ console.log('Cant delete AWS mail idenitiy @' + this.id + ' for ' + mailDomain + ': already validated and might be in use by other organizations');
509
+ return;
509
510
  }
510
511
 
511
- console.log("Deleting AWS mail idenitiy @"+this.id+" for "+mailDomain)
512
+ console.log('Deleting AWS mail idenitiy @' + this.id + ' for ' + mailDomain);
512
513
 
513
514
  await sesv2.deleteEmailIdentity({
514
- EmailIdentity: mailDomain
515
- }).promise()
516
- console.log("Deleted AWS mail idenitiy @"+this.id+" for "+this.privateMeta.mailDomain)
517
-
518
- } catch (e) {
519
- console.error("Could not delete AWS email identitiy @"+this.id+" for "+this.privateMeta.mailDomain)
520
- console.error(e)
515
+ EmailIdentity: mailDomain,
516
+ }).promise();
517
+ console.log('Deleted AWS mail idenitiy @' + this.id + ' for ' + this.privateMeta.mailDomain);
518
+ }
519
+ catch (e) {
520
+ console.error('Could not delete AWS email identitiy @' + this.id + ' for ' + this.privateMeta.mailDomain);
521
+ console.error(e);
521
522
  }
522
523
  }
523
524
 
@@ -530,13 +531,13 @@ export class Organization extends Model {
530
531
  }
531
532
 
532
533
  // Protect specific domain names
533
- if (["stamhoofd.be", "stamhoofd.nl", "stamhoofd.shop", "stamhoofd.app", "stamhoofd.email"].includes(this.privateMeta.mailDomain)) {
534
- console.error("Tried to validate AWS mail identity with protected domains @"+this.id)
534
+ if (['stamhoofd.be', 'stamhoofd.nl', 'stamhoofd.shop', 'stamhoofd.app', 'stamhoofd.email'].includes(this.privateMeta.mailDomain)) {
535
+ console.error('Tried to validate AWS mail identity with protected domains @' + this.id);
535
536
  this.privateMeta.mailDomainActive = false;
536
- return
537
+ return;
537
538
  }
538
539
 
539
- if (STAMHOOFD.environment != "production") {
540
+ if (STAMHOOFD.environment !== 'production') {
540
541
  // Temporary ignore this
541
542
  this.privateMeta.mailDomainActive = true;
542
543
  return;
@@ -545,80 +546,81 @@ export class Organization extends Model {
545
546
  const sesv2 = new SES();
546
547
 
547
548
  // Check if mail identitiy already exists..
548
- let exists = false
549
- let existing: PromiseResult<SES.GetEmailIdentityResponse, AWSError> | undefined = undefined
549
+ let exists = false;
550
+ let existing: PromiseResult<SES.GetEmailIdentityResponse, AWSError> | undefined = undefined;
550
551
  try {
551
552
  existing = await sesv2.getEmailIdentity({
552
- EmailIdentity: this.privateMeta.mailDomain
553
- }).promise()
554
- exists = true
553
+ EmailIdentity: this.privateMeta.mailDomain,
554
+ }).promise();
555
+ exists = true;
555
556
 
556
- console.log("AWS mail idenitiy exists already: just checking the verification status in AWS @"+this.id)
557
+ console.log('AWS mail idenitiy exists already: just checking the verification status in AWS @' + this.id);
557
558
 
558
- if (existing.ConfigurationSetName !== "stamhoofd-domains") {
559
+ if (existing.ConfigurationSetName !== 'stamhoofd-domains') {
559
560
  // Not allowed to use this identity
560
561
  this.privateMeta.mailDomainActive = false;
561
- console.error("Organization is not allowed to use email identity "+this.privateMeta.mailDomain+" @"+this.id+", got "+existing.ConfigurationSetName)
562
+ console.error('Organization is not allowed to use email identity ' + this.privateMeta.mailDomain + ' @' + this.id + ', got ' + existing.ConfigurationSetName);
562
563
  return;
563
564
  }
564
565
 
565
- this.privateMeta.mailDomainActive = existing.VerifiedForSendingStatus ?? false
566
+ this.privateMeta.mailDomainActive = existing.VerifiedForSendingStatus ?? false;
566
567
 
567
568
  if (existing.VerifiedForSendingStatus !== true) {
568
- console.error("Not validated @"+this.id)
569
+ console.error('Not validated @' + this.id);
569
570
  }
570
-
571
- if (existing.VerifiedForSendingStatus !== true && existing.DkimAttributes?.Status === "FAILED") {
572
- console.error("AWS failed to verify DKIM records. Triggering a forced recheck @"+this.id)
571
+
572
+ if (existing.VerifiedForSendingStatus !== true && existing.DkimAttributes?.Status === 'FAILED') {
573
+ console.error('AWS failed to verify DKIM records. Triggering a forced recheck @' + this.id);
573
574
  await sesv2.deleteEmailIdentity({
574
- EmailIdentity: this.privateMeta.mailDomain
575
- }).promise()
575
+ EmailIdentity: this.privateMeta.mailDomain,
576
+ }).promise();
576
577
 
577
578
  // Recreate it immediately
578
- exists = false
579
+ exists = false;
579
580
  }
580
- } catch (e) {
581
- console.error(e)
581
+ }
582
+ catch (e) {
583
+ console.error(e);
582
584
  }
583
585
 
584
586
  if (!exists) {
585
- console.log("Creating email identity in AWS SES...")
587
+ console.log('Creating email identity in AWS SES...');
586
588
 
587
589
  const result = await sesv2.createEmailIdentity({
588
590
  EmailIdentity: this.privateMeta.mailDomain,
589
- ConfigurationSetName: "stamhoofd-domains",
591
+ ConfigurationSetName: 'stamhoofd-domains',
590
592
  DkimSigningAttributes: {
591
593
  DomainSigningPrivateKey: this.serverMeta.privateDKIMKey!,
592
- DomainSigningSelector: "stamhoofd"
594
+ DomainSigningSelector: 'stamhoofd',
593
595
  },
594
596
  Tags: [
595
597
  {
596
- "Key": "OrganizationId",
597
- "Value": this.id
598
+ Key: 'OrganizationId',
599
+ Value: this.id,
598
600
  },
599
601
  {
600
- "Key": "Environment",
601
- "Value": STAMHOOFD.environment ?? "Unknown"
602
- }
603
- ]
602
+ Key: 'Environment',
603
+ Value: STAMHOOFD.environment ?? 'Unknown',
604
+ },
605
+ ],
604
606
 
605
- }).promise()
606
- this.privateMeta.mailDomainActive = result.VerifiedForSendingStatus ?? false
607
+ }).promise();
608
+ this.privateMeta.mailDomainActive = result.VerifiedForSendingStatus ?? false;
607
609
 
608
610
  // Disable email forwarding of bounces and complaints
609
611
  // We handle this now with the configuration set
610
612
  await sesv2.putEmailIdentityFeedbackAttributes({
611
613
  EmailIdentity: this.privateMeta.mailDomain,
612
- EmailForwardingEnabled: false
613
- }).promise()
614
+ EmailForwardingEnabled: false,
615
+ }).promise();
614
616
  }
615
617
 
616
618
  if (this.privateMeta.mailFromDomain && (!exists || (existing && (!existing.MailFromAttributes || existing.MailFromAttributes.MailFromDomain !== this.privateMeta.mailFromDomain)))) {
617
619
  // Also set a from domain, to fix SPF
618
- console.log("Setting mail from domain: "+this.privateMeta.mailFromDomain+" for "+this.id)
620
+ console.log('Setting mail from domain: ' + this.privateMeta.mailFromDomain + ' for ' + this.id);
619
621
  const params = {
620
622
  EmailIdentity: this.privateMeta.mailDomain,
621
- BehaviorOnMxFailure: "USE_DEFAULT_VALUE",
623
+ BehaviorOnMxFailure: 'USE_DEFAULT_VALUE',
622
624
  MailFromDomain: this.privateMeta.mailFromDomain,
623
625
  };
624
626
  await sesv2.putEmailIdentityMailFromAttributes(params).promise();
@@ -626,15 +628,15 @@ export class Organization extends Model {
626
628
  }
627
629
 
628
630
  async checkDrips() {
629
- const days7 = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000)
631
+ const days7 = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
630
632
 
631
633
  // Welcome drip
632
634
  // Created maximum 7 days ago
633
635
  if (this.createdAt > days7 && !this.serverMeta.hasEmail(EmailTemplateType.OrganizationDripWelcome)) {
634
636
  await this.sendEmailTemplate({
635
637
  type: EmailTemplateType.OrganizationDripWelcome,
636
- personal: true
637
- })
638
+ personal: true,
639
+ });
638
640
 
639
641
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripWelcome);
640
642
  await this.save();
@@ -645,13 +647,13 @@ export class Organization extends Model {
645
647
  // Webshop trial checkin
646
648
  if (!this.serverMeta.hasEmail(EmailTemplateType.OrganizationDripWebshopTrialCheckin)) {
647
649
  if (this.meta.packages.isWebshopsTrial) {
648
- const activeTime = this.meta.packages.getActiveTime(STPackageType.TrialWebshops)
650
+ const activeTime = this.meta.packages.getActiveTime(STPackageType.TrialWebshops);
649
651
  if (activeTime !== null && activeTime > 4 * 24 * 60 * 60 * 1000) {
650
652
  // 7 days checkin
651
653
  await this.sendEmailTemplate({
652
654
  type: EmailTemplateType.OrganizationDripWebshopTrialCheckin,
653
- personal: true
654
- })
655
+ personal: true,
656
+ });
655
657
 
656
658
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripWebshopTrialCheckin);
657
659
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripMembersTrialCheckin); // also mark members checkin
@@ -665,13 +667,13 @@ export class Organization extends Model {
665
667
  // Members trial checkin
666
668
  if (!this.serverMeta.hasEmail(EmailTemplateType.OrganizationDripMembersTrialCheckin)) {
667
669
  if (this.meta.packages.isMembersTrial) {
668
- const activeTime = this.meta.packages.getActiveTime(STPackageType.TrialMembers)
670
+ const activeTime = this.meta.packages.getActiveTime(STPackageType.TrialMembers);
669
671
  if (activeTime !== null && activeTime > 4 * 24 * 60 * 60 * 1000) {
670
672
  // 7 days checkin
671
673
  await this.sendEmailTemplate({
672
674
  type: EmailTemplateType.OrganizationDripMembersTrialCheckin,
673
- personal: true
674
- })
675
+ personal: true,
676
+ });
675
677
 
676
678
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripMembersTrialCheckin);
677
679
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripWebshopTrialCheckin); // Also mark webshop trial checkin
@@ -685,12 +687,12 @@ export class Organization extends Model {
685
687
  // Webshop trial expired after 1 week
686
688
  if (!this.serverMeta.hasEmail(EmailTemplateType.OrganizationDripWebshopTrialExpired)) {
687
689
  if (!this.meta.packages.useWebshops) {
688
- const deactivatedTime = this.meta.packages.getDeactivatedTime(STPackageType.TrialWebshops)
690
+ const deactivatedTime = this.meta.packages.getDeactivatedTime(STPackageType.TrialWebshops);
689
691
  if (deactivatedTime !== null && deactivatedTime < 14 * 24 * 60 * 60 * 1000 && deactivatedTime > 7 * 24 * 60 * 60 * 1000) {
690
692
  await this.sendEmailTemplate({
691
693
  type: EmailTemplateType.OrganizationDripWebshopTrialExpired,
692
- personal: true
693
- })
694
+ personal: true,
695
+ });
694
696
 
695
697
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripWebshopTrialExpired);
696
698
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripMembersTrialExpired); // also mark members
@@ -703,12 +705,12 @@ export class Organization extends Model {
703
705
 
704
706
  if (!this.serverMeta.hasEmail(EmailTemplateType.OrganizationDripMembersTrialExpired)) {
705
707
  if (!this.meta.packages.useMembers) {
706
- const deactivatedTime = this.meta.packages.getDeactivatedTime(STPackageType.TrialMembers)
708
+ const deactivatedTime = this.meta.packages.getDeactivatedTime(STPackageType.TrialMembers);
707
709
  if (deactivatedTime !== null && deactivatedTime < 14 * 24 * 60 * 60 * 1000 && deactivatedTime > 7 * 24 * 60 * 60 * 1000) {
708
710
  await this.sendEmailTemplate({
709
711
  type: EmailTemplateType.OrganizationDripMembersTrialExpired,
710
- personal: true
711
- })
712
+ personal: true,
713
+ });
712
714
 
713
715
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripMembersTrialExpired);
714
716
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripWebshopTrialExpired); // also mark webshops
@@ -722,17 +724,17 @@ export class Organization extends Model {
722
724
  // trial expired reminder (after 10 months)
723
725
  if (!this.serverMeta.hasEmail(EmailTemplateType.OrganizationDripTrialExpiredReminder)) {
724
726
  if (!this.meta.packages.isPaid && !this.meta.packages.wasPaid) {
725
- const deactivatedTime1 = this.meta.packages.getDeactivatedTime(STPackageType.TrialWebshops)
726
- const deactivatedTime2 = this.meta.packages.getDeactivatedTime(STPackageType.TrialMembers)
727
+ const deactivatedTime1 = this.meta.packages.getDeactivatedTime(STPackageType.TrialWebshops);
728
+ const deactivatedTime2 = this.meta.packages.getDeactivatedTime(STPackageType.TrialMembers);
727
729
 
728
- const deactivatedTime = deactivatedTime1 && deactivatedTime2 ? Math.max(deactivatedTime1, deactivatedTime2) : (deactivatedTime1 ? deactivatedTime1 : deactivatedTime2)
730
+ const deactivatedTime = deactivatedTime1 && deactivatedTime2 ? Math.max(deactivatedTime1, deactivatedTime2) : (deactivatedTime1 ? deactivatedTime1 : deactivatedTime2);
729
731
 
730
732
  if (deactivatedTime !== null && deactivatedTime > 10 * 30 * 24 * 60 * 60 * 1000 && deactivatedTime < 13 * 31 * 24 * 60 * 60 * 1000) {
731
733
  await this.sendEmailTemplate({
732
734
  type: EmailTemplateType.OrganizationDripTrialExpiredReminder,
733
735
  personal: true,
734
- bcc: true
735
- })
736
+ bcc: true,
737
+ });
736
738
 
737
739
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripTrialExpiredReminder);
738
740
  await this.save();
@@ -744,14 +746,14 @@ export class Organization extends Model {
744
746
 
745
747
  if (!this.serverMeta.hasEmail(EmailTemplateType.OrganizationDripWebshopNotRenewed)) {
746
748
  if (!this.meta.packages.useWebshops) {
747
- const deactivatedTime = this.meta.packages.getDeactivatedTime(STPackageType.Webshops)
748
-
749
- if (deactivatedTime !== null && deactivatedTime > 30 * 24 * 60 * 60 * 1000 && deactivatedTime < 30*3 * 24 * 60 * 60 * 1000) {
749
+ const deactivatedTime = this.meta.packages.getDeactivatedTime(STPackageType.Webshops);
750
+
751
+ if (deactivatedTime !== null && deactivatedTime > 30 * 24 * 60 * 60 * 1000 && deactivatedTime < 30 * 3 * 24 * 60 * 60 * 1000) {
750
752
  await this.sendEmailTemplate({
751
753
  type: EmailTemplateType.OrganizationDripWebshopNotRenewed,
752
754
  personal: true,
753
- bcc: true
754
- })
755
+ bcc: true,
756
+ });
755
757
 
756
758
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripWebshopNotRenewed);
757
759
  await this.save();
@@ -763,14 +765,14 @@ export class Organization extends Model {
763
765
 
764
766
  if (!this.serverMeta.hasEmail(EmailTemplateType.OrganizationDripMembersNotRenewed)) {
765
767
  if (!this.meta.packages.useMembers) {
766
- const deactivatedTime = this.meta.packages.getDeactivatedTime(STPackageType.Members)
767
-
768
- if (deactivatedTime !== null && deactivatedTime > 30 * 24 * 60 * 60 * 1000 && deactivatedTime < 30*3 * 24 * 60 * 60 * 1000) {
768
+ const deactivatedTime = this.meta.packages.getDeactivatedTime(STPackageType.Members);
769
+
770
+ if (deactivatedTime !== null && deactivatedTime > 30 * 24 * 60 * 60 * 1000 && deactivatedTime < 30 * 3 * 24 * 60 * 60 * 1000) {
769
771
  await this.sendEmailTemplate({
770
772
  type: EmailTemplateType.OrganizationDripMembersNotRenewed,
771
773
  personal: true,
772
- bcc: true
773
- })
774
+ bcc: true,
775
+ });
774
776
 
775
777
  this.serverMeta.addEmail(EmailTemplateType.OrganizationDripMembersNotRenewed);
776
778
  await this.save();
@@ -792,18 +794,18 @@ export class Organization extends Model {
792
794
  return [
793
795
  {
794
796
  name: sender.name,
795
- email: sender.email
796
- }
797
- ]
797
+ email: sender.email,
798
+ },
799
+ ];
798
800
  }
799
801
 
800
- return await this.getAdminToEmails()
802
+ return await this.getAdminToEmails();
801
803
  }
802
804
 
803
805
  async getAdmins() {
804
806
  // Circular reference fix
805
807
  const User = (await import('./User')).User;
806
- return await User.getAdmins([this.id], {verified: true});
808
+ return await User.getAdmins([this.id], { verified: true });
807
809
  }
808
810
 
809
811
  /**
@@ -813,66 +815,66 @@ export class Organization extends Model {
813
815
  const admins = await this.getAdmins();
814
816
 
815
817
  // Only full access
816
- return admins.filter(a => a.permissions && a.permissions.forOrganization(this)?.hasFullAccess())
818
+ return admins.filter(a => a.permissions && a.permissions.forOrganization(this)?.hasFullAccess());
817
819
  }
818
820
 
819
821
  /**
820
822
  * These email addresess are private
821
823
  */
822
824
  async getAdminToEmails(): Promise<EmailInterfaceRecipient[]> {
823
- const filtered = await this.getFullAdmins()
825
+ const filtered = await this.getFullAdmins();
824
826
 
825
- if (STAMHOOFD.environment === "production") {
827
+ if (STAMHOOFD.environment === 'production') {
826
828
  if (filtered.length > 1) {
827
829
  // remove stamhoofd email addresses
828
- const f = filtered.flatMap(f => f.getEmailTo() ).filter(e => !e.email.endsWith("@stamhoofd.be") && !e.email.endsWith("@stamhoofd.nl"))
830
+ const f = filtered.flatMap(f => f.getEmailTo()).filter(e => !e.email.endsWith('@stamhoofd.be') && !e.email.endsWith('@stamhoofd.nl'));
829
831
  if (f.length > 0) {
830
- return f
832
+ return f;
831
833
  }
832
834
  }
833
835
  }
834
836
 
835
- return filtered.flatMap(f => f.getEmailTo() )
837
+ return filtered.flatMap(f => f.getEmailTo());
836
838
  }
837
839
 
838
840
  /**
839
841
  * These email addresess are private
840
842
  */
841
843
  async getAdminRecipients(): Promise<Recipient[]> {
842
- let filtered = await this.getFullAdmins()
844
+ let filtered = await this.getFullAdmins();
843
845
 
844
- if (STAMHOOFD.environment === "production") {
846
+ if (STAMHOOFD.environment === 'production') {
845
847
  if (filtered.length > 1) {
846
848
  // remove stamhoofd email addresses
847
- filtered = filtered.filter(e => !e.email.endsWith("@stamhoofd.be") && !e.email.endsWith("@stamhoofd.nl"))
849
+ filtered = filtered.filter(e => !e.email.endsWith('@stamhoofd.be') && !e.email.endsWith('@stamhoofd.nl'));
848
850
  }
849
851
  }
850
852
 
851
- return filtered.flatMap(f => {
853
+ return filtered.flatMap((f) => {
852
854
  return Recipient.create({
853
855
  firstName: f.firstName,
854
856
  lastName: f.lastName,
855
857
  email: f.email,
856
858
  replacements: [
857
859
  Replacement.create({
858
- token: "organizationName",
859
- value: this.name
860
- })
861
- ]
862
- })
863
- } )
860
+ token: 'organizationName',
861
+ value: this.name,
862
+ }),
863
+ ],
864
+ });
865
+ });
864
866
  }
865
867
 
866
868
  /**
867
869
  * Return default e-mail address if no email addresses are set.
868
870
  */
869
871
  getDefaultFrom(i18n: I18n, withName = true, type: 'transactional' | 'broadcast' = 'broadcast') {
870
- const domain = type === 'transactional' ? i18n.localizedDomains.defaultTransactionalEmail() : i18n.localizedDomains.defaultBroadcastEmail()
872
+ const domain = type === 'transactional' ? i18n.localizedDomains.defaultTransactionalEmail() : i18n.localizedDomains.defaultBroadcastEmail();
871
873
 
872
874
  if (!withName) {
873
- return ('noreply-' + this.uri+"@"+domain);
875
+ return ('noreply-' + this.uri + '@' + domain);
874
876
  }
875
- return '"'+this.name.replaceAll("\"", "\\\"")+'" <'+ ('noreply-' + this.uri+"@"+domain) +'>'
877
+ return '"' + this.name.replaceAll('"', '\\"') + '" <' + ('noreply-' + this.uri + '@' + domain) + '>';
876
878
  }
877
879
 
878
880
  /**
@@ -880,40 +882,42 @@ export class Organization extends Model {
880
882
  */
881
883
  getEmail(id: string | null, strongDefault = false): { from: string; replyTo: string | undefined } {
882
884
  if (id === null) {
883
- return this.getDefaultEmail(strongDefault)
885
+ return this.getDefaultEmail(strongDefault);
884
886
  }
885
-
887
+
886
888
  // Send confirmation e-mail
887
- let from = this.getDefaultFrom(this.i18n, false, strongDefault ? 'transactional' : 'broadcast')
888
- const sender: OrganizationEmail | undefined = this.privateMeta.emails.find(e => e.id === id)
889
- let replyTo: string | undefined = undefined
889
+ let from = this.getDefaultFrom(this.i18n, false, strongDefault ? 'transactional' : 'broadcast');
890
+ const sender: OrganizationEmail | undefined = this.privateMeta.emails.find(e => e.id === id);
891
+ let replyTo: string | undefined = undefined;
890
892
 
891
893
  if (sender) {
892
- replyTo = sender.email
894
+ replyTo = sender.email;
893
895
 
894
896
  // Can we send from this e-mail or reply-to?
895
- if (replyTo && this.privateMeta.mailDomain && this.privateMeta.mailDomainActive && sender.email.endsWith("@"+this.privateMeta.mailDomain)) {
896
- from = sender.email
897
- replyTo = undefined
897
+ if (replyTo && this.privateMeta.mailDomain && this.privateMeta.mailDomainActive && sender.email.endsWith('@' + this.privateMeta.mailDomain)) {
898
+ from = sender.email;
899
+ replyTo = undefined;
898
900
  }
899
901
 
900
902
  // Include name in form field
901
903
  if (sender.name) {
902
- from = '"'+sender.name.replaceAll("\"", "\\\"")+"\" <"+from+">"
903
- } else {
904
- from = '"'+this.name.replaceAll("\"", "\\\"")+"\" <"+from+">"
904
+ from = '"' + sender.name.replaceAll('"', '\\"') + '" <' + from + '>';
905
+ }
906
+ else {
907
+ from = '"' + this.name.replaceAll('"', '\\"') + '" <' + from + '>';
905
908
  }
906
909
 
907
910
  if (replyTo) {
908
911
  if (sender.name) {
909
- replyTo = '"'+sender.name.replaceAll("\"", "\\\"")+"\" <"+replyTo+">"
910
- } else {
911
- replyTo = '"'+this.name.replaceAll("\"", "\\\"")+"\" <"+replyTo+">"
912
+ replyTo = '"' + sender.name.replaceAll('"', '\\"') + '" <' + replyTo + '>';
913
+ }
914
+ else {
915
+ replyTo = '"' + this.name.replaceAll('"', '\\"') + '" <' + replyTo + '>';
912
916
  }
913
917
  }
914
- return { from, replyTo }
918
+ return { from, replyTo };
915
919
  }
916
- return this.getDefaultEmail(strongDefault)
920
+ return this.getDefaultEmail(strongDefault);
917
921
  }
918
922
 
919
923
  /**
@@ -921,91 +925,94 @@ export class Organization extends Model {
921
925
  */
922
926
  getDefaultEmail(strongDefault = false): { from: string; replyTo: string | undefined } {
923
927
  // Send confirmation e-mail
924
- let from = strongDefault ? this.getDefaultFrom(this.i18n, false) : this.uri+"@stamhoofd.email";
928
+ let from = strongDefault ? this.getDefaultFrom(this.i18n, false) : this.uri + '@stamhoofd.email';
925
929
  const sender: OrganizationEmail | undefined = this.privateMeta.emails.find(e => e.default) ?? this.privateMeta.emails[0];
926
- let replyTo: string | undefined = undefined
930
+ let replyTo: string | undefined = undefined;
927
931
 
928
932
  if (sender) {
929
- replyTo = sender.email
933
+ replyTo = sender.email;
930
934
 
931
935
  // Can we send from this e-mail or reply-to?
932
- if (replyTo && this.privateMeta.mailDomain && this.privateMeta.mailDomainActive && sender.email.endsWith("@"+this.privateMeta.mailDomain)) {
933
- from = sender.email
934
- replyTo = undefined
936
+ if (replyTo && this.privateMeta.mailDomain && this.privateMeta.mailDomainActive && sender.email.endsWith('@' + this.privateMeta.mailDomain)) {
937
+ from = sender.email;
938
+ replyTo = undefined;
935
939
  }
936
940
 
937
941
  // Include name in form field
938
942
  if (sender.name) {
939
- from = '"'+sender.name.replaceAll("\"", "\\\"")+"\" <"+from+">"
940
- } else {
941
- from = '"'+this.name.replaceAll("\"", "\\\"")+"\" <"+from+">"
943
+ from = '"' + sender.name.replaceAll('"', '\\"') + '" <' + from + '>';
944
+ }
945
+ else {
946
+ from = '"' + this.name.replaceAll('"', '\\"') + '" <' + from + '>';
942
947
  }
943
948
 
944
949
  if (replyTo) {
945
950
  if (sender.name) {
946
- replyTo = '"'+sender.name.replaceAll("\"", "\\\"")+"\" <"+replyTo+">"
947
- } else {
948
- replyTo = '"'+this.name.replaceAll("\"", "\\\"")+"\" <"+replyTo+">"
951
+ replyTo = '"' + sender.name.replaceAll('"', '\\"') + '" <' + replyTo + '>';
952
+ }
953
+ else {
954
+ replyTo = '"' + this.name.replaceAll('"', '\\"') + '" <' + replyTo + '>';
949
955
  }
950
956
  }
951
- } else {
952
- from = '"'+this.name.replaceAll("\"", "\\\"")+"\" <"+from+">"
957
+ }
958
+ else {
959
+ from = '"' + this.name.replaceAll('"', '\\"') + '" <' + from + '>';
953
960
  }
954
961
 
955
962
  return {
956
- from, replyTo
957
- }
963
+ from, replyTo,
964
+ };
958
965
  }
959
966
 
960
967
  async getPaymentProviderFor(method: PaymentMethod, config: PrivatePaymentConfiguration): Promise<{
961
- provider: PaymentProvider | null,
962
- stripeAccount: StripeAccount | null
963
- }> {
964
- let stripeAccount = (config.stripeAccountId ? (await StripeAccount.getByID(config.stripeAccountId)) : null) ?? null
968
+ provider: PaymentProvider | null;
969
+ stripeAccount: StripeAccount | null;
970
+ }> {
971
+ let stripeAccount = (config.stripeAccountId ? (await StripeAccount.getByID(config.stripeAccountId)) : null) ?? null;
965
972
  if (stripeAccount && stripeAccount.organizationId !== this.id) {
966
- console.warn('Stripe account '+stripeAccount.id+' is not linked to organization '+this.id);
967
- stripeAccount = null
973
+ console.warn('Stripe account ' + stripeAccount.id + ' is not linked to organization ' + this.id);
974
+ stripeAccount = null;
968
975
  }
969
- const provider = this.privateMeta.getPaymentProviderFor(method, stripeAccount?.meta)
976
+ const provider = this.privateMeta.getPaymentProviderFor(method, stripeAccount?.meta);
970
977
  if (provider === null && ![PaymentMethod.Unknown, PaymentMethod.Transfer, PaymentMethod.PointOfSale].includes(method)) {
971
978
  if (!stripeAccount && config.stripeAccountId) {
972
979
  console.warn('Missing stripe account id ' + config.stripeAccountId);
973
980
  }
974
981
  throw new SimpleError({
975
982
  code: 'payment_provider_not_configured',
976
- message: 'Payment provider not configured for '+method,
977
- human: 'Deze betaalmethode werd helaas niet volledig geconfigureerd. Probeer later even opnieuw, neem contact met ons op of kies een andere betaalmethode.'
978
- })
983
+ message: 'Payment provider not configured for ' + method,
984
+ human: 'Deze betaalmethode werd helaas niet volledig geconfigureerd. Probeer later even opnieuw, neem contact met ons op of kies een andere betaalmethode.',
985
+ });
979
986
  }
980
987
 
981
988
  if (provider !== PaymentProvider.Stripe && stripeAccount) {
982
- stripeAccount = null
989
+ stripeAccount = null;
983
990
  }
984
991
  return {
985
992
  provider,
986
- stripeAccount
987
- }
993
+ stripeAccount,
994
+ };
988
995
  }
989
996
 
990
997
  async getConnectedPaymentProviders(): Promise<PaymentProvider[]> {
991
- const allPaymentMethods = Object.values(PaymentMethod)
992
- const providers: PaymentProvider[] = []
998
+ const allPaymentMethods = Object.values(PaymentMethod);
999
+ const providers: PaymentProvider[] = [];
993
1000
 
994
- let stripeAccounts: (StripeAccount|null)[] = await StripeAccount.where({ organizationId: this.id, status: 'active' })
1001
+ let stripeAccounts: (StripeAccount | null)[] = await StripeAccount.where({ organizationId: this.id, status: 'active' });
995
1002
 
996
1003
  if (stripeAccounts.length === 0) {
997
- stripeAccounts = [null]
1004
+ stripeAccounts = [null];
998
1005
  }
999
1006
 
1000
1007
  for (const account of stripeAccounts) {
1001
1008
  for (const method of allPaymentMethods) {
1002
- const provider = this.privateMeta.getPaymentProviderFor(method, account?.meta)
1009
+ const provider = this.privateMeta.getPaymentProviderFor(method, account?.meta);
1003
1010
  if (provider && !providers.includes(provider)) {
1004
- providers.push(provider)
1011
+ providers.push(provider);
1005
1012
  }
1006
1013
  }
1007
1014
  }
1008
1015
 
1009
- return providers
1016
+ return providers;
1010
1017
  }
1011
1018
  }