Skip to content

Commit 6884811

Browse files
guo-yuclaude
andcommitted
fix: escape dots in project names for op assignment statements
Projects with dots (e.g. sandbank.dev) caused op CLI to reject the assignment statement due to multiple unescaped periods. Now escape dots, equals, and backslashes in section/field names per op CLI spec. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 96b4056 commit 6884811

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

packages/core/src/backends/onepassword.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ export class OnePasswordBackend implements SecretBackend {
2121
return `${project}-${env}`;
2222
}
2323

24+
/** Escape dots, equals, and backslashes for op assignment statements */
25+
private escapeAssignment(s: string): string {
26+
return s.replace(/\\/g, "\\\\").replace(/\./g, "\\.").replace(/=/g, "\\=");
27+
}
28+
2429
buildRef(ref: SecretRef): string {
2530
const section = this.sectionName(ref.project, ref.env);
2631
return `op://${ref.vault}/${ref.provider}/${section}/${ref.field}`;
@@ -32,8 +37,9 @@ export class OnePasswordBackend implements SecretBackend {
3237

3338
buildWriteArgs(entry: SecretEntry): string[] {
3439
const { ref, value } = entry;
35-
const section = this.sectionName(ref.project, ref.env);
36-
const fieldKey = `${section}.${ref.field}`;
40+
const section = this.escapeAssignment(this.sectionName(ref.project, ref.env));
41+
const field = this.escapeAssignment(ref.field);
42+
const fieldKey = `${section}.${field}`;
3743
return [
3844
"item",
3945
"edit",
@@ -178,8 +184,9 @@ export class OnePasswordBackend implements SecretBackend {
178184

179185
async write(entry: SecretEntry): Promise<void> {
180186
const { ref, value } = entry;
181-
const section = this.sectionName(ref.project, ref.env);
182-
const fieldKey = `${section}.${ref.field}`;
187+
const section = this.escapeAssignment(this.sectionName(ref.project, ref.env));
188+
const field = this.escapeAssignment(ref.field);
189+
const fieldKey = `${section}.${field}`;
183190

184191
await this.ensureVault(ref.vault);
185192

@@ -223,11 +230,12 @@ export class OnePasswordBackend implements SecretBackend {
223230

224231
for (const group of groups.values()) {
225232
const { vault, provider, project, env } = group[0].ref;
226-
const section = this.sectionName(project, env);
233+
const section = this.escapeAssignment(this.sectionName(project, env));
227234
await this.ensureVault(vault);
228235

229236
const fieldArgs = group.map(({ ref, value }) => {
230-
const fieldKey = `${section}.${ref.field}`;
237+
const field = this.escapeAssignment(ref.field);
238+
const fieldKey = `${section}.${field}`;
231239
return `${fieldKey}[password]=${value}`;
232240
});
233241

0 commit comments

Comments
 (0)