Changeset View
Changeset View
Standalone View
Standalone View
keyserver/src/push/crypto.js
// @flow | // @flow | |||||||||||||
import apn from '@parse/node-apn'; | import apn from '@parse/node-apn'; | |||||||||||||
import invariant from 'invariant'; | import invariant from 'invariant'; | |||||||||||||
import type { AndroidNotification } from './types.js'; | ||||||||||||||
import { encryptAndUpdateOlmSession } from '../updaters/olm-session-updater.js'; | import { encryptAndUpdateOlmSession } from '../updaters/olm-session-updater.js'; | |||||||||||||
async function encryptIOSNotification( | async function encryptIOSNotification( | |||||||||||||
cookieID: string, | cookieID: string, | |||||||||||||
notification: apn.Notification, | notification: apn.Notification, | |||||||||||||
): Promise<apn.Notification> { | ): Promise<apn.Notification> { | |||||||||||||
invariant( | invariant( | |||||||||||||
!notification.collapseId, | !notification.collapseId, | |||||||||||||
▲ Show 20 Lines • Show All 74 Lines • ▼ Show 20 Lines | for (const payloadField in restPayload) { | |||||||||||||
encryptedNotification.payload[payloadField] = | encryptedNotification.payload[payloadField] = | |||||||||||||
restPayload[payloadField].body; | restPayload[payloadField].body; | |||||||||||||
} | } | |||||||||||||
encryptedNotification.payload.encrypted = 1; | encryptedNotification.payload.encrypted = 1; | |||||||||||||
return encryptedNotification; | return encryptedNotification; | |||||||||||||
} | } | |||||||||||||
async function encryptAndroidNotification( | ||||||||||||||
cookieID: string, | ||||||||||||||
notification: AndroidNotification, | ||||||||||||||
): Promise<AndroidNotification> { | ||||||||||||||
const encryptedNotification = { | ||||||||||||||
data: { | ||||||||||||||
id: notification.data.id, | ||||||||||||||
badgeOnly: notification.data.badgeOnly, | ||||||||||||||
}, | ||||||||||||||
}; | ||||||||||||||
const { | ||||||||||||||
data: { id, badgeOnly, ...unencryptedPayload }, | ||||||||||||||
} = notification; | ||||||||||||||
ashoat: Personally I think this is more clear:
```lang=js
const { id, badgeOnly, ...unencryptedPayload… | ||||||||||||||
let encryptedSerializedPayload; | ||||||||||||||
try { | ||||||||||||||
const unencryptedSerializedPayload = JSON.stringify(unencryptedPayload); | ||||||||||||||
const { serializedPayload } = await encryptAndUpdateOlmSession( | ||||||||||||||
cookieID, | ||||||||||||||
'notifications', | ||||||||||||||
{ | ||||||||||||||
serializedPayload: unencryptedSerializedPayload, | ||||||||||||||
}, | ||||||||||||||
); | ||||||||||||||
encryptedSerializedPayload = serializedPayload; | ||||||||||||||
} catch (e) { | ||||||||||||||
console.log('Notification encryption failed: ' + e); | ||||||||||||||
encryptedNotification.data = { | ||||||||||||||
...unencryptedPayload, | ||||||||||||||
...encryptedNotification.data, | ||||||||||||||
encryptionFailed: '1', | ||||||||||||||
}; | ||||||||||||||
ashoatUnsubmitted Not Done Inline Actions
Personally I prefer to always have the existing data first when doing this pattern ashoat: Personally I prefer to always have the existing data first when doing this pattern | ||||||||||||||
marcinAuthorUnsubmitted Done Inline ActionsBy changing the AndroidNotification type to be purely readonly, we can no longer introduce this change due to the flow error. It even explicitly advises to change the order of spreads: Cannot spread object literal because Flow cannot determine a type for object literal [1]. rest of object pattern [2] cannot be spread because the indexer string [3] may overwrite properties with explicit keys in a way that Flow cannot track. Try spreading rest of object pattern [2] first or remove the indexer. [cannot-spread-indexer] src/push/crypto.js [2] 73│ const { id, badgeOnly, ...unencryptedPayload } = notification.data; : 87│ } catch (e) { 88│ console.log('Notification encryption failed: ' + e); 89│ [1] 90│ encryptedNotification.data = { 91│ ...encryptedNotification.data, 92│ ...unencryptedPayload, 93│ encryptionFailed: '1', 94│ }; 95│ return encryptedNotification; 96│ } 97│ src/push/types.js [3] 7│ +[string]: string, If it is a really important convention we can introduce it but we would probably have to refactor this function significantly. marcin: By changing the `AndroidNotification` type to be purely readonly, we can no longer introduce… | ||||||||||||||
return encryptedNotification; | ||||||||||||||
} | ||||||||||||||
encryptedNotification.data = { | ||||||||||||||
...encryptedNotification.data, | ||||||||||||||
encryptedPayload: encryptedSerializedPayload.body, | ||||||||||||||
}; | ||||||||||||||
return encryptedNotification; | ||||||||||||||
} | ||||||||||||||
function prepareEncryptedIOSNotifications( | function prepareEncryptedIOSNotifications( | |||||||||||||
cookieIDs: $ReadOnlyArray<string>, | cookieIDs: $ReadOnlyArray<string>, | |||||||||||||
notification: apn.Notification, | notification: apn.Notification, | |||||||||||||
): Promise<Array<apn.Notification>> { | ): Promise<Array<apn.Notification>> { | |||||||||||||
const notificationPromises = cookieIDs.map(cookieID => | const notificationPromises = cookieIDs.map(cookieID => | |||||||||||||
encryptIOSNotification(cookieID, notification), | encryptIOSNotification(cookieID, notification), | |||||||||||||
); | ); | |||||||||||||
return Promise.all(notificationPromises); | return Promise.all(notificationPromises); | |||||||||||||
} | } | |||||||||||||
export { prepareEncryptedIOSNotifications }; | function prepareEncryptedAndroidNotifications( | |||||||||||||
cookieIDs: $ReadOnlyArray<string>, | ||||||||||||||
notification: AndroidNotification, | ||||||||||||||
): Promise<Array<AndroidNotification>> { | ||||||||||||||
const notificationPromises = cookieIDs.map(cookieID => | ||||||||||||||
encryptAndroidNotification(cookieID, notification), | ||||||||||||||
); | ||||||||||||||
return Promise.all(notificationPromises); | ||||||||||||||
} | ||||||||||||||
export { | ||||||||||||||
prepareEncryptedIOSNotifications, | ||||||||||||||
prepareEncryptedAndroidNotifications, | ||||||||||||||
}; |
Personally I think this is more clear: