68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
import "server-only";
|
|
|
|
import {
|
|
createCipheriv,
|
|
createDecipheriv,
|
|
createHash,
|
|
randomBytes,
|
|
} from "node:crypto";
|
|
|
|
const ENCRYPTED_SECRET_PREFIX = "enc:v1";
|
|
|
|
function getEncryptionKey() {
|
|
const secret = String(
|
|
process.env.OPENCLAW_TASK_SECRET ||
|
|
process.env.AUTH_SECRET ||
|
|
process.env.NEXTAUTH_SECRET ||
|
|
""
|
|
).trim();
|
|
if (!secret) {
|
|
throw new Error(
|
|
"OPENCLAW_TASK_SECRET or AUTH_SECRET is required for durable tasks"
|
|
);
|
|
}
|
|
return createHash("sha256").update(secret, "utf8").digest();
|
|
}
|
|
|
|
export function encryptOpenClawTaskSecret(value: string) {
|
|
const normalized = value.trim();
|
|
if (!normalized || normalized.startsWith(`${ENCRYPTED_SECRET_PREFIX}:`)) {
|
|
return normalized;
|
|
}
|
|
const iv = randomBytes(12);
|
|
const cipher = createCipheriv("aes-256-gcm", getEncryptionKey(), iv);
|
|
const encrypted = Buffer.concat([
|
|
cipher.update(normalized, "utf8"),
|
|
cipher.final(),
|
|
]);
|
|
const authTag = cipher.getAuthTag();
|
|
return [
|
|
ENCRYPTED_SECRET_PREFIX,
|
|
iv.toString("base64url"),
|
|
authTag.toString("base64url"),
|
|
encrypted.toString("base64url"),
|
|
].join(":");
|
|
}
|
|
|
|
export function decryptOpenClawTaskSecret(value: string) {
|
|
const normalized = value.trim();
|
|
if (!normalized.startsWith(`${ENCRYPTED_SECRET_PREFIX}:`)) {
|
|
// Backward compatibility for tasks persisted before encryption was added.
|
|
return normalized;
|
|
}
|
|
const [, , ivValue, authTagValue, encryptedValue] = normalized.split(":");
|
|
if (!ivValue || !authTagValue || !encryptedValue) {
|
|
throw new Error("Invalid encrypted OpenClaw task secret");
|
|
}
|
|
const decipher = createDecipheriv(
|
|
"aes-256-gcm",
|
|
getEncryptionKey(),
|
|
Buffer.from(ivValue, "base64url")
|
|
);
|
|
decipher.setAuthTag(Buffer.from(authTagValue, "base64url"));
|
|
return Buffer.concat([
|
|
decipher.update(Buffer.from(encryptedValue, "base64url")),
|
|
decipher.final(),
|
|
]).toString("utf8");
|
|
}
|