Page MenuHomePhabricator

D12396.id41714.diff
No OneTemporary

D12396.id41714.diff

diff --git a/keyserver/src/push/crypto.js b/keyserver/src/push/crypto.js
--- a/keyserver/src/push/crypto.js
+++ b/keyserver/src/push/crypto.js
@@ -1,6 +1,5 @@
// @flow
-import type { EncryptResult } from '@commapp/olm';
import apn from '@parse/node-apn';
import crypto from 'crypto';
import invariant from 'invariant';
@@ -18,16 +17,17 @@
AndroidNotificationRescind,
NotificationTargetDevice,
SenderDeviceDescriptor,
+ EncryptedNotifUtilsAPI,
} from 'lib/types/notif-types.js';
import { toBase64URL } from 'lib/utils/base64.js';
-import { encryptAndUpdateOlmSession } from '../updaters/olm-session-updater.js';
import { encrypt, generateKey } from '../utils/aes-crypto-utils.js';
import { getOlmUtility } from '../utils/olm-utils.js';
async function encryptAPNsNotification(
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
cookieID: string,
- senderDeviceID: SenderDeviceDescriptor,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
notification: apn.Notification,
codeVersion?: ?number,
notificationSizeValidator?: apn.Notification => boolean,
@@ -71,33 +71,26 @@
let dbPersistCondition;
if (notificationSizeValidator) {
- dbPersistCondition = ({
- serializedPayload,
- }: {
- +[string]: EncryptResult,
- }) => {
+ dbPersistCondition = (serializedPayload: string) => {
const notifCopy = _cloneDeep(encryptedNotification);
- notifCopy.payload.encryptedPayload = serializedPayload.body;
+ notifCopy.payload.encryptedPayload = serializedPayload;
return notificationSizeValidator(notifCopy);
};
}
const {
- encryptedMessages: { serializedPayload },
- dbPersistConditionViolated,
+ encryptedData: serializedPayload,
+ sizeLimitViolated: dbPersistConditionViolated,
encryptionOrder,
- } = await encryptAndUpdateOlmSession(
+ } = await encryptedNotifUtilsAPI.encryptSerializedNotifPayload(
cookieID,
- 'notifications',
- {
- serializedPayload: unencryptedSerializedPayload,
- },
+ unencryptedSerializedPayload,
dbPersistCondition,
);
encryptedNotification.payload.encryptedPayload = serializedPayload.body;
encryptedNotification.payload = {
- ...senderDeviceID,
...encryptedNotification.payload,
+ ...senderDeviceDescriptor,
};
if (codeVersion && codeVersion >= 254 && codeVersion % 2 === 0) {
@@ -140,8 +133,9 @@
}
async function encryptAndroidNotificationPayload<T>(
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
cookieID: string,
- senderDeviceID: SenderDeviceDescriptor,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
unencryptedPayload: T,
payloadSizeValidator?: (
T | $ReadOnly<{ ...SenderDeviceDescriptor, +encryptedPayload: string }>,
@@ -166,33 +160,27 @@
let dbPersistCondition;
if (payloadSizeValidator) {
- dbPersistCondition = ({
- serializedPayload,
- }: {
- +[string]: EncryptResult,
- }) =>
+ dbPersistCondition = (serializedPayload: string) =>
payloadSizeValidator({
- encryptedPayload: serializedPayload.body,
- ...senderDeviceID,
+ encryptedPayload: serializedPayload,
+ ...senderDeviceDescriptor,
});
}
const {
- encryptedMessages: { serializedPayload },
- dbPersistConditionViolated,
+ encryptedData: serializedPayload,
+ sizeLimitViolated: dbPersistConditionViolated,
encryptionOrder,
- } = await encryptAndUpdateOlmSession(
+ } = await encryptedNotifUtilsAPI.encryptSerializedNotifPayload(
cookieID,
- 'notifications',
- {
- serializedPayload: unencryptedSerializedPayload,
- },
+ unencryptedSerializedPayload,
dbPersistCondition,
);
+
return {
resultPayload: {
encryptedPayload: serializedPayload.body,
- ...senderDeviceID,
+ ...senderDeviceDescriptor,
},
payloadSizeExceeded: !!dbPersistConditionViolated,
encryptionOrder,
@@ -213,7 +201,8 @@
}
async function encryptAndroidVisualNotification(
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
cookieID: string,
notification: AndroidVisualNotification,
notificationSizeValidator?: AndroidVisualNotification => boolean,
@@ -249,8 +238,9 @@
}
const { resultPayload, payloadSizeExceeded, encryptionOrder } =
await encryptAndroidNotificationPayload(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
unencryptedPayload,
payloadSizeValidator,
);
@@ -267,8 +257,9 @@
}
async function encryptAndroidSilentNotification(
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
cookieID: string,
- senderDeviceID: SenderDeviceDescriptor,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
notification: AndroidNotificationRescind | AndroidBadgeOnlyNotification,
): Promise<AndroidNotificationRescind | AndroidBadgeOnlyNotification> {
// We don't validate payload size for rescind
@@ -276,8 +267,9 @@
// never exceed any FCM limit
const { ...unencryptedPayload } = notification.data;
const { resultPayload } = await encryptAndroidNotificationPayload(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
unencryptedPayload,
);
if (resultPayload.encryptedPayload) {
@@ -300,8 +292,9 @@
}
async function encryptBasicPayload<T>(
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
cookieID: string,
- senderDeviceID: SenderDeviceDescriptor,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
basicPayload: T,
): Promise<
| $ReadOnly<{
@@ -318,15 +311,14 @@
}
try {
- const {
- encryptedMessages: { serializedPayload },
- encryptionOrder,
- } = await encryptAndUpdateOlmSession(cookieID, 'notifications', {
- serializedPayload: unencryptedSerializedPayload,
- });
+ const { encryptedData: serializedPayload, encryptionOrder } =
+ await encryptedNotifUtilsAPI.encryptSerializedNotifPayload(
+ cookieID,
+ unencryptedSerializedPayload,
+ );
return {
- ...senderDeviceID,
+ ...senderDeviceDescriptor,
encryptedPayload: serializedPayload.body,
encryptionOrder,
};
@@ -340,15 +332,17 @@
}
async function encryptWebNotification(
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
cookieID: string,
- senderDeviceID: SenderDeviceDescriptor,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
notification: PlainTextWebNotification,
): Promise<{ +notification: WebNotification, +encryptionOrder?: number }> {
const { id, ...payloadSansId } = notification;
const { encryptionOrder, ...encryptionResult } =
await encryptBasicPayload<PlainTextWebNotificationPayload>(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
payloadSansId,
);
@@ -359,14 +353,16 @@
}
async function encryptWNSNotification(
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
cookieID: string,
- senderDeviceID: SenderDeviceDescriptor,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
notification: PlainTextWNSNotification,
): Promise<{ +notification: WNSNotification, +encryptionOrder?: number }> {
const { encryptionOrder, ...encryptionResult } =
await encryptBasicPayload<PlainTextWNSNotification>(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
notification,
);
return {
@@ -376,7 +372,8 @@
}
function prepareEncryptedAPNsNotifications(
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
devices: $ReadOnlyArray<NotificationTargetDevice>,
notification: apn.Notification,
codeVersion?: ?number,
@@ -394,8 +391,9 @@
const notificationPromises = devices.map(
async ({ cookieID, deviceToken, blobHolder }) => {
const notif = await encryptAPNsNotification(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
notification,
codeVersion,
notificationSizeValidator,
@@ -408,7 +406,8 @@
}
function prepareEncryptedIOSNotificationRescind(
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
devices: $ReadOnlyArray<NotificationTargetDevice>,
notification: apn.Notification,
codeVersion?: ?number,
@@ -422,8 +421,9 @@
const notificationPromises = devices.map(
async ({ deviceToken, cookieID }) => {
const { notification: notif } = await encryptAPNsNotification(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
notification,
codeVersion,
);
@@ -434,7 +434,8 @@
}
function prepareEncryptedAndroidVisualNotifications(
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
devices: $ReadOnlyArray<NotificationTargetDevice>,
notification: AndroidVisualNotification,
notificationSizeValidator?: (
@@ -452,7 +453,8 @@
const notificationPromises = devices.map(
async ({ deviceToken, cookieID, blobHolder }) => {
const notif = await encryptAndroidVisualNotification(
- senderDeviceID,
+ encryptedNotifUtilsAPI,
+ senderDeviceDescriptor,
cookieID,
notification,
notificationSizeValidator,
@@ -465,7 +467,8 @@
}
function prepareEncryptedAndroidSilentNotifications(
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
devices: $ReadOnlyArray<NotificationTargetDevice>,
notification: AndroidNotificationRescind | AndroidBadgeOnlyNotification,
): Promise<
@@ -479,8 +482,9 @@
const notificationPromises = devices.map(
async ({ deviceToken, cookieID }) => {
const notif = await encryptAndroidSilentNotification(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
notification,
);
return { deviceToken, cookieID, notification: notif };
@@ -490,7 +494,8 @@
}
function prepareEncryptedWebNotifications(
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
devices: $ReadOnlyArray<NotificationTargetDevice>,
notification: PlainTextWebNotification,
): Promise<
@@ -503,8 +508,9 @@
const notificationPromises = devices.map(
async ({ deviceToken, cookieID }) => {
const notif = await encryptWebNotification(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
notification,
);
return { ...notif, deviceToken };
@@ -514,7 +520,8 @@
}
function prepareEncryptedWNSNotifications(
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
devices: $ReadOnlyArray<NotificationTargetDevice>,
notification: PlainTextWNSNotification,
): Promise<
@@ -527,8 +534,9 @@
const notificationPromises = devices.map(
async ({ deviceToken, cookieID }) => {
const notif = await encryptWNSNotification(
+ encryptedNotifUtilsAPI,
cookieID,
- senderDeviceID,
+ senderDeviceDescriptor,
notification,
);
return { ...notif, deviceToken };
diff --git a/keyserver/src/push/encrypted-notif-utils-api.js b/keyserver/src/push/encrypted-notif-utils-api.js
new file mode 100644
--- /dev/null
+++ b/keyserver/src/push/encrypted-notif-utils-api.js
@@ -0,0 +1,49 @@
+// @flow
+
+import type { EncryptResult } from '@commapp/olm';
+
+import type { EncryptedNotifUtilsAPI } from 'lib/types/notif-types.js';
+
+import { blobServiceUpload } from './utils.js';
+import { encryptAndUpdateOlmSession } from '../updaters/olm-session-updater.js';
+
+const encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI = {
+ encryptSerializedNotifPayload: async (
+ cryptoID: string,
+ unencryptedPayload: string,
+ encryptedPayloadSizeValidator?: (encryptedPayload: string) => boolean,
+ ) => {
+ let dbPersistCondition;
+ if (encryptedPayloadSizeValidator) {
+ dbPersistCondition = ({
+ serializedPayload,
+ }: {
+ +[string]: EncryptResult,
+ }) => encryptedPayloadSizeValidator(serializedPayload.body);
+ }
+
+ const {
+ encryptedMessages: { serializedPayload },
+ dbPersistConditionViolated,
+ encryptionOrder,
+ } = await encryptAndUpdateOlmSession(
+ cryptoID,
+ 'notifications',
+ {
+ serializedPayload: unencryptedPayload,
+ },
+ dbPersistCondition,
+ );
+
+ return {
+ encryptedData: serializedPayload,
+ sizeLimitViolated: dbPersistConditionViolated,
+ encryptionOrder,
+ };
+ },
+ uploadLargeNotifPayload: blobServiceUpload,
+ getNotifByteSize: (serializedPayload: string) =>
+ Buffer.byteLength(serializedPayload),
+};
+
+export default encryptedNotifUtilsAPI;
diff --git a/keyserver/src/push/rescind.js b/keyserver/src/push/rescind.js
--- a/keyserver/src/push/rescind.js
+++ b/keyserver/src/push/rescind.js
@@ -10,6 +10,7 @@
NotificationTargetDevice,
TargetedAndroidNotification,
SenderDeviceDescriptor,
+ EncryptedNotifUtilsAPI,
} from 'lib/types/notif-types.js';
import { threadSubscriptions } from 'lib/types/subscription-types.js';
import { threadPermissions } from 'lib/types/thread-permission-types.js';
@@ -20,6 +21,7 @@
prepareEncryptedAndroidSilentNotifications,
prepareEncryptedIOSNotificationRescind,
} from './crypto.js';
+import encryptedNotifUtilsAPI from './encrypted-notif-utils-api.js';
import { getAPNsNotificationTopic } from './providers.js';
import type { TargetedAPNsNotification } from './types.js';
import {
@@ -275,12 +277,14 @@
}
async function conditionallyEncryptNotification<T>(
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPIInstance: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
notification: T,
codeVersion: ?number,
devices: $ReadOnlyArray<NotificationTargetDevice>,
encryptCallback: (
- senderDeviceID: SenderDeviceDescriptor,
+ encryptedNotifUtilsAPI: EncryptedNotifUtilsAPI,
+ senderDeviceDescriptor: SenderDeviceDescriptor,
devices: $ReadOnlyArray<NotificationTargetDevice>,
notification: T,
codeVersion?: ?number,
@@ -301,7 +305,8 @@
}));
}
const notifications = await encryptCallback(
- senderDeviceID,
+ encryptedNotifUtilsAPI,
+ senderDeviceDescriptor,
devices,
notification,
codeVersion,
@@ -354,6 +359,7 @@
},
};
return await conditionallyEncryptNotification(
+ encryptedNotifUtilsAPI,
{ keyserverID },
notification,
codeVersion,
@@ -383,6 +389,7 @@
},
};
const targetedRescinds = await conditionallyEncryptNotification(
+ encryptedNotifUtilsAPI,
{ keyserverID },
notification,
codeVersion,
diff --git a/keyserver/src/push/send.js b/keyserver/src/push/send.js
--- a/keyserver/src/push/send.js
+++ b/keyserver/src/push/send.js
@@ -56,6 +56,7 @@
prepareEncryptedWebNotifications,
prepareEncryptedWNSNotifications,
} from './crypto.js';
+import encryptedNotifUtilsAPI from './encrypted-notif-utils-api.js';
import { getAPNsNotificationTopic } from './providers.js';
import { rescindPushNotifs } from './rescind.js';
import type { TargetedAPNsNotification } from './types.js';
@@ -70,7 +71,6 @@
wnsMaxNotificationPayloadByteSize,
wnsPush,
type WNSPushError,
- blobServiceUpload,
} from './utils.js';
import createIDs from '../creators/id-creator.js';
import { createUpdates } from '../creators/update-creator.js';
@@ -1039,6 +1039,7 @@
if (platformDetails.platform === 'macos') {
const macOSNotifsWithoutMessageInfos =
await prepareEncryptedAPNsNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
devices,
notification,
@@ -1053,6 +1054,7 @@
}
const notifsWithMessageInfos = await prepareEncryptedAPNsNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
devices,
copyWithMessageInfos,
@@ -1090,7 +1092,7 @@
let blobHash, blobHolders, encryptionKey, blobUploadError;
if (canQueryBlobService) {
({ blobHash, blobHolders, encryptionKey, blobUploadError } =
- await blobServiceUpload(
+ await encryptedNotifUtilsAPI.uploadLargeNotifPayload(
copyWithMessageInfos.compile(),
devicesWithExcessiveSizeNoHolders.length,
));
@@ -1123,6 +1125,7 @@
}
const notifsWithoutMessageInfos = await prepareEncryptedAPNsNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
devicesWithExcessiveSize,
notification,
@@ -1247,8 +1250,9 @@
const priority = 'high';
if (!shouldBeEncrypted) {
const notificationToSend =
- Buffer.byteLength(JSON.stringify(copyWithMessageInfos)) <=
- fcmMaxNotificationPayloadByteSize
+ encryptedNotifUtilsAPI.getNotifByteSize(
+ JSON.stringify(copyWithMessageInfos),
+ ) <= fcmMaxNotificationPayloadByteSize
? copyWithMessageInfos
: notification;
@@ -1263,12 +1267,14 @@
const serializedNotif = JSON.stringify(notif);
return (
!serializedNotif ||
- Buffer.byteLength(serializedNotif) <= fcmMaxNotificationPayloadByteSize
+ encryptedNotifUtilsAPI.getNotifByteSize(serializedNotif) <=
+ fcmMaxNotificationPayloadByteSize
);
};
const notifsWithMessageInfos =
await prepareEncryptedAndroidVisualNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
devices,
copyWithMessageInfos,
@@ -1297,7 +1303,7 @@
let blobHash, blobHolders, encryptionKey, blobUploadError;
if (canQueryBlobService) {
({ blobHash, blobHolders, encryptionKey, blobUploadError } =
- await blobServiceUpload(
+ await encryptedNotifUtilsAPI.uploadLargeNotifPayload(
JSON.stringify(copyWithMessageInfos.data),
devicesWithExcessiveSizeNoHolders.length,
));
@@ -1331,6 +1337,7 @@
const notifsWithoutMessageInfos =
await prepareEncryptedAndroidVisualNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
devicesWithExcessiveSize,
notification,
@@ -1402,6 +1409,7 @@
}
return prepareEncryptedWebNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
devices,
notification,
@@ -1440,7 +1448,7 @@
};
if (
- Buffer.byteLength(JSON.stringify(notification)) >
+ encryptedNotifUtilsAPI.getNotifByteSize(JSON.stringify(notification)) >
wnsMaxNotificationPayloadByteSize
) {
console.warn('WNS notification exceeds size limit');
@@ -1457,6 +1465,7 @@
}));
}
return await prepareEncryptedWNSNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
devices,
notification,
@@ -1813,6 +1822,7 @@
let targetedNotifications: $ReadOnlyArray<TargetedAPNsNotification>;
if (codeVersion > 222) {
const notificationsArray = await prepareEncryptedAPNsNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
deviceInfos,
notification,
@@ -1865,6 +1875,7 @@
if (codeVersion > 222) {
const notificationsArray =
await prepareEncryptedAndroidSilentNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
deviceInfos,
notification,
@@ -1923,6 +1934,7 @@
let targetedNotifications: $ReadOnlyArray<TargetedAPNsNotification>;
if (shouldBeEncrypted) {
const notificationsArray = await prepareEncryptedAPNsNotifications(
+ encryptedNotifUtilsAPI,
{ keyserverID },
deviceInfos,
notification,
diff --git a/lib/types/notif-types.js b/lib/types/notif-types.js
--- a/lib/types/notif-types.js
+++ b/lib/types/notif-types.js
@@ -1,5 +1,6 @@
// @flow
+import type { EncryptResult } from '@commapp/olm';
import t, { type TInterface } from 'tcomb';
import type { EntityText, ThreadEntity } from '../utils/entity-text.js';
@@ -185,3 +186,27 @@
+deviceToken: string,
+blobHolder?: string,
};
+
+export type EncryptedNotifUtilsAPI = {
+ +encryptSerializedNotifPayload: (
+ cryptoID: string,
+ unencryptedPayload: string,
+ encryptedPayloadSizeValidator?: (encryptedPayload: string) => boolean,
+ ) => Promise<{
+ +encryptedData: EncryptResult,
+ +sizeLimitViolated?: boolean,
+ +encryptionOrder?: number,
+ }>,
+ +uploadLargeNotifPayload: (
+ payload: string,
+ numberOfHolders: number,
+ ) => Promise<
+ | {
+ +blobHolders: $ReadOnlyArray<string>,
+ +blobHash: string,
+ +encryptionKey: string,
+ }
+ | { +blobUploadError: string },
+ >,
+ +getNotifByteSize: (serializedNotification: string) => number,
+};

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 22, 4:49 PM (3 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2562868
Default Alt Text
D12396.id41714.diff (20 KB)

Event Timeline