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);
9 error.response = response;
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 = {
55 Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
60 KEY_FLAG.FLAG_NOT_OBSOLETE |
61 KEY_FLAG.FLAG_NOT_COMPROMISED |
62 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
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/);
76 it('internal recipient with no mail-capable address keys', async () => {
77 const mockApiResponse = {
83 KEY_FLAG.FLAG_NOT_OBSOLETE |
84 KEY_FLAG.FLAG_NOT_COMPROMISED |
85 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
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);
98 it('external account with internal address keys and wkd keys', async () => {
99 const mockApiResponse = {
105 KEY_FLAG.FLAG_NOT_OBSOLETE |
106 KEY_FLAG.FLAG_NOT_COMPROMISED |
107 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
115 Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
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/);
129 it('external recipient with wkd keys', async () => {
130 const mockApiResponse = {
138 Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
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);
152 describe('includeInternalKeysWithE2EEDisabledForMail', () => {
153 it('internal recipient with mail-capable address keys', async () => {
154 const mockApiResponse = {
159 Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
165 const api = getMockedApi(mockApiResponse);
166 const result = await getPublicKeysEmailHelper({
169 email: 'internal@proton.me',
170 includeInternalKeysWithE2EEDisabledForMail: true,
172 expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_INTERNAL);
173 expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
174 expect(result.publicKeys).toHaveSize(1);
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 = {
184 Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
189 KEY_FLAG.FLAG_NOT_OBSOLETE |
190 KEY_FLAG.FLAG_NOT_COMPROMISED |
191 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
197 const api = getMockedApi(mockApiResponse);
198 const result = await getPublicKeysEmailHelper({
201 email: 'internal@proton.me',
202 includeInternalKeysWithE2EEDisabledForMail: true,
204 expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_INTERNAL);
205 expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
206 expect(result.publicKeys).toHaveSize(2);
209 it('internal recipient with no mail-capable address keys', async () => {
210 const mockApiResponse = {
216 KEY_FLAG.FLAG_NOT_OBSOLETE |
217 KEY_FLAG.FLAG_NOT_COMPROMISED |
218 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
224 const api = getMockedApi(mockApiResponse);
225 const result = await getPublicKeysEmailHelper({
228 email: 'internal@proton.me',
229 includeInternalKeysWithE2EEDisabledForMail: true,
231 expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_INTERNAL);
232 expect(result.isInternalWithDisabledE2EEForMail).toBe(true);
233 expect(result.publicKeys).toHaveSize(1);
236 it('external account with internal address keys and wkd keys', async () => {
237 const mockApiResponse = {
243 KEY_FLAG.FLAG_NOT_OBSOLETE |
244 KEY_FLAG.FLAG_NOT_COMPROMISED |
245 KEY_FLAG.FLAG_EMAIL_NO_ENCRYPT,
253 Flags: KEY_FLAG.FLAG_NOT_OBSOLETE | KEY_FLAG.FLAG_NOT_COMPROMISED,
259 const api = getMockedApi(mockApiResponse);
260 const result = await getPublicKeysEmailHelper({
263 email: 'external@example.com',
264 includeInternalKeysWithE2EEDisabledForMail: true,
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/);
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({
279 Error: 'This address does not exist. Please try again',
281 Address: 'external@example.com',
285 const api = getMockedApi(mockApiResponse, true);
286 const result = await getPublicKeysEmailHelper({
289 email: 'external@example.com',
290 internalKeysOnly: true,
292 expect(result.RecipientType).toBe(RECIPIENT_TYPES.TYPE_EXTERNAL);
293 expect(result.isInternalWithDisabledE2EEForMail).toBe(false);
294 expect(result.publicKeys).toHaveSize(0);