diff --git a/.versions b/.versions
index 9931819..1250526 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.5
diff --git a/README.md b/README.md
index b39d150..b5941dd 100644
--- a/README.md
+++ b/README.md
@@ -1,142 +1,3 @@
-
-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.
diff --git a/lib/common/notifications.js b/lib/common/notifications.js
index 7f00e39..755034a 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,24 @@ 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);
+ return Push.serverSend(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.hasRegisteredToken = function(userId, appName) {
+ if (Meteor.isClient) {
+ throw new Error("Cannot call Push.hasRegisteredToken from the client.");
}
-};
-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]);
- }
- });
+ // 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;
+}
diff --git a/lib/server/push.api.js b/lib/server/push.api.js
index 6c512a2..d15103c 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;
@@ -341,32 +350,31 @@ 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) {
+ 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: [
@@ -377,13 +385,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
@@ -394,56 +402,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
-
};
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
diff --git a/package.js b/package.js
index 7a2c91e..5a30aff 100644
--- a/package.js
+++ b/package.js
@@ -1,6 +1,6 @@
Package.describe({
- name: 'raix:push',
- version: '2.6.0',
+ name: 'workpop:push',
+ version: '2.6.5',
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');
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 = {