Skip to content

Commit 457af8d

Browse files
committed
fix: try both SSH agent and key files when identityFile not set
Previously, if SSH_AUTH_SOCK was set the code skipped key files entirely. If the agent had no keys loaded the connection failed with no fallback. Now both agent and default key files are set independently so ssh2 can try both. Also adds a clear error when neither auth method is available.
1 parent ac013a0 commit 457af8d

2 files changed

Lines changed: 41 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,38 @@ All notable changes to `@devalade/shipnode` will be documented here.
44

55
## [Unreleased]
66

7+
### Added
8+
- `shipnode init` now prompts for SSH users to add during setup, generating `.shipnode/users.yml`
9+
- Database configuration prompts in `shipnode init` (PostgreSQL, MySQL, SQLite, MongoDB)
10+
11+
### Changed
12+
- CLI UI overhauled: replaced plain `console.log` output with `@clack/prompts` (spinners, notes, banners) and `listr2` task lists — all commands now render structured, coloured output
13+
14+
### Fixed
15+
- SSH authentication: when no `identityFile` is set, connection now tries the running SSH agent (`SSH_AUTH_SOCK`) first, then falls back to default key files (`~/.ssh/id_ed25519`, `id_ecdsa`, `id_rsa`, `id_dsa`)
16+
17+
## [2.0.3] - 2026-05-16
18+
19+
### Fixed
20+
- `shipnode init` generated config always includes SSH `port:` field (was missing)
21+
- `shipnode init` generated config always includes `.port()` call for backend apps
22+
- `shipnode init` generated config now includes `.build()` terminator
23+
- `shipnode init` generated config now includes `.pkgManager()` when detected
24+
- Restored database prompts in interactive `shipnode init` flow
25+
- Fixed `chmod` import: now imported from `node:fs/promises` at module top level (was broken dynamic import)
26+
27+
## [2.0.2] - 2026-05-15
28+
29+
### Fixed
30+
- `writeFile` and `readFile` imported from `node:fs/promises` instead of `fs-extra` — these are not named ESM exports in `fs-extra`
31+
32+
## [2.0.1] - 2026-05-15
33+
34+
### Fixed
35+
- `mkdir` replaced with `ensureDir` from `fs-extra``mkdir` is not a named ESM export in `fs-extra`
36+
- CI: pinned pnpm to v10 to match lockfile format and avoid pnpm v11 build approval errors
37+
- CI: bumped Node.js to 22 in all workflows
38+
739
## [2.0.0] - 2026-05-16
840

941
Complete rewrite in TypeScript with full feature parity with v1 and new capabilities.

src/infrastructure/ssh/connection.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ export class SshConnection implements RemoteExecutor {
2929

3030
if (config.identityFile) {
3131
sshConfig.privateKey = readFileSync(config.identityFile);
32-
} else if (process.env['SSH_AUTH_SOCK']) {
33-
// Use the running SSH agent (covers all keys added via ssh-add)
34-
sshConfig.agent = process.env['SSH_AUTH_SOCK'];
3532
} else {
36-
// Fall back to default key files in ~/.ssh
33+
if (process.env['SSH_AUTH_SOCK']) {
34+
sshConfig.agent = process.env['SSH_AUTH_SOCK'];
35+
}
36+
// Also try default key files — agent may be set but have no keys loaded
3737
const defaults = ['id_ed25519', 'id_ecdsa', 'id_rsa', 'id_dsa'];
3838
for (const name of defaults) {
3939
const keyPath = join(homedir(), '.ssh', name);
@@ -42,6 +42,11 @@ export class SshConnection implements RemoteExecutor {
4242
break;
4343
}
4444
}
45+
if (!sshConfig.agent && !sshConfig.privateKey) {
46+
throw new SshError(
47+
'No SSH auth method found. Set identityFile in config, run ssh-add, or place a key in ~/.ssh/',
48+
);
49+
}
4550
}
4651

4752
if (config.proxyMode === 'cloudflare') {

0 commit comments

Comments
 (0)