Created
August 17, 2023 08:39
-
-
Save wyozi/3f51420413d7faa2cb92fe7d15ee5bd5 to your computer and use it in GitHub Desktop.
inngest encrypted step.run return value
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import crypto from "crypto"; | |
import { StepOpts } from "inngest/types"; | |
const CRYPTO_KEY = process.env.BACKGROUND_VAR_CRYPTO_KEY; | |
export type Encrypted<T> = { | |
iv: string; | |
ciphertext: string; | |
}; | |
export async function encryptVars<T>(input: T): Promise<Encrypted<T>> { | |
const key = CRYPTO_KEY!; | |
if (!key) { | |
throw new Error("failed to import key"); | |
} | |
const plaintext = JSON.stringify(input); | |
const iv = crypto.randomBytes(16).toString("hex"); | |
const cipher = crypto.createCipheriv( | |
"aes-256-cbc", | |
Buffer.from(key, "hex"), | |
Buffer.from(iv, "hex") | |
); | |
const ciphertext = `${cipher.update( | |
plaintext, | |
"utf8", | |
"base64" | |
)}${cipher.final("base64")}`; | |
return { | |
iv, | |
ciphertext, | |
}; | |
} | |
export async function decryptVars<T>(encrypted: Encrypted<T>): Promise<T> { | |
const key = CRYPTO_KEY!; | |
if (!key) { | |
throw new Error("failed to import key"); | |
} | |
const decipher = crypto.createDecipheriv( | |
"aes-256-cbc", | |
Buffer.from(key, "hex"), | |
Buffer.from(encrypted.iv, "hex") | |
); | |
const decrypted = `${decipher.update( | |
encrypted.ciphertext, | |
"base64", | |
"utf8" | |
)}${decipher.final("utf8")}`; | |
return JSON.parse(decrypted); | |
} | |
export async function stepRunWithEncryption< | |
Step extends { | |
run: <T extends () => unknown>( | |
name: string, | |
fn: T, | |
opts?: StepOpts | undefined | |
) => Promise<any>; | |
}, | |
T extends () => unknown | |
>(step: Step, name: string, fn: T, opts?: StepOpts | undefined) { | |
return decryptVars( | |
await step.run( | |
name, | |
async () => { | |
const vals = await fn(); | |
return encryptVars(vals); | |
}, | |
opts | |
) | |
) as ReturnType<T>; | |
} | |
/* Usage: | |
1. generate symmetric crypto key with e.g. `node -e 'console.log(require(`crypto`).randomBytes(32).toString(`hex`))'` and store in ENV (BACKGROUND_VAR_CRYPTO_KEY) | |
2. use stepRunWithEncryption for steps that return data that should be encrypted | |
const { foo } = await stepRunWithEncryption(step, "Do something", async () => { | |
return { foo: "this is a secret value" } | |
}) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment