@vandenberghinc/volt 1.1.2

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 (451) hide show
  1. package/.vrepo +28 -0
  2. package/.vscode/tasks.json +87 -0
  3. package/README.md +67 -0
  4. package/backend/dist/cjs/blacklist.d.ts +10 -0
  5. package/backend/dist/cjs/blacklist.js +53 -0
  6. package/backend/dist/cjs/cli.d.ts +2 -0
  7. package/backend/dist/cjs/cli.js +263 -0
  8. package/backend/dist/cjs/database.d.ts +364 -0
  9. package/backend/dist/cjs/database.js +1962 -0
  10. package/backend/dist/cjs/endpoint.d.ts +57 -0
  11. package/backend/dist/cjs/endpoint.js +425 -0
  12. package/backend/dist/cjs/file_watcher.d.ts +44 -0
  13. package/backend/dist/cjs/file_watcher.js +348 -0
  14. package/backend/dist/cjs/frontend.d.ts +13 -0
  15. package/backend/dist/cjs/frontend.js +30 -0
  16. package/backend/dist/cjs/image_endpoint.d.ts +24 -0
  17. package/backend/dist/cjs/image_endpoint.js +210 -0
  18. package/backend/dist/cjs/logger.d.ts +5 -0
  19. package/backend/dist/cjs/logger.js +16 -0
  20. package/backend/dist/cjs/meta.d.ts +50 -0
  21. package/backend/dist/cjs/meta.js +153 -0
  22. package/backend/dist/cjs/mutex.d.ts +24 -0
  23. package/backend/dist/cjs/mutex.js +52 -0
  24. package/backend/dist/cjs/package.json +1 -0
  25. package/backend/dist/cjs/payments/paddle.d.ts +161 -0
  26. package/backend/dist/cjs/payments/paddle.js +2301 -0
  27. package/backend/dist/cjs/plugins/browser.d.ts +36 -0
  28. package/backend/dist/cjs/plugins/browser.js +183 -0
  29. package/backend/dist/cjs/plugins/communication.d.ts +70 -0
  30. package/backend/dist/cjs/plugins/communication.js +177 -0
  31. package/backend/dist/cjs/plugins/css.d.ts +10 -0
  32. package/backend/dist/cjs/plugins/css.js +71 -0
  33. package/backend/dist/cjs/plugins/mail.d.ts +277 -0
  34. package/backend/dist/cjs/plugins/mail.js +1419 -0
  35. package/backend/dist/cjs/plugins/pdf.d.ts +757 -0
  36. package/backend/dist/cjs/plugins/pdf.js +1694 -0
  37. package/backend/dist/cjs/plugins/thread_monitor.d.ts +18 -0
  38. package/backend/dist/cjs/plugins/thread_monitor.js +127 -0
  39. package/backend/dist/cjs/plugins/ts/compiler.d.ts +132 -0
  40. package/backend/dist/cjs/plugins/ts/compiler.js +944 -0
  41. package/backend/dist/cjs/plugins/ts/preprocessing.d.ts +14 -0
  42. package/backend/dist/cjs/plugins/ts/preprocessing.js +762 -0
  43. package/backend/dist/cjs/rate_limit.d.ts +65 -0
  44. package/backend/dist/cjs/rate_limit.js +463 -0
  45. package/backend/dist/cjs/request.deprc.d.ts +48 -0
  46. package/backend/dist/cjs/request.deprc.js +572 -0
  47. package/backend/dist/cjs/response.deprc.d.ts +55 -0
  48. package/backend/dist/cjs/response.deprc.js +275 -0
  49. package/backend/dist/cjs/server.d.ts +311 -0
  50. package/backend/dist/cjs/server.js +3475 -0
  51. package/backend/dist/cjs/splash_screen.d.ts +35 -0
  52. package/backend/dist/cjs/splash_screen.js +152 -0
  53. package/backend/dist/cjs/status.d.ts +60 -0
  54. package/backend/dist/cjs/status.js +199 -0
  55. package/backend/dist/cjs/stream.d.ts +75 -0
  56. package/backend/dist/cjs/stream.js +954 -0
  57. package/backend/dist/cjs/users.d.ts +111 -0
  58. package/backend/dist/cjs/users.js +1945 -0
  59. package/backend/dist/cjs/utils.d.ts +27 -0
  60. package/backend/dist/cjs/utils.js +329 -0
  61. package/backend/dist/cjs/view.d.ts +52 -0
  62. package/backend/dist/cjs/view.js +568 -0
  63. package/backend/dist/cjs/vinc.d.ts +2 -0
  64. package/backend/dist/cjs/vinc.dev.d.ts +2 -0
  65. package/backend/dist/cjs/vinc.dev.js +42 -0
  66. package/backend/dist/cjs/vinc.js +42 -0
  67. package/backend/dist/cjs/volt.d.ts +15 -0
  68. package/backend/dist/cjs/volt.js +64 -0
  69. package/backend/dist/css/adyen.css +92 -0
  70. package/backend/dist/css/volt.css +65 -0
  71. package/backend/dist/esm/blacklist.d.ts +10 -0
  72. package/backend/dist/esm/blacklist.js +49 -0
  73. package/backend/dist/esm/cli.d.ts +2 -0
  74. package/backend/dist/esm/cli.js +228 -0
  75. package/backend/dist/esm/database.d.ts +364 -0
  76. package/backend/dist/esm/database.js +1957 -0
  77. package/backend/dist/esm/endpoint.d.ts +57 -0
  78. package/backend/dist/esm/endpoint.js +421 -0
  79. package/backend/dist/esm/file_watcher.d.ts +44 -0
  80. package/backend/dist/esm/file_watcher.js +313 -0
  81. package/backend/dist/esm/frontend.d.ts +13 -0
  82. package/backend/dist/esm/frontend.js +27 -0
  83. package/backend/dist/esm/image_endpoint.d.ts +24 -0
  84. package/backend/dist/esm/image_endpoint.js +206 -0
  85. package/backend/dist/esm/logger.d.ts +5 -0
  86. package/backend/dist/esm/logger.js +13 -0
  87. package/backend/dist/esm/meta.d.ts +50 -0
  88. package/backend/dist/esm/meta.js +149 -0
  89. package/backend/dist/esm/mutex.d.ts +24 -0
  90. package/backend/dist/esm/mutex.js +48 -0
  91. package/backend/dist/esm/payments/paddle.d.ts +161 -0
  92. package/backend/dist/esm/payments/paddle.js +2261 -0
  93. package/backend/dist/esm/plugins/browser.d.ts +36 -0
  94. package/backend/dist/esm/plugins/browser.js +176 -0
  95. package/backend/dist/esm/plugins/communication.d.ts +70 -0
  96. package/backend/dist/esm/plugins/communication.js +169 -0
  97. package/backend/dist/esm/plugins/css.d.ts +10 -0
  98. package/backend/dist/esm/plugins/css.js +64 -0
  99. package/backend/dist/esm/plugins/mail.d.ts +277 -0
  100. package/backend/dist/esm/plugins/mail.js +1403 -0
  101. package/backend/dist/esm/plugins/pdf.d.ts +757 -0
  102. package/backend/dist/esm/plugins/pdf.js +1694 -0
  103. package/backend/dist/esm/plugins/thread_monitor.d.ts +18 -0
  104. package/backend/dist/esm/plugins/thread_monitor.js +120 -0
  105. package/backend/dist/esm/plugins/ts/compiler.d.ts +132 -0
  106. package/backend/dist/esm/plugins/ts/compiler.js +907 -0
  107. package/backend/dist/esm/plugins/ts/preprocessing.d.ts +14 -0
  108. package/backend/dist/esm/plugins/ts/preprocessing.js +724 -0
  109. package/backend/dist/esm/rate_limit.d.ts +65 -0
  110. package/backend/dist/esm/rate_limit.js +425 -0
  111. package/backend/dist/esm/request.deprc.d.ts +48 -0
  112. package/backend/dist/esm/request.deprc.js +572 -0
  113. package/backend/dist/esm/response.deprc.d.ts +55 -0
  114. package/backend/dist/esm/response.deprc.js +275 -0
  115. package/backend/dist/esm/server.d.ts +311 -0
  116. package/backend/dist/esm/server.js +3435 -0
  117. package/backend/dist/esm/splash_screen.d.ts +35 -0
  118. package/backend/dist/esm/splash_screen.js +148 -0
  119. package/backend/dist/esm/status.d.ts +60 -0
  120. package/backend/dist/esm/status.js +196 -0
  121. package/backend/dist/esm/stream.d.ts +75 -0
  122. package/backend/dist/esm/stream.js +947 -0
  123. package/backend/dist/esm/users.d.ts +111 -0
  124. package/backend/dist/esm/users.js +1908 -0
  125. package/backend/dist/esm/utils.d.ts +27 -0
  126. package/backend/dist/esm/utils.js +324 -0
  127. package/backend/dist/esm/view.d.ts +52 -0
  128. package/backend/dist/esm/view.js +561 -0
  129. package/backend/dist/esm/vinc.d.ts +2 -0
  130. package/backend/dist/esm/vinc.dev.d.ts +2 -0
  131. package/backend/dist/esm/vinc.dev.js +6 -0
  132. package/backend/dist/esm/vinc.js +6 -0
  133. package/backend/dist/esm/volt.d.ts +15 -0
  134. package/backend/dist/esm/volt.js +23 -0
  135. package/backend/dist/esm-dev/blacklist.d.ts +10 -0
  136. package/backend/dist/esm-dev/blacklist.js +49 -0
  137. package/backend/dist/esm-dev/cli.d.ts +2 -0
  138. package/backend/dist/esm-dev/cli.js +228 -0
  139. package/backend/dist/esm-dev/database.d.ts +364 -0
  140. package/backend/dist/esm-dev/database.js +1957 -0
  141. package/backend/dist/esm-dev/endpoint.d.ts +57 -0
  142. package/backend/dist/esm-dev/endpoint.js +421 -0
  143. package/backend/dist/esm-dev/file_watcher.d.ts +44 -0
  144. package/backend/dist/esm-dev/file_watcher.js +313 -0
  145. package/backend/dist/esm-dev/frontend.d.ts +13 -0
  146. package/backend/dist/esm-dev/frontend.js +27 -0
  147. package/backend/dist/esm-dev/image_endpoint.d.ts +24 -0
  148. package/backend/dist/esm-dev/image_endpoint.js +206 -0
  149. package/backend/dist/esm-dev/logger.d.ts +5 -0
  150. package/backend/dist/esm-dev/logger.js +13 -0
  151. package/backend/dist/esm-dev/meta.d.ts +50 -0
  152. package/backend/dist/esm-dev/meta.js +149 -0
  153. package/backend/dist/esm-dev/mutex.d.ts +24 -0
  154. package/backend/dist/esm-dev/mutex.js +48 -0
  155. package/backend/dist/esm-dev/payments/paddle.d.ts +161 -0
  156. package/backend/dist/esm-dev/payments/paddle.js +2261 -0
  157. package/backend/dist/esm-dev/plugins/browser.d.ts +36 -0
  158. package/backend/dist/esm-dev/plugins/browser.js +176 -0
  159. package/backend/dist/esm-dev/plugins/communication.d.ts +70 -0
  160. package/backend/dist/esm-dev/plugins/communication.js +169 -0
  161. package/backend/dist/esm-dev/plugins/css.d.ts +10 -0
  162. package/backend/dist/esm-dev/plugins/css.js +64 -0
  163. package/backend/dist/esm-dev/plugins/mail.d.ts +277 -0
  164. package/backend/dist/esm-dev/plugins/mail.js +1403 -0
  165. package/backend/dist/esm-dev/plugins/pdf.d.ts +757 -0
  166. package/backend/dist/esm-dev/plugins/pdf.js +1694 -0
  167. package/backend/dist/esm-dev/plugins/thread_monitor.d.ts +18 -0
  168. package/backend/dist/esm-dev/plugins/thread_monitor.js +120 -0
  169. package/backend/dist/esm-dev/plugins/ts/compiler.d.ts +132 -0
  170. package/backend/dist/esm-dev/plugins/ts/compiler.js +907 -0
  171. package/backend/dist/esm-dev/plugins/ts/preprocessing.d.ts +14 -0
  172. package/backend/dist/esm-dev/plugins/ts/preprocessing.js +724 -0
  173. package/backend/dist/esm-dev/rate_limit.d.ts +65 -0
  174. package/backend/dist/esm-dev/rate_limit.js +425 -0
  175. package/backend/dist/esm-dev/request.deprc.d.ts +48 -0
  176. package/backend/dist/esm-dev/request.deprc.js +572 -0
  177. package/backend/dist/esm-dev/response.deprc.d.ts +55 -0
  178. package/backend/dist/esm-dev/response.deprc.js +275 -0
  179. package/backend/dist/esm-dev/server.d.ts +311 -0
  180. package/backend/dist/esm-dev/server.js +3435 -0
  181. package/backend/dist/esm-dev/splash_screen.d.ts +35 -0
  182. package/backend/dist/esm-dev/splash_screen.js +148 -0
  183. package/backend/dist/esm-dev/status.d.ts +60 -0
  184. package/backend/dist/esm-dev/status.js +196 -0
  185. package/backend/dist/esm-dev/stream.d.ts +75 -0
  186. package/backend/dist/esm-dev/stream.js +947 -0
  187. package/backend/dist/esm-dev/users.d.ts +111 -0
  188. package/backend/dist/esm-dev/users.js +1908 -0
  189. package/backend/dist/esm-dev/utils.d.ts +27 -0
  190. package/backend/dist/esm-dev/utils.js +324 -0
  191. package/backend/dist/esm-dev/view.d.ts +52 -0
  192. package/backend/dist/esm-dev/view.js +561 -0
  193. package/backend/dist/esm-dev/vinc.d.ts +2 -0
  194. package/backend/dist/esm-dev/vinc.dev.d.ts +2 -0
  195. package/backend/dist/esm-dev/vinc.dev.js +6 -0
  196. package/backend/dist/esm-dev/vinc.js +6 -0
  197. package/backend/dist/esm-dev/volt.d.ts +15 -0
  198. package/backend/dist/esm-dev/volt.js +23 -0
  199. package/backend/src/blacklist.ts +69 -0
  200. package/backend/src/cli.js +245 -0
  201. package/backend/src/database.ts +2241 -0
  202. package/backend/src/endpoint.ts +494 -0
  203. package/backend/src/file_watcher.ts +359 -0
  204. package/backend/src/frontend.ts +35 -0
  205. package/backend/src/globals.d.ts +8 -0
  206. package/backend/src/image_endpoint.ts +258 -0
  207. package/backend/src/logger.ts +18 -0
  208. package/backend/src/meta.ts +202 -0
  209. package/backend/src/mutex.ts +51 -0
  210. package/backend/src/payments/paddle.ts +2659 -0
  211. package/backend/src/plugins/browser.ts +188 -0
  212. package/backend/src/plugins/communication.ts +204 -0
  213. package/backend/src/plugins/css.ts +84 -0
  214. package/backend/src/plugins/fonts/Menlo-Bold.ttf +0 -0
  215. package/backend/src/plugins/fonts/Menlo-Regular.ttf +0 -0
  216. package/backend/src/plugins/mail.ts +1720 -0
  217. package/backend/src/plugins/pdf.js +1932 -0
  218. package/backend/src/plugins/thread_monitor.ts +164 -0
  219. package/backend/src/plugins/ts/compiler.ts +1242 -0
  220. package/backend/src/plugins/ts/preprocessing.ts +812 -0
  221. package/backend/src/rate_limit.ts +503 -0
  222. package/backend/src/request.deprc.js +626 -0
  223. package/backend/src/response.deprc.js +354 -0
  224. package/backend/src/server.ts +4149 -0
  225. package/backend/src/splash_screen.ts +192 -0
  226. package/backend/src/status.ts +199 -0
  227. package/backend/src/stream.ts +1070 -0
  228. package/backend/src/users.ts +2077 -0
  229. package/backend/src/utils.ts +359 -0
  230. package/backend/src/view.ts +655 -0
  231. package/backend/src/vinc.dev.js +6 -0
  232. package/backend/src/vinc.ts +6 -0
  233. package/backend/src/volt.js +25 -0
  234. package/backend/tsconfig.cjs.json +29 -0
  235. package/backend/tsconfig.esm.dev.json +34 -0
  236. package/backend/tsconfig.esm.json +30 -0
  237. package/backend/tsconfig.json +2 -0
  238. package/frontend/compile.js +436 -0
  239. package/frontend/dist/elements/base.d.ts +9891 -0
  240. package/frontend/dist/elements/base.js +8818 -0
  241. package/frontend/dist/elements/module.d.ts +16 -0
  242. package/frontend/dist/elements/module.js +178 -0
  243. package/frontend/dist/modules/array.d.ts +37 -0
  244. package/frontend/dist/modules/array.js +284 -0
  245. package/frontend/dist/modules/auth.d.ts +45 -0
  246. package/frontend/dist/modules/auth.js +138 -0
  247. package/frontend/dist/modules/colors.d.ts +26 -0
  248. package/frontend/dist/modules/colors.js +340 -0
  249. package/frontend/dist/modules/compression.d.ts +6 -0
  250. package/frontend/dist/modules/compression.js +999 -0
  251. package/frontend/dist/modules/cookies.d.ts +17 -0
  252. package/frontend/dist/modules/cookies.js +166 -0
  253. package/frontend/dist/modules/date.d.ts +142 -0
  254. package/frontend/dist/modules/date.js +493 -0
  255. package/frontend/dist/modules/events.d.ts +7 -0
  256. package/frontend/dist/modules/events.js +90 -0
  257. package/frontend/dist/modules/google.d.ts +10 -0
  258. package/frontend/dist/modules/google.js +53 -0
  259. package/frontend/dist/modules/meta.d.ts +9 -0
  260. package/frontend/dist/modules/meta.js +45 -0
  261. package/frontend/dist/modules/mutex.d.ts +8 -0
  262. package/frontend/dist/modules/mutex.js +52 -0
  263. package/frontend/dist/modules/number.d.ts +12 -0
  264. package/frontend/dist/modules/number.js +8 -0
  265. package/frontend/dist/modules/object.d.ts +50 -0
  266. package/frontend/dist/modules/object.js +147 -0
  267. package/frontend/dist/modules/paddle.d.ts +1403 -0
  268. package/frontend/dist/modules/paddle.js +2641 -0
  269. package/frontend/dist/modules/scheme.d.ts +207 -0
  270. package/frontend/dist/modules/scheme.js +649 -0
  271. package/frontend/dist/modules/settings.d.ts +3 -0
  272. package/frontend/dist/modules/settings.js +4 -0
  273. package/frontend/dist/modules/statics.d.ts +4 -0
  274. package/frontend/dist/modules/statics.js +45 -0
  275. package/frontend/dist/modules/string.d.ts +163 -0
  276. package/frontend/dist/modules/string.js +291 -0
  277. package/frontend/dist/modules/support.d.ts +18 -0
  278. package/frontend/dist/modules/support.js +102 -0
  279. package/frontend/dist/modules/themes.d.ts +8 -0
  280. package/frontend/dist/modules/themes.js +17 -0
  281. package/frontend/dist/modules/user.d.ts +58 -0
  282. package/frontend/dist/modules/user.js +279 -0
  283. package/frontend/dist/modules/utils.d.ts +58 -0
  284. package/frontend/dist/modules/utils.js +1159 -0
  285. package/frontend/dist/types/gradient.d.ts +12 -0
  286. package/frontend/dist/types/gradient.js +79 -0
  287. package/frontend/dist/ui/border_button.d.ts +177 -0
  288. package/frontend/dist/ui/border_button.js +235 -0
  289. package/frontend/dist/ui/button.d.ts +42 -0
  290. package/frontend/dist/ui/button.js +114 -0
  291. package/frontend/dist/ui/canvas.d.ts +56 -0
  292. package/frontend/dist/ui/canvas.js +411 -0
  293. package/frontend/dist/ui/checkbox.d.ts +72 -0
  294. package/frontend/dist/ui/checkbox.js +277 -0
  295. package/frontend/dist/ui/code.d.ts +232 -0
  296. package/frontend/dist/ui/code.js +977 -0
  297. package/frontend/dist/ui/color.d.ts +1 -0
  298. package/frontend/dist/ui/color.js +110 -0
  299. package/frontend/dist/ui/context_menu.d.ts +30 -0
  300. package/frontend/dist/ui/context_menu.js +211 -0
  301. package/frontend/dist/ui/css.d.ts +10 -0
  302. package/frontend/dist/ui/css.js +44 -0
  303. package/frontend/dist/ui/divider.d.ts +18 -0
  304. package/frontend/dist/ui/divider.js +82 -0
  305. package/frontend/dist/ui/dropdown.d.ts +115 -0
  306. package/frontend/dist/ui/dropdown.js +446 -0
  307. package/frontend/dist/ui/for_each.d.ts +38 -0
  308. package/frontend/dist/ui/for_each.js +97 -0
  309. package/frontend/dist/ui/form.d.ts +25 -0
  310. package/frontend/dist/ui/form.js +227 -0
  311. package/frontend/dist/ui/frame_modes.d.ts +28 -0
  312. package/frontend/dist/ui/frame_modes.js +116 -0
  313. package/frontend/dist/ui/google_map.d.ts +31 -0
  314. package/frontend/dist/ui/google_map.js +111 -0
  315. package/frontend/dist/ui/gradient.d.ts +24 -0
  316. package/frontend/dist/ui/gradient.js +115 -0
  317. package/frontend/dist/ui/image.d.ts +138 -0
  318. package/frontend/dist/ui/image.js +570 -0
  319. package/frontend/dist/ui/input.d.ts +316 -0
  320. package/frontend/dist/ui/input.js +1187 -0
  321. package/frontend/dist/ui/link.d.ts +39 -0
  322. package/frontend/dist/ui/link.js +146 -0
  323. package/frontend/dist/ui/list.d.ts +33 -0
  324. package/frontend/dist/ui/list.js +161 -0
  325. package/frontend/dist/ui/loader_button.d.ts +108 -0
  326. package/frontend/dist/ui/loader_button.js +207 -0
  327. package/frontend/dist/ui/loaders.d.ts +60 -0
  328. package/frontend/dist/ui/loaders.js +150 -0
  329. package/frontend/dist/ui/popup.d.ts +84 -0
  330. package/frontend/dist/ui/popup.js +331 -0
  331. package/frontend/dist/ui/pseudo.d.ts +16 -0
  332. package/frontend/dist/ui/pseudo.js +81 -0
  333. package/frontend/dist/ui/scroller.d.ts +131 -0
  334. package/frontend/dist/ui/scroller.js +1251 -0
  335. package/frontend/dist/ui/slider.d.ts +35 -0
  336. package/frontend/dist/ui/slider.js +203 -0
  337. package/frontend/dist/ui/spacer.d.ts +20 -0
  338. package/frontend/dist/ui/spacer.js +83 -0
  339. package/frontend/dist/ui/span.d.ts +11 -0
  340. package/frontend/dist/ui/span.js +75 -0
  341. package/frontend/dist/ui/stack.d.ts +123 -0
  342. package/frontend/dist/ui/stack.js +344 -0
  343. package/frontend/dist/ui/steps.d.ts +72 -0
  344. package/frontend/dist/ui/steps.js +306 -0
  345. package/frontend/dist/ui/style.d.ts +12 -0
  346. package/frontend/dist/ui/style.js +78 -0
  347. package/frontend/dist/ui/switch.d.ts +44 -0
  348. package/frontend/dist/ui/switch.js +280 -0
  349. package/frontend/dist/ui/table.d.ts +118 -0
  350. package/frontend/dist/ui/table.js +411 -0
  351. package/frontend/dist/ui/tabs.d.ts +85 -0
  352. package/frontend/dist/ui/tabs.js +392 -0
  353. package/frontend/dist/ui/text.d.ts +19 -0
  354. package/frontend/dist/ui/text.js +88 -0
  355. package/frontend/dist/ui/theme.d.ts +25 -0
  356. package/frontend/dist/ui/theme.js +237 -0
  357. package/frontend/dist/ui/title.d.ts +36 -0
  358. package/frontend/dist/ui/title.js +127 -0
  359. package/frontend/dist/ui/ui.d.ts +38 -0
  360. package/frontend/dist/ui/ui.js +41 -0
  361. package/frontend/dist/ui/view.d.ts +25 -0
  362. package/frontend/dist/ui/view.js +93 -0
  363. package/frontend/dist/volt.d.ts +22 -0
  364. package/frontend/dist/volt.js +27 -0
  365. package/frontend/exports.json +1340 -0
  366. package/frontend/src/css/adyen.css +92 -0
  367. package/frontend/src/css/volt.css +65 -0
  368. package/frontend/src/elements/base.ts +16790 -0
  369. package/frontend/src/elements/module.ts +184 -0
  370. package/frontend/src/elements/types.d.ts +155 -0
  371. package/frontend/src/modules/array.ts +366 -0
  372. package/frontend/src/modules/auth.ts +188 -0
  373. package/frontend/src/modules/colors.ts +449 -0
  374. package/frontend/src/modules/compression.ts +67 -0
  375. package/frontend/src/modules/cookies.ts +182 -0
  376. package/frontend/src/modules/date.js +535 -0
  377. package/frontend/src/modules/date.ts +583 -0
  378. package/frontend/src/modules/events.ts +96 -0
  379. package/frontend/src/modules/google.ts +60 -0
  380. package/frontend/src/modules/meta.ts +59 -0
  381. package/frontend/src/modules/mutex.ts +59 -0
  382. package/frontend/src/modules/number.ts +20 -0
  383. package/frontend/src/modules/object.ts +212 -0
  384. package/frontend/src/modules/paddle.ts +2990 -0
  385. package/frontend/src/modules/scheme.ts +740 -0
  386. package/frontend/src/modules/settings.ts +5 -0
  387. package/frontend/src/modules/statics.ts +47 -0
  388. package/frontend/src/modules/string.ts +500 -0
  389. package/frontend/src/modules/support.ts +118 -0
  390. package/frontend/src/modules/themes.ts +24 -0
  391. package/frontend/src/modules/user.ts +321 -0
  392. package/frontend/src/modules/utils.ts +1260 -0
  393. package/frontend/src/static/admin/admin.png +0 -0
  394. package/frontend/src/static/admin/password.webp +0 -0
  395. package/frontend/src/static/icons/copy.webp +0 -0
  396. package/frontend/src/static/payments/arrow.long.webp +0 -0
  397. package/frontend/src/static/payments/arrow.long2.webp +0 -0
  398. package/frontend/src/static/payments/cancelled.webp +0 -0
  399. package/frontend/src/static/payments/check.sign.webp +0 -0
  400. package/frontend/src/static/payments/check.webp +0 -0
  401. package/frontend/src/static/payments/close.webp +0 -0
  402. package/frontend/src/static/payments/error.webp +0 -0
  403. package/frontend/src/static/payments/exclamation.webp +0 -0
  404. package/frontend/src/static/payments/minus.webp +0 -0
  405. package/frontend/src/static/payments/party.webp +0 -0
  406. package/frontend/src/static/payments/plus.webp +0 -0
  407. package/frontend/src/static/payments/shopping_cart.webp +0 -0
  408. package/frontend/src/static/payments/trash.webp +0 -0
  409. package/frontend/src/types/global.d.ts +4 -0
  410. package/frontend/src/types/gradient.ts +87 -0
  411. package/frontend/src/ui/any_element.d.ts +5 -0
  412. package/frontend/src/ui/border_button.ts +320 -0
  413. package/frontend/src/ui/button.ts +62 -0
  414. package/frontend/src/ui/canvas.ts +431 -0
  415. package/frontend/src/ui/checkbox.ts +284 -0
  416. package/frontend/src/ui/code.ts +1049 -0
  417. package/frontend/src/ui/color.ts +117 -0
  418. package/frontend/src/ui/context_menu.ts +194 -0
  419. package/frontend/src/ui/css.ts +57 -0
  420. package/frontend/src/ui/divider.ts +28 -0
  421. package/frontend/src/ui/dropdown.ts +503 -0
  422. package/frontend/src/ui/for_each.ts +71 -0
  423. package/frontend/src/ui/form.ts +208 -0
  424. package/frontend/src/ui/frame_modes.ts +140 -0
  425. package/frontend/src/ui/google_map.ts +70 -0
  426. package/frontend/src/ui/gradient.ts +73 -0
  427. package/frontend/src/ui/image.ts +587 -0
  428. package/frontend/src/ui/input.ts +1284 -0
  429. package/frontend/src/ui/link.ts +77 -0
  430. package/frontend/src/ui/list.ts +88 -0
  431. package/frontend/src/ui/loader_button.ts +192 -0
  432. package/frontend/src/ui/loaders.ts +126 -0
  433. package/frontend/src/ui/popup.ts +370 -0
  434. package/frontend/src/ui/pseudo.ts +33 -0
  435. package/frontend/src/ui/scroller.ts +1324 -0
  436. package/frontend/src/ui/slider.ts +215 -0
  437. package/frontend/src/ui/spacer.ts +29 -0
  438. package/frontend/src/ui/span.ts +23 -0
  439. package/frontend/src/ui/stack.ts +238 -0
  440. package/frontend/src/ui/steps.ts +334 -0
  441. package/frontend/src/ui/style.ts +26 -0
  442. package/frontend/src/ui/switch.ts +286 -0
  443. package/frontend/src/ui/table.ts +323 -0
  444. package/frontend/src/ui/tabs.ts +441 -0
  445. package/frontend/src/ui/text.ts +38 -0
  446. package/frontend/src/ui/theme.ts +279 -0
  447. package/frontend/src/ui/title.ts +64 -0
  448. package/frontend/src/ui/ui.ts +47 -0
  449. package/frontend/src/ui/view.ts +44 -0
  450. package/frontend/src/volt.ts +31 -0
  451. package/package.json +58 -0
@@ -0,0 +1,1945 @@
1
+ "use strict";
2
+ /*
3
+ * Author: Daan van den Bergh
4
+ * Copyright: © 2022 - 2024 Daan van den Bergh.
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.Users = void 0;
41
+ // ---------------------------------------------------------
42
+ // Imports.
43
+ const _vinc_1 = require("./vinc.js");
44
+ const utils = __importStar(require("./utils.js"));
45
+ const Mail = __importStar(require("./plugins/mail.js"));
46
+ const status_js_1 = require("./status.js");
47
+ const { FrontendError } = utils;
48
+ const logger_js_1 = require("./logger.js");
49
+ const log_source = logger_js_1.logger.LogSource("Users");
50
+ // interface Server {
51
+ // db: { create_uid_collection: (name: string) => UsersDB };
52
+ // on_delete_user: ({ uid }: { uid: string }) => void | Promise<void>;
53
+ // send_mail: ({ recipients, subject, body, attachments }: { recipients: string[]; subject: string; body: string; attachments?: any[] }) => Promise<void>;
54
+ // token_expiration: number;
55
+ // https?: boolean;
56
+ // _hmac: (value: string) => string;
57
+ // enable_2fa: boolean;
58
+ // on_2fa_mail?: (params: { code: string; username: string; email: string; date: string; ip: string; device: string }) => string | Mail.MailElement;
59
+ // enable_account_activation: boolean;
60
+ // }
61
+ // ---------------------------------------------------------
62
+ // The server object.
63
+ /* @docs:
64
+ @nav: Backend
65
+ @chapter: Server
66
+ @title: Users
67
+ @desc:
68
+ The users class, accessible under `Server.users`.
69
+ @param:
70
+ @name: _server
71
+ @ignore: true
72
+ */
73
+ class Users {
74
+ server;
75
+ avg_send_2fa_time = [];
76
+ _tokens_db;
77
+ _users_db;
78
+ public;
79
+ protected;
80
+ private;
81
+ constructor(_server) {
82
+ this.server = _server;
83
+ }
84
+ // ---------------------------------------------------------
85
+ // Utils.
86
+ // Generate a code.
87
+ _generate_code(length = 6) {
88
+ const charset = "0123456789";
89
+ let key = "";
90
+ for (let i = 0; i < length; i++) {
91
+ key += charset.charAt(Math.floor(Math.random() * charset.length));
92
+ }
93
+ return key;
94
+ }
95
+ // Generate a str.
96
+ _generate_str(length = 32) {
97
+ const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
98
+ let key = "";
99
+ for (let i = 0; i < length; i++) {
100
+ key += charset.charAt(Math.floor(Math.random() * charset.length));
101
+ }
102
+ return key;
103
+ }
104
+ // Create a new uid.
105
+ async _generate_uid() {
106
+ while (true) {
107
+ const uid = this._generate_str(16);
108
+ if ((await this.uid_exists(uid)) === false) {
109
+ return uid;
110
+ }
111
+ }
112
+ }
113
+ // Generate an api key.
114
+ _generate_api_key(uid) {
115
+ return `0${uid}:${this._generate_str(64)}`;
116
+ }
117
+ // Generate a token.
118
+ _generate_token(uid) {
119
+ return `1${uid}:${this._generate_str(64)}`;
120
+ }
121
+ // Check a password and the verify password.
122
+ _verify_new_pass(pass, verify_pass) {
123
+ let error = null;
124
+ if (pass !== verify_pass) {
125
+ error = "Passwords do not match.";
126
+ return { error, invalid_fields: { password: error, verify_password: error } };
127
+ }
128
+ else if (pass.length < 8) {
129
+ error = "The password should at least include eight characters.";
130
+ return { error, invalid_fields: { password: error, verify_password: error } };
131
+ }
132
+ else if (pass.toLowerCase() === pass) {
133
+ error = "The password should at least include one capital letter.";
134
+ return { error, invalid_fields: { password: error, verify_password: error } };
135
+ }
136
+ else if (!/\d|[!@#$%^&*]/.test(pass)) {
137
+ error = "The password should at least include one numeric or special character.";
138
+ return { error, invalid_fields: { password: error, verify_password: error } };
139
+ }
140
+ return { error: null, invalid_fields: null };
141
+ }
142
+ // ---------------------------------------------------------
143
+ // Authentication (private).
144
+ // Generate a token by uid.
145
+ async _create_token(uid) {
146
+ const token = this._generate_token(uid);
147
+ await this._tokens_db.save(uid, "token", {
148
+ expiration: Date.now() + this.server.token_expiration * 1000,
149
+ token: this.server._hmac(token),
150
+ active: true,
151
+ });
152
+ return token;
153
+ }
154
+ // Deactivate a token by uid.
155
+ async _deactivate_token(uid) {
156
+ await this._tokens_db.save(uid, "token", { active: false });
157
+ }
158
+ // Create a 2FA token.
159
+ async _create_2fa_token(uid_or_email, expiration) {
160
+ const code = this._generate_code(6);
161
+ await this._tokens_db.save(uid_or_email, "2fa", {
162
+ expiration: Date.now() + expiration * 1000,
163
+ code: code,
164
+ active: true,
165
+ });
166
+ return code;
167
+ }
168
+ // Deactivate a 2FA token.
169
+ async _deactivate_2fa_token(uid_or_email) {
170
+ await this._tokens_db.save(uid_or_email, "2fa", { active: false });
171
+ }
172
+ // Perform authentication on a request.
173
+ async _authenticate(stream) {
174
+ const authorization = stream.headers["authorization"];
175
+ if (authorization !== undefined) {
176
+ if (typeof authorization !== "string") {
177
+ return {
178
+ status: status_js_1.Status.bad_request,
179
+ data: "Invalid authorization header.",
180
+ };
181
+ }
182
+ if (!authorization.startsWith("Bearer ")) {
183
+ return {
184
+ status: status_js_1.Status.bad_request,
185
+ data: "Invalid authorization scheme, the authorization scheme must be \"Bearer\".",
186
+ };
187
+ }
188
+ let api_key = "";
189
+ for (let i = 7; i < authorization.length; i++) {
190
+ const c = authorization[i];
191
+ if (c == " ") {
192
+ continue;
193
+ }
194
+ api_key += c;
195
+ }
196
+ let uid;
197
+ try {
198
+ uid = await this.get_uid_by_api_key(api_key);
199
+ }
200
+ catch (e) {
201
+ return {
202
+ status: status_js_1.Status.unauthorized,
203
+ data: "Unauthorized.",
204
+ };
205
+ }
206
+ if ((await this.verify_api_key_by_uid(uid, api_key)) !== true) {
207
+ return {
208
+ status: status_js_1.Status.unauthorized,
209
+ data: "Unauthorized.",
210
+ };
211
+ }
212
+ stream.uid = uid;
213
+ return null;
214
+ }
215
+ else {
216
+ if (stream.cookies.T == null || stream.cookies.T.value == null) {
217
+ return {
218
+ status: 302,
219
+ headers: { Location: `/signin?next=${stream.endpoint}` },
220
+ data: "Permission denied.",
221
+ };
222
+ }
223
+ const token = stream.cookies.T.value;
224
+ let uid;
225
+ try {
226
+ uid = await this.get_uid_by_api_key(token);
227
+ }
228
+ catch (e) {
229
+ return {
230
+ status: 302,
231
+ headers: { Location: `/signin?next=${stream.endpoint}` },
232
+ data: "Permission denied.",
233
+ };
234
+ }
235
+ if ((await this.verify_token_by_uid(uid, token)) !== true) {
236
+ return {
237
+ status: 302,
238
+ headers: { Location: `/signin?next=${stream.endpoint}` },
239
+ data: "Permission denied.",
240
+ };
241
+ }
242
+ stream.uid = uid;
243
+ return null;
244
+ }
245
+ }
246
+ // Sign a user in and return a response.
247
+ async _sign_in_response(stream, uid) {
248
+ // Generate token.
249
+ const token = await this._create_token(uid);
250
+ // Create headers.
251
+ this._create_token_cookie(stream, token);
252
+ await this._create_user_cookie(stream, uid);
253
+ await this._create_detailed_user_cookie(stream, uid);
254
+ // Response.
255
+ stream.send({
256
+ status: 200,
257
+ data: { message: "Successfully signed in." },
258
+ });
259
+ }
260
+ // ---------------------------------------------------------
261
+ // Cookies (private).
262
+ // Create token headers.
263
+ _create_token_cookie(stream, token) {
264
+ stream.set_header("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate, proxy-revalidate");
265
+ stream.set_header("Access-Control-Allow-Credentials", "true");
266
+ const expires = new Date(new Date().getTime() + this.server.token_expiration * 1000);
267
+ if (typeof token === "object") {
268
+ token = token.token;
269
+ }
270
+ stream.set_cookie(`T=${token}; Max-Age=86400; Path=/; Expires=${expires.toUTCString()}; SameSite=None; ${this.server.https === undefined ? "" : "Secure"}; HttpOnly;`);
271
+ }
272
+ // Create user headers.
273
+ async _create_user_cookie(stream, uid) {
274
+ const secure = this.server.https === undefined ? "" : "Secure";
275
+ if (typeof uid === "string") {
276
+ stream.set_cookie(`UserID=${uid}; Path=/; SameSite=None; ${secure};`);
277
+ const is_activated = this.server.enable_account_activation ? await this.is_activated(uid) : true;
278
+ stream.set_cookie(`UserActivated=${is_activated}; Path=/; SameSite=None; ${secure};`);
279
+ }
280
+ else {
281
+ stream.set_cookie(`UserID=-1; Path=/; SameSite=None; ${secure};`);
282
+ const is_activated = this.server.enable_account_activation ? false : true;
283
+ stream.set_cookie(`UserActivated=${is_activated}; Path=/; SameSite=None; ${secure};`);
284
+ }
285
+ }
286
+ // Create detailed user headers.
287
+ async _create_detailed_user_cookie(stream, uid) {
288
+ const secure = this.server.https === undefined ? "" : "Secure";
289
+ const user = await this.get(uid);
290
+ stream.set_cookie(`UserName=${user.username}; Path=/; SameSite=None; ${secure};`);
291
+ stream.set_cookie(`UserFirstName=${user.first_name}; Path=/; SameSite=None; ${secure};`);
292
+ stream.set_cookie(`UserLastName=${user.last_name}; Path=/; SameSite=None; ${secure};`);
293
+ stream.set_cookie(`UserEmail=${user.email}; Path=/; SameSite=None; ${secure};`);
294
+ }
295
+ // Reset all default cookies.
296
+ _reset_cookies(stream) {
297
+ const secure = this.server.https === undefined ? "" : "Secure";
298
+ stream.set_cookie(`T=; Path=/; SameSite=None; ${secure}; HttpOnly;`);
299
+ stream.set_cookie(`UserID=-1; Path=/; SameSite=None; ${secure};`);
300
+ stream.set_cookie(`UserActivated=false; Path=/; SameSite=None; ${secure};`);
301
+ stream.set_cookie(`UserName=; Path=/; SameSite=None; ${secure};`);
302
+ stream.set_cookie(`UserFirstName=; Path=/; SameSite=None; ${secure};`);
303
+ stream.set_cookie(`UserLastName=; Path=/; SameSite=None; ${secure};`);
304
+ stream.set_cookie(`UserEmail=; Path=/; SameSite=None; ${secure};`);
305
+ }
306
+ // ---------------------------------------------------------
307
+ // Initialization (private).
308
+ // Initialize.
309
+ _initialize() {
310
+ // Database collections.
311
+ this._tokens_db = this.server.db.create_uid_collection("_tokens");
312
+ this._users_db = this.server.db.create_uid_collection("_users");
313
+ // Public database collections.
314
+ this.public = this.server.db.create_uid_collection("_users_public");
315
+ this.protected = this.server.db.create_uid_collection("_users_protected");
316
+ this.private = this.server.db.create_uid_collection("_users_private");
317
+ // ---------------------------------------------------------
318
+ // Default auth endpoints.
319
+ this.server.endpoint(
320
+ // Send 2fa.
321
+ {
322
+ method: "GET",
323
+ endpoint: "/volt/auth/2fa",
324
+ content_type: "application/json",
325
+ rate_limit: "global",
326
+ params: {
327
+ email: "string",
328
+ },
329
+ callback: async (stream, params) => {
330
+ // Get uid.
331
+ let uid;
332
+ if ((uid = await this.get_uid_by_email(params.email)) == null) {
333
+ return stream.success({
334
+ data: { message: "A 2FA code was sent if the specified email exists." },
335
+ });
336
+ }
337
+ // Send.
338
+ await this.send_2fa({ uid: uid, stream });
339
+ return stream.success({
340
+ data: { message: "A 2FA code was sent if the specified email exists." },
341
+ });
342
+ }
343
+ },
344
+ // Sign in.
345
+ {
346
+ method: "POST",
347
+ endpoint: "/volt/auth/signin",
348
+ content_type: "application/json",
349
+ rate_limit: {
350
+ limit: 10,
351
+ interval: 60,
352
+ group: "volt.auth"
353
+ },
354
+ callback: async (stream) => {
355
+ // Get params.
356
+ let email, email_err, username, username_err, password, uid, code;
357
+ try {
358
+ email = stream.param("email");
359
+ }
360
+ catch (err) {
361
+ email_err = err;
362
+ }
363
+ try {
364
+ username = stream.param("username");
365
+ }
366
+ catch (err) {
367
+ username_err = err;
368
+ }
369
+ if (email_err && username_err) {
370
+ return stream.error({ status: status_js_1.Status.bad_request, data: { error: email_err.message } });
371
+ }
372
+ try {
373
+ password = stream.param("password");
374
+ }
375
+ catch (err) {
376
+ return stream.error({ status: status_js_1.Status.bad_request, data: { error: err.message } });
377
+ }
378
+ // Get uid.
379
+ if (email) {
380
+ if ((uid = await this.get_uid_by_email(email)) == null) {
381
+ return stream.error({
382
+ status: status_js_1.Status.unauthorized,
383
+ data: {
384
+ error: "Unauthorized.",
385
+ invalid_fields: {
386
+ "email": "Invalid or unrecognized email",
387
+ "password": "Invalid or unrecognized password",
388
+ },
389
+ }
390
+ });
391
+ }
392
+ }
393
+ else {
394
+ if ((uid = await this.get_uid(username)) == null) {
395
+ return stream.error({
396
+ status: status_js_1.Status.unauthorized,
397
+ data: {
398
+ error: "Unauthorized.",
399
+ invalid_fields: {
400
+ "username": "Invalid or unrecognized username",
401
+ "password": "Invalid or unrecognized password",
402
+ },
403
+ }
404
+ });
405
+ }
406
+ }
407
+ // Verify password.
408
+ if (await this.verify_password(uid, password)) {
409
+ // Verify 2fa.
410
+ if (this.server.enable_2fa) {
411
+ // Get 2FA.
412
+ try {
413
+ code = stream.param("code");
414
+ }
415
+ catch (err) {
416
+ // Send 2fa and add to avg time tracking.
417
+ const start_time = Date.now();
418
+ await this.send_2fa({ uid: uid, stream });
419
+ // Add to avg time tracking.
420
+ if (this.avg_send_2fa_time.length >= 10000) {
421
+ this.avg_send_2fa_time.shift();
422
+ }
423
+ this.avg_send_2fa_time.push(Date.now() - start_time);
424
+ // Send error.
425
+ return stream.send({
426
+ status: status_js_1.Status.two_factor_auth_required,
427
+ data: { error: "2FA required." }
428
+ });
429
+ }
430
+ // Verify 2FA.
431
+ const err = await this.verify_2fa(uid, code);
432
+ if (err) {
433
+ return stream.send({
434
+ status: status_js_1.Status.unauthorized,
435
+ data: {
436
+ error: "Invalid 2FA code.",
437
+ invalid_fields: {
438
+ "code": err,
439
+ },
440
+ }
441
+ });
442
+ }
443
+ }
444
+ // Sign in.
445
+ return await this._sign_in_response(stream, uid);
446
+ }
447
+ // Wait for the same time as it would time on avg to send a mail.
448
+ if (this.avg_send_2fa_time.length >= 10) {
449
+ const sorted = [...this.avg_send_2fa_time].sort((a, b) => a - b);
450
+ const mid = Math.floor(sorted.length / 2);
451
+ if (sorted.length % 2 === 0) {
452
+ return (sorted[mid - 1] + sorted[mid]) / 2;
453
+ }
454
+ await new Promise(resolve => setTimeout(resolve, sorted[mid]));
455
+ }
456
+ // Unauthorized.
457
+ return stream.send({
458
+ status: status_js_1.Status.unauthorized,
459
+ data: {
460
+ error: "Unauthorized.",
461
+ invalid_fields: {
462
+ "username": "Invalid or unrecognized username",
463
+ "password": "Invalid or unrecognized password",
464
+ },
465
+ }
466
+ });
467
+ }
468
+ },
469
+ // Sign out.
470
+ {
471
+ method: "POST",
472
+ endpoint: "/volt/auth/signout",
473
+ content_type: "application/json",
474
+ authenticated: true,
475
+ rate_limit: "global",
476
+ callback: async (stream) => {
477
+ // Delete token.
478
+ await this._deactivate_token(stream.uid);
479
+ // Create headers.
480
+ this._reset_cookies(stream);
481
+ // Response.
482
+ return stream.success({
483
+ data: { message: "Successfully signed out." },
484
+ });
485
+ }
486
+ },
487
+ // Sign up.
488
+ {
489
+ method: "POST",
490
+ endpoint: "/volt/auth/signup",
491
+ content_type: "application/json",
492
+ rate_limit: "global",
493
+ params: {
494
+ username: "string",
495
+ first_name: "string",
496
+ last_name: "string",
497
+ email: "string",
498
+ password: "string",
499
+ verify_password: "string",
500
+ phone_number: { type: "string", required: false },
501
+ code: { type: "string", required: false },
502
+ },
503
+ callback: async (stream, params) => {
504
+ // Verify password.
505
+ const { error, invalid_fields } = this._verify_new_pass(params.password, params.verify_password);
506
+ if (error) {
507
+ return stream.error({
508
+ status: status_js_1.Status.bad_request,
509
+ data: {
510
+ error,
511
+ invalid_fields,
512
+ }
513
+ });
514
+ }
515
+ // Verify username and email.
516
+ if (await this.username_exists(params.username)) {
517
+ const e = new FrontendError(`Username "${params.username}" is already registered.`);
518
+ e.invalid_fields = { "username": "Username is already registered" };
519
+ throw e;
520
+ }
521
+ if (await this.email_exists(params.email)) {
522
+ const e = new FrontendError(`Email "${params.email}" is already registered.`);
523
+ e.invalid_fields = { "email": "Email is already registered" };
524
+ throw e;
525
+ }
526
+ // Verify 2fa.
527
+ if (this.server.enable_2fa) {
528
+ // Send 2FA.
529
+ if (params.code == null || params.code == "") {
530
+ // Send 2fa and add to avg time tracking.
531
+ const start_time = Date.now();
532
+ await this.send_2fa({
533
+ _email: params.email,
534
+ _username: params.username,
535
+ stream,
536
+ uid: undefined, // keep uid required param but use _email sys arg here.
537
+ });
538
+ // Add to avg time tracking.
539
+ if (this.avg_send_2fa_time.length >= 10000) {
540
+ this.avg_send_2fa_time.shift();
541
+ }
542
+ this.avg_send_2fa_time.push(Date.now() - start_time);
543
+ // Send error.
544
+ return stream.send({
545
+ status: status_js_1.Status.two_factor_auth_required,
546
+ data: { error: "2FA required." }
547
+ });
548
+ }
549
+ // Verify 2FA.
550
+ const err = await this.verify_2fa(params.email, params.code);
551
+ if (err) {
552
+ return stream.send({
553
+ status: status_js_1.Status.unauthorized,
554
+ data: {
555
+ error: "Invalid 2FA code.",
556
+ invalid_fields: {
557
+ "code": err,
558
+ },
559
+ }
560
+ });
561
+ }
562
+ }
563
+ // Create.
564
+ delete params.verify_password;
565
+ delete params.code;
566
+ params.is_activated = true; // already verified by 2fa or no 2fa is enabled.
567
+ params._check_username_email = false; // already checked.
568
+ let uid;
569
+ try {
570
+ uid = await this.create(params);
571
+ }
572
+ catch (err) {
573
+ return stream.error({
574
+ status: status_js_1.Status.bad_request,
575
+ data: {
576
+ error: err.message,
577
+ invalid_fields: err.invalid_fields || {},
578
+ }
579
+ });
580
+ }
581
+ // Sign in.
582
+ return await this._sign_in_response(stream, uid);
583
+ }
584
+ },
585
+ // Activate account.
586
+ {
587
+ method: "POST",
588
+ endpoint: "/volt/auth/activate",
589
+ content_type: "application/json",
590
+ rate_limit: "global",
591
+ params: {
592
+ "code": "string",
593
+ },
594
+ callback: async (stream, params) => {
595
+ // Vars.
596
+ let uid = stream.uid;
597
+ // Get uid by cookie.
598
+ if (uid == null) {
599
+ uid = stream.cookies["UserID"].value;
600
+ if (uid === "null" || uid === "-1") {
601
+ uid = null;
602
+ }
603
+ }
604
+ // Check uid.
605
+ if (uid == null) {
606
+ return stream.error({ status: status_js_1.Status.forbidden, data: { error: "Permission denied." } });
607
+ }
608
+ // Verify.
609
+ const err = await this.verify_2fa(uid, params.code);
610
+ if (err) {
611
+ return stream.error({
612
+ status: status_js_1.Status.forbidden,
613
+ data: {
614
+ error: "Permission denied.",
615
+ invalid_fields: {
616
+ "code": err,
617
+ },
618
+ }
619
+ });
620
+ }
621
+ // Set activated.
622
+ await this.set_activated(uid, true);
623
+ // Response.
624
+ await this._create_user_cookie(stream, uid);
625
+ return stream.success({ data: { message: "Successfully verified the 2FA code." } });
626
+ }
627
+ },
628
+ // Forgot password.
629
+ {
630
+ method: "POST",
631
+ endpoint: "/volt/auth/forgot_password",
632
+ content_type: "application/json",
633
+ rate_limit: "global",
634
+ params: {
635
+ email: "string",
636
+ code: "string",
637
+ password: "string",
638
+ verify_password: "string",
639
+ },
640
+ callback: async (stream, params) => {
641
+ // Verify password.
642
+ const { error, invalid_fields } = this._verify_new_pass(params.password, params.verify_password);
643
+ if (error) {
644
+ return stream.error({
645
+ status: status_js_1.Status.bad_request,
646
+ data: {
647
+ error: error,
648
+ invalid_fields,
649
+ }
650
+ });
651
+ }
652
+ // Get uid.
653
+ let uid;
654
+ if ((uid = await this.get_uid_by_email(params.email)) == null) {
655
+ return stream.error({ status: status_js_1.Status.forbidden, data: { error: "Invalid email." } });
656
+ }
657
+ // Verify 2fa.
658
+ const err = await this.verify_2fa(uid, params.code);
659
+ if (err) {
660
+ return stream.error({
661
+ status: status_js_1.Status.forbidden,
662
+ data: {
663
+ error: "Invalid 2FA code.",
664
+ invalid_fields: {
665
+ "code": "Invalid code"
666
+ },
667
+ }
668
+ });
669
+ }
670
+ // Set password.
671
+ await this.set_password(uid, params.password);
672
+ // Sign in.
673
+ return await this._sign_in_response(stream, uid);
674
+ }
675
+ });
676
+ // ---------------------------------------------------------
677
+ // Default user endpoints.
678
+ this.server.endpoint(
679
+ // Get user.
680
+ {
681
+ method: "GET",
682
+ endpoint: "/volt/user",
683
+ content_type: "application/json",
684
+ authenticated: true,
685
+ rate_limit: "global",
686
+ params: {
687
+ // detailed: { type: "boolean", default: false },
688
+ },
689
+ callback: async (stream, params) => {
690
+ const user = await this.get(stream.uid);
691
+ // Mask sensitive data.
692
+ if (user.password) {
693
+ user.password = "*".repeat(user.password.length);
694
+ }
695
+ if (user.api_key) {
696
+ user.api_key = "*".repeat(user.api_key.length);
697
+ }
698
+ // Ensure string type for frontend scheme.
699
+ user.first_name ??= "";
700
+ user.last_name ??= "";
701
+ user.username ??= "";
702
+ user.email ??= "";
703
+ user.password ??= "";
704
+ user.api_key ??= "";
705
+ user.support_pin ??= "";
706
+ return stream.success({ data: user });
707
+ }
708
+ },
709
+ // Set user.
710
+ {
711
+ method: "POST",
712
+ endpoint: "/volt/user",
713
+ authenticated: true,
714
+ rate_limit: "global",
715
+ callback: async (stream) => {
716
+ await this.set(stream.uid, stream.params);
717
+ await this._create_detailed_user_cookie(stream, stream.uid);
718
+ return stream.success({ data: { message: "Successfully updated your account." } });
719
+ }
720
+ },
721
+ // Change password.
722
+ {
723
+ method: "POST",
724
+ endpoint: "/volt/user/change_password",
725
+ authenticated: true,
726
+ rate_limit: "global",
727
+ params: {
728
+ current_password: "string",
729
+ password: "string",
730
+ verify_password: "string",
731
+ },
732
+ callback: async (stream, params) => {
733
+ // Verify old password.
734
+ if (await this.verify_password(stream.uid, params.current_password) !== true) {
735
+ return stream.error({
736
+ status: status_js_1.Status.unauthorized,
737
+ data: {
738
+ error: "Incorrect password.",
739
+ invalid_fields: {
740
+ current_password: "Incorrect password.",
741
+ }
742
+ },
743
+ });
744
+ }
745
+ // Verify new password.
746
+ const { error, invalid_fields } = this._verify_new_pass(params.password, params.verify_password);
747
+ if (error) {
748
+ return stream.error({
749
+ status: status_js_1.Status.bad_request,
750
+ data: {
751
+ error: error,
752
+ invalid_fields,
753
+ }
754
+ });
755
+ }
756
+ // Set password.
757
+ await this.set_password(stream.uid, params.password);
758
+ // Success.
759
+ return stream.success({
760
+ status: status_js_1.Status.success,
761
+ data: { message: "Successfully updated your password." },
762
+ });
763
+ }
764
+ },
765
+ // Delete account.
766
+ {
767
+ method: "DELETE",
768
+ endpoint: "/volt/user",
769
+ authenticated: true,
770
+ rate_limit: "global",
771
+ callback: async (stream) => {
772
+ // Delete.
773
+ await this.delete(stream.uid);
774
+ // Reset cookies.
775
+ this._reset_cookies(stream);
776
+ // Success.
777
+ return stream.success({
778
+ status: status_js_1.Status.success,
779
+ data: { message: "Successfully deleted your account." },
780
+ });
781
+ }
782
+ },
783
+ // Generate API key.
784
+ {
785
+ method: "POST",
786
+ endpoint: "/volt/user/api_key",
787
+ authenticated: true,
788
+ rate_limit: "global",
789
+ callback: async (stream) => {
790
+ return stream.success({
791
+ data: {
792
+ message: "Successfully generated an API key.",
793
+ api_key: await this.generate_api_key(stream.uid),
794
+ }
795
+ });
796
+ }
797
+ },
798
+ // Revoke API key.
799
+ {
800
+ method: "DELETE",
801
+ endpoint: "/volt/user/api_key",
802
+ authenticated: true,
803
+ rate_limit: "global",
804
+ callback: async (stream) => {
805
+ await this.revoke_api_key(stream.uid);
806
+ return stream.send({
807
+ status: status_js_1.Status.success,
808
+ data: { message: "Successfully revoked your API key." },
809
+ });
810
+ }
811
+ },
812
+ // Load data.
813
+ {
814
+ method: "GET",
815
+ endpoint: "/volt/user/data",
816
+ authenticated: true,
817
+ rate_limit: "global",
818
+ params: {
819
+ path: "string",
820
+ default: { type: "string", default: null },
821
+ },
822
+ callback: async (stream, params) => {
823
+ return stream.send({
824
+ status: status_js_1.Status.success,
825
+ data: await this.public.load(stream.uid, params.path, { default: params.default })
826
+ });
827
+ }
828
+ },
829
+ // Save data.
830
+ {
831
+ method: "POST",
832
+ endpoint: "/volt/user/data",
833
+ authenticated: true,
834
+ rate_limit: "global",
835
+ params: {
836
+ path: "string",
837
+ data: { type: undefined },
838
+ },
839
+ callback: async (stream, params) => {
840
+ await this.public.save(stream.uid, params.path, params.data);
841
+ return stream.send({
842
+ status: status_js_1.Status.success,
843
+ data: { message: "Successfully saved." },
844
+ });
845
+ }
846
+ },
847
+ // Delete data.
848
+ {
849
+ method: "DELETE",
850
+ endpoint: "/volt/user/data",
851
+ authenticated: true,
852
+ rate_limit: "global",
853
+ params: {
854
+ path: "string",
855
+ data: { type: undefined },
856
+ recursive: { type: "string", default: false },
857
+ },
858
+ callback: async (stream, params) => {
859
+ await this.public.delete(stream.uid, params.path, params.recursive);
860
+ return stream.send({
861
+ status: status_js_1.Status.success,
862
+ data: { message: "Successfully deleted." },
863
+ });
864
+ }
865
+ },
866
+ // Load protected data.
867
+ {
868
+ method: "GET",
869
+ endpoint: "/volt/user/data/protected",
870
+ authenticated: true,
871
+ rate_limit: "global",
872
+ params: {
873
+ path: "string",
874
+ default: { type: "string", default: null },
875
+ },
876
+ callback: async (stream, params) => {
877
+ return stream.send({
878
+ status: status_js_1.Status.success,
879
+ data: await this.protected.load(stream.uid, params.path, { default: params.default })
880
+ });
881
+ }
882
+ });
883
+ // ---------------------------------------------------------
884
+ // Default support endpoints.
885
+ this.server.endpoint(
886
+ // Get PIN.
887
+ {
888
+ method: "GET",
889
+ endpoint: "/volt/support/pin",
890
+ content_type: "application/json",
891
+ authenticated: true,
892
+ rate_limit: "global",
893
+ callback: async (stream) => {
894
+ // Sign in.
895
+ const pin = await this.get_support_pin(stream.uid);
896
+ return stream.success({
897
+ data: {
898
+ message: "Successfully retrieved your support PIN.",
899
+ pin: pin,
900
+ }
901
+ });
902
+ }
903
+ },
904
+ // Support.
905
+ // Supported params are: `support_pin`, `subject`, `summary`, `detailed`, `attachments`, `recipient` and `type`.
906
+ {
907
+ method: "POST",
908
+ endpoint: "/volt/support/submit",
909
+ content_type: "application/json",
910
+ rate_limit: "global",
911
+ callback: async (stream) => {
912
+ // Get params.
913
+ let params = stream.params;
914
+ // When unauthenticated get contact params.
915
+ let user = null, email, first_name, last_name;
916
+ if (stream.uid == null) {
917
+ try {
918
+ email = stream.param("email");
919
+ first_name = stream.param("first_name");
920
+ last_name = stream.param("last_name");
921
+ }
922
+ catch (err) {
923
+ return stream.error({ status: status_js_1.Status.bad_request, data: { error: err.message } });
924
+ }
925
+ }
926
+ else {
927
+ user = await this.get(stream.uid);
928
+ email = user.email;
929
+ first_name = user.first_name;
930
+ last_name = user.last_name;
931
+ }
932
+ // Create mail body.
933
+ let body = "";
934
+ const subject = params.subject || (params.type == null ? "Support" : `Support ${params.type}`);
935
+ body += `<h1>${subject}</h1>`;
936
+ if (params.subject) {
937
+ delete params.subject;
938
+ }
939
+ if (params.type) {
940
+ body += `<span style='font-weight: bold'>Type</span>: ${params.type}<br>`;
941
+ delete params.type;
942
+ }
943
+ if (user) {
944
+ body += `<span style='font-weight: bold'>UID</span>: ${stream.uid}<br>`;
945
+ body += `<span style='font-weight: bold'>User</span>: ${user.username}<br>`;
946
+ }
947
+ body += `<span style='font-weight: bold'>Email</span>: ${email}<br>`;
948
+ body += `<span style='font-weight: bold'>First Name</span>: ${first_name}<br>`;
949
+ body += `<span style='font-weight: bold'>Last Name</span>: ${last_name}<br>`;
950
+ if (stream.uid != null) {
951
+ const support_pin = await this.get_support_pin(stream.uid);
952
+ body += `<span style='font-weight: bold'>Support PIN</span>: ${support_pin} <span style='color: green'>verified</span><br>`;
953
+ }
954
+ else if (params.support_pin) {
955
+ body += `<span style='font-weight: bold'>Support PIN</span>: ${params.support_pin} <span style='color: red'>not yet verified</span><br>`;
956
+ delete params.support_pin;
957
+ }
958
+ else {
959
+ body += `<span style='font-weight: bold'>Support PIN</span>: Unknown<br>`;
960
+ }
961
+ if (params.summary) {
962
+ body += `<br><span style='font-weight: bold'>Summary</span>:<br>${params.summary}<br>`;
963
+ delete params.summary;
964
+ }
965
+ if (params.detailed) {
966
+ body += `<br><span style='font-weight: bold'>Detailed</span>:<br>${params.detailed}<br>`;
967
+ delete params.detailed;
968
+ }
969
+ Object.keys(params).forEach((key) => {
970
+ if (key !== "attachments" && key !== "recipient") {
971
+ body += `<br><span style='font-weight: bold'>${key}</span>: ${params[key]}<br>`;
972
+ }
973
+ });
974
+ // Attachments.
975
+ body += "<br>";
976
+ let attachments = [];
977
+ if (params.attachments) {
978
+ Object.keys(params.attachments).forEach((key) => {
979
+ attachments.push({
980
+ filename: key,
981
+ content: Buffer.from(params.attachments[key], 'utf-8'),
982
+ });
983
+ });
984
+ }
985
+ // Send email.
986
+ await this.server.send_mail({
987
+ recipients: [params.recipient || this.server.smtp_sender],
988
+ subject: subject,
989
+ body: body,
990
+ attachments: attachments,
991
+ });
992
+ // Sign in.
993
+ return stream.success({ data: { message: "Successfully sent your request." } });
994
+ }
995
+ });
996
+ }
997
+ // ---------------------------------------------------------
998
+ // Users.
999
+ // Check if a username exists.
1000
+ async uid_exists(uid) {
1001
+ return (await this._users_db.find(uid, { _path: "user" })) != null;
1002
+ }
1003
+ // Check if a username exists.
1004
+ /* @docs:
1005
+ * @title: Username Exists
1006
+ * @description: Check if a username exists.
1007
+ * @type: boolean
1008
+ * @return: Returns a boolean indicating whether the username exists or not.
1009
+ * @parameter:
1010
+ * @name: username
1011
+ * @description: The username to check.
1012
+ * @type: string
1013
+ * @usage:
1014
+ * ...
1015
+ * const exists = await server.users.username_exists("someusername");
1016
+ */
1017
+ async username_exists(username) {
1018
+ return (await this._users_db.find(null, { _path: "user", username })) != null;
1019
+ }
1020
+ // Check if an email exists.
1021
+ /* @docs:
1022
+ * @title: Email Exists
1023
+ * @description: Check if a email exists.
1024
+ * @type: boolean
1025
+ * @return: Returns a boolean indicating whether the email exists or not.
1026
+ * @parameter:
1027
+ * @name: email
1028
+ * @description: The email to check.
1029
+ * @type: string
1030
+ * @usage:
1031
+ * ...
1032
+ * const exists = await server.users.email_exists("some\@email.com");
1033
+ */
1034
+ async email_exists(email) {
1035
+ return (await this._users_db.find(null, { _path: "user", email })) != null;
1036
+ }
1037
+ // Is activated.
1038
+ /* @docs:
1039
+ * @title: Is Activated
1040
+ * @description: Check if a user account is activated.
1041
+ * @return: Returns a boolean indicating whether the account is activated or not.
1042
+ * @parameter:
1043
+ * @name: uid
1044
+ * @description: The id of the user.
1045
+ * @type: string
1046
+ * @cache: Users:uid:param
1047
+ * @usage:
1048
+ * ...
1049
+ * const activated = await server.users.is_activated(0);
1050
+ */
1051
+ async is_activated(uid) {
1052
+ return (await this.get(uid)).is_activated == true;
1053
+ }
1054
+ // Set activated.
1055
+ /* @docs:
1056
+ * @title: Set Activated
1057
+ * @description: Set the activated status of a user account is activated.
1058
+ * @parameter:
1059
+ * @name: uid
1060
+ * @cached: Users:uid:param
1061
+ * @parameter:
1062
+ * @name: activated
1063
+ * @description: The boolean with the new activated status.
1064
+ * @type: boolean
1065
+ * @usage:
1066
+ * ...
1067
+ * await server.users.set_activated(1, true);
1068
+ */
1069
+ async set_activated(uid, is_activated) {
1070
+ await this._sys_set(uid, { is_activated: is_activated });
1071
+ }
1072
+ // Create a user.
1073
+ /* @docs:
1074
+ * @title: Create User
1075
+ * @description:
1076
+ * Create a user account.
1077
+ *
1078
+ * Only the hashed password will be saved.
1079
+ * @return: Returns the uid of the newly created user.
1080
+ * @parameter:
1081
+ * @name: first_name
1082
+ * @description: The user's first name.
1083
+ * @type: string
1084
+ * @required: true
1085
+ * @parameter:
1086
+ * @name: last_name
1087
+ * @description: The user's last name.
1088
+ * @type: string
1089
+ * @required: true
1090
+ * @parameter:
1091
+ * @name: username
1092
+ * @description: The username of the new account.
1093
+ * @type: string
1094
+ * @required: true
1095
+ * @parameter:
1096
+ * @name: email
1097
+ * @description: The email of the new account.
1098
+ * @type: string
1099
+ * @required: true
1100
+ * @parameter:
1101
+ * @name: password
1102
+ * @description: The password of the new account.
1103
+ * @type: string
1104
+ * @required: true
1105
+ * @parameter:
1106
+ * @name: phone_number
1107
+ * @description: The phone number of the user account.
1108
+ * @type: string
1109
+ * @parameter:
1110
+ * @name: is_activated
1111
+ * @description: A boolean indicating if the account should be set to activated or not, accounts created through the /volt/api/signup endpoint are always immediately activated due to the required 2FA code. When called manually the default value of `!Server.enable_account_activation` will be used for parameter `is_activated`.
1112
+ * @type: boolean
1113
+ * @parameter:
1114
+ * @name: _check_username_email
1115
+ * @ignore: true
1116
+ * @usage:
1117
+ * ...
1118
+ * const uid = await server.users.create{
1119
+ * first_name: "John",
1120
+ * last_name: "Doe",
1121
+ * username: "johndoe",
1122
+ * email: "johndoe\@email.com",
1123
+ * password: "HelloWorld!"
1124
+ * });
1125
+ */
1126
+ async create({ first_name, last_name, username, email, password, phone_number = "", is_activated = null, _check_username_email = false, }) {
1127
+ // Verify params.
1128
+ _vinc_1.vlib.Scheme.verify({
1129
+ object: arguments[0],
1130
+ check_unknown: true,
1131
+ scheme: {
1132
+ first_name: "string",
1133
+ last_name: "string",
1134
+ username: "string",
1135
+ email: "string",
1136
+ password: "string",
1137
+ phone_number: { type: "string", default: "" },
1138
+ is_activated: { type: "boolean", required: false },
1139
+ _check_username_email: { type: "boolean", required: false },
1140
+ }
1141
+ });
1142
+ // Check if username & email already exist.
1143
+ if (_check_username_email) {
1144
+ if (await this.username_exists(username)) {
1145
+ const e = new FrontendError(`Username "${username}" is already registered.`);
1146
+ e.invalid_fields = { "username": "Username is already registered" };
1147
+ throw e;
1148
+ }
1149
+ if (await this.email_exists(email)) {
1150
+ const e = new FrontendError(`Email "${email}" is already registered.`);
1151
+ e.invalid_fields = { "email": "Email is already registered" };
1152
+ throw e;
1153
+ }
1154
+ }
1155
+ // Generate a uid.
1156
+ const uid = await this._generate_uid();
1157
+ // Create the user.
1158
+ await this._users_db.save(uid, "user", {
1159
+ uid,
1160
+ first_name,
1161
+ last_name,
1162
+ username,
1163
+ email,
1164
+ password: this.server._hmac(password),
1165
+ phone_number,
1166
+ created: Date.now(),
1167
+ api_key: null,
1168
+ support_pin: this._generate_code(8),
1169
+ is_activated: is_activated ?? !this.server.enable_account_activation,
1170
+ });
1171
+ // Response.
1172
+ return uid;
1173
+ }
1174
+ // Delete a user.
1175
+ /* @docs:
1176
+ * @title: Delete User
1177
+ * @description: Delete a user account.
1178
+ * @parameter:
1179
+ * @name: uid
1180
+ * @cached: Users:uid:param
1181
+ * @usage:
1182
+ * ...
1183
+ * await server.users.delete(0);
1184
+ */
1185
+ async delete(uid) {
1186
+ await this._users_db.delete_all(uid);
1187
+ await this._tokens_db.delete_all(uid);
1188
+ await this.public.delete_all(uid);
1189
+ await this.protected.delete_all(uid);
1190
+ await this.private.delete_all(uid);
1191
+ if (this.server.payments !== undefined) {
1192
+ await this.server.payments._delete_user(uid);
1193
+ }
1194
+ const res = this.server.on_delete_user({ uid });
1195
+ if (res instanceof Promise) {
1196
+ await res;
1197
+ }
1198
+ }
1199
+ // Set a user's first name.
1200
+ /* @docs:
1201
+ * @title: Set First Name
1202
+ * @description:
1203
+ * Set a user's first name
1204
+ *
1205
+ * If the uid does not exist an `Error` will be thrown.
1206
+ * @parameter:
1207
+ * @name: uid
1208
+ * @cached: Users:uid:param
1209
+ * @parameter:
1210
+ * @name: first_name
1211
+ * @description: The new first name.
1212
+ * @type: string
1213
+ * @usage:
1214
+ * ...
1215
+ * await server.users.set_first_name(1, "John");
1216
+ */
1217
+ async set_first_name(uid, first_name) {
1218
+ const user = await this.get(uid);
1219
+ await this._sys_set(uid, { first_name });
1220
+ }
1221
+ // Set a user's last name.
1222
+ /* @docs:
1223
+ * @title: Set Last Name
1224
+ * @description:
1225
+ * Set a user's last name
1226
+ *
1227
+ * If the uid does not exist an `Error` will be thrown.
1228
+ * @parameter:
1229
+ * @name: uid
1230
+ * @cached: Users:uid:param
1231
+ * @parameter:
1232
+ * @name: last_name
1233
+ * @description: The new last name.
1234
+ * @type: string
1235
+ * @usage:
1236
+ * ...
1237
+ * await server.users.set_last_name(1, "Doe");
1238
+ */
1239
+ async set_last_name(uid, last_name) {
1240
+ const user = await this.get(uid);
1241
+ await this._sys_set(uid, { last_name });
1242
+ }
1243
+ // Set a user's username.
1244
+ /* @docs:
1245
+ * @title: Set Username
1246
+ * @description:
1247
+ * Set a user's username
1248
+ *
1249
+ * If the uid does not exist an `Error` will be thrown.
1250
+ * @parameter:
1251
+ * @name: uid
1252
+ * @cached: Users:uid:param
1253
+ * @parameter:
1254
+ * @name: username
1255
+ * @description: The new username.
1256
+ * @type: string
1257
+ * @usage:
1258
+ * ...
1259
+ * await server.users.set_username(1, "newusername");
1260
+ */
1261
+ async set_username(uid, username) {
1262
+ if (await this.username_exists(username)) {
1263
+ throw Error(`Username "${username}" already exists.`);
1264
+ }
1265
+ await this._sys_set(uid, { username });
1266
+ }
1267
+ // Set a user's email.
1268
+ /* @docs:
1269
+ * @title: Set Email
1270
+ * @description:
1271
+ * Set a user's email
1272
+ *
1273
+ * If the uid does not exist an `Error` will be thrown.
1274
+ * @parameter:
1275
+ * @name: uid
1276
+ * @cached: Users:uid:param
1277
+ * @parameter:
1278
+ * @name: email
1279
+ * @description: The new email.
1280
+ * @type: string
1281
+ * @usage:
1282
+ * ...
1283
+ * await server.users.set_email(1, "new\@email.com");
1284
+ */
1285
+ async set_email(uid, email) {
1286
+ if (await this.email_exists(email)) {
1287
+ throw Error(`Email "${email}" already exists.`);
1288
+ }
1289
+ await this._sys_set(uid, { email });
1290
+ }
1291
+ // Set a user's password.
1292
+ /* @docs:
1293
+ * @title: Set Password
1294
+ * @description:
1295
+ * Set a user's password
1296
+ *
1297
+ * If the uid does not exist an `Error` will be thrown.
1298
+ * @parameter:
1299
+ * @name: uid
1300
+ * @cached: Users:uid:param
1301
+ * @parameter:
1302
+ * @name: password
1303
+ * @description: The new password.
1304
+ * @type: string
1305
+ * @usage:
1306
+ * ...
1307
+ * await server.users.set_password(1, "XXXXXX");
1308
+ */
1309
+ async set_password(uid, password) {
1310
+ await this._sys_set(uid, { password: this.server._hmac(password) });
1311
+ }
1312
+ // Update a user.
1313
+ /* @docs:
1314
+ * @title: Set user
1315
+ * @description:
1316
+ * Set a user's data
1317
+ *
1318
+ * This function only updates the passed user attributes, unpresent attributes will not be deleted.
1319
+ *
1320
+ * If the uid does not exist an `Error` will be thrown.
1321
+ *
1322
+ * @note: The username can not be changed using this function, use `Server.set_username()` instead.
1323
+ * @note: The email can not be changed using this function, use `Server.set_email()` instead.
1324
+ * @note: The password can not be changed using this function, use `Server.set_password()` instead.
1325
+ * @parameter:
1326
+ * @name: uid
1327
+ * @cached: Users:uid:param
1328
+ * @parameter:
1329
+ * @name: data
1330
+ * @description: The new user object.
1331
+ * @type: object
1332
+ * @usage:
1333
+ * ...
1334
+ * await server.users.set(1, {first_name: "John", last_name: "Doe"});
1335
+ */
1336
+ async set(uid, data) {
1337
+ let old_data;
1338
+ const set_data = {};
1339
+ for (const key of Object.keys(data)) {
1340
+ switch (key) {
1341
+ case "first_name":
1342
+ case "last_name":
1343
+ case "phone_number":
1344
+ case "is_activated":
1345
+ set_data[key] = data[key];
1346
+ break;
1347
+ case "password":
1348
+ set_data[key] = this.server._hmac(data[key]);
1349
+ break;
1350
+ case "username":
1351
+ if (old_data === undefined) {
1352
+ old_data = await this.get(uid);
1353
+ }
1354
+ if (old_data.username !== data.username) {
1355
+ if (await this.username_exists(data.username)) {
1356
+ throw Error(`Username "${data.username}" already exists.`);
1357
+ }
1358
+ set_data[key] = data[key];
1359
+ }
1360
+ break;
1361
+ case "email":
1362
+ if (old_data === undefined) {
1363
+ old_data = await this.get(uid);
1364
+ }
1365
+ if (old_data.email !== data.email) {
1366
+ if (await this.email_exists(data.email)) {
1367
+ throw Error(`Email "${data.email}" already exists.`);
1368
+ }
1369
+ set_data[key] = data[key];
1370
+ }
1371
+ break;
1372
+ default:
1373
+ break;
1374
+ }
1375
+ }
1376
+ data = await this._users_db.save(uid, "user", set_data);
1377
+ if (data == null) {
1378
+ throw new Error(`Unable to find a user by uid "${uid}".`);
1379
+ }
1380
+ return data;
1381
+ }
1382
+ async _sys_set(uid, data) {
1383
+ data = await this._users_db.save(uid, "user", data);
1384
+ if (data == null) {
1385
+ throw new Error(`Unable to find a user by uid "${uid}".`);
1386
+ }
1387
+ return data;
1388
+ }
1389
+ // Get user info by uid.
1390
+ /* @docs:
1391
+ * @title: Get User
1392
+ * @description:
1393
+ * Get a user by uid.
1394
+ *
1395
+ * If the uid does not exist an `Error` will be thrown.
1396
+ * @return:
1397
+ * Returns a User object.
1398
+ * @parameter:
1399
+ * @name: uid
1400
+ * @cached: Users:uid:param
1401
+ * @parameter:
1402
+ * @name: detailed
1403
+ * @description: Also retrieve the detailed user data.
1404
+ * @type: boolean
1405
+ * @usage:
1406
+ * ...
1407
+ * const user = await server.users.get(0);
1408
+ */
1409
+ async get(uid) {
1410
+ const data = await this._users_db.load(uid, "user");
1411
+ if (data == null) {
1412
+ throw new Error(`Unable to find a user by uid "${uid}".`);
1413
+ }
1414
+ return data;
1415
+ }
1416
+ // Get user info by username.
1417
+ /* @docs:
1418
+ * @title: Get User By Username
1419
+ * @description:
1420
+ * Get a user by username.
1421
+ *
1422
+ * If the username does not exist an `Error` will be thrown.
1423
+ * @return:
1424
+ * Returns a User object.
1425
+ * @parameter:
1426
+ * @name: username
1427
+ * @description: The username of the user to fetch.
1428
+ * @type: string
1429
+ * @usage:
1430
+ * ...
1431
+ * const user = await server.users.get_by_username("myusername");
1432
+ */
1433
+ async get_by_username(username) {
1434
+ const data = await this._users_db.find(null, { _path: "user", username });
1435
+ if (data == null) {
1436
+ throw new Error(`Unable to find a user by username "${username}".`);
1437
+ }
1438
+ return data;
1439
+ }
1440
+ // Get user info by email.
1441
+ /* @docs:
1442
+ * @title: Get User By Email
1443
+ * @description:
1444
+ * Get a user by email.
1445
+ *
1446
+ * If the email does not exist an `Error` will be thrown.
1447
+ * @return:
1448
+ * Returns a User object.
1449
+ * @parameter:
1450
+ * @name: email
1451
+ * @description: The email of the user to fetch.
1452
+ * @type: string
1453
+ * @usage:
1454
+ * ...
1455
+ * const user = await server.users.get_by_email("my\@email.com");
1456
+ */
1457
+ async get_by_email(email) {
1458
+ const data = await this._users_db.find(null, { _path: "user", email });
1459
+ if (data == null) {
1460
+ throw new Error(`Unable to find a user by email "${email}".`);
1461
+ }
1462
+ return data;
1463
+ }
1464
+ // Get user info by api key.
1465
+ /* @docs:
1466
+ * @title: Get User By API Key
1467
+ * @description:
1468
+ * Get a user by API key.
1469
+ *
1470
+ * If the API key does not exist an `Error` will be thrown.
1471
+ * @return:
1472
+ * Returns a User object.
1473
+ * @parameter:
1474
+ * @name: api_key
1475
+ * @description: The API key of the user to fetch.
1476
+ * @type: string
1477
+ * @usage:
1478
+ * ...
1479
+ * const user = await server.users.get_by_api_key("XXXXXX");
1480
+ */
1481
+ async get_by_api_key(api_key) {
1482
+ const data = await this._users_db.find(null, { _path: "user", api_key });
1483
+ if (data == null) {
1484
+ throw new Error(`Unable to find a user by api key "${api_key}".`);
1485
+ }
1486
+ return data;
1487
+ }
1488
+ // Get user info by token.
1489
+ /* @docs:
1490
+ * @title: Get User By Token
1491
+ * @description:
1492
+ * Get a user by token.
1493
+ *
1494
+ * If the token does not exist an `Error` will be thrown.
1495
+ * @return:
1496
+ * Returns a User object.
1497
+ * @parameter:
1498
+ * @name: token
1499
+ * @description: The authentication token of the user to fetch.
1500
+ * @type: string
1501
+ * @usage:
1502
+ * ...
1503
+ * const user = await server.users.get_by_token("XXXXXX");
1504
+ */
1505
+ async get_by_token(token) {
1506
+ const data = await this._tokens_db.find(null, { _path: "token", token });
1507
+ if (data == null) {
1508
+ throw new Error(`Unable to find a user by token "${token}".`);
1509
+ }
1510
+ return await this.get(data.uid);
1511
+ }
1512
+ // Get uid by username.
1513
+ /* @docs:
1514
+ * @title: Get UID
1515
+ * @description: Get a uid by username.
1516
+ * @return:
1517
+ * Returns the uid of the username.
1518
+ *
1519
+ * If the user does not exist `null` is returned.
1520
+ * @parameter:
1521
+ * @name: username
1522
+ * @description: The username of the uid to fetch.
1523
+ * @type: string
1524
+ * @usage:
1525
+ * ...
1526
+ * let uid;
1527
+ * if ((uid = await server.users.get_uid("myusername")) != null) { ... }
1528
+ */
1529
+ async get_uid(username) {
1530
+ try {
1531
+ return (await this.get_by_username(username)).uid;
1532
+ }
1533
+ catch (e) {
1534
+ return null;
1535
+ }
1536
+ }
1537
+ // Get uid by username.
1538
+ /* @docs:
1539
+ * @title: Get UID By Email
1540
+ * @description: Get a uid by username.
1541
+ * @return:
1542
+ * Returns the uid of the username.
1543
+ *
1544
+ * If the user does not exist `null` is returned.
1545
+ * @parameter:
1546
+ * @name: username
1547
+ * @description: The username of the uid to fetch.
1548
+ * @type: string
1549
+ * @usage:
1550
+ * ...
1551
+ * let uid;
1552
+ * if ((uid = await server.users.get_uid_by_username("myuser")) != null) { ... }
1553
+ */
1554
+ async get_uid_by_username(username) {
1555
+ try {
1556
+ return (await this.get_by_username(username)).uid;
1557
+ }
1558
+ catch (e) {
1559
+ return null;
1560
+ }
1561
+ }
1562
+ // Get uid by email.
1563
+ /* @docs:
1564
+ * @title: Get UID By Email
1565
+ * @description: Get a uid by email.
1566
+ * @return:
1567
+ * Returns the uid of the email.
1568
+ *
1569
+ * If the user does not exist `null` is returned.
1570
+ * @parameter:
1571
+ * @name: email
1572
+ * @description: The email of the uid to fetch.
1573
+ * @type: string
1574
+ * @usage:
1575
+ * ...
1576
+ * let uid;
1577
+ * if ((uid = await server.users.get_uid_by_email("my\@email.com")) != null) { ... }
1578
+ */
1579
+ async get_uid_by_email(email) {
1580
+ try {
1581
+ return (await this.get_by_email(email)).uid;
1582
+ }
1583
+ catch (e) {
1584
+ return null;
1585
+ }
1586
+ }
1587
+ // Get uid by api key.
1588
+ /* @docs:
1589
+ * @title: Get UID By API Key
1590
+ * @description: Get a uid by API key.
1591
+ * @return:
1592
+ * Returns the uid of the api key.
1593
+ *
1594
+ * If the user does not exist `null` is returned.
1595
+ * @parameter:
1596
+ * @name: api_key
1597
+ * @description: The API key of the uid to fetch.
1598
+ * @type: string
1599
+ * @usage:
1600
+ * ...
1601
+ * let uid;
1602
+ * if ((uid = await server.users.get_uid_by_api_key("XXXXXXXXXX")) != null) { ... }
1603
+ */
1604
+ async get_uid_by_api_key(api_key) {
1605
+ if (typeof api_key !== "string") {
1606
+ return null;
1607
+ }
1608
+ const pos = api_key.indexOf(":");
1609
+ if (pos === -1) {
1610
+ return null;
1611
+ }
1612
+ return api_key.substr(1, pos - 1);
1613
+ }
1614
+ // Get uid by token.
1615
+ /* @docs:
1616
+ * @title: Get UID By Token
1617
+ * @description: Get a uid by token.
1618
+ * @return:
1619
+ * Returns the uid of the token.
1620
+ *
1621
+ * If the user does not exist `null` is returned.
1622
+ * @parameter:
1623
+ * @name: token
1624
+ * @description: The token of the uid to fetch.
1625
+ * @type: string
1626
+ * @usage:
1627
+ * ...
1628
+ * let uid;
1629
+ * if ((uid = await server.users.get_uid_by_token("XXXXXXXXXX")) != null) { ... }
1630
+ */
1631
+ async get_uid_by_token(token) {
1632
+ return await this.get_uid_by_api_key(token);
1633
+ }
1634
+ // Get a user's support pin by uid.
1635
+ /* @docs:
1636
+ * @title: Get Support PIN
1637
+ * @description:
1638
+ * Get a user's support pin by uid.
1639
+ * @return:
1640
+ * Returns a User object.
1641
+ * @parameter:
1642
+ * @name: uid
1643
+ * @cached: Users:uid:param
1644
+ * @usage:
1645
+ * ...
1646
+ * const pin = await server.users.get_support_pin(1);
1647
+ */
1648
+ async get_support_pin(uid) {
1649
+ return (await this.get(uid)).support_pin;
1650
+ }
1651
+ // Generate an api key by uid.
1652
+ /* @docs:
1653
+ * @title: Generate API Key
1654
+ * @description:
1655
+ * Generate an API key for a user.
1656
+ *
1657
+ * Generating an API key overwrites all existing API keys.
1658
+ *
1659
+ * If the uid does not exist an `Error` will be thrown.
1660
+ * @return:
1661
+ * Returns the API key string.
1662
+ * @parameter:
1663
+ * @name: uid
1664
+ * @cached: Users:uid:param
1665
+ * @usage:
1666
+ * ...
1667
+ * const api_key = await server.users.generate_api_key(0);
1668
+ */
1669
+ async generate_api_key(uid) {
1670
+ const api_key = this._generate_api_key(uid);
1671
+ await this._sys_set(uid, { api_key: this.server._hmac(api_key) });
1672
+ return api_key;
1673
+ }
1674
+ // Revoke the API key of a user.
1675
+ /* @docs:
1676
+ * @title: Revoke API Key
1677
+ * @description:
1678
+ * Revoke the API key of a user.
1679
+ *
1680
+ * If the uid does not exist an `Error` will be thrown.
1681
+ * @parameter:
1682
+ * @name: uid
1683
+ * @cached: Users:uid:param
1684
+ * @usage:
1685
+ * ...
1686
+ * await server.users.revoke_api_key(0);
1687
+ */
1688
+ async revoke_api_key(uid) {
1689
+ await this._sys_set(uid, { api_key: "" });
1690
+ }
1691
+ // Verify a plaintext password.
1692
+ // Use async to keep it persistent with other functions.
1693
+ /* @docs:
1694
+ * @title: Verify Password
1695
+ * @description:
1696
+ * Verify a plaintext password.
1697
+ *
1698
+ * If the uid does not exist an `Error` will be thrown.
1699
+ * @return:
1700
+ * Returns a boolean indicating whether the verification was successful.
1701
+ * @parameter:
1702
+ * @name: uid
1703
+ * @cached: Users:uid:param
1704
+ * @parameter:
1705
+ * @name: password
1706
+ * @description: The plaintext password.
1707
+ * @type: string
1708
+ * @usage:
1709
+ * ...
1710
+ * const success = await server.users.verify_password(1, "XXXXXX");
1711
+ */
1712
+ async verify_password(uid, password) {
1713
+ try {
1714
+ const user = await this.get(uid);
1715
+ return user.uid != null && user.password === this.server._hmac(password);
1716
+ }
1717
+ catch (err) {
1718
+ return false;
1719
+ }
1720
+ }
1721
+ // Verify a plaintext api key.
1722
+ // Use async to keep it persistent with other functions.
1723
+ /* @docs:
1724
+ * @title: Verify API Key
1725
+ * @description:
1726
+ * Verify an plaintext API key.
1727
+ *
1728
+ * If the uid does not exist an `Error` will be thrown.
1729
+ * @return:
1730
+ * Returns a boolean indicating whether the verification was successful.
1731
+ * @parameter:
1732
+ * @name: api_key
1733
+ * @description: The api key to verify.
1734
+ * @type: string
1735
+ * @usage:
1736
+ * ...
1737
+ * const success = await server.users.verify_api_key("XXXXXX");
1738
+ */
1739
+ async verify_api_key(api_key) {
1740
+ return await this.verify_api_key_by_uid(await this.get_uid_by_api_key(api_key), api_key);
1741
+ }
1742
+ // Verify a plaintext api key by uid.
1743
+ // Use async to keep it persistent with other functions.
1744
+ /* @docs:
1745
+ * @title: Verify API Key By UID
1746
+ * @description:
1747
+ * Verify an plaintext API key by uid.
1748
+ *
1749
+ * If the uid does not exist an `Error` will be thrown.
1750
+ * @return:
1751
+ * Returns a boolean indicating whether the verification was successful.
1752
+ * @parameter:
1753
+ * @name: uid
1754
+ * @cached: Users:uid:param
1755
+ * @parameter:
1756
+ * @name: api_key
1757
+ * @description: The api key to verify.
1758
+ * @type: string
1759
+ * @usage:
1760
+ * ...
1761
+ * const success = await server.users.verify_api_key_by_uid(1, "XXXXXX");
1762
+ */
1763
+ async verify_api_key_by_uid(uid, api_key) {
1764
+ try {
1765
+ const user = await this.get(uid);
1766
+ return user.uid != null && user.api_key != null && user.api_key?.length > 0 && user.api_key == this.server._hmac(api_key);
1767
+ }
1768
+ catch (err) {
1769
+ return false;
1770
+ }
1771
+ }
1772
+ // Verify a token.
1773
+ // Use async to keep it persistent with other functions.
1774
+ /* @docs:
1775
+ * @title: Verify Token
1776
+ * @description:
1777
+ * Verify an plaintext token.
1778
+ *
1779
+ * If the uid does not exist an `Error` will be thrown.
1780
+ * @return:
1781
+ * Returns a boolean indicating whether the verification was successful.
1782
+ * @parameter:
1783
+ * @name: api_key
1784
+ * @description: The token to verify.
1785
+ * @type: string
1786
+ * @usage:
1787
+ * ...
1788
+ * const success = await server.users.verify_token("XXXXXX");
1789
+ */
1790
+ async verify_token(token) {
1791
+ return await this.verify_token_by_uid(await this.get_uid_by_api_key(token), token);
1792
+ }
1793
+ // Verify a token by uid.
1794
+ // Use async to keep it persistent with other functions.
1795
+ /* @docs:
1796
+ * @title: Verify Token By UID.
1797
+ * @description:
1798
+ * Verify an plaintext token by uid.
1799
+ *
1800
+ * If the uid does not exist an `Error` will be thrown.
1801
+ * @return:
1802
+ * Returns a boolean indicating whether the verification was successful.
1803
+ * @parameter:
1804
+ * @name: uid
1805
+ * @cached: Users:uid:param
1806
+ * @parameter:
1807
+ * @name: api_key
1808
+ * @description: The token to verify.
1809
+ * @type: string
1810
+ * @usage:
1811
+ * ...
1812
+ * const success = await server.users.verify_token_by_uid(1, "XXXXXX");
1813
+ */
1814
+ async verify_token_by_uid(uid, token) {
1815
+ try {
1816
+ const correct_token = await this._tokens_db.load(uid, "token");
1817
+ return (correct_token != null &&
1818
+ correct_token.token != null &&
1819
+ correct_token.active !== false &&
1820
+ Date.now() < correct_token.expiration &&
1821
+ correct_token.token == this.server._hmac(token));
1822
+ }
1823
+ catch (err) {
1824
+ return false;
1825
+ }
1826
+ }
1827
+ // Verify a 2fa code.
1828
+ // Use async to keep it persistent with other functions.
1829
+ /* @docs:
1830
+ * @title: Verify 2FA Code
1831
+ * @description:
1832
+ * Verify a 2FA code by user id.
1833
+ * @parameter:
1834
+ * @name: uid
1835
+ * @cached: Users:uid:param
1836
+ * @parameter:
1837
+ * @name: code
1838
+ * @description: The 2FA code.
1839
+ * @type: string
1840
+ * @return: Returns a boolean indicating whether the verification was successful or not.
1841
+ * @usage:
1842
+ * ...
1843
+ * await server.users.verify_2fa(1, "123456");
1844
+ */
1845
+ async verify_2fa(uid, code) {
1846
+ try {
1847
+ const auth = await this._tokens_db.load(uid, "2fa");
1848
+ if (auth == null) {
1849
+ return "Invalid 2FA code.";
1850
+ }
1851
+ const now = Date.now();
1852
+ if (now >= auth.expiration) {
1853
+ await this._deactivate_2fa_token(uid);
1854
+ return "The 2FA code has expired.";
1855
+ }
1856
+ const status = (auth != null &&
1857
+ auth.code != null &&
1858
+ now < auth.expiration &&
1859
+ auth.code == code &&
1860
+ auth.active !== false);
1861
+ if (status === false) {
1862
+ return "Invalid 2FA code.";
1863
+ }
1864
+ return null;
1865
+ }
1866
+ catch (err) {
1867
+ logger_js_1.logger.error(log_source, "Encountered an error while validating the 2FA code.");
1868
+ logger_js_1.logger.error(log_source, `${err}.`);
1869
+ return "Unknown error.";
1870
+ }
1871
+ }
1872
+ // Send a 2fa code.
1873
+ /* @docs:
1874
+ * @title: Send 2FA Code
1875
+ * @description:
1876
+ * Send a 2FA code to a user by user id.
1877
+ *
1878
+ * By default the 2FA code will be valid for 5 minutes.
1879
+ *
1880
+ * The mail body will be generated using the `Server.on_2fa_mail({code, username, email, date, ip, device})` callback. When the callback is not defined an error will be thrown.
1881
+ * @return:
1882
+ * Returns a promise that will be resolved or rejected when the 2fa mail has been sent.
1883
+ * @parameter:
1884
+ * @name: uid
1885
+ * @cached: Users:uid:param
1886
+ * @parameter:
1887
+ * @name: stream
1888
+ * @description: The stream object from the client request.
1889
+ * @type: object
1890
+ * @parameter:
1891
+ * @name: expiration
1892
+ * @description: The amount of seconds in which the code will expire.
1893
+ * @type: number
1894
+ * @usage:
1895
+ * ...
1896
+ * await server.users.send_2fa({uid: 0, stream});
1897
+ */
1898
+ async send_2fa({ uid, stream, expiration = 300, _device = null, _username = null, _email = null, }) {
1899
+ // Generate 2fa and get user email.
1900
+ let code;
1901
+ if (_username == null && _email == null) {
1902
+ code = await this._create_2fa_token(uid, expiration);
1903
+ const user = await this.get(uid);
1904
+ _username = user.username;
1905
+ _email = user.email;
1906
+ }
1907
+ else {
1908
+ code = await this._create_2fa_token(_email, expiration);
1909
+ }
1910
+ // Get device.
1911
+ let device;
1912
+ if (_device == null) {
1913
+ device = stream.headers["user-agent"];
1914
+ }
1915
+ // Replace body.
1916
+ if (this.server.on_2fa_mail === undefined) {
1917
+ throw Error("Define server callback \"Server.on_2fa_mail\" to generate the HTML mail body.");
1918
+ }
1919
+ let mail = this.server.on_2fa_mail({
1920
+ code: code,
1921
+ username: _username,
1922
+ email: _email,
1923
+ date: new Date().toUTCString(),
1924
+ ip: stream.ip,
1925
+ device: device ? device : "Unknown",
1926
+ });
1927
+ let body = mail, subject = null;
1928
+ if (mail instanceof Mail.MailElement) {
1929
+ body = mail.html();
1930
+ subject = mail.subject();
1931
+ }
1932
+ // Send mail.
1933
+ await this.server.send_mail({
1934
+ recipients: [_email],
1935
+ subject: subject ?? "Two Factor Authentication Code",
1936
+ body,
1937
+ });
1938
+ }
1939
+ // List all users.
1940
+ async list() {
1941
+ return await this._users_db.list_query({ _path: "user" });
1942
+ }
1943
+ }
1944
+ exports.Users = Users;
1945
+ exports.default = Users;