mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 07:43:35 +00:00
* Rename service-factory folder * Move cryptographic service factories * Move crypto models * Move crypto services * Move domain base class * Platform code owners * Move desktop log services * Move log files * Establish component library ownership * Move background listeners * Move background background * Move localization to Platform * Move browser alarms to Platform * Move browser state to Platform * Move CLI state to Platform * Move Desktop native concerns to Platform * Move flag and misc to Platform * Lint fixes * Move electron state to platform * Move web state to Platform * Move lib state to Platform * Fix broken tests * Rename interface to idiomatic TS * `npm run prettier` 🤖 * Resolve review feedback * Set platform as owners of web core and shared * Expand moved services * Fix test types --------- Co-authored-by: Hinton <hinton@users.noreply.github.com>
87 lines
2.5 KiB
TypeScript
87 lines
2.5 KiB
TypeScript
import { defaultIfEmpty, filter, firstValueFrom, fromEvent, map, Subject, takeUntil } from "rxjs";
|
|
import { Jsonify } from "type-fest";
|
|
|
|
import { Utils } from "../../../platform/misc/utils";
|
|
import { Decryptable } from "../../interfaces/decryptable.interface";
|
|
import { InitializerMetadata } from "../../interfaces/initializer-metadata.interface";
|
|
import { SymmetricCryptoKey } from "../../models/domain/symmetric-crypto-key";
|
|
|
|
import { EncryptServiceImplementation } from "./encrypt.service.implementation";
|
|
import { getClassInitializer } from "./get-class-initializer";
|
|
|
|
// TTL (time to live) is not strictly required but avoids tying up memory resources if inactive
|
|
const workerTTL = 3 * 60000; // 3 minutes
|
|
|
|
export class MultithreadEncryptServiceImplementation extends EncryptServiceImplementation {
|
|
private worker: Worker;
|
|
private timeout: any;
|
|
|
|
private clear$ = new Subject<void>();
|
|
|
|
/**
|
|
* Sends items to a web worker to decrypt them.
|
|
* This utilises multithreading to decrypt items faster without interrupting other operations (e.g. updating UI).
|
|
*/
|
|
async decryptItems<T extends InitializerMetadata>(
|
|
items: Decryptable<T>[],
|
|
key: SymmetricCryptoKey
|
|
): Promise<T[]> {
|
|
if (items == null || items.length < 1) {
|
|
return [];
|
|
}
|
|
|
|
this.logService.info("Starting decryption using multithreading");
|
|
|
|
this.worker ??= new Worker(
|
|
new URL(
|
|
/* webpackChunkName: 'encrypt-worker' */
|
|
"@bitwarden/common/platform/services/cryptography/encrypt.worker.ts",
|
|
import.meta.url
|
|
)
|
|
);
|
|
|
|
this.restartTimeout();
|
|
|
|
const request = {
|
|
id: Utils.newGuid(),
|
|
items: items,
|
|
key: key,
|
|
};
|
|
|
|
this.worker.postMessage(JSON.stringify(request));
|
|
|
|
return await firstValueFrom(
|
|
fromEvent(this.worker, "message").pipe(
|
|
filter((response: MessageEvent) => response.data?.id === request.id),
|
|
map((response) => JSON.parse(response.data.items)),
|
|
map((items) =>
|
|
items.map((jsonItem: Jsonify<T>) => {
|
|
const initializer = getClassInitializer<T>(jsonItem.initializerKey);
|
|
return initializer(jsonItem);
|
|
})
|
|
),
|
|
takeUntil(this.clear$),
|
|
defaultIfEmpty([])
|
|
)
|
|
);
|
|
}
|
|
|
|
private clear() {
|
|
this.clear$.next();
|
|
this.worker?.terminate();
|
|
this.worker = null;
|
|
this.clearTimeout();
|
|
}
|
|
|
|
private restartTimeout() {
|
|
this.clearTimeout();
|
|
this.timeout = setTimeout(() => this.clear(), workerTTL);
|
|
}
|
|
|
|
private clearTimeout() {
|
|
if (this.timeout != null) {
|
|
clearTimeout(this.timeout);
|
|
}
|
|
}
|
|
}
|