@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.
Files changed (481) hide show
  1. package/dist/src/assets/Metropolis-Black.woff2 +0 -0
  2. package/dist/src/assets/Metropolis-BlackItalic.woff2 +0 -0
  3. package/dist/src/assets/Metropolis-Bold.woff2 +0 -0
  4. package/dist/src/assets/Metropolis-BoldItalic.woff2 +0 -0
  5. package/dist/src/assets/Metropolis-ExtraBold.woff2 +0 -0
  6. package/dist/src/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
  7. package/dist/src/assets/Metropolis-ExtraLight.woff2 +0 -0
  8. package/dist/src/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
  9. package/dist/src/assets/Metropolis-Light.woff2 +0 -0
  10. package/dist/src/assets/Metropolis-LightItalic.woff2 +0 -0
  11. package/dist/src/assets/Metropolis-Medium.woff2 +0 -0
  12. package/dist/src/assets/Metropolis-MediumItalic.woff2 +0 -0
  13. package/dist/src/assets/Metropolis-Regular.woff2 +0 -0
  14. package/dist/src/assets/Metropolis-RegularItalic.woff2 +0 -0
  15. package/dist/src/assets/Metropolis-SemiBold.woff2 +0 -0
  16. package/dist/src/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
  17. package/dist/src/assets/Metropolis-Thin.woff2 +0 -0
  18. package/dist/src/assets/Metropolis-ThinItalic.woff2 +0 -0
  19. package/dist/src/assets/assets/Metropolis-Black.woff2 +0 -0
  20. package/dist/src/assets/assets/Metropolis-BlackItalic.woff2 +0 -0
  21. package/dist/src/assets/assets/Metropolis-Bold.woff2 +0 -0
  22. package/dist/src/assets/assets/Metropolis-BoldItalic.woff2 +0 -0
  23. package/dist/src/assets/assets/Metropolis-ExtraBold.woff2 +0 -0
  24. package/dist/src/assets/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
  25. package/dist/src/assets/assets/Metropolis-ExtraLight.woff2 +0 -0
  26. package/dist/src/assets/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
  27. package/dist/src/assets/assets/Metropolis-Light.woff2 +0 -0
  28. package/dist/src/assets/assets/Metropolis-LightItalic.woff2 +0 -0
  29. package/dist/src/assets/assets/Metropolis-Medium.woff2 +0 -0
  30. package/dist/src/assets/assets/Metropolis-MediumItalic.woff2 +0 -0
  31. package/dist/src/assets/assets/Metropolis-Regular.woff2 +0 -0
  32. package/dist/src/assets/assets/Metropolis-RegularItalic.woff2 +0 -0
  33. package/dist/src/assets/assets/Metropolis-SemiBold.woff2 +0 -0
  34. package/dist/src/assets/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
  35. package/dist/src/assets/assets/Metropolis-Thin.woff2 +0 -0
  36. package/dist/src/assets/assets/Metropolis-ThinItalic.woff2 +0 -0
  37. package/dist/src/assets/assets/logo.png +0 -0
  38. package/dist/src/assets/logo.png +0 -0
  39. package/dist/src/factories/AddressFactory.d.ts +10 -0
  40. package/dist/src/factories/AddressFactory.d.ts.map +1 -0
  41. package/dist/src/factories/AddressFactory.js +42 -0
  42. package/dist/src/factories/AddressFactory.js.map +1 -0
  43. package/dist/src/factories/EmergencyContactFactory.d.ts +9 -0
  44. package/dist/src/factories/EmergencyContactFactory.d.ts.map +1 -0
  45. package/dist/src/factories/EmergencyContactFactory.js +42 -0
  46. package/dist/src/factories/EmergencyContactFactory.js.map +1 -0
  47. package/dist/src/factories/GroupFactory.d.ts +19 -0
  48. package/dist/src/factories/GroupFactory.d.ts.map +1 -0
  49. package/dist/src/factories/GroupFactory.js +52 -0
  50. package/dist/src/factories/GroupFactory.js.map +1 -0
  51. package/dist/src/factories/MemberFactory.d.ts +16 -0
  52. package/dist/src/factories/MemberFactory.d.ts.map +1 -0
  53. package/dist/src/factories/MemberFactory.js +98 -0
  54. package/dist/src/factories/MemberFactory.js.map +1 -0
  55. package/dist/src/factories/OrganizationFactory.d.ts +16 -0
  56. package/dist/src/factories/OrganizationFactory.d.ts.map +1 -0
  57. package/dist/src/factories/OrganizationFactory.js +40 -0
  58. package/dist/src/factories/OrganizationFactory.js.map +1 -0
  59. package/dist/src/factories/ParentFactory.d.ts +10 -0
  60. package/dist/src/factories/ParentFactory.d.ts.map +1 -0
  61. package/dist/src/factories/ParentFactory.js +44 -0
  62. package/dist/src/factories/ParentFactory.js.map +1 -0
  63. package/dist/src/factories/RecordFactory.d.ts +10 -0
  64. package/dist/src/factories/RecordFactory.d.ts.map +1 -0
  65. package/dist/src/factories/RecordFactory.js +14 -0
  66. package/dist/src/factories/RecordFactory.js.map +1 -0
  67. package/dist/src/factories/RegisterCodeFactory.d.ts +18 -0
  68. package/dist/src/factories/RegisterCodeFactory.d.ts.map +1 -0
  69. package/dist/src/factories/RegisterCodeFactory.js +19 -0
  70. package/dist/src/factories/RegisterCodeFactory.js.map +1 -0
  71. package/dist/src/factories/RegistrationFactory.d.ts +14 -0
  72. package/dist/src/factories/RegistrationFactory.d.ts.map +1 -0
  73. package/dist/src/factories/RegistrationFactory.js +26 -0
  74. package/dist/src/factories/RegistrationFactory.js.map +1 -0
  75. package/dist/src/factories/UserFactory.d.ts +21 -0
  76. package/dist/src/factories/UserFactory.d.ts.map +1 -0
  77. package/dist/src/factories/UserFactory.js +41 -0
  78. package/dist/src/factories/UserFactory.js.map +1 -0
  79. package/dist/src/factories/WebshopFactory.d.ts +16 -0
  80. package/dist/src/factories/WebshopFactory.d.ts.map +1 -0
  81. package/dist/src/factories/WebshopFactory.js +35 -0
  82. package/dist/src/factories/WebshopFactory.js.map +1 -0
  83. package/dist/src/helpers/DNSValidator.d.ts +6 -0
  84. package/dist/src/helpers/DNSValidator.d.ts.map +1 -0
  85. package/dist/src/helpers/DNSValidator.js +144 -0
  86. package/dist/src/helpers/DNSValidator.js.map +1 -0
  87. package/dist/src/helpers/EmailBuilder.d.ts +22 -0
  88. package/dist/src/helpers/EmailBuilder.d.ts.map +1 -0
  89. package/dist/src/helpers/EmailBuilder.js +100 -0
  90. package/dist/src/helpers/EmailBuilder.js.map +1 -0
  91. package/dist/src/helpers/GroupBuilder.d.ts +9 -0
  92. package/dist/src/helpers/GroupBuilder.d.ts.map +1 -0
  93. package/dist/src/helpers/GroupBuilder.js +382 -0
  94. package/dist/src/helpers/GroupBuilder.js.map +1 -0
  95. package/dist/src/helpers/Handlebars.d.ts +2 -0
  96. package/dist/src/helpers/Handlebars.d.ts.map +1 -0
  97. package/dist/src/helpers/Handlebars.js +192 -0
  98. package/dist/src/helpers/Handlebars.js.map +1 -0
  99. package/dist/src/helpers/InvoiceBuilder.d.ts +29 -0
  100. package/dist/src/helpers/InvoiceBuilder.d.ts.map +1 -0
  101. package/dist/src/helpers/InvoiceBuilder.js +406 -0
  102. package/dist/src/helpers/InvoiceBuilder.js.map +1 -0
  103. package/dist/src/helpers/InvoiceBuilder.test.d.ts +2 -0
  104. package/dist/src/helpers/InvoiceBuilder.test.d.ts.map +1 -0
  105. package/dist/src/helpers/InvoiceBuilder.test.js +52 -0
  106. package/dist/src/helpers/InvoiceBuilder.test.js.map +1 -0
  107. package/dist/src/helpers/RateLimiter.d.ts +27 -0
  108. package/dist/src/helpers/RateLimiter.d.ts.map +1 -0
  109. package/dist/src/helpers/RateLimiter.js +57 -0
  110. package/dist/src/helpers/RateLimiter.js.map +1 -0
  111. package/dist/src/helpers/WebshopCounter.d.ts +6 -0
  112. package/dist/src/helpers/WebshopCounter.d.ts.map +1 -0
  113. package/dist/src/helpers/WebshopCounter.js +36 -0
  114. package/dist/src/helpers/WebshopCounter.js.map +1 -0
  115. package/dist/src/helpers/WebshopCounter.test.d.ts +2 -0
  116. package/dist/src/helpers/WebshopCounter.test.d.ts.map +1 -0
  117. package/dist/src/helpers/WebshopCounter.test.js +17 -0
  118. package/dist/src/helpers/WebshopCounter.test.js.map +1 -0
  119. package/dist/src/index.d.ts +18 -0
  120. package/dist/src/index.d.ts.map +1 -0
  121. package/dist/src/index.js +23 -0
  122. package/dist/src/index.js.map +1 -0
  123. package/dist/src/migrations/1593773929-create-initial-tables.sql +634 -0
  124. package/dist/src/migrations/1605261999-gemeenten-tmp.sql +2820 -0
  125. package/dist/src/migrations/1605262045-import-postcodes.d.ts +16 -0
  126. package/dist/src/migrations/1605262045-import-postcodes.d.ts.map +1 -0
  127. package/dist/src/migrations/1605262045-import-postcodes.js +116 -0
  128. package/dist/src/migrations/1605262045-import-postcodes.js.map +1 -0
  129. package/dist/src/migrations/1605262046-import-postcodes-nl.d.ts +4 -0
  130. package/dist/src/migrations/1605262046-import-postcodes-nl.d.ts.map +1 -0
  131. package/dist/src/migrations/1605262046-import-postcodes-nl.js +83 -0
  132. package/dist/src/migrations/1605262046-import-postcodes-nl.js.map +1 -0
  133. package/dist/src/migrations/1605279038-drop-gemeenten-tmp.sql +1 -0
  134. package/dist/src/migrations/1648392491-default-templates.sql +9 -0
  135. package/dist/src/migrations/1651245707-default-templates-reminders.sql +6 -0
  136. package/dist/src/migrations/1708607340-tickets-deleted-at.sql +1 -0
  137. package/dist/src/migrations/1710459176-register-code-invoices.sql +3 -0
  138. package/dist/src/migrations/1712158247-discount-codes.sql +17 -0
  139. package/dist/src/migrations/1713178665-drop-invites.sql +1 -0
  140. package/dist/src/migrations/1713178666-drop-keychain.sql +1 -0
  141. package/dist/src/migrations/1713178667-drop-challenges.sql +1 -0
  142. package/dist/src/migrations/1713178668-drop-user-keys.sql +7 -0
  143. package/dist/src/migrations/1713178669-drop-organization-key.sql +2 -0
  144. package/dist/src/migrations/data/postcodes/nl/Drenthe +291 -0
  145. package/dist/src/migrations/data/postcodes/nl/Flevoland +107 -0
  146. package/dist/src/migrations/data/postcodes/nl/Friesland +518 -0
  147. package/dist/src/migrations/data/postcodes/nl/Gelderland +601 -0
  148. package/dist/src/migrations/data/postcodes/nl/Groningen +279 -0
  149. package/dist/src/migrations/data/postcodes/nl/Limburg +324 -0
  150. package/dist/src/migrations/data/postcodes/nl/Noord-Brabant +620 -0
  151. package/dist/src/migrations/data/postcodes/nl/Noord-Holland +566 -0
  152. package/dist/src/migrations/data/postcodes/nl/Overrijsel +344 -0
  153. package/dist/src/migrations/data/postcodes/nl/Utrecht +278 -0
  154. package/dist/src/migrations/data/postcodes/nl/Zeeland +179 -0
  155. package/dist/src/migrations/data/postcodes/nl/Zuid-Holland +662 -0
  156. package/dist/src/models/BalanceItem.d.ts +57 -0
  157. package/dist/src/models/BalanceItem.d.ts.map +1 -0
  158. package/dist/src/models/BalanceItem.js +346 -0
  159. package/dist/src/models/BalanceItem.js.map +1 -0
  160. package/dist/src/models/BalanceItemPayment.d.ts +31 -0
  161. package/dist/src/models/BalanceItemPayment.d.ts.map +1 -0
  162. package/dist/src/models/BalanceItemPayment.js +101 -0
  163. package/dist/src/models/BalanceItemPayment.js.map +1 -0
  164. package/dist/src/models/BuckarooPayment.d.ts +8 -0
  165. package/dist/src/models/BuckarooPayment.d.ts.map +1 -0
  166. package/dist/src/models/BuckarooPayment.js +24 -0
  167. package/dist/src/models/BuckarooPayment.js.map +1 -0
  168. package/dist/src/models/Document.d.ts +44 -0
  169. package/dist/src/models/Document.d.ts.map +1 -0
  170. package/dist/src/models/Document.js +194 -0
  171. package/dist/src/models/Document.js.map +1 -0
  172. package/dist/src/models/DocumentTemplate.d.ts +45 -0
  173. package/dist/src/models/DocumentTemplate.d.ts.map +1 -0
  174. package/dist/src/models/DocumentTemplate.js +533 -0
  175. package/dist/src/models/DocumentTemplate.js.map +1 -0
  176. package/dist/src/models/EmailTemplate.d.ts +22 -0
  177. package/dist/src/models/EmailTemplate.d.ts.map +1 -0
  178. package/dist/src/models/EmailTemplate.js +70 -0
  179. package/dist/src/models/EmailTemplate.js.map +1 -0
  180. package/dist/src/models/EmailVerificationCode.d.ts +60 -0
  181. package/dist/src/models/EmailVerificationCode.d.ts.map +1 -0
  182. package/dist/src/models/EmailVerificationCode.js +307 -0
  183. package/dist/src/models/EmailVerificationCode.js.map +1 -0
  184. package/dist/src/models/Group.d.ts +36 -0
  185. package/dist/src/models/Group.d.ts.map +1 -0
  186. package/dist/src/models/Group.js +231 -0
  187. package/dist/src/models/Group.js.map +1 -0
  188. package/dist/src/models/Image.d.ts +12 -0
  189. package/dist/src/models/Image.d.ts.map +1 -0
  190. package/dist/src/models/Image.js +137 -0
  191. package/dist/src/models/Image.js.map +1 -0
  192. package/dist/src/models/Member.d.ts +66 -0
  193. package/dist/src/models/Member.d.ts.map +1 -0
  194. package/dist/src/models/Member.js +309 -0
  195. package/dist/src/models/Member.js.map +1 -0
  196. package/dist/src/models/MemberResponsibilityRecord.d.ts +11 -0
  197. package/dist/src/models/MemberResponsibilityRecord.d.ts.map +1 -0
  198. package/dist/src/models/MemberResponsibilityRecord.js +47 -0
  199. package/dist/src/models/MemberResponsibilityRecord.js.map +1 -0
  200. package/dist/src/models/MolliePayment.d.ts +8 -0
  201. package/dist/src/models/MolliePayment.d.ts.map +1 -0
  202. package/dist/src/models/MolliePayment.js +24 -0
  203. package/dist/src/models/MolliePayment.js.map +1 -0
  204. package/dist/src/models/MollieToken.d.ts +45 -0
  205. package/dist/src/models/MollieToken.d.ts.map +1 -0
  206. package/dist/src/models/MollieToken.js +333 -0
  207. package/dist/src/models/MollieToken.js.map +1 -0
  208. package/dist/src/models/OneTimeToken.d.ts +38 -0
  209. package/dist/src/models/OneTimeToken.d.ts.map +1 -0
  210. package/dist/src/models/OneTimeToken.js +126 -0
  211. package/dist/src/models/OneTimeToken.js.map +1 -0
  212. package/dist/src/models/Order.d.ts +99 -0
  213. package/dist/src/models/Order.d.ts.map +1 -0
  214. package/dist/src/models/Order.js +912 -0
  215. package/dist/src/models/Order.js.map +1 -0
  216. package/dist/src/models/Organization.d.ts +119 -0
  217. package/dist/src/models/Organization.d.ts.map +1 -0
  218. package/dist/src/models/Organization.js +900 -0
  219. package/dist/src/models/Organization.js.map +1 -0
  220. package/dist/src/models/OrganizationRegistrationPeriod.d.ts +14 -0
  221. package/dist/src/models/OrganizationRegistrationPeriod.d.ts.map +1 -0
  222. package/dist/src/models/OrganizationRegistrationPeriod.js +62 -0
  223. package/dist/src/models/OrganizationRegistrationPeriod.js.map +1 -0
  224. package/dist/src/models/PasswordToken.d.ts +29 -0
  225. package/dist/src/models/PasswordToken.d.ts.map +1 -0
  226. package/dist/src/models/PasswordToken.js +118 -0
  227. package/dist/src/models/PasswordToken.js.map +1 -0
  228. package/dist/src/models/PayconiqPayment.d.ts +18 -0
  229. package/dist/src/models/PayconiqPayment.d.ts.map +1 -0
  230. package/dist/src/models/PayconiqPayment.js +216 -0
  231. package/dist/src/models/PayconiqPayment.js.map +1 -0
  232. package/dist/src/models/Payment.d.ts +62 -0
  233. package/dist/src/models/Payment.d.ts.map +1 -0
  234. package/dist/src/models/Payment.js +199 -0
  235. package/dist/src/models/Payment.js.map +1 -0
  236. package/dist/src/models/Platform.d.ts +15 -0
  237. package/dist/src/models/Platform.d.ts.map +1 -0
  238. package/dist/src/models/Platform.js +77 -0
  239. package/dist/src/models/Platform.js.map +1 -0
  240. package/dist/src/models/RegisterCode.d.ts +27 -0
  241. package/dist/src/models/RegisterCode.d.ts.map +1 -0
  242. package/dist/src/models/RegisterCode.js +162 -0
  243. package/dist/src/models/RegisterCode.js.map +1 -0
  244. package/dist/src/models/Registration.d.ts +47 -0
  245. package/dist/src/models/Registration.d.ts.map +1 -0
  246. package/dist/src/models/Registration.js +369 -0
  247. package/dist/src/models/Registration.js.map +1 -0
  248. package/dist/src/models/RegistrationPeriod.d.ts +15 -0
  249. package/dist/src/models/RegistrationPeriod.d.ts.map +1 -0
  250. package/dist/src/models/RegistrationPeriod.js +64 -0
  251. package/dist/src/models/RegistrationPeriod.js.map +1 -0
  252. package/dist/src/models/STCredit.d.ts +20 -0
  253. package/dist/src/models/STCredit.d.ts.map +1 -0
  254. package/dist/src/models/STCredit.js +129 -0
  255. package/dist/src/models/STCredit.js.map +1 -0
  256. package/dist/src/models/STInvoice.d.ts +51 -0
  257. package/dist/src/models/STInvoice.d.ts.map +1 -0
  258. package/dist/src/models/STInvoice.js +453 -0
  259. package/dist/src/models/STInvoice.js.map +1 -0
  260. package/dist/src/models/STPackage.d.ts +36 -0
  261. package/dist/src/models/STPackage.d.ts.map +1 -0
  262. package/dist/src/models/STPackage.js +300 -0
  263. package/dist/src/models/STPackage.js.map +1 -0
  264. package/dist/src/models/STPendingInvoice.d.ts +45 -0
  265. package/dist/src/models/STPendingInvoice.d.ts.map +1 -0
  266. package/dist/src/models/STPendingInvoice.js +284 -0
  267. package/dist/src/models/STPendingInvoice.js.map +1 -0
  268. package/dist/src/models/StripeAccount.d.ts +17 -0
  269. package/dist/src/models/StripeAccount.d.ts.map +1 -0
  270. package/dist/src/models/StripeAccount.js +81 -0
  271. package/dist/src/models/StripeAccount.js.map +1 -0
  272. package/dist/src/models/StripeCheckoutSession.d.ts +9 -0
  273. package/dist/src/models/StripeCheckoutSession.d.ts.map +1 -0
  274. package/dist/src/models/StripeCheckoutSession.js +31 -0
  275. package/dist/src/models/StripeCheckoutSession.js.map +1 -0
  276. package/dist/src/models/StripePaymentIntent.d.ts +9 -0
  277. package/dist/src/models/StripePaymentIntent.d.ts.map +1 -0
  278. package/dist/src/models/StripePaymentIntent.js +31 -0
  279. package/dist/src/models/StripePaymentIntent.js.map +1 -0
  280. package/dist/src/models/Ticket.d.ts +61 -0
  281. package/dist/src/models/Ticket.d.ts.map +1 -0
  282. package/dist/src/models/Ticket.js +143 -0
  283. package/dist/src/models/Ticket.js.map +1 -0
  284. package/dist/src/models/Token.d.ts +49 -0
  285. package/dist/src/models/Token.d.ts.map +1 -0
  286. package/dist/src/models/Token.js +218 -0
  287. package/dist/src/models/Token.js.map +1 -0
  288. package/dist/src/models/Token.test.d.ts +2 -0
  289. package/dist/src/models/Token.test.d.ts.map +1 -0
  290. package/dist/src/models/Token.test.js +60 -0
  291. package/dist/src/models/Token.test.js.map +1 -0
  292. package/dist/src/models/UsedRegisterCode.d.ts +22 -0
  293. package/dist/src/models/UsedRegisterCode.d.ts.map +1 -0
  294. package/dist/src/models/UsedRegisterCode.js +158 -0
  295. package/dist/src/models/UsedRegisterCode.js.map +1 -0
  296. package/dist/src/models/User.d.ts +55 -0
  297. package/dist/src/models/User.d.ts.map +1 -0
  298. package/dist/src/models/User.js +314 -0
  299. package/dist/src/models/User.js.map +1 -0
  300. package/dist/src/models/UserPermissions.d.ts +15 -0
  301. package/dist/src/models/UserPermissions.d.ts.map +1 -0
  302. package/dist/src/models/UserPermissions.js +57 -0
  303. package/dist/src/models/UserPermissions.js.map +1 -0
  304. package/dist/src/models/Webshop.d.ts +44 -0
  305. package/dist/src/models/Webshop.d.ts.map +1 -0
  306. package/dist/src/models/Webshop.js +184 -0
  307. package/dist/src/models/Webshop.js.map +1 -0
  308. package/dist/src/models/WebshopDiscountCode.d.ts +18 -0
  309. package/dist/src/models/WebshopDiscountCode.d.ts.map +1 -0
  310. package/dist/src/models/WebshopDiscountCode.js +88 -0
  311. package/dist/src/models/WebshopDiscountCode.js.map +1 -0
  312. package/dist/src/models/addresses/City.d.ts +14 -0
  313. package/dist/src/models/addresses/City.d.ts.map +1 -0
  314. package/dist/src/models/addresses/City.js +37 -0
  315. package/dist/src/models/addresses/City.js.map +1 -0
  316. package/dist/src/models/addresses/PostalCode.d.ts +20 -0
  317. package/dist/src/models/addresses/PostalCode.d.ts.map +1 -0
  318. package/dist/src/models/addresses/PostalCode.js +138 -0
  319. package/dist/src/models/addresses/PostalCode.js.map +1 -0
  320. package/dist/src/models/addresses/PostalCode.test.d.ts +2 -0
  321. package/dist/src/models/addresses/PostalCode.test.d.ts.map +1 -0
  322. package/dist/src/models/addresses/PostalCode.test.js +98 -0
  323. package/dist/src/models/addresses/PostalCode.test.js.map +1 -0
  324. package/dist/src/models/addresses/Province.d.ts +9 -0
  325. package/dist/src/models/addresses/Province.d.ts.map +1 -0
  326. package/dist/src/models/addresses/Province.js +24 -0
  327. package/dist/src/models/addresses/Province.js.map +1 -0
  328. package/dist/src/models/addresses/Street.d.ts +10 -0
  329. package/dist/src/models/addresses/Street.d.ts.map +1 -0
  330. package/dist/src/models/addresses/Street.js +26 -0
  331. package/dist/src/models/addresses/Street.js.map +1 -0
  332. package/dist/src/models/index.d.ts +37 -0
  333. package/dist/src/models/index.d.ts.map +1 -0
  334. package/dist/src/models/index.js +53 -0
  335. package/dist/src/models/index.js.map +1 -0
  336. package/dist/src/structures/OrganizationServerMetaData.d.ts +43 -0
  337. package/dist/src/structures/OrganizationServerMetaData.d.ts.map +1 -0
  338. package/dist/src/structures/OrganizationServerMetaData.js +128 -0
  339. package/dist/src/structures/OrganizationServerMetaData.js.map +1 -0
  340. package/dist/tests/jest.global.setup.d.ts +3 -0
  341. package/dist/tests/jest.global.setup.d.ts.map +1 -0
  342. package/dist/tests/jest.global.setup.js +20 -0
  343. package/dist/tests/jest.global.setup.js.map +1 -0
  344. package/dist/tests/jest.setup.d.ts +2 -0
  345. package/dist/tests/jest.setup.d.ts.map +1 -0
  346. package/dist/tests/jest.setup.js +15 -0
  347. package/dist/tests/jest.setup.js.map +1 -0
  348. package/package.json +30 -0
  349. package/src/assets/Metropolis-Black.woff2 +0 -0
  350. package/src/assets/Metropolis-BlackItalic.woff2 +0 -0
  351. package/src/assets/Metropolis-Bold.woff2 +0 -0
  352. package/src/assets/Metropolis-BoldItalic.woff2 +0 -0
  353. package/src/assets/Metropolis-ExtraBold.woff2 +0 -0
  354. package/src/assets/Metropolis-ExtraBoldItalic.woff2 +0 -0
  355. package/src/assets/Metropolis-ExtraLight.woff2 +0 -0
  356. package/src/assets/Metropolis-ExtraLightItalic.woff2 +0 -0
  357. package/src/assets/Metropolis-Light.woff2 +0 -0
  358. package/src/assets/Metropolis-LightItalic.woff2 +0 -0
  359. package/src/assets/Metropolis-Medium.woff2 +0 -0
  360. package/src/assets/Metropolis-MediumItalic.woff2 +0 -0
  361. package/src/assets/Metropolis-Regular.woff2 +0 -0
  362. package/src/assets/Metropolis-RegularItalic.woff2 +0 -0
  363. package/src/assets/Metropolis-SemiBold.woff2 +0 -0
  364. package/src/assets/Metropolis-SemiBoldItalic.woff2 +0 -0
  365. package/src/assets/Metropolis-Thin.woff2 +0 -0
  366. package/src/assets/Metropolis-ThinItalic.woff2 +0 -0
  367. package/src/assets/logo.png +0 -0
  368. package/src/factories/AddressFactory.ts +42 -0
  369. package/src/factories/EmergencyContactFactory.ts +43 -0
  370. package/src/factories/GroupFactory.ts +66 -0
  371. package/src/factories/MemberFactory.ts +122 -0
  372. package/src/factories/OrganizationFactory.ts +45 -0
  373. package/src/factories/ParentFactory.ts +49 -0
  374. package/src/factories/RecordFactory.ts +12 -0
  375. package/src/factories/RegisterCodeFactory.ts +25 -0
  376. package/src/factories/RegistrationFactory.ts +32 -0
  377. package/src/factories/UserFactory.ts +66 -0
  378. package/src/factories/WebshopFactory.ts +43 -0
  379. package/src/helpers/DNSValidator.ts +153 -0
  380. package/src/helpers/EmailBuilder.ts +127 -0
  381. package/src/helpers/GroupBuilder.ts +438 -0
  382. package/src/helpers/Handlebars.ts +203 -0
  383. package/src/helpers/InvoiceBuilder.test.ts +57 -0
  384. package/src/helpers/InvoiceBuilder.ts +501 -0
  385. package/src/helpers/RateLimiter.ts +75 -0
  386. package/src/helpers/WebshopCounter.test.ts +16 -0
  387. package/src/helpers/WebshopCounter.ts +36 -0
  388. package/src/index.ts +21 -0
  389. package/src/migrations/1593773929-create-initial-tables.sql +634 -0
  390. package/src/migrations/1605261999-gemeenten-tmp.sql +2820 -0
  391. package/src/migrations/1605262045-import-postcodes.ts +132 -0
  392. package/src/migrations/1605262046-import-postcodes-nl.ts +97 -0
  393. package/src/migrations/1605279038-drop-gemeenten-tmp.sql +1 -0
  394. package/src/migrations/1648392491-default-templates.sql +9 -0
  395. package/src/migrations/1651245707-default-templates-reminders.sql +6 -0
  396. package/src/migrations/1708607340-tickets-deleted-at.sql +1 -0
  397. package/src/migrations/1710459176-register-code-invoices.sql +3 -0
  398. package/src/migrations/1712158247-discount-codes.sql +17 -0
  399. package/src/migrations/1713178665-drop-invites.sql +1 -0
  400. package/src/migrations/1713178666-drop-keychain.sql +1 -0
  401. package/src/migrations/1713178667-drop-challenges.sql +1 -0
  402. package/src/migrations/1713178668-drop-user-keys.sql +7 -0
  403. package/src/migrations/1713178669-drop-organization-key.sql +2 -0
  404. package/src/migrations/1714985451-user-nullable-organization-id.sql +2 -0
  405. package/src/migrations/1714985452-email-verification-code-nullable-organization-id.sql +2 -0
  406. package/src/migrations/1714985453-user-organization-permissions.sql +2 -0
  407. package/src/migrations/1714985454-user-organization-permissions.sql +2 -0
  408. package/src/migrations/1715079362-platform.sql +6 -0
  409. package/src/migrations/1715181649-registrations-organization-id.sql +2 -0
  410. package/src/migrations/1715181650-registrations-organization-id-fill.sql +1 -0
  411. package/src/migrations/1715181651-registrations-organization-id-drop-null.sql +2 -0
  412. package/src/migrations/1716117067-members-nullable-organization-id.sql +2 -0
  413. package/src/migrations/1719567581-registration-periods.sql +13 -0
  414. package/src/migrations/1719567582-organization-registration-periods.sql +13 -0
  415. package/src/migrations/1719567881-organization-periodId.sql +2 -0
  416. package/src/migrations/1719567882-groups-periodId.sql +2 -0
  417. package/src/migrations/1719567883-platform-periodId.sql +2 -0
  418. package/src/migrations/1719568079-default-period.sql +2 -0
  419. package/src/migrations/1719568080-set-default-period-platform.sql +1 -0
  420. package/src/migrations/1719568081-set-default-period-organizations.sql +1 -0
  421. package/src/migrations/1719568082-set-default-period-groups.sql +1 -0
  422. package/src/migrations/1719580828-registrations-periodId.sql +2 -0
  423. package/src/migrations/1719580829-set-default-period-registrations.sql +1 -0
  424. package/src/migrations/data/postcodes/nl/Drenthe +291 -0
  425. package/src/migrations/data/postcodes/nl/Flevoland +107 -0
  426. package/src/migrations/data/postcodes/nl/Friesland +518 -0
  427. package/src/migrations/data/postcodes/nl/Gelderland +601 -0
  428. package/src/migrations/data/postcodes/nl/Groningen +279 -0
  429. package/src/migrations/data/postcodes/nl/Limburg +324 -0
  430. package/src/migrations/data/postcodes/nl/Noord-Brabant +620 -0
  431. package/src/migrations/data/postcodes/nl/Noord-Holland +566 -0
  432. package/src/migrations/data/postcodes/nl/Overrijsel +344 -0
  433. package/src/migrations/data/postcodes/nl/Utrecht +278 -0
  434. package/src/migrations/data/postcodes/nl/Zeeland +179 -0
  435. package/src/migrations/data/postcodes/nl/Zuid-Holland +662 -0
  436. package/src/models/BalanceItem.ts +392 -0
  437. package/src/models/BalanceItemPayment.ts +106 -0
  438. package/src/models/BuckarooPayment.ts +19 -0
  439. package/src/models/Document.ts +203 -0
  440. package/src/models/DocumentTemplate.ts +583 -0
  441. package/src/models/EmailTemplate.ts +64 -0
  442. package/src/models/EmailVerificationCode.ts +352 -0
  443. package/src/models/Group.ts +293 -0
  444. package/src/models/Image.ts +147 -0
  445. package/src/models/Member.ts +386 -0
  446. package/src/models/MemberResponsibilityRecord.ts +39 -0
  447. package/src/models/MolliePayment.ts +19 -0
  448. package/src/models/MollieToken.ts +369 -0
  449. package/src/models/OneTimeToken.ts +131 -0
  450. package/src/models/Order.ts +1030 -0
  451. package/src/models/Organization.ts +1085 -0
  452. package/src/models/OrganizationRegistrationPeriod.ts +54 -0
  453. package/src/models/PasswordToken.ts +139 -0
  454. package/src/models/PayconiqPayment.ts +241 -0
  455. package/src/models/Payment.ts +216 -0
  456. package/src/models/Platform.ts +76 -0
  457. package/src/models/RegisterCode.ts +164 -0
  458. package/src/models/Registration.ts +405 -0
  459. package/src/models/RegistrationPeriod.ts +55 -0
  460. package/src/models/STCredit.ts +134 -0
  461. package/src/models/STInvoice.ts +507 -0
  462. package/src/models/STPackage.ts +324 -0
  463. package/src/models/STPendingInvoice.ts +308 -0
  464. package/src/models/StripeAccount.ts +71 -0
  465. package/src/models/StripeCheckoutSession.ts +22 -0
  466. package/src/models/StripePaymentIntent.ts +22 -0
  467. package/src/models/Ticket.ts +145 -0
  468. package/src/models/Token.test.ts +69 -0
  469. package/src/models/Token.ts +269 -0
  470. package/src/models/UsedRegisterCode.ts +166 -0
  471. package/src/models/User.ts +445 -0
  472. package/src/models/UserPermissions.ts +54 -0
  473. package/src/models/Webshop.ts +206 -0
  474. package/src/models/WebshopDiscountCode.ts +81 -0
  475. package/src/models/addresses/City.ts +31 -0
  476. package/src/models/addresses/PostalCode.test.ts +117 -0
  477. package/src/models/addresses/PostalCode.ts +164 -0
  478. package/src/models/addresses/Province.ts +20 -0
  479. package/src/models/addresses/Street.ts +25 -0
  480. package/src/models/index.ts +49 -0
  481. package/src/structures/OrganizationServerMetaData.ts +117 -0
@@ -0,0 +1,166 @@
1
+ import { column, Model } from "@simonbackx/simple-database";
2
+ import { Email } from "@stamhoofd/email";
3
+ import { Formatter } from "@stamhoofd/utility";
4
+ import { v4 as uuidv4 } from "uuid";
5
+
6
+ import { Organization, RegisterCode, STCredit, STPendingInvoice } from "./";
7
+ import { STInvoiceItem } from "@stamhoofd/structures";
8
+ import { QueueHandler } from "@stamhoofd/queues";
9
+
10
+ export class UsedRegisterCode extends Model {
11
+ static table = "used_register_codes";
12
+
13
+ @column({
14
+ primary: true, type: "string", beforeSave(value) {
15
+ return value ?? uuidv4();
16
+ }
17
+ })
18
+ id!: string;
19
+
20
+ @column({ type: "string" })
21
+ code: string;
22
+
23
+ /**
24
+ * Code is used by...
25
+ */
26
+ @column({ type: "string" })
27
+ organizationId: string;
28
+
29
+ /**
30
+ * Set if this has been rewarded
31
+ */
32
+ @column({ type: "string", nullable: true })
33
+ creditId: string | null = null;
34
+
35
+ @column({
36
+ type: "datetime", beforeSave(old?: any) {
37
+ if (old !== undefined) {
38
+ return old;
39
+ }
40
+ const date = new Date()
41
+ date.setMilliseconds(0)
42
+ return date
43
+ }
44
+ })
45
+ createdAt: Date
46
+
47
+ @column({
48
+ type: "datetime", beforeSave() {
49
+ const date = new Date()
50
+ date.setMilliseconds(0)
51
+ return date
52
+ },
53
+ skipUpdate: true
54
+ })
55
+ updatedAt: Date
56
+
57
+ static async getFor(organizationId: string): Promise<UsedRegisterCode | undefined> {
58
+ const code = await this.where({ organizationId }, { limit: 1 })
59
+ return code[0] ?? undefined
60
+ }
61
+
62
+ async reward() {
63
+ if (this.creditId) {
64
+ // Already received
65
+ console.error("Already rewarded for used register code "+this.id)
66
+ return
67
+ }
68
+
69
+ const code = await RegisterCode.getByID(this.code)
70
+ if (!code || !code.organizationId) {
71
+ console.error("Couldn't find code "+this.code+" for used register code "+this.id)
72
+ return
73
+ }
74
+
75
+ const organization = await Organization.getByID(this.organizationId)
76
+ if (!organization) {
77
+ console.error("Couldn't find organization with id "+this.organizationId+" for used register code "+this.id)
78
+ return
79
+ }
80
+
81
+ const receivingOrganization = await Organization.getByID(code.organizationId)
82
+ if (!receivingOrganization) {
83
+ console.error("Couldn't find receiving organization with id "+code.organizationId+" for used register code "+this.id)
84
+ return
85
+ }
86
+
87
+ const usedCount = await UsedRegisterCode.getUsedCount(this.code) + 1
88
+
89
+ const credit = new STCredit()
90
+ credit.organizationId = code.organizationId
91
+ credit.change = code.invoiceValue ? 0 : Math.min(100 * 100, usedCount * 10 * 100)
92
+ credit.description = organization.name+" doorverwezen 🙌"
93
+
94
+ // Expire in one year (will get extended for every purchase or activation)
95
+ credit.expireAt = new Date()
96
+ credit.expireAt.setFullYear(credit.expireAt.getFullYear() + 1)
97
+ credit.expireAt.setMilliseconds(0)
98
+
99
+ await credit.save()
100
+ this.creditId = credit.id
101
+ await this.save()
102
+
103
+ if (code.invoiceValue) {
104
+ const name = "Aankoop Stamhoofd voor " + organization.name
105
+ const item = STInvoiceItem.create({
106
+ name,
107
+ description: "Via doorverwijzingscode",
108
+ amount: 1,
109
+ unitPrice: code.invoiceValue,
110
+ canUseCredits: false
111
+ })
112
+ console.log("Scheduling code charge for ", code)
113
+ await QueueHandler.schedule("billing/invoices-"+receivingOrganization.id, async () => {
114
+ await STPendingInvoice.addItems(receivingOrganization, [item])
115
+ });
116
+ }
117
+
118
+ const admins = await receivingOrganization.getAdminToEmails()
119
+ if (admins) {
120
+ if (code.invoiceValue) {
121
+ Email.sendInternal({
122
+ to: admins,
123
+ bcc: "simon@stamhoofd.be",
124
+ subject: `${organization.name} heeft jullie tegoed gebruikt`,
125
+ text: "Dag "+receivingOrganization.name+",\n\n"+organization.name+" had jullie doorverwijzingslink gebruikt om zich op Stamhoofd te registreren, en nu hebben ze dit ook gebruikt. Zoals afgesproken wordt hiervoor " + Formatter.price(code.invoiceValue)+ " aangerekend via jullie openstaand saldo in jullie Stamhoofd account."
126
+ + "\n\n— Stamhoofd"
127
+ }, organization.i18n)
128
+
129
+ } else {
130
+ // Delay email until everything is validated and saved
131
+ Email.sendInternal({
132
+ to: admins,
133
+ bcc: "simon@stamhoofd.be",
134
+ subject: "Je hebt "+Formatter.price(credit.change)+" tegoed ontvangen 💰",
135
+ text: "Dag "+receivingOrganization.name+",\n\nGeweldig nieuws! "+organization.name+" had jullie doorverwijzingslink gebruikt om zich op Stamhoofd te registreren, en nu hebben ze ook voor het eerst minstens één euro uitgegeven. Daardoor ontvangen jullie "+Formatter.price(credit.change)+" tegoed voor Stamhoofd (zie daarvoor Stamhoofd > Instellingen). "
136
+ + (credit.change <= 90*100 ? ("Bij de volgende vereniging ontvangen jullie nog meer: "+Formatter.price(credit.change + 10*100)+". ") : "")
137
+ + (credit.change <= 80*100 ? ("En dat blijft oplopen tot € 100,00 per vereniging die je aanbrengt 🎁 ") : "")
138
+ + "Doe zo verder! Lees zeker onze tips na om nog een groter bedrag te verzamelen 😉\n\n— Stamhoofd"
139
+ }, organization.i18n)
140
+ }
141
+ }
142
+ }
143
+
144
+ static async getAll(code: string) {
145
+ const used = await UsedRegisterCode.where({
146
+ code
147
+ })
148
+ return used
149
+ }
150
+
151
+ static async getUsed(code: string) {
152
+ const used = await UsedRegisterCode.where({
153
+ code,
154
+ creditId: {
155
+ value: null,
156
+ sign: "!="
157
+ }
158
+ })
159
+ return used
160
+ }
161
+
162
+ static async getUsedCount(code: string) {
163
+ const used = await this.getUsed(code)
164
+ return used.length
165
+ }
166
+ }
@@ -0,0 +1,445 @@
1
+
2
+ import { column, Database, ManyToOneRelation, Model } from "@simonbackx/simple-database";
3
+ import { EmailInterfaceRecipient } from "@stamhoofd/email";
4
+ import { LoginProviderType, NewUser, Permissions, User as UserStruct,UserMeta, UserPermissions } from "@stamhoofd/structures";
5
+ import argon2 from "argon2";
6
+ import { v4 as uuidv4 } from "uuid";
7
+
8
+ import { Organization, Platform } from "./";
9
+
10
+ export class User extends Model {
11
+ static table = "users";
12
+
13
+ // Columns
14
+ @column({
15
+ primary: true, type: "string", beforeSave(value) {
16
+ return value ?? uuidv4();
17
+ }
18
+ })
19
+ id!: string;
20
+
21
+ @column({ foreignKey: User.organization, type: "string", nullable: true })
22
+ organizationId: string|null;
23
+
24
+ @column({ type: "string", nullable: true })
25
+ firstName: string | null = null;
26
+
27
+ @column({ type: "string", nullable: true })
28
+ lastName: string | null = null;
29
+
30
+ @column({ type: "string" })
31
+ email: string;
32
+
33
+ @column({ type: "string", nullable: true })
34
+ password: string | null = null;
35
+
36
+ @column({ type: "boolean" })
37
+ verified = false
38
+
39
+ @column({ type: "json", decoder: UserPermissions, nullable: true })
40
+ permissions: UserPermissions | null = null
41
+
42
+ /**
43
+ * @deprecated
44
+ * use permissions
45
+ */
46
+ @column({ type: "json", decoder: Permissions, nullable: true })
47
+ organizationPermissions: Permissions | null = null
48
+
49
+ @column({ type: "json", decoder: UserMeta, nullable: true })
50
+ meta: UserMeta | null = null
51
+
52
+ @column({
53
+ type: "datetime", beforeSave(old?: any) {
54
+ if (old !== undefined) {
55
+ return old;
56
+ }
57
+ const date = new Date()
58
+ date.setMilliseconds(0)
59
+ return date
60
+ }
61
+ })
62
+ createdAt: Date
63
+
64
+ @column({
65
+ type: "datetime", beforeSave() {
66
+ const date = new Date()
67
+ date.setMilliseconds(0)
68
+ return date
69
+ },
70
+ skipUpdate: true
71
+ })
72
+ updatedAt: Date
73
+
74
+ static organization = new ManyToOneRelation(Organization, "organization");
75
+
76
+ get name() {
77
+ if (this.firstName && this.lastName) {
78
+ return this.firstName + " " + this.lastName;
79
+ }
80
+
81
+ if (this.firstName) {
82
+ return this.firstName;
83
+ }
84
+
85
+ if (this.lastName) {
86
+ return this.lastName;
87
+ }
88
+
89
+ return null;
90
+ }
91
+
92
+ static async getAdmins(organizationIds: string[], options?: {verified?: boolean}) {
93
+ if (organizationIds.length == 0) {
94
+ return []
95
+ }
96
+
97
+ if (STAMHOOFD.userMode === 'platform') {
98
+ // Custom implementation
99
+ let global = (await User.where({ organizationId: null, permissions: { sign: "!=", value: null }}))
100
+ global = global.filter(u => organizationIds.find(organizationId => u.permissions?.organizationPermissions.has(organizationId)))
101
+
102
+ // Hide api accounts
103
+ global = global.filter(a => !a.isApiUser)
104
+
105
+ return global
106
+ }
107
+
108
+ const query: any = {
109
+ permissions: { sign: "!=", value: null },
110
+ organizationId: {sign: 'IN', value: organizationIds},
111
+ };
112
+
113
+ if (options?.verified !== undefined) {
114
+ query.verified = options.verified
115
+ }
116
+
117
+ return (
118
+ await User.where(query)
119
+ ).filter(a => !a.isApiUser)
120
+ }
121
+
122
+ static async getApiUsers(organizationIds: string[]) {
123
+ return organizationIds.length > 0 ? (await User.where({ permissions: { sign: "!=", value: null }, organizationId: {sign: 'IN', value: organizationIds}})).filter(a => a.isApiUser) : []
124
+ }
125
+
126
+ async merge(other: User) {
127
+ if (other.hasAccount()) {
128
+ // We are going to merge accounts!
129
+ if (this.organizationPermissions && other.organizationPermissions) {
130
+ this.organizationPermissions.add(other.organizationPermissions);
131
+ } else {
132
+ if (!this.organizationPermissions && other.organizationPermissions) {
133
+ this.organizationPermissions = other.organizationPermissions;
134
+ }
135
+ }
136
+ await this.save();
137
+
138
+ if (other.firstName && !this.firstName) {
139
+ this.firstName = other.firstName;
140
+ }
141
+
142
+ if (other.lastName && !this.lastName) {
143
+ this.lastName = other.lastName;
144
+ }
145
+ }
146
+
147
+ const Member = (await import("./Member")).Member
148
+
149
+ // Delete placeholder account, but migrate members first
150
+ const members = await Member.getMembersWithRegistrationForUser(other)
151
+
152
+ if (members.length > 0) {
153
+ console.log("Moving members from user "+other.id+" to "+this.id)
154
+ await Member.users.reverse("members").link(this, members)
155
+ }
156
+
157
+ // Update balance items
158
+ const query = "UPDATE balance_items SET userId = ? WHERE userId = ?"
159
+ await Database.update(query, [this.id, other.id])
160
+
161
+ // Update payments
162
+ const query2 = "UPDATE payments SET userId = ? WHERE userId = ?"
163
+ await Database.update(query2, [this.id, other.id])
164
+
165
+ // Update orders
166
+ const query3 = "UPDATE webshop_orders SET userId = ? WHERE userId = ?"
167
+ await Database.update(query3, [this.id, other.id])
168
+
169
+ await other.delete()
170
+ }
171
+
172
+ static async login(organizationId: string|null, email: string, password: string): Promise<User | undefined> {
173
+ const user = await User.getForAuthentication(organizationId, email)
174
+ if (!user || !user.hasKeys() || user.isApiUser) {
175
+ return undefined
176
+ }
177
+
178
+ if (STAMHOOFD.environment === 'development') {
179
+ if (password === 'stamhoofd') {
180
+ return user
181
+ }
182
+ }
183
+
184
+ if (!user.password) {
185
+ console.log('Tried to login to a user without password', email)
186
+ return
187
+ }
188
+
189
+ try {
190
+ if (await argon2.verify(user.password, password)) {
191
+ return user
192
+ }
193
+ } catch (e) {
194
+ // internal failure
195
+ console.error(e)
196
+ }
197
+ }
198
+
199
+ /// Delete users when we delete a member
200
+ static async deleteForDeletedMember(memberId: string) {
201
+ const [rows] = await Database.delete(`DELETE ${this.table} FROM ${this.table} JOIN _members_users a ON a.usersId = ${this.table}.id LEFT JOIN _members_users b ON b.usersId = ${this.table}.id AND b.membersId != a.membersId WHERE a.membersId = ? and b.membersId is null and users.permissions is null`, [memberId]);
202
+ return rows
203
+ }
204
+
205
+ hasPasswordBasedAccount() {
206
+ if (this.password) {
207
+ return true;
208
+ }
209
+
210
+ return false
211
+ }
212
+
213
+ get isApiUser() {
214
+ return !this.email.includes('@') && this.email.endsWith('.api') && this.verified
215
+ }
216
+
217
+ hasAccount() {
218
+ if (this.hasPasswordBasedAccount()) {
219
+ return true;
220
+ }
221
+ if ((this.meta?.loginProviderIds?.size ?? 0) > 0) {
222
+ return true;
223
+ }
224
+ if (this.isApiUser) {
225
+ return true;
226
+ }
227
+ return false
228
+ }
229
+
230
+ protected hasKeys() {
231
+ if (this.password) {
232
+ // Users with a password are 'real' users. Always.
233
+ return true;
234
+ }
235
+
236
+ return false;
237
+ }
238
+
239
+ static async getForRegister(organizationId: string|null, email: string): Promise<User | undefined> {
240
+ return await this.getForAuthentication(organizationId, email, {allowWithoutAccount: true})
241
+ }
242
+
243
+ static async getOrganizationLevelUser(organizationId: string, email: string): Promise<User | undefined> {
244
+ const users = await User.where({
245
+ email,
246
+ organizationId: organizationId
247
+ }, {
248
+ limit: 1
249
+ })
250
+
251
+ if (users.length == 0) {
252
+ return undefined;
253
+ }
254
+ const user = users[0]
255
+
256
+ if (!user) {
257
+ return undefined
258
+ }
259
+
260
+ return user;
261
+ }
262
+
263
+ static async getForAuthentication(organizationId: string|null, email: string, {allowWithoutAccount = false}: {allowWithoutAccount?: boolean} = {}): Promise<User | undefined> {
264
+ const users = await User.where({
265
+ email,
266
+ organizationId: STAMHOOFD.userMode === 'platform' ? null : organizationId
267
+ }, {
268
+ limit: 1
269
+ })
270
+
271
+ if (users.length == 0) {
272
+ if (organizationId && STAMHOOFD.userMode === 'organization') {
273
+ return this.getForAuthentication(null, email, {allowWithoutAccount})
274
+ }
275
+ return undefined;
276
+ }
277
+ const user = users[0]
278
+
279
+ if (!user || (!user.hasKeys() && !allowWithoutAccount)) {
280
+ if (organizationId && STAMHOOFD.userMode === 'organization') {
281
+ return this.getForAuthentication(null, email, {allowWithoutAccount})
282
+ }
283
+ return undefined
284
+ }
285
+
286
+ // Read member + address from first row
287
+ return user;
288
+ }
289
+
290
+ static async hash(password: string) {
291
+ const hash = await argon2.hash(password, { type: argon2.argon2id })
292
+ return hash
293
+ }
294
+
295
+ static async createInvited(
296
+ organization: Organization|null,
297
+ data: {firstName: string|null, lastName: string|null, email: string, allowPlatform?: boolean}
298
+ ): Promise<User | undefined> {
299
+ const {
300
+ email,
301
+ firstName,
302
+ lastName
303
+ } = data;
304
+
305
+ if (!organization && STAMHOOFD.userMode !== 'platform' && !data.allowPlatform) {
306
+ throw new Error("Missing organization")
307
+ }
308
+
309
+ const user = new User();
310
+ user.organizationId = STAMHOOFD.userMode === 'platform' ? null : (organization?.id ?? null)
311
+ user.id = uuidv4()
312
+ user.email = email;
313
+ user.verified = false;
314
+ user.firstName = firstName
315
+ user.lastName = lastName
316
+
317
+ try {
318
+ await user.save();
319
+ } catch (e) {
320
+ // Duplicate key probably
321
+ if (e.code && e.code == "ER_DUP_ENTRY") {
322
+ return;
323
+ }
324
+ throw e;
325
+ }
326
+
327
+ return user;
328
+ }
329
+
330
+ static async register(
331
+ organization: Organization|null,
332
+ data: NewUser
333
+ ): Promise<User | undefined> {
334
+ const {
335
+ email,
336
+ password,
337
+ id,
338
+ firstName,
339
+ lastName
340
+ } = data;
341
+
342
+ if (!password) {
343
+ throw new Error("A password is required for new users")
344
+ }
345
+
346
+ if (!organization && STAMHOOFD.userMode !== 'platform') {
347
+ throw new Error("Missing organization")
348
+ }
349
+
350
+ const user = new User();
351
+ user.organizationId = STAMHOOFD.userMode === 'platform' ? null : (organization?.id ?? null)
352
+ user.id = id ?? uuidv4()
353
+ user.email = email;
354
+ user.password = await this.hash(password)
355
+ user.verified = false;
356
+ user.firstName = firstName
357
+ user.lastName = lastName
358
+
359
+ try {
360
+ await user.save();
361
+ } catch (e) {
362
+ // Duplicate key probably
363
+ if (e.code && e.code == "ER_DUP_ENTRY") {
364
+ return;
365
+ }
366
+ throw e;
367
+ }
368
+
369
+ return user;
370
+ }
371
+
372
+ linkLoginProvider(type: LoginProviderType, sub: string) {
373
+ if (!this.meta) {
374
+ this.meta = UserMeta.create({})
375
+ }
376
+ this.meta.loginProviderIds.set(type, sub)
377
+ }
378
+
379
+ static async registerSSO(
380
+ organization: Organization|null,
381
+ data: {email, id, firstName, lastName, type: LoginProviderType, sub: string}
382
+ ): Promise<User | undefined> {
383
+ const {
384
+ email,
385
+ id,
386
+ firstName,
387
+ lastName
388
+ } = data;
389
+
390
+ if (STAMHOOFD.userMode === 'platform') {
391
+ throw new Error('SSO is disabled on platforms for now')
392
+ }
393
+
394
+ if (!organization) {
395
+ throw new Error("Missing organization")
396
+ }
397
+
398
+ const user = new User();
399
+ user.organizationId = organization.id
400
+ user.id = id ?? uuidv4()
401
+ user.email = email;
402
+ user.verified = false;
403
+ user.firstName = firstName
404
+ user.lastName = lastName
405
+ user.linkLoginProvider(data.type, data.sub)
406
+
407
+ try {
408
+ await user.save();
409
+ } catch (e) {
410
+ // Duplicate key probably
411
+ if (e.code && e.code == "ER_DUP_ENTRY") {
412
+ return;
413
+ }
414
+ throw e;
415
+ }
416
+
417
+ return user;
418
+ }
419
+
420
+ async changePassword(password: string) {
421
+ this.password = await User.hash(password)
422
+ }
423
+
424
+ getStructure() {
425
+ return UserStruct.create({
426
+ firstName: this.firstName,
427
+ lastName: this.lastName,
428
+ id: this.id,
429
+ email: this.email,
430
+ verified: this.verified,
431
+ permissions: this.permissions,
432
+ hasAccount: this.hasAccount()
433
+ });
434
+ }
435
+
436
+ getEmailTo(): EmailInterfaceRecipient[] {
437
+ return [
438
+ {
439
+ email: this.email,
440
+ name: this.name
441
+ }
442
+ ]
443
+ }
444
+
445
+ }
@@ -0,0 +1,54 @@
1
+
2
+ import { column, ManyToOneRelation, Model } from "@simonbackx/simple-database";
3
+ import { Permissions } from "@stamhoofd/structures";
4
+ import { v4 as uuidv4 } from "uuid";
5
+
6
+ import { Organization, User } from "./";
7
+
8
+ export class UserPermissions extends Model {
9
+ static table = "user_permissions";
10
+
11
+ // Columns
12
+ @column({
13
+ primary: true, type: "string", beforeSave(value) {
14
+ return value ?? uuidv4();
15
+ }
16
+ })
17
+ id!: string;
18
+
19
+ @column({ foreignKey: UserPermissions.organization, type: "string" })
20
+ organizationId: string;
21
+
22
+ @column({ foreignKey: UserPermissions.user, type: "string" })
23
+ userId: string;
24
+
25
+ @column({ type: "json", decoder: Permissions, nullable: true })
26
+ permissions: Permissions | null = null
27
+
28
+ @column({
29
+ type: "datetime", beforeSave(old?: any) {
30
+ if (old !== undefined) {
31
+ return old;
32
+ }
33
+ const date = new Date()
34
+ date.setMilliseconds(0)
35
+ return date
36
+ }
37
+ })
38
+ createdAt: Date
39
+
40
+ @column({
41
+ type: "datetime", beforeSave() {
42
+ const date = new Date()
43
+ date.setMilliseconds(0)
44
+ return date
45
+ },
46
+ skipUpdate: true
47
+ })
48
+ updatedAt: Date
49
+
50
+ static organization = new ManyToOneRelation(Organization, "organization");
51
+ static user = new ManyToOneRelation(User, "user");
52
+
53
+
54
+ }