@factiii/stack 0.1.203 → 0.7.2

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.
@@ -5,6 +5,9 @@
5
5
  * Manages authentication secrets in Ansible Vault:
6
6
  * - JWT_SECRET: auto-generated 256-bit random key
7
7
  * - OAuth keys: prompted from user (Google, Apple)
8
+ *
9
+ * Secret names are sourced from @factiii/auth's stack-plugin contract
10
+ * to avoid hardcoded strings drifting out of sync.
8
11
  */
9
12
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
13
  if (k2 === undefined) k2 = k;
@@ -43,6 +46,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
43
46
  exports.secretsFixes = void 0;
44
47
  const crypto = __importStar(require("crypto"));
45
48
  const config_helpers_js_1 = require("../../../../utils/config-helpers.js");
49
+ /**
50
+ * Load secret name constants from @factiii/auth's stack-plugin contract.
51
+ * Falls back to hardcoded values if auth is not installed.
52
+ */
53
+ function loadAuthSecretNames() {
54
+ try {
55
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
56
+ const contract = require('@factiii/auth/stack-plugin');
57
+ return {
58
+ requiredEnvVars: [...contract.AUTH_REQUIRED_ENV_VARS],
59
+ oauthEnvVars: {
60
+ google: [...contract.AUTH_OAUTH_ENV_VARS.google],
61
+ apple: [...contract.AUTH_OAUTH_ENV_VARS.apple],
62
+ },
63
+ };
64
+ }
65
+ catch {
66
+ // Fallback if @factiii/auth not installed
67
+ return {
68
+ requiredEnvVars: ['JWT_SECRET'],
69
+ oauthEnvVars: {
70
+ google: ['GOOGLE_CLIENT_ID', 'GOOGLE_CLIENT_SECRET'],
71
+ apple: ['APPLE_CLIENT_ID'],
72
+ },
73
+ };
74
+ }
75
+ }
76
+ const authSecrets = loadAuthSecretNames();
46
77
  /**
47
78
  * Get auth config from FactiiiConfig (handles undefined/null)
48
79
  */
@@ -79,16 +110,20 @@ async function getVault(config, rootDir) {
79
110
  rootDir,
80
111
  });
81
112
  }
113
+ const JWT_SECRET = authSecrets.requiredEnvVars[0] ?? 'JWT_SECRET';
114
+ const GOOGLE_CLIENT_ID = authSecrets.oauthEnvVars.google[0] ?? 'GOOGLE_CLIENT_ID';
115
+ const GOOGLE_CLIENT_SECRET = authSecrets.oauthEnvVars.google[1] ?? 'GOOGLE_CLIENT_SECRET';
116
+ const APPLE_CLIENT_ID = authSecrets.oauthEnvVars.apple[0] ?? 'APPLE_CLIENT_ID';
82
117
  exports.secretsFixes = [
83
118
  {
84
119
  id: 'auth-jwt-secret-missing',
85
120
  stage: 'secrets',
86
121
  severity: 'critical',
87
- description: 'JWT_SECRET not found in Ansible Vault (required for auth)',
122
+ description: JWT_SECRET + ' not found in Ansible Vault (required for auth)',
88
123
  scan: async (config, rootDir) => {
89
124
  try {
90
125
  const vault = await getVault(config, rootDir);
91
- const secret = await vault.getSecret('JWT_SECRET');
126
+ const secret = await vault.getSecret(JWT_SECRET);
92
127
  return !secret;
93
128
  }
94
129
  catch {
@@ -100,13 +135,13 @@ exports.secretsFixes = [
100
135
  const vault = await getVault(config, rootDir);
101
136
  // Auto-generate a cryptographically secure 256-bit secret
102
137
  const jwtSecret = crypto.randomBytes(32).toString('hex');
103
- const result = await vault.setSecret('JWT_SECRET', jwtSecret);
138
+ const result = await vault.setSecret(JWT_SECRET, jwtSecret);
104
139
  if (result.success) {
105
- console.log(' [OK] Generated and stored JWT_SECRET in Ansible Vault');
140
+ console.log(' [OK] Generated and stored ' + JWT_SECRET + ' in Ansible Vault');
106
141
  console.log(' (256-bit random key, no manual input needed)');
107
142
  return true;
108
143
  }
109
- console.log(' Failed to store JWT_SECRET in vault');
144
+ console.log(' Failed to store ' + JWT_SECRET + ' in vault');
110
145
  return false;
111
146
  }
112
147
  catch (e) {
@@ -114,19 +149,19 @@ exports.secretsFixes = [
114
149
  return false;
115
150
  }
116
151
  },
117
- manualFix: 'Generate and store JWT secret: npx stack deploy --secrets set JWT_SECRET',
152
+ manualFix: 'Generate and store JWT secret: npx stack deploy --secrets set ' + JWT_SECRET,
118
153
  },
119
154
  {
120
155
  id: 'auth-oauth-google-missing',
121
156
  stage: 'secrets',
122
157
  severity: 'warning',
123
- description: 'Google OAuth credentials not in vault (GOOGLE_CLIENT_ID)',
158
+ description: 'Google OAuth credentials not in vault (' + GOOGLE_CLIENT_ID + ')',
124
159
  scan: async (config, rootDir) => {
125
160
  if (!isOAuthEnabled(config, 'google'))
126
161
  return false;
127
162
  try {
128
163
  const vault = await getVault(config, rootDir);
129
- const clientId = await vault.getSecret('GOOGLE_CLIENT_ID');
164
+ const clientId = await vault.getSecret(GOOGLE_CLIENT_ID);
130
165
  return !clientId;
131
166
  }
132
167
  catch {
@@ -141,12 +176,12 @@ exports.secretsFixes = [
141
176
  console.log(' Google OAuth Setup');
142
177
  console.log(' Get credentials from: https://console.cloud.google.com/apis/credentials');
143
178
  console.log('');
144
- const clientId = await promptForSecret('GOOGLE_CLIENT_ID', config);
145
- const r1 = await vault.setSecret('GOOGLE_CLIENT_ID', clientId);
179
+ const clientId = await promptForSecret(GOOGLE_CLIENT_ID, config);
180
+ const r1 = await vault.setSecret(GOOGLE_CLIENT_ID, clientId);
146
181
  if (!r1.success)
147
182
  return false;
148
- const clientSecret = await promptForSecret('GOOGLE_CLIENT_SECRET', config);
149
- const r2 = await vault.setSecret('GOOGLE_CLIENT_SECRET', clientSecret);
183
+ const clientSecret = await promptForSecret(GOOGLE_CLIENT_SECRET, config);
184
+ const r2 = await vault.setSecret(GOOGLE_CLIENT_SECRET, clientSecret);
150
185
  if (!r2.success)
151
186
  return false;
152
187
  console.log(' [OK] Stored Google OAuth credentials in vault');
@@ -157,21 +192,21 @@ exports.secretsFixes = [
157
192
  }
158
193
  },
159
194
  manualFix: 'Store Google OAuth credentials:\n' +
160
- ' npx stack deploy --secrets set GOOGLE_CLIENT_ID\n' +
161
- ' npx stack deploy --secrets set GOOGLE_CLIENT_SECRET\n' +
195
+ ' npx stack deploy --secrets set ' + GOOGLE_CLIENT_ID + '\n' +
196
+ ' npx stack deploy --secrets set ' + GOOGLE_CLIENT_SECRET + '\n' +
162
197
  ' Get from: https://console.cloud.google.com/apis/credentials',
163
198
  },
164
199
  {
165
200
  id: 'auth-oauth-apple-missing',
166
201
  stage: 'secrets',
167
202
  severity: 'warning',
168
- description: 'Apple OAuth credentials not in vault (APPLE_CLIENT_ID)',
203
+ description: 'Apple OAuth credentials not in vault (' + APPLE_CLIENT_ID + ')',
169
204
  scan: async (config, rootDir) => {
170
205
  if (!isOAuthEnabled(config, 'apple'))
171
206
  return false;
172
207
  try {
173
208
  const vault = await getVault(config, rootDir);
174
- const clientId = await vault.getSecret('APPLE_CLIENT_ID');
209
+ const clientId = await vault.getSecret(APPLE_CLIENT_ID);
175
210
  return !clientId;
176
211
  }
177
212
  catch {
@@ -186,8 +221,8 @@ exports.secretsFixes = [
186
221
  console.log(' Apple OAuth Setup');
187
222
  console.log(' Get credentials from: https://developer.apple.com/account/resources/identifiers');
188
223
  console.log('');
189
- const clientId = await promptForSecret('APPLE_CLIENT_ID', config);
190
- const r1 = await vault.setSecret('APPLE_CLIENT_ID', clientId);
224
+ const clientId = await promptForSecret(APPLE_CLIENT_ID, config);
225
+ const r1 = await vault.setSecret(APPLE_CLIENT_ID, clientId);
191
226
  if (!r1.success)
192
227
  return false;
193
228
  console.log(' [OK] Stored Apple OAuth credentials in vault');
@@ -198,7 +233,7 @@ exports.secretsFixes = [
198
233
  }
199
234
  },
200
235
  manualFix: 'Store Apple OAuth credentials:\n' +
201
- ' npx stack deploy --secrets set APPLE_CLIENT_ID\n' +
236
+ ' npx stack deploy --secrets set ' + APPLE_CLIENT_ID + '\n' +
202
237
  ' Get from: https://developer.apple.com/account/resources/identifiers',
203
238
  },
204
239
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/secrets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/secrets.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,9 @@
3
3
  *
4
4
  * Validates that auth environment variables are properly
5
5
  * configured on staging and production servers.
6
+ *
7
+ * Secret names are sourced from @factiii/auth's stack-plugin contract
8
+ * to avoid hardcoded strings drifting out of sync.
6
9
  */
7
10
  import type { Fix } from '../../../../types/index.js';
8
11
  export declare const validateFixes: Fix[];
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAkBrE,eAAO,MAAM,aAAa,EAAE,GAAG,EAiG9B,CAAC"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAiB,GAAG,EAAE,MAAM,4BAA4B,CAAC;AAmCrE,eAAO,MAAM,aAAa,EAAE,GAAG,EAiG9B,CAAC"}
@@ -4,6 +4,9 @@
4
4
  *
5
5
  * Validates that auth environment variables are properly
6
6
  * configured on staging and production servers.
7
+ *
8
+ * Secret names are sourced from @factiii/auth's stack-plugin contract
9
+ * to avoid hardcoded strings drifting out of sync.
7
10
  */
8
11
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
12
  if (k2 === undefined) k2 = k;
@@ -43,6 +46,22 @@ exports.validateFixes = void 0;
43
46
  const fs = __importStar(require("fs"));
44
47
  const path = __importStar(require("path"));
45
48
  const config_helpers_js_1 = require("../../../../utils/config-helpers.js");
49
+ /**
50
+ * Load required env var names from @factiii/auth's stack-plugin contract.
51
+ * Falls back to hardcoded values if auth is not installed.
52
+ */
53
+ function loadRequiredEnvVars() {
54
+ try {
55
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
56
+ const contract = require('@factiii/auth/stack-plugin');
57
+ return [...contract.AUTH_REQUIRED_ENV_VARS];
58
+ }
59
+ catch {
60
+ return ['JWT_SECRET'];
61
+ }
62
+ }
63
+ const requiredEnvVars = loadRequiredEnvVars();
64
+ const JWT_SECRET = requiredEnvVars[0] ?? 'JWT_SECRET';
46
65
  /**
47
66
  * Check if an env file has a variable set (non-empty, non-EXAMPLE)
48
67
  */
@@ -62,10 +81,10 @@ exports.validateFixes = [
62
81
  id: 'auth-env-jwt-staging',
63
82
  stage: 'staging',
64
83
  severity: 'critical',
65
- description: 'JWT_SECRET not set in .env.staging (auth will not work)',
84
+ description: JWT_SECRET + ' not set in .env.staging (auth will not work)',
66
85
  scan: async (_config, rootDir) => {
67
86
  const envPath = path.join(rootDir, '.env.staging');
68
- return !envFileHasVar(envPath, 'JWT_SECRET');
87
+ return !envFileHasVar(envPath, JWT_SECRET);
69
88
  },
70
89
  fix: async (config, rootDir) => {
71
90
  try {
@@ -75,9 +94,9 @@ exports.validateFixes = [
75
94
  vault_password_file: config.ansible?.vault_password_file,
76
95
  rootDir,
77
96
  });
78
- const jwtSecret = await vault.getSecret('JWT_SECRET');
97
+ const jwtSecret = await vault.getSecret(JWT_SECRET);
79
98
  if (!jwtSecret) {
80
- console.log(' JWT_SECRET not in vault — run: npx stack fix --secrets');
99
+ console.log(' ' + JWT_SECRET + ' not in vault — run: npx stack fix --secrets');
81
100
  return false;
82
101
  }
83
102
  // Append to .env.staging
@@ -86,15 +105,15 @@ exports.validateFixes = [
86
105
  if (fs.existsSync(envPath)) {
87
106
  content = fs.readFileSync(envPath, 'utf8');
88
107
  }
89
- if (content.includes('JWT_SECRET=')) {
108
+ if (content.includes(JWT_SECRET + '=')) {
90
109
  // Replace existing (empty or EXAMPLE) value
91
- content = content.replace(/^JWT_SECRET\s*=.*$/m, 'JWT_SECRET=' + jwtSecret);
110
+ content = content.replace(new RegExp('^' + JWT_SECRET + '\\s*=.*$', 'm'), JWT_SECRET + '=' + jwtSecret);
92
111
  }
93
112
  else {
94
- content = content.trimEnd() + '\nJWT_SECRET=' + jwtSecret + '\n';
113
+ content = content.trimEnd() + '\n' + JWT_SECRET + '=' + jwtSecret + '\n';
95
114
  }
96
115
  fs.writeFileSync(envPath, content, 'utf8');
97
- console.log(' [OK] Set JWT_SECRET in .env.staging from vault');
116
+ console.log(' [OK] Set ' + JWT_SECRET + ' in .env.staging from vault');
98
117
  return true;
99
118
  }
100
119
  catch (e) {
@@ -102,16 +121,16 @@ exports.validateFixes = [
102
121
  return false;
103
122
  }
104
123
  },
105
- manualFix: 'Add JWT_SECRET to .env.staging or run: npx stack fix --secrets && npx stack fix --staging',
124
+ manualFix: 'Add ' + JWT_SECRET + ' to .env.staging or run: npx stack fix --secrets && npx stack fix --staging',
106
125
  },
107
126
  {
108
127
  id: 'auth-env-jwt-prod',
109
128
  stage: 'prod',
110
129
  severity: 'critical',
111
- description: 'JWT_SECRET not set in .env.prod (auth will not work)',
130
+ description: JWT_SECRET + ' not set in .env.prod (auth will not work)',
112
131
  scan: async (_config, rootDir) => {
113
132
  const envPath = path.join(rootDir, '.env.prod');
114
- return !envFileHasVar(envPath, 'JWT_SECRET');
133
+ return !envFileHasVar(envPath, JWT_SECRET);
115
134
  },
116
135
  fix: async (config, rootDir) => {
117
136
  try {
@@ -121,9 +140,9 @@ exports.validateFixes = [
121
140
  vault_password_file: config.ansible?.vault_password_file,
122
141
  rootDir,
123
142
  });
124
- const jwtSecret = await vault.getSecret('JWT_SECRET');
143
+ const jwtSecret = await vault.getSecret(JWT_SECRET);
125
144
  if (!jwtSecret) {
126
- console.log(' JWT_SECRET not in vault — run: npx stack fix --secrets');
145
+ console.log(' ' + JWT_SECRET + ' not in vault — run: npx stack fix --secrets');
127
146
  return false;
128
147
  }
129
148
  // Append to .env.prod
@@ -132,14 +151,14 @@ exports.validateFixes = [
132
151
  if (fs.existsSync(envPath)) {
133
152
  content = fs.readFileSync(envPath, 'utf8');
134
153
  }
135
- if (content.includes('JWT_SECRET=')) {
136
- content = content.replace(/^JWT_SECRET\s*=.*$/m, 'JWT_SECRET=' + jwtSecret);
154
+ if (content.includes(JWT_SECRET + '=')) {
155
+ content = content.replace(new RegExp('^' + JWT_SECRET + '\\s*=.*$', 'm'), JWT_SECRET + '=' + jwtSecret);
137
156
  }
138
157
  else {
139
- content = content.trimEnd() + '\nJWT_SECRET=' + jwtSecret + '\n';
158
+ content = content.trimEnd() + '\n' + JWT_SECRET + '=' + jwtSecret + '\n';
140
159
  }
141
160
  fs.writeFileSync(envPath, content, 'utf8');
142
- console.log(' [OK] Set JWT_SECRET in .env.prod from vault');
161
+ console.log(' [OK] Set ' + JWT_SECRET + ' in .env.prod from vault');
143
162
  return true;
144
163
  }
145
164
  catch (e) {
@@ -147,7 +166,7 @@ exports.validateFixes = [
147
166
  return false;
148
167
  }
149
168
  },
150
- manualFix: 'Add JWT_SECRET to .env.prod or run: npx stack fix --secrets && npx stack fix --prod',
169
+ manualFix: 'Add ' + JWT_SECRET + ' to .env.prod or run: npx stack fix --secrets && npx stack fix --prod',
151
170
  },
152
171
  ];
153
172
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../../src/plugins/addons/auth/scanfix/validate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ssh-helper.d.ts","sourceRoot":"","sources":["../../src/utils/ssh-helper.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAKjF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAU5E;AA+BD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAS9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA4BlF;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,aAAa,GACpB,iBAAiB,GAAG,IAAI,CAc1B;AA+aD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAo0B/D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,KAAK,EACb,MAAM,CAAC,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAqMjB"}
1
+ {"version":3,"file":"ssh-helper.d.ts","sourceRoot":"","sources":["../../src/utils/ssh-helper.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAKjF;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAU5E;AA+BD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAS9E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA4BlF;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,aAAa,GACpB,iBAAiB,GAAG,IAAI,CAc1B;AAwbD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA+2B/D;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAC3B,SAAS,EAAE,iBAAiB,EAC5B,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,KAAK,EACb,MAAM,CAAC,EAAE,aAAa,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAqMjB"}
@@ -354,14 +354,15 @@ async function autoSetupSshKey(stage, host, user, config, rootDir) {
354
354
  return null;
355
355
  }
356
356
  }
357
- // Fix remote permissions
357
+ // Fix remote permissions using the key we just copied (avoid extra password prompt)
358
358
  try {
359
359
  (0, child_process_1.spawnSync)('ssh', [
360
+ '-i', keyPath,
360
361
  '-o', 'StrictHostKeyChecking=no',
361
362
  '-o', 'ConnectTimeout=5',
362
363
  user + '@' + host,
363
364
  'chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys',
364
- ], { stdio: 'inherit', timeout: 15000 });
365
+ ], { encoding: 'utf8', stdio: 'pipe', timeout: 15000 });
365
366
  }
366
367
  catch { /* best effort */ }
367
368
  // Verify key auth
@@ -426,6 +427,11 @@ async function promptAndValidatePassword(stage, host, user, config, rootDir) {
426
427
  stdio: 'pipe',
427
428
  timeout: 15000,
428
429
  });
430
+ if (testResult.status === 5) {
431
+ // sshpass exit code 5 = wrong password
432
+ console.log(' [!] Incorrect password.');
433
+ return null;
434
+ }
429
435
  if (testResult.status !== 0) {
430
436
  // sshpass failed — likely keyboard-interactive auth (Mac servers)
431
437
  // Fall back to auto SSH key setup so we never need sshpass again
@@ -513,16 +519,18 @@ async function promptAndValidatePassword(stage, host, user, config, rootDir) {
513
519
  // Store password in vault anyway so sshExec can try it
514
520
  return await storePasswordAndReturn(password, stage, config, rootDir);
515
521
  }
516
- // Step 2.5: Fix remote permissions (common issue on Mac servers)
522
+ // Step 2.5: Fix remote permissions using the key we just copied (avoid extra password prompt)
517
523
  console.log(' Fixing remote SSH permissions...');
518
524
  try {
519
525
  (0, child_process_1.spawnSync)('ssh', [
526
+ '-i', keyPath,
520
527
  '-o', 'StrictHostKeyChecking=no',
521
528
  '-o', 'ConnectTimeout=5',
522
529
  user + '@' + host,
523
530
  'chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys',
524
531
  ], {
525
- stdio: 'inherit',
532
+ encoding: 'utf8',
533
+ stdio: 'pipe',
526
534
  timeout: 15000,
527
535
  });
528
536
  }
@@ -879,47 +887,61 @@ async function sshRemoteFactiiiCommand(stage, config, command, rootDir) {
879
887
  if (!password) {
880
888
  password = await promptAndValidatePassword(stage, host, user, config, rootDir);
881
889
  }
882
- if (!password) {
890
+ // promptAndValidatePassword may have set up an SSH key — check before falling back to sshpass
891
+ const candidateKey1 = path.join(os.homedir(), '.ssh', stage + '_deploy_key');
892
+ if (fs.existsSync(candidateKey1)) {
893
+ const kv = (0, child_process_1.spawnSync)('ssh', [
894
+ '-i', candidateKey1, '-o', 'BatchMode=yes', '-o', 'StrictHostKeyChecking=no',
895
+ '-o', 'ConnectTimeout=5', user + '@' + host, 'echo ok',
896
+ ], { encoding: 'utf8', stdio: 'pipe', timeout: 10000 });
897
+ if (kv.status === 0) {
898
+ resolvedKeyPath = candidateKey1;
899
+ }
900
+ }
901
+ // If we now have a key, skip sshpass and fall through to Step 3
902
+ if (!resolvedKeyPath) {
903
+ if (!password) {
904
+ return {
905
+ success: false,
906
+ stdout: '',
907
+ stderr: 'No SSH key for ' + stage + '. For EC2: provide the .pem file from AWS Console.',
908
+ };
909
+ }
910
+ console.log(' SSH (password): ' + user + '@' + host + ' → npx stack ' + command);
911
+ const pwStart = Date.now();
912
+ let pwResult;
913
+ if (process.platform === 'win32') {
914
+ // Windows: no sshpass — use interactive SSH so user types password
915
+ console.log(' You will be prompted for the password by SSH:');
916
+ console.log('');
917
+ pwResult = (0, child_process_1.spawnSync)('ssh', [
918
+ '-tt',
919
+ '-o', 'StrictHostKeyChecking=no',
920
+ '-o', 'ConnectTimeout=10',
921
+ '-o', 'ServerAliveInterval=60',
922
+ '-o', 'ServerAliveCountMax=5',
923
+ user + '@' + host,
924
+ pwRemoteCommand,
925
+ ], { encoding: 'utf8', stdio: 'inherit', timeout: 600000 });
926
+ }
927
+ else {
928
+ pwResult = (0, child_process_1.spawnSync)('sshpass', [
929
+ '-p', password, 'ssh', '-tt',
930
+ '-o', 'StrictHostKeyChecking=no',
931
+ '-o', 'ConnectTimeout=10',
932
+ '-o', 'ServerAliveInterval=60',
933
+ '-o', 'ServerAliveCountMax=5',
934
+ user + '@' + host,
935
+ pwRemoteCommand,
936
+ ], { encoding: 'utf8', stdio: 'inherit', timeout: 600000 });
937
+ }
938
+ console.log(' SSH completed in ' + Math.floor((Date.now() - pwStart) / 1000) + 's');
883
939
  return {
884
- success: false,
940
+ success: pwResult.status === 0,
885
941
  stdout: '',
886
- stderr: 'No SSH key for ' + stage + '. For EC2: provide the .pem file from AWS Console.',
942
+ stderr: pwResult.status !== 0 ? 'SSH command exited with code ' + pwResult.status : '',
887
943
  };
888
944
  }
889
- console.log(' SSH (password): ' + user + '@' + host + ' → npx stack ' + command);
890
- const pwStart = Date.now();
891
- let pwResult;
892
- if (process.platform === 'win32') {
893
- // Windows: no sshpass — use interactive SSH so user types password
894
- console.log(' You will be prompted for the password by SSH:');
895
- console.log('');
896
- pwResult = (0, child_process_1.spawnSync)('ssh', [
897
- '-tt',
898
- '-o', 'StrictHostKeyChecking=no',
899
- '-o', 'ConnectTimeout=10',
900
- '-o', 'ServerAliveInterval=60',
901
- '-o', 'ServerAliveCountMax=5',
902
- user + '@' + host,
903
- pwRemoteCommand,
904
- ], { encoding: 'utf8', stdio: 'inherit', timeout: 600000 });
905
- }
906
- else {
907
- pwResult = (0, child_process_1.spawnSync)('sshpass', [
908
- '-p', password, 'ssh', '-tt',
909
- '-o', 'StrictHostKeyChecking=no',
910
- '-o', 'ConnectTimeout=10',
911
- '-o', 'ServerAliveInterval=60',
912
- '-o', 'ServerAliveCountMax=5',
913
- user + '@' + host,
914
- pwRemoteCommand,
915
- ], { encoding: 'utf8', stdio: 'inherit', timeout: 600000 });
916
- }
917
- console.log(' SSH completed in ' + Math.floor((Date.now() - pwStart) / 1000) + 's');
918
- return {
919
- success: pwResult.status === 0,
920
- stdout: '',
921
- stderr: pwResult.status !== 0 ? 'SSH command exited with code ' + pwResult.status : '',
922
- };
923
945
  }
924
946
  }
925
947
  // Step 3: We have a key — build command and run
@@ -1156,6 +1178,32 @@ async function sshRemoteFactiiiCommand(stage, config, command, rootDir) {
1156
1178
  if (!password) {
1157
1179
  password = await promptAndValidatePassword(stage, host, user, config, rootDir);
1158
1180
  }
1181
+ // promptAndValidatePassword may have set up an SSH key — use it directly instead of sshpass
1182
+ const candidateKey2 = path.join(os.homedir(), '.ssh', stage + '_deploy_key');
1183
+ if (fs.existsSync(candidateKey2)) {
1184
+ const kv2 = (0, child_process_1.spawnSync)('ssh', [
1185
+ '-i', candidateKey2, '-o', 'BatchMode=yes', '-o', 'StrictHostKeyChecking=no',
1186
+ '-o', 'ConnectTimeout=5', user + '@' + host, 'echo ok',
1187
+ ], { encoding: 'utf8', stdio: 'pipe', timeout: 10000 });
1188
+ if (kv2.status === 0) {
1189
+ console.log(' [OK] Using SSH key set up during password auth');
1190
+ const ksStart = Date.now();
1191
+ const ksResult = (0, child_process_1.spawnSync)('ssh', [
1192
+ '-tt', '-i', candidateKey2,
1193
+ '-o', 'StrictHostKeyChecking=no',
1194
+ '-o', 'ConnectTimeout=10',
1195
+ '-o', 'ServerAliveInterval=60',
1196
+ '-o', 'ServerAliveCountMax=5',
1197
+ user + '@' + host, remoteCommand,
1198
+ ], { encoding: 'utf8', stdio: 'inherit', timeout: 600000 });
1199
+ console.log(' SSH completed in ' + Math.floor((Date.now() - ksStart) / 1000) + 's');
1200
+ return {
1201
+ success: ksResult.status === 0,
1202
+ stdout: '',
1203
+ stderr: ksResult.status !== 0 ? 'SSH command exited with code ' + ksResult.status : '',
1204
+ };
1205
+ }
1206
+ }
1159
1207
  if (password) {
1160
1208
  console.log(' Falling back to SSH password auth...');
1161
1209
  console.log(' SSH (password): ' + user + '@' + host + ' → npx stack ' + command);