@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.
- package/.dockerignore +1 -0
- package/.env.example +16 -0
- package/.github/workflows/coverall.cyberia.ci.yml +107 -0
- package/.github/workflows/cyberia-client.cd.yml +6 -18
- package/.github/workflows/cyberia-server.cd.yml +6 -18
- package/.github/workflows/docker-image.cyberia-client.ci.yml +8 -5
- package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +8 -3
- package/.github/workflows/docker-image.cyberia-server.ci.yml +8 -5
- package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +8 -5
- package/.github/workflows/docker-image.engine-cyberia.ci.yml +15 -1
- package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +15 -1
- package/.github/workflows/engine-cyberia.cd.yml +6 -78
- package/.github/workflows/engine-cyberia.ci.yml +4 -5
- package/.github/workflows/ghpkg.ci.yml +42 -21
- package/.github/workflows/hardhat.ci.yml +12 -11
- package/.github/workflows/npmpkg.ci.yml +17 -15
- package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -16
- package/.github/workflows/pwa-microservices-template-test.ci.yml +2 -2
- package/.github/workflows/release.cd.yml +2 -9
- package/.prettierignore +1 -0
- package/AGENTS.md +47 -0
- package/CHANGELOG.md +581 -2417
- package/CLI-HELP.md +416 -127
- package/Dockerfile +25 -9
- package/Dockerfile.dev +25 -9
- package/Dockerfile.test +4 -4
- package/README.md +21 -1
- package/bin/build.js +70 -43
- package/bin/build.template.js +8 -3
- package/bin/cyberia.js +372 -135
- package/bin/deploy.js +18 -104
- package/bin/index.js +372 -135
- package/compose.env +16 -0
- package/conf.js +93 -4
- package/deploy/cyberia-client/deploy.sh +47 -0
- package/deploy/cyberia-client/package.sh +18 -0
- package/deploy/cyberia-client/state.sh +14 -0
- package/deploy/cyberia-server/deploy.sh +47 -0
- package/deploy/cyberia-server/package.sh +18 -0
- package/deploy/cyberia-server/state.sh +14 -0
- package/deploy/dd-cyberia/deploy.sh +22 -0
- package/deploy/dd-cyberia/init.sh +55 -0
- package/deploy/dd-cyberia/package.sh +17 -0
- package/deploy/dd-cyberia/state.sh +14 -0
- package/deploy/dd-cyberia/sync-deploy.sh +116 -0
- package/deploy/lib/github-actions-logging.sh +594 -0
- package/deploy/lib/host.sh +185 -0
- package/deploy/lib/state.sh +62 -0
- package/deploy/pwa-microservices-template/deploy.sh +45 -0
- package/deploy/release/deploy.sh +32 -0
- package/deployment.yaml +7 -2
- package/docker-compose.yml +31 -37
- package/examples/static-page/README.md +19 -19
- package/examples/static-page/ssr-components/CustomPage.js +2 -2
- package/hardhat/hardhat.config.js +1 -6
- package/hardhat/package-lock.json +104 -43
- package/hardhat/package.json +3 -3
- package/manifests/alertmanager/deployment.yaml +81 -0
- package/manifests/blackbox-exporter/deployment.yaml +75 -0
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +36 -7
- package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +77 -0
- package/manifests/deployment/dd-cyberia-development/deployment.yaml +7 -2
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
- package/manifests/grafana/deployment.yaml +26 -7
- package/manifests/grafana/kustomization.yaml +1 -0
- package/manifests/grafana/service.yaml +6 -1
- package/manifests/mariadb/pv.yaml +1 -0
- package/manifests/mongodb/statefulset.yaml +9 -2
- package/manifests/mysql/pv-pvc.yaml +14 -1
- package/manifests/postgresql/pv.yaml +12 -1
- package/manifests/postgresql/pvc.yaml +1 -0
- package/manifests/prometheus/deployment.yaml +18 -22
- package/package.json +83 -10
- package/scripts/audit-selinux.sh +64 -0
- package/scripts/event-monitor.sh +56 -0
- package/scripts/gpu-diag.sh +0 -0
- package/scripts/ip-info.sh +0 -0
- package/scripts/k3s-node-setup.sh +30 -14
- package/scripts/kubeadm-node-setup.sh +40 -31
- package/scripts/lxd-vm-setup.sh +0 -0
- package/scripts/maas-nat-firewalld.sh +0 -0
- package/scripts/maas-setup.sh +8 -8
- package/scripts/nat-iptables.sh +2 -0
- package/scripts/rhel-grpc-setup.sh +0 -0
- package/scripts/rocky-kickstart.sh +25 -9
- package/scripts/selinux-normalize.sh +907 -0
- package/scripts/shutdown-machine.sh +843 -0
- package/scripts/test-monitor.sh +3 -3
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +1 -1
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +2 -2
- package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +2 -2
- package/src/api/core/core.controller.js +1 -1
- package/src/api/core/core.router.js +2 -2
- package/src/api/core/core.service.js +2 -2
- package/src/api/crypto/crypto.controller.js +1 -1
- package/src/api/crypto/crypto.service.js +1 -1
- package/src/api/cyberia-action/cyberia-action.controller.js +1 -1
- package/src/api/cyberia-action/cyberia-action.router.js +1 -1
- package/src/api/cyberia-action/cyberia-action.service.js +2 -2
- package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +1 -1
- package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +1 -1
- package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +2 -2
- package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +1 -1
- package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +2 -2
- package/src/api/cyberia-entity/cyberia-entity.controller.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.router.js +1 -1
- package/src/api/cyberia-entity/cyberia-entity.service.js +2 -2
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +1 -1
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +1 -1
- package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +2 -2
- package/src/api/cyberia-instance/cyberia-fallback-capture.js +466 -0
- package/src/api/cyberia-instance/cyberia-fallback-default-items.js +63 -0
- package/src/api/cyberia-instance/cyberia-fallback-world.js +16 -1
- package/src/api/cyberia-instance/cyberia-instance-map.service.js +1 -1
- package/src/api/cyberia-instance/cyberia-instance.controller.js +4 -1
- package/src/api/cyberia-instance/cyberia-instance.router.js +15 -2
- package/src/api/cyberia-instance/cyberia-instance.service.js +45 -2
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +1 -0
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +1 -1
- package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +2 -2
- package/src/api/cyberia-map/cyberia-map.controller.js +1 -1
- package/src/api/cyberia-map/cyberia-map.router.js +1 -1
- package/src/api/cyberia-map/cyberia-map.service.js +2 -2
- package/src/api/cyberia-quest/cyberia-quest.controller.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.router.js +1 -1
- package/src/api/cyberia-quest/cyberia-quest.service.js +2 -2
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +1 -1
- package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +2 -2
- package/src/api/cyberia-saga/cyberia-saga.controller.js +1 -1
- package/src/api/cyberia-saga/cyberia-saga.router.js +1 -1
- package/src/api/cyberia-saga/cyberia-saga.service.js +2 -2
- package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +16 -29
- package/src/api/cyberia-skill/cyberia-skill.controller.js +1 -1
- package/src/api/cyberia-skill/cyberia-skill.router.js +1 -1
- package/src/api/cyberia-skill/cyberia-skill.service.js +2 -2
- package/src/api/default/default.controller.js +1 -1
- package/src/api/default/default.router.js +1 -1
- package/src/api/default/default.service.js +2 -2
- package/src/api/document/document.controller.js +1 -1
- package/src/api/document/document.router.js +1 -1
- package/src/api/document/document.service.js +2 -2
- package/src/api/file/file.controller.js +1 -1
- package/src/api/file/file.router.js +1 -1
- package/src/api/file/file.service.js +2 -2
- package/src/api/instance/instance.controller.js +1 -1
- package/src/api/instance/instance.router.js +1 -1
- package/src/api/instance/instance.service.js +2 -2
- package/src/api/ipfs/ipfs.controller.js +1 -1
- package/src/api/ipfs/ipfs.router.js +2 -2
- package/src/api/ipfs/ipfs.service.js +2 -2
- package/src/api/object-layer/object-layer.controller.js +1 -1
- package/src/api/object-layer/object-layer.model.js +204 -3
- package/src/api/object-layer/object-layer.router.js +2 -2
- package/src/api/object-layer/object-layer.service.js +4 -17
- package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +1 -1
- package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +1 -1
- package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +2 -2
- package/src/api/test/test.controller.js +1 -1
- package/src/api/test/test.service.js +1 -1
- package/src/api/user/guest.service.js +3 -3
- package/src/api/user/user.controller.js +1 -1
- package/src/api/user/user.router.js +2 -2
- package/src/api/user/user.service.js +4 -4
- package/src/api.js +5 -9
- package/src/cli/app.js +391 -0
- package/src/cli/baremetal.js +30 -36
- package/src/cli/client.js +306 -0
- package/src/cli/cloud-init.js +3 -3
- package/src/cli/cluster.js +242 -135
- package/src/cli/db.js +126 -67
- package/src/cli/deploy.js +158 -60
- package/src/cli/docker-compose.js +5 -5
- package/src/cli/domains.js +184 -0
- package/src/cli/dotenv-store.js +143 -0
- package/src/cli/event.js +2281 -0
- package/src/cli/fs.js +3 -3
- package/src/cli/host.js +672 -0
- package/src/cli/image.js +4 -7
- package/src/cli/index.js +426 -134
- package/src/cli/ipfs.js +34 -30
- package/src/cli/kickstart.js +1 -1
- package/src/cli/kubectl.js +218 -41
- package/src/cli/lxd.js +3 -3
- package/src/cli/monitor.js +1359 -26
- package/src/cli/package.js +90 -0
- package/src/cli/release.js +73 -34
- package/src/cli/repository.js +564 -367
- package/src/cli/run.js +362 -654
- package/src/cli/secrets.js +2158 -964
- package/src/cli/ssh.js +651 -331
- package/src/cli/state.js +394 -0
- package/src/cli/static.js +2 -2
- package/src/cli/system.js +26 -13
- package/src/cli/test.js +199 -125
- package/src/cli/vultr.js +623 -0
- package/src/cli/wireguard.js +2930 -0
- package/src/client/components/core/CalendarCore.js +53 -96
- package/src/client/components/core/Docs.js +258 -211
- package/src/client/components/core/FileExplorer.js +0 -21
- package/src/client/components/core/PanelForm.js +4 -4
- package/src/client/components/core/Repository.js +56 -0
- package/src/client/components/core/Translate.js +7 -0
- package/src/client/components/core/{FullScreen.js → ViewModeController.js} +42 -39
- package/src/client/components/core/Wallet.js +0 -11
- package/src/client/components/core/Worker.js +7 -1
- package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +2 -2
- package/src/client/components/cyberia/FallbackWorldEngineCyberia.js +368 -0
- package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +35 -1
- package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +4 -0
- package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +2 -2
- package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +4 -0
- package/src/client/components/default/AppShellDefault.js +1 -1
- package/src/client/components/default/SettingsDefault.js +2 -2
- package/src/client/components/itemledger/SettingsItemledger.js +2 -2
- package/src/client/components/underpost/AppShellUnderpost.js +3 -2
- package/src/client/components/underpost/SettingsUnderpost.js +2 -2
- package/src/client/public/cyberia-docs/ARCHITECTURE.md +17 -3
- package/src/client/public/cyberia-docs/CYBERIA-CLI.md +32 -5
- package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +1 -1
- package/src/client/public/cyberia-docs/CYBERIA.md +21 -1
- package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +23 -6
- package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
- package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
- package/src/client/public/default/android-chrome-144x144.png +0 -0
- package/src/client/public/default/android-chrome-192x192.png +0 -0
- package/src/client/public/default/android-chrome-256x256.png +0 -0
- package/src/client/public/default/android-chrome-36x36.png +0 -0
- package/src/client/public/default/android-chrome-384x384.png +0 -0
- package/src/client/public/default/android-chrome-48x48.png +0 -0
- package/src/client/public/default/android-chrome-512x512.png +0 -0
- package/src/client/public/default/android-chrome-72x72.png +0 -0
- package/src/client/public/default/android-chrome-96x96.png +0 -0
- package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
- package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
- package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
- package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
- package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
- package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
- package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
- package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
- package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
- package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
- package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
- package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
- package/src/client/public/default/apple-touch-icon.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
- package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
- package/src/client/public/default/assets/background/white.jpg +0 -0
- package/src/client/public/default/browserconfig.xml +1 -1
- package/src/client/public/default/favicon-16x16.png +0 -0
- package/src/client/public/default/favicon-32x32.png +0 -0
- package/src/client/public/default/favicon-48x48.png +0 -0
- package/src/client/public/default/favicon.ico +0 -0
- package/src/client/public/default/manifest.webmanifest +5 -5
- package/src/client/public/default/mstile-144x144.png +0 -0
- package/src/client/public/default/mstile-150x150.png +0 -0
- package/src/client/public/default/mstile-310x150.png +0 -0
- package/src/client/public/default/mstile-310x310.png +0 -0
- package/src/client/public/default/mstile-70x70.png +0 -0
- package/src/client/public/default/yandex-browser-50x50.png +0 -0
- package/src/client/public/default/yandex-browser-manifest.json +1 -1
- package/src/client/services/cyberia-instance/cyberia-instance.service.js +40 -0
- package/src/client/services/object-layer/object-layer.management.js +4 -4
- package/src/client/ssr/RootDocument.js +1 -1
- package/src/client/ssr/body/404.js +1 -1
- package/src/client/ssr/body/500.js +1 -1
- package/src/client/ssr/body/CacheControl.js +1 -1
- package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +1 -1
- package/src/client/ssr/body/DefaultSplashScreen.js +1 -1
- package/src/client/ssr/body/SwaggerDarkMode.js +1 -1
- package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +1 -1
- package/src/client/ssr/head/CryptokoynScripts.js +1 -1
- package/src/client/ssr/head/Css.js +1 -1
- package/src/client/ssr/head/CyberiaPortalScripts.js +1 -1
- package/src/client/ssr/head/DefaultScripts.js +1 -1
- package/src/client/ssr/head/ItemledgerScripts.js +1 -1
- package/src/client/ssr/head/Microdata.js +1 -1
- package/src/client/ssr/head/Production.js +1 -1
- package/src/client/ssr/head/Pwa.js +1 -1
- package/src/client/ssr/head/PwaItemledger.js +1 -1
- package/src/client/ssr/head/Seo.js +1 -1
- package/src/client/ssr/head/UnderpostScripts.js +1 -1
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +1 -1
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +1 -1
- package/src/client/ssr/views/Cyberia404.js +7 -5
- package/src/client/ssr/views/CyberiaServerMetrics.js +1 -1
- package/src/client/ssr/views/Maintenance.js +1 -1
- package/src/client/ssr/views/NoNetworkConnection.js +1 -1
- package/src/client/ssr/views/Test.js +1 -1
- package/src/client/sw/core.sw.js +20 -14
- package/src/client-builder/client-build-docs.js +61 -46
- package/src/client-builder/client-build-live.js +2 -2
- package/src/client-builder/client-build.js +58 -44
- package/src/client-builder/client-dev-server.js +3 -3
- package/src/client-builder/client-icons.js +2 -2
- package/src/client-builder/ssr.js +3 -3
- package/src/client.build.js +3 -6
- package/src/client.dev.js +3 -6
- package/src/db/DataBaseProvider.js +186 -3
- package/src/db/mariadb/MariaDB.js +3 -2
- package/src/db/mongo/MongoBootstrap.js +273 -101
- package/src/db/mongo/MongooseDB.js +11 -8
- package/src/{server/valkey.js → db/valkey/Valkey.js} +5 -4
- package/src/grpc/cyberia/grpc-server.js +1 -1
- package/src/index.js +103 -23
- package/src/mailer/EmailRender.js +2 -2
- package/src/mailer/MailerInterceptor.js +87 -0
- package/src/mailer/MailerProvider.js +50 -6
- package/src/projects/cyberia/atlas-sprite-sheet-generator.js +1 -1
- package/src/projects/cyberia/besu-genesis-generator.js +3 -3
- package/src/projects/cyberia/catalog-cyberia.js +54 -6
- package/src/projects/cyberia/gemini-client.js +1 -1
- package/src/projects/cyberia/generate-saga.js +15 -24
- package/src/projects/cyberia/hot-reload-trigger.js +1 -1
- package/src/projects/cyberia/instance-data.js +22 -3
- package/src/projects/cyberia/ipfs-client.js +4 -4
- package/src/projects/cyberia/map-preview-generator.js +1 -1
- package/src/projects/cyberia/object-layer.js +12 -22
- package/src/projects/cyberia/semantic-layer-generator.js +1 -1
- package/src/projects/underpost/catalog-underpost.js +13 -2
- package/src/proxy.js +4 -7
- package/src/runtime/cyberia-client/Dockerfile +9 -4
- package/src/runtime/cyberia-client/Dockerfile.dev +8 -2
- package/src/runtime/cyberia-server/Dockerfile +9 -4
- package/src/runtime/cyberia-server/Dockerfile.dev +8 -2
- package/src/runtime/engine-cyberia/Dockerfile +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.dev +25 -9
- package/src/runtime/engine-cyberia/Dockerfile.test +4 -4
- package/src/runtime/engine-cyberia/compose.env +16 -0
- package/src/runtime/engine-cyberia/docker-compose.yml +31 -37
- package/src/runtime/express/Express.js +32 -27
- package/src/runtime/lampp/Lampp.js +22 -70
- package/src/runtime/nginx/Nginx.js +1 -1
- package/src/runtime/wp/Wp.js +16 -48
- package/src/server/{catalog.js → build/catalog.js} +15 -5
- package/src/server/build/coverage.js +117 -0
- package/src/server/build/execution.js +402 -0
- package/src/server/build/package.js +465 -0
- package/src/server/build/testing.js +528 -0
- package/src/server/{dns.js → network/dns.js} +241 -14
- package/src/server/network/forward-proxy.js +541 -0
- package/src/server/{middlewares.js → network/middlewares.js} +59 -4
- package/src/server/network/node-capability.js +98 -0
- package/src/server/{peer.js → network/peer.js} +3 -3
- package/src/server/{proxy.js → network/proxy.js} +7 -13
- package/src/server/network/router.js +356 -0
- package/src/server/{tls.js → network/tls.js} +2 -2
- package/src/server/network/underpost-compression.js +186 -0
- package/src/server/{underpost-gateway.js → network/underpost-gateway.js} +26 -16
- package/src/server/{underpost-ingress.js → network/underpost-ingress.js} +19 -3
- package/src/server/{cri.js → ops/cri.js} +2 -2
- package/src/server/ops/cron.js +949 -0
- package/src/server/ops/event-notification.js +284 -0
- package/src/server/{logger.js → ops/logger.js} +108 -23
- package/src/server/ops/monitoring.js +1724 -0
- package/src/server/ops/systemd.js +259 -0
- package/src/server/{conf.js → runtime/conf.js} +521 -520
- package/src/server/runtime/config-scope.js +215 -0
- package/src/server/runtime/environment.js +149 -0
- package/src/server/{process.js → runtime/process.js} +153 -13
- package/src/server/{runtime-status.js → runtime/runtime-status.js} +155 -16
- package/src/server/{runtime.js → runtime/runtime.js} +12 -8
- package/src/server/{start.js → runtime/start.js} +128 -39
- package/src/server/{auth.js → security/auth.js} +7 -8
- package/src/server/security/container-storage.js +382 -0
- package/src/server/{crypto.js → security/crypto.js} +1 -1
- package/src/server/security/selinux.js +185 -0
- package/src/server/{backup.js → storage/backup.js} +17 -8
- package/src/server/{data-query.js → storage/data-query.js} +1 -1
- package/src/server/{downloader.js → storage/downloader.js} +2 -2
- package/src/server/storage/repository.js +68 -0
- package/src/server.js +4 -7
- package/src/ws/IoInterface.js +1 -1
- package/src/ws/IoServer.js +1 -1
- package/src/ws/core/core.ws.connection.js +1 -1
- package/src/ws/core/core.ws.emit.js +1 -1
- package/src/ws/core/core.ws.server.js +1 -1
- package/src/ws/default/default.ws.connection.js +1 -1
- package/src/ws/default/default.ws.emit.js +1 -1
- package/src/ws/default/default.ws.server.js +1 -1
- package/test/e2e/event-e2e-public-ingress-down.js +45 -0
- package/test/e2e/event-e2e-wireguard-server-down.js +38 -0
- package/test/e2e/event-e2e-wireguard-spoke-down.js +40 -0
- package/test/{api.test.js → integration/app/api.test.js} +33 -14
- package/test/integration/app/cyberia/cyberia-cli-plain-reads.test.js +30 -0
- package/test/{cyberia-instance-conf-defaults.test.js → integration/app/cyberia/cyberia-instance-conf-defaults.test.js} +2 -1
- package/test/integration/app/cyberia/cyberia-load.test.js +467 -0
- package/test/integration/app/cyberia/fallback-world-capture.test.js +253 -0
- package/test/integration/app/cyberia/object-layer-item-id.test.js +327 -0
- package/test/{shape-generator.test.js → integration/app/cyberia/shape-generator.test.js} +1 -1
- package/test/integration/infra/1-security/config-scope.test.js +305 -0
- package/test/integration/infra/1-security/container-storage.test.js +356 -0
- package/test/integration/infra/1-security/in-pod-cli-surface.test.js +86 -0
- package/test/integration/infra/1-security/secret-onboarding.test.js +930 -0
- package/test/integration/infra/1-security/selinux.test.js +69 -0
- package/test/{sops-secret-store.test.js → integration/infra/1-security/sops-secret-store.test.js} +415 -61
- package/test/integration/infra/1-security/systemd-service.test.js +70 -0
- package/test/integration/infra/1-security/underpost-config-secret.test.js +367 -0
- package/test/integration/infra/2-network/dns-firewall.test.js +566 -0
- package/test/integration/infra/2-network/node-capability.test.js +182 -0
- package/test/integration/infra/2-network/wireguard-cli.test.js +1163 -0
- package/test/integration/infra/2-network/wireguard-edge.test.js +1731 -0
- package/test/{cluster-instances.test.js → integration/infra/3-cluster/cluster-instances.test.js} +11 -15
- package/test/{deploy-node-placement.test.js → integration/infra/3-cluster/deploy-node-placement.test.js} +3 -3
- package/test/integration/infra/3-cluster/docker-compose-stack.test.js +313 -0
- package/test/integration/infra/4-ingress/deploy-routes.test.js +379 -0
- package/test/integration/infra/4-ingress/gateway-static-assets.test.js +453 -0
- package/test/{instance-traffic-plan.test.js → integration/infra/4-ingress/instance-traffic-plan.test.js} +10 -6
- package/test/{underpost-gateway.test.js → integration/infra/4-ingress/underpost-gateway.test.js} +47 -6
- package/test/{underpost-ingress.test.js → integration/infra/4-ingress/underpost-ingress.test.js} +56 -4
- package/test/integration/infra/5-observability/cron-jobs.test.js +652 -0
- package/test/{deploy-monitor.test.js → integration/infra/5-observability/deploy-monitor.test.js} +29 -31
- package/test/integration/infra/5-observability/event-notification.test.js +197 -0
- package/test/integration/infra/5-observability/event-remediation.test.js +502 -0
- package/test/integration/infra/5-observability/event-targets.test.js +1174 -0
- package/test/integration/infra/5-observability/monitoring-stack.test.js +902 -0
- package/test/support/shell-harness.js +73 -0
- package/test/unit/build-template.test.js +97 -0
- package/test/unit/build-workflow-offline.test.js +132 -0
- package/test/unit/catalog.test.js +71 -0
- package/test/unit/client-build-docs.test.js +334 -0
- package/test/unit/conf-loading.test.js +303 -0
- package/test/unit/conf-resolution.test.js +979 -0
- package/test/unit/coverage-artifact.test.js +130 -0
- package/test/{crypto.test.js → unit/crypto.test.js} +1 -1
- package/test/unit/deploy-env-resolution.test.js +38 -0
- package/test/unit/deploy-log-table.test.js +447 -0
- package/test/unit/execution-profiles.test.js +219 -0
- package/test/unit/fleet-sync-source.test.js +149 -0
- package/test/unit/logger-redaction.test.js +112 -0
- package/test/unit/package.test.js +403 -0
- package/test/unit/prepare-host.test.js +299 -0
- package/test/unit/process-environment.test.js +18 -0
- package/test/unit/propagation-message.test.js +78 -0
- package/test/unit/redeploy-plan.test.js +24 -0
- package/test/unit/release-bump.test.js +474 -0
- package/test/unit/ssh-output-redaction.test.js +28 -0
- package/test/unit/start-options.test.js +46 -0
- package/test/unit/test-tiers.test.js +193 -0
- package/vitest.config.js +58 -0
- package/.nycrc +0 -9
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +0 -48
- package/manifests/mongodb/pv-pvc.yaml +0 -59
- package/scripts/link-local-underpost-cli.sh +0 -6
- package/src/api/user/user.build.js +0 -16
- package/src/cli/env.js +0 -177
- package/src/client/components/core/Blockchain.js +0 -41
- package/src/client/components/core/Blog.js +0 -9
- package/src/client/components/core/KeyboardAvoidance.js +0 -145
- package/src/client/public/default/assets/background/dark.jpg +0 -0
- package/src/client/public/default/assets/background/white0-min.jpg +0 -0
- package/src/client/public/default/assets/background/white0.jpg +0 -0
- package/src/client/public/doc/favicon.ico +0 -0
- package/src/client/public/doc/sitemap +0 -148
- 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 '
|
|
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
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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(
|
|
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
|
-
:
|
|
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:
|
|
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 {
|
|
304
|
+
export {
|
|
305
|
+
REDACTED,
|
|
306
|
+
actionInitLog,
|
|
307
|
+
loggerFactory,
|
|
308
|
+
loggerFormatFactory,
|
|
309
|
+
loggerMiddleware,
|
|
310
|
+
redactSensitiveText,
|
|
311
|
+
serializeLogValue,
|
|
312
|
+
setUpInfo,
|
|
313
|
+
underpostASCII,
|
|
314
|
+
};
|