-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix secrets stored in JSON format #473
Changes from 11 commits
a24b038
788264d
e5605de
b536ec9
a2cae73
8e836c6
ccc7cef
b239ef3
1a47f33
4ef6471
d12e95b
32afcc7
51d98a5
d98037e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,4 +66,4 @@ describe('exportSecrets retries', () => { | |
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,7 +72,21 @@ async function getSecrets(secretRequests, client) { | |
*/ | ||
async function selectData(data, selector) { | ||
const ata = jsonata(selector); | ||
let result = JSON.stringify(await ata.evaluate(data)); | ||
let d = await ata.evaluate(data); | ||
|
||
// If we have a Javascript Object, then this data was stored in Vault as | ||
// pure JSON (not a JSON string) | ||
const storedAsJSONData = isObject(d); | ||
|
||
if (isJSONString(d)) { | ||
// If we already have a JSON string we will not "stringify" it yet so | ||
// that we don't end up calling JSON.parse. This would break the | ||
// secrets that are stored as pure JSON. See: https://github.com/hashicorp/vault-action/issues/194 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like you mentioned this before so apologies if this is a repeated q: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, JSON.parse does not call JSON.stringify --if I am understanding you correctly. I see how this comment might convey that though. I will see if I can improve the wording a bit. |
||
result = d; | ||
} else { | ||
result = JSON.stringify(d); | ||
} | ||
|
||
// Compat for custom engines | ||
if (!result && ((ata.ast().type === "path" && ata.ast()['steps'].length === 1) || ata.ast().type === "string") && selector !== 'data' && 'data' in data) { | ||
result = JSON.stringify(await jsonata(`data.${selector}`).evaluate(data)); | ||
|
@@ -81,12 +95,57 @@ async function selectData(data, selector) { | |
} | ||
|
||
if (result.startsWith(`"`)) { | ||
result = JSON.parse(result); | ||
// we need to strip the beginning and ending quotes otherwise it will | ||
// always successfully parse as a JSON string | ||
result = result.substring(1, result.length - 1); | ||
if (!isJSONString(result)) { | ||
// add the quotes back so we can parse it into a Javascript object | ||
// to allow support for multi-line secrets. See https://github.com/hashicorp/vault-action/issues/160 | ||
result = `"${result}"` | ||
result = JSON.parse(result); | ||
} | ||
} else if (isJSONString(result)) { | ||
if (storedAsJSONData) { | ||
// Support secrets stored in Vault as pure JSON. | ||
vinay-gopalan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// See https://github.com/hashicorp/vault-action/issues/194 and https://github.com/hashicorp/vault-action/pull/173 | ||
result = JSON.stringify(result); | ||
result = result.substring(1, result.length - 1); | ||
} else { | ||
// Support secrets stored in Vault as JSON Strings | ||
result = JSON.stringify(result); | ||
result = JSON.parse(result); | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
/** | ||
* isOjbect returns true if target is a Javascript object | ||
* @param {Type} target | ||
*/ | ||
function isObject(target) { | ||
return typeof target === 'object' && target !== null; | ||
} | ||
|
||
/** | ||
* isJSONString returns true if target parses as a valid JSON string | ||
* @param {Type} target | ||
*/ | ||
function isJSONString(target) { | ||
if (typeof target !== "string"){ | ||
return false; | ||
} | ||
|
||
try { | ||
let o = JSON.parse(target); | ||
} catch (e) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
module.exports = { | ||
getSecrets, | ||
selectData | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like an accidental second newline added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops submitted this too late 😓