Initial open-source self-hosted Songs2YT edition
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { createCipheriv, createDecipheriv, createHash, randomBytes } from "crypto";
|
||||
|
||||
const ENC_PREFIX = "enc:v1:";
|
||||
|
||||
function getEncryptionKey() {
|
||||
const secret = process.env.TOKEN_ENCRYPTION_KEY || process.env.NEXTAUTH_SECRET;
|
||||
if (!secret) {
|
||||
throw new Error("TOKEN_ENCRYPTION_KEY or NEXTAUTH_SECRET must be set to encrypt secrets");
|
||||
}
|
||||
return createHash("sha256").update(secret).digest();
|
||||
}
|
||||
|
||||
/** Encrypt a secret for DB storage (AES-256-GCM). Idempotent if already encrypted. */
|
||||
export function encryptSecret(plaintext: string): string {
|
||||
if (!plaintext) return plaintext;
|
||||
if (plaintext.startsWith(ENC_PREFIX)) return plaintext;
|
||||
|
||||
const iv = randomBytes(12);
|
||||
const cipher = createCipheriv("aes-256-gcm", getEncryptionKey(), iv);
|
||||
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
||||
const tag = cipher.getAuthTag();
|
||||
|
||||
return [
|
||||
ENC_PREFIX,
|
||||
iv.toString("base64url"),
|
||||
".",
|
||||
tag.toString("base64url"),
|
||||
".",
|
||||
encrypted.toString("base64url"),
|
||||
].join("");
|
||||
}
|
||||
|
||||
/** Decrypt a stored secret. Legacy plaintext values are returned as-is. */
|
||||
export function decryptSecret(value: string): string {
|
||||
if (!value) return value;
|
||||
if (!value.startsWith(ENC_PREFIX)) return value;
|
||||
|
||||
const payload = value.slice(ENC_PREFIX.length);
|
||||
const [ivB64, tagB64, dataB64] = payload.split(".");
|
||||
if (!ivB64 || !tagB64 || !dataB64) {
|
||||
throw new Error("Invalid encrypted secret format");
|
||||
}
|
||||
|
||||
const decipher = createDecipheriv(
|
||||
"aes-256-gcm",
|
||||
getEncryptionKey(),
|
||||
Buffer.from(ivB64, "base64url"),
|
||||
);
|
||||
decipher.setAuthTag(Buffer.from(tagB64, "base64url"));
|
||||
const decrypted = Buffer.concat([
|
||||
decipher.update(Buffer.from(dataB64, "base64url")),
|
||||
decipher.final(),
|
||||
]);
|
||||
return decrypted.toString("utf8");
|
||||
}
|
||||
Reference in New Issue
Block a user