Files
feeddeck/supabase/functions/_shared/utils/encrypt.ts
Rico Berger b8fdbf17a2 Rework Edge Functions (#247)
Instead of using an `import_map.json` file to define the versions for
dependencies, they are now defined directly within the import. Since the
`import_map.json` file should not be used anymore and instead a
`deno.json` file per function should be used, we decided to define them
directly with the code. The overhead compared to a `deno.json` file per
function shouldn't be that large and it makes using functions in a
self-hosted setup easier.
2025-04-23 17:00:21 +02:00

81 lines
2.3 KiB
TypeScript

import {
decodeHex,
encodeHex,
} from "https://deno.land/std@0.208.0/encoding/hex.ts";
import {
FEEDDECK_ENCRYPTION_IV,
FEEDDECK_ENCRYPTION_KEY,
} from "./constants.ts";
/**
* The `generateKey` function is used to generate the values for the
* `FEEDDECK_ENCRYPTION_KEY` and `FEEDDECK_ENCRYPTION_IV` environment variables,
* which are used to encryt / decrypt the users account data, before it is
* stored in the database.
*/
export const generateKey = async (): Promise<{
rawKey: string;
iv: string;
}> => {
const key = await crypto.subtle.generateKey(
{ name: "AES-CBC", length: 128 },
true,
["encrypt", "decrypt"],
);
const rawKey = new Uint8Array(await crypto.subtle.exportKey("raw", key));
return {
rawKey: encodeHex(rawKey),
iv: encodeHex(crypto.getRandomValues(new Uint8Array(16))),
};
};
/**
* `encrypt` encrypts the provided `plainText` so it can be stored in the
* database. The values for the required environment variables can be generated
* using the `generateKey` function.
*/
export const encrypt = async (plainText: string): Promise<string> => {
const rawKey = decodeHex(FEEDDECK_ENCRYPTION_KEY);
const key = await crypto.subtle.importKey(
"raw",
rawKey.buffer,
"AES-CBC",
true,
["encrypt", "decrypt"],
);
const iv = decodeHex(FEEDDECK_ENCRYPTION_IV);
const encrypted = await crypto.subtle.encrypt(
{ name: "AES-CBC", iv },
key,
new TextEncoder().encode(plainText),
);
const encryptedBytes = new Uint8Array(encrypted);
return encodeHex(encryptedBytes);
};
/**
* `decrypt` decrypts the provided `encryptedText` so it can be used in the
* application. The values for the required environment variables can be
* generated using the `generateKey` function.
*/
export const decrypt = async (encryptedText: string): Promise<string> => {
const rawKey = decodeHex(FEEDDECK_ENCRYPTION_KEY);
const key = await crypto.subtle.importKey(
"raw",
rawKey.buffer,
"AES-CBC",
true,
["encrypt", "decrypt"],
);
const iv = decodeHex(FEEDDECK_ENCRYPTION_IV);
const decrypted = await crypto.subtle.decrypt(
{ name: "AES-CBC", iv },
key,
decodeHex(encryptedText),
);
const decryptedBytes = new Uint8Array(decrypted);
return new TextDecoder().decode(decryptedBytes);
};