Update selected item color in Pass menu
[ProtonMail-WebClient.git] / packages / pass / lib / monitor / service.ts
blob8ed5f803f8fae9c461a270bedb725d8e6cb40f4a
1 import type { Store } from 'redux';
3 import { WASM_PROCEDURE_BATCH_SIZE } from '@proton/pass/lib/core/constants';
4 import type { PassCoreProxy } from '@proton/pass/lib/core/types';
5 import { hasDomain, hasOTP } from '@proton/pass/lib/items/item.predicates';
6 import { intoSelectedItem } from '@proton/pass/lib/items/item.utils';
7 import { selectMonitoredLogins } from '@proton/pass/store/selectors';
8 import { type UniqueItem } from '@proton/pass/types';
9 import { and, not } from '@proton/pass/utils/fp/predicates';
10 import { deobfuscate } from '@proton/pass/utils/obfuscate/xor';
11 import chunk from '@proton/utils/chunk';
13 export interface MonitorService {
14     checkMissing2FAs: () => Promise<UniqueItem[]>;
15     checkWeakPasswords: () => Promise<UniqueItem[]>;
18 /** MonitorService provides `PassMonitor` methods that rely
19  * on the `PassRustCore` module */
20 export const createMonitorService = (core: PassCoreProxy, store: Store): MonitorService => {
21     const getLoginItems = () => selectMonitoredLogins(store.getState());
23     const service: MonitorService = {
24         checkMissing2FAs: async () => {
25             const logins = getLoginItems();
26             const candidates = logins.filter(and(hasDomain, not(hasOTP)));
27             const domains = candidates.flatMap((item) => item.data.content.urls);
28             const chunks = chunk(domains, WASM_PROCEDURE_BATCH_SIZE);
30             const results = await Promise.all(chunks.map(core.twofa_domains_eligible));
31             const eligible = new Map(...results.flatMap((dic) => dic.entries()));
32             const eligibleDomain = (url: string) => eligible.get(url) === true;
34             return candidates.filter((item) => item.data.content.urls.some(eligibleDomain)).map(intoSelectedItem);
35         },
37         checkWeakPasswords: async () => {
38             const logins = getLoginItems();
39             const candidates = logins.filter((item) => item.data.content.password.v);
40             const passwords = candidates.map((item) => deobfuscate(item.data.content.password));
41             const chunks = chunk(passwords, WASM_PROCEDURE_BATCH_SIZE);
42             const scores = (await Promise.all(chunks.map(core.check_password_scores))).flat();
44             return candidates.filter((_, idx) => scores[idx] !== 'Strong').map(intoSelectedItem);
45         },
46     };
48     return service;