@underpostnet/cyberia 3.3.76 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/.env.example +1 -0
  2. package/.github/workflows/coverall.cyberia.ci.yml +17 -3
  3. package/.github/workflows/cyberia-client.cd.yml +2 -1
  4. package/.github/workflows/cyberia-server.cd.yml +2 -1
  5. package/.github/workflows/docker-image.cyberia-client.ci.yml +1 -1
  6. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +1 -1
  7. package/.github/workflows/docker-image.cyberia-server.ci.yml +1 -1
  8. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +1 -1
  9. package/.github/workflows/docker-image.engine-cyberia.ci.yml +1 -1
  10. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +1 -1
  11. package/.github/workflows/engine-cyberia.ci.yml +7 -1
  12. package/.github/workflows/ghpkg.ci.yml +19 -2
  13. package/.github/workflows/gitlab.ci.yml +8 -6
  14. package/.github/workflows/hardhat.ci.yml +4 -1
  15. package/.github/workflows/npmpkg.ci.yml +9 -5
  16. package/.github/workflows/publish.ci.yml +21 -12
  17. package/.github/workflows/publish.cyberia.ci.yml +25 -14
  18. package/.github/workflows/pwa-microservices-template-page.cd.yml +4 -2
  19. package/CHANGELOG.md +110 -262
  20. package/CLI-HELP.md +29 -2
  21. package/Dockerfile +1 -1
  22. package/Dockerfile.dev +1 -1
  23. package/Dockerfile.test +1 -1
  24. package/README.md +1 -1
  25. package/bin/build.js +67 -14
  26. package/bin/cyberia.js +4 -4
  27. package/bin/index.js +4 -4
  28. package/compose.env +1 -0
  29. package/conf.js +1 -1043
  30. package/deploy/cyberia-client/deploy.sh +13 -11
  31. package/deploy/cyberia-server/deploy.sh +13 -11
  32. package/deploy/dd-cyberia/sync-deploy.sh +7 -28
  33. package/deploy/lib/config.sh +1 -1
  34. package/deploy/lib/github-actions-logging.sh +3 -2
  35. package/deploy/lib/host.sh +1 -1
  36. package/deploy/pwa-microservices-template/deploy.sh +7 -1
  37. package/deployment.yaml +1 -1
  38. package/docker-compose.yml +7 -7
  39. package/docs/coverage/cyberia/api/cyberia-instance/cyberia-fallback-capture.js.html +1591 -0
  40. package/docs/coverage/cyberia/api/cyberia-instance/index.html +116 -0
  41. package/docs/coverage/cyberia/api/cyberia-server-defaults/cyberia-server-defaults.js.html +4138 -0
  42. package/docs/coverage/cyberia/api/cyberia-server-defaults/index.html +116 -0
  43. package/docs/coverage/cyberia/api/object-layer/index.html +116 -0
  44. package/docs/coverage/cyberia/api/object-layer/object-layer.model.js.html +1393 -0
  45. package/docs/coverage/cyberia/base.css +362 -0
  46. package/docs/coverage/cyberia/block-navigation.js +82 -0
  47. package/docs/coverage/cyberia/favicon.png +0 -0
  48. package/docs/coverage/cyberia/index.html +161 -0
  49. package/docs/coverage/cyberia/prettify.css +101 -0
  50. package/docs/coverage/cyberia/prettify.js +937 -0
  51. package/docs/coverage/cyberia/projects/cyberia/atlas-sprite-sheet-generator.js.html +1315 -0
  52. package/docs/coverage/cyberia/projects/cyberia/index.html +176 -0
  53. package/docs/coverage/cyberia/projects/cyberia/instance-backup.js.html +715 -0
  54. package/docs/coverage/cyberia/projects/cyberia/instance-data.js.html +2182 -0
  55. package/docs/coverage/cyberia/projects/cyberia/shape-generator.js.html +3265 -0
  56. package/docs/coverage/cyberia/projects/cyberia/stat-balance.js.html +328 -0
  57. package/docs/coverage/cyberia/sort-arrow-sprite.png +0 -0
  58. package/docs/coverage/cyberia/sorter.js +205 -0
  59. package/hardhat/package-lock.json +6 -6
  60. package/hardhat/package.json +2 -2
  61. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  62. package/manifests/cronjobs/dd-cron/dd-cron-vultr.yaml +1 -1
  63. package/manifests/deployment/dd-cyberia-development/deployment.yaml +1 -1
  64. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  65. package/package.json +19 -17
  66. package/scripts/test-monitor.sh +1 -1
  67. package/src/api/file/file.router.js +7 -1
  68. package/src/cli/baremetal.js +1 -1
  69. package/src/cli/cluster.js +73 -18
  70. package/src/cli/deploy.js +211 -30
  71. package/src/cli/docker-compose.js +1 -1
  72. package/src/cli/index.js +36 -0
  73. package/src/cli/kubectl.js +4 -3
  74. package/src/cli/release.js +5 -1
  75. package/src/cli/repository.js +14 -11
  76. package/src/cli/run.js +10 -3
  77. package/src/cli/secrets.js +393 -200
  78. package/src/cli/socketsecurity.js +260 -0
  79. package/src/client/components/core/Badge.js +0 -1
  80. package/src/client/components/core/CssCore.js +11 -1
  81. package/src/client/components/core/Modal.js +189 -66
  82. package/src/client/components/core/SearchBox.js +0 -1
  83. package/src/client/components/core/ToolTip.js +15 -0
  84. package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +0 -2
  85. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +0 -4
  86. package/src/client/components/default/AppShellDefault.js +1 -4
  87. package/src/client/components/itemledger/AppShellItemledger.js +0 -2
  88. package/src/client/components/underpost/AppShellUnderpost.js +12 -0
  89. package/src/client/components/underpost/CssUnderpost.js +15 -2
  90. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +8 -0
  91. package/src/client/public/cyberia-docs/CYBERIA.md +1 -1
  92. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +54 -56
  93. package/src/client/public/cyberia-docs/ROADMAP.md +1 -1
  94. package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +30 -29
  95. package/src/client/public/cyberia-docs/WHITE-PAPER.md +1 -1
  96. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +54 -25
  97. package/src/client/ssr/head/Css.js +12 -10
  98. package/src/client/ssr/views/Cyberia404.js +9 -13
  99. package/src/client/ssr/views/NotFound.js +75 -0
  100. package/src/client-builder/client-bundle.js +2 -2
  101. package/src/index.js +13 -1
  102. package/src/runtime/engine-cyberia/Dockerfile +1 -1
  103. package/src/runtime/engine-cyberia/Dockerfile.dev +1 -1
  104. package/src/runtime/engine-cyberia/Dockerfile.test +1 -1
  105. package/src/runtime/engine-cyberia/compose.env +1 -0
  106. package/src/runtime/engine-cyberia/docker-compose.yml +7 -7
  107. package/src/server/build/catalog.js +1 -0
  108. package/src/server/build/execution.js +19 -5
  109. package/src/server/build/package.js +166 -3
  110. package/src/server/build/testing.js +2 -1
  111. package/src/server/network/underpost-gateway.js +113 -14
  112. package/src/server/runtime/conf.js +57 -7
  113. package/src/server/runtime/config-scope.js +2 -0
  114. package/src/server/runtime/process.js +4 -3
  115. package/src/server/runtime/start.js +11 -2
  116. package/src/server/security/socketsecurity.js +1735 -0
  117. package/test/integration/infra/1-security/config-scope.test.js +3 -0
  118. package/test/integration/infra/1-security/socketsecurity.test.js +1041 -0
  119. package/test/integration/infra/1-security/sops-secret-store.test.js +201 -71
  120. package/test/integration/infra/4-ingress/underpost-ingress.test.js +1 -1
  121. package/test/unit/build-template.test.js +24 -0
  122. package/test/unit/catalog.test.js +13 -2
  123. package/test/unit/conf-resolution.test.js +41 -7
  124. package/test/unit/cyberia/instance-data.test.js +314 -0
  125. package/test/unit/deploy-legacy-gateway-sweep.test.js +63 -0
  126. package/test/unit/deploy-log-table.test.js +38 -0
  127. package/test/unit/execution-profiles.test.js +1 -0
  128. package/test/unit/gateway-pod-fetch.test.js +95 -0
  129. package/test/unit/letsencrypt-issuer.test.js +101 -0
  130. package/test/unit/package.test.js +118 -0
  131. package/test/unit/release-bump.test.js +3 -1
  132. package/test/unit/start-options.test.js +12 -0
@@ -0,0 +1,260 @@
1
+ /**
2
+ * Socket security domain: the security audit of a checkout — the packages it installs and its own
3
+ * source code — and the patches it carries.
4
+ *
5
+ * {@link module:src/server/security/socketsecurity.js} owns the Socket CLI integration and the
6
+ * report; this domain is the operator surface over it: the audit a person or a workflow runs,
7
+ * the remediation pass, and the `prepare` hook that replays the patch manifest.
8
+ * @module src/cli/socketsecurity.js
9
+ * @namespace UnderpostSocketSecurity
10
+ */
11
+
12
+ import fs from 'fs-extra';
13
+ import nodePath from 'node:path';
14
+ import { auditRuntimeDependencies } from '../server/build/package.js';
15
+ import { loggerFactory } from '../server/ops/logger.js';
16
+ import SocketSecurityService, {
17
+ fix,
18
+ npmAudit,
19
+ packageAlerts,
20
+ npmAuditFix,
21
+ patchApply,
22
+ patchGet,
23
+ patchManifestFactory,
24
+ patchScan,
25
+ patchSelectionFactory,
26
+ patchSetup,
27
+ publishedPackagesFactory,
28
+ reportViolates,
29
+ scan,
30
+ securityReportFactory,
31
+ socketEnvFactory,
32
+ socketVersion,
33
+ writeSecurityReports,
34
+ } from '../server/security/socketsecurity.js';
35
+ import Underpost from '../index.js';
36
+
37
+ const logger = loggerFactory(import.meta);
38
+
39
+ /**
40
+ * @class UnderpostSocketSecurity
41
+ * @description Audits a checkout's dependencies and source code through Socket, and remediates and patches its dependencies.
42
+ * @memberof UnderpostSocketSecurity
43
+ */
44
+ class UnderpostSocketSecurity {
45
+ static API = {
46
+ /**
47
+ * @method audit
48
+ * @description Runs the audit and writes its reports. Dependency security: segregation,
49
+ * `npm audit`, the Socket patch scan and, with an API token, the Socket full scan with the
50
+ * local reachability analysis when asked. Source code risk: with an API token, the alerts
51
+ * Socket's registry analysis raises on this project's own published package, as refactoring
52
+ * tasks at their locations.
53
+ * @param {object} [params]
54
+ * @param {string} [params.root] - Checkout to audit.
55
+ * @param {string} [params.out] - Report directory.
56
+ * @param {boolean} [params.reach] - Run the reachability analysis with the scan.
57
+ * @param {object} [params.remediation] - Actions a remediation pass took before this audit.
58
+ * @returns {Promise<object>} The report, with the files written.
59
+ * @memberof UnderpostSocketSecurity
60
+ */
61
+ async audit({
62
+ root = process.cwd(),
63
+ out = nodePath.join(root, SocketSecurityService.REPORT_DIRECTORY),
64
+ reach = false,
65
+ remediation = {},
66
+ } = {}) {
67
+ const env = socketEnvFactory();
68
+ const dependencies = await auditRuntimeDependencies({ root });
69
+ const audit = npmAudit({ root });
70
+ const patches = patchScan({ root, env });
71
+ if (reach && !env.token)
72
+ logger.warn('Reachability analysis needs a Socket API token', { variable: SocketSecurityService.ENV.token });
73
+ const scanResult = env.token ? scan({ root, env, reach }) : null;
74
+ const packageJson = fs.readJsonSync(nodePath.join(root, 'package.json'));
75
+ const ownPackages = SocketSecurityService.ownPackageNamesFactory({ packageJson });
76
+ const ownAlerts = env.token
77
+ ? packageAlerts({ root, env, packages: publishedPackagesFactory({ root, packageJson, ownPackages }) })
78
+ : null;
79
+ const report = securityReportFactory({
80
+ root,
81
+ packageJson,
82
+ ownPackages,
83
+ dependencies,
84
+ npmAudit: audit.summary,
85
+ scan: scanResult,
86
+ packageAlerts: ownAlerts,
87
+ patchScan: patches,
88
+ manifest: patchManifestFactory(root),
89
+ remediation,
90
+ env,
91
+ cliVersion: socketVersion({ root }),
92
+ });
93
+ const files = writeSecurityReports({
94
+ report,
95
+ directory: out,
96
+ artifacts: {
97
+ npmAudit: audit.raw,
98
+ scan: scanResult?.report ?? null,
99
+ scanArtifacts: scanResult?.artifacts ?? null,
100
+ packageAlerts: ownAlerts?.artifacts ?? null,
101
+ reach: scanResult?.facts ?? null,
102
+ patchScan: patches.data,
103
+ },
104
+ });
105
+ const { dependencySecurity: dependency, sourceCodeRisk: source } = report;
106
+ logger.info('Security audit complete', {
107
+ scan: report.scan.skipped ?? { healthy: report.scan.healthy, url: report.scan.url },
108
+ dependencySecurity: {
109
+ findings: dependency.counts,
110
+ misplacedDependencies: dependency.segregation.misplaced.map(({ name }) => name),
111
+ patchesAvailable: dependency.patches.scan.available.length,
112
+ patchesInManifest: dependency.patches.manifest.patches.length,
113
+ deferred: dependency.deferred.length,
114
+ },
115
+ sourceCodeRisk: {
116
+ status: source.status,
117
+ analyzed: source.analyzed.map(({ name, version }) => `${name}@${version}`),
118
+ findings: source.counts,
119
+ tasks: source.tasks.map(({ label, locations }) => `${label}: ${locations.length}`),
120
+ },
121
+ files,
122
+ });
123
+ return { ...report, files };
124
+ },
125
+
126
+ /**
127
+ * @method remediate
128
+ * @description The non-breaking remediation pass: `npm audit fix`, every available Socket
129
+ * patch, `socket fix` without major upgrades unless allowed, and a final manifest apply.
130
+ * @param {object} [params]
131
+ * @param {string} [params.root] - Checkout to remediate.
132
+ * @param {string} [params.out] - Directory `socket fix` writes its upgrade list into.
133
+ * @param {boolean} [params.majorUpdates] - Let `socket fix` apply major upgrades.
134
+ * @returns {Promise<object>} Results by action name.
135
+ * @memberof UnderpostSocketSecurity
136
+ */
137
+ async remediate({
138
+ root = process.cwd(),
139
+ out = nodePath.join(root, SocketSecurityService.REPORT_DIRECTORY),
140
+ majorUpdates = false,
141
+ } = {}) {
142
+ const env = socketEnvFactory();
143
+ fs.ensureDirSync(out);
144
+ const actions = { 'npm audit fix': npmAuditFix({ root }) };
145
+ const { selected, skipped } = patchSelectionFactory(patchScan({ root, env }).summary.available);
146
+ actions['socket patch get'] = [
147
+ ...selected.map(({ uuid, purl }) => {
148
+ const { ok, message } = patchGet({ root, env, identifier: uuid });
149
+ return { uuid, purl, ok, message };
150
+ }),
151
+ ...skipped.map(({ uuid, purl, reason }) => ({ uuid, purl, skipped: reason })),
152
+ ];
153
+ actions['socket fix'] = env.token
154
+ ? fix({
155
+ root,
156
+ env,
157
+ majorUpdates,
158
+ outputFile: nodePath.join(out, SocketSecurityService.REPORT_FILES.fixUpgrades),
159
+ })
160
+ : { skipped: `${SocketSecurityService.ENV.token} is not set` };
161
+ actions['socket patch apply'] = patchApply({ root, env });
162
+ logger.info('Remediation pass complete', actions);
163
+ return actions;
164
+ },
165
+
166
+ /**
167
+ * @method applyPatches
168
+ * @description Applies the patch manifest; the `prepare` hook. A host without the
169
+ * Socket CLI and a checkout without a manifest are both no-ops, a patch that fails to apply
170
+ * fails the install.
171
+ * @param {object} [params]
172
+ * @param {string} [params.root] - Checkout to patch.
173
+ * @param {boolean} [params.dryRun] - Verify without writing.
174
+ * @returns {object} The apply result.
175
+ * @throws {Error} When a recorded patch does not apply.
176
+ * @memberof UnderpostSocketSecurity
177
+ */
178
+ applyPatches({ root = process.cwd(), dryRun = false } = {}) {
179
+ const result = patchApply({ root, dryRun });
180
+ if (result.unavailable) {
181
+ logger.info('Socket CLI not installed; patch manifest not applied', {
182
+ install: `npm install -g ${SocketSecurityService.CLI_PACKAGE}`,
183
+ });
184
+ return result;
185
+ }
186
+ if (!result.ok || result.failed > 0)
187
+ throw new Error(
188
+ `[socketsecurity] patch apply failed: ${result.message || `${result.failed} patch(es) failed`}`,
189
+ );
190
+ logger.info(result.status === 'no_manifest' ? 'No patch manifest to apply' : 'Patch manifest applied', {
191
+ manifest: SocketSecurityService.MANIFEST_PATH,
192
+ patchesApplied: result.patchesApplied,
193
+ alreadyPatched: result.alreadyPatched,
194
+ dryRun,
195
+ });
196
+ return result;
197
+ },
198
+
199
+ /**
200
+ * @method callback
201
+ * @description `underpost socketsecurity` entrypoint. Without an operation flag it runs the
202
+ * audit.
203
+ * @param {object} [options]
204
+ * @param {boolean} [options.audit] - Run the audit and write the reports.
205
+ * @param {boolean} [options.reach] - Include the reachability analysis in the scan.
206
+ * @param {boolean} [options.ci] - Audit, then fail on a policy violation or a finding at `--fail-on`.
207
+ * @param {string} [options.failOn] - Severity `--ci` fails at.
208
+ * @param {boolean} [options.fix] - Run the remediation pass before the audit.
209
+ * @param {boolean} [options.major] - Let the remediation pass apply major upgrades.
210
+ * @param {boolean} [options.patchScan] - Scan the installed packages for available patches.
211
+ * @param {string} [options.patchGet] - Download and apply one patch.
212
+ * @param {boolean} [options.patchApply] - Apply the patch manifest.
213
+ * @param {boolean} [options.patchSetup] - Install the `prepare` hook.
214
+ * @param {string} [options.out] - Report directory.
215
+ * @param {boolean} [options.dryRun] - Preview `--patch-setup`; verify only for `--patch-apply`.
216
+ * @returns {Promise<object>} The operation result.
217
+ * @memberof UnderpostSocketSecurity
218
+ */
219
+ async callback(options = {}) {
220
+ const root = process.cwd();
221
+ const out = nodePath.resolve(root, options.out || SocketSecurityService.REPORT_DIRECTORY);
222
+ const dryRun = options.dryRun === true;
223
+
224
+ if (options.patchSetup) {
225
+ const result = patchSetup({ root, dryRun });
226
+ logger.info(
227
+ result.changed ? `prepare hook ${dryRun ? 'to install' : 'installed'}` : 'prepare hook present',
228
+ result,
229
+ );
230
+ return result;
231
+ }
232
+ if (options.patchApply) return Underpost.socketSecurity.applyPatches({ root, dryRun });
233
+ if (options.patchGet) {
234
+ const result = patchGet({ root, identifier: options.patchGet });
235
+ if (!result.ok) throw new Error(`[socketsecurity] patch get failed: ${result.message}`);
236
+ logger.info('Socket patch recorded and applied', result.data);
237
+ return result;
238
+ }
239
+ if (options.patchScan) {
240
+ const result = patchScan({ root });
241
+ if (!result.ok) throw new Error(`[socketsecurity] patch scan failed: ${result.message}`);
242
+ logger.info('Socket patches available', result.summary);
243
+ return result;
244
+ }
245
+
246
+ const remediation = options.fix
247
+ ? await Underpost.socketSecurity.remediate({ root, out, majorUpdates: options.major === true })
248
+ : {};
249
+ const report = await Underpost.socketSecurity.audit({ root, out, reach: options.reach === true, remediation });
250
+ if (options.ci && reportViolates(report, options.failOn))
251
+ throw new Error(
252
+ `[socketsecurity] policy gate failed (fail-on ${options.failOn || 'high'}); ` +
253
+ `see ${nodePath.join(out, SocketSecurityService.REPORT_FILES.markdown)}`,
254
+ );
255
+ return report;
256
+ },
257
+ };
258
+ }
259
+
260
+ export default UnderpostSocketSecurity;
@@ -7,7 +7,6 @@ class Badge {
7
7
  static async instance(options = { id: '', type: 'circle-red', classList: '', text: '', style: '' }) {
8
8
  if (!options.id) options.id = getId(Badge.Tokens, 'badge-');
9
9
  else options.id = 'badge-' + options.id;
10
- if (options && options.style && !options.style.color) options.style.color = 'white';
11
10
  if (!options.classList) options.classList = '';
12
11
  const { id, type } = options;
13
12
  Badge.Tokens[id] = { ...options };
@@ -16,6 +16,9 @@ const CssCommonCore = async () => {
16
16
  );
17
17
  await AgGrid.RenderStyle();
18
18
  return html`<style>
19
+ .top-bar {
20
+ transition: 0.3s;
21
+ }
19
22
  .top-bar-app-icon {
20
23
  width: 40px;
21
24
  height: 40px;
@@ -53,23 +56,30 @@ const CssCommonCore = async () => {
53
56
  .btn-label-content {
54
57
  top: 15px;
55
58
  }
59
+ /* Badge: one dark chip in every theme, so its lettering is always white — a caller
60
+ only sets a color when it also sets the background (see Badge.instance style). */
56
61
  .badge {
57
62
  min-width: 20px;
58
63
  height: 20px;
59
64
  border-radius: 3px;
60
65
  background: #3b434b;
66
+ color: white;
61
67
  position: relative;
62
68
  font-size: 12px;
63
69
  font-family: arial;
64
70
  }
65
71
  .badge-text {
66
- /* color: white; */
67
72
  padding: 3px 6px 0px 6px;
68
73
  }
69
74
  .badge-notification-circle-red {
70
75
  background: #bd0c0c;
71
76
  border-radius: 50%;
72
77
  }
78
+ /* Unread dot over a menu button icon; the label reads left-to-right in both menu modes. */
79
+ .badge-notification-menu {
80
+ top: -33px;
81
+ left: 24px;
82
+ }
73
83
  .top-box-profile-container {
74
84
  top: 0px;
75
85
  right: 0px;