Changeset View
Changeset View
Standalone View
Standalone View
keyserver/src/push/crypto.js
- This file was added.
// @flow | |||||
import apn from '@parse/node-apn'; | |||||
import invariant from 'invariant'; | |||||
import { encryptAndUpdateOlmSession } from '../updaters/olm-session-updater.js'; | |||||
async function encryptIOSNotification( | |||||
cookieID: string, | |||||
notification: apn.Notification, | |||||
): Promise<apn.Notification> { | |||||
invariant( | |||||
!notification.collapseId, | |||||
'Collapsible notifications encryption currently not implemented', | |||||
); | |||||
const encryptedNotification = new apn.Notification(); | |||||
encryptedNotification.id = notification.id; | |||||
encryptedNotification.payload.id = notification.id; | |||||
encryptedNotification.topic = notification.topic; | |||||
encryptedNotification.sound = notification.aps.sound; | |||||
encryptedNotification.pushType = 'alert'; | |||||
encryptedNotification.mutableContent = true; | |||||
const { id, ...payloadSansId } = notification.payload; | |||||
const unencryptedPayload = { | |||||
...payloadSansId, | |||||
badge: notification.aps.badge.toString(), | |||||
merged: notification.body, | |||||
}; | |||||
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.body = notification.body; | |||||
encryptedNotification.threadId = notification.payload.threadID; | |||||
invariant( | |||||
typeof notification.aps.badge === 'number', | |||||
'Unencrypted notification must have badge as a number', | |||||
); | |||||
encryptedNotification.badge = notification.aps.badge; | |||||
encryptedNotification.payload = { | |||||
...encryptedNotification.payload, | |||||
...notification.payload, | |||||
encryptionFailed: 1, | |||||
}; | |||||
return encryptedNotification; | |||||
} | |||||
encryptedNotification.payload.encryptedPayload = | |||||
encryptedSerializedPayload.body; | |||||
return encryptedNotification; | |||||
} | |||||
function prepareEncryptedIOSNotifications( | |||||
cookieIDs: $ReadOnlyArray<string>, | |||||
notification: apn.Notification, | |||||
): Promise<Array<apn.Notification>> { | |||||
const notificationPromises = cookieIDs.map(cookieID => | |||||
encryptIOSNotification(cookieID, notification), | |||||
); | |||||
return Promise.all(notificationPromises); | |||||
} | |||||
export { prepareEncryptedIOSNotifications }; |