Merge branch 'IDTEAM-1.26.0' into 'main'
[ProtonMail-WebClient.git] / packages / pass / lib / monitor / monitor.utils.ts
blob086f4c7ffad76e334191850f3d964cd0d01c2de3
1 import type { FetchedBreaches } from '@proton/components';
2 import { isBreached, isMonitored } from '@proton/pass/lib/items/item.predicates';
3 import type {
4     Breach,
5     BreachAddressGetResponse,
6     BreachCustomEmailGetResponse,
7     BreachDomainPeekResponse,
8     ItemRevision,
9     UniqueItem,
10 } from '@proton/pass/types';
11 import { deobfuscate } from '@proton/pass/utils/obfuscate/xor';
13 import type { AddressBreachDTO, MonitorAddress, MonitorDomain } from './types';
14 import { AddressType, BreachFlag } from './types';
16 export const getDuplicatePasswords = (logins: ItemRevision<'login'>[]): UniqueItem[][] => {
17     const duplicatesMap = new Map<string, UniqueItem[]>();
18     const seenMap = new Map<string, UniqueItem>();
20     logins.forEach(({ data, itemId, shareId }) => {
21         if (!data.content.password.v) return;
23         const password = deobfuscate(data.content.password);
24         const seen = seenMap.get(password);
25         let duplicates = duplicatesMap.get(password);
27         if (!seen && !duplicates) return seenMap.set(password, { itemId, shareId });
29         if (seen) {
30             duplicates = duplicates ?? [];
31             duplicates.push(seen);
32             duplicatesMap.set(password, duplicates);
33             seenMap.delete(password);
34         }
36         duplicates?.push({ itemId, shareId });
37     });
39     return Array.from(duplicatesMap.values());
42 export const getAddressId = (address: AddressBreachDTO): string => {
43     switch (address.type) {
44         case AddressType.CUSTOM:
45         case AddressType.PROTON:
46             return address.addressId;
47         case AddressType.ALIAS:
48             return `${address.shareId}:${address.itemId}`;
49     }
52 export const isBreachedMonitored = ({ Flags }: BreachCustomEmailGetResponse | BreachAddressGetResponse): boolean =>
53     (Flags & BreachFlag.MonitorDisabled) !== BreachFlag.MonitorDisabled;
55 export const intoCustomMonitorAddress = (breach: BreachCustomEmailGetResponse): MonitorAddress<AddressType.CUSTOM> => ({
56     addressId: breach.CustomEmailID,
57     breachCount: breach.BreachCounter,
58     breached: breach.BreachCounter > 0,
59     email: breach.Email,
60     monitored: isBreachedMonitored(breach),
61     type: AddressType.CUSTOM,
62     verified: breach.Verified,
63     suggestion: false,
64 });
66 export const intoProtonMonitorAddress = (breach: BreachAddressGetResponse): MonitorAddress<AddressType.PROTON> => ({
67     addressId: breach.AddressID,
68     breachCount: breach.BreachCounter,
69     breached: breach.BreachCounter > 0,
70     breachedAt: breach.LastBreachTime,
71     email: breach.Email,
72     monitored: isBreachedMonitored(breach),
73     type: AddressType.PROTON,
74 });
76 export const intoAliasMonitorAddress = (item: ItemRevision<'alias'>): MonitorAddress<AddressType.ALIAS> => ({
77     itemId: item.itemId,
78     shareId: item.shareId,
79     breached: isBreached(item),
80     email: item.aliasEmail!,
81     monitored: isMonitored(item),
82     type: AddressType.ALIAS,
83 });
85 export const intoMonitorDomain = ({ Domain, BreachTime }: BreachDomainPeekResponse): MonitorDomain => ({
86     domain: Domain,
87     breachedAt: BreachTime,
88 });
90 export const intoFetchedBreach = (breach: Breach): FetchedBreaches => ({
91     id: breach.ID,
92     name: breach.Name,
93     email: breach.Email,
94     severity: breach.Severity,
95     createdAt: breach.CreatedAt,
96     publishedAt: breach.PublishedAt,
97     size: breach.Size ?? 0,
98     passwordLastChars: breach.PasswordLastChars ?? null,
99     exposedData: breach.ExposedData.map((data) => ({ code: data.Code, name: data.Name, values: data.Values ?? [] })),
100     actions: breach.Actions.map((action) => ({
101         code: action.Code,
102         name: action.Name,
103         desc: action.Desc,
104         urls: action.Urls,
105     })),
106     source: {
107         isAggregated: breach.Source.IsAggregated,
108         domain: breach.Source.Domain ?? null,
109         category: null,
110         country: null,
111     },
112     resolvedState: breach.ResolvedState,