@underpostnet/cyberia 3.2.90 → 3.3.73

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 (490) hide show
  1. package/.dockerignore +1 -0
  2. package/.env.example +16 -0
  3. package/.github/workflows/coverall.cyberia.ci.yml +107 -0
  4. package/.github/workflows/cyberia-client.cd.yml +6 -18
  5. package/.github/workflows/cyberia-server.cd.yml +6 -18
  6. package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
  7. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
  8. package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
  9. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
  10. package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
  11. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
  12. package/.github/workflows/engine-cyberia.cd.yml +6 -78
  13. package/.github/workflows/engine-cyberia.ci.yml +4 -5
  14. package/.github/workflows/ghpkg.ci.yml +42 -21
  15. package/.github/workflows/hardhat.ci.yml +12 -11
  16. package/.github/workflows/npmpkg.ci.yml +17 -15
  17. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -16
  18. package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
  19. package/.github/workflows/release.cd.yml +2 -9
  20. package/.prettierignore +1 -0
  21. package/AGENTS.md +47 -0
  22. package/CHANGELOG.md +581 -2417
  23. package/CLI-HELP.md +416 -127
  24. package/Dockerfile +25 -9
  25. package/Dockerfile.dev +25 -9
  26. package/Dockerfile.test +4 -4
  27. package/README.md +21 -1
  28. package/bin/build.js +70 -43
  29. package/bin/build.template.js +8 -3
  30. package/bin/cyberia.js +372 -135
  31. package/bin/deploy.js +18 -104
  32. package/bin/index.js +372 -135
  33. package/compose.env +16 -0
  34. package/conf.js +93 -4
  35. package/deploy/cyberia-client/deploy.sh +47 -0
  36. package/deploy/cyberia-client/package.sh +18 -0
  37. package/deploy/cyberia-client/state.sh +14 -0
  38. package/deploy/cyberia-server/deploy.sh +47 -0
  39. package/deploy/cyberia-server/package.sh +18 -0
  40. package/deploy/cyberia-server/state.sh +14 -0
  41. package/deploy/dd-cyberia/deploy.sh +22 -0
  42. package/deploy/dd-cyberia/init.sh +55 -0
  43. package/deploy/dd-cyberia/package.sh +17 -0
  44. package/deploy/dd-cyberia/state.sh +14 -0
  45. package/deploy/dd-cyberia/sync-deploy.sh +116 -0
  46. package/deploy/lib/github-actions-logging.sh +594 -0
  47. package/deploy/lib/host.sh +185 -0
  48. package/deploy/lib/state.sh +62 -0
  49. package/deploy/pwa-microservices-template/deploy.sh +45 -0
  50. package/deploy/release/deploy.sh +32 -0
  51. package/deployment.yaml +7 -2
  52. package/docker-compose.yml +31 -37
  53. package/examples/static-page/README.md +19 -19
  54. package/examples/static-page/ssr-components/CustomPage.js +2 -2
  55. package/hardhat/hardhat.config.js +1 -6
  56. package/hardhat/package-lock.json +104 -43
  57. package/hardhat/package.json +3 -3
  58. package/manifests/alertmanager/deployment.yaml +81 -0
  59. package/manifests/blackbox-exporter/deployment.yaml +75 -0
  60. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +36 -7
  61. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +77 -0
  62. package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
  63. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  64. package/manifests/grafana/deployment.yaml +26 -7
  65. package/manifests/grafana/kustomization.yaml +1 -0
  66. package/manifests/grafana/service.yaml +6 -1
  67. package/manifests/mariadb/pv.yaml +1 -0
  68. package/manifests/mongodb/statefulset.yaml +9 -2
  69. package/manifests/mysql/pv-pvc.yaml +14 -1
  70. package/manifests/postgresql/pv.yaml +12 -1
  71. package/manifests/postgresql/pvc.yaml +1 -0
  72. package/manifests/prometheus/deployment.yaml +18 -22
  73. package/package.json +83 -10
  74. package/scripts/audit-selinux.sh +64 -0
  75. package/scripts/event-monitor.sh +56 -0
  76. package/scripts/gpu-diag.sh +0 -0
  77. package/scripts/ip-info.sh +0 -0
  78. package/scripts/k3s-node-setup.sh +30 -14
  79. package/scripts/kubeadm-node-setup.sh +40 -31
  80. package/scripts/lxd-vm-setup.sh +0 -0
  81. package/scripts/maas-nat-firewalld.sh +0 -0
  82. package/scripts/maas-setup.sh +8 -8
  83. package/scripts/nat-iptables.sh +2 -0
  84. package/scripts/rhel-grpc-setup.sh +0 -0
  85. package/scripts/rocky-kickstart.sh +25 -9
  86. package/scripts/selinux-normalize.sh +907 -0
  87. package/scripts/shutdown-machine.sh +843 -0
  88. package/scripts/test-monitor.sh +3 -3
  89. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +1 -1
  90. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +2 -2
  91. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +2 -2
  92. package/src/api/core/core.controller.js +1 -1
  93. package/src/api/core/core.router.js +2 -2
  94. package/src/api/core/core.service.js +2 -2
  95. package/src/api/crypto/crypto.controller.js +1 -1
  96. package/src/api/crypto/crypto.service.js +1 -1
  97. package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
  98. package/src/api/cyberia-action/cyberia-action.router.js +1 -1
  99. package/src/api/cyberia-action/cyberia-action.service.js +2 -2
  100. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +1 -1
  101. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +1 -1
  102. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +2 -2
  103. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
  104. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +1 -1
  105. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
  106. package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
  107. package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
  108. package/src/api/cyberia-entity/cyberia-entity.service.js +2 -2
  109. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +1 -1
  110. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +1 -1
  111. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +2 -2
  112. package/src/api/cyberia-instance/cyberia-fallback-capture.js +466 -0
  113. package/src/api/cyberia-instance/cyberia-fallback-default-items.js +63 -0
  114. package/src/api/cyberia-instance/cyberia-fallback-world.js +16 -1
  115. package/src/api/cyberia-instance/cyberia-instance-map.service.js +1 -1
  116. package/src/api/cyberia-instance/cyberia-instance.controller.js +4 -1
  117. package/src/api/cyberia-instance/cyberia-instance.router.js +15 -2
  118. package/src/api/cyberia-instance/cyberia-instance.service.js +45 -2
  119. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
  120. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +1 -0
  121. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
  122. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +2 -2
  123. package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
  124. package/src/api/cyberia-map/cyberia-map.router.js +1 -1
  125. package/src/api/cyberia-map/cyberia-map.service.js +2 -2
  126. package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
  127. package/src/api/cyberia-quest/cyberia-quest.router.js +1 -1
  128. package/src/api/cyberia-quest/cyberia-quest.service.js +2 -2
  129. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
  130. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
  131. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
  132. package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
  133. package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
  134. package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
  135. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +16 -29
  136. package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
  137. package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
  138. package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
  139. package/src/api/default/default.controller.js +1 -1
  140. package/src/api/default/default.router.js +1 -1
  141. package/src/api/default/default.service.js +2 -2
  142. package/src/api/document/document.controller.js +1 -1
  143. package/src/api/document/document.router.js +1 -1
  144. package/src/api/document/document.service.js +2 -2
  145. package/src/api/file/file.controller.js +1 -1
  146. package/src/api/file/file.router.js +1 -1
  147. package/src/api/file/file.service.js +2 -2
  148. package/src/api/instance/instance.controller.js +1 -1
  149. package/src/api/instance/instance.router.js +1 -1
  150. package/src/api/instance/instance.service.js +2 -2
  151. package/src/api/ipfs/ipfs.controller.js +1 -1
  152. package/src/api/ipfs/ipfs.router.js +2 -2
  153. package/src/api/ipfs/ipfs.service.js +2 -2
  154. package/src/api/object-layer/object-layer.controller.js +1 -1
  155. package/src/api/object-layer/object-layer.model.js +204 -3
  156. package/src/api/object-layer/object-layer.router.js +2 -2
  157. package/src/api/object-layer/object-layer.service.js +4 -17
  158. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
  159. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
  160. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
  161. package/src/api/test/test.controller.js +1 -1
  162. package/src/api/test/test.service.js +1 -1
  163. package/src/api/user/guest.service.js +3 -3
  164. package/src/api/user/user.controller.js +1 -1
  165. package/src/api/user/user.router.js +2 -2
  166. package/src/api/user/user.service.js +4 -4
  167. package/src/api.js +5 -9
  168. package/src/cli/app.js +391 -0
  169. package/src/cli/baremetal.js +30 -36
  170. package/src/cli/client.js +306 -0
  171. package/src/cli/cloud-init.js +3 -3
  172. package/src/cli/cluster.js +242 -135
  173. package/src/cli/db.js +126 -67
  174. package/src/cli/deploy.js +158 -60
  175. package/src/cli/docker-compose.js +5 -5
  176. package/src/cli/domains.js +184 -0
  177. package/src/cli/dotenv-store.js +143 -0
  178. package/src/cli/event.js +2281 -0
  179. package/src/cli/fs.js +3 -3
  180. package/src/cli/host.js +672 -0
  181. package/src/cli/image.js +4 -7
  182. package/src/cli/index.js +426 -134
  183. package/src/cli/ipfs.js +34 -30
  184. package/src/cli/kickstart.js +1 -1
  185. package/src/cli/kubectl.js +218 -41
  186. package/src/cli/lxd.js +3 -3
  187. package/src/cli/monitor.js +1359 -26
  188. package/src/cli/package.js +90 -0
  189. package/src/cli/release.js +73 -34
  190. package/src/cli/repository.js +564 -367
  191. package/src/cli/run.js +362 -654
  192. package/src/cli/secrets.js +2158 -964
  193. package/src/cli/ssh.js +651 -331
  194. package/src/cli/state.js +394 -0
  195. package/src/cli/static.js +2 -2
  196. package/src/cli/system.js +26 -13
  197. package/src/cli/test.js +199 -125
  198. package/src/cli/vultr.js +623 -0
  199. package/src/cli/wireguard.js +2930 -0
  200. package/src/client/components/core/CalendarCore.js +53 -96
  201. package/src/client/components/core/Docs.js +258 -211
  202. package/src/client/components/core/FileExplorer.js +0 -21
  203. package/src/client/components/core/PanelForm.js +4 -4
  204. package/src/client/components/core/Repository.js +56 -0
  205. package/src/client/components/core/Translate.js +7 -0
  206. package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
  207. package/src/client/components/core/Wallet.js +0 -11
  208. package/src/client/components/core/Worker.js +7 -1
  209. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
  210. package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +368 -0
  211. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +35 -1
  212. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +4 -0
  213. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
  214. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
  215. package/src/client/components/default/AppShellDefault.js +1 -1
  216. package/src/client/components/default/SettingsDefault.js +2 -2
  217. package/src/client/components/itemledger/SettingsItemledger.js +2 -2
  218. package/src/client/components/underpost/AppShellUnderpost.js +3 -2
  219. package/src/client/components/underpost/SettingsUnderpost.js +2 -2
  220. package/src/client/public/cyberia-docs/ARCHITECTURE.md +17 -3
  221. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +32 -5
  222. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +1 -1
  223. package/src/client/public/cyberia-docs/CYBERIA.md +21 -1
  224. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
  225. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  226. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  227. package/src/client/public/default/android-chrome-144x144.png +0 -0
  228. package/src/client/public/default/android-chrome-192x192.png +0 -0
  229. package/src/client/public/default/android-chrome-256x256.png +0 -0
  230. package/src/client/public/default/android-chrome-36x36.png +0 -0
  231. package/src/client/public/default/android-chrome-384x384.png +0 -0
  232. package/src/client/public/default/android-chrome-48x48.png +0 -0
  233. package/src/client/public/default/android-chrome-512x512.png +0 -0
  234. package/src/client/public/default/android-chrome-72x72.png +0 -0
  235. package/src/client/public/default/android-chrome-96x96.png +0 -0
  236. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  237. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  238. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  239. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  240. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  241. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  242. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  243. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  244. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  245. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  246. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  247. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  248. package/src/client/public/default/apple-touch-icon.png +0 -0
  249. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  250. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  251. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  252. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  253. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  254. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  255. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  256. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  257. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  258. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  259. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  260. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  261. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  262. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  263. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  264. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  265. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  266. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  267. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  268. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  269. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  270. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  271. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  272. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  273. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  274. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  275. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  276. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  277. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  278. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  279. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  280. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  281. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  282. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  283. package/src/client/public/default/assets/background/white.jpg +0 -0
  284. package/src/client/public/default/browserconfig.xml +1 -1
  285. package/src/client/public/default/favicon-16x16.png +0 -0
  286. package/src/client/public/default/favicon-32x32.png +0 -0
  287. package/src/client/public/default/favicon-48x48.png +0 -0
  288. package/src/client/public/default/favicon.ico +0 -0
  289. package/src/client/public/default/manifest.webmanifest +5 -5
  290. package/src/client/public/default/mstile-144x144.png +0 -0
  291. package/src/client/public/default/mstile-150x150.png +0 -0
  292. package/src/client/public/default/mstile-310x150.png +0 -0
  293. package/src/client/public/default/mstile-310x310.png +0 -0
  294. package/src/client/public/default/mstile-70x70.png +0 -0
  295. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  296. package/src/client/public/default/yandex-browser-manifest.json +1 -1
  297. package/src/client/services/cyberia-instance/cyberia-instance.service.js +40 -0
  298. package/src/client/services/object-layer/object-layer.management.js +4 -4
  299. package/src/client/ssr/RootDocument.js +1 -1
  300. package/src/client/ssr/body/404.js +1 -1
  301. package/src/client/ssr/body/500.js +1 -1
  302. package/src/client/ssr/body/CacheControl.js +1 -1
  303. package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
  304. package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
  305. package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
  306. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
  307. package/src/client/ssr/head/CryptokoynScripts.js +1 -1
  308. package/src/client/ssr/head/Css.js +1 -1
  309. package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
  310. package/src/client/ssr/head/DefaultScripts.js +1 -1
  311. package/src/client/ssr/head/ItemledgerScripts.js +1 -1
  312. package/src/client/ssr/head/Microdata.js +1 -1
  313. package/src/client/ssr/head/Production.js +1 -1
  314. package/src/client/ssr/head/Pwa.js +1 -1
  315. package/src/client/ssr/head/PwaItemledger.js +1 -1
  316. package/src/client/ssr/head/Seo.js +1 -1
  317. package/src/client/ssr/head/UnderpostScripts.js +1 -1
  318. package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
  319. package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
  320. package/src/client/ssr/views/Cyberia404.js +7 -5
  321. package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
  322. package/src/client/ssr/views/Maintenance.js +1 -1
  323. package/src/client/ssr/views/NoNetworkConnection.js +1 -1
  324. package/src/client/ssr/views/Test.js +1 -1
  325. package/src/client/sw/core.sw.js +20 -14
  326. package/src/client-builder/client-build-docs.js +61 -46
  327. package/src/client-builder/client-build-live.js +2 -2
  328. package/src/client-builder/client-build.js +58 -44
  329. package/src/client-builder/client-dev-server.js +3 -3
  330. package/src/client-builder/client-icons.js +2 -2
  331. package/src/client-builder/ssr.js +3 -3
  332. package/src/client.build.js +3 -6
  333. package/src/client.dev.js +3 -6
  334. package/src/db/DataBaseProvider.js +186 -3
  335. package/src/db/mariadb/MariaDB.js +3 -2
  336. package/src/db/mongo/MongoBootstrap.js +273 -101
  337. package/src/db/mongo/MongooseDB.js +11 -8
  338. package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
  339. package/src/grpc/cyberia/grpc-server.js +1 -1
  340. package/src/index.js +103 -23
  341. package/src/mailer/EmailRender.js +2 -2
  342. package/src/mailer/MailerInterceptor.js +87 -0
  343. package/src/mailer/MailerProvider.js +50 -6
  344. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +1 -1
  345. package/src/projects/cyberia/besu-genesis-generator.js +3 -3
  346. package/src/projects/cyberia/catalog-cyberia.js +54 -6
  347. package/src/projects/cyberia/gemini-client.js +1 -1
  348. package/src/projects/cyberia/generate-saga.js +15 -24
  349. package/src/projects/cyberia/hot-reload-trigger.js +1 -1
  350. package/src/projects/cyberia/instance-data.js +22 -3
  351. package/src/projects/cyberia/ipfs-client.js +4 -4
  352. package/src/projects/cyberia/map-preview-generator.js +1 -1
  353. package/src/projects/cyberia/object-layer.js +12 -22
  354. package/src/projects/cyberia/semantic-layer-generator.js +1 -1
  355. package/src/projects/underpost/catalog-underpost.js +13 -2
  356. package/src/proxy.js +4 -7
  357. package/src/runtime/cyberia-client/Dockerfile +9 -4
  358. package/src/runtime/cyberia-client/Dockerfile.dev +8 -2
  359. package/src/runtime/cyberia-server/Dockerfile +9 -4
  360. package/src/runtime/cyberia-server/Dockerfile.dev +8 -2
  361. package/src/runtime/engine-cyberia/Dockerfile +25 -9
  362. package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
  363. package/src/runtime/engine-cyberia/Dockerfile.test +4 -4
  364. package/src/runtime/engine-cyberia/compose.env +16 -0
  365. package/src/runtime/engine-cyberia/docker-compose.yml +31 -37
  366. package/src/runtime/express/Express.js +32 -27
  367. package/src/runtime/lampp/Lampp.js +22 -70
  368. package/src/runtime/nginx/Nginx.js +1 -1
  369. package/src/runtime/wp/Wp.js +16 -48
  370. package/src/server/{catalog.js → build/catalog.js} +15 -5
  371. package/src/server/build/coverage.js +117 -0
  372. package/src/server/build/execution.js +402 -0
  373. package/src/server/build/package.js +465 -0
  374. package/src/server/build/testing.js +528 -0
  375. package/src/server/{dns.js → network/dns.js} +241 -14
  376. package/src/server/network/forward-proxy.js +541 -0
  377. package/src/server/{middlewares.js → network/middlewares.js} +59 -4
  378. package/src/server/network/node-capability.js +98 -0
  379. package/src/server/{peer.js → network/peer.js} +3 -3
  380. package/src/server/{proxy.js → network/proxy.js} +7 -13
  381. package/src/server/network/router.js +356 -0
  382. package/src/server/{tls.js → network/tls.js} +2 -2
  383. package/src/server/network/underpost-compression.js +186 -0
  384. package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +26 -16
  385. package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +19 -3
  386. package/src/server/{cri.js → ops/cri.js} +2 -2
  387. package/src/server/ops/cron.js +949 -0
  388. package/src/server/ops/event-notification.js +284 -0
  389. package/src/server/{logger.js → ops/logger.js} +108 -23
  390. package/src/server/ops/monitoring.js +1724 -0
  391. package/src/server/ops/systemd.js +259 -0
  392. package/src/server/{conf.js → runtime/conf.js} +521 -520
  393. package/src/server/runtime/config-scope.js +215 -0
  394. package/src/server/runtime/environment.js +149 -0
  395. package/src/server/{process.js → runtime/process.js} +153 -13
  396. package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
  397. package/src/server/{runtime.js → runtime/runtime.js} +12 -8
  398. package/src/server/{start.js → runtime/start.js} +128 -39
  399. package/src/server/{auth.js → security/auth.js} +7 -8
  400. package/src/server/security/container-storage.js +382 -0
  401. package/src/server/{crypto.js → security/crypto.js} +1 -1
  402. package/src/server/security/selinux.js +185 -0
  403. package/src/server/{backup.js → storage/backup.js} +17 -8
  404. package/src/server/{data-query.js → storage/data-query.js} +1 -1
  405. package/src/server/{downloader.js → storage/downloader.js} +2 -2
  406. package/src/server/storage/repository.js +68 -0
  407. package/src/server.js +4 -7
  408. package/src/ws/IoInterface.js +1 -1
  409. package/src/ws/IoServer.js +1 -1
  410. package/src/ws/core/core.ws.connection.js +1 -1
  411. package/src/ws/core/core.ws.emit.js +1 -1
  412. package/src/ws/core/core.ws.server.js +1 -1
  413. package/src/ws/default/default.ws.connection.js +1 -1
  414. package/src/ws/default/default.ws.emit.js +1 -1
  415. package/src/ws/default/default.ws.server.js +1 -1
  416. package/test/e2e/event-e2e-public-ingress-down.js +45 -0
  417. package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
  418. package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
  419. package/test/{api.test.js → integration/app/api.test.js} +33 -14
  420. package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +30 -0
  421. package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +2 -1
  422. package/test/integration/app/cyberia/cyberia-load.test.js +467 -0
  423. package/test/integration/app/cyberia/fallback-world-capture.test.js +253 -0
  424. package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
  425. package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
  426. package/test/integration/infra/1-security/config-scope.test.js +305 -0
  427. package/test/integration/infra/1-security/container-storage.test.js +356 -0
  428. package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
  429. package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
  430. package/test/integration/infra/1-security/selinux.test.js +69 -0
  431. package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
  432. package/test/integration/infra/1-security/systemd-service.test.js +70 -0
  433. package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
  434. package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
  435. package/test/integration/infra/2-network/node-capability.test.js +182 -0
  436. package/test/integration/infra/2-network/wireguard-cli.test.js +1163 -0
  437. package/test/integration/infra/2-network/wireguard-edge.test.js +1731 -0
  438. package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
  439. package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
  440. package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
  441. package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
  442. package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
  443. package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
  444. package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +47 -6
  445. package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +56 -4
  446. package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
  447. package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
  448. package/test/integration/infra/5-observability/event-notification.test.js +197 -0
  449. package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
  450. package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
  451. package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
  452. package/test/support/shell-harness.js +73 -0
  453. package/test/unit/build-template.test.js +97 -0
  454. package/test/unit/build-workflow-offline.test.js +132 -0
  455. package/test/unit/catalog.test.js +71 -0
  456. package/test/unit/client-build-docs.test.js +334 -0
  457. package/test/unit/conf-loading.test.js +303 -0
  458. package/test/unit/conf-resolution.test.js +979 -0
  459. package/test/unit/coverage-artifact.test.js +130 -0
  460. package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
  461. package/test/unit/deploy-env-resolution.test.js +38 -0
  462. package/test/unit/deploy-log-table.test.js +447 -0
  463. package/test/unit/execution-profiles.test.js +219 -0
  464. package/test/unit/fleet-sync-source.test.js +149 -0
  465. package/test/unit/logger-redaction.test.js +112 -0
  466. package/test/unit/package.test.js +403 -0
  467. package/test/unit/prepare-host.test.js +299 -0
  468. package/test/unit/process-environment.test.js +18 -0
  469. package/test/unit/propagation-message.test.js +78 -0
  470. package/test/unit/redeploy-plan.test.js +24 -0
  471. package/test/unit/release-bump.test.js +474 -0
  472. package/test/unit/ssh-output-redaction.test.js +28 -0
  473. package/test/unit/start-options.test.js +46 -0
  474. package/test/unit/test-tiers.test.js +193 -0
  475. package/vitest.config.js +58 -0
  476. package/.nycrc +0 -9
  477. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
  478. package/manifests/mongodb/pv-pvc.yaml +0 -59
  479. package/scripts/link-local-underpost-cli.sh +0 -6
  480. package/src/api/user/user.build.js +0 -16
  481. package/src/cli/env.js +0 -177
  482. package/src/client/components/core/Blockchain.js +0 -41
  483. package/src/client/components/core/Blog.js +0 -9
  484. package/src/client/components/core/KeyboardAvoidance.js +0 -145
  485. package/src/client/public/default/assets/background/dark.jpg +0 -0
  486. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  487. package/src/client/public/default/assets/background/white0.jpg +0 -0
  488. package/src/client/public/doc/favicon.ico +0 -0
  489. package/src/client/public/doc/sitemap +0 -148
  490. package/src/server/cron.js +0 -476
@@ -0,0 +1,284 @@
1
+ import fs from 'fs-extra';
2
+ import { resolveConfSecrets } from '../runtime/conf.js';
3
+ import { loggerFactory } from './logger.js';
4
+ import { MailerProvider } from '../../mailer/MailerProvider.js';
5
+
6
+ /**
7
+ * The notification contract for operational events.
8
+ *
9
+ * Detection and remediation are declared in code because they are behaviour;
10
+ * who hears about them is deployment data, and lives in
11
+ * `engine-private/deploy/conf.event.json`. Adding a subscriber or repointing a
12
+ * transport is therefore a configuration change, and no recipient address or
13
+ * credential reaches the event registry, a rendered manifest, or this
14
+ * repository.
15
+ *
16
+ * @module src/server/ops/event-notification.js
17
+ * @namespace UnderpostEventNotification
18
+ */
19
+
20
+ const logger = loggerFactory(import.meta);
21
+
22
+ /**
23
+ * @constant EVENT_CONF_PATH
24
+ * @description The notification contract, read relative to the engine checkout
25
+ * every command already resolves its deploy configuration from.
26
+ * @memberof UnderpostEventNotification
27
+ */
28
+ const EVENT_CONF_PATH = './engine-private/deploy/conf.event.json';
29
+
30
+ const EMPTY_CONF = { 'notification-providers': {}, events: {} };
31
+
32
+ /** What a rule writes where its declared threshold belongs. */
33
+ const THRESHOLD_TOKEN = '<threshold>';
34
+
35
+ /**
36
+ * @method readEventConf
37
+ * @description Parses the contract without resolving `env:` references.
38
+ *
39
+ * Structure and secrets are read apart so the shape can be listed, validated
40
+ * and tested on a machine that holds none of the credentials.
41
+ * @returns {{'notification-providers': object, events: object}} Parsed contract.
42
+ * @throws {Error} When the file exists but does not parse.
43
+ * @memberof UnderpostEventNotification
44
+ */
45
+ const readEventConf = () => {
46
+ if (!fs.existsSync(EVENT_CONF_PATH)) return { ...EMPTY_CONF };
47
+ try {
48
+ const source = JSON.parse(fs.readFileSync(EVENT_CONF_PATH, 'utf8'));
49
+ return {
50
+ 'notification-providers': source['notification-providers'] || {},
51
+ events: source.events || {},
52
+ };
53
+ } catch (error) {
54
+ throw new Error(`[event] invalid notification contract ${EVENT_CONF_PATH}: ${error.message}`);
55
+ }
56
+ };
57
+
58
+ const recipientFactory = (subscriber = {}) => {
59
+ const email = `${subscriber.email || ''}`.trim();
60
+ const name = `${subscriber.name || ''}`.trim();
61
+ return email ? { email, name, address: name ? `${name} <${email}>` : email } : undefined;
62
+ };
63
+
64
+ /**
65
+ * @constant NOTIFICATION_PROVIDER_TYPES
66
+ * @description The transports a notification route can name.
67
+ *
68
+ * `describe` renders the route for `--list` and validates it; `deliver` sends
69
+ * one rendered notification. A type is one entry here, so adding a transport
70
+ * never means editing the dispatcher.
71
+ * @memberof UnderpostEventNotification
72
+ */
73
+ const NOTIFICATION_PROVIDER_TYPES = {
74
+ mailer: {
75
+ describe: (provider) => {
76
+ const transport = provider?.mailer?.transport || {};
77
+ const host = `${transport.host || ''}`.replace(/^env:.*/, '(env)');
78
+ if (!transport.host) throw new Error('mailer provider has no transport.host');
79
+ if (!provider?.mailer?.sender?.email) throw new Error('mailer provider has no sender.email');
80
+ return `smtp ${host}`;
81
+ },
82
+ deliver: async ({ providerId, provider, recipients, subject, text }) => {
83
+ const mailer = resolveConfSecrets(provider.mailer);
84
+ const port = Number(mailer.transport?.port) || 587;
85
+ const id = `event-notification:${providerId}`;
86
+
87
+ await MailerProvider.load({
88
+ id,
89
+ sender: { email: mailer.sender.email, name: mailer.sender.name || 'Underpost' },
90
+ transport: {
91
+ host: mailer.transport.host,
92
+ port,
93
+ secure: `${mailer.transport?.secure}` === 'true' || port === 465,
94
+ auth: { user: mailer.transport?.auth?.user || '', pass: mailer.transport?.auth?.pass || '' },
95
+ },
96
+ templates: {},
97
+ });
98
+
99
+ // Plain text by design: an operational alert must not depend on a client
100
+ // build being present on the host that dispatches it.
101
+ try {
102
+ const info = await MailerProvider.send({
103
+ id,
104
+ sendOptions: { to: recipients.map((recipient) => recipient.address).join(', '), subject, text },
105
+ });
106
+ return Boolean(info);
107
+ } finally {
108
+ // One delivery per dispatch: an open SMTP socket would outlive the
109
+ // command that sent it and keep the process from exiting.
110
+ MailerProvider.close(id);
111
+ }
112
+ },
113
+ },
114
+ };
115
+
116
+ /**
117
+ * @method eventNotificationRoutes
118
+ * @description Resolves where one event's notifications go.
119
+ *
120
+ * An unresolvable route is returned carrying its reason rather than thrown, so
121
+ * `--list` can show a broken contract before an outage does.
122
+ * @param {string} eventId - Registered event id.
123
+ * @param {object} [conf] - Parsed contract; read from disk when omitted.
124
+ * @returns {Array<{providerId: string, type: string, target: string, recipients: Array<object>, error?: string}>} Routes.
125
+ * @memberof UnderpostEventNotification
126
+ */
127
+ const eventNotificationRoutes = (eventId, conf = readEventConf()) => {
128
+ const providers = conf['notification-providers'] || {};
129
+ const notifications = conf.events?.[eventId]?.notifications || [];
130
+
131
+ if (notifications.length === 0)
132
+ return [
133
+ {
134
+ providerId: '',
135
+ type: '',
136
+ target: '',
137
+ recipients: [],
138
+ error: `no notification is declared for '${eventId}' in ${EVENT_CONF_PATH}`,
139
+ },
140
+ ];
141
+
142
+ return notifications.map((notification) => {
143
+ const providerId = `${notification['notification-provider-id'] || ''}`;
144
+ const provider = providers[providerId];
145
+ const recipients = (notification.payload?.subscribers || []).map(recipientFactory).filter(Boolean);
146
+ const route = { providerId, type: `${provider?.type || ''}`, target: '', recipients };
147
+
148
+ if (!provider)
149
+ return { ...route, error: `notification-provider-id '${providerId}' is not declared in ${EVENT_CONF_PATH}` };
150
+ const type = NOTIFICATION_PROVIDER_TYPES[route.type];
151
+ if (!type) return { ...route, error: `unsupported notification provider type '${route.type}'` };
152
+ if (recipients.length === 0) return { ...route, error: `provider '${providerId}' has no subscriber with an email` };
153
+ try {
154
+ return { ...route, target: type.describe(provider), provider };
155
+ } catch (error) {
156
+ return { ...route, error: `provider '${providerId}': ${error.message}` };
157
+ }
158
+ });
159
+ };
160
+
161
+ /**
162
+ * @method assertNotificationRoutes
163
+ * @description Refuses a contract that cannot deliver.
164
+ *
165
+ * Detection without a route to a human is the failure mode this guards: the
166
+ * remediation runs, nobody learns it ran, and a repeated repair goes unnoticed.
167
+ * @param {Array<object>} routes - Resolved routes, keyed by event id.
168
+ * @returns {Array<object>} The same routes, when every one resolves.
169
+ * @throws {Error} Naming each unresolved route.
170
+ * @memberof UnderpostEventNotification
171
+ */
172
+ const assertNotificationRoutes = (routes = []) => {
173
+ const unresolved = routes.filter((route) => route.error);
174
+ if (unresolved.length > 0)
175
+ throw new Error(
176
+ `[event] notification routes are unresolved:\n${unresolved.map((route) => `- ${route.error}`).join('\n')}`,
177
+ );
178
+ return routes;
179
+ };
180
+
181
+ /**
182
+ * @method deliverEventNotification
183
+ * @description Sends one rendered notification over every route the event declares.
184
+ *
185
+ * Routes are independent subscribers: one failing transport must not silence
186
+ * the rest, so each is attempted and reported separately.
187
+ * @param {object} params
188
+ * @param {string} params.eventId - Dispatched event id.
189
+ * @param {string} params.subject - Rendered subject.
190
+ * @param {string} params.text - Rendered body.
191
+ * @returns {Promise<{ok: boolean, delivered: Array<object>, failed: Array<object>}>} Per-route outcome.
192
+ * @memberof UnderpostEventNotification
193
+ */
194
+ const deliverEventNotification = async ({ eventId, subject, text }) => {
195
+ const routes = eventNotificationRoutes(eventId);
196
+ const delivered = [];
197
+ const failed = [];
198
+
199
+ for (const route of routes) {
200
+ const recipients = route.recipients.map((recipient) => recipient.email);
201
+ if (route.error) {
202
+ failed.push({ providerId: route.providerId, recipients, error: route.error });
203
+ continue;
204
+ }
205
+ try {
206
+ const ok = await NOTIFICATION_PROVIDER_TYPES[route.type].deliver({
207
+ providerId: route.providerId,
208
+ provider: route.provider,
209
+ recipients: route.recipients,
210
+ subject,
211
+ text,
212
+ });
213
+ if (ok) delivered.push({ providerId: route.providerId, recipients });
214
+ else failed.push({ providerId: route.providerId, recipients, error: 'transport rejected the message' });
215
+ } catch (error) {
216
+ failed.push({ providerId: route.providerId, recipients, error: `${error?.message || error}` });
217
+ }
218
+ }
219
+
220
+ for (const route of failed) logger.error('Event notification not delivered', { eventId, ...route });
221
+ if (delivered.length > 0) logger.info('Event notification delivered', { eventId, subject, routes: delivered });
222
+
223
+ return { ok: failed.length === 0 && delivered.length > 0, delivered, failed };
224
+ };
225
+
226
+ /**
227
+ * @method eventSchedule
228
+ * @description When an event's probes run, and how long its condition must hold
229
+ * before an alert fires.
230
+ *
231
+ * Both are declared per event in the contract rather than in the registry: how
232
+ * often a subject is asked and how long it must stay wrong are operational
233
+ * decisions tuned per deployment, and they are the two numbers Prometheus needs
234
+ * to schedule a job and evaluate the rule that job feeds. Reading them from one
235
+ * place is what stops a probe period and its alert window from drifting apart.
236
+ * @param {string} eventId - Registered event id.
237
+ * @param {object} [conf] - Parsed contract; read from disk when omitted.
238
+ * @returns {{probeInterval: string, alertFor: string, threshold: string}} Declared schedule; empty when undeclared.
239
+ * @memberof UnderpostEventNotification
240
+ */
241
+ const eventSchedule = (eventId, conf = readEventConf()) => {
242
+ const event = conf.events?.[eventId] || {};
243
+ return {
244
+ probeInterval: `${event.probeInterval || ''}`.trim(),
245
+ alertFor: `${event.alertFor || ''}`.trim(),
246
+ // A number the rule compares against: it belongs beside the cadence, not in
247
+ // an expression, because tuning it is a deployment decision.
248
+ threshold: `${event.threshold ?? ''}`.trim(),
249
+ };
250
+ };
251
+
252
+ /**
253
+ * @method assertEventSchedules
254
+ * @description Refuses to publish a rule whose cadence the contract does not declare.
255
+ *
256
+ * An undeclared period would silently inherit the global scrape interval and an
257
+ * undeclared window a hardcoded default — the second source of truth these
258
+ * attributes exist to remove.
259
+ * @param {Array<{id: string, schedule: object}>} [definitions] - Resolved definitions.
260
+ * @returns {Array<object>} The same definitions, when every schedule is declared.
261
+ * @throws {Error} Naming each event and the attribute it is missing.
262
+ * @memberof UnderpostEventNotification
263
+ */
264
+ const assertEventSchedules = (definitions = []) => {
265
+ const missing = definitions.flatMap(({ id, alert = {}, schedule = {} }) =>
266
+ ['probeInterval', 'alertFor', ...(`${alert.expr || ''}`.includes(THRESHOLD_TOKEN) ? ['threshold'] : [])]
267
+ .filter((key) => !schedule[key])
268
+ .map((key) => `- ${id}: ${key}`),
269
+ );
270
+ if (missing.length > 0) throw new Error(`[event] undeclared in ${EVENT_CONF_PATH}:\n${missing.join('\n')}`);
271
+ return definitions;
272
+ };
273
+
274
+ export {
275
+ EVENT_CONF_PATH,
276
+ THRESHOLD_TOKEN,
277
+ assertEventSchedules,
278
+ eventSchedule,
279
+ NOTIFICATION_PROVIDER_TYPES,
280
+ assertNotificationRoutes,
281
+ deliverEventNotification,
282
+ eventNotificationRoutes,
283
+ readEventConf,
284
+ };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Module for managing logger control and configuration
3
- * @module src/server/logger.js
3
+ * @module src/server/ops/logger.js
4
4
  * @namespace Logger
5
5
  */
6
6
 
@@ -11,7 +11,7 @@ import morgan from 'morgan';
11
11
  import { colorize, color } from 'json-colorizer';
12
12
  import colors from 'colors';
13
13
  import v8 from 'v8';
14
- import { clearTerminalStringColor, formatBytes } from '../client/components/core/CommonJs.js';
14
+ import { clearTerminalStringColor, formatBytes } from '../../client/components/core/CommonJs.js';
15
15
 
16
16
  colors.enable();
17
17
 
@@ -34,6 +34,93 @@ const levels = {
34
34
  */
35
35
  const level = (logLevel = '') => logLevel || 'info';
36
36
 
37
+ const REDACTED = '[REDACTED]';
38
+ const CONFIG_NAME_SOURCE = '[A-Za-z_][A-Za-z0-9_.-]*';
39
+ const SENSITIVE_VALUE_SOURCE = '(?:"[^"\\r\\n]*"|\'[^\'\\r\\n]*\'|[^\\s;&|]+)';
40
+ const SENSITIVE_WORDS = new Set([
41
+ 'authorization',
42
+ 'cookie',
43
+ 'credential',
44
+ 'pass',
45
+ 'passwd',
46
+ 'password',
47
+ 'secret',
48
+ 'token',
49
+ ]);
50
+ const SENSITIVE_COMPOUNDS = ['apikey', 'privatekey', 'accesskey', 'sessionid', 'mysqlpwd', 'mariadbpwd'];
51
+ const sensitiveField = (key) => {
52
+ const words = `${key || ''}`
53
+ .replace(/([a-z0-9])([A-Z])/g, '$1_$2')
54
+ .toLowerCase()
55
+ .split(/[^a-z0-9]+/)
56
+ .filter(Boolean);
57
+ const compact = words.join('');
58
+ return (
59
+ words.some((word) => SENSITIVE_WORDS.has(word)) ||
60
+ SENSITIVE_COMPOUNDS.some((compound) => compact.endsWith(compound))
61
+ );
62
+ };
63
+
64
+ const redactSensitiveText = (value = '') =>
65
+ `${value ?? ''}`
66
+ .replace(/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g, REDACTED)
67
+ .replace(
68
+ /\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|glpat-[A-Za-z0-9_-]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+)\b/g,
69
+ REDACTED,
70
+ )
71
+ .replace(/([a-z][a-z0-9+.-]*\\?:(?:\\?\/){2})(?:(?:\\.)|[^/\\\s@])+(\\?@)/gi, '$1***$2')
72
+ .replace(/\b(x-access-token\\?:)[^\s"']+?(?=\\?@github\.com\b)/gi, '$1***')
73
+ .replace(
74
+ /((?:"|')?(?:authorization|proxy-authorization)(?:"|')?\s*:\s*)(?:"[^"]*"|'[^']*'|(?:bearer|basic)\s+\S+|\S+)/gi,
75
+ `$1"${REDACTED}"`,
76
+ )
77
+ .replace(
78
+ new RegExp(
79
+ `(\\b(?:host|app|state|secret)\\s+set\\s+)(${CONFIG_NAME_SOURCE})(\\s+)(${SENSITIVE_VALUE_SOURCE})`,
80
+ 'gi',
81
+ ),
82
+ (match, prefix, key, separator) => (sensitiveField(key) ? `${prefix}${key}${separator}${REDACTED}` : match),
83
+ )
84
+ .replace(
85
+ new RegExp(`(\\s--?)(${CONFIG_NAME_SOURCE})(=|\\s+)(${SENSITIVE_VALUE_SOURCE})`, 'gi'),
86
+ (match, prefix, key, separator) => (sensitiveField(key) ? `${prefix}${key}${separator}${REDACTED}` : match),
87
+ )
88
+ .replace(
89
+ new RegExp(`(^|\\s)(-p)(\\s*)(${SENSITIVE_VALUE_SOURCE})`, 'gi'),
90
+ (match, prefix, flag, separator, secret) =>
91
+ secret.startsWith('-') ? match : `${prefix}${flag}${separator}${REDACTED}`,
92
+ )
93
+ .replace(
94
+ new RegExp(`\\b(${CONFIG_NAME_SOURCE})(\\s*=\\s*)(${SENSITIVE_VALUE_SOURCE})`, 'gi'),
95
+ (match, key, separator) => (sensitiveField(key) ? `${key}${separator}${REDACTED}` : match),
96
+ )
97
+ .replace(
98
+ new RegExp(`((?:"|')?)(${CONFIG_NAME_SOURCE})((?:"|')?\\s*:\\s*)(${SENSITIVE_VALUE_SOURCE})`, 'gi'),
99
+ (match, quote, key, separator) => (sensitiveField(key) ? `${quote}${key}${separator}"${REDACTED}"` : match),
100
+ );
101
+
102
+ const serializeLogValue = (value) => {
103
+ const seen = new WeakSet();
104
+ const serialized = JSON.stringify(
105
+ value,
106
+ (key, current) => {
107
+ if (key && sensitiveField(key)) return REDACTED;
108
+ if (typeof current === 'string') return redactSensitiveText(current);
109
+ if (typeof current === 'bigint') return `${current}`;
110
+ if (typeof current === 'function') return `[Function: ${current.name || 'anonymous'}]`;
111
+ if (current instanceof Error)
112
+ return Object.fromEntries(Object.getOwnPropertyNames(current).map((name) => [name, current[name]]));
113
+ if (typeof current === 'object' && current !== null) {
114
+ if (seen.has(current)) return '[Circular]';
115
+ seen.add(current);
116
+ }
117
+ return current;
118
+ },
119
+ 4,
120
+ );
121
+ return serialized === undefined ? redactSensitiveText(`${value ?? ''}`) : serialized;
122
+ };
123
+
37
124
  // Define different colors for each level.
38
125
  // Colors make the log message more visible,
39
126
  // adding the ability to focus or ignore messages.
@@ -49,7 +136,7 @@ winston.addColors({
49
136
  });
50
137
 
51
138
  // Chose the aspect of your log customizing the log format.
52
- const format = (meta) =>
139
+ const loggerFormatFactory = (meta) =>
53
140
  winston.format.combine(
54
141
  // winston.format.errors({ stack: true }),
55
142
  // Add the message timestamp with the preferred format
@@ -61,25 +148,13 @@ const format = (meta) =>
61
148
  const splatKey = Symbol.for('splat');
62
149
  const splat = info[splatKey];
63
150
  const hasSplat = Array.isArray(splat) && splat.length > 0 && splat[0] !== undefined;
64
- let splatStr = '';
65
- if (hasSplat) {
66
- const seen = new WeakSet();
67
- splatStr = JSON.stringify(
68
- splat[0],
69
- (key, value) => {
70
- if (typeof value === 'function') return `[Function: ${value.name || 'anonymous'}]`;
71
- if (typeof value === 'object' && value !== null) {
72
- if (seen.has(value)) return '[Circular]';
73
- seen.add(value);
74
- }
75
- return value;
76
- },
77
- 4,
78
- );
79
- }
151
+ const splatStr = hasSplat ? serializeLogValue(splat[0]) : '';
152
+ const message = redactSensitiveText(
153
+ info.message instanceof Error ? info.message.stack || info.message.message : info.message,
154
+ );
80
155
  return `${`[${meta}]`.green} ${info.timestamp} ${info.level} ${
81
156
  hasSplat
82
- ? `${clearTerminalStringColor(info.message)}: ${colorize(splatStr, {
157
+ ? `${clearTerminalStringColor(message)}: ${colorize(splatStr, {
83
158
  colors: {
84
159
  StringKey: color.green,
85
160
  StringLiteral: color.magenta,
@@ -88,7 +163,7 @@ const format = (meta) =>
88
163
  NullLiteral: color.white,
89
164
  },
90
165
  })}`
91
- : info.message
166
+ : message
92
167
  }`;
93
168
  }),
94
169
  );
@@ -158,7 +233,7 @@ const loggerFactory = (
158
233
  defaultMeta: meta,
159
234
  level: level(logLevel),
160
235
  levels,
161
- format: format(meta),
236
+ format: loggerFormatFactory(meta),
162
237
  transports,
163
238
  // exceptionHandlers: [new winston.transports.File({ filename: 'exceptions.log' })],
164
239
  // rejectionHandlers: [new winston.transports.File({ filename: 'rejections.log' })],
@@ -226,4 +301,14 @@ const actionInitLog = () =>
226
301
  `,
227
302
  );
228
303
 
229
- export { loggerFactory, loggerMiddleware, setUpInfo, underpostASCII, actionInitLog };
304
+ export {
305
+ REDACTED,
306
+ actionInitLog,
307
+ loggerFactory,
308
+ loggerFormatFactory,
309
+ loggerMiddleware,
310
+ redactSensitiveText,
311
+ serializeLogValue,
312
+ setUpInfo,
313
+ underpostASCII,
314
+ };