Update selected item color in Pass menu
[ProtonMail-WebClient.git] / packages / pass / store / actions / creators / monitor.ts
blob5b6fc110e66d0767ba681911da2d77bcc1d2d750
1 import { c } from 'ttag';
3 import type { FetchedBreaches } from '@proton/components';
4 import { isMonitored } from '@proton/pass/lib/items/item.predicates';
5 import { getAddressId } from '@proton/pass/lib/monitor/monitor.utils';
6 import type {
7     AddressBreachDTO,
8     AddressType,
9     CustomAddressID,
10     MonitorAddress,
11     MonitorToggleDTO,
12     MonitorVerifyDTO,
13     ProtonAddressID,
14 } from '@proton/pass/lib/monitor/types';
15 import { withCache } from '@proton/pass/store/actions/enhancers/cache';
16 import { withNotification } from '@proton/pass/store/actions/enhancers/notification';
17 import {
18     addCustomAddressRequest,
19     aliasBreachRequest,
20     breachesRequest,
21     customBreachRequest,
22     deleteCustomAddressRequest,
23     itemUpdateFlagsRequest,
24     protonBreachRequest,
25     resendCustomAddressCodeRequest,
26     resolveAddressMonitorRequest,
27     sentinelToggleRequest,
28     toggleAddressMonitorRequest,
29     toggleMonitorRequest,
30     verifyCustomAddressRequest,
31 } from '@proton/pass/store/actions/requests';
32 import { requestActionsFactory } from '@proton/pass/store/request/flow';
33 import type { ItemRevision, SelectedItem } from '@proton/pass/types';
34 import type {
35     BreachCustomEmailGetResponse,
36     BreachesGetResponse,
37     UpdateUserMonitorStateRequest,
38 } from '@proton/pass/types/api/pass';
39 import { pipe } from '@proton/pass/utils/fp/pipe';
40 import { UNIX_MINUTE } from '@proton/pass/utils/time/constants';
41 import { getApiError } from '@proton/shared/lib/api/helpers/apiErrorHelper';
42 import { PROTON_SENTINEL_NAME } from '@proton/shared/lib/constants';
43 import type { SETTINGS_PROTON_SENTINEL_STATE } from '@proton/shared/lib/interfaces';
45 export type SentinelState = SETTINGS_PROTON_SENTINEL_STATE;
47 export const sentinelToggle = requestActionsFactory<SentinelState, SentinelState>('monitor::sentinel::toggle')({
48     requestId: sentinelToggleRequest,
49     success: {
50         prepare: (value) =>
51             withNotification({
52                 type: 'info',
53                 text: value
54                     ? c('Info').t`${PROTON_SENTINEL_NAME} successfully enabled`
55                     : c('Info').t`${PROTON_SENTINEL_NAME} successfully disabled`,
56             })({ payload: { value } }),
57     },
58     failure: {
59         prepare: (error) =>
60             withNotification({
61                 type: 'error',
62                 text: c('Error').t`Failed updating ${PROTON_SENTINEL_NAME} setting`,
63                 error,
64             })({ payload: {} }),
65     },
66 });
68 export const monitorToggle = requestActionsFactory<UpdateUserMonitorStateRequest, UpdateUserMonitorStateRequest>(
69     'monitor::all:addresses:toggle'
70 )({
71     requestId: toggleMonitorRequest,
72     success: {
73         prepare: ({ ProtonAddress, Aliases }) =>
74             pipe(
75                 withCache,
76                 withNotification({
77                     type: 'info',
78                     text: c('Info').t`Monitoring settings successfully updated`,
79                 })
80             )({ payload: { ProtonAddress, Aliases } }),
81     },
82     failure: {
83         prepare: (error) =>
84             withNotification({
85                 type: 'error',
86                 text: c('Error').t`Failed to update monitoring settings`,
87                 error,
88             })({ payload: {} }),
89     },
90 });
92 export const getBreaches = requestActionsFactory<void, BreachesGetResponse>('monitor::breaches::get')({
93     requestId: breachesRequest,
94     success: { config: { maxAge: UNIX_MINUTE } },
95 });
97 export const getProtonBreach = requestActionsFactory<ProtonAddressID, FetchedBreaches[]>(
98     'monitor::breaches::proton::get'
99 )({
100     requestId: protonBreachRequest,
101     success: { config: { data: true } },
102     failure: {
103         prepare: (error) =>
104             withNotification({
105                 text: c('Error').t`Failed to load breaches for this address`,
106                 type: 'error',
107                 error,
108             })({ payload: null }),
109     },
112 export const getCustomBreach = requestActionsFactory<CustomAddressID, FetchedBreaches[]>(
113     'monitor::breaches::custom::get'
115     requestId: customBreachRequest,
116     success: { config: { data: true } },
117     failure: {
118         prepare: (error) =>
119             withNotification({
120                 text: c('Error').t`Failed to load breaches for this address`,
121                 type: 'error',
122                 error,
123             })({ payload: null }),
124     },
127 export const getAliasBreach = requestActionsFactory<SelectedItem, FetchedBreaches[]>('monitor::breaches::alias::get')({
128     requestId: ({ shareId, itemId }) => aliasBreachRequest(shareId, itemId),
129     success: { config: { data: true } },
130     failure: {
131         prepare: (error) =>
132             withNotification({
133                 text: c('Error').t`Failed to load breaches for this email alias`,
134                 type: 'error',
135                 error,
136             })({ payload: null }),
137     },
140 export const addCustomAddress = requestActionsFactory<string, BreachCustomEmailGetResponse>(
141     'monitor::breaches::custom::add'
143     requestId: addCustomAddressRequest,
144     success: { config: { data: true } },
145     failure: {
146         prepare: (error) =>
147             withNotification({
148                 text: c('Error').t`Failed to add email address`,
149                 type: 'error',
150                 error,
151             })({ payload: null }),
152     },
155 export const deleteCustomAddress = requestActionsFactory<CustomAddressID, CustomAddressID>(
156     'monitor::breaches::custom::delete'
158     requestId: deleteCustomAddressRequest,
159     success: {
160         prepare: (addressId) =>
161             withNotification({
162                 text: c('Info').t`Email address successfully deleted from monitoring`,
163                 type: 'info',
164             })({ payload: addressId }),
165     },
166     failure: {
167         prepare: (error) =>
168             withNotification({
169                 text: c('Error').t`Failed to delete email address from monitoring`,
170                 type: 'error',
171                 error,
172             })({ payload: null }),
173     },
176 export const verifyCustomAddress = requestActionsFactory<MonitorVerifyDTO, MonitorAddress<AddressType.CUSTOM>>(
177     'monitor::breaches::custom::verify'
179     requestId: ({ addressId }) => verifyCustomAddressRequest(addressId),
180     failure: {
181         config: { data: true },
182         prepare: (error) =>
183             withNotification({
184                 text: c('Error').t`Failed to verify email address`,
185                 type: 'error',
186                 error,
187             })({ payload: getApiError(error) }),
188     },
191 export const toggleAddressMonitor = requestActionsFactory<MonitorToggleDTO, MonitorAddress>(
192     'monitor::breaches::address::toggle'
194     requestId: (dto) => toggleAddressMonitorRequest(getAddressId(dto)),
195     success: {
196         prepare: (payload) =>
197             withNotification({
198                 type: 'info',
199                 text: payload.monitored
200                     ? c('Info').t`Email address successfully included in monitoring`
201                     : c('Info').t`Email address successfully excluded from monitoring`,
202             })({ payload }),
203     },
204     failure: {
205         prepare: (error) =>
206             withNotification({
207                 type: 'error',
208                 text: c('Error').t`Failed updating monitoring status for this email address`,
209                 error,
210             })({ payload: {} }),
211     },
214 export const resolveAddressMonitor = requestActionsFactory<AddressBreachDTO, AddressBreachDTO>(
215     'monitor::breaches::address::resolve'
217     requestId: (dto) => resolveAddressMonitorRequest(getAddressId(dto)),
218     success: {
219         prepare: (payload) =>
220             withNotification({
221                 type: 'info',
222                 text: c('Info').t`All breaches for this address were resolved`,
223             })({ payload }),
224     },
225     failure: {
226         prepare: (error) =>
227             withNotification({
228                 text: c('Error').t`Failed to resolve breaches for this address`,
229                 type: 'error',
230                 error,
231             })({ payload: null }),
232     },
235 export const setItemFlags = requestActionsFactory<
236     SelectedItem & { SkipHealthCheck: boolean },
237     SelectedItem & { item: ItemRevision }
238 >('monitor::toggle::item')({
239     requestId: ({ shareId, itemId }) => itemUpdateFlagsRequest(shareId, itemId),
240     success: {
241         prepare: ({ shareId, itemId, item }) =>
242             withNotification({
243                 type: 'info',
244                 text: isMonitored(item)
245                     ? c('Info').t`Item successfully included in monitoring`
246                     : c('Info').t`Item successfully excluded from monitoring`,
247             })({ payload: { shareId, itemId, item } }),
248     },
249     failure: {
250         prepare: (error) =>
251             withNotification({
252                 type: 'error',
253                 text: c('Error').t`Failed updating monitor flag of the item`,
254                 error,
255             })({ payload: {} }),
256     },
259 export const resendVerificationCode = requestActionsFactory<CustomAddressID, boolean>(
260     'monitor::breaches::custom::resend::verification'
262     requestId: resendCustomAddressCodeRequest,
263     failure: {
264         prepare: (error) =>
265             withNotification({
266                 text: c('Error').t`Failed to resend verification for custom email`,
267                 type: 'error',
268                 error,
269             })({ payload: null }),
270     },