From f1cb886f009030f76a758dca5402fe1da1ac9576 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Mon, 26 Jan 2015 16:09:57 -0800 Subject: [PATCH 01/16] change name to workpop:push --- package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.js b/package.js index 7a2c91e..85227fe 100644 --- a/package.js +++ b/package.js @@ -1,5 +1,5 @@ Package.describe({ - name: 'raix:push', + name: 'workpop:push', version: '2.6.0', summary: 'Isomorphic Push notifications for APN and GCM', git: 'https://github.com/raix/push.git' From 55778d5e205fe9036ac2794ecce5250b72e875fd Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Mon, 26 Jan 2015 16:10:38 -0800 Subject: [PATCH 02/16] add useRootJSONPayload option to not force ejson serialization of push body under 'ejson' key --- lib/server/push.api.js | 13 +++++++++++-- plugin/push.configuration.js | 4 +++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/server/push.api.js b/lib/server/push.api.js index 6c512a2..c30521e 100644 --- a/lib/server/push.api.js +++ b/lib/server/push.api.js @@ -130,8 +130,13 @@ Push.Configure = function(options) { if (typeof notification.sound !== 'undefined') note.sound = notification.sound; note.alert = notification.text; + // Allow the user to set payload data - note.payload = (notification.payload) ? { ejson: EJSON.stringify(notification.payload) } : {}; + if (options.useRootJSONPayload) { + note.payload = notification.payload ? notification.payload : {}; + } else { + note.payload = (notification.payload) ? { ejson: EJSON.stringify(notification.payload) } : {}; + } note.payload.messageFrom = notification.from; note.priority = priority; @@ -190,7 +195,11 @@ Push.Configure = function(options) { var Fiber = Npm.require('fibers'); // Allow user to set payload - var data = (notification.payload) ? { ejson: EJSON.stringify(notification.payload) } : {}; + if (options.useRootJSONPayload) { + var data = notification.payload ? notification.payload : {}; + } else { + var data = (notification.payload) ? { ejson: EJSON.stringify(notification.payload) } : {}; + } data.title = notification.title; data.message = notification.text; diff --git a/plugin/push.configuration.js b/plugin/push.configuration.js index b40682a..f9be6ef 100644 --- a/plugin/push.configuration.js +++ b/plugin/push.configuration.js @@ -24,7 +24,8 @@ var checkConfig = function(config) { alert: Match.Optional(Boolean), vibrate: Match.Optional(Boolean), // Support the old iframe Meteor cordova integration - iframe: Match.Optional(String) + iframe: Match.Optional(String), + useRootJSONPayload: Match.Optional(Boolean) }); // Make sure at least one service is configured? @@ -47,6 +48,7 @@ var cloneCommon = function(config, result) { clone('badge', config, result); clone('alert', config, result); clone('vibrate', config, result); + clone('useRootJSONPayload', config, result); }; var archConfig = { From 25baa84a8480d326e9f3dd818cdf1a9d0d30e8d2 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Mon, 26 Jan 2015 16:11:42 -0800 Subject: [PATCH 03/16] updated versions --- .versions | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.versions b/.versions index 9931819..b6681ae 100644 --- a/.versions +++ b/.versions @@ -2,8 +2,8 @@ application-configuration@1.0.4 base64@1.0.2 binary-heap@1.0.2 callback-hook@1.0.2 -check@1.0.3 -ddp@1.0.13 +check@1.0.4 +ddp@1.0.14 ejson@1.0.5 follower-livedata@1.0.3 geojson-utils@1.0.2 @@ -15,8 +15,8 @@ minimongo@1.0.6 mongo@1.0.11 ordered-dict@1.0.2 raix:eventemitter@0.1.1 -raix:push@2.5.1 random@1.0.2 retry@1.0.2 -tracker@1.0.4 +tracker@1.0.5 underscore@1.0.2 +workpop:push@2.6.0 From 96479d27ef1be4802ad0880ba3358ff7f8210606 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Wed, 28 Jan 2015 14:48:48 -0800 Subject: [PATCH 04/16] bump 2.6.1. Turning off build plugin, client must call Push.Configure() explicitly --- package.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/package.js b/package.js index 85227fe..c8b0178 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'workpop:push', - version: '2.6.0', + version: '2.6.1', summary: 'Isomorphic Push notifications for APN and GCM', git: 'https://github.com/raix/push.git' }); @@ -19,15 +19,16 @@ Cordova.depends({ //'com.phonegap.plugins.PushPlugin': 'http://github.com/rossmartin/PushPlugin/tarball/6cf2e1a107310e859839fb7a0dc2618a7a199430' }); -Package.registerBuildPlugin({ - name: 'configuration', - use: [ - 'check' - ], - sources: [ - 'plugin/push.configuration.js' - ] -}); +// TODO: turn this back on if we're actually using cordova in the future +//Package.registerBuildPlugin({ +// name: 'configuration', +// use: [ +// 'check' +// ], +// sources: [ +// 'plugin/push.configuration.js' +// ] +//}); Package.onUse(function(api) { api.versionsFrom('1.0'); From ec2f092b5a63aa52f715bba5f42254b6b6dcc991 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Wed, 28 Jan 2015 14:51:16 -0800 Subject: [PATCH 05/16] added released version --- .versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.versions b/.versions index b6681ae..37ef3eb 100644 --- a/.versions +++ b/.versions @@ -19,4 +19,4 @@ random@1.0.2 retry@1.0.2 tracker@1.0.5 underscore@1.0.2 -workpop:push@2.6.0 +workpop:push@2.6.1 From baa4a29cc9a36b945fdcc16a898bc456e2328d5c Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Thu, 29 Jan 2015 13:41:25 -0800 Subject: [PATCH 06/16] remove the queue so that we send push notifications in real time --- lib/common/notifications.js | 41 +++-------------- lib/server/push.api.js | 90 ++++++++++--------------------------- 2 files changed, 30 insertions(+), 101 deletions(-) diff --git a/lib/common/notifications.js b/lib/common/notifications.js index 7f00e39..d3d3870 100644 --- a/lib/common/notifications.js +++ b/lib/common/notifications.js @@ -1,6 +1,3 @@ -// Notifications collection -Push.notifications = new Mongo.Collection('_raix_push_notifications'); - // This is a general function to validate that the data added to notifications // is in the correct format. If not this function will throw errors var _validateDocument = function(notification) { @@ -30,12 +27,14 @@ var _validateDocument = function(notification) { }; Push.send = function(options) { - // If on the client we set the user id - on the server we need an option - // set or we default to "" as the creator of the notification + if (Meteor.isClient) { + throw new Error("Cannot call Push.send from client"); + } + + // We default to "" as the creator of the notification // If current user not set see if we can set it to the logged in user // this will only run on the client if Meteor.userId is available - var currentUser = Meteor.isClient && Meteor.userId && Meteor.userId() || - Meteor.isServer && (options.createdBy || '') || null; + var currentUser = (options.createdBy || '') || null; // Rig the notification object var notification = { @@ -67,31 +66,5 @@ Push.send = function(options) { _validateDocument(notification); // Try to add the notification to send, we return an id to keep track - return Push.notifications.insert(notification); -}; - -Push.allow = function(rules) { - if (rules.send) { - Push.notifications.allow({ - 'insert': function(userId, notification) { - // Validate the notification - _validateDocument(notification); - // Set the user defined "send" rules - return rules.send.apply(this, [userId, notification]); - } - }); - } -}; - -Push.deny = function(rules) { - if (rules.send) { - Push.notifications.deny({ - 'insert': function(userId, notification) { - // Validate the notification - _validateDocument(notification); - // Set the user defined "send" rules - return rules.send.apply(this, [userId, notification]); - } - }); - } + return Push.serverSend(notification); }; diff --git a/lib/server/push.api.js b/lib/server/push.api.js index c30521e..763a3d6 100644 --- a/lib/server/push.api.js +++ b/lib/server/push.api.js @@ -350,32 +350,32 @@ Push.Configure = function(options) { }; }; - self.serverSend = function(options) { - options = options || { badge: 0 }; - var query; - - // Check basic options - if (options.from !== ''+options.from) - throw new Error('Push.send: option "from" not a string'); - - if (options.title !== ''+options.title) - throw new Error('Push.send: option "title" not a string'); - - if (options.text !== ''+options.text) - throw new Error('Push.send: option "text" not a string'); + /** + * Sends the given push notification immediately. Sends to apple/google depending + * on the included token + * + * @param notification - {Object} The push notification object to send. + * @returns - {Object} - Send status containing number of apn/gcn sent. + */ + self.serverSend = function(notification) { + console.log('serverSend: ', notification); + if (!notification) { + return; + } - if (options.token || options.tokens) { + var query; - // The user set one token or array of tokens - var tokenList = (options.token)? [options.token] : options.tokens; + if (notification.token || notification.tokens) { + // if token is set wrap in array, otherwise use tokens array + var tokenList = (notification.token) ? [notification.token] : notification.tokens; - if (Push.debug) console.log('Push: Send message "' + options.title + '" via token(s)', tokenList); + if (Push.debug) console.log('Push: Send message "' + notification.title + '" via token(s)', tokenList); query = { $or: [ - // XXX: Test this query: can we hand in a list of push tokens? + // TODO: Test this query: can we hand in a list of push tokens? { token: { $in: tokenList } }, - // XXX: Test this query: does this work on app id? + // TODO: Test this query: does this work on app id? { $and: [ { _in: { $in: tokenList } }, // one of the app ids { $or: [ @@ -386,13 +386,13 @@ Push.Configure = function(options) { ] }; - } else if (options.query) { + } else if (notification.query) { - if (Push.debug) console.log('Push: Send message "' + options.title + '" via query', options.query); + if (Push.debug) console.log('Push: Send message "' + notification.title + '" via query', notification.query); query = { $and: [ - options.query, // query object + notification.query, // query object { $or: [ { 'token.apn': { $exists: true } }, // got apn token { 'token.gcm': { $exists: true } } // got gcm token @@ -403,56 +403,12 @@ Push.Configure = function(options) { if (query) { - // Convert to querySend and return status - return _querySend(query, options) - + return _querySend(query, notification) } else { throw new Error('Push.send: please set option "token"/"tokens" or "query"'); } }; - var isSendingNotification = false; - - Meteor.setInterval(function() { - - if (!isSendingNotification) { - // Set send fence - isSendingNotification = true; - - // Find one notification - var notification = Push.notifications.findOne({ sent : { $ne: true } }, { sort: { createdAt: 1 } }); - - // Check if we got any notifications to send - if (notification) { - - // Send the notification - var result = Push.serverSend(notification); - - if (!options.keepNotifications) { - // Pr. Default we will remove notifications - Push.notifications.remove({ _id: notification._id }); - } else { - - // Update the notification - Push.notifications.update({ _id: notification._id }, { - $set: { - sent: true, - sentAt: new Date(), - count: result - } - }); - - } - - // Emit the send - self.emit('send', { notification: notification._id, result: result }); - } - - // Remove the send fence - isSendingNotification = false; - } - }, options.sendInterval || 15000); // Default every 15'the sec - }; From 2862fa1918bbc41d58e532490256d3ae5b32673b Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Thu, 29 Jan 2015 13:42:09 -0800 Subject: [PATCH 07/16] bump version to 2.6.2 --- package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.js b/package.js index c8b0178..b673c01 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'workpop:push', - version: '2.6.1', + version: '2.6.2', summary: 'Isomorphic Push notifications for APN and GCM', git: 'https://github.com/raix/push.git' }); From 173fbdf4e77e8067aed5912160735dcf43b60a6c Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Thu, 29 Jan 2015 13:43:14 -0800 Subject: [PATCH 08/16] update .versions file --- .versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.versions b/.versions index 37ef3eb..bf51539 100644 --- a/.versions +++ b/.versions @@ -19,4 +19,4 @@ random@1.0.2 retry@1.0.2 tracker@1.0.5 underscore@1.0.2 -workpop:push@2.6.1 +workpop:push@2.6.2 From 06ca35de9fd4ab6383267e71295220e39ebdec9a Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Thu, 29 Jan 2015 13:47:40 -0800 Subject: [PATCH 09/16] remove console.log --- lib/server/push.api.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/server/push.api.js b/lib/server/push.api.js index 763a3d6..d15103c 100644 --- a/lib/server/push.api.js +++ b/lib/server/push.api.js @@ -358,7 +358,6 @@ Push.Configure = function(options) { * @returns - {Object} - Send status containing number of apn/gcn sent. */ self.serverSend = function(notification) { - console.log('serverSend: ', notification); if (!notification) { return; } From 064677e6ff0da9bfa7c830b6ec2987176198ccb5 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Thu, 29 Jan 2015 13:48:06 -0800 Subject: [PATCH 10/16] bump version --- package.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.js b/package.js index b673c01..8019c67 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'workpop:push', - version: '2.6.2', + version: '2.6.3', summary: 'Isomorphic Push notifications for APN and GCM', git: 'https://github.com/raix/push.git' }); From 432ea648215018a3d1de3e6545c136b5465c0199 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Wed, 4 Feb 2015 15:52:26 -0800 Subject: [PATCH 11/16] update .versions file --- .versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.versions b/.versions index bf51539..66b2314 100644 --- a/.versions +++ b/.versions @@ -19,4 +19,4 @@ random@1.0.2 retry@1.0.2 tracker@1.0.5 underscore@1.0.2 -workpop:push@2.6.2 +workpop:push@2.6.3 From 527df00451f896ca686fe85d85ac13bb6a12b38d Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Wed, 4 Feb 2015 15:53:32 -0800 Subject: [PATCH 12/16] add hasRegisteredToken utility function to server API --- lib/common/notifications.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/common/notifications.js b/lib/common/notifications.js index d3d3870..755034a 100644 --- a/lib/common/notifications.js +++ b/lib/common/notifications.js @@ -68,3 +68,22 @@ Push.send = function(options) { // Try to add the notification to send, we return an id to keep track return Push.serverSend(notification); }; + +Push.hasRegisteredToken = function(userId, appName) { + if (Meteor.isClient) { + throw new Error("Cannot call Push.hasRegisteredToken from the client."); + } + + // basic query will check userId has existing token field + var query = { + userId: userId, + token: { $exists: true } + }; + + // add appName to query if it was included + if (appName) { + query.appName = appName; + } + + return Push.appCollection.find(query).count() > 0; +} From 17e008a5a8b8a4b3ba9259ec4d33c9dd08fa31b6 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Wed, 4 Feb 2015 15:55:16 -0800 Subject: [PATCH 13/16] upgrade version to 2.6.4 --- .versions | 2 +- package.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.versions b/.versions index 66b2314..9075391 100644 --- a/.versions +++ b/.versions @@ -19,4 +19,4 @@ random@1.0.2 retry@1.0.2 tracker@1.0.5 underscore@1.0.2 -workpop:push@2.6.3 +workpop:push@2.6.4 diff --git a/package.js b/package.js index 8019c67..5659f76 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'workpop:push', - version: '2.6.3', + version: '2.6.4', summary: 'Isomorphic Push notifications for APN and GCM', git: 'https://github.com/raix/push.git' }); From 7536ffe9e0ae3cc107a91e5cb8cd2311809b99d3 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Wed, 8 Apr 2015 11:37:23 -0700 Subject: [PATCH 14/16] remove 404 when a non-existent id is sent from client. Can get into this case indefinitely if a user is logged out for some reason without going through proper logout on iOS --- lib/server/server.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/server/server.js b/lib/server/server.js index 8a7bce6..fe9c568 100644 --- a/lib/server/server.js +++ b/lib/server/server.js @@ -31,10 +31,6 @@ Meteor.methods({ // lookup app by id if one was included if (options.id) { doc = Push.appCollection.findOne({ _id: options.id }); - - if (!doc) { - throw new Meteor.Error(404, 'raix:push-update could not find the record specified by ID'); - } } // No id was sent by the client - we check the database to see if From 1b8d17252429a1381a8ec58e761564f8d080f43a Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Thu, 9 Apr 2015 19:07:28 -0700 Subject: [PATCH 15/16] upgrade to 2.6.5 --- .versions | 2 +- package.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.versions b/.versions index 9075391..1250526 100644 --- a/.versions +++ b/.versions @@ -19,4 +19,4 @@ random@1.0.2 retry@1.0.2 tracker@1.0.5 underscore@1.0.2 -workpop:push@2.6.4 +workpop:push@2.6.5 diff --git a/package.js b/package.js index 5659f76..5a30aff 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'workpop:push', - version: '2.6.4', + version: '2.6.5', summary: 'Isomorphic Push notifications for APN and GCM', git: 'https://github.com/raix/push.git' }); From af047218a80ab1edefd4f1a9978b68111fdff087 Mon Sep 17 00:00:00 2001 From: Alex Corre Date: Mon, 20 Apr 2015 12:48:20 -0700 Subject: [PATCH 16/16] add maintenance notice to readme --- README.md | 143 +----------------------------------------------------- 1 file changed, 2 insertions(+), 141 deletions(-) diff --git a/README.md b/README.md index b39d150..b5941dd 100644 --- a/README.md +++ b/README.md @@ -1,142 +1,3 @@ -Gi-SoftWare -raix:push Push notifications -========= +# THIS FORK IS NO LONGER BEING MAINTAINED. -> Push notifications for cordova (ios, android) browser (Chrome, Safari, Firefox) - One unified api on client and server. - -Status: -* [x] APN iOS -* [x] GCM Android -* [x] APN Safari web push (partially implemented) -* [x] GCM Chrome OS (partially implemented) -* [x] Firefox OS (partially implemented) -* [ ] BPS Blackberry 10 -* [ ] MPNS Windows phone 8 -* [ ] MPNS Windows 8 -* [ ] ADM Amazon Fire OS -* [ ] Meteor in app notifications - -## Getting started -Depending on the platforms you want to work with you will need some credentials or certificates. -* [Android](docs/ANDROID.md) -* [iOS](docs/IOS.md) - -Have a look at the [Basic example](docs/BASIC.md) - -## Config -Add a `config.push.json` file in your project and configure credentials / keys / certificates: - -```js -{ - "apn": { - "passphrase": "xxxxxxxxx", - "key": "apnProdKey.pem", - "cert": "apnProdCert.pem" - }, - "gcm": { - "apiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - "projectNumber": xxxxxxxxxxxx - }, - "production": true, - // "badge": true, - // "sound": true, - // "alert": true, - // "vibrate": true -} -``` - -## Common api -```js - // Push.debug = true; // Add verbosity - - Push.send({ - from: 'push', - title: 'Hello', - text: 'world', - query: { - // Ex. send to a specific user if using accounts: - userId: 'xxxxxxxxx' - } // Query the appCollection - // token: appId or token eg. "{ apn: token }" - // tokens: array of appId's or tokens - // payload: user data - }); -``` -*When in secure mode the client send features require adding allow/deny rules in order to allow the user to send push messages to other users directly from the client - Read more below* - -## Client api -```js - Push.id(); // Unified application id - not a token - Push.setBadge(count); // ios specific - ignored everywhere else -``` - -## Security allow/deny send -This package allows you to send notifications from the server and client. To restrict the client or allowing the client to send use `allow` or `deny` rules. - -When a client calls send on Push, the Push's allow and deny callbacks are called on the server to determine if the send should be allowed. If at least one allow callback allows the send, and no deny callbacks deny the send, then the send is allowed to proceed. - -```js - Push.allow({ - send: function(userId, notification) { - return true; // Allow all users to send - } - }); - - // Or... - Push.deny({ - send: function(userId, notification) { - return false; // Allow all users to send - } - }); -``` - -## Meteor Methods - -### raix:push-update - -Stores a token associated with an application and optionally, a userId. - -**Parameters**: - -*options* - An object containing the necessary data to store a token. Fields: -* `id` - String (optional) - a record id for the Application/Token document to update. If this does not exist, will return 404. -* `token` - Object - `{ apn: 'TOKEN' }` or `{ gcm: 'TOKEN' }` -* `appName` - String - the name of the application to associate the token with -* `userId` - String (optional) - the user id so associate with the token and application. If none is included no user will be associated. Use `raix:push-setuser` to later associate a userId with a token. - -**Returns**: - -*recordId* - The id of the stored document associating appName, token, and optionally user in an object of the form: - -``` -{ - result: 'recordId' -} -``` - -### raix:push-setuser - -Associates the current users ID with an Application/Token record based on the given id. - -**Parameters**: - -*id* - String - The ID of the Application/Token record - -### raix:push-metadata - -Adds metadata to a particular Application/Token record. - -**Parameters** - -*data* - Object containing the following fields: -* `id` - String - the ID of the Application/Token record to update -* `metadata` - Object - The metadata object to add to the Application/Token document - -## More Info - - -For more internal or advanced features read [ADVANCED.md](docs/ADVANCED.md) - -Kind regards - -Morten (aka RaiX) +> Head on over to the original [raix/push](http://github.com/raix/push) for updates.