Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / shared / lib / keys / setupKeys.ts
blob5494608232db5d3cc0cbbef0e9ff77f38481994f
1 import type { ProductParam } from '@proton/shared/lib/apps/product';
3 import { setupKeys } from '../api/keys';
4 import { getUser } from '../api/user';
5 import type { Address, Api, PreAuthKTVerify, User } from '../interfaces';
6 import { srpVerify } from '../srp';
7 import { getDecryptedUserKeysHelper } from './getDecryptedUserKeys';
8 import { generateKeySaltAndPassphrase } from './keys';
9 import { getResetAddressesKeysV2 } from './resetKeys';
11 interface Args {
12     api: Api;
13     addresses: Address[];
14     password: string;
15     preAuthKTVerify: PreAuthKTVerify;
16     product: ProductParam;
19 export const handleSetupKeys = async ({ api, addresses, password, preAuthKTVerify, product }: Args) => {
20     if (!addresses.length) {
21         throw new Error('An address is required to setup keys');
22     }
23     const { passphrase, salt } = await generateKeySaltAndPassphrase(password);
25     const { userKeyPayload, addressKeysPayload, onSKLPublishSuccess } = await getResetAddressesKeysV2({
26         addresses,
27         passphrase,
28         preAuthKTVerify,
29     });
31     if (!userKeyPayload || !addressKeysPayload) {
32         throw new Error('Invalid setup');
33     }
35     const verifySuccess = async () => {
36         const user = await api<{ User: User }>(getUser()).then(({ User }) => User);
37         const decryptedKeys = await getDecryptedUserKeysHelper(user, passphrase);
38         if (!decryptedKeys.length) {
39             throw new Error('Failed to setup keys');
40         }
41     };
43     try {
44         await srpVerify({
45             api,
46             credentials: { password },
47             config: setupKeys(
48                 {
49                     KeySalt: salt,
50                     PrimaryKey: userKeyPayload,
51                     AddressKeys: addressKeysPayload,
52                 },
53                 product
54             ),
55         });
56     } catch (setupError) {
57         // We are observing some strange behavior where the setup call seems to be retried even though it has succeeded.
58         // One theory might be that the request is retried natively by the browser (even POST requests) according to
59         // "Client Behavior if Server Prematurely Closes Connection is to retry the request". This is attempting to fix that.
60         // We don't care about the status code because it could be valid for requests that time out or offline as well.
61         try {
62             await verifySuccess();
63             // It succeeded setting up the keys with this passphrase
64         } catch (newError) {
65             throw setupError;
66         }
67     }
69     if (onSKLPublishSuccess) {
70         await onSKLPublishSuccess();
71     }
73     return passphrase;