Skip to content

Commit c7a681d

Browse files
LukasFritzeDevLukas Fritzemartin-helmich
authored
Fix TransitDecryptResponse interfaces (#13)
* Fix TransitDecryptResponse interfaces to match the vault response for empty strings * Fix batch transit test * Use default "" instead of undefined * Add test for empty strings in batch transit * Prefer await Co-authored-by: Martin Helmich <[email protected]> Co-authored-by: Lukas Fritze <[email protected]> Co-authored-by: Martin Helmich <[email protected]>
1 parent cbdc045 commit c7a681d

File tree

4 files changed

+60
-4
lines changed

4 files changed

+60
-4
lines changed

src/engines/transit.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
ITransitCreateOptions,
77
ITransitDecryptOptionsBatch,
88
ITransitDecryptOptionsSingle,
9+
ITransitDecryptRawResponseBatch,
910
ITransitDecryptResponseBatch,
1011
ITransitDecryptResponseSingle,
1112
ITransitEncryptOptionsBatch,
@@ -200,11 +201,12 @@ export class TransitVaultClient extends AbstractVaultClient {
200201
validateKeyName(key);
201202
return this.rawWrite(["decrypt", key], options).then((res) => {
202203
if ("batch_input" in options) {
203-
transitChecker.ITransitDecryptResponseBatch.check(res);
204+
transitChecker.ITransitDecryptRawResponseBatch.check(res);
205+
return TransitVaultClient.checkEmptyBatchValues(res as ITransitDecryptRawResponseBatch);
204206
} else {
205207
transitChecker.ITransitDecryptResponseSingle.check(res);
208+
return res;
206209
}
207-
return res;
208210
});
209211
}
210212

@@ -226,6 +228,32 @@ export class TransitVaultClient extends AbstractVaultClient {
226228
*/
227229
public async decryptText(key: string, ciphertext: string): Promise<string> {
228230
validateKeyName(key);
229-
return this.decrypt(key, { ciphertext }).then((res) => Buffer.from(res.data.plaintext, "base64").toString());
231+
const res = await this.decrypt(key, { ciphertext });
232+
if (res.data.plaintext === undefined) {
233+
return "";
234+
}
235+
return Buffer.from(res.data.plaintext, "base64").toString();
236+
}
237+
238+
/*
239+
* Check to fix undefined plaintext values in a decrypt response.
240+
* @see https://github.com/hashicorp/vault/issues/6140
241+
*
242+
* {plaintext: ""} -> encrypt -> {ciphertext: "abc...yxz"} -> decrypt -> {}
243+
*/
244+
private static checkEmptyBatchValues(res: ITransitDecryptRawResponseBatch): ITransitDecryptResponseBatch {
245+
const batchData = res.data.batch_results;
246+
return {
247+
...res,
248+
data: {
249+
...res.data,
250+
batch_results: batchData.map((v) => {
251+
return {
252+
...v,
253+
plaintext: v.plaintext ?? "",
254+
};
255+
}),
256+
},
257+
};
230258
}
231259
}

src/engines/transit_types-ti.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ export const ITransitBatchPlaintext = t.array(t.iface([], {
1111
"context": t.opt("string"),
1212
}));
1313

14+
export const ITransitRawBatchPlaintext = t.array(t.iface([], {
15+
"plaintext": t.opt("string"),
16+
"context": t.opt("string"),
17+
}));
18+
1419
export const ITransitBatchCiphertext = t.array(t.iface([], {
1520
"ciphertext": "string",
1621
"context": t.opt("string"),
@@ -125,9 +130,16 @@ export const ITransitDecryptResponseBatch = t.iface([], {
125130
}),
126131
});
127132

133+
export const ITransitDecryptRawResponseBatch = t.iface([], {
134+
"data": t.iface([], {
135+
"batch_results": "ITransitRawBatchPlaintext",
136+
}),
137+
});
138+
128139
const exportedTypeSuite: t.ITypeSuite = {
129140
ITransitKeyType,
130141
ITransitBatchPlaintext,
142+
ITransitRawBatchPlaintext,
131143
ITransitBatchCiphertext,
132144
ITransitCreateOptions,
133145
ITransitReadResponse,
@@ -143,5 +155,6 @@ const exportedTypeSuite: t.ITypeSuite = {
143155
ITransitDecryptOptionsBatch,
144156
ITransitDecryptResponseSingle,
145157
ITransitDecryptResponseBatch,
158+
ITransitDecryptRawResponseBatch,
146159
};
147160
export default exportedTypeSuite;

src/engines/transit_types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ export type ITransitBatchPlaintext = Array<{
44
plaintext: string;
55
context?: string;
66
}>;
7+
export type ITransitRawBatchPlaintext = Array<{
8+
plaintext?: string;
9+
context?: string;
10+
}>;
711
export type ITransitBatchCiphertext = Array<{
812
ciphertext: string;
913
context?: string;
@@ -118,3 +122,8 @@ export interface ITransitDecryptResponseBatch {
118122
batch_results: ITransitBatchPlaintext;
119123
};
120124
}
125+
export interface ITransitDecryptRawResponseBatch {
126+
data: {
127+
batch_results: ITransitRawBatchPlaintext;
128+
};
129+
}

tests/engines/transit.spec.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ describe("Transit Vault Client", () => {
8686
{
8787
plaintext: text,
8888
},
89+
{
90+
plaintext: "",
91+
},
8992
];
9093

9194
const result = await client
@@ -95,7 +98,10 @@ describe("Transit Vault Client", () => {
9598
.then((res) => res.data.batch_results);
9699
const res = await client
97100
.decrypt("test", {
98-
batch_input: result,
101+
batch_input: result.map((r) => ({
102+
ciphertext: r.ciphertext,
103+
context: r.context,
104+
})),
99105
})
100106
.then((res) => res.data.batch_results);
101107

0 commit comments

Comments
 (0)