Merge branch 'docs-header-fix' into 'main'
[ProtonMail-WebClient.git] / packages / shared / test / api / getPublicKeysEmailHelper.spec.js
blobe97fc8bb2d2dbb46cb4eafd145fa073fbad407fb
1 import getPublicKeysEmailHelper from '../../lib/api/helpers/getPublicKeysEmailHelper';
2 import { KEY_FLAG, RECIPIENT_TYPES } from '../../lib/constants';
3 import { KeyTransparencyActivation } from '../../lib/interfaces';
5 const getApiError = ({ message, response = { headers: { get: () => '' } }, data, status }) => {
6     const error = new Error(message);
7     error.status = status;
8     error.data = data;
9     error.response = response;
10     return error;
13 const getMockedApi = (mockApiResponse, isError) => {
14     const response = isError ? Promise.reject(mockApiResponse) : Promise.resolve(mockApiResponse);
15     return jasmine.createSpy('api').and.returnValue(response);
18 // `internalKeysOnly` is not being tested atm as it only affects the API returned data
19 describe('getPublicKeysEmailHelper', () => {
20     const ktActivation = KeyTransparencyActivation.DISABLED;
21     const testKeyA = `-----BEGIN PGP PUBLIC KEY BLOCK-----
22 Comment: email is aaa@test.com
24 xjMEZVeZjRYJKwYBBAHaRw8BAQdA39O4dS41Fqwvj0Xo/xWioK5Q7BudKJ/H
25 tna/S6Rl9KvNDjxhYWFAdGVzdC5jb20+wokEEBYKADsFgmVXmY0DCwkHCZCg
26 Jdhc+VtnygMVCAoCFgACGQECmwMCHgEWIQQgf6DlToGVRDJ8fuKgJdhc+Vtn
27 ygAAj2wA/3Zj6NrRdnUWMt5bqSOr49i9nJCplDlEDsUo15eWssQbAPwJ4toM
28 1eTmSXuHPe0qmV4bH+rmz2R1CojffAlBgHrhDs44BGVXmY0SCisGAQQBl1UB
29 BQEBB0CccwR7RDG2BrJUlko0XWcWz9r8tbKSZN/beWKBl2ORfgMBCAfCeAQY
30 FgoAKgWCZVeZjQmQoCXYXPlbZ8oCmwwWIQQgf6DlToGVRDJ8fuKgJdhc+Vtn
31 ygAAQu4A/isbPn6kW7t8Kz/JhcNbXYNLxzwUz2WYgU+b8IZA6iT2AQDN5Z6V
32 o641lFnk8Bo1GSevHgItogC7uU90n6i/fCrQBg==
33 -----END PGP PUBLIC KEY BLOCK-----`;
34     const testKeyB = `-----BEGIN PGP PUBLIC KEY BLOCK-----
35 Comment: email is bbb@test.com
37 xjMEZVeZkRYJKwYBBAHaRw8BAQdA1dHIjjOu9APYbRpYCdbDOB7aw0CPYOkd
38 qR7yuhSpqL3NDjxiYmJAdGVzdC5jb20+wokEEBYKADsFgmVXmZEDCwkHCZBG
39 XNa/N9gwHgMVCAoCFgACGQECmwMCHgEWIQS0U9zqvzhJRPKLh4VGXNa/N9gw
40 HgAAgv0A/AzlMq39rVpNTjNbrvIlh95wRflNTw86oadFtpocuWSWAQCZB1a3
41 BaOXeVZoHte7e7k7rTaAzZ8e0haSJPpy4qWpA844BGVXmZESCisGAQQBl1UB
42 BQEBB0CKHsFTozeEl7L0l9ueitptl9Bf2Tk/Q2yAZUgXVFbXHAMBCAfCeAQY
43 FgoAKgWCZVeZkQmQRlzWvzfYMB4CmwwWIQS0U9zqvzhJRPKLh4VGXNa/N9gw
44 HgAA4F0BAP3QbD5trB7BemDyRIET8pvs0J/s1ruMWV8/SC4u50nbAP9AIRON
45 vqg5tCgoAiPlCv5xna6ypuLS4rnVUVdNbYVRAA==
46 -----END PGP PUBLIC KEY BLOCK-----`;
47     describe('mail encryption use case', () => {
48         it('internal recipient with mail-capable address keys', async () => {
49             // test with a mix of mail-capable and non-capable keys, even though it's unclear if this scenario can ever happen.
50             const mockApiResponse = {
51                 Address: {
52                     Keys: [
53                         {
54                             PublicKey: testKeyA,
55                             Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
56                         },
57                         {
58                             PublicKey: testKeyB,
59                             Flags:
60                                 KEY_FLAG.FLAG_NOT_OBSOLETE |
61                                 KEY_FLAG.FLAG_NOT_COMPROMISED |
62                                 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
63                         },
64                     ],
65                 },
66                 ProtonMX: false,
67             };
68             const api = getMockedApi(mockApiResponse);
69             const result = await getPublicKeysEmailHelper({ api, ktActivation, email: 'internal@proton.me' });
70             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_INTERNAL);
71             expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
72             expect(result.publicKeys).toHaveSize(1);
73             expect(result.publicKeys[0].publicKey.getUserIDs()[0]).toMatch(/aaa@test.com/);
74         });
76         it('internal recipient with no mail-capable address keys', async () => {
77             const mockApiResponse = {
78                 Address: {
79                     Keys: [
80                         {
81                             PublicKey: testKeyA,
82                             Flags:
83                                 KEY_FLAG.FLAG_NOT_OBSOLETE |
84                                 KEY_FLAG.FLAG_NOT_COMPROMISED |
85                                 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
86                         },
87                     ],
88                 },
89                 ProtonMX: true,
90             };
91             const api = getMockedApi(mockApiResponse);
92             const result = await getPublicKeysEmailHelper({ api, ktActivation, email: 'internal@proton.me' });
93             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_EXTERNAL);
94             expect(result.isInternalWithDisabledE2EEForMail).toBe(true);
95             expect(result.publicKeys).toHaveSize(0);
96         });
98         it('external account with internal address keys and wkd keys', async () => {
99             const mockApiResponse = {
100                 Address: {
101                     Keys: [
102                         {
103                             PublicKey: testKeyA,
104                             Flags:
105                                 KEY_FLAG.FLAG_NOT_OBSOLETE |
106                                 KEY_FLAG.FLAG_NOT_COMPROMISED |
107                                 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
108                         },
109                     ],
110                 },
111                 Unverified: {
112                     Keys: [
113                         {
114                             PublicKey: testKeyB,
115                             Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
116                         },
117                     ],
118                 },
119                 ProtonMX: false,
120             };
121             const api = getMockedApi(mockApiResponse);
122             const result = await getPublicKeysEmailHelper({ api, ktActivation, email: 'external@example.com' });
123             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_EXTERNAL);
124             expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
125             expect(result.publicKeys).toHaveSize(1);
126             expect(result.publicKeys[0].publicKey.getUserIDs()[0]).toMatch(/bbb@test.com/);
127         });
129         it('external recipient with wkd keys', async () => {
130             const mockApiResponse = {
131                 Address: {
132                     Keys: [],
133                 },
134                 Unverified: {
135                     Keys: [
136                         {
137                             PublicKey: testKeyB,
138                             Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
139                         },
140                     ],
141                 },
142                 ProtonMX: false,
143             };
144             const api = getMockedApi(mockApiResponse);
145             const result = await getPublicKeysEmailHelper({ api, ktActivation, email: 'external@example.com' });
146             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_EXTERNAL);
147             expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
148             expect(result.publicKeys).toHaveSize(1);
149         });
150     });
152     describe('includeInternalKeysWithE2EEDisabledForMail', () => {
153         it('internal recipient with mail-capable address keys', async () => {
154             const mockApiResponse = {
155                 Address: {
156                     Keys: [
157                         {
158                             PublicKey: testKeyA,
159                             Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
160                         },
161                     ],
162                 },
163                 ProtonMX: true,
164             };
165             const api = getMockedApi(mockApiResponse);
166             const result = await getPublicKeysEmailHelper({
167                 api,
168                 ktActivation,
169                 email: 'internal@proton.me',
170                 includeInternalKeysWithE2EEDisabledForMail: true,
171             });
172             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_INTERNAL);
173             expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
174             expect(result.publicKeys).toHaveSize(1);
175         });
177         it('internal recipient with mail-capable address keys and bad MX settings', async () => {
178             // test with a mix of mail-capable and non-capable keys, even though it's unclear if this scenario can ever happen.
179             const mockApiResponse = {
180                 Address: {
181                     Keys: [
182                         {
183                             PublicKey: testKeyA,
184                             Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
185                         },
186                         {
187                             PublicKey: testKeyB,
188                             Flags:
189                                 KEY_FLAG.FLAG_NOT_OBSOLETE |
190                                 KEY_FLAG.FLAG_NOT_COMPROMISED |
191                                 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
192                         },
193                     ],
194                 },
195                 ProtonMX: false,
196             };
197             const api = getMockedApi(mockApiResponse);
198             const result = await getPublicKeysEmailHelper({
199                 api,
200                 ktActivation,
201                 email: 'internal@proton.me',
202                 includeInternalKeysWithE2EEDisabledForMail: true,
203             });
204             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_INTERNAL);
205             expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
206             expect(result.publicKeys).toHaveSize(2);
207         });
209         it('internal recipient with no mail-capable address keys', async () => {
210             const mockApiResponse = {
211                 Address: {
212                     Keys: [
213                         {
214                             PublicKey: testKeyA,
215                             Flags:
216                                 KEY_FLAG.FLAG_NOT_OBSOLETE |
217                                 KEY_FLAG.FLAG_NOT_COMPROMISED |
218                                 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
219                         },
220                     ],
221                 },
222                 ProtonMX: true,
223             };
224             const api = getMockedApi(mockApiResponse);
225             const result = await getPublicKeysEmailHelper({
226                 api,
227                 ktActivation,
228                 email: 'internal@proton.me',
229                 includeInternalKeysWithE2EEDisabledForMail: true,
230             });
231             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_INTERNAL);
232             expect(result.isInternalWithDisabledE2EEForMail).toBe(true);
233             expect(result.publicKeys).toHaveSize(1);
234         });
236         it('external account with internal address keys and wkd keys', async () => {
237             const mockApiResponse = {
238                 Address: {
239                     Keys: [
240                         {
241                             PublicKey: testKeyA,
242                             Flags:
243                                 KEY_FLAG.FLAG_NOT_OBSOLETE |
244                                 KEY_FLAG.FLAG_NOT_COMPROMISED |
245                                 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
246                         },
247                     ],
248                 },
249                 Unverified: {
250                     Keys: [
251                         {
252                             PublicKey: testKeyB,
253                             Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
254                         },
255                     ],
256                 },
257                 ProtonMX: false,
258             };
259             const api = getMockedApi(mockApiResponse);
260             const result = await getPublicKeysEmailHelper({
261                 api,
262                 ktActivation,
263                 email: 'external@example.com',
264                 includeInternalKeysWithE2EEDisabledForMail: true,
265             });
266             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_EXTERNAL);
267             expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
268             // the internal address keys is always ignored for external accounts
269             expect(result.publicKeys).toHaveSize(1);
270             expect(result.publicKeys[0].publicKey.getUserIDs()[0]).toMatch(/bbb@test.com/);
271         });
273         it('external address with wkd keys - internalKeysOnly', async () => {
274             // this simulates the error that the API currently gives, to ensure we handle it properly
275             const mockApiResponse = getApiError({
276                 status: 422,
277                 data: {
278                     Code: 33103,
279                     Error: 'This address does not exist. Please try again',
280                     Details: {
281                         Address: 'external@example.com',
282                     },
283                 },
284             });
285             const api = getMockedApi(mockApiResponse, true);
286             const result = await getPublicKeysEmailHelper({
287                 api,
288                 ktActivation,
289                 email: 'external@example.com',
290                 internalKeysOnly: true,
291             });
292             expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_EXTERNAL);
293             expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
294             expect(result.publicKeys).toHaveSize(0);
295         });
296     });