feat: update ESLint and TypeScript configurations across frontend and backend; enhance component structure and improve data handling in various modules

This commit is contained in:
2025-12-02 16:36:02 -03:00
parent f48d28067c
commit d79e6959c3
215 changed files with 29474 additions and 28173 deletions

View File

@@ -7,127 +7,112 @@
* Gera um hash seguro de senha usando PBKDF2
*/
export async function hashPassword(password: string): Promise<string> {
const encoder = new TextEncoder();
const data = encoder.encode(password);
// Gerar salt aleatório
const salt = crypto.getRandomValues(new Uint8Array(16));
// Importar a senha como chave
const keyMaterial = await crypto.subtle.importKey(
"raw",
data,
"PBKDF2",
false,
["deriveBits"]
);
// Derivar a chave usando PBKDF2
const derivedBits = await crypto.subtle.deriveBits(
{
name: "PBKDF2",
salt: salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
256
);
// Combinar salt + hash
const hashArray = new Uint8Array(derivedBits);
const combined = new Uint8Array(salt.length + hashArray.length);
combined.set(salt);
combined.set(hashArray, salt.length);
// Converter para base64
return btoa(String.fromCharCode(...combined));
const encoder = new TextEncoder();
const data = encoder.encode(password);
// Gerar salt aleatório
const salt = crypto.getRandomValues(new Uint8Array(16));
// Importar a senha como chave
const keyMaterial = await crypto.subtle.importKey('raw', data, 'PBKDF2', false, ['deriveBits']);
// Derivar a chave usando PBKDF2
const derivedBits = await crypto.subtle.deriveBits(
{
name: 'PBKDF2',
salt: salt,
iterations: 100000,
hash: 'SHA-256'
},
keyMaterial,
256
);
// Combinar salt + hash
const hashArray = new Uint8Array(derivedBits);
const combined = new Uint8Array(salt.length + hashArray.length);
combined.set(salt);
combined.set(hashArray, salt.length);
// Converter para base64
return btoa(String.fromCharCode(...combined));
}
/**
* Verifica se uma senha corresponde ao hash
*/
export async function verifyPassword(
password: string,
hash: string
): Promise<boolean> {
try {
// Decodificar o hash de base64
const combined = Uint8Array.from(atob(hash), (c) => c.charCodeAt(0));
// Extrair salt e hash
const salt = combined.slice(0, 16);
const storedHash = combined.slice(16);
// Gerar hash da senha fornecida
const encoder = new TextEncoder();
const data = encoder.encode(password);
const keyMaterial = await crypto.subtle.importKey(
"raw",
data,
"PBKDF2",
false,
["deriveBits"]
);
const derivedBits = await crypto.subtle.deriveBits(
{
name: "PBKDF2",
salt: salt,
iterations: 100000,
hash: "SHA-256",
},
keyMaterial,
256
);
const newHash = new Uint8Array(derivedBits);
// Comparar os hashes
if (newHash.length !== storedHash.length) {
return false;
}
for (let i = 0; i < newHash.length; i++) {
if (newHash[i] !== storedHash[i]) {
return false;
}
}
return true;
} catch (error) {
console.error("Erro ao verificar senha:", error);
return false;
}
export async function verifyPassword(password: string, hash: string): Promise<boolean> {
try {
// Decodificar o hash de base64
const combined = Uint8Array.from(atob(hash), (c) => c.charCodeAt(0));
// Extrair salt e hash
const salt = combined.slice(0, 16);
const storedHash = combined.slice(16);
// Gerar hash da senha fornecida
const encoder = new TextEncoder();
const data = encoder.encode(password);
const keyMaterial = await crypto.subtle.importKey('raw', data, 'PBKDF2', false, ['deriveBits']);
const derivedBits = await crypto.subtle.deriveBits(
{
name: 'PBKDF2',
salt: salt,
iterations: 100000,
hash: 'SHA-256'
},
keyMaterial,
256
);
const newHash = new Uint8Array(derivedBits);
// Comparar os hashes
if (newHash.length !== storedHash.length) {
return false;
}
for (let i = 0; i < newHash.length; i++) {
if (newHash[i] !== storedHash[i]) {
return false;
}
}
return true;
} catch (error) {
console.error('Erro ao verificar senha:', error);
return false;
}
}
/**
* Gera um token aleatório seguro
*/
export function generateToken(): string {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return btoa(String.fromCharCode(...array))
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=/g, "");
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return btoa(String.fromCharCode(...array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
/**
* Valida formato de matrícula (apenas números)
*/
export function validarMatricula(matricula: string): boolean {
return /^\d+$/.test(matricula) && matricula.length >= 3;
return /^\d+$/.test(matricula) && matricula.length >= 3;
}
/**
* Valida formato de senha (alfanuméricos e símbolos)
*/
export function validarSenha(senha: string): boolean {
// Mínimo 8 caracteres, pelo menos uma letra, um número e um símbolo
const regex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/;
return regex.test(senha);
// Mínimo 8 caracteres, pelo menos uma letra, um número e um símbolo
const regex = /^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$/;
return regex.test(senha);
}
/**
@@ -139,97 +124,93 @@ export function validarSenha(senha: string): boolean {
// Chave de criptografia derivada (em produção, deve vir de variável de ambiente)
// Para desenvolvimento, usando uma chave fixa. Em produção, deve ser configurada via env var.
const getEncryptionKey = async (): Promise<CryptoKey> => {
// Chave base - em produção, isso deve vir de process.env.ENCRYPTION_KEY
// Por enquanto, usando uma chave derivada de um valor fixo
const keyMaterial = new TextEncoder().encode("SGSE-EMAIL-ENCRYPTION-KEY-2024");
// Deriva uma chave de 256 bits usando PBKDF2
const key = await crypto.subtle.importKey(
"raw",
keyMaterial,
{ name: "PBKDF2" },
false,
["deriveBits", "deriveKey"]
);
// Chave base - em produção, isso deve vir de process.env.ENCRYPTION_KEY
// Por enquanto, usando uma chave derivada de um valor fixo
const keyMaterial = new TextEncoder().encode('SGSE-EMAIL-ENCRYPTION-KEY-2024');
return await crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: new TextEncoder().encode("SGSE-SALT"),
iterations: 100000,
hash: "SHA-256",
},
key,
{ name: "AES-GCM", length: 256 },
false,
["encrypt", "decrypt"]
);
// Deriva uma chave de 256 bits usando PBKDF2
const key = await crypto.subtle.importKey('raw', keyMaterial, { name: 'PBKDF2' }, false, [
'deriveBits',
'deriveKey'
]);
return await crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: new TextEncoder().encode('SGSE-SALT'),
iterations: 100000,
hash: 'SHA-256'
},
key,
{ name: 'AES-GCM', length: 256 },
false,
['encrypt', 'decrypt']
);
};
/**
* Criptografa uma senha SMTP usando AES-GCM
*/
export async function encryptSMTPPassword(password: string): Promise<string> {
try {
const key = await getEncryptionKey();
const encoder = new TextEncoder();
const data = encoder.encode(password);
try {
const key = await getEncryptionKey();
const encoder = new TextEncoder();
const data = encoder.encode(password);
// Gerar IV (Initialization Vector) aleatório
const iv = crypto.getRandomValues(new Uint8Array(12));
// Gerar IV (Initialization Vector) aleatório
const iv = crypto.getRandomValues(new Uint8Array(12));
// Criptografar
const encrypted = await crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv,
},
key,
data
);
// Criptografar
const encrypted = await crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: iv
},
key,
data
);
// Combinar IV + dados criptografados e converter para base64
const combined = new Uint8Array(iv.length + encrypted.byteLength);
combined.set(iv);
combined.set(new Uint8Array(encrypted), iv.length);
// Combinar IV + dados criptografados e converter para base64
const combined = new Uint8Array(iv.length + encrypted.byteLength);
combined.set(iv);
combined.set(new Uint8Array(encrypted), iv.length);
return btoa(String.fromCharCode(...combined));
} catch (error) {
console.error("Erro ao criptografar senha SMTP:", error);
throw new Error("Falha ao criptografar senha SMTP");
}
return btoa(String.fromCharCode(...combined));
} catch (error) {
console.error('Erro ao criptografar senha SMTP:', error);
throw new Error('Falha ao criptografar senha SMTP');
}
}
/**
* Descriptografa uma senha SMTP usando AES-GCM
*/
export async function decryptSMTPPassword(encryptedPassword: string): Promise<string> {
try {
const key = await getEncryptionKey();
// Decodificar base64
const combined = Uint8Array.from(atob(encryptedPassword), (c) => c.charCodeAt(0));
try {
const key = await getEncryptionKey();
// Extrair IV e dados criptografados
const iv = combined.slice(0, 12);
const encrypted = combined.slice(12);
// Decodificar base64
const combined = Uint8Array.from(atob(encryptedPassword), (c) => c.charCodeAt(0));
// Descriptografar
const decrypted = await crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv,
},
key,
encrypted
);
// Extrair IV e dados criptografados
const iv = combined.slice(0, 12);
const encrypted = combined.slice(12);
// Converter para string
const decoder = new TextDecoder();
return decoder.decode(decrypted);
} catch (error) {
console.error("Erro ao descriptografar senha SMTP:", error);
throw new Error("Falha ao descriptografar senha SMTP");
}
// 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) {
console.error('Erro ao descriptografar senha SMTP:', error);
throw new Error('Falha ao descriptografar senha SMTP');
}
}