@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,71 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
+ import { column, Model } from '@simonbackx/simple-database';
3
+ import { Requirements, StripeBusinessProfile, StripeCompany, StripeMetaAccountSettings, StripeMetaData } from '@stamhoofd/structures';
4
+ import { v4 as uuidv4 } from "uuid";
5
+
6
+ /**
7
+ * Keeps track of how much a member/user owes or needs to be reimbursed.
8
+ */
9
+ export class StripeAccount extends Model {
10
+ static table = "stripe_accounts"
11
+
12
+ @column({
13
+ primary: true, type: "string", beforeSave(value) {
14
+ return value ?? uuidv4();
15
+ }
16
+ })
17
+ id!: string;
18
+
19
+ @column({ type: "string" })
20
+ organizationId: string
21
+
22
+ @column({ type: "string" })
23
+ accountId: string
24
+
25
+ @column({ type: "json", decoder: StripeMetaData })
26
+ meta = StripeMetaData.create({})
27
+
28
+ @column({ type: "string" })
29
+ status: 'active' | 'deleted' = 'active'
30
+
31
+ @column({
32
+ type: "datetime", beforeSave(old?: any) {
33
+ if (old !== undefined) {
34
+ return old;
35
+ }
36
+ const date = new Date()
37
+ date.setMilliseconds(0)
38
+ return date
39
+ }
40
+ })
41
+ createdAt: Date
42
+
43
+ @column({
44
+ type: "datetime", beforeSave() {
45
+ const date = new Date()
46
+ date.setMilliseconds(0)
47
+ return date
48
+ },
49
+ skipUpdate: true
50
+ })
51
+ updatedAt: Date
52
+
53
+ setMetaFromStripeAccount(account: any) {
54
+ this.meta = StripeMetaData.create({
55
+ type: account.type ?? 'express',
56
+ blob: account,
57
+ business_profile: StripeBusinessProfile.create(!account.business_profile?.name ? {...account.business_profile, name: ''} : account.business_profile),
58
+ business_type: account.business_type ?? this.meta.business_type ?? null,
59
+ company: account.company ? StripeCompany.create(account.company) : (this.meta.company ?? null),
60
+ charges_enabled: account.charges_enabled,
61
+ payouts_enabled: account.payouts_enabled,
62
+ details_submitted: account.details_submitted,
63
+ capabilities: account.capabilities,
64
+ requirements: Requirements.create(account.requirements),
65
+ future_requirements: Requirements.create(account.future_requirements),
66
+ settings: StripeMetaAccountSettings.create(account.settings),
67
+ bank_account_last4: account.external_accounts?.data[0]?.last4 ?? this.meta.bank_account_last4 ?? "",
68
+ bank_account_bank_name: account.external_accounts?.data[0]?.bank_name ?? this.meta.bank_account_bank_name ?? "",
69
+ });
70
+ }
71
+ }
@@ -0,0 +1,22 @@
1
+ import { column,Model } from "@simonbackx/simple-database";
2
+ import { v4 as uuidv4 } from "uuid";
3
+
4
+ export class StripeCheckoutSession extends Model {
5
+ static table = "stripe_checkout_sessions";
6
+
7
+ @column({
8
+ primary: true, type: "string", beforeSave(value) {
9
+ return value ?? uuidv4();
10
+ }
11
+ })
12
+ id!: string;
13
+
14
+ @column({ type: "string" })
15
+ paymentId: string;
16
+
17
+ @column({ type: "string" })
18
+ stripeSessionId: string;
19
+
20
+ @column({ type: "string", nullable: true })
21
+ organizationId: string | null = null;
22
+ }
@@ -0,0 +1,22 @@
1
+ import { column,Model } from "@simonbackx/simple-database";
2
+ import { v4 as uuidv4 } from "uuid";
3
+
4
+ export class StripePaymentIntent extends Model {
5
+ static table = "stripe_payment_intents";
6
+
7
+ @column({
8
+ primary: true, type: "string", beforeSave(value) {
9
+ return value ?? uuidv4();
10
+ }
11
+ })
12
+ id!: string;
13
+
14
+ @column({ type: "string" })
15
+ paymentId: string;
16
+
17
+ @column({ type: "string" })
18
+ stripeIntentId: string;
19
+
20
+ @column({ type: "string", nullable: true })
21
+ organizationId: string | null = null;
22
+ }
@@ -0,0 +1,145 @@
1
+ import { column, ManyToOneRelation, Model } from "@simonbackx/simple-database";
2
+ import { CartReservedSeat } from "@stamhoofd/structures";
3
+ import basex from "base-x";
4
+ import crypto from "crypto";
5
+ import { v4 as uuidv4 } from "uuid";
6
+
7
+ import { Order, Organization, Webshop } from './';
8
+
9
+ // Note: 0 and O is removed to prevent typing it in wrong
10
+ const ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZ'
11
+ const bs58 = basex(ALPHABET)
12
+
13
+ async function randomBytes(size: number): Promise<Buffer> {
14
+ return new Promise((resolve, reject) => {
15
+ crypto.randomBytes(size, (err: Error | null, buf: Buffer) => {
16
+ if (err) {
17
+ reject(err);
18
+ return;
19
+ }
20
+ resolve(buf);
21
+ });
22
+ });
23
+ }
24
+
25
+ /**
26
+ * Use this method when you don't need access to the items of an order.
27
+ * This avoids the select in the database, saving some bytes in network communication
28
+ * (especially needed when clients requests all the changed tickets)
29
+ */
30
+ export class Ticket extends Model {
31
+ static table = "webshop_tickets";
32
+
33
+ // Columns
34
+ @column({
35
+ primary: true, type: "string", beforeSave(value) {
36
+ return value ?? uuidv4();
37
+ }
38
+ })
39
+ id!: string;
40
+
41
+ /**
42
+ * Unique per webshop. Used for lookups
43
+ */
44
+ @column({ type: "string", async beforeSave(value) {
45
+ return value ?? bs58.encode(await randomBytes(10));
46
+ } })
47
+ secret!: string
48
+
49
+
50
+ @column({ foreignKey: Ticket.organization, type: "string" })
51
+ organizationId: string;
52
+
53
+ @column({ foreignKey: Ticket.webshop, type: "string" })
54
+ webshopId: string;
55
+
56
+ /**
57
+ * Important note: access to a ticket doesn't guarantee access to an order
58
+ * because one person could buy 10 tickets and share them with friends.
59
+ * The order details should remain private to a ticket holder except for the item details
60
+ * + also the orderID should remain private for the holder (since this provides access via URL, need to add a secret here)
61
+ */
62
+ @column({ foreignKey: Ticket.order, type: "string" })
63
+ orderId: string
64
+
65
+ /**
66
+ * null = whole order
67
+ */
68
+ @column({ type: "string", nullable: true })
69
+ itemId: string | null = null
70
+
71
+ /**
72
+ * If multiple items are made for the same product, this contains the index
73
+ */
74
+ @column({ type: "number" })
75
+ index = 0
76
+
77
+ /**
78
+ * total items with index
79
+ */
80
+ @column({ type: "number" })
81
+ total = 0
82
+
83
+ /**
84
+ * If multiple items are made for the same product, this contains the index
85
+ */
86
+ @column({ type: "json", nullable: true, decoder: CartReservedSeat })
87
+ seat: CartReservedSeat | null = null
88
+
89
+ /**
90
+ * In case the seat is changed, this contains the first assigned seat
91
+ */
92
+ @column({ type: "json", nullable: true, decoder: CartReservedSeat })
93
+ originalSeat: CartReservedSeat | null = null
94
+
95
+ @column({
96
+ type: "datetime", beforeSave(old?: any) {
97
+ if (old !== undefined) {
98
+ return old;
99
+ }
100
+ const date = new Date()
101
+ date.setMilliseconds(0)
102
+ return date
103
+ }
104
+ })
105
+ createdAt: Date
106
+
107
+ @column({
108
+ type: "datetime", beforeSave() {
109
+ const date = new Date()
110
+ date.setMilliseconds(0)
111
+ return date
112
+ },
113
+ skipUpdate: true
114
+ })
115
+ updatedAt: Date
116
+
117
+ @column({ type: "datetime", nullable: true })
118
+ deletedAt: Date | null = null
119
+
120
+ @column({ type: "datetime", nullable: true })
121
+ scannedAt: Date | null = null
122
+
123
+ @column({ type: "string", nullable: true })
124
+ scannedBy: string | null = null
125
+
126
+ static webshop = new ManyToOneRelation(Webshop, "webshop");
127
+ static order = new ManyToOneRelation(Order, "order");
128
+ static organization = new ManyToOneRelation(Organization, "organization");
129
+
130
+ getUrl(this: Ticket & { webshop: Webshop & { organization: Organization } }) {
131
+ return "https://"+this.webshop.getHost()+"/ticket/"+this.secret
132
+ }
133
+
134
+ get isDeleted() {
135
+ return this.deletedAt !== null;
136
+ }
137
+
138
+ async softDelete() {
139
+ if (this.isDeleted) {
140
+ return;
141
+ }
142
+ this.deletedAt = new Date();
143
+ await this.save()
144
+ }
145
+ }
@@ -0,0 +1,69 @@
1
+ import { Database } from '@simonbackx/simple-database';
2
+
3
+ import { OrganizationFactory } from '../factories/OrganizationFactory';
4
+ import { UserFactory } from '../factories/UserFactory';
5
+ import { Organization } from './Organization';
6
+ import { Token } from "./Token";
7
+ import { User } from "./User";
8
+
9
+ describe("Model.Token", () => {
10
+ const existingToken = "ABCDEFG";
11
+ let user: User;
12
+ let organization: Organization;
13
+
14
+ beforeAll(async () => {
15
+ organization = await new OrganizationFactory({}).create();
16
+ user = await new UserFactory({ organization }).create();
17
+
18
+ await Database.insert("INSERT INTO " + Token.table + " SET ?", [
19
+ {
20
+ accessToken: existingToken,
21
+ refreshToken: "refreshtoken",
22
+
23
+ accessTokenValidUntil: "2050-08-29 14:30:15",
24
+ refreshTokenValidUntil: "2050-08-29 14:30:15",
25
+ userId: user.id,
26
+ // = "myPassword"
27
+ createdAt: "2020-03-29 14:30:15",
28
+ updatedAt: "2020-03-29 14:30:15",
29
+ },
30
+ ]);
31
+ });
32
+
33
+ test("Get token", async () => {
34
+ const token: any = await Token.getByAccessToken(existingToken);
35
+ expect(token).toBeDefined();
36
+ expect(token).toBeInstanceOf(Token);
37
+ expect(token.user.id).toEqual(user.id);
38
+ expect(token.accessToken).toEqual(existingToken);
39
+ expect(token.userId).toEqual(user.id);
40
+ });
41
+
42
+ test("Create a token", async () => {
43
+ const token = await Token.createToken(user);
44
+ expect(token).toBeDefined();
45
+ if (!token) return;
46
+ expect(token).toBeInstanceOf(Token);
47
+ expect(token.user.id).toEqual(user.id);
48
+ expect(token.accessToken).toHaveLength(256);
49
+ expect(token.refreshToken).toHaveLength(256);
50
+ expect(token.accessTokenValidUntil.getTime()).toBeGreaterThan(new Date().getTime() + (3600 * 1000) / 2 - 1);
51
+ expect(token.accessTokenValidUntil.getTime()).toBeLessThan(new Date().getTime() + 3600 * 1000 * 24 * 365);
52
+
53
+ expect(token.refreshTokenValidUntil.getTime()).toBeGreaterThan(token.accessTokenValidUntil.getTime());
54
+ expect(token.refreshTokenValidUntil.getTime()).toBeLessThan(new Date().getTime() + 3600 * 1000 * 24 * 365);
55
+
56
+ expect(token.userId).toEqual(user.id);
57
+
58
+ const search = await Token.getByAccessToken(token.accessToken);
59
+ // Make sure we do not compare the organization, since that won't be loaded now, but is loaded on user, and on token
60
+
61
+ expect(search).toMatchObject({
62
+ accessToken: token.accessToken,
63
+ refreshToken: token.refreshToken,
64
+ userId: token.userId,
65
+ accessTokenValidUntil: token.accessTokenValidUntil,
66
+ refreshTokenValidUntil: token.refreshTokenValidUntil
67
+ });
68
+ });
69
+ });
@@ -0,0 +1,269 @@
1
+ import { column, Database, ManyToOneRelation, Model } from "@simonbackx/simple-database";
2
+ import { ApiUser } from "@stamhoofd/structures";
3
+ import crypto from "crypto";
4
+
5
+ import { RateLimiter } from "../helpers/RateLimiter";
6
+ import { User } from './';
7
+
8
+ export type TokenWithUser = Token & { user: User };
9
+
10
+ async function randomBytes(size: number): Promise<Buffer> {
11
+ return new Promise((resolve, reject) => {
12
+ crypto.randomBytes(size, (err: Error | null, buf: Buffer) => {
13
+ if (err) {
14
+ reject(err);
15
+ return;
16
+ }
17
+ resolve(buf);
18
+ });
19
+ });
20
+ }
21
+
22
+ export const apiUserRateLimiter = new RateLimiter({
23
+ limits: [
24
+ {
25
+ // Block heavy bursts (5req/s for 5s)
26
+ limit: 25,
27
+ duration: 5 * 1000
28
+ },
29
+ {
30
+ // max 1req/s during 150s
31
+ limit: 150,
32
+ duration: 150 * 1000
33
+ },
34
+ {
35
+ // 1000 requests per hour
36
+ limit: 1000,
37
+ duration: 60 * 1000 * 60
38
+ },
39
+ {
40
+ // 2000 requests per day
41
+ limit: 2000,
42
+ duration: 24 * 60 * 1000 * 60
43
+ }
44
+ ]
45
+ });
46
+
47
+ export class Token extends Model {
48
+ static table = "tokens";
49
+ static MAX_DEVICES = 15;
50
+
51
+ @column({ type: "string", foreignKey: Token.user })
52
+ userId: string;
53
+
54
+ // Columns
55
+ @column({ primary: true, type: "string" })
56
+ accessToken: string;
57
+
58
+ @column({ type: "string" })
59
+ refreshToken: string;
60
+
61
+ @column({ type: "datetime" })
62
+ accessTokenValidUntil: Date;
63
+
64
+ @column({ type: "datetime" })
65
+ refreshTokenValidUntil: Date;
66
+
67
+ @column({
68
+ type: "datetime", beforeSave(old?: any) {
69
+ if (old !== undefined) {
70
+ return old;
71
+ }
72
+ const date = new Date()
73
+ date.setMilliseconds(0)
74
+ return date
75
+ }
76
+ })
77
+ createdAt: Date
78
+
79
+ @column({
80
+ type: "datetime", beforeSave() {
81
+ const date = new Date()
82
+ date.setMilliseconds(0)
83
+ return date
84
+ },
85
+ skipUpdate: true
86
+ })
87
+ updatedAt: Date
88
+
89
+ static user = new ManyToOneRelation(User, "user");
90
+
91
+ isAccessTokenExpired(): boolean {
92
+ return this.accessTokenValidUntil < new Date() || this.refreshTokenValidUntil < new Date()
93
+ }
94
+
95
+ static async getAPIUserWithToken(user: User) {
96
+ if (!user.isApiUser) {
97
+ throw new Error('Unexpected user type')
98
+ }
99
+
100
+ const [lastToken] = await this.where({
101
+ userId: user.id
102
+ }, {limit: 1})
103
+
104
+ return ApiUser.create({
105
+ id: user.id,
106
+ organizationId: user.organizationId,
107
+ name: user.name,
108
+ permissions: user.permissions,
109
+ expiresAt: lastToken?.accessTokenValidUntil ?? null,
110
+ createdAt: user.createdAt,
111
+ })
112
+ }
113
+
114
+ /**
115
+ * Get the token and user for a given accessToken IF it is still valid
116
+ */
117
+ static async getByAccessToken(accessToken: string, ignoreExpireDate = false): Promise<TokenWithUser | undefined> {
118
+ const [rows] = await Database.select(
119
+ `SELECT ${this.getDefaultSelect()}, user.* FROM ${
120
+ this.table
121
+ } ${Token.user.joinQuery(this.table, "user")} WHERE ${this.primary.name} = ? LIMIT 1 `,
122
+ [accessToken]
123
+ );
124
+
125
+ if (rows.length == 0) {
126
+ return undefined;
127
+ }
128
+
129
+ // Read member + address from first row
130
+ const token = this.fromRow(rows[0][this.table]);
131
+
132
+ if (!token) {
133
+ return undefined;
134
+ }
135
+
136
+ if (!ignoreExpireDate && (token.accessTokenValidUntil < new Date() || token.refreshTokenValidUntil < new Date())) {
137
+ // Also if the refresh token is invalid, the access token will always be invalid
138
+ return undefined
139
+ }
140
+
141
+ const user = User.fromRow(rows[0]["user"]) || null;
142
+
143
+ if (!user) {
144
+ console.warn("Selected a token without a user!");
145
+ return undefined;
146
+ }
147
+
148
+ return token.setRelation(Token.user, user);
149
+ }
150
+
151
+ // Methods
152
+ static async getByRefreshToken(refreshToken: string): Promise<TokenWithUser | undefined> {
153
+ const [rows] = await Database.select(
154
+ `SELECT ${this.getDefaultSelect()}, ${User.getDefaultSelect("user")} FROM ${
155
+ this.table
156
+ } ${Token.user.joinQuery(this.table, "user")} WHERE \`refreshToken\` = ? LIMIT 1 `,
157
+ [refreshToken]
158
+ );
159
+
160
+ if (rows.length == 0) {
161
+ return undefined;
162
+ }
163
+
164
+ // Read member + address from first row
165
+ const token = this.fromRow(rows[0][this.table]);
166
+
167
+ if (!token) {
168
+ return undefined;
169
+ }
170
+
171
+ if (token.refreshTokenValidUntil < new Date()) {
172
+ // Refreh token invalid = can throw it away
173
+ token.delete().catch(e => {
174
+ console.error(e)
175
+ })
176
+ return undefined
177
+ }
178
+
179
+ const user = User.fromRow(rows[0]["user"]) || null;
180
+
181
+ if (!user || user.isApiUser) {
182
+ console.warn("Selected a token without a user!");
183
+ return undefined;
184
+ }
185
+
186
+ return token.setRelation(Token.user, user);
187
+ }
188
+
189
+ /**
190
+ * Create a token that is expired. This can be usefull if renewing the token is restricted by some account state.
191
+ * E.g. you cannot renew this token until the e-mail address has been verified.
192
+ * @param user
193
+ */
194
+ static async createExpiredToken<U extends User>(user: U): Promise<(Token & { user: U })> {
195
+ const token = await this.createUnsavedToken(user);
196
+
197
+ /// Expired a month ago (to prevent any timezone bugs)
198
+ token.accessTokenValidUntil = new Date(Date.now() - 24 * 60 * 60 * 1000 * 31 );
199
+ token.accessTokenValidUntil.setMilliseconds(0);
200
+
201
+ await token.save();
202
+ return token;
203
+ }
204
+
205
+ /***
206
+ * Create a token without saving it
207
+ */
208
+ static async createUnsavedToken<U extends User>(user: U): Promise<(Token & { user: U })> {
209
+ // Get all the tokens of the user that are olde
210
+
211
+ // First search if we already have more than 5 tokens (we only allow up to 5 devices)
212
+ // In case we already have a token for that deviceId, we'll delete it first.
213
+ try {
214
+ const [
215
+ rows,
216
+ ] = await Database.delete(
217
+ `DELETE FROM \`${this.table}\` WHERE ${this.primary.name} IN (SELECT ${this.primary.name} FROM (SELECT ${this.primary.name} FROM \`${this.table}\` WHERE \`userId\` = ? ORDER BY\`refreshTokenValidUntil\` DESC LIMIT ? OFFSET ?) x)`,
218
+ [user.id, this.MAX_DEVICES, this.MAX_DEVICES]
219
+ );
220
+
221
+ if (rows.affectedRows > 0) {
222
+ console.log(`Deleted ${rows.affectedRows} old tokens first`);
223
+ }
224
+ } catch (e) {
225
+ // This is not a crucial operation, so don't fail when there is a deadlock problem in the query
226
+ console.error(e)
227
+ }
228
+
229
+ const token = new Token().setRelation(Token.user, user);
230
+ token.accessTokenValidUntil = new Date();
231
+ token.accessTokenValidUntil.setTime(token.accessTokenValidUntil.getTime() + 3600 * 1000);
232
+ token.accessTokenValidUntil.setMilliseconds(0);
233
+
234
+ token.refreshTokenValidUntil = new Date();
235
+ token.refreshTokenValidUntil.setTime(token.refreshTokenValidUntil.getTime() + 3600 * 1000 * 24 * 365);
236
+ token.refreshTokenValidUntil.setMilliseconds(0);
237
+
238
+ token.accessToken = (await randomBytes(192)).toString("base64").toUpperCase();
239
+ token.refreshToken = (await randomBytes(192)).toString("base64").toUpperCase();
240
+ return token;
241
+ }
242
+
243
+ static async createToken<U extends User>(user: U): Promise<(Token & { user: U })> {
244
+ const token = await this.createUnsavedToken(user);
245
+ await token.save();
246
+ return token;
247
+ }
248
+
249
+ static async createApiToken<U extends User>(user: U): Promise<(Token & { user: U })> {
250
+ const token = await this.createUnsavedToken(user);
251
+
252
+ // 5 year valid
253
+ token.accessTokenValidUntil = new Date();
254
+ token.accessTokenValidUntil.setTime(token.accessTokenValidUntil.getTime() + 1000 * 60 * 60 * 24 * 365 * 5);
255
+ token.accessTokenValidUntil.setMilliseconds(0);
256
+
257
+ token.refreshTokenValidUntil = new Date();
258
+ token.refreshTokenValidUntil.setTime(token.accessTokenValidUntil.getTime());
259
+ token.refreshTokenValidUntil.setMilliseconds(0);
260
+
261
+ await token.save();
262
+ return token;
263
+ }
264
+
265
+ static async clearFor(userId: string, currentToken: string) {
266
+ const query = `DELETE from ${this.table} where userId = ? AND accessToken != ?`;
267
+ await Database.delete(query, [userId, currentToken])
268
+ }
269
+ }