From b1b50300a35a1d86522c453c1e81ba3c0497f9b2 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Wed, 26 Jun 2024 16:45:29 +1000 Subject: [PATCH] fix: support most unix style file paths We allow most file paths now including spaces. We exclude `=` to allow the `path=whatever` format and `/` because `isomoric-git` doesn't handle it. [ci skip] --- src/utils/parsers.ts | 5 ++--- tests/secrets/create.test.ts | 40 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/utils/parsers.ts b/src/utils/parsers.ts index 487b49d2..d37af85c 100644 --- a/src/utils/parsers.ts +++ b/src/utils/parsers.ts @@ -8,10 +8,9 @@ import * as gestaltsUtils from 'polykey/dist/gestalts/utils'; import * as networkUtils from 'polykey/dist/network/utils'; import * as nodesUtils from 'polykey/dist/nodes/utils'; -const secretPathRegex = - /^([\w-]+)(?::)([\w\-\\\/\.\$]+)(?:=)?([a-zA-Z_][\w]+)?$/; +const secretPathRegex = /^([\w-]+)(?::)([^\0\\=]+)(?:=)?([a-zA-Z_][\w]+)?$/; const secretPathEnvRegex = - /^([\w-]+)(?::)([\w\-\\\/\.\$]+)(?:=)?([a-zA-Z_]+[a-zA-Z0-9_]*)?$/; + /^([\w-]+)(?::)([^\0\\=]+)(?:=)?([a-zA-Z_]+[a-zA-Z0-9_]*)?$/; /** * Converts a validation parser to commander argument parser diff --git a/tests/secrets/create.test.ts b/tests/secrets/create.test.ts index 11bfec7e..3120535b 100644 --- a/tests/secrets/create.test.ts +++ b/tests/secrets/create.test.ts @@ -1,6 +1,8 @@ import type { VaultName } from 'polykey/dist/vaults/types'; import path from 'path'; import fs from 'fs'; +import { test } from '@fast-check/jest'; +import fc from 'fast-check'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import PolykeyAgent from 'polykey/dist/PolykeyAgent'; import { vaultOps } from 'polykey/dist/vaults'; @@ -76,4 +78,42 @@ describe('commandCreateSecret', () => { }, globalThis.defaultTimeout * 2, ); + const fileNameArb = fc.stringMatching(/^[^\0\\/=]$/); + test.prop([fileNameArb, fileNameArb], { numRuns: 10 })( + 'secrets handle unix style paths for secrets', + async (directoryName, secretName) => { + await polykeyAgent.vaultManager.stop(); + await polykeyAgent.vaultManager.start({ fresh: true }); + const vaultName = 'Vault1' as VaultName; + const vaultId = await polykeyAgent.vaultManager.createVault(vaultName); + const secretPath = path.join(dataDir, 'secret'); + await fs.promises.writeFile(secretPath, 'this is a secret'); + const vaultsSecretPath = path.join(directoryName, secretName); + + command = [ + 'secrets', + 'create', + '-np', + dataDir, + secretPath, + `${vaultName}:${vaultsSecretPath}`, + ]; + + const result = await testUtils.pkStdio([...command], { + env: { + PK_PASSWORD: password, + }, + cwd: dataDir, + }); + expect(result.exitCode).toBe(0); + + await polykeyAgent.vaultManager.withVaults([vaultId], async (vault) => { + const list = await vaultOps.listSecrets(vault); + expect(list.sort()).toStrictEqual([vaultsSecretPath]); + expect( + (await vaultOps.getSecret(vault, vaultsSecretPath)).toString(), + ).toStrictEqual('this is a secret'); + }); + }, + ); });