Исправление утечки памяти, оптимизация кода, лучшая читаемость кода

This commit is contained in:
RoyceDa
2026-02-19 21:53:55 +02:00
parent 95a1f57381
commit 5741097334
2 changed files with 88 additions and 133 deletions

View File

@@ -1,109 +1,82 @@
import { sha256, md5 } from "node-forge"; import { sha256, md5 } from "node-forge";
import { generateRandomKey } from "../../utils/utils";
import * as secp256k1 from '@noble/secp256k1'; import * as secp256k1 from '@noble/secp256k1';
const worker = new Worker(new URL('./crypto.worker.ts', import.meta.url), { type: 'module' }); const worker = new Worker(new URL('./crypto.worker.ts', import.meta.url), { type: 'module' });
export const encodeWithPassword = async (password : string, data : any) : Promise<any> => { type WorkerReq =
let task = generateRandomKey(16); | { id: number; type: 'encodeWithPassword'; payload: { password: string; data: any } }
return new Promise((resolve, _) => { | { id: number; type: 'decodeWithPassword'; payload: { password: string; data: any } }
worker.addEventListener('message', (event: MessageEvent) => { | { id: number; type: 'encrypt'; payload: { publicKey: string; data: string } }
if (event.data.action === 'encodeWithPasswordResult' && event.data.task === task) { | { id: number; type: 'decrypt'; payload: { privateKey: string; data: string } }
resolve(event.data.result); | { id: number; type: 'chacha20Encrypt'; payload: { data: string } }
| { id: number; type: 'chacha20Decrypt'; payload: { ciphertext: string; nonce: string; key: string } };
type WorkerRes =
| { id: number; ok: true; data: any }
| { id: number; ok: false; error: string };
let seq = 0;
const pending = new Map<number, (res: WorkerRes) => void>();
worker.onmessage = (e: MessageEvent<WorkerRes>) => {
const res = e.data;
const cb = pending.get(res.id);
if (cb) {
pending.delete(res.id);
cb(res);
} }
}); };
worker.postMessage({ action: 'encodeWithPassword', data: { password, payload: data, task } });
function callWorker(req: Omit<WorkerReq, 'id'>): Promise<any> {
return new Promise((resolve, reject) => {
const id = ++seq;
pending.set(id, (res) => (res.ok ? resolve(res.data) : reject(res.error)));
worker.postMessage({ ...req, id });
}); });
} }
export const encodeWithPassword = (password: string, data: any): Promise<any> => {
return callWorker({ type: 'encodeWithPassword', payload: { password, data } });
};
export const decodeWithPassword = (password: string, data: any): Promise<any> => { export const decodeWithPassword = (password: string, data: any): Promise<any> => {
let task = generateRandomKey(16); return callWorker({ type: 'decodeWithPassword', payload: { password, data } });
return new Promise((resolve, reject) => { };
worker.addEventListener('message', (event: MessageEvent) => {
if (event.data.action === 'decodeWithPasswordResult' && event.data.task === task) { export const encrypt = (data: string, publicKey: string): Promise<any> => {
if(event.data.result === null){ return callWorker({ type: 'encrypt', payload: { publicKey, data } });
reject("Decryption failed"); };
return;
} export const decrypt = (data: string, privateKey: string): Promise<any> => {
resolve(event.data.result); return callWorker({ type: 'decrypt', payload: { privateKey, data } });
} };
});
worker.postMessage({ action: 'decodeWithPassword', data: { password, payload: data, task } }); export const chacha20Encrypt = (data: string): Promise<any> => {
}); return callWorker({ type: 'chacha20Encrypt', payload: { data } });
} };
export const chacha20Decrypt = (ciphertext: string, nonce: string, key: string): Promise<any> => {
return callWorker({ type: 'chacha20Decrypt', payload: { ciphertext, nonce, key } });
};
export const generateKeyPairFromSeed = async (seed: string) => { export const generateKeyPairFromSeed = async (seed: string) => {
//generate key pair using secp256k1 includes privatekey from seed
const privateKey = sha256.create().update(seed).digest().toHex().toString(); const privateKey = sha256.create().update(seed).digest().toHex().toString();
const publicKey = secp256k1.getPublicKey(Buffer.from(privateKey, "hex"), true); const publicKey = secp256k1.getPublicKey(Buffer.from(privateKey, "hex"), true);
return { return {
privateKey: privateKey, privateKey: privateKey,
publicKey: Buffer.from(publicKey).toString('hex'), publicKey: Buffer.from(publicKey).toString('hex'),
}; };
};
}
export const encrypt = async (data : string, publicKey : string) : Promise<any> => {
let task = generateRandomKey(16);
return new Promise((resolve, _) => {
worker.addEventListener('message', (event: MessageEvent) => {
if (event.data.action === 'encryptResult' && event.data.task === task) {
resolve(event.data.result);
}
});
worker.postMessage({ action: 'encrypt', data: { publicKey, payload: data, task } });
});
}
export const decrypt = async (data : string, privateKey : string) : Promise<any> => {
let task = generateRandomKey(16);
return new Promise((resolve, reject) => {
worker.addEventListener('message', (event: MessageEvent) => {
if (event.data.action === 'decryptResult' && event.data.task === task) {
if(event.data.result === null){
reject("Decryption failed");
return;
}
resolve(event.data.result);
}
});
worker.postMessage({ action: 'decrypt', data: { privateKey, payload: data, task } });
});
}
export const chacha20Encrypt = async (data : string) => {
let task = generateRandomKey(16);
return new Promise((resolve, _) => {
worker.addEventListener('message', (event: MessageEvent) => {
if (event.data.action === 'chacha20EncryptResult' && event.data.task === task) {
resolve(event.data.result);
}
});
worker.postMessage({ action: 'chacha20Encrypt', data: { payload: data, task } });
});
}
export const chacha20Decrypt = async (ciphertext : string, nonce : string, key : string) => {
let task = generateRandomKey(16);
return new Promise((resolve, _) => {
worker.addEventListener('message', (event: MessageEvent) => {
if (event.data.action === 'chacha20DecryptResult' && event.data.task === task) {
resolve(event.data.result);
}
});
worker.postMessage({ action: 'chacha20Decrypt', data: { ciphertext, nonce, key, task } });
});
}
export const generateMd5 = async (data: string) => { export const generateMd5 = async (data: string) => {
const hash = md5.create(); const hash = md5.create();
hash.update(data); hash.update(data);
return hash.digest().toHex(); return hash.digest().toHex();
} };
export const generateHashFromPrivateKey = async (privateKey: string) => { export const generateHashFromPrivateKey = async (privateKey: string) => {
return sha256.create().update(privateKey + "rosetta").digest().toHex().toString(); return sha256.create().update(privateKey + "rosetta").digest().toHex().toString();
} };
export const isEncodedWithPassword = (data: string) => { export const isEncodedWithPassword = (data: string) => {
try { try {
@@ -112,4 +85,4 @@ export const isEncodedWithPassword = (data : string) => {
} catch (e) { } catch (e) {
return false; return false;
} }
} };

View File

@@ -6,53 +6,35 @@ import * as secp256k1 from '@noble/secp256k1';
self.onmessage = async (event: MessageEvent) => { self.onmessage = async (event: MessageEvent) => {
const { action, data } = event.data; const { id, type, payload } = event.data;
switch (action) {
case 'encodeWithPassword': {
const { password, payload, task } = data;
const result = await encodeWithPassword(password, payload);
self.postMessage({ action: 'encodeWithPasswordResult', result, task });
break;
}
case 'chacha20Encrypt': {
const { payload, task } = data;
const result = await chacha20Encrypt(payload);
self.postMessage({ action: 'chacha20EncryptResult', result, task });
break;
}
case 'chacha20Decrypt': {
const { ciphertext, nonce, key, task } = data;
const result = await chacha20Decrypt(ciphertext, nonce, key);
self.postMessage({ action: 'chacha20DecryptResult', result, task });
break;
}
case 'decodeWithPassword': {
const { password, payload, task } = data;
try { try {
const result = await decodeWithPassword(password, payload); let result;
self.postMessage({ action: 'decodeWithPasswordResult', result, task }); switch (type) {
return; case 'encodeWithPassword':
}catch(e){ result = await encodeWithPassword(payload.password, payload.data);
const result = null;
self.postMessage({ action: 'decodeWithPasswordResult', result, task });
}
break; break;
} case 'decodeWithPassword':
case 'decrypt': { result = await decodeWithPassword(payload.password, payload.data);
const { payload: encryptedData, privateKey, task } = data;
const result = await decrypt(encryptedData, privateKey);
self.postMessage({ action: 'decryptResult', result, task });
break; break;
} case 'encrypt':
case 'encrypt': { result = await encrypt(payload.publicKey, payload.data);
const { payload: plainData, publicKey, task } = data; break;
const result = await encrypt(plainData, publicKey); case 'decrypt':
self.postMessage({ action: 'encryptResult', result, task }); result = await decrypt(payload.privateKey, payload.data);
break;
case 'chacha20Encrypt':
result = await chacha20Encrypt(payload.data);
break;
case 'chacha20Decrypt':
result = await chacha20Decrypt(payload.ciphertext, payload.nonce, payload.key);
break; break;
}
default: default:
console.error(`Unknown action: ${action}`); throw new Error(`Unknown action: ${type}`);
}
self.postMessage({ id, ok: true, data: result });
} catch (error) {
self.postMessage({ id, ok: false, error: String(error) });
} }
}; };