Skip to content

Commit a09aa47

Browse files
committed
add a cli command
1 parent 95c9300 commit a09aa47

10 files changed

Lines changed: 113 additions & 5 deletions

eslint.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,10 @@ export default defineConfig([
5252
'@typescript-eslint/no-unsafe-return': 'off',
5353
},
5454
},
55+
{
56+
files: ['src/index.ts'],
57+
rules: {
58+
'@typescript-eslint/no-unsafe-argument': 'off',
59+
},
60+
},
5561
])

package-lock.json

Lines changed: 28 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
{
22
"name": "ssh-agent-secrets",
33
"version": "0.0.1",
4+
"keywords": [
5+
"ssh",
6+
"encryption",
7+
"typescript",
8+
"ssh-agent",
9+
"cli"
10+
],
11+
"homepage": "https://github.com/ddebin/ssh-agent-secrets",
12+
"bugs": {
13+
"url": "https://github.com/ddebin/ssh-agent-secrets/issues"
14+
},
415
"license": "MIT",
516
"type": "module",
17+
"bin": {
18+
"ssh-crypt": "./dist/src/index.js"
19+
},
620
"scripts": {
721
"build": "tsc -b",
822
"coverage": "nyc --reporter=lcov --reporter=text-summary npm test",
@@ -15,7 +29,11 @@
1529
"test": "mocha",
1630
"typecheck": "tsc --noEmit"
1731
},
32+
"dependencies": {
33+
"commander": "^14"
34+
},
1835
"devDependencies": {
36+
"@commander-js/extra-typings": "^14.0.0",
1937
"@eslint/js": "^10",
2038
"@types/chai": "^5",
2139
"@types/chai-as-promised": "^8",

src/index.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env node
2+
import * as fs from 'fs'
3+
import { program } from 'commander'
4+
import { SSHAgentClient } from './lib/ssh_agent_client.js'
5+
6+
program.name('ssh-crypt').description('Encryption through SSH Agent')
7+
8+
program
9+
.command('encrypt')
10+
.description('Encrypt a file with your ssh-agent private key')
11+
.argument('<source>', 'file to encrypt')
12+
.argument('[destination]', 'output path (default to stdout)')
13+
.requiredOption('-k, --key <string>', 'select the first matching pubkey in the ssh-agent')
14+
.requiredOption('-s, --seed <string>', 'is used to generate the secret')
15+
.action(async (source, destination, options) => {
16+
const agent = new SSHAgentClient()
17+
const key = await agent.getIdentity(options.key)
18+
if (!key) {
19+
throw new Error(`No SSH key found for "${options.key}"!`)
20+
}
21+
const data = fs.readFileSync(source)
22+
const output = await agent.encrypt(key, options.seed, data)
23+
if (destination) {
24+
fs.writeFileSync(destination, output)
25+
} else {
26+
process.stdout.write(output)
27+
}
28+
})
29+
30+
program
31+
.command('decrypt')
32+
.description('Decrypt a file with your ssh-agent private key')
33+
.argument('<source>', 'file to decrypt')
34+
.argument('[destination]', 'output path (default to stdout)')
35+
.requiredOption('-k, --key <string>', 'select the first matching pubkey in the ssh-agent')
36+
.requiredOption('-s, --seed <string>', 'is used to generate the secret')
37+
.action(async (source, destination, options) => {
38+
const agent = new SSHAgentClient()
39+
const key = await agent.getIdentity(options.key)
40+
if (!key) {
41+
throw new Error(`No SSH key found for "${options.key}"!`)
42+
}
43+
const data = fs.readFileSync(source, { encoding: 'ascii' })
44+
const output = await agent.decrypt(key, options.seed, data)
45+
if (destination) {
46+
fs.writeFileSync(destination, output)
47+
} else {
48+
process.stdout.write(output)
49+
}
50+
})
51+
52+
program.parse()

src/type/commander.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
declare module 'commander' {
2+
export * from '@commander-js/extra-typings'
3+
}

test/ssh_agent_client.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it } from 'mocha'
2-
import { SSHAgentClient } from '../src/ssh_agent_client.js'
2+
import { SSHAgentClient } from '../src/lib/ssh_agent_client.js'
33
import * as chai from 'chai'
44

55
describe('SSHAgentClient tests', () => {

test/ssh_agent_mandatory_rsa.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it } from 'mocha'
2-
import { SSHAgentClient } from '../src/ssh_agent_client.js'
2+
import { SSHAgentClient } from '../src/lib/ssh_agent_client.js'
33
import * as chai from 'chai'
44
import chaiAsPromised from 'chai-as-promised'
55

test/ssh_agent_socket.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it } from 'mocha'
2-
import { SSHAgentClient } from '../src/ssh_agent_client.js'
2+
import { SSHAgentClient } from '../src/lib/ssh_agent_client.js'
33
import * as chai from 'chai'
44
import * as net from 'net'
55
import * as fs from 'fs'

tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
"outDir": "dist",
77
"strict": true,
88
"skipLibCheck": true,
9+
"paths": {
10+
"commander": ["./src/type/commander.d.ts"]
11+
},
912
"types": ["node"]
1013
},
1114
"include": ["src", "test"]

0 commit comments

Comments
 (0)