underpost 3.2.30 → 3.2.70

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.
@@ -13,6 +13,58 @@ import { loggerFactory } from '../server/logger.js';
13
13
 
14
14
  const logger = loggerFactory(import.meta);
15
15
 
16
+ // Shell/runtime-critical and Kubernetes-injected env keys that must never be persisted as
17
+ // application secrets nor injected into a pod via `envFrom`. An injected PATH (or HOME, etc.)
18
+ // overrides the container image's own and breaks coreutils/sudo resolution inside the pod
19
+ // ("rm: command not found"). Single source of truth for both container-env capture and the
20
+ // `underpost-config` secret built from an env file.
21
+ const RESERVED_ENV_KEYS = new Set([
22
+ 'HOME',
23
+ 'HOSTNAME',
24
+ 'PATH',
25
+ 'TERM',
26
+ 'SHLVL',
27
+ 'PWD',
28
+ '_',
29
+ 'LANG',
30
+ 'LANGUAGE',
31
+ 'LC_ALL',
32
+ 'container',
33
+ 'SHELL',
34
+ 'USER',
35
+ 'LOGNAME',
36
+ 'MAIL',
37
+ 'OLDPWD',
38
+ 'LESSOPEN',
39
+ 'LESSCLOSE',
40
+ 'LS_COLORS',
41
+ 'DISPLAY',
42
+ 'COLORTERM',
43
+ 'EDITOR',
44
+ 'VISUAL',
45
+ 'TERM_PROGRAM',
46
+ 'TERM_PROGRAM_VERSION',
47
+ 'SSH_AUTH_SOCK',
48
+ 'SSH_CLIENT',
49
+ 'SSH_CONNECTION',
50
+ 'SSH_TTY',
51
+ 'XDG_SESSION_ID',
52
+ 'XDG_RUNTIME_DIR',
53
+ 'XDG_DATA_DIRS',
54
+ 'XDG_CONFIG_DIRS',
55
+ 'DBUS_SESSION_BUS_ADDRESS',
56
+ 'GPG_AGENT_INFO',
57
+ 'WINDOWID',
58
+ 'DESKTOP_SESSION',
59
+ 'SESSION_MANAGER',
60
+ 'XAUTHORITY',
61
+ 'WAYLAND_DISPLAY',
62
+ 'which_declare',
63
+ ]);
64
+ const RESERVED_ENV_KEY_PREFIXES = ['KUBERNETES_', 'npm_', 'NODE_'];
65
+ const isReservedEnvKey = (key) =>
66
+ RESERVED_ENV_KEYS.has(key) || RESERVED_ENV_KEY_PREFIXES.some((prefix) => key.startsWith(prefix));
67
+
16
68
  /**
17
69
  * @class UnderpostSecret
18
70
  * @description Manages the secrets of the application.
@@ -49,58 +101,35 @@ class UnderpostSecret {
49
101
  */
50
102
  createFromContainerEnv() {
51
103
  Underpost.env.clean();
52
- const systemKeys = new Set([
53
- 'HOME',
54
- 'HOSTNAME',
55
- 'PATH',
56
- 'TERM',
57
- 'SHLVL',
58
- 'PWD',
59
- '_',
60
- 'LANG',
61
- 'LANGUAGE',
62
- 'LC_ALL',
63
- 'container',
64
- 'SHELL',
65
- 'USER',
66
- 'LOGNAME',
67
- 'MAIL',
68
- 'OLDPWD',
69
- 'LESSOPEN',
70
- 'LESSCLOSE',
71
- 'LS_COLORS',
72
- 'DISPLAY',
73
- 'COLORTERM',
74
- 'EDITOR',
75
- 'VISUAL',
76
- 'TERM_PROGRAM',
77
- 'TERM_PROGRAM_VERSION',
78
- 'SSH_AUTH_SOCK',
79
- 'SSH_CLIENT',
80
- 'SSH_CONNECTION',
81
- 'SSH_TTY',
82
- 'XDG_SESSION_ID',
83
- 'XDG_RUNTIME_DIR',
84
- 'XDG_DATA_DIRS',
85
- 'XDG_CONFIG_DIRS',
86
- 'DBUS_SESSION_BUS_ADDRESS',
87
- 'GPG_AGENT_INFO',
88
- 'WINDOWID',
89
- 'DESKTOP_SESSION',
90
- 'SESSION_MANAGER',
91
- 'XAUTHORITY',
92
- 'WAYLAND_DISPLAY',
93
- 'which_declare',
94
- ]);
95
- const systemKeyPrefixes = ['KUBERNETES_', 'npm_', 'NODE_'];
96
104
  for (const [key, value] of Object.entries(process.env)) {
97
- if (systemKeys.has(key)) continue;
98
- if (systemKeyPrefixes.some((prefix) => key.startsWith(prefix))) continue;
105
+ if (isReservedEnvKey(key)) continue;
99
106
  Underpost.env.set(key, value);
100
107
  }
101
108
  },
102
109
  },
103
110
 
111
+ /**
112
+ * @method sanitizeSecretEnvFile
113
+ * @description Strips shell/runtime-critical and Kubernetes-injected keys (PATH, HOME, …) from
114
+ * raw `.env` file content so the resulting `underpost-config` secret can be safely injected via
115
+ * `envFrom` without clobbering the container image's own PATH. Blank lines and comments are
116
+ * preserved. Uses the same {@link RESERVED_ENV_KEYS} blocklist as container-env capture.
117
+ * @param {string} envFileContent - Raw contents of a `.env.<env>` file.
118
+ * @returns {string} Filtered env-file content.
119
+ * @memberof UnderpostSecret
120
+ */
121
+ sanitizeSecretEnvFile(envFileContent) {
122
+ return envFileContent
123
+ .split('\n')
124
+ .filter((line) => {
125
+ const trimmed = line.trimStart();
126
+ if (!trimmed || trimmed.startsWith('#')) return true;
127
+ const key = line.slice(0, line.indexOf('=')).trim();
128
+ return !key || !isReservedEnvKey(key);
129
+ })
130
+ .join('\n');
131
+ },
132
+
104
133
  /**
105
134
  * Removes all filesystem traces of secrets after deployment startup.
106
135
  * Centralizes the defense-in-depth cleanup performed
package/src/index.js CHANGED
@@ -45,7 +45,7 @@ class Underpost {
45
45
  * @type {String}
46
46
  * @memberof Underpost
47
47
  */
48
- static version = 'v3.2.30';
48
+ static version = 'v3.2.70';
49
49
 
50
50
  /**
51
51
  * Required Node.js major version
@@ -24,6 +24,8 @@ const EMPTY_CATALOG = {
24
24
  privateConfPaths: [],
25
25
  templatePaths: [],
26
26
  stripPaths: [],
27
+ moves: [],
28
+ copies: [],
27
29
  keywords: [],
28
30
  description: '',
29
31
  };
@@ -476,9 +476,6 @@ const loadConf = (deployId = DEFAULT_DEPLOY_ID, subConf) => {
476
476
  fs.removeSync(`${path}/.env.production`);
477
477
  fs.removeSync(`${path}/.env.development`);
478
478
  fs.removeSync(`${path}/.env.test`);
479
- if (fs.existsSync(`${path}/typedoc.json`)) shellExec(`git checkout ${path}/typedoc.json`);
480
- shellExec(`git checkout ${path}/package.json`);
481
- shellExec(`git checkout ${path}/package-lock.json`);
482
479
  return;
483
480
  }
484
481
  const folder = getConfFolder(deployId);