@axium/server 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/build/client/_app/immutable/chunks/46qGscyh.js +2 -0
  2. package/build/client/_app/immutable/chunks/46qGscyh.js.br +0 -0
  3. package/build/client/_app/immutable/chunks/46qGscyh.js.gz +0 -0
  4. package/build/client/_app/immutable/chunks/B2Vkpbkw.js +2 -0
  5. package/build/client/_app/immutable/chunks/B2Vkpbkw.js.br +0 -0
  6. package/build/client/_app/immutable/chunks/B2Vkpbkw.js.gz +0 -0
  7. package/build/client/_app/immutable/chunks/BKixenYx.js +1 -0
  8. package/build/client/_app/immutable/chunks/BKixenYx.js.br +0 -0
  9. package/build/client/_app/immutable/chunks/BKixenYx.js.gz +0 -0
  10. package/build/client/_app/immutable/chunks/BLtAtlP3.js +1 -0
  11. package/build/client/_app/immutable/chunks/BLtAtlP3.js.br +2 -0
  12. package/build/client/_app/immutable/chunks/BLtAtlP3.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/BNTlty5m.js +1 -0
  14. package/build/client/_app/immutable/chunks/BNTlty5m.js.br +0 -0
  15. package/build/client/_app/immutable/chunks/BNTlty5m.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/Beh6Ec8J.js +1 -0
  17. package/build/client/_app/immutable/chunks/Beh6Ec8J.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/Beh6Ec8J.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/BrUe-Qen.js +1 -0
  20. package/build/client/_app/immutable/chunks/BrUe-Qen.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/BrUe-Qen.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/Bs4cD_pX.js +1 -0
  23. package/build/client/_app/immutable/chunks/Bs4cD_pX.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/Bs4cD_pX.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/C62F-tXu.js +1 -0
  26. package/build/client/_app/immutable/chunks/C62F-tXu.js.br +1 -0
  27. package/build/client/_app/immutable/chunks/C62F-tXu.js.gz +0 -0
  28. package/build/client/_app/immutable/chunks/CUBtP2L9.js +23 -0
  29. package/build/client/_app/immutable/chunks/CUBtP2L9.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/CUBtP2L9.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/CoYD6HNm.js +1 -0
  32. package/build/client/_app/immutable/chunks/CoYD6HNm.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/CoYD6HNm.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/D40Zn55h.js +1 -0
  35. package/build/client/_app/immutable/chunks/D40Zn55h.js.br +0 -0
  36. package/build/client/_app/immutable/chunks/D40Zn55h.js.gz +0 -0
  37. package/build/client/_app/immutable/chunks/DW7-1esk.js +21 -0
  38. package/build/client/_app/immutable/chunks/DW7-1esk.js.br +0 -0
  39. package/build/client/_app/immutable/chunks/DW7-1esk.js.gz +0 -0
  40. package/build/client/_app/immutable/chunks/DvOBbqVY.js +1 -0
  41. package/build/client/_app/immutable/chunks/DvOBbqVY.js.br +0 -0
  42. package/build/client/_app/immutable/chunks/DvOBbqVY.js.gz +0 -0
  43. package/build/client/_app/immutable/chunks/DwZYWemd.js +1 -0
  44. package/build/client/_app/immutable/chunks/DwZYWemd.js.br +0 -0
  45. package/build/client/_app/immutable/chunks/DwZYWemd.js.gz +0 -0
  46. package/build/client/_app/immutable/chunks/Dy2Ho0cF.js +1 -0
  47. package/build/client/_app/immutable/chunks/Dy2Ho0cF.js.br +0 -0
  48. package/build/client/_app/immutable/chunks/Dy2Ho0cF.js.gz +0 -0
  49. package/build/client/_app/immutable/chunks/FTv0qR3w.js +1 -0
  50. package/build/client/_app/immutable/chunks/FTv0qR3w.js.br +0 -0
  51. package/build/client/_app/immutable/chunks/FTv0qR3w.js.gz +0 -0
  52. package/build/client/_app/immutable/chunks/NeK0YGoY.js +1 -0
  53. package/build/client/_app/immutable/chunks/NeK0YGoY.js.br +0 -0
  54. package/build/client/_app/immutable/chunks/NeK0YGoY.js.gz +0 -0
  55. package/build/client/_app/immutable/chunks/aArGsq9c.js +1 -0
  56. package/build/client/_app/immutable/chunks/aArGsq9c.js.br +0 -0
  57. package/build/client/_app/immutable/chunks/aArGsq9c.js.gz +0 -0
  58. package/build/client/_app/immutable/chunks/lH47zGKU.js +1 -0
  59. package/build/client/_app/immutable/chunks/lH47zGKU.js.br +0 -0
  60. package/build/client/_app/immutable/chunks/lH47zGKU.js.gz +0 -0
  61. package/build/client/_app/immutable/chunks/sMHjBQqw.js +1 -0
  62. package/build/client/_app/immutable/chunks/sMHjBQqw.js.br +0 -0
  63. package/build/client/_app/immutable/chunks/sMHjBQqw.js.gz +0 -0
  64. package/build/client/_app/immutable/chunks/vQfHcJV6.js +2 -0
  65. package/build/client/_app/immutable/chunks/vQfHcJV6.js.br +0 -0
  66. package/build/client/_app/immutable/chunks/vQfHcJV6.js.gz +0 -0
  67. package/build/client/_app/immutable/entry/app.pLVZKpSD.js +2 -0
  68. package/build/client/_app/immutable/entry/app.pLVZKpSD.js.br +0 -0
  69. package/build/client/_app/immutable/entry/app.pLVZKpSD.js.gz +0 -0
  70. package/build/client/_app/immutable/entry/start.CUaVsIrY.js +1 -0
  71. package/build/client/_app/immutable/entry/start.CUaVsIrY.js.br +2 -0
  72. package/build/client/_app/immutable/entry/start.CUaVsIrY.js.gz +0 -0
  73. package/build/client/_app/immutable/nodes/0.D7hET-Bq.js +1 -0
  74. package/build/client/_app/immutable/nodes/0.D7hET-Bq.js.br +0 -0
  75. package/build/client/_app/immutable/nodes/0.D7hET-Bq.js.gz +0 -0
  76. package/build/client/_app/immutable/nodes/1.BWU-JJm_.js +1 -0
  77. package/build/client/_app/immutable/nodes/1.BWU-JJm_.js.br +2 -0
  78. package/build/client/_app/immutable/nodes/1.BWU-JJm_.js.gz +0 -0
  79. package/build/client/_app/immutable/nodes/10.C5N2XBee.js +1 -0
  80. package/build/client/_app/immutable/nodes/10.C5N2XBee.js.br +0 -0
  81. package/build/client/_app/immutable/nodes/10.C5N2XBee.js.gz +0 -0
  82. package/build/client/_app/immutable/nodes/11.CerbuSAv.js +1 -0
  83. package/build/client/_app/immutable/nodes/11.CerbuSAv.js.br +0 -0
  84. package/build/client/_app/immutable/nodes/11.CerbuSAv.js.gz +0 -0
  85. package/build/client/_app/immutable/nodes/12.Z4B9zS78.js +1 -0
  86. package/build/client/_app/immutable/nodes/12.Z4B9zS78.js.br +0 -0
  87. package/build/client/_app/immutable/nodes/12.Z4B9zS78.js.gz +0 -0
  88. package/build/client/_app/immutable/nodes/13.CuICShck.js +1 -0
  89. package/build/client/_app/immutable/nodes/13.CuICShck.js.br +0 -0
  90. package/build/client/_app/immutable/nodes/13.CuICShck.js.gz +0 -0
  91. package/build/client/_app/immutable/nodes/14.BSEF5oaF.js +1 -0
  92. package/build/client/_app/immutable/nodes/14.BSEF5oaF.js.br +0 -0
  93. package/build/client/_app/immutable/nodes/14.BSEF5oaF.js.gz +0 -0
  94. package/build/client/_app/immutable/nodes/15.D1nsmo6j.js +1 -0
  95. package/build/client/_app/immutable/nodes/15.D1nsmo6j.js.br +0 -0
  96. package/build/client/_app/immutable/nodes/15.D1nsmo6j.js.gz +0 -0
  97. package/build/client/_app/immutable/nodes/2.DQ1JcYgz.js +1 -0
  98. package/build/client/_app/immutable/nodes/2.DQ1JcYgz.js.br +0 -0
  99. package/build/client/_app/immutable/nodes/2.DQ1JcYgz.js.gz +0 -0
  100. package/build/client/_app/immutable/nodes/3.BJp2JEtW.js +1 -0
  101. package/build/client/_app/immutable/nodes/3.BJp2JEtW.js.br +0 -0
  102. package/build/client/_app/immutable/nodes/3.BJp2JEtW.js.gz +0 -0
  103. package/build/client/_app/immutable/nodes/4.Cvn_QsIx.js +1 -0
  104. package/build/client/_app/immutable/nodes/4.Cvn_QsIx.js.br +0 -0
  105. package/build/client/_app/immutable/nodes/4.Cvn_QsIx.js.gz +0 -0
  106. package/build/client/_app/immutable/nodes/5.DgPP9GX3.js +1 -0
  107. package/build/client/_app/immutable/nodes/5.DgPP9GX3.js.br +0 -0
  108. package/build/client/_app/immutable/nodes/5.DgPP9GX3.js.gz +0 -0
  109. package/build/client/_app/immutable/nodes/6.DKIzms8i.js +2 -0
  110. package/build/client/_app/immutable/nodes/6.DKIzms8i.js.br +0 -0
  111. package/build/client/_app/immutable/nodes/6.DKIzms8i.js.gz +0 -0
  112. package/build/client/_app/immutable/nodes/7.3UigVXV4.js +1 -0
  113. package/build/client/_app/immutable/nodes/7.3UigVXV4.js.br +0 -0
  114. package/build/client/_app/immutable/nodes/7.3UigVXV4.js.gz +0 -0
  115. package/build/client/_app/immutable/nodes/8.B8s2TdNQ.js +1 -0
  116. package/build/client/_app/immutable/nodes/8.B8s2TdNQ.js.br +0 -0
  117. package/build/client/_app/immutable/nodes/8.B8s2TdNQ.js.gz +0 -0
  118. package/build/client/_app/immutable/nodes/9.LBMMe2kc.js +1 -0
  119. package/build/client/_app/immutable/nodes/9.LBMMe2kc.js.br +0 -0
  120. package/build/client/_app/immutable/nodes/9.LBMMe2kc.js.gz +0 -0
  121. package/build/client/_app/version.json +1 -1
  122. package/build/client/_app/version.json.br +0 -0
  123. package/build/client/_app/version.json.gz +0 -0
  124. package/build/client/styles.css +21 -0
  125. package/build/client/styles.css.br +0 -0
  126. package/build/client/styles.css.gz +0 -0
  127. package/build/server/chunks/{0-CZBaNtSI.js → 0-CNbALTKz.js} +2 -2
  128. package/build/server/chunks/0-CNbALTKz.js.map +1 -0
  129. package/build/server/chunks/1-Dgxy393u.js +9 -0
  130. package/build/server/chunks/1-Dgxy393u.js.map +1 -0
  131. package/build/server/chunks/10-DovmbqKa.js +14 -0
  132. package/build/server/chunks/10-DovmbqKa.js.map +1 -0
  133. package/build/server/chunks/11-CRK_ubcl.js +14 -0
  134. package/build/server/chunks/11-CRK_ubcl.js.map +1 -0
  135. package/build/server/chunks/12-SbQlwMfe.js +9 -0
  136. package/build/server/chunks/12-SbQlwMfe.js.map +1 -0
  137. package/build/server/chunks/13-CbniIW7F.js +14 -0
  138. package/build/server/chunks/13-CbniIW7F.js.map +1 -0
  139. package/build/server/chunks/14-D9Vb_8Yx.js +9 -0
  140. package/build/server/chunks/14-D9Vb_8Yx.js.map +1 -0
  141. package/build/server/chunks/15-D-75Hdef.js +9 -0
  142. package/build/server/chunks/15-D-75Hdef.js.map +1 -0
  143. package/build/server/chunks/2-57exN8ae.js +14 -0
  144. package/build/server/chunks/2-57exN8ae.js.map +1 -0
  145. package/build/server/chunks/{3-B1CwnVF_.js → 3-DNQft-pY.js} +2 -2
  146. package/build/server/chunks/{3-B1CwnVF_.js.map → 3-DNQft-pY.js.map} +1 -1
  147. package/build/server/chunks/4-D9Bwp-f8.js +14 -0
  148. package/build/server/chunks/4-D9Bwp-f8.js.map +1 -0
  149. package/build/server/chunks/5-COEQwZNP.js +14 -0
  150. package/build/server/chunks/5-COEQwZNP.js.map +1 -0
  151. package/build/server/chunks/6-RT4yiDcP.js +14 -0
  152. package/build/server/chunks/6-RT4yiDcP.js.map +1 -0
  153. package/build/server/chunks/7-CVqF_r5D.js +14 -0
  154. package/build/server/chunks/7-CVqF_r5D.js.map +1 -0
  155. package/build/server/chunks/8-C5SO-sVH.js +14 -0
  156. package/build/server/chunks/8-C5SO-sVH.js.map +1 -0
  157. package/build/server/chunks/9-DoCOKtY-.js +14 -0
  158. package/build/server/chunks/9-DoCOKtY-.js.map +1 -0
  159. package/build/server/chunks/FormDialog-ZCY0chY1.js +102 -0
  160. package/build/server/chunks/FormDialog-ZCY0chY1.js.map +1 -0
  161. package/build/server/chunks/{Icon-CG7XnWX5.js → Icon-BVo9qbDf.js} +2 -2
  162. package/build/server/chunks/{Icon-CG7XnWX5.js.map → Icon-BVo9qbDf.js.map} +1 -1
  163. package/build/server/chunks/{Logout-BwzK1P29.js → Logout-CmBZgu0j.js} +4 -3
  164. package/build/server/chunks/{Logout-BwzK1P29.js.map → Logout-CmBZgu0j.js.map} +1 -1
  165. package/build/server/chunks/{_layout.svelte-9KMUotip.js → _layout.svelte-DuS006VZ.js} +6 -4
  166. package/build/server/chunks/_layout.svelte-DuS006VZ.js.map +1 -0
  167. package/build/server/chunks/_page.svelte-BFVobcI7.js +14 -0
  168. package/build/server/chunks/{_page.svelte-Bou2_u6i.js.map → _page.svelte-BFVobcI7.js.map} +1 -1
  169. package/build/server/chunks/{_page.svelte-rrN2zFNa.js → _page.svelte-B_cvhWJS.js} +4 -4
  170. package/build/server/chunks/_page.svelte-B_cvhWJS.js.map +1 -0
  171. package/build/server/chunks/{_page.svelte-BD3HmLo_.js → _page.svelte-BriaBR9l.js} +3 -3
  172. package/build/server/chunks/_page.svelte-BriaBR9l.js.map +1 -0
  173. package/build/server/chunks/{_page.svelte-CAzWL4aq.js → _page.svelte-BtQQzT7H.js} +12 -6
  174. package/build/server/chunks/_page.svelte-BtQQzT7H.js.map +1 -0
  175. package/build/server/chunks/{_page.svelte-BIxxuzff.js → _page.svelte-C8D3c3yB.js} +4 -4
  176. package/build/server/chunks/_page.svelte-C8D3c3yB.js.map +1 -0
  177. package/build/server/chunks/{_page.svelte-cAsZlwLs.js → _page.svelte-CVSb9eHQ.js} +4 -4
  178. package/build/server/chunks/_page.svelte-CVSb9eHQ.js.map +1 -0
  179. package/build/server/chunks/{_page.svelte-BFzPdJ6z.js → _page.svelte-CwRjZqL7.js} +9 -7
  180. package/build/server/chunks/_page.svelte-CwRjZqL7.js.map +1 -0
  181. package/build/server/chunks/{_page.svelte-DgyZKeaF.js → _page.svelte-D9A9RYjx.js} +10 -8
  182. package/build/server/chunks/_page.svelte-D9A9RYjx.js.map +1 -0
  183. package/build/server/chunks/_page.svelte-DGhwqWMM.js +34 -0
  184. package/build/server/chunks/_page.svelte-DGhwqWMM.js.map +1 -0
  185. package/build/server/chunks/{_page.svelte-Ci5V-DhL.js → _page.svelte-DTvnX95_.js} +10 -7
  186. package/build/server/chunks/_page.svelte-DTvnX95_.js.map +1 -0
  187. package/build/server/chunks/{_page.svelte-C25oQ2NT.js → _page.svelte-DUfwpXfC.js} +51 -9
  188. package/build/server/chunks/_page.svelte-DUfwpXfC.js.map +1 -0
  189. package/build/server/chunks/{_page.svelte-CnfRSJsl.js → _page.svelte-DxDoD3rZ.js} +3 -3
  190. package/build/server/chunks/_page.svelte-DxDoD3rZ.js.map +1 -0
  191. package/build/server/chunks/{account-BZSP6KBP.js → account-Bf_llRe2.js} +6 -5
  192. package/build/server/chunks/{account-BZSP6KBP.js.map → account-Bf_llRe2.js.map} +1 -1
  193. package/build/server/chunks/auth_redirect-olBYiIF2.js +24 -0
  194. package/build/server/chunks/auth_redirect-olBYiIF2.js.map +1 -0
  195. package/build/server/chunks/{error.svelte-DTrQqomO.js → error.svelte-CkSCwrMJ.js} +2 -2
  196. package/build/server/chunks/error.svelte-CkSCwrMJ.js.map +1 -0
  197. package/build/server/chunks/{index-DJrm8BZm.js → index-CIEcmmdN.js} +57 -11
  198. package/build/server/chunks/index-CIEcmmdN.js.map +1 -0
  199. package/build/server/chunks/{index-eKiDBuyI.js → index-Tt4zVDIZ.js} +25 -8
  200. package/build/server/chunks/index-Tt4zVDIZ.js.map +1 -0
  201. package/build/server/chunks/{user2-Coq3Frtw.js → user2-CRfK67II.js} +9 -102
  202. package/build/server/chunks/user2-CRfK67II.js.map +1 -0
  203. package/build/server/chunks/{utils-DlBYhQz7.js → utils-h74ns7K6.js} +1 -2
  204. package/build/server/chunks/utils-h74ns7K6.js.map +1 -0
  205. package/build/server/index.js +573 -202
  206. package/build/server/index.js.map +1 -1
  207. package/build/server/manifest.js +26 -18
  208. package/build/server/manifest.js.map +1 -1
  209. package/dist/acl.js +1 -1
  210. package/dist/api/admin.js +20 -3
  211. package/dist/api/metadata.js +3 -3
  212. package/dist/api/users.js +4 -1
  213. package/dist/audit.d.ts +1 -0
  214. package/dist/audit.js +3 -3
  215. package/dist/cli.js +511 -541
  216. package/dist/config.d.ts +6 -6
  217. package/dist/config.js +25 -13
  218. package/dist/database.js +7 -6
  219. package/dist/io.d.ts +0 -50
  220. package/dist/io.js +23 -171
  221. package/dist/linking.js +4 -4
  222. package/dist/requests.d.ts +5 -1
  223. package/dist/requests.js +4 -2
  224. package/dist/routes.js +3 -3
  225. package/dist/serve.d.ts +4 -0
  226. package/dist/serve.js +13 -8
  227. package/package.json +5 -5
  228. package/routes/admin/+layout.ts +2 -0
  229. package/routes/admin/audit/+page.svelte +23 -2
  230. package/routes/admin/audit/+page.ts +4 -2
  231. package/routes/login/client/+page.svelte +72 -0
  232. package/routes/login/client/+page.ts +27 -0
  233. package/build/client/_app/immutable/chunks/1taVrT-y.js +0 -1
  234. package/build/client/_app/immutable/chunks/1taVrT-y.js.br +0 -0
  235. package/build/client/_app/immutable/chunks/1taVrT-y.js.gz +0 -0
  236. package/build/client/_app/immutable/chunks/BSFUgC2l.js +0 -23
  237. package/build/client/_app/immutable/chunks/BSFUgC2l.js.br +0 -0
  238. package/build/client/_app/immutable/chunks/BSFUgC2l.js.gz +0 -0
  239. package/build/client/_app/immutable/chunks/Bbzjahjl.js +0 -2
  240. package/build/client/_app/immutable/chunks/Bbzjahjl.js.br +0 -0
  241. package/build/client/_app/immutable/chunks/Bbzjahjl.js.gz +0 -0
  242. package/build/client/_app/immutable/chunks/BxjargW5.js +0 -1
  243. package/build/client/_app/immutable/chunks/BxjargW5.js.br +0 -0
  244. package/build/client/_app/immutable/chunks/BxjargW5.js.gz +0 -0
  245. package/build/client/_app/immutable/chunks/C2ewTgu8.js +0 -1
  246. package/build/client/_app/immutable/chunks/C2ewTgu8.js.br +0 -0
  247. package/build/client/_app/immutable/chunks/C2ewTgu8.js.gz +0 -0
  248. package/build/client/_app/immutable/chunks/CFWAHLsq.js +0 -1
  249. package/build/client/_app/immutable/chunks/CFWAHLsq.js.br +0 -0
  250. package/build/client/_app/immutable/chunks/CFWAHLsq.js.gz +0 -0
  251. package/build/client/_app/immutable/chunks/CPL43v-I.js +0 -1
  252. package/build/client/_app/immutable/chunks/CPL43v-I.js.br +0 -0
  253. package/build/client/_app/immutable/chunks/CPL43v-I.js.gz +0 -0
  254. package/build/client/_app/immutable/chunks/CTKC36WM.js +0 -1
  255. package/build/client/_app/immutable/chunks/CTKC36WM.js.br +0 -0
  256. package/build/client/_app/immutable/chunks/CTKC36WM.js.gz +0 -0
  257. package/build/client/_app/immutable/chunks/CekH6JMP.js +0 -1
  258. package/build/client/_app/immutable/chunks/CekH6JMP.js.br +0 -0
  259. package/build/client/_app/immutable/chunks/CekH6JMP.js.gz +0 -0
  260. package/build/client/_app/immutable/chunks/CqfYW08-.js +0 -1
  261. package/build/client/_app/immutable/chunks/CqfYW08-.js.br +0 -0
  262. package/build/client/_app/immutable/chunks/CqfYW08-.js.gz +0 -0
  263. package/build/client/_app/immutable/chunks/D1v6O410.js +0 -1
  264. package/build/client/_app/immutable/chunks/D1v6O410.js.br +0 -0
  265. package/build/client/_app/immutable/chunks/D1v6O410.js.gz +0 -0
  266. package/build/client/_app/immutable/chunks/DdnE6dyJ.js +0 -2
  267. package/build/client/_app/immutable/chunks/DdnE6dyJ.js.br +0 -0
  268. package/build/client/_app/immutable/chunks/DdnE6dyJ.js.gz +0 -0
  269. package/build/client/_app/immutable/chunks/DeieCYM0.js +0 -22
  270. package/build/client/_app/immutable/chunks/DeieCYM0.js.br +0 -0
  271. package/build/client/_app/immutable/chunks/DeieCYM0.js.gz +0 -0
  272. package/build/client/_app/immutable/chunks/DfUzlYF5.js +0 -1
  273. package/build/client/_app/immutable/chunks/DfUzlYF5.js.br +0 -0
  274. package/build/client/_app/immutable/chunks/DfUzlYF5.js.gz +0 -0
  275. package/build/client/_app/immutable/chunks/Dnk28BpG.js +0 -1
  276. package/build/client/_app/immutable/chunks/Dnk28BpG.js.br +0 -0
  277. package/build/client/_app/immutable/chunks/Dnk28BpG.js.gz +0 -0
  278. package/build/client/_app/immutable/chunks/DsnmJJEf.js +0 -1
  279. package/build/client/_app/immutable/chunks/DsnmJJEf.js.br +0 -2
  280. package/build/client/_app/immutable/chunks/DsnmJJEf.js.gz +0 -0
  281. package/build/client/_app/immutable/chunks/KNAS5R2A.js +0 -3
  282. package/build/client/_app/immutable/chunks/KNAS5R2A.js.br +0 -0
  283. package/build/client/_app/immutable/chunks/KNAS5R2A.js.gz +0 -0
  284. package/build/client/_app/immutable/chunks/eyJgPND9.js +0 -1
  285. package/build/client/_app/immutable/chunks/eyJgPND9.js.br +0 -1
  286. package/build/client/_app/immutable/chunks/eyJgPND9.js.gz +0 -0
  287. package/build/client/_app/immutable/entry/app.CPF6A_DV.js +0 -2
  288. package/build/client/_app/immutable/entry/app.CPF6A_DV.js.br +0 -0
  289. package/build/client/_app/immutable/entry/app.CPF6A_DV.js.gz +0 -0
  290. package/build/client/_app/immutable/entry/start.Dos_Ttds.js +0 -1
  291. package/build/client/_app/immutable/entry/start.Dos_Ttds.js.br +0 -2
  292. package/build/client/_app/immutable/entry/start.Dos_Ttds.js.gz +0 -0
  293. package/build/client/_app/immutable/nodes/0.C5HgTRfT.js +0 -1
  294. package/build/client/_app/immutable/nodes/0.C5HgTRfT.js.br +0 -0
  295. package/build/client/_app/immutable/nodes/0.C5HgTRfT.js.gz +0 -0
  296. package/build/client/_app/immutable/nodes/1.CGcgSoA9.js +0 -1
  297. package/build/client/_app/immutable/nodes/1.CGcgSoA9.js.br +0 -0
  298. package/build/client/_app/immutable/nodes/1.CGcgSoA9.js.gz +0 -0
  299. package/build/client/_app/immutable/nodes/10.ukScuXwz.js +0 -1
  300. package/build/client/_app/immutable/nodes/10.ukScuXwz.js.br +0 -5
  301. package/build/client/_app/immutable/nodes/10.ukScuXwz.js.gz +0 -0
  302. package/build/client/_app/immutable/nodes/11.D3RDNx7M.js +0 -1
  303. package/build/client/_app/immutable/nodes/11.D3RDNx7M.js.br +0 -0
  304. package/build/client/_app/immutable/nodes/11.D3RDNx7M.js.gz +0 -0
  305. package/build/client/_app/immutable/nodes/12._vvpCcSG.js +0 -1
  306. package/build/client/_app/immutable/nodes/12._vvpCcSG.js.br +0 -0
  307. package/build/client/_app/immutable/nodes/12._vvpCcSG.js.gz +0 -0
  308. package/build/client/_app/immutable/nodes/13.BWPzZMQ5.js +0 -1
  309. package/build/client/_app/immutable/nodes/13.BWPzZMQ5.js.br +0 -0
  310. package/build/client/_app/immutable/nodes/13.BWPzZMQ5.js.gz +0 -0
  311. package/build/client/_app/immutable/nodes/14.Cr843Lep.js +0 -1
  312. package/build/client/_app/immutable/nodes/14.Cr843Lep.js.br +0 -0
  313. package/build/client/_app/immutable/nodes/14.Cr843Lep.js.gz +0 -0
  314. package/build/client/_app/immutable/nodes/2.DUpwDjw8.js +0 -1
  315. package/build/client/_app/immutable/nodes/2.DUpwDjw8.js.br +0 -0
  316. package/build/client/_app/immutable/nodes/2.DUpwDjw8.js.gz +0 -0
  317. package/build/client/_app/immutable/nodes/3.DPH7xl7M.js +0 -1
  318. package/build/client/_app/immutable/nodes/3.DPH7xl7M.js.br +0 -0
  319. package/build/client/_app/immutable/nodes/3.DPH7xl7M.js.gz +0 -0
  320. package/build/client/_app/immutable/nodes/4.Bk0knTIK.js +0 -1
  321. package/build/client/_app/immutable/nodes/4.Bk0knTIK.js.br +0 -0
  322. package/build/client/_app/immutable/nodes/4.Bk0knTIK.js.gz +0 -0
  323. package/build/client/_app/immutable/nodes/5.DwnZ1Bh8.js +0 -1
  324. package/build/client/_app/immutable/nodes/5.DwnZ1Bh8.js.br +0 -0
  325. package/build/client/_app/immutable/nodes/5.DwnZ1Bh8.js.gz +0 -0
  326. package/build/client/_app/immutable/nodes/6.5U-KxFgt.js +0 -2
  327. package/build/client/_app/immutable/nodes/6.5U-KxFgt.js.br +0 -0
  328. package/build/client/_app/immutable/nodes/6.5U-KxFgt.js.gz +0 -0
  329. package/build/client/_app/immutable/nodes/7.DFc4sJix.js +0 -1
  330. package/build/client/_app/immutable/nodes/7.DFc4sJix.js.br +0 -0
  331. package/build/client/_app/immutable/nodes/7.DFc4sJix.js.gz +0 -0
  332. package/build/client/_app/immutable/nodes/8.BG4bv5P5.js +0 -1
  333. package/build/client/_app/immutable/nodes/8.BG4bv5P5.js.br +0 -0
  334. package/build/client/_app/immutable/nodes/8.BG4bv5P5.js.gz +0 -0
  335. package/build/client/_app/immutable/nodes/9.BKljyhOi.js +0 -1
  336. package/build/client/_app/immutable/nodes/9.BKljyhOi.js.br +0 -0
  337. package/build/client/_app/immutable/nodes/9.BKljyhOi.js.gz +0 -0
  338. package/build/server/chunks/0-CZBaNtSI.js.map +0 -1
  339. package/build/server/chunks/1-D_3BtEbe.js +0 -9
  340. package/build/server/chunks/1-D_3BtEbe.js.map +0 -1
  341. package/build/server/chunks/10-CLkNMKHU.js +0 -13
  342. package/build/server/chunks/10-CLkNMKHU.js.map +0 -1
  343. package/build/server/chunks/11-5xPYR_1w.js +0 -13
  344. package/build/server/chunks/11-5xPYR_1w.js.map +0 -1
  345. package/build/server/chunks/12-N7UaQj7u.js +0 -9
  346. package/build/server/chunks/12-N7UaQj7u.js.map +0 -1
  347. package/build/server/chunks/13-QYVLpXli.js +0 -9
  348. package/build/server/chunks/13-QYVLpXli.js.map +0 -1
  349. package/build/server/chunks/14-CPY578rT.js +0 -9
  350. package/build/server/chunks/14-CPY578rT.js.map +0 -1
  351. package/build/server/chunks/2-_1jFrcvz.js +0 -13
  352. package/build/server/chunks/2-_1jFrcvz.js.map +0 -1
  353. package/build/server/chunks/4-CcxCcH4F.js +0 -13
  354. package/build/server/chunks/4-CcxCcH4F.js.map +0 -1
  355. package/build/server/chunks/5-CrlH6VoB.js +0 -13
  356. package/build/server/chunks/5-CrlH6VoB.js.map +0 -1
  357. package/build/server/chunks/6-FkP678Uz.js +0 -13
  358. package/build/server/chunks/6-FkP678Uz.js.map +0 -1
  359. package/build/server/chunks/7-B1iCe7VA.js +0 -13
  360. package/build/server/chunks/7-B1iCe7VA.js.map +0 -1
  361. package/build/server/chunks/8-p6n9G-P_.js +0 -13
  362. package/build/server/chunks/8-p6n9G-P_.js.map +0 -1
  363. package/build/server/chunks/9-fc3lKB7X.js +0 -13
  364. package/build/server/chunks/9-fc3lKB7X.js.map +0 -1
  365. package/build/server/chunks/_layout.svelte-9KMUotip.js.map +0 -1
  366. package/build/server/chunks/_page.svelte-BD3HmLo_.js.map +0 -1
  367. package/build/server/chunks/_page.svelte-BFzPdJ6z.js.map +0 -1
  368. package/build/server/chunks/_page.svelte-BIxxuzff.js.map +0 -1
  369. package/build/server/chunks/_page.svelte-Bou2_u6i.js +0 -13
  370. package/build/server/chunks/_page.svelte-C25oQ2NT.js.map +0 -1
  371. package/build/server/chunks/_page.svelte-CAzWL4aq.js.map +0 -1
  372. package/build/server/chunks/_page.svelte-Ci5V-DhL.js.map +0 -1
  373. package/build/server/chunks/_page.svelte-CnfRSJsl.js.map +0 -1
  374. package/build/server/chunks/_page.svelte-DgyZKeaF.js.map +0 -1
  375. package/build/server/chunks/_page.svelte-cAsZlwLs.js.map +0 -1
  376. package/build/server/chunks/_page.svelte-rrN2zFNa.js.map +0 -1
  377. package/build/server/chunks/error.svelte-DTrQqomO.js.map +0 -1
  378. package/build/server/chunks/index-DJrm8BZm.js.map +0 -1
  379. package/build/server/chunks/index-eKiDBuyI.js.map +0 -1
  380. package/build/server/chunks/user2-Coq3Frtw.js.map +0 -1
  381. package/build/server/chunks/utils-DlBYhQz7.js.map +0 -1
  382. package/dist/apps.d.ts +0 -6
  383. package/dist/apps.js +0 -6
  384. package/dist/plugins.d.ts +0 -14
  385. package/dist/plugins.js +0 -64
  386. /package/{axiumd.service → axium.service} +0 -0
package/dist/cli.js CHANGED
@@ -51,11 +51,12 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
51
51
  var e = new Error(message);
52
52
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
53
53
  });
54
- import { AuditFilter } from '@axium/core/audit';
55
- import { severityNames } from '@axium/core/audit';
54
+ import { apps } from '@axium/core';
55
+ import { AuditFilter, severityNames } from '@axium/core/audit';
56
56
  import { formatDateRange } from '@axium/core/format';
57
+ import { outputDaemonStatus, io, pluginText } from '@axium/core/node';
58
+ import { _findPlugin, plugins } from '@axium/core/plugins';
57
59
  import { Argument, Option, program } from 'commander';
58
- import { spawnSync } from 'node:child_process';
59
60
  import { access } from 'node:fs/promises';
60
61
  import { join, resolve } from 'node:path/posix';
61
62
  import { createInterface } from 'node:readline/promises';
@@ -63,323 +64,21 @@ import { styleText } from 'node:util';
63
64
  import { getByString, isJSON, setByString } from 'utilium';
64
65
  import * as z from 'zod';
65
66
  import $pkg from '../package.json' with { type: 'json' };
66
- import { apps } from './apps.js';
67
67
  import { audit, getEvents, styleSeverity } from './audit.js';
68
68
  import config, { configFiles, FileSchema, saveConfigTo } from './config.js';
69
69
  import * as db from './database.js';
70
- import * as io from './io.js';
70
+ import { _portActions, _portMethods, restrictedPorts, systemDir } from './io.js';
71
71
  import { linkRoutes, listRouteLinks, unlinkRoutes } from './linking.js';
72
- import { plugins, pluginText } from './plugins.js';
73
72
  import { serve } from './serve.js';
74
- function readline() {
75
- const rl = createInterface({
76
- input: process.stdin,
77
- output: process.stdout,
78
- });
79
- return Object.assign(rl, {
80
- [Symbol.dispose]: rl.close.bind(rl),
81
- });
82
- }
83
73
  function userText(user, bold = false) {
84
74
  const text = `${user.name} <${user.email}> (${user.id})`;
85
75
  return bold ? styleText('bold', text) : text;
86
76
  }
87
- let safe = false;
88
- program
89
- .version($pkg.version)
90
- .name('axium')
91
- .description('Axium server CLI')
92
- .configureHelp({ showGlobalOptions: true })
93
- .option('--safe', 'do not execute code from plugins')
94
- .option('--debug', 'override debug mode')
95
- .option('--no-debug', 'override debug mode')
96
- .option('-c, --config <path>', 'path to the config file');
97
- program.on('option:safe', () => (safe = true));
98
- program.on('option:debug', () => config.set({ debug: true }));
99
- program.on('option:config', () => void config.load(program.opts().config, { safe }));
100
- const noAutoDB = ['init', 'serve', 'check'];
101
- program.hook('preAction', async function (_, action) {
102
- await config.loadDefaults(safe);
103
- const opt = action.optsWithGlobals();
104
- opt.force && io.output.warn('--force: Protections disabled.');
105
- if (typeof opt.debug == 'boolean') {
106
- config.set({ debug: opt.debug });
107
- io._setDebugOutput(opt.debug);
108
- }
109
- try {
110
- db.connect();
111
- }
112
- catch (e) {
113
- if (!noAutoDB.includes(action.name()))
114
- throw e;
115
- }
116
- });
117
- program.hook('postAction', async (_, action) => {
118
- if (!noAutoDB.includes(action.name()))
119
- await db.database.destroy();
120
- });
121
- // Options shared by multiple (sub)commands
122
- const opts = {
123
- // database specific
124
- host: new Option('-H, --host <host>', 'the host of the database.').argParser(value => {
125
- const [hostname, port] = value?.split(':') ?? [];
126
- config.db.host = hostname || config.db.host;
127
- config.db.port = port && Number.isSafeInteger(parseInt(port)) ? parseInt(port) : config.db.port;
128
- }),
129
- check: new Option('--check', 'check the database schema after initialization').default(false),
130
- force: new Option('-f, --force', 'force the operation').default(false),
131
- global: new Option('-g, --global', 'apply the operation globally').default(false),
132
- timeout: new Option('-t, --timeout <ms>', 'how long to wait for commands to complete.').default('1000').argParser(value => {
133
- const timeout = parseInt(value);
134
- if (!Number.isSafeInteger(timeout) || timeout < 0)
135
- io.warn('Invalid timeout value, using default.');
136
- io.setCommandTimeout(timeout);
137
- }),
138
- packagesDir: new Option('-p, --packages-dir <dir>', 'the directory to look for packages in'),
139
- };
140
- const axiumDB = program.command('db').alias('database').description('Manage the database').addOption(opts.timeout).addOption(opts.host);
141
- axiumDB
142
- .command('init')
143
- .description('Initialize the database')
144
- .addOption(opts.force)
145
- .option('-s, --skip', 'If the user, database, or schema already exists, skip trying to create it.')
146
- .addOption(opts.check)
147
- .action(async (_localOpts, _) => {
148
- const opt = _.optsWithGlobals();
149
- await db.init(opt).catch(io.handleError);
150
- });
151
- axiumDB
152
- .command('status')
153
- .alias('stats')
154
- .description('Check the status of the database')
155
- .action(async () => {
156
- try {
157
- console.log(await db.statText());
158
- }
159
- catch {
160
- io.output.error('Unavailable');
161
- process.exitCode = 1;
162
- }
163
- });
164
- axiumDB
165
- .command('drop')
166
- .description('Drop the Axium database and user')
167
- .addOption(opts.force)
168
- .action(async (opt) => {
169
- const stats = await db.count('users', 'passkeys', 'sessions').catch(io.exit);
170
- if (!opt.force)
171
- for (const key of ['users', 'passkeys', 'sessions']) {
172
- if (stats[key] == 0)
173
- continue;
174
- io.output.warn(`Database has existing ${key}. Use --force if you really want to drop the database.`);
175
- process.exit(2);
176
- }
177
- await db.uninstall(opt).catch(io.exit);
178
- });
179
- axiumDB
180
- .command('wipe')
181
- .description('Wipe the database')
182
- .addOption(opts.force)
183
- .action(async (opt) => {
184
- const stats = await db.count('users', 'passkeys', 'sessions').catch(io.exit);
185
- if (!opt.force)
186
- for (const key of ['users', 'passkeys', 'sessions']) {
187
- if (stats[key] == 0)
188
- continue;
189
- io.output.warn(`Database has existing ${key}. Use --force if you really want to wipe the database.`);
190
- process.exit(2);
191
- }
192
- await db.wipe(opt).catch(io.exit);
193
- });
194
- axiumDB
195
- .command('check')
196
- .description('Check the structure of the database')
197
- .option('-s, --strict', 'Throw errors instead of emitting warnings for most column problems')
198
- .action(async (opt) => {
199
- await db.check(opt).catch(io.exit);
200
- });
201
- axiumDB
202
- .command('clean')
203
- .description('Remove expired rows')
204
- .addOption(opts.force)
205
- .action(async (opt) => {
206
- await db.clean(opt).catch(io.exit);
207
- });
208
- axiumDB
209
- .command('rotate-password')
210
- .description('Generate a new password for the database user and update the config')
211
- .action(db.rotatePassword);
212
- const axiumConfig = program
213
- .command('config')
214
- .description('Manage the configuration')
215
- .addOption(opts.global)
216
- .option('-j, --json', 'values are JSON encoded')
217
- .option('-r, --redact', 'Do not output sensitive values');
218
77
  function configReplacer(opt) {
219
78
  return (key, value) => {
220
79
  return opt.redact && ['password', 'secret'].includes(key) ? '[redacted]' : value;
221
80
  };
222
81
  }
223
- axiumConfig
224
- .command('dump')
225
- .description('Output the entire current configuration')
226
- .action(() => {
227
- const opt = axiumConfig.optsWithGlobals();
228
- const value = config.plain();
229
- console.log(opt.json ? JSON.stringify(value, configReplacer(opt), 4) : value);
230
- });
231
- axiumConfig
232
- .command('get')
233
- .description('Get a config value')
234
- .argument('<key>', 'the key to get')
235
- .action((key) => {
236
- const opt = axiumConfig.optsWithGlobals();
237
- const value = getByString(config.plain(), key);
238
- console.log(opt.json ? JSON.stringify(value, configReplacer(opt), 4) : value);
239
- });
240
- axiumConfig
241
- .command('set')
242
- .description('Set a config value. Note setting objects is not supported.')
243
- .argument('<key>', 'the key to set')
244
- .argument('<value>', 'the value')
245
- .action((key, value) => {
246
- const opt = axiumConfig.optsWithGlobals();
247
- if (opt.json && !isJSON(value))
248
- io.exit('Invalid JSON');
249
- const obj = {};
250
- setByString(obj, key, opt.json ? JSON.parse(value) : value);
251
- config.save(obj, opt.global);
252
- });
253
- axiumConfig
254
- .command('list')
255
- .alias('ls')
256
- .alias('files')
257
- .description('List loaded config files')
258
- .action(() => {
259
- for (const path of config.files.keys())
260
- console.log(path);
261
- });
262
- axiumConfig
263
- .command('schema')
264
- .description('Get the JSON schema for the configuration file')
265
- .action(() => {
266
- const opt = axiumConfig.optsWithGlobals();
267
- const schema = z.toJSONSchema(FileSchema, { io: 'input' });
268
- console.log(opt.json ? JSON.stringify(schema, configReplacer(opt), 4) : schema);
269
- });
270
- const axiumPlugin = program.command('plugin').alias('plugins').description('Manage plugins').addOption(opts.global);
271
- axiumPlugin
272
- .command('list')
273
- .alias('ls')
274
- .description('List loaded plugins')
275
- .option('-l, --long', 'use the long listing format')
276
- .option('--no-versions', 'do not show plugin versions')
277
- .action((opt) => {
278
- if (!plugins.size) {
279
- console.log('No plugins loaded.');
280
- return;
281
- }
282
- if (!opt.long) {
283
- console.log(Array.from(plugins.keys()).join(', '));
284
- return;
285
- }
286
- console.log(styleText('whiteBright', plugins.size + ' plugin(s) loaded:'));
287
- for (const plugin of plugins.values()) {
288
- console.log(plugin.name, opt.versions ? plugin.version : '');
289
- }
290
- });
291
- function _findPlugin(search) {
292
- const plugin = plugins.get(search) ?? plugins.values().find(p => p.specifier.toLowerCase() == search.toLowerCase());
293
- if (!plugin)
294
- io.exit(`Can't find a plugin matching "${search}"`);
295
- return plugin;
296
- }
297
- axiumPlugin
298
- .command('info')
299
- .description('Get information about a plugin')
300
- .argument('<plugin>', 'the plugin to get information about')
301
- .action((search) => {
302
- const plugin = _findPlugin(search);
303
- console.log(pluginText(plugin));
304
- });
305
- axiumPlugin
306
- .command('remove')
307
- .alias('rm')
308
- .description('Remove a plugin')
309
- .argument('<plugin>', 'the plugin to remove')
310
- .action(async (search, opt) => {
311
- const plugin = _findPlugin(search);
312
- await plugin._hooks?.remove?.(opt);
313
- for (const [path, data] of configFiles) {
314
- if (!data.plugins)
315
- continue;
316
- data.plugins = data.plugins.filter(p => p !== plugin.specifier);
317
- saveConfigTo(path, data);
318
- }
319
- plugins.delete(plugin.name);
320
- });
321
- axiumPlugin
322
- .command('init')
323
- .alias('setup')
324
- .alias('install')
325
- .description('Initialize a plugin. This could include adding tables to the database or linking routes.')
326
- .addOption(opts.timeout)
327
- .addOption(opts.check)
328
- .argument('<plugin>', 'the plugin to initialize')
329
- .action(async (search, opt) => {
330
- const env_1 = { stack: [], error: void 0, hasError: false };
331
- try {
332
- const plugin = _findPlugin(search);
333
- if (!plugin)
334
- io.exit(`Can't find a plugin matching "${search}"`);
335
- const _ = __addDisposableResource(env_1, db.connect(), true);
336
- await plugin._hooks?.db_init?.({ force: false, ...opt, skip: true });
337
- }
338
- catch (e_1) {
339
- env_1.error = e_1;
340
- env_1.hasError = true;
341
- }
342
- finally {
343
- const result_1 = __disposeResources(env_1);
344
- if (result_1)
345
- await result_1;
346
- }
347
- });
348
- const axiumApps = program.command('apps').description('Manage Axium apps').addOption(opts.global);
349
- axiumApps
350
- .command('list')
351
- .alias('ls')
352
- .description('List apps added by plugins')
353
- .option('-l, --long', 'use the long listing format')
354
- .option('-b, --builtin', 'include built-in apps')
355
- .action((opt) => {
356
- if (!apps.size) {
357
- console.log('No apps.');
358
- return;
359
- }
360
- if (!opt.long) {
361
- console.log(Array.from(apps.values().map(app => app.name)).join(', '));
362
- return;
363
- }
364
- console.log(styleText('whiteBright', apps.size + ' app(s) loaded:'));
365
- for (const app of apps.values()) {
366
- console.log(app.name, styleText('dim', `(${app.id})`));
367
- }
368
- });
369
- const lookup = new Argument('<user>', 'the UUID or email of the user to operate on').argParser(async (lookup) => {
370
- const value = await (lookup.includes('@') ? z.email() : z.uuid())
371
- .parseAsync(lookup.toLowerCase())
372
- .catch(() => io.exit('Invalid user ID or email.'));
373
- const result = await db
374
- .connect()
375
- .selectFrom('users')
376
- .where(value.includes('@') ? 'email' : 'id', '=', value)
377
- .selectAll()
378
- .executeTakeFirst();
379
- if (!result)
380
- io.exit('No user with matching ID or email.');
381
- return result;
382
- });
383
82
  /**
384
83
  * Updates an array of strings by adding or removing items.
385
84
  * Only returns whether the array was updated and diff text for what actually changed.
@@ -404,45 +103,335 @@ function diffUpdate(original, add, remove) {
404
103
  });
405
104
  return [!!diffs.length, original, diffs.join(', ')];
406
105
  }
407
- program
408
- .command('user')
409
- .description('Get or change information about a user')
410
- .addArgument(lookup)
411
- .option('-S, --sessions', 'show user sessions')
412
- .option('-P, --passkeys', 'show user passkeys')
413
- .option('--add-role <role...>', 'add roles to the user')
414
- .option('--remove-role <role...>', 'remove roles from the user')
415
- .option('--tag <tag...>', 'Add tags to the user')
416
- .option('--untag <tag...>', 'Remove tags from the user')
417
- .option('--delete', 'Delete the user')
418
- .option('--suspend', 'Suspend the user')
419
- .addOption(new Option('--unsuspend', 'Un-suspend the user').conflicts('suspend'))
420
- .action(async (_user, opt) => {
421
- let user = await _user;
422
- const [updatedRoles, roles, rolesDiff] = diffUpdate(user.roles, opt.addRole, opt.removeRole);
423
- const [updatedTags, tags, tagsDiff] = diffUpdate(user.tags, opt.tag, opt.untag);
424
- const changeSuspend = (opt.suspend || opt.unsuspend) && user.isSuspended != (opt.suspend ?? !opt.unsuspend);
425
- if (updatedRoles || updatedTags || changeSuspend) {
426
- user = await db.database
427
- .updateTable('users')
428
- .set({ roles, tags, isSuspended: !changeSuspend ? user.isSuspended : (opt.suspend ?? !opt.unsuspend) })
429
- .returningAll()
430
- .executeTakeFirstOrThrow()
431
- .then(u => {
432
- if (updatedRoles && rolesDiff)
433
- console.log(`> Updated roles: ${rolesDiff}`);
434
- if (updatedTags && tagsDiff)
435
- console.log(`> Updated tags: ${tagsDiff}`);
436
- if (changeSuspend)
437
- console.log(opt.suspend ? '> Suspended' : '> Un-suspended');
438
- return u;
439
- })
440
- .catch(e => io.exit('Failed to update user: ' + e.message));
441
- }
442
- if (opt.delete) {
106
+ var rl, safe, noAutoDB, opts, axiumDB, axiumConfig, axiumPlugin, axiumApps, lookup;
107
+ const env_1 = { stack: [], error: void 0, hasError: false };
108
+ try {
109
+ rl = __addDisposableResource(env_1, createInterface({
110
+ input: process.stdin,
111
+ output: process.stdout,
112
+ }), false);
113
+ safe = z.stringbool().default(false).parse(process.env.SAFE?.toLowerCase()) || process.argv.includes('--safe');
114
+ await config.load(join(systemDir, 'config.json'), { safe });
115
+ program
116
+ .version($pkg.version)
117
+ .name('axium')
118
+ .description('Axium server CLI')
119
+ .configureHelp({ showGlobalOptions: true })
120
+ .option('--safe', 'do not execute code from plugins')
121
+ .option('--debug', 'override debug mode')
122
+ .option('--no-debug', 'override debug mode')
123
+ .option('-c, --config <path>', 'path to the config file');
124
+ program.on('option:debug', () => config.set({ debug: true }));
125
+ program.on('option:config', () => void config.load(program.opts().config, { safe }));
126
+ noAutoDB = ['init', 'serve', 'check'];
127
+ program.hook('preAction', async function (_, action) {
128
+ await config.loadDefaults(safe);
129
+ const opt = action.optsWithGlobals();
130
+ opt.force && io.warn('--force: Protections disabled.');
131
+ if (typeof opt.debug == 'boolean') {
132
+ config.set({ debug: opt.debug });
133
+ io._setDebugOutput(opt.debug);
134
+ }
135
+ try {
136
+ db.connect();
137
+ }
138
+ catch (e) {
139
+ if (!noAutoDB.includes(action.name()))
140
+ throw e;
141
+ }
142
+ });
143
+ program.hook('postAction', async (_, action) => {
144
+ if (!noAutoDB.includes(action.name()))
145
+ await db.database.destroy();
146
+ });
147
+ // Options shared by multiple (sub)commands
148
+ opts = {
149
+ // database specific
150
+ host: new Option('-H, --host <host>', 'the host of the database.').argParser(value => {
151
+ const [hostname, port] = value?.split(':') ?? [];
152
+ config.db.host = hostname || config.db.host;
153
+ config.db.port = port && Number.isSafeInteger(parseInt(port)) ? parseInt(port) : config.db.port;
154
+ }),
155
+ check: new Option('--check', 'check the database schema after initialization').default(false),
156
+ force: new Option('-f, --force', 'force the operation').default(false),
157
+ global: new Option('-g, --global', 'apply the operation globally').default(false),
158
+ timeout: new Option('-t, --timeout <ms>', 'how long to wait for commands to complete.').default('1000').argParser(value => {
159
+ const timeout = parseInt(value);
160
+ if (!Number.isSafeInteger(timeout) || timeout < 0)
161
+ io.warn('Invalid timeout value, using default.');
162
+ io.setCommandTimeout(timeout);
163
+ }),
164
+ packagesDir: new Option('-p, --packages-dir <dir>', 'the directory to look for packages in'),
165
+ };
166
+ axiumDB = program.command('db').alias('database').description('Manage the database').addOption(opts.timeout).addOption(opts.host);
167
+ axiumDB
168
+ .command('init')
169
+ .description('Initialize the database')
170
+ .addOption(opts.force)
171
+ .option('-s, --skip', 'If the user, database, or schema already exists, skip trying to create it.')
172
+ .addOption(opts.check)
173
+ .action(async (_localOpts, _) => {
174
+ const opt = _.optsWithGlobals();
175
+ await db.init(opt).catch(io.handleError);
176
+ });
177
+ axiumDB
178
+ .command('status')
179
+ .alias('stats')
180
+ .description('Check the status of the database')
181
+ .action(async () => {
182
+ try {
183
+ console.log(await db.statText());
184
+ }
185
+ catch {
186
+ io.error('Unavailable');
187
+ process.exitCode = 1;
188
+ }
189
+ });
190
+ axiumDB
191
+ .command('drop')
192
+ .description('Drop the Axium database and user')
193
+ .addOption(opts.force)
194
+ .action(async (opt) => {
195
+ const stats = await db.count('users', 'passkeys', 'sessions').catch(io.exit);
196
+ if (!opt.force)
197
+ for (const key of ['users', 'passkeys', 'sessions']) {
198
+ if (stats[key] == 0)
199
+ continue;
200
+ io.warn(`Database has existing ${key}. Use --force if you really want to drop the database.`);
201
+ process.exit(2);
202
+ }
203
+ await db.uninstall(opt).catch(io.exit);
204
+ });
205
+ axiumDB
206
+ .command('wipe')
207
+ .description('Wipe the database')
208
+ .addOption(opts.force)
209
+ .action(async (opt) => {
210
+ const stats = await db.count('users', 'passkeys', 'sessions').catch(io.exit);
211
+ if (!opt.force)
212
+ for (const key of ['users', 'passkeys', 'sessions']) {
213
+ if (stats[key] == 0)
214
+ continue;
215
+ io.warn(`Database has existing ${key}. Use --force if you really want to wipe the database.`);
216
+ process.exit(2);
217
+ }
218
+ await db.wipe(opt).catch(io.exit);
219
+ });
220
+ axiumDB
221
+ .command('check')
222
+ .description('Check the structure of the database')
223
+ .option('-s, --strict', 'Throw errors instead of emitting warnings for most column problems')
224
+ .action(async (opt) => {
225
+ await db.check(opt).catch(io.exit);
226
+ });
227
+ axiumDB
228
+ .command('clean')
229
+ .description('Remove expired rows')
230
+ .addOption(opts.force)
231
+ .action(async (opt) => {
232
+ await db.clean(opt).catch(io.exit);
233
+ });
234
+ axiumDB
235
+ .command('rotate-password')
236
+ .description('Generate a new password for the database user and update the config')
237
+ .action(db.rotatePassword);
238
+ axiumConfig = program
239
+ .command('config')
240
+ .description('Manage the configuration')
241
+ .addOption(opts.global)
242
+ .option('-j, --json', 'values are JSON encoded')
243
+ .option('-r, --redact', 'Do not output sensitive values');
244
+ axiumConfig
245
+ .command('dump')
246
+ .description('Output the entire current configuration')
247
+ .action(() => {
248
+ const opt = axiumConfig.optsWithGlobals();
249
+ const value = config.plain();
250
+ console.log(opt.json ? JSON.stringify(value, configReplacer(opt), 4) : value);
251
+ });
252
+ axiumConfig
253
+ .command('get')
254
+ .description('Get a config value')
255
+ .argument('<key>', 'the key to get')
256
+ .action((key) => {
257
+ const opt = axiumConfig.optsWithGlobals();
258
+ const value = getByString(config.plain(), key);
259
+ console.log(opt.json ? JSON.stringify(value, configReplacer(opt), 4) : value);
260
+ });
261
+ axiumConfig
262
+ .command('set')
263
+ .description('Set a config value. Note setting objects is not supported.')
264
+ .argument('<key>', 'the key to set')
265
+ .argument('<value>', 'the value')
266
+ .action((key, value) => {
267
+ const opt = axiumConfig.optsWithGlobals();
268
+ if (opt.json && !isJSON(value))
269
+ io.exit('Invalid JSON');
270
+ const obj = {};
271
+ setByString(obj, key, opt.json ? JSON.parse(value) : value);
272
+ config.save(obj, opt.global);
273
+ });
274
+ axiumConfig
275
+ .command('list')
276
+ .alias('ls')
277
+ .alias('files')
278
+ .description('List loaded config files')
279
+ .action(() => {
280
+ for (const path of config.files.keys())
281
+ console.log(path);
282
+ });
283
+ axiumConfig
284
+ .command('schema')
285
+ .description('Get the JSON schema for the configuration file')
286
+ .action(() => {
287
+ const opt = axiumConfig.optsWithGlobals();
288
+ const schema = z.toJSONSchema(FileSchema, { io: 'input' });
289
+ console.log(opt.json ? JSON.stringify(schema, configReplacer(opt), 4) : schema);
290
+ });
291
+ axiumPlugin = program.command('plugin').alias('plugins').description('Manage plugins').addOption(opts.global);
292
+ axiumPlugin
293
+ .command('list')
294
+ .alias('ls')
295
+ .description('List loaded plugins')
296
+ .option('-l, --long', 'use the long listing format')
297
+ .option('--no-versions', 'do not show plugin versions')
298
+ .action((opt) => {
299
+ if (!plugins.size) {
300
+ console.log('No plugins loaded.');
301
+ return;
302
+ }
303
+ if (!opt.long) {
304
+ console.log(Array.from(plugins.keys()).join(', '));
305
+ return;
306
+ }
307
+ console.log(styleText('whiteBright', plugins.size + ' plugin(s) loaded:'));
308
+ for (const plugin of plugins.values()) {
309
+ console.log(plugin.name, opt.versions ? plugin.version : '');
310
+ }
311
+ });
312
+ axiumPlugin
313
+ .command('info')
314
+ .description('Get information about a plugin')
315
+ .argument('<plugin>', 'the plugin to get information about')
316
+ .action((search) => {
317
+ const plugin = _findPlugin(search);
318
+ for (const line of pluginText(plugin))
319
+ console.log(line);
320
+ });
321
+ axiumPlugin
322
+ .command('remove')
323
+ .alias('rm')
324
+ .description('Remove a plugin')
325
+ .argument('<plugin>', 'the plugin to remove')
326
+ .action(async (search, opt) => {
327
+ const plugin = _findPlugin(search);
328
+ await plugin._hooks?.remove?.(opt);
329
+ for (const [path, data] of configFiles) {
330
+ if (!data.plugins)
331
+ continue;
332
+ data.plugins = data.plugins.filter(p => p !== plugin.specifier);
333
+ saveConfigTo(path, data);
334
+ }
335
+ plugins.delete(plugin.name);
336
+ });
337
+ axiumPlugin
338
+ .command('init')
339
+ .alias('setup')
340
+ .alias('install')
341
+ .description('Initialize a plugin. This could include adding tables to the database or linking routes.')
342
+ .addOption(opts.timeout)
343
+ .addOption(opts.check)
344
+ .argument('<plugin>', 'the plugin to initialize')
345
+ .action(async (search, opt) => {
443
346
  const env_2 = { stack: [], error: void 0, hasError: false };
444
347
  try {
445
- const rl = __addDisposableResource(env_2, readline(), false);
348
+ const plugin = _findPlugin(search);
349
+ if (!plugin)
350
+ io.exit(`Can't find a plugin matching "${search}"`);
351
+ const _ = __addDisposableResource(env_2, db.connect(), true);
352
+ await plugin._hooks?.db_init?.({ force: false, ...opt, skip: true });
353
+ }
354
+ catch (e_2) {
355
+ env_2.error = e_2;
356
+ env_2.hasError = true;
357
+ }
358
+ finally {
359
+ const result_1 = __disposeResources(env_2);
360
+ if (result_1)
361
+ await result_1;
362
+ }
363
+ });
364
+ axiumApps = program.command('apps').description('Manage Axium apps').addOption(opts.global);
365
+ axiumApps
366
+ .command('list')
367
+ .alias('ls')
368
+ .description('List apps added by plugins')
369
+ .option('-l, --long', 'use the long listing format')
370
+ .option('-b, --builtin', 'include built-in apps')
371
+ .action((opt) => {
372
+ if (!apps.size) {
373
+ console.log('No apps.');
374
+ return;
375
+ }
376
+ if (!opt.long) {
377
+ console.log(Array.from(apps.values().map(app => app.name)).join(', '));
378
+ return;
379
+ }
380
+ console.log(styleText('whiteBright', apps.size + ' app(s) loaded:'));
381
+ for (const app of apps.values()) {
382
+ console.log(app.name, styleText('dim', `(${app.id})`));
383
+ }
384
+ });
385
+ lookup = new Argument('<user>', 'the UUID or email of the user to operate on').argParser(async (lookup) => {
386
+ const value = await (lookup.includes('@') ? z.email() : z.uuid())
387
+ .parseAsync(lookup.toLowerCase())
388
+ .catch(() => io.exit('Invalid user ID or email.'));
389
+ const result = await db
390
+ .connect()
391
+ .selectFrom('users')
392
+ .where(value.includes('@') ? 'email' : 'id', '=', value)
393
+ .selectAll()
394
+ .executeTakeFirst();
395
+ if (!result)
396
+ io.exit('No user with matching ID or email.');
397
+ return result;
398
+ });
399
+ program
400
+ .command('user')
401
+ .description('Get or change information about a user')
402
+ .addArgument(lookup)
403
+ .option('-S, --sessions', 'show user sessions')
404
+ .option('-P, --passkeys', 'show user passkeys')
405
+ .option('--add-role <role...>', 'add roles to the user')
406
+ .option('--remove-role <role...>', 'remove roles from the user')
407
+ .option('--tag <tag...>', 'Add tags to the user')
408
+ .option('--untag <tag...>', 'Remove tags from the user')
409
+ .option('--delete', 'Delete the user')
410
+ .option('--suspend', 'Suspend the user')
411
+ .addOption(new Option('--unsuspend', 'Un-suspend the user').conflicts('suspend'))
412
+ .action(async (_user, opt) => {
413
+ let user = await _user;
414
+ const [updatedRoles, roles, rolesDiff] = diffUpdate(user.roles, opt.addRole, opt.removeRole);
415
+ const [updatedTags, tags, tagsDiff] = diffUpdate(user.tags, opt.tag, opt.untag);
416
+ const changeSuspend = (opt.suspend || opt.unsuspend) && user.isSuspended != (opt.suspend ?? !opt.unsuspend);
417
+ if (updatedRoles || updatedTags || changeSuspend) {
418
+ user = await db.database
419
+ .updateTable('users')
420
+ .set({ roles, tags, isSuspended: !changeSuspend ? user.isSuspended : (opt.suspend ?? !opt.unsuspend) })
421
+ .returningAll()
422
+ .executeTakeFirstOrThrow()
423
+ .then(u => {
424
+ if (updatedRoles && rolesDiff)
425
+ console.log(`> Updated roles: ${rolesDiff}`);
426
+ if (updatedTags && tagsDiff)
427
+ console.log(`> Updated tags: ${tagsDiff}`);
428
+ if (changeSuspend)
429
+ console.log(opt.suspend ? '> Suspended' : '> Un-suspended');
430
+ return u;
431
+ })
432
+ .catch(e => io.exit('Failed to update user: ' + e.message));
433
+ }
434
+ if (opt.delete) {
446
435
  const confirmed = await rl
447
436
  .question(`Are you sure you want to delete ${userText(user, true)}? (y/N) `)
448
437
  .then(v => z.stringbool().parseAsync(v))
@@ -457,208 +446,189 @@ program
457
446
  .then(() => console.log(styleText(['red', 'bold'], '> Deleted')))
458
447
  .catch(e => io.exit('Failed to delete user: ' + e.message));
459
448
  }
460
- catch (e_2) {
461
- env_2.error = e_2;
462
- env_2.hasError = true;
463
- }
464
- finally {
465
- __disposeResources(env_2);
449
+ console.log([
450
+ user.isSuspended && styleText('yellowBright', 'Suspended'),
451
+ user.isAdmin && styleText('redBright', 'Administrator'),
452
+ 'UUID: ' + user.id,
453
+ 'Name: ' + user.name,
454
+ `Email: ${user.email}, ${user.emailVerified ? 'verified on ' + formatDateRange(user.emailVerified) : styleText(config.auth.email_verification ? 'yellow' : 'dim', 'not verified')}`,
455
+ 'Registered ' + formatDateRange(user.registeredAt),
456
+ `Roles: ${user.roles.length ? user.roles.join(', ') : styleText('dim', '(none)')}`,
457
+ `Tags: ${user.tags.length ? user.tags.join(', ') : styleText('dim', '(none)')}`,
458
+ ]
459
+ .filter(v => v)
460
+ .join('\n'));
461
+ if (opt.sessions) {
462
+ const sessions = await db.database.selectFrom('sessions').where('userId', '=', user.id).selectAll().execute();
463
+ console.log(styleText('bold', 'Sessions:'));
464
+ if (!sessions.length)
465
+ console.log(styleText('dim', '(none)'));
466
+ else
467
+ for (const session of sessions) {
468
+ console.log(`\t${session.id}\tcreated ${formatDateRange(session.created).padEnd(40)}\texpires ${formatDateRange(session.expires).padEnd(40)}\t${session.elevated ? styleText('yellow', '(elevated)') : ''}`);
469
+ }
466
470
  }
467
- }
468
- console.log([
469
- user.isSuspended && styleText('yellowBright', 'Suspended'),
470
- user.isAdmin && styleText('redBright', 'Administrator'),
471
- 'UUID: ' + user.id,
472
- 'Name: ' + user.name,
473
- `Email: ${user.email}, ${user.emailVerified ? 'verified on ' + formatDateRange(user.emailVerified) : styleText(config.auth.email_verification ? 'yellow' : 'dim', 'not verified')}`,
474
- 'Registered ' + formatDateRange(user.registeredAt),
475
- `Roles: ${user.roles.length ? user.roles.join(', ') : styleText('dim', '(none)')}`,
476
- `Tags: ${user.tags.length ? user.tags.join(', ') : styleText('dim', '(none)')}`,
477
- ]
478
- .filter(v => v)
479
- .join('\n'));
480
- if (opt.sessions) {
481
- const sessions = await db.database.selectFrom('sessions').where('userId', '=', user.id).selectAll().execute();
482
- console.log(styleText('bold', 'Sessions:'));
483
- if (!sessions.length)
484
- console.log(styleText('dim', '(none)'));
485
- else
486
- for (const session of sessions) {
487
- console.log(`\t${session.id}\tcreated ${formatDateRange(session.created).padEnd(40)}\texpires ${formatDateRange(session.expires).padEnd(40)}\t${session.elevated ? styleText('yellow', '(elevated)') : ''}`);
471
+ if (opt.passkeys) {
472
+ const passkeys = await db.database.selectFrom('passkeys').where('userId', '=', user.id).selectAll().execute();
473
+ console.log(styleText('bold', 'Passkeys:'));
474
+ for (const passkey of passkeys) {
475
+ console.log(`\t${passkey.id}: created ${formatDateRange(passkey.createdAt).padEnd(40)} used ${passkey.counter} times. ${passkey.deviceType}, ${passkey.backedUp ? '' : 'not '}backed up; transports are [${passkey.transports.join(', ')}], ${passkey.name ? 'named ' + JSON.stringify(passkey.name) : 'unnamed'}.`);
488
476
  }
489
- }
490
- if (opt.passkeys) {
491
- const passkeys = await db.database.selectFrom('passkeys').where('userId', '=', user.id).selectAll().execute();
492
- console.log(styleText('bold', 'Passkeys:'));
493
- for (const passkey of passkeys) {
494
- console.log(`\t${passkey.id}: created ${formatDateRange(passkey.createdAt).padEnd(40)} used ${passkey.counter} times. ${passkey.deviceType}, ${passkey.backedUp ? '' : 'not '}backed up; transports are [${passkey.transports.join(', ')}], ${passkey.name ? 'named ' + JSON.stringify(passkey.name) : 'unnamed'}.`);
495
477
  }
496
- }
497
- });
498
- program
499
- .command('toggle-admin')
500
- .description('Toggle whether a user is an administrator')
501
- .addArgument(lookup)
502
- .action(async (_user) => {
503
- const user = await _user;
504
- const isAdmin = !user.isAdmin;
505
- await db.database.updateTable('users').set({ isAdmin }).where('id', '=', user.id).executeTakeFirstOrThrow();
506
- await audit('admin_change', undefined, { user: user.id });
507
- console.log(`${userText(user)} is ${isAdmin ? 'now' : 'no longer'} an administrator. (${styleText(['whiteBright', 'bold'], isAdmin.toString())})`);
508
- });
509
- program
510
- .command('status')
511
- .alias('stats')
512
- .description('Get information about the server')
513
- .addOption(opts.host)
514
- .action(async () => {
515
- console.log('Axium Server v' + $pkg.version);
516
- console.log(styleText('whiteBright', 'Debug mode:'), config.debug ? styleText('yellow', 'enabled') : 'disabled');
517
- const configFiles = config.files.keys().toArray();
518
- console.log(styleText('whiteBright', 'Loaded config files:'), styleText(['dim', 'bold'], `(${configFiles.length})`), configFiles.join(', '));
519
- process.stdout.write(styleText('whiteBright', 'Daemon: '));
520
- const daemonIs = (sub) => spawnSync('systemctl', ['is-' + sub, 'axiumd'], {
521
- stdio: 'pipe',
522
- encoding: 'utf8',
523
478
  });
524
- const { status: dNotActive, stdout: dStatus } = daemonIs('active');
525
- const { status: dNotFailed } = daemonIs('failed');
526
- const { stdout: dEnabled } = daemonIs('enabled');
527
- if (dEnabled.trim() == 'not-found')
528
- console.log(styleText('dim', 'not found'));
529
- else {
530
- process.stdout.write(dEnabled.trim() + ', ');
531
- const status = dStatus.trim();
532
- if (!dNotFailed)
533
- console.log(styleText('red', status));
534
- else if (!dNotActive)
535
- console.log(styleText('green', status));
536
- else
537
- console.log(styleText('yellow', status));
538
- }
539
- process.stdout.write(styleText('whiteBright', 'Database: '));
540
- try {
541
- console.log(await db.statText());
542
- }
543
- catch {
544
- console.log(styleText('red', 'Unavailable'));
545
- }
546
- console.log(styleText('whiteBright', 'Loaded plugins:'), styleText(['dim', 'bold'], `(${plugins.size || 'none'})`), Array.from(plugins.keys()).join(', '));
547
- for (const plugin of plugins.values()) {
548
- if (!plugin._hooks?.statusText)
549
- continue;
550
- const text = await plugin._hooks?.statusText();
551
- console.log(styleText('bold', plugin.name), plugin.version + ':', text.includes('\n') ? '\n' + text : text);
552
- }
553
- });
554
- program
555
- .command('ports')
556
- .description('Enable or disable use of restricted ports (e.g. 443)')
557
- .addArgument(new Argument('<action>', 'The action to take').choices(io._portActions))
558
- .addOption(new Option('-m, --method <method>', 'the method to use').choices(io._portMethods).default('node-cap'))
559
- .option('-N, --node <path>', 'the path to the node binary')
560
- .action(async (action, opt) => {
561
- await io.restrictedPorts({ ...opt, action }).catch(io.handleError);
562
- });
563
- program
564
- .command('init')
565
- .description('Install Axium server')
566
- .addOption(opts.force)
567
- .addOption(opts.host)
568
- .addOption(opts.check)
569
- .addOption(opts.packagesDir)
570
- .action(async (opt) => {
571
- await db.init({ ...opt, skip: opt.dbSkip }).catch(io.handleError);
572
- await io.restrictedPorts({ method: 'node-cap', action: 'enable' }).catch(io.handleError);
573
- });
574
- program
575
- .command('serve')
576
- .description('Start the Axium server')
577
- .option('-p, --port <port>', 'the port to listen on')
578
- .option('--ssl <prefix>', 'the prefix for the cert.pem and key.pem SSL files')
579
- .option('-b, --build <path>', 'the path to the handler build')
580
- .action(async (opt) => {
581
- const server = await serve({
582
- secure: opt.ssl ? true : config.web.secure,
583
- ssl_cert: opt.ssl ? join(opt.ssl, 'cert.pem') : config.web.ssl_cert,
584
- ssl_key: opt.ssl ? join(opt.ssl, 'key.pem') : config.web.ssl_key,
585
- build: opt.build ? resolve(opt.build) : undefined,
586
- });
587
- const port = !Number.isNaN(Number.parseInt(opt.port ?? '')) ? Number.parseInt(opt.port) : config.web.port;
588
- server.listen(port, () => {
589
- console.log('Server is listening on port ' + port);
479
+ program
480
+ .command('toggle-admin')
481
+ .description('Toggle whether a user is an administrator')
482
+ .addArgument(lookup)
483
+ .action(async (_user) => {
484
+ const user = await _user;
485
+ const isAdmin = !user.isAdmin;
486
+ await db.database.updateTable('users').set({ isAdmin }).where('id', '=', user.id).executeTakeFirstOrThrow();
487
+ await audit('admin_change', undefined, { user: user.id });
488
+ console.log(`${userText(user)} is ${isAdmin ? 'now' : 'no longer'} an administrator. (${styleText(['whiteBright', 'bold'], isAdmin.toString())})`);
590
489
  });
591
- });
592
- program
593
- .command('link')
594
- .description('Link routes provided by plugins and the server')
595
- .addOption(opts.packagesDir)
596
- .addOption(new Option('-l, --list', 'list route links').conflicts('delete'))
597
- .option('-d, --delete', 'delete route links')
598
- .argument('[name...]', 'List of plugin names to operate on. If not specified, operates on all plugins and built-in routes.')
599
- .action(async function (names) {
600
- const opt = this.optsWithGlobals();
601
- if (names.length)
602
- opt.only = names;
603
- if (opt.list) {
604
- for (const link of listRouteLinks(opt)) {
605
- const idText = link.id.startsWith('#') ? `(${link.id.slice(1)})` : link.id;
606
- const fromColor = await access(link.from)
607
- .then(() => 'cyanBright')
608
- .catch(() => 'redBright');
609
- console.log(`${idText}:\t ${styleText(fromColor, link.from)}\t->\t${link.to.replace(/.*\/node_modules\//, styleText('dim', '$&'))}`);
610
- }
611
- return;
612
- }
613
- if (opt.delete) {
614
- unlinkRoutes(opt);
615
- return;
616
- }
617
- linkRoutes(opt);
618
- });
619
- program
620
- .command('audit')
621
- .description('View audit logs')
622
- .option('-x, --extra', 'Include the extra object when listing events')
623
- .option('-t, --include-tags', 'Include tags when listing events')
624
- .addOption(new Option('-s, --summary', 'Summarize audit log entries instead of displaying individual ones').conflicts(['extra', 'includeTags']))
625
- .optionsGroup('Filters:')
626
- .option('--since <date>', 'Filter for events since a date')
627
- .option('--until <date>', 'Filter for events until a date')
628
- .option('--user <uuid|null>', 'Filter for events triggered by a user')
629
- .addOption(new Option('--severity <level>', 'Filter for events at or above a severity level').choices(severityNames))
630
- .option('--source <source>', 'Filter by source')
631
- .option('--tag <tag...>', 'Filter by tag(s)')
632
- .option('--event <event>', 'Filter by event name')
633
- .action(async (opt) => {
634
- const filter = await AuditFilter.parseAsync(opt).catch(e => io.exit('Invalid filter: ' + z.prettifyError(e)));
635
- const events = await getEvents(filter).execute();
636
- if (opt.summary) {
637
- const groups = Object.groupBy(events, e => e.severity);
638
- const maxGroupLength = Math.max(...Object.values(groups).map(g => g.length.toString().length), 0);
639
- for (const [severity, group] of Object.entries(groups)) {
640
- if (!group?.length)
490
+ program
491
+ .command('status')
492
+ .alias('stats')
493
+ .description('Get information about the server')
494
+ .addOption(opts.host)
495
+ .action(async () => {
496
+ console.log('Axium Server v' + $pkg.version);
497
+ console.log(styleText('whiteBright', 'Debug mode:'), config.debug ? styleText('yellow', 'enabled') : 'disabled');
498
+ const configFiles = config.files.keys().toArray();
499
+ console.log(styleText('whiteBright', 'Loaded config files:'), styleText(['dim', 'bold'], `(${configFiles.length})`), configFiles.join(', '));
500
+ outputDaemonStatus('axium');
501
+ process.stdout.write(styleText('whiteBright', 'Database: '));
502
+ try {
503
+ console.log(await db.statText());
504
+ }
505
+ catch {
506
+ console.log(styleText('red', 'Unavailable'));
507
+ }
508
+ console.log(styleText('whiteBright', 'Loaded plugins:'), styleText(['dim', 'bold'], `(${plugins.size || 'none'})`), Array.from(plugins.keys()).join(', '));
509
+ for (const plugin of plugins.values()) {
510
+ if (!plugin._hooks?.statusText)
641
511
  continue;
642
- console.log(styleText('white', group.length.toString().padStart(maxGroupLength)), styleSeverity(severity, true), 'events. Latest occurred', group.at(-1).timestamp.toLocaleString());
512
+ const text = await plugin._hooks?.statusText();
513
+ console.log(styleText('bold', plugin.name), plugin.version + ':', text.includes('\n') ? '\n' + text : text);
643
514
  }
644
- return;
645
- }
646
- let maxSource = 0, maxName = 0, maxTags = 0, maxExtra = 0;
647
- for (const event of events) {
648
- maxSource = Math.max(maxSource, event.source.length);
649
- maxName = Math.max(maxName, event.name.length);
650
- event._tags = !event.tags.length
651
- ? ''
652
- : opt.includeTags
653
- ? '# ' + event.tags.join(', ')
654
- : `(${event.tags.length} tag${event.tags.length == 1 ? '' : 's'})`;
655
- maxTags = Math.max(maxTags, event._tags.length);
656
- const extraKeys = Object.keys(event.extra);
657
- event._extra = !extraKeys.length ? '' : opt.extra ? JSON.stringify(event.extra) : '+' + extraKeys.length;
658
- maxExtra = Math.max(maxExtra, event._extra.length);
659
- }
660
- for (const event of events) {
661
- console.log(styleSeverity(event.severity, true), styleText('dim', io.prettyDate(event.timestamp)), event.source.padEnd(maxSource), styleText('whiteBright', event.name.padEnd(maxName)), styleText('gray', event._tags.padEnd(maxTags)), 'by', event.userId ? event.userId : styleText(['dim', 'italic'], 'unknown'.padEnd(36)), styleText('blue', event._extra));
662
- }
663
- });
664
- program.parse();
515
+ });
516
+ program
517
+ .command('ports')
518
+ .description('Enable or disable use of restricted ports (e.g. 443)')
519
+ .addArgument(new Argument('<action>', 'The action to take').choices(_portActions))
520
+ .addOption(new Option('-m, --method <method>', 'the method to use').choices(_portMethods).default('node-cap'))
521
+ .option('-N, --node <path>', 'the path to the node binary')
522
+ .action(async (action, opt) => {
523
+ await restrictedPorts({ ...opt, action }).catch(io.handleError);
524
+ });
525
+ program
526
+ .command('init')
527
+ .description('Install Axium server')
528
+ .addOption(opts.force)
529
+ .addOption(opts.host)
530
+ .addOption(opts.check)
531
+ .addOption(opts.packagesDir)
532
+ .action(async (opt) => {
533
+ await db.init({ ...opt, skip: opt.dbSkip }).catch(io.handleError);
534
+ await restrictedPorts({ method: 'node-cap', action: 'enable' }).catch(io.handleError);
535
+ });
536
+ program
537
+ .command('serve')
538
+ .description('Start the Axium server')
539
+ .option('-p, --port <port>', 'the port to listen on')
540
+ .option('--ssl <prefix>', 'the prefix for the cert.pem and key.pem SSL files')
541
+ .option('-b, --build <path>', 'the path to the handler build')
542
+ .action(async (opt) => {
543
+ const server = await serve({
544
+ secure: opt.ssl ? true : config.web.secure,
545
+ ssl_cert: opt.ssl ? join(opt.ssl, 'cert.pem') : config.web.ssl_cert,
546
+ ssl_key: opt.ssl ? join(opt.ssl, 'key.pem') : config.web.ssl_key,
547
+ build: opt.build ? resolve(opt.build) : undefined,
548
+ });
549
+ const port = !Number.isNaN(Number.parseInt(opt.port ?? '')) ? Number.parseInt(opt.port) : config.web.port;
550
+ server.listen(port, () => {
551
+ console.log('Server is listening on port ' + port);
552
+ });
553
+ });
554
+ program
555
+ .command('link')
556
+ .description('Link routes provided by plugins and the server')
557
+ .addOption(opts.packagesDir)
558
+ .addOption(new Option('-l, --list', 'list route links').conflicts('delete'))
559
+ .option('-d, --delete', 'delete route links')
560
+ .argument('[name...]', 'List of plugin names to operate on. If not specified, operates on all plugins and built-in routes.')
561
+ .action(async function (names) {
562
+ const opt = this.optsWithGlobals();
563
+ if (names.length)
564
+ opt.only = names;
565
+ if (opt.list) {
566
+ for (const link of listRouteLinks(opt)) {
567
+ const idText = link.id.startsWith('#') ? `(${link.id.slice(1)})` : link.id;
568
+ const fromColor = await access(link.from)
569
+ .then(() => 'cyanBright')
570
+ .catch(() => 'redBright');
571
+ console.log(`${idText}:\t ${styleText(fromColor, link.from)}\t->\t${link.to.replace(/.*\/node_modules\//, styleText('dim', '$&'))}`);
572
+ }
573
+ return;
574
+ }
575
+ if (opt.delete) {
576
+ unlinkRoutes(opt);
577
+ return;
578
+ }
579
+ linkRoutes(opt);
580
+ });
581
+ program
582
+ .command('audit')
583
+ .description('View audit logs')
584
+ .option('-x, --extra', 'Include the extra object when listing events')
585
+ .option('-t, --include-tags', 'Include tags when listing events')
586
+ .addOption(new Option('-s, --summary', 'Summarize audit log entries instead of displaying individual ones').conflicts(['extra', 'includeTags']))
587
+ .optionsGroup('Filters:')
588
+ .option('--since <date>', 'Filter for events since a date')
589
+ .option('--until <date>', 'Filter for events until a date')
590
+ .option('--user <uuid|null>', 'Filter for events triggered by a user')
591
+ .addOption(new Option('--severity <level>', 'Filter for events at or above a severity level').choices(severityNames))
592
+ .option('--source <source>', 'Filter by source')
593
+ .option('--tag <tag...>', 'Filter by tag(s)')
594
+ .option('--event <event>', 'Filter by event name')
595
+ .action(async (opt) => {
596
+ const filter = await AuditFilter.parseAsync(opt).catch(e => io.exit('Invalid filter: ' + z.prettifyError(e)));
597
+ const events = await getEvents(filter).execute();
598
+ if (opt.summary) {
599
+ const groups = Object.groupBy(events, e => e.severity);
600
+ const maxGroupLength = Math.max(...Object.values(groups).map(g => g.length.toString().length), 0);
601
+ for (const [severity, group] of Object.entries(groups)) {
602
+ if (!group?.length)
603
+ continue;
604
+ console.log(styleText('white', group.length.toString().padStart(maxGroupLength)), styleSeverity(severity, true), 'events. Latest occurred', group.at(-1).timestamp.toLocaleString());
605
+ }
606
+ return;
607
+ }
608
+ let maxSource = 0, maxName = 0, maxTags = 0, maxExtra = 0;
609
+ for (const event of events) {
610
+ maxSource = Math.max(maxSource, event.source.length);
611
+ maxName = Math.max(maxName, event.name.length);
612
+ event._tags = !event.tags.length
613
+ ? ''
614
+ : opt.includeTags
615
+ ? '# ' + event.tags.join(', ')
616
+ : `(${event.tags.length} tag${event.tags.length == 1 ? '' : 's'})`;
617
+ maxTags = Math.max(maxTags, event._tags.length);
618
+ const extraKeys = Object.keys(event.extra);
619
+ event._extra = !extraKeys.length ? '' : opt.extra ? JSON.stringify(event.extra) : '+' + extraKeys.length;
620
+ maxExtra = Math.max(maxExtra, event._extra.length);
621
+ }
622
+ for (const event of events) {
623
+ console.log(styleSeverity(event.severity, true), styleText('dim', io.prettyDate(event.timestamp)), event.source.padEnd(maxSource), styleText('whiteBright', event.name.padEnd(maxName)), styleText('gray', event._tags.padEnd(maxTags)), 'by', event.userId ? event.userId : styleText(['dim', 'italic'], 'unknown'.padEnd(36)), styleText('blue', event._extra));
624
+ }
625
+ });
626
+ await program.parseAsync();
627
+ }
628
+ catch (e_1) {
629
+ env_1.error = e_1;
630
+ env_1.hasError = true;
631
+ }
632
+ finally {
633
+ __disposeResources(env_1);
634
+ }