Skip to content

Commit 5b60762

Browse files
committed
wip: working on secrets cat command
feat: removed Secrets/CommandGet and added tests chore: working on stdin test bug: working on adding test for stdin to stdout bug: still working on that error chore: fixed stdin test feat: updated secrets edit with new secrets get RPC fix: build chore: updated way of specifying multiple files chore: simplified tests chore: undefined files are gracefully ignored chore: updated implementation to use metadata flags chore: version bump fix: tests fix: package lock fix: npmdepshash
1 parent db47ae7 commit 5b60762

File tree

10 files changed

+330
-168
lines changed

10 files changed

+330
-168
lines changed

npmDepsHash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sha256-bKqMvZvc//Fo63MbPtkkXyLpCKNHyA0SKFy/Ts/fJLw=
1+
sha256-Wy7kocLYL/MMhybl1I5plId1SNe6Jxwyd4hsyh0YkZ0=

package-lock.json

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

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@
150150
"nexpect": "^0.6.0",
151151
"node-gyp-build": "^4.4.0",
152152
"nodemon": "^3.0.1",
153-
"polykey": "^1.11.1",
153+
"polykey": "^1.12.0",
154154
"prettier": "^3.0.0",
155155
"shelljs": "^0.8.5",
156156
"shx": "^0.3.4",

src/secrets/CommandCat.ts

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import type PolykeyClient from 'polykey/dist/PolykeyClient';
2+
import CommandPolykey from '../CommandPolykey';
3+
import * as binUtils from '../utils';
4+
import * as binOptions from '../utils/options';
5+
import * as binParsers from '../utils/parsers';
6+
import * as binProcessors from '../utils/processors';
7+
8+
class CommandGet extends CommandPolykey {
9+
constructor(...args: ConstructorParameters<typeof CommandPolykey>) {
10+
super(...args);
11+
this.name('cat');
12+
this.description(
13+
'Concatenates secrets and prints them on the standard output',
14+
);
15+
this.argument(
16+
'[secretPaths...]',
17+
'Path to a secret to be retrieved, specified as <vaultName>:<directoryPath>',
18+
);
19+
this.addOption(binOptions.nodeId);
20+
this.addOption(binOptions.clientHost);
21+
this.addOption(binOptions.clientPort);
22+
this.action(async (secretPaths, options) => {
23+
secretPaths = secretPaths.map((path: string) =>
24+
binParsers.parseSecretPathValue(path),
25+
);
26+
const { default: PolykeyClient } = await import(
27+
'polykey/dist/PolykeyClient'
28+
);
29+
const clientOptions = await binProcessors.processClientOptions(
30+
options.nodePath,
31+
options.nodeId,
32+
options.clientHost,
33+
options.clientPort,
34+
this.fs,
35+
this.logger.getChild(binProcessors.processClientOptions.name),
36+
);
37+
const meta = await binProcessors.processAuthentication(
38+
options.passwordFile,
39+
this.fs,
40+
);
41+
42+
let pkClient: PolykeyClient;
43+
this.exitHandlers.handlers.push(async () => {
44+
if (pkClient != null) await pkClient.stop();
45+
});
46+
try {
47+
pkClient = await PolykeyClient.createPolykeyClient({
48+
nodeId: clientOptions.nodeId,
49+
host: clientOptions.clientHost,
50+
port: clientOptions.clientPort,
51+
options: {
52+
nodePath: options.nodePath,
53+
},
54+
logger: this.logger.getChild(PolykeyClient.name),
55+
});
56+
if (secretPaths.length === 0) {
57+
await new Promise<void>((resolve, reject) => {
58+
const cleanup = () => {
59+
process.stdin.removeListener('data', dataHandler);
60+
process.stdin.removeListener('error', errorHandler);
61+
process.stdin.removeListener('end', endHandler);
62+
};
63+
const dataHandler = (data: Buffer) => {
64+
process.stdout.write(data);
65+
};
66+
const errorHandler = (err: Error) => {
67+
cleanup();
68+
reject(err);
69+
};
70+
const endHandler = () => {
71+
cleanup();
72+
resolve();
73+
};
74+
process.stdin.on('data', dataHandler);
75+
process.stdin.once('error', errorHandler);
76+
process.stdin.once('end', endHandler);
77+
});
78+
return;
79+
}
80+
await binUtils.retryAuthentication(async (auth) => {
81+
const response = await pkClient.rpcClient.methods.vaultsSecretsGet();
82+
await (async () => {
83+
const writer = response.writable.getWriter();
84+
let first = true;
85+
for (const [vaultName, secretPath] of secretPaths) {
86+
await writer.write({
87+
nameOrId: vaultName,
88+
secretName: secretPath,
89+
metadata: first
90+
? { ...auth, options: { continueOnError: true } }
91+
: undefined,
92+
});
93+
first = false;
94+
}
95+
await writer.close();
96+
})();
97+
for await (const chunk of response.readable) {
98+
if (chunk.error) process.stderr.write(chunk.error);
99+
else process.stdout.write(chunk.secretContent);
100+
}
101+
}, meta);
102+
} finally {
103+
if (pkClient! != null) await pkClient.stop();
104+
}
105+
});
106+
}
107+
}
108+
109+
export default CommandGet;

src/secrets/CommandEdit.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,24 @@ class CommandEdit extends CommandPolykey {
6363
const secretExists = await binUtils.retryAuthentication(
6464
async (auth) => {
6565
let exists: boolean = true;
66+
const response =
67+
await pkClient.rpcClient.methods.vaultsSecretsGet();
68+
await (async () => {
69+
const writer = response.writable.getWriter();
70+
await writer.write({
71+
nameOrId: secretPath[0],
72+
secretName: secretPath[1],
73+
metadata: auth,
74+
});
75+
await writer.close();
76+
})();
6677
try {
67-
const response =
68-
await pkClient.rpcClient.methods.vaultsSecretsGet({
69-
metadata: auth,
70-
nameOrId: secretPath[0],
71-
secretName: secretPath[1],
72-
});
73-
await this.fs.promises.writeFile(tmpFile, response.secretContent);
78+
let rawSecretContent: string = '';
79+
for await (const chunk of response.readable) {
80+
rawSecretContent += chunk.secretContent;
81+
}
82+
const secretContent = Buffer.from(rawSecretContent, 'binary');
83+
await this.fs.promises.writeFile(tmpFile, secretContent);
7484
} catch (e) {
7585
const [cause, _] = binUtils.remoteErrorCause(e);
7686
if (cause instanceof vaultsErrors.ErrorSecretsSecretUndefined) {

src/secrets/CommandGet.ts

Lines changed: 0 additions & 86 deletions
This file was deleted.

src/secrets/CommandRemove.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,28 @@ class CommandDelete extends CommandPolykey {
4949
options: { nodePath: options.nodePath },
5050
logger: this.logger.getChild(PolykeyClient.name),
5151
});
52-
await binUtils.retryAuthentication(async (auth) => {
53-
await pkClient.rpcClient.methods.vaultsSecretsRemove({
54-
metadata: auth,
55-
secretNames: secretPaths,
56-
options: { recursive: options.recursive },
57-
});
52+
const response = await binUtils.retryAuthentication(async (auth) => {
53+
const response =
54+
await pkClient.rpcClient.methods.vaultsSecretsRemove();
55+
await (async () => {
56+
const writer = response.writable.getWriter();
57+
let first = true;
58+
for (const [vault, path] of secretPaths) {
59+
await writer.write({
60+
nameOrId: vault,
61+
secretName: path,
62+
metadata: first
63+
? { ...auth, options: { recursive: options.recursive } }
64+
: undefined,
65+
});
66+
first = false;
67+
}
68+
await writer.close();
69+
})();
70+
return response;
5871
}, meta);
72+
// Wait for the program to generate a response (complete processing).
73+
await response.output;
5974
} finally {
6075
if (pkClient! != null) await pkClient.stop();
6176
}

src/secrets/CommandSecrets.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import CommandCreate from './CommandCreate';
2+
import CommandCat from './CommandCat';
23
import CommandDir from './CommandDir';
34
import CommandEdit from './CommandEdit';
45
import CommandEnv from './CommandEnv';
5-
import CommandGet from './CommandGet';
66
import CommandList from './CommandList';
77
import CommandMkdir from './CommandMkdir';
88
import CommandRename from './CommandRename';
@@ -17,10 +17,10 @@ class CommandSecrets extends CommandPolykey {
1717
this.name('secrets');
1818
this.description('Secrets Operations');
1919
this.addCommand(new CommandCreate(...args));
20+
this.addCommand(new CommandCat(...args));
2021
this.addCommand(new CommandDir(...args));
2122
this.addCommand(new CommandEdit(...args));
2223
this.addCommand(new CommandEnv(...args));
23-
this.addCommand(new CommandGet(...args));
2424
this.addCommand(new CommandList(...args));
2525
this.addCommand(new CommandMkdir(...args));
2626
this.addCommand(new CommandRename(...args));

0 commit comments

Comments
 (0)