import crypto from 'node:crypto';
const ALGORITHM = 'aes-256-gcm';
const IV_LENGTH = 16;
const KEY_LENGTH = 32;
function deriveKey() {
    const secret = process.env.TUTANUS_ENCRYPTION_KEY;
    if (secret && secret.length >= 16) {
        return crypto.scryptSync(secret, 'tutanus-salt', KEY_LENGTH);
    }
    const fallbackParts = [
        process.env.TUTANUS_ADMIN_TOKEN,
        process.env.GITHUB_WEBHOOK_SECRET,
        process.env.GITHUB_PRIVATE_KEY?.slice(0, 64),
        'tutanus-fallback-key',
    ].filter(Boolean);
    const combined = fallbackParts.join(':');
    return crypto.scryptSync(combined, 'tutanus-salt', KEY_LENGTH);
}
let cachedKey = null;
function getKey() {
    if (!cachedKey) {
        cachedKey = deriveKey();
    }
    return cachedKey;
}
export function encrypt(text) {
    const iv = crypto.randomBytes(IV_LENGTH);
    const cipher = crypto.createCipheriv(ALGORITHM, getKey(), iv);
    let encrypted = cipher.update(text, 'utf8', 'base64');
    encrypted += cipher.final('base64');
    const authTag = cipher.getAuthTag();
    return `${iv.toString('base64')}:${authTag.toString('base64')}:${encrypted}`;
}
export function decrypt(encrypted) {
    const parts = encrypted.split(':');
    if (parts.length !== 3) {
        throw new Error('Formato de dado criptografado invalido');
    }
    const iv = Buffer.from(parts[0], 'base64');
    const authTag = Buffer.from(parts[1], 'base64');
    const data = parts[2];
    const decipher = crypto.createDecipheriv(ALGORITHM, getKey(), iv);
    decipher.setAuthTag(authTag);
    let decrypted = decipher.update(data, 'base64', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
}
export function encryptJson(data) {
    return encrypt(JSON.stringify(data));
}
export function decryptJson(encrypted) {
    return JSON.parse(decrypt(encrypted));
}
export function encryptObject(obj, sensitiveFields) {
    const result = { ...obj };
    for (const field of sensitiveFields) {
        if (result[field] !== undefined && result[field] !== null) {
            const val = result[field];
            if (typeof val === 'string') {
                result[field] = encrypt(val);
            }
            else {
                result[field] = encryptJson(val);
            }
        }
    }
    return result;
}
export function decryptObject(obj, sensitiveFields) {
    const result = { ...obj };
    for (const field of sensitiveFields) {
        const val = result[field];
        if (typeof val === 'string' && val.includes(':')) {
            try {
                result[field] = decrypt(val);
            }
            catch {
                try {
                    const decrypted = decryptJson(val);
                    result[field] = decrypted;
                }
                catch {
                }
            }
        }
    }
    return result;
}
export function hashToken(token) {
    return crypto.createHash('sha256').update(token).digest('hex');
}
export function signRequest(payload, secret) {
    return crypto.createHmac('sha256', secret).update(payload).digest('hex');
}
export function verifyRequestSignature(payload, signature, secret) {
    try {
        const expected = signRequest(payload, secret);
        return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
    }
    catch {
        return false;
    }
}
//# sourceMappingURL=crypto.js.map