Decoding base64 string as an expression

Describe the issue/error/question

What is the error message (if any)?

I need to decrypt several base64 strings that are output by my http request node as keys from a single item:

{
	"data": {
		"key1": "SGVsbG8sIFdvcmxkIQ==",
		"key2": "T2ggd2hhdCBhIGxvdmVseSBkYXkh"
	}
}

Since the crypto node does not yet support decoding, I would like to do this using an expression (so I can reference each Key using the standard n8n input).

I tried: {{ Buffer.from("SGVsbG8sIFdvcmxkIQ==", 'base64').toString('utf8') }} but it doesn’t work.

If it is not possble to do this using an expression, then I need to loop through each key and decode the value of each one.

However, I am really not good with Javascript and especially re-factoring code into expressions.

I would appreciate if anyone can provide me a solution.

Please share the workflow

Share the output returned by the last node

Information on your n8n setup

  • n8n version: 0.201.0
  • Database you’re using (default: SQLite): Postgres
  • Running n8n with the execution process [own(default), main]: own
  • Running n8n via [Docker, npm, n8n.cloud, desktop app]: k8s

Hi @joeldeteves I’m not sure what you’re trying to do, and how to do this via an expression, but perhaps doing this via the Code node maybe an option for you.

let items = $input.all()

let temp = Buffer.from(items[0].json.data.key1).toString('utf8')

return {temp}
1 Like

The Code node option is probably the best one, While you can run JS in Expressions there are somethings that it doesn’t like doing.

Any idea why this doesn’t work?

{{ Buffer.from("SGVsbG8sIFdvcmxkIQ==", 'base64').toString('utf8') }}

This would be perfect for me if it did work.

Re: code node, that would work too but @dickhoning’s solution doesn’t work for me since I have multiple key:value pairs.

I could use a bit of help with that JS is not my strong suit so I’m grateful for any assistance there!

The buffer doesn’t work in expressions I think.
So like @Jon and @dickhoning mentioned, the code node would be the only option I think.

How do I loop through each of my keys?

The example provided by @dickhoning doesn’t tell me how to do that.

EDIT: Got somewhat further - took me awhile to figure out how to return items in the Code Node as objects. but I still have to manually input the key names, which is cumbersome when there are lots of keys with different names to be decoded:

If there is a clever way to loop through json key regardless of its name (and preferably to keep its name in the output) that would solve a big problem for me

Hi @joeldeteves how many keys do you have? Only the 2 in your example?

Two in this example. But in some cases there could be 10 or more.

For context, I’m pulling in Secrets from Kubernetes all of which are encoded in Base64 - I’m doing this because the current Oauth2 Credentials node is not flexible enough (does not include the ability to add custom body parameters).

My next best solution to avoid storing creds in plaintext is to store them as K8s secrets in the same pod as my n8n instance, and pull them in where needed using the K8s API which is how I arrived at this problem.

@joeldeteves you may want to try this …

let items = $input.all()

let results = [];

for (item of items) {
  for (key of Object.keys(item.json.data)) {
    results.push({
      json: {
        [key]: Buffer.from(items[0].json.data[key]).toString('utf8')
      }
    })
  }
}

return results;

Sample workflow:

2 Likes

Amazing! A slight change (add the base64 spec so it knows what to decode from).

But your suggestion worked beautifully!

let items = $input.all()

let results = [];

for (item of items) {
  for (key of Object.keys(item.json.data)) {
    results.push({
      json: {
        [key]: Buffer.from(items[0].json.data[key], 'base64').toString('utf8')
      }
    })
  }
}

return results;

@dickhoning @BramKn here is an even better solution. Dick’s solution got my brain moving in the right direction.

This modified version keeps the existing data structure without needing to push to an array. It does EXACTLY what I want. Thanks for all your help! :smiley:

let items = $input.all()

for (item of items) {
  for (key of Object.keys(item.json.data)) {
    item.json.data[key] = Buffer.from(items[0].json.data[key], 'base64').toString('utf8')
  }
}

return items;
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.