129 lines
3.2 KiB
TypeScript
129 lines
3.2 KiB
TypeScript
import CryptoWorkerMethods from './crypto_methods';
|
|
|
|
type Task = {
|
|
taskID: number,
|
|
task: string,
|
|
args: any[]
|
|
};
|
|
|
|
class CryptoWorker extends CryptoWorkerMethods {
|
|
private webWorker: Worker | boolean = false;
|
|
private taskID = 0;
|
|
private awaiting: {
|
|
[id: number]: {
|
|
resolve: any,
|
|
reject: any,
|
|
taskName: string
|
|
}
|
|
} = {} as any;
|
|
private pending: Array<Task> = [];
|
|
private debug = false;
|
|
|
|
private utils: {[name: string]: (...args: any[]) => any} = {};
|
|
|
|
constructor() {
|
|
super();
|
|
console.log('CW constructor');
|
|
|
|
/// #if MTPROTO_WORKER
|
|
Promise.all([
|
|
import('./crypto_utils').then(utils => {
|
|
Object.assign(this.utils, {
|
|
'sha1-hash': utils.sha1HashSync,
|
|
'sha256-hash': utils.sha256HashSync,
|
|
'pbkdf2': utils.hash_pbkdf2,
|
|
'aes-encrypt': utils.aesEncryptSync,
|
|
'aes-decrypt': utils.aesDecryptSync,
|
|
'rsa-encrypt': utils.rsaEncrypt,
|
|
'factorize': utils.pqPrimeFactorization,
|
|
'mod-pow': utils.bytesModPow,
|
|
'gzipUncompress': utils.gzipUncompress,
|
|
});
|
|
}),
|
|
|
|
import('./srp').then(srp => {
|
|
this.utils.computeSRP = srp.computeSRP;
|
|
})/* ,
|
|
|
|
import('../bin_utils').then(utils => {
|
|
this.utils.unzip = utils.gzipUncompress;
|
|
}) */
|
|
]);
|
|
|
|
return;
|
|
/// #else
|
|
if(window.Worker) {
|
|
import('./crypto.worker.js').then((worker: any) => {
|
|
var tmpWorker = new worker.default();
|
|
//var tmpWorker = new Worker();
|
|
tmpWorker.onmessage = (e: any) => {
|
|
if(!this.webWorker) {
|
|
this.webWorker = tmpWorker;
|
|
console.info('CW set webWorker');
|
|
this.releasePending();
|
|
} else {
|
|
this.finalizeTask(e.data.taskID, e.data.result);
|
|
}
|
|
};
|
|
|
|
tmpWorker.onerror = (error: any) => {
|
|
console.error('CW error', error);
|
|
this.webWorker = false;
|
|
};
|
|
});
|
|
}
|
|
/// #endif
|
|
}
|
|
|
|
/// #if !MTPROTO_WORKER
|
|
private finalizeTask(taskID: number, result: any) {
|
|
let deferred = this.awaiting[taskID];
|
|
if(deferred !== undefined) {
|
|
this.debug && console.log('CW done', deferred.taskName, result);
|
|
deferred.resolve(result);
|
|
delete this.awaiting[taskID];
|
|
}
|
|
}
|
|
/// #endif
|
|
|
|
public performTaskWorker<T>(task: string, ...args: any[]) {
|
|
this.debug && console.log('CW start', task, args);
|
|
|
|
/// #if MTPROTO_WORKER
|
|
return Promise.resolve<T>(this.utils[task](...args));
|
|
/// #else
|
|
return new Promise<T>((resolve, reject) => {
|
|
this.awaiting[this.taskID] = {resolve, reject, taskName: task};
|
|
|
|
let params = {
|
|
task,
|
|
taskID: this.taskID,
|
|
args
|
|
};
|
|
|
|
//(this.webWorker as Worker).postMessage(params);
|
|
this.pending.push(params);
|
|
this.releasePending();
|
|
|
|
this.taskID++;
|
|
});
|
|
/// #endif
|
|
}
|
|
|
|
/// #if !MTPROTO_WORKER
|
|
private releasePending() {
|
|
if(this.webWorker) {
|
|
this.pending.forEach(pending => {
|
|
(this.webWorker as Worker).postMessage(pending);
|
|
});
|
|
|
|
this.pending.length = 0;
|
|
}
|
|
}
|
|
/// #endif
|
|
}
|
|
|
|
const cryptoWorker = new CryptoWorker();
|
|
//(window as any).CryptoWorker = cryptoWorker;
|
|
export default cryptoWorker;
|