Page MenuHomePhabricator

D6892.id23301.diff
No OneTemporary

D6892.id23301.diff

diff --git a/keyserver/src/push/providers.js b/keyserver/src/push/providers.js
--- a/keyserver/src/push/providers.js
+++ b/keyserver/src/push/providers.js
@@ -7,11 +7,20 @@
import invariant from 'invariant';
import webpush from 'web-push';
+import type { PlatformDetails } from 'lib/types/device-types';
+
import { importJSON } from '../utils/import-json.js';
type APNPushProfile = 'apn_config' | 'comm_apn_config';
-function getAPNPushProfileForCodeVersion(codeVersion: ?number): APNPushProfile {
- return codeVersion && codeVersion >= 87 ? 'comm_apn_config' : 'apn_config';
+function getAPNPushProfileForCodeVersion(
+ platformDetails: PlatformDetails,
+): APNPushProfile {
+ if (platformDetails.platform === 'macos') {
+ return 'comm_apn_config';
+ }
+ return platformDetails.codeVersion && platformDetails.codeVersion >= 87
+ ? 'comm_apn_config'
+ : 'apn_config';
}
type FCMPushProfile = 'fcm_config' | 'comm_fcm_config';
@@ -77,8 +86,13 @@
}
}
-function getAPNsNotificationTopic(codeVersion: ?number): string {
- return codeVersion && codeVersion >= 87 ? 'app.comm' : 'org.squadcal.app';
+function getAPNsNotificationTopic(platformDetails: PlatformDetails): string {
+ if (platformDetails.platform === 'macos') {
+ return 'app.comm.macos';
+ }
+ return platformDetails.codeVersion && platformDetails.codeVersion >= 87
+ ? 'app.comm'
+ : 'org.squadcal.app';
}
type WebPushConfig = { +publicKey: string, +privateKey: string };
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
@@ -61,7 +61,7 @@
deliveryPromises[id] = apnPush({
notification,
deviceTokens: delivery.iosDeviceTokens,
- codeVersion: null,
+ platformDetails: { platform: 'ios' },
});
} else if (delivery.androidID) {
// Old Android
@@ -87,7 +87,7 @@
deliveryPromises[id] = apnPush({
notification,
deviceTokens,
- codeVersion,
+ platformDetails: { platform: 'ios', codeVersion },
});
} else if (delivery.deviceType === 'android') {
// New Android
@@ -162,7 +162,10 @@
): apn.Notification {
const notification = new apn.Notification();
notification.contentAvailable = true;
- notification.topic = getAPNsNotificationTopic(codeVersion);
+ notification.topic = getAPNsNotificationTopic({
+ platform: 'ios',
+ codeVersion: codeVersion ?? undefined,
+ });
notification.priority = 5;
notification.pushType = 'background';
notification.payload =
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
@@ -22,7 +22,7 @@
rawThreadInfoFromServerThreadInfo,
threadInfoFromRawThreadInfo,
} from 'lib/shared/thread-utils.js';
-import type { Platform } from 'lib/types/device-types.js';
+import type { Platform, PlatformDetails } from 'lib/types/device-types.js';
import {
type RawMessageInfo,
type MessageInfo,
@@ -173,28 +173,34 @@
if (iosVersionsToTokens) {
for (const [codeVer, deviceTokens] of iosVersionsToTokens) {
const codeVersion = parseInt(codeVer, 10); // only for Flow
+ const platformDetails = { platform: 'ios', codeVersion };
const shimmedNewRawMessageInfos = shimUnsupportedRawMessageInfos(
newRawMessageInfos,
- { platform: 'ios', codeVersion },
+ platformDetails,
);
const deliveryPromise = (async () => {
- const notification = await prepareIOSNotification({
+ const notification = await prepareAPNsNotification({
allMessageInfos,
newRawMessageInfos: shimmedNewRawMessageInfos,
threadInfo,
collapseKey: notifInfo.collapseKey,
badgeOnly,
unreadCount: unreadCounts[userID],
- codeVersion,
+ platformDetails,
notifTargetUserInfo: {
id: userID,
username,
},
});
- return await sendIOSNotification(notification, [...deviceTokens], {
- ...notificationInfo,
- codeVersion,
- });
+ return await sendAPNsNotification(
+ 'ios',
+ notification,
+ [...deviceTokens],
+ {
+ ...notificationInfo,
+ codeVersion,
+ },
+ );
})();
deliveryPromises.push(deliveryPromise);
}
@@ -203,9 +209,10 @@
if (androidVersionsToTokens) {
for (const [codeVer, deviceTokens] of androidVersionsToTokens) {
const codeVersion = parseInt(codeVer, 10); // only for Flow
+ const platformDetails = { platform: 'android', codeVersion };
const shimmedNewRawMessageInfos = shimUnsupportedRawMessageInfos(
newRawMessageInfos,
- { platform: 'android', codeVersion },
+ platformDetails,
);
const deliveryPromise = (async () => {
const notification = await prepareAndroidNotification({
@@ -215,7 +222,7 @@
collapseKey: notifInfo.collapseKey,
badgeOnly,
unreadCount: unreadCounts[userID],
- codeVersion,
+ platformDetails,
notifTargetUserInfo: {
id: userID,
username,
@@ -540,18 +547,18 @@
return byPlatform;
}
-type IOSNotifInputData = {
+type APNsNotifInputData = {
+allMessageInfos: MessageInfo[],
+newRawMessageInfos: RawMessageInfo[],
+threadInfo: ThreadInfo,
+collapseKey: ?string,
+badgeOnly: boolean,
+unreadCount: number,
- +codeVersion: number,
+ +platformDetails: PlatformDetails,
+notifTargetUserInfo: UserInfo,
};
-async function prepareIOSNotification(
- inputData: IOSNotifInputData,
+async function prepareAPNsNotification(
+ inputData: APNsNotifInputData,
): Promise<apn.Notification> {
const {
allMessageInfos,
@@ -560,14 +567,13 @@
collapseKey,
badgeOnly,
unreadCount,
- codeVersion,
+ platformDetails,
notifTargetUserInfo,
} = inputData;
const uniqueID = uuidv4();
const notification = new apn.Notification();
- notification.topic = getAPNsNotificationTopic(codeVersion);
-
+ notification.topic = getAPNsNotificationTopic(platformDetails);
const { merged, ...rest } = await notifTextsForMessageInfo(
allMessageInfos,
threadInfo,
@@ -589,7 +595,7 @@
notification.pushType = 'alert';
notification.payload.id = uniqueID;
notification.payload.threadID = threadInfo.id;
- if (codeVersion > 1000) {
+ if (platformDetails.codeVersion && platformDetails.codeVersion > 1000) {
notification.mutableContent = true;
}
if (collapseKey) {
@@ -612,14 +618,15 @@
const notificationCopy = _cloneDeep(notification);
if (notificationCopy.length() > apnMaxNotificationPayloadByteSize) {
console.warn(
- `iOS notification ${uniqueID} exceeds size limit, even with messageInfos omitted`,
+ `${platformDetails.platform} notification ${uniqueID} ` +
+ `exceeds size limit, even with messageInfos omitted`,
);
}
return notification;
}
type AndroidNotifInputData = {
- ...IOSNotifInputData,
+ ...APNsNotifInputData,
+dbID: string,
};
async function prepareAndroidNotification(
@@ -632,7 +639,7 @@
collapseKey,
badgeOnly,
unreadCount,
- codeVersion,
+ platformDetails: { codeVersion },
notifTargetUserInfo,
dbID,
} = inputData;
@@ -658,7 +665,7 @@
// the notif has a full payload, and then crash when trying to parse it.
// By skipping `id` we allow old clients to still handle in-app notifs and
// badge updating.
- if (!badgeOnly || codeVersion >= 69) {
+ if (!badgeOnly || (codeVersion && codeVersion >= 69)) {
notification.data = {
...notification.data,
id: notifID,
@@ -734,29 +741,34 @@
+codeVersion: number,
};
-type IOSDelivery = {
+type APNsDelivery = {
source: $PropertyType<NotificationInfo, 'source'>,
- deviceType: 'ios',
+ deviceType: 'ios' | 'macos',
iosID: string,
deviceTokens: $ReadOnlyArray<string>,
codeVersion: number,
errors?: $ReadOnlyArray<ResponseFailure>,
};
-type IOSResult = {
+type APNsResult = {
info: NotificationInfo,
- delivery: IOSDelivery,
+ delivery: APNsDelivery,
invalidTokens?: $ReadOnlyArray<string>,
};
-async function sendIOSNotification(
+async function sendAPNsNotification(
+ platform: 'ios' | 'macos',
notification: apn.Notification,
deviceTokens: $ReadOnlyArray<string>,
notificationInfo: NotificationInfo,
-): Promise<IOSResult> {
+): Promise<APNsResult> {
const { source, codeVersion } = notificationInfo;
- const response = await apnPush({ notification, deviceTokens, codeVersion });
- const delivery: IOSDelivery = {
+ const response = await apnPush({
+ notification,
+ deviceTokens,
+ platformDetails: { platform, codeVersion },
+ });
+ const delivery: APNsDelivery = {
source,
- deviceType: 'ios',
+ deviceType: platform,
iosID: notification.id,
deviceTokens,
codeVersion,
@@ -764,7 +776,7 @@
if (response.errors) {
delivery.errors = response.errors;
}
- const result: IOSResult = {
+ const result: APNsResult = {
info: notificationInfo,
delivery,
};
@@ -774,8 +786,8 @@
return result;
}
-type PushResult = AndroidResult | IOSResult | WebResult;
-type PushDelivery = AndroidDelivery | IOSDelivery | WebDelivery;
+type PushResult = AndroidResult | APNsResult | WebResult;
+type PushDelivery = AndroidDelivery | APNsDelivery | WebDelivery;
type AndroidDelivery = {
source: $PropertyType<NotificationInfo, 'source'>,
deviceType: 'android',
@@ -964,11 +976,14 @@
for (const [codeVer, deviceTokens] of iosVersionsToTokens) {
const codeVersion = parseInt(codeVer, 10); // only for Flow
const notification = new apn.Notification();
- notification.topic = getAPNsNotificationTopic(codeVersion);
+ notification.topic = getAPNsNotificationTopic({
+ platform: 'ios',
+ codeVersion,
+ });
notification.badge = unreadCount;
notification.pushType = 'alert';
deliveryPromises.push(
- sendIOSNotification(notification, [...deviceTokens], {
+ sendAPNsNotification('ios', notification, [...deviceTokens], {
source,
dbID,
userID,
diff --git a/keyserver/src/push/utils.js b/keyserver/src/push/utils.js
--- a/keyserver/src/push/utils.js
+++ b/keyserver/src/push/utils.js
@@ -6,6 +6,7 @@
import invariant from 'invariant';
import webpush from 'web-push';
+import type { PlatformDetails } from 'lib/types/device-types.js';
import type { WebNotification } from 'lib/types/notif-types.js';
import { threadSubscriptions } from 'lib/types/subscription-types.js';
import { threadPermissions } from 'lib/types/thread-types.js';
@@ -39,13 +40,13 @@
async function apnPush({
notification,
deviceTokens,
- codeVersion,
+ platformDetails,
}: {
+notification: apn.Notification,
+deviceTokens: $ReadOnlyArray<string>,
- +codeVersion: ?number,
+ +platformDetails: PlatformDetails,
}): Promise<APNPushResult> {
- const pushProfile = getAPNPushProfileForCodeVersion(codeVersion);
+ const pushProfile = getAPNPushProfileForCodeVersion(platformDetails);
const apnProvider = await getAPNProvider(pushProfile);
if (!apnProvider && process.env.NODE_ENV === 'development') {
console.log(`no keyserver/secrets/${pushProfile}.json so ignoring notifs`);

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 9, 12:55 PM (1 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2835116
Default Alt Text
D6892.id23301.diff (11 KB)

Event Timeline