UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

78 lines (77 loc) 2.06 kB
import { decodeBase64, decodeHex, encodeBase64, encodeHexUpperCase } from "@oslojs/encoding"; const ALGORITHM = "AES-GCM"; async function createKey() { const key = await crypto.subtle.generateKey( { name: ALGORITHM, length: 256 }, true, ["encrypt", "decrypt"] ); return key; } const ENVIRONMENT_KEY_NAME = "ASTRO_KEY"; function getEncodedEnvironmentKey() { return process.env[ENVIRONMENT_KEY_NAME] || ""; } function hasEnvironmentKey() { return getEncodedEnvironmentKey() !== ""; } async function getEnvironmentKey() { if (!hasEnvironmentKey()) { throw new Error( `There is no environment key defined. If you see this error there is a bug in Astro.` ); } const encodedKey = getEncodedEnvironmentKey(); return decodeKey(encodedKey); } async function encodeKey(key) { const exported = await crypto.subtle.exportKey("raw", key); const encodedKey = encodeBase64(new Uint8Array(exported)); return encodedKey; } async function decodeKey(encoded) { const bytes = decodeBase64(encoded); return crypto.subtle.importKey("raw", bytes, ALGORITHM, true, ["encrypt", "decrypt"]); } const encoder = new TextEncoder(); const decoder = new TextDecoder(); const IV_LENGTH = 24; async function encryptString(key, raw) { const iv = crypto.getRandomValues(new Uint8Array(IV_LENGTH / 2)); const data = encoder.encode(raw); const buffer = await crypto.subtle.encrypt( { name: ALGORITHM, iv }, key, data ); return encodeHexUpperCase(iv) + encodeBase64(new Uint8Array(buffer)); } async function decryptString(key, encoded) { const iv = decodeHex(encoded.slice(0, IV_LENGTH)); const dataArray = decodeBase64(encoded.slice(IV_LENGTH)); const decryptedBuffer = await crypto.subtle.decrypt( { name: ALGORITHM, iv }, key, dataArray ); const decryptedString = decoder.decode(decryptedBuffer); return decryptedString; } export { createKey, decodeKey, decryptString, encodeKey, encryptString, getEnvironmentKey, hasEnvironmentKey };