Skip to content

Commit c2d70c1

Browse files
committed
fix: fixed parsing secret path not parsing the optional value
1 parent b7871a4 commit c2d70c1

5 files changed

Lines changed: 30 additions & 40 deletions

File tree

src/secrets/CommandList.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class CommandList extends CommandPolykey {
1414
this.argument(
1515
'<directoryPath>',
1616
'Directory to list files from, specified as <vaultName>[:<path>]',
17-
binParsers.parseSecretName,
17+
binParsers.parseSecretPathOptional,
1818
);
1919
this.addOption(binOptions.nodeId);
2020
this.addOption(binOptions.clientHost);

src/utils/parsers.ts

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import * as gestaltsUtils from 'polykey/dist/gestalts/utils';
88
import * as networkUtils from 'polykey/dist/network/utils';
99
import * as nodesUtils from 'polykey/dist/nodes/utils';
1010

11-
const vaultNameRegex = /^[\w.-]+$/;
12-
const secretPathNameRegex = /^([\w-]+)(?::([^\0\\=]+))?$/;
11+
const secretPathRegex = /^([\w-]+)(?::([^\0\\=]+))?$/;
1312
const secretPathValueRegex = /^([a-zA-Z_][\w]+)?$/;
1413
const environmentVariableRegex = /^([a-zA-Z_]+[a-zA-Z0-9_]*)?$/;
1514

@@ -66,47 +65,44 @@ function parseCoreCount(v: string): number | undefined {
6665
}
6766
}
6867

69-
function parseVaultName(vaultName: string): string {
70-
// E.g. If 'vault1, 'vault1' is returned
71-
// If 'vault1:a/b/c', an error is thrown
72-
if (!vaultNameRegex.test(vaultName)) {
73-
throw new commander.InvalidArgumentError(
74-
`${vaultName} is not of the format <vaultName>`,
75-
);
76-
}
77-
// Returns match[1], or the parsed vaultName
78-
return vaultName.match(secretPathNameRegex)![1];
79-
}
80-
81-
function parseSecretName(secretPath: string): [string, string?] {
68+
function parseSecretPathOptional(
69+
secretPath: string,
70+
): [string, string?, string?] {
8271
// E.g. If 'vault1:a/b/c', ['vault1', 'a/b/c'] is returned
8372
// If 'vault1', ['vault1, undefined] is returned
84-
if (!secretPathNameRegex.test(secretPath)) {
73+
// splits out everything after an `=` separator
74+
const lastEqualIndex = secretPath.lastIndexOf('=');
75+
const splitSecretPath =
76+
lastEqualIndex === -1
77+
? secretPath
78+
: secretPath.substring(0, lastEqualIndex);
79+
const value =
80+
lastEqualIndex === -1
81+
? undefined
82+
: secretPath.substring(lastEqualIndex + 1);
83+
if (!secretPathRegex.test(splitSecretPath)) {
8584
throw new commander.InvalidArgumentError(
86-
`${secretPath} is not of the format <vaultName>[:<directoryPath>]`,
85+
`${secretPath} is not of the format <vaultName>[:<directoryPath>][=<value>]`,
8786
);
8887
}
89-
// Returns [vaultName, secretName?]
90-
const match = secretPath.match(secretPathNameRegex)!;
91-
return [match[1], match[2] || undefined];
88+
const [, vaultName, directoryPath] = splitSecretPath.match(secretPathRegex)!;
89+
return [vaultName, directoryPath, value];
9290
}
9391

9492
function parseSecretPath(secretPath: string): [string, string, string?] {
9593
// E.g. If 'vault1:a/b/c', ['vault1', 'a/b/c'] is returned
9694
// If 'vault1', an error is thrown
97-
const [vaultName, secretName] = parseSecretName(secretPath);
95+
const [vaultName, secretName, value] = parseSecretPathOptional(secretPath);
9896
if (secretName === undefined) {
9997
throw new commander.InvalidArgumentError(
100-
`${secretPath} is not of the format <vaultName>:<directoryPath>`,
98+
`${secretPath} is not of the format <vaultName>:<directoryPath>[=<value>]`,
10199
);
102100
}
103-
return [vaultName, secretName];
101+
return [vaultName, secretName, value];
104102
}
105103

106104
function parseSecretPathValue(secretPath: string): [string, string, string?] {
107-
const [vaultName, directoryPath] = parseSecretPath(secretPath);
108-
const lastEqualIndex = secretPath.lastIndexOf('=');
109-
const value = lastEqualIndex === -1 ? '' : secretPath.substring(lastEqualIndex + 1);
105+
const [vaultName, directoryPath, value] = parseSecretPath(secretPath);
110106
if (value != null && !secretPathValueRegex.test(value)) {
111107
throw new commander.InvalidArgumentError(
112108
`${value} is not a valid value name`,
@@ -219,13 +215,13 @@ function parseEnvArgs(
219215
}
220216

221217
export {
218+
secretPathRegex,
222219
secretPathValueRegex,
223220
environmentVariableRegex,
224221
validateParserToArgParser,
225222
validateParserToArgListParser,
226223
parseCoreCount,
227-
parseVaultName,
228-
parseSecretName,
224+
parseSecretPathOptional,
229225
parseSecretPath,
230226
parseSecretPathValue,
231227
parseSecretPathEnv,

src/vaults/CommandCreate.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,14 @@ import CommandPolykey from '../CommandPolykey';
44
import * as binUtils from '../utils';
55
import * as binOptions from '../utils/options';
66
import * as binProcessors from '../utils/processors';
7-
import * as binParsers from '../utils/parsers';
87

98
class CommandCreate extends CommandPolykey {
109
constructor(...args: ConstructorParameters<typeof CommandPolykey>) {
1110
super(...args);
1211
this.name('create');
1312
this.aliases(['touch']);
1413
this.description('Create a new Vault');
15-
this.argument(
16-
'<vaultName>',
17-
'Name of the new vault to be created',
18-
binParsers.parseVaultName,
19-
);
14+
this.argument('<vaultName>', 'Name of the new vault to be created');
2015
this.addOption(binOptions.nodeId);
2116
this.addOption(binOptions.clientHost);
2217
this.addOption(binOptions.clientPort);

tests/secrets/env.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ describe('commandEnv', () => {
764764
const jsonOut = JSON.parse(result.stdout);
765765
expect(jsonOut['SECRET']).toBe('this is a secret\nit has multiple lines\n');
766766
});
767-
test.only.prop([
767+
test.prop([
768768
testUtils.secretPathEnvArrayArb,
769769
fc.string().noShrink(),
770770
testUtils.cmdArgsArrayArb,
@@ -773,7 +773,6 @@ describe('commandEnv', () => {
773773
async (secretPathEnvArray, cmd, cmdArgsArray) => {
774774
// If we don't use the optional `--` delimiter then we can't include `:` in vault names
775775
fc.pre(!cmd.includes(':'));
776-
777776
let output:
778777
| [Array<[string, string, string?]>, Array<string>]
779778
| undefined = undefined;

tests/utils/utils.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ async function nodesConnect(localNode: PolykeyAgent, remoteNode: PolykeyAgent) {
8888
);
8989
}
9090

91-
const secretPathWithoutEnvArb = fc
92-
.stringMatching(binParsers.secretPathRegex)
93-
.noShrink();
91+
// This regex defines a vault secret path that always includes the secret path
92+
const secretPathRegex = /^([\w-]+)(?::)([^\0\\=]+)$/;
93+
const secretPathWithoutEnvArb = fc.stringMatching(secretPathRegex).noShrink();
9494
const environmentVariableAre = fc
9595
.stringMatching(binParsers.environmentVariableRegex)
9696
.filter((v) => v.length > 0)

0 commit comments

Comments
 (0)