Files
sgse-app/packages/backend/convex/actions/utils/nodeCrypto.ts

74 lines
1.9 KiB
TypeScript

'use node';
/**
* Utilitários de criptografia compatíveis com Node.js
* Para uso em actions que rodam em ambiente Node.js
*/
/**
* Descriptografa senha SMTP usando Web Crypto API compatível com Node.js
* Esta versão funciona em ambiente Node.js (actions)
*/
export async function decryptSMTPPasswordNode(encryptedPassword: string): Promise<string> {
try {
// Em Node.js, crypto.subtle está disponível globalmente
const crypto = globalThis.crypto;
if (!crypto || !crypto.subtle) {
throw new Error('Web Crypto API não disponível');
}
// Chave base - mesma usada em auth/utils.ts
const keyMaterial = new TextEncoder().encode('SGSE-EMAIL-ENCRYPTION-KEY-2024');
// Importar chave material
const keyMaterialKey = await crypto.subtle.importKey(
'raw',
keyMaterial,
{ name: 'PBKDF2' },
false,
['deriveBits', 'deriveKey']
);
// Derivar chave de 256 bits usando PBKDF2
const key = await crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: new TextEncoder().encode('SGSE-SALT'),
iterations: 100000,
hash: 'SHA-256'
},
keyMaterialKey,
{ name: 'AES-GCM', length: 256 },
false,
['encrypt', 'decrypt']
);
// Decodificar base64 manualmente (compatível com Node.js e browser)
const binaryString = atob(encryptedPassword);
const combined = Uint8Array.from(binaryString, (c) => c.charCodeAt(0));
// Extrair IV e dados criptografados
const iv = combined.slice(0, 12);
const encrypted = combined.slice(12);
// Descriptografar
const decrypted = await crypto.subtle.decrypt(
{
name: 'AES-GCM',
iv: iv
},
key,
encrypted
);
// Converter para string
const decoder = new TextDecoder();
return decoder.decode(decrypted);
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
console.error('Erro ao descriptografar senha SMTP (Node.js):', errorMessage);
throw new Error(`Falha ao descriptografar senha SMTP: ${errorMessage}`);
}
}