diff --git a/package-lock.json b/package-lock.json index 69d839e..53ad761 100644 --- a/package-lock.json +++ b/package-lock.json @@ -254,9 +254,8 @@ } }, "apn": { - "version": "3.0.0-alpha1", - "resolved": "https://registry.npmjs.org/apn/-/apn-3.0.0-alpha1.tgz", - "integrity": "sha512-o/wVNAxaQ7eegLZ69rtNEgiIQFngPClOAFFsVowsBDjVIaFsRccI+kfTda6rmVuiMSiGBMurlX01jyMNlO+AXQ==", + "version": "github:parse-community/node-apn#538d09480adfa4dddac644ee1f4bef443b674721", + "from": "github:parse-community/node-apn#semver:^3.0.1-parse", "requires": { "debug": "^3.1.0", "jsonwebtoken": "^8.1.0", @@ -265,17 +264,17 @@ }, "dependencies": { "debug": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", - "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "requires": { "ms": "^2.1.1" } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -367,6 +366,11 @@ "dev": true, "optional": true }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3428,9 +3432,9 @@ } }, "ecdsa-sig-formatter": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz", - "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "requires": { "safe-buffer": "^5.0.1" } @@ -4984,11 +4988,11 @@ "dev": true }, "jsonwebtoken": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz", - "integrity": "sha512-oge/hvlmeJCH+iIz1DwcO7vKPkNGJHhgkspk8OH3VKlw+mbi42WtD4ig1+VXRln765vxptAv+xT26Fd3cteqag==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", "requires": { - "jws": "^3.1.5", + "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", @@ -4996,13 +5000,14 @@ "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", - "ms": "^2.1.1" + "ms": "^2.1.1", + "semver": "^5.6.0" }, "dependencies": { "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -5018,21 +5023,21 @@ } }, "jwa": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz", - "integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", "requires": { "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.10", + "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "jws": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz", - "integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "requires": { - "jwa": "^1.1.5", + "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, @@ -5695,11 +5700,6 @@ "wordwrap": "~0.0.2" } }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" - }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -5789,20 +5789,13 @@ } }, "parse": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/parse/-/parse-1.9.2.tgz", - "integrity": "sha1-5B18tu/UZO6jDDTsBlFUj2bFuOQ=", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/parse/-/parse-1.11.1.tgz", + "integrity": "sha1-VY5TnULZ+4khDggiCdbzsD1frtU=", "requires": { "babel-runtime": "^6.11.6", - "ws": "^1.0.1", + "ws": "^3.3.1", "xmlhttprequest": "^1.7.0" - }, - "dependencies": { - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" - } } }, "parse-glob": { @@ -6570,8 +6563,7 @@ "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" }, "set-blocking": { "version": "2.0.0", @@ -7096,9 +7088,9 @@ } }, "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, "union-value": { "version": "1.0.1", @@ -7305,14 +7297,20 @@ } }, "ws": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", - "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "requires": { - "options": ">=0.0.5", - "ultron": "1.0.x" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" } }, + "xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", diff --git a/package.json b/package.json index 4afe175..6009466 100644 --- a/package.json +++ b/package.json @@ -33,10 +33,10 @@ "nyc": "^14.1.1" }, "dependencies": { - "apn": "^3.0.0-alpha1", "@parse/node-gcm": "^1.0.0", + "apn": "parse-community/node-apn#semver:^3.0.1-parse", "npmlog": "^4.0.2", - "parse": "^1.9.2" + "parse": "^1.11.1" }, "engines": { "node": ">= 8.9.1" diff --git a/spec/APNS.spec.js b/spec/APNS.spec.js index 00f8ed3..0fb58d8 100644 --- a/spec/APNS.spec.js +++ b/spec/APNS.spec.js @@ -190,9 +190,10 @@ describe('APNS', () => { }; let expirationTime = 1454571491354; let collapseId = "collapseIdentifier"; - let priority = 5; - let notification = APNS._generateNotification(data, { expirationTime: expirationTime, collapseId: collapseId, priority: priority }); + let pushType = "alert"; + let priority = 5; + let notification = APNS._generateNotification(data, { expirationTime: expirationTime, collapseId: collapseId, pushType: pushType, priority: priority }); expect(notification.aps.alert).toEqual({ body: 'alert', title: 'title' }); expect(notification.aps.badge).toEqual(data.badge); @@ -207,11 +208,35 @@ describe('APNS', () => { }); expect(notification.expiry).toEqual(Math.round(expirationTime / 1000)); expect(notification.collapseId).toEqual(collapseId); + expect(notification.pushType).toEqual(pushType); expect(notification.priority).toEqual(priority); done(); }); + + it('sets push type to alert if not defined explicitly', (done) => { + //Mock request data + let data = { + 'alert': 'alert', + 'title': 'title', + 'badge': 100, + 'sound': 'test', + 'content-available': 1, + 'mutable-content': 1, + 'category': 'INVITE_CATEGORY', + 'threadId': 'a-thread-id', + 'key': 'value', + 'keyAgain': 'valueAgain' + }; + let expirationTime = 1454571491354; + let collapseId = "collapseIdentifier"; + + let notification = APNS._generateNotification(data, { expirationTime: expirationTime, collapseId: collapseId }); + + expect(notification.pushType).toEqual('alert'); + done(); + }); - it('can generate APNS notification from raw data', (done) => { + it('can generate APNS notification from raw data', (done) => { //Mock request data let data = { 'aps': { @@ -228,12 +253,14 @@ describe('APNS', () => { }; let expirationTime = 1454571491354; let collapseId = "collapseIdentifier"; - let priority = 5 + let pushType = "background"; + let priority = 5; - let notification = APNS._generateNotification(data, { expirationTime: expirationTime, collapseId: collapseId, priority: priority }); + let notification = APNS._generateNotification(data, { expirationTime: expirationTime, collapseId: collapseId, pushType: pushType, priority: priority }); expect(notification.expiry).toEqual(Math.round(expirationTime / 1000)); expect(notification.collapseId).toEqual(collapseId); + expect(notification.pushType).toEqual(pushType); expect(notification.priority).toEqual(priority); let stringifiedJSON = notification.compile(); @@ -302,8 +329,10 @@ describe('APNS', () => { // Mock data let expirationTime = 1454571491354; let collapseId = "collapseIdentifier"; + let pushType = "alert"; // or background let data = { 'collapse_id': collapseId, + 'push_type': pushType, 'expiration_time': expirationTime, 'priority': 6, 'data': { @@ -335,7 +364,8 @@ describe('APNS', () => { let notification = calledArgs[0]; expect(notification.aps.alert).toEqual(data.data.alert); expect(notification.expiry).toEqual(Math.round(data['expiration_time'] / 1000)); - expect(notification.collapseId).toEqual(data['collapse_id']); + expect(notification.collapseId).toEqual(collapseId); + expect(notification.pushType).toEqual(pushType); expect(notification.priority).toEqual(data['priority']); let apnDevices = calledArgs[1]; expect(apnDevices.length).toEqual(4); @@ -373,9 +403,11 @@ describe('APNS', () => { apns.providers = [provider, providerDev]; // Mock data let expirationTime = 1454571491354; + let pushType = "alert"; // or background let collapseId = "collapseIdentifier"; let data = { 'collapse_id': collapseId, + 'push_type': pushType, 'expiration_time': expirationTime, 'data': { 'alert': 'alert' @@ -413,6 +445,7 @@ describe('APNS', () => { expect(notification.aps.alert).toEqual(data.data.alert); expect(notification.expiry).toEqual(Math.round(data['expiration_time'] / 1000)); expect(notification.collapseId).toEqual(data['collapse_id']); + expect(notification.pushType).toEqual(pushType); let apnDevices = calledArgs[1]; expect(apnDevices.length).toBe(3); @@ -422,6 +455,7 @@ describe('APNS', () => { expect(notification.aps.alert).toEqual(data.data.alert); expect(notification.expiry).toEqual(Math.round(data['expiration_time'] / 1000)); expect(notification.collapseId).toEqual(data['collapse_id']); + expect(notification.pushType).toEqual(pushType); apnDevices = calledArgs[1]; expect(apnDevices.length).toBe(2); done(); diff --git a/src/APNS.js b/src/APNS.js index 0458f76..acd9937 100644 --- a/src/APNS.js +++ b/src/APNS.js @@ -73,6 +73,7 @@ export class APNS { let coreData = data.data; let expirationTime = data['expiration_time']; let collapseId = data['collapse_id']; + let pushType = data['push_type']; let priority = data['priority']; let allPromises = []; @@ -97,7 +98,7 @@ export class APNS { continue; } - let headers = { expirationTime: expirationTime, topic: appIdentifier, collapseId: collapseId, priority: priority } + let headers = { expirationTime: expirationTime, topic: appIdentifier, collapseId: collapseId, pushType: pushType, priority: priority } let notification = APNS._generateNotification(coreData, headers); const deviceIds = devices.map(device => device.deviceToken); let promise = this.sendThroughProvider(notification, deviceIds, providers); @@ -167,7 +168,7 @@ export class APNS { /** * Generate the apns Notification from the data we get from api request. * @param {Object} coreData The data field under api request body - * @param {Object} headers The header properties for the notification (topic, expirationTime, collapseId, priority) + * @param {Object} headers The header properties for the notification (topic, expirationTime, collapseId, pushType, priority) * @returns {Object} A apns Notification */ static _generateNotification(coreData, headers) { @@ -215,6 +216,11 @@ export class APNS { notification.topic = headers.topic; notification.expiry = Math.round(headers.expirationTime / 1000); notification.collapseId = headers.collapseId; + // set alert as default push type. If push type is not set notifications are not delivered to devices running iOS 13, watchOS 6 and later. + notification.pushType = 'alert'; + if (headers.pushType) { + notification.pushType = headers.pushType; + } if (headers.priority) { // if headers priority is not set 'node-apn' defaults it to 5 which is min. required value for background pushes to launch the app in background. notification.priority = headers.priority