Update selected item color in Pass menu
[ProtonMail-WebClient.git] / packages / pass / store / actions / creators / auth.ts
blobe3af1126494d3b38769e6863759bab852c6fef8f
1 import { createAction } from '@reduxjs/toolkit';
2 import { c } from 'ttag';
4 import { type Lock, type LockCreateDTO, LockMode, type UnlockDTO } from '@proton/pass/lib/auth/lock/types';
5 import type { ExtraPasswordDTO, PasswordConfirmDTO } from '@proton/pass/lib/auth/password';
6 import { withCache } from '@proton/pass/store/actions/enhancers/cache';
7 import { withNotification } from '@proton/pass/store/actions/enhancers/notification';
8 import { withSettings } from '@proton/pass/store/actions/enhancers/settings';
9 import {
10     extraPasswordToggleRequest,
11     lockCreateRequest,
12     passwordConfirmRequest,
13     unlockRequest,
14 } from '@proton/pass/store/actions/requests';
15 import { withRequest, withRequestFailure, withRequestSuccess } from '@proton/pass/store/request/enhancers';
16 import { requestActionsFactory } from '@proton/pass/store/request/flow';
17 import type { ClientEndpoint } from '@proton/pass/types';
18 import { NotificationKey } from '@proton/pass/types/worker/notification';
19 import { getErrorMessage } from '@proton/pass/utils/errors/get-error-message';
20 import { pipe } from '@proton/pass/utils/fp/pipe';
21 import { PASS_APP_NAME } from '@proton/shared/lib/constants';
23 export const signoutIntent = createAction('auth::signout::intent', (payload: { soft: boolean }) => ({ payload }));
24 export const signoutSuccess = createAction('auth::signout::success', (payload: { soft: boolean }) => ({ payload }));
26 export const lock = createAction('auth::lock', () => ({ payload: null }));
27 export const lockSync = createAction('auth::lock::sync', (lock: Lock) => ({ payload: { lock } }));
29 export const lockCreateIntent = createAction('auth::lock::create::intent', (lock: LockCreateDTO) =>
30     pipe(
31         withRequest({ status: 'start', id: lockCreateRequest(), data: true }),
32         withNotification({
33             key: NotificationKey.LOCK,
34             loading: true,
35             text: `${(() => {
36                 switch (lock.mode) {
37                     case LockMode.NONE:
38                         return c('Info').t`Disabling auto-lock`;
39                     case LockMode.SESSION:
40                         return c('Info').t`Enabling PIN auto-lock`;
41                     case LockMode.PASSWORD:
42                         return c('Info').t`Enabling password auto-lock`;
43                     case LockMode.BIOMETRICS:
44                         return c('Info').t`Enabling biometrics auto-lock`;
45                 }
46             })()} (${c('Info').t`Please do not close this window`})`,
47             type: 'info',
48         })
49     )({ payload: { lock } })
52 export const lockCreateFailure = createAction(
53     'auth::lock::create::failure',
54     withRequestFailure((mode: LockMode, error: unknown, endpoint?: ClientEndpoint) =>
55         withNotification({
56             endpoint,
57             error,
58             key: NotificationKey.LOCK,
59             text: (() => {
60                 switch (mode) {
61                     case LockMode.NONE:
62                         return c('Info').t`Disabling auto-lock failed`;
63                     case LockMode.SESSION:
64                         return c('Info').t`Registering PIN lock failed`;
65                     case LockMode.PASSWORD:
66                         return c('Info').t`Enabling password lock failed`;
67                     case LockMode.BIOMETRICS:
68                         return c('Info').t`Enabling biometrics lock failed`;
69                 }
70             })(),
71             type: 'error',
72         })({ payload: {}, error })
73     )
76 export const lockCreateSuccess = createAction(
77     'auth::lock::create::success',
78     withRequestSuccess((lock: Lock, endpoint?: ClientEndpoint) =>
79         pipe(
80             withCache,
81             withSettings,
82             withNotification({
83                 endpoint,
84                 key: NotificationKey.LOCK,
85                 text: (() => {
86                     switch (lock.mode) {
87                         case LockMode.NONE:
88                             return c('Info').t`Auto-lock successfully disabled.`;
89                         case LockMode.SESSION:
90                             return c('Info').t`PIN code successfully registered. Use it to unlock ${PASS_APP_NAME}`;
91                         case LockMode.PASSWORD:
92                             return c('Info')
93                                 .t`Password lock successfully registered. Use it to unlock ${PASS_APP_NAME}`;
94                         case LockMode.BIOMETRICS:
95                             return c('Info')
96                                 .t`Biometrics lock successfully registered. Use it to unlock ${PASS_APP_NAME}`;
97                     }
98                 })(),
99                 type: 'info',
100             })
101         )({ payload: { lock } })
102     )
105 export const unlock = requestActionsFactory<UnlockDTO, LockMode, LockMode>('auth::unlock')({
106     requestId: unlockRequest,
107     failure: {
108         prepare: (error, mode) =>
109             withNotification({
110                 key: NotificationKey.LOCK,
111                 type: 'error',
112                 text: (() => {
113                     switch (mode) {
114                         case LockMode.SESSION:
115                             if (error instanceof Error) {
116                                 if (error.name === 'LockedSession') return c('Error').t`Wrong PIN code. Try again.`;
117                                 if (error.name === 'InactiveSession') {
118                                     return c('Error').t`Too many failed attempts. Please sign in again.`;
119                                 }
120                             }
121                         default:
122                             return c('Error').t`Unlock failure`;
123                     }
124                 })(),
125                 error,
126             })({ payload: null, error }),
127     },
130 export const passwordConfirm = requestActionsFactory<PasswordConfirmDTO, boolean>('auth::password::confirm')({
131     requestId: passwordConfirmRequest,
132     failure: {
133         prepare: (error, payload) =>
134             withNotification({
135                 type: 'error',
136                 text: getErrorMessage(error),
137                 error: null,
138             })({ payload }),
139     },
142 export const extraPasswordToggle = requestActionsFactory<ExtraPasswordDTO, boolean>('auth::extra-password::toggle')({
143     requestId: extraPasswordToggleRequest,
144     intent: {
145         prepare: (payload) =>
146             withNotification({
147                 type: 'info',
148                 loading: true,
149                 text: payload.enabled
150                     ? c('Info').t`Registering extra password...`
151                     : c('Info').t`Removing extra password...`,
152             })({ payload }),
153     },
154     success: {
155         prepare: (enabled) =>
156             pipe(
157                 withCache,
158                 withSettings,
159                 withNotification({
160                     type: 'success',
161                     text: enabled
162                         ? c('Info').t`Extra password successfully created`
163                         : c('Info').t`Extra password successfully removed`,
164                 })
165             )({ payload: enabled }),
166     },
167     failure: {
168         prepare: (error, payload) =>
169             withNotification({
170                 type: 'error',
171                 text: getErrorMessage(error),
172                 error: null,
173             })({ payload }),
174     },