New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

apnagent

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apnagent - npm Package Compare versions

Comparing version 0.3.1 to 0.4.0

lib/apnagent/cache.js

48

History.md
0.4.0 / 2013-02-15
==================
* example: [error.mitigation] remove trim for device
* device: improve string regexp to remove all non-alphanumeric
* message: [alert] if only key, set as body
* message: [device] allow device constructor as set
* agent: [close] refactor to wait for queue to finish current
* pgk: update breeze-queue to 0.4.x
* message: [expires] do unix calculation on set, no serialize
* Merge branch 'feature/cache'
* agent: [mock] fix reference errors
* examples: [error.mitigation] refactor to handle different situations
* agent: [all] implement cache mechanism
* test: [cache] increase fuzziness of timing
* message: [device] if no args, return device
* code: [gateway response] change status to code.
* errors: add GatewayNotificationError for apn response errors
* test: [cache] increase test delays for more leighway
* codecs: [gateway.response] add gateway response codec
* cache: store settings on self
* pgk: [breeze-queue] update to 0.3.x
* test: resume running all tests
* test: [cache] add tests for cache constructor
* cache: add the cache constructor
* examples: [basic] load key from certs folder
* agent: [live] remove extraneous console logs"
* message: fix bug preventing 0 expires to proceed
* Merge branch 'refactor/defaultEnhanced'
* makefile: turn live tests off by default
* test: refactor tests for default enhanced codec
* message/agent: [codec] make enhanced the default codec
* test: better naming structure
* test: [message] increase setters test coverage
* message: clean up setters
* docs: note that ios project can be used with tests
* makefile: allow for custom timeouts
* Merge branch 'feature/expires'
* test: [message] add exiration tests
* message: add support for expiration, enabling enhanced codec
* dpes: add tea-ms
* Merge branch 'feature/device'
* test: [message] refactor to use Device constructor
* message: refactor to use Device constructor
* test: [device] add device tests
* device: add device constructor
* deps: update lotus to 0.4.x
0.3.1 / 2013-01-27

@@ -3,0 +51,0 @@ ==================

12

lib/apnagent.js
/*!
* apnagent - Message Constructor
* Copyright(c) 2012 Jake Luer <jake@alogicalparadox.com>
* apnagent
* Copyright(c) 2012-2013 Jake Luer <jake@alogicalparadox.com>
* MIT Licensed

@@ -11,3 +11,3 @@ */

exports.version = '0.3.1';
exports.version = '0.4.0';

@@ -27,2 +27,8 @@ /*!

/*!
* Device
*/
exports.Device = require('./apnagent/device');
/*!
* Errors

@@ -29,0 +35,0 @@ */

@@ -22,3 +22,4 @@ /*!

var codecs = require('../codecs')
var Cache = require('../cache')
, codecs = require('../codecs')
, errors = require('../errors')

@@ -28,2 +29,23 @@ , Message = require('../message');

/*!
* Constants
*/
// max unique ids
var INT32 = 0xffffffff;
// Apple notification error messages
var notifErrors = {
0: 'No errors encountered'
, 1: 'Processing error'
, 2: 'Missing device token'
, 3: 'Missing topic'
, 4: 'Missing payload'
, 5: 'Invalid token size'
, 6: 'Invalid topic size'
, 7: 'Invalid payload size'
, 8: 'Invalid token'
, 255: 'None (unknown)'
};
/*!
* Primary Export

@@ -41,23 +63,29 @@ */

function Base () {
var self = this
, outgoing, queue;
EventEmitter.call(this, { delimeter: ':' });
// configuration
this.connected = false;
this.gatewayOpts = null;
this.gatewayError = null;
this.lastId = -1;
this.disable('sandbox');
this.set('codec', 'simple');
this.set('cache ttl', '10m');
this.set('codec', 'enhanced');
this.set('expires', 0);
this.enable('reconnect');
this.set('reconnect delay', 3000);
this.disable('sandbox');
var self = this
, cache, decoder, encoder, queue;
// temp storage for messages
cache = new Cache();
// queue handles writing buffers to gateway
queue = new Queue(this.queueIterator.bind(this), 1);
queue = new Queue(function () {
debug('(queue) iterate');
self._queueIterator.apply(self, arguments);
}, 1);
// emit queue errors on agent
queue.onerror = function (err) {
debug('queue error: %s', err.message);
self.emit([ 'queue', 'error' ], err);
debug('(queue) error: %s', err.message);
self.emit('queue:error', err);
};

@@ -67,19 +95,38 @@

queue.drain = function () {
debug('queue has been drained');
self.emit([ 'queue', 'drain' ]);
debug('(queue) drain');
self.emit('queue:drain');
};
// outgoing handles converting msg json to buffers
outgoing = lotus.createWriterStream();
outgoing.use(0, codecs.getInterface('gateway simple', 'writer'));
outgoing.use(1, codecs.getInterface('gateway enhanced', 'writer'));
outgoing.on('data', function (buf) {
debug('pushing message to send queue');
self.queue.push(buf, self.connected);
// decoder handles incoming apn errors
decoder = lotus.createReaderStream();
decoder.use(8, codecs.getInterface('gateway response', 'reader'));
decoder.on('data', function (obj) {
obj.code = obj.code[0];
var message = notifErrors[obj.code] || 'None (unknown)'
, err = new errors.GatewayNotificationError(message, obj)
, cached = self.cache.get(obj.identifier)
, msg = null;
if (cached) {
msg = new Message(self, 'enhanced', cached.json.payload);
msg.device(cached.json.deviceToken);
msg.meta.expires = cached.json.expiration;
}
debug('(notification) error: %s', err.message);
self.gatewayError = err;
self.emit('notification:error', err, msg);
});
// encoder handles converting msg json to buffers
encoder = lotus.createWriterStream();
encoder.use(0, codecs.getInterface('gateway simple', 'writer'));
encoder.use(1, codecs.getInterface('gateway enhanced', 'writer'));
// mount objects
this.outgoing = outgoing;
this.cache = cache;
this.decoder = decoder;
this.encoder = encoder;
this.gateway = null;
this.queue = queue;
this.gateway = null;
}

@@ -105,4 +152,4 @@

*
* @param {String} encoding (default: utf8)
* @param {String} codec (simple or enhanced)
* @param {String} encoding (default: utf8)
* @name create

@@ -112,5 +159,5 @@ * @api public

Base.prototype.createMessage = function (codec, enc) {
Base.prototype.createMessage = function (enc, codec) {
codec = codec || this.get('codec');
return new Message(this, codec, enc);
return new Message(this, codec, { enc: enc });
};

@@ -136,3 +183,3 @@

if (i > 4294967296) {
if (i > INT32) {
i = this.lastId = 0;

@@ -167,4 +214,5 @@ }

process.nextTick(function () {
debug('serialize message failed: %s', err.message);
debug('(message) error: %s', err.message);
cb(err);
self.emit('notification:error', err, msg);
});

@@ -175,3 +223,3 @@ }

if (!~[ 0, 1 ].indexOf(codec)) {
error(new errors.SerializationError('Invalid codec: ' + codecStr, null, arguments.callee));
error(new errors.SerializationError('Invalid codec: ' + codecStr));
return this;

@@ -188,9 +236,5 @@ }

// write json to outgoing codec stream
process.nextTick(function () {
debug('writing message to codec');
self.outgoing.write(codec, json);
cb();
});
// write json to to the queue
debug('(queue) push: %d', json.identifier);
self.queue.push({ codec: codec, json: json }, cb);
return this;

@@ -206,3 +250,3 @@ };

var err = new Error('Gateway connect not implemented.');
this.emit([ 'gateway', 'error' ], err);
this.emit('gateway:error', err);
cb(err);

@@ -209,0 +253,0 @@ };

@@ -13,2 +13,3 @@ /*!

, inherits = require('tea-inherits')
, ms = require('tea-ms')
, tls = require('tls');

@@ -69,3 +70,6 @@

var self = this
, delay = this.get('reconnect delay')
, opts = util.gatewayOptions(this)
, recon = this.enabled('reconnect')
, ttl = this.get('cache ttl')
, gateway;

@@ -75,7 +79,6 @@

if (!opts.pfx && !opts.key && !opts.cert) {
console.log(opts);
process.nextTick(function () {
var err = new errors.GatewayAuthorizationError('Insufficient credentials');
debug('gateway error: insufficient credentials');
self.emit([ 'gateway', 'error' ], err);
debug('(gateway) error: %s', err.message);
self.emit('gateway:error', err);
cb(err);

@@ -87,18 +90,42 @@ });

debug('gateway initializing connection to %s:%d', opts.host, opts.port);
this.gatewayOpts = opts;
// how to perform a reconnect
function reconnect () {
var gwe = self.gatewayError
, pos = 0;
// connect to tls service using opts
if (gwe && 'undefined' !== typeof gwe.identifier) {
debug('(cache) since: %d', gwe.identifier);
self.cache.sinceId(gwe.identifier, function (obj, id) {
debug('(queue) push: %d', id);
self.queue.pushAt(pos++, obj);
});
}
debug('(gateway) reconnecting');
self.connect(function (err) {
if (err) return;
debug('(gateway) reconnected');
self.emit('gateway:reconnect');
});
}
// reset state
this.gatewayError = null;
// connect to gateway
debug('(gateway) connecting - %s:%d', opts.host, opts.port);
gateway = tls.connect(opts, function () {
if (gateway.authorized) {
debug('gateway connection established to %s:%d', opts.host, opts.port);
debug('(gateway) connected - %s:%d', opts.host, opts.port);
self.connected = true;
self.cache.ttl = ttl;
self.cache.resume();
self.queue.resume();
self.emit([ 'gateway', 'connect' ], opts.host, opts.port);
self.emit('gateway:connect');
cb();
} else {
var err = new errors.GatewayAuthorizationError(gateway.authorizationError);
debug('gateway connection denied to %s:%d', opts.host, opts.port, gateway.authorizationError);
debug('(gateway) unauthorized - %s:%d', opts.host, opts.port, gateway.authorizationError);
self.gateway.destroy();
self.emit([ 'gateway', 'error' ], err);
self.emit('gateway:error', err);
cb(err);

@@ -110,27 +137,21 @@ }

gateway.on('close', function () {
self.cache.pause();
self.queue.pause();
self.gatewayOpts = null;
self.gateway = null;
// if user DID trigger disconnect or reconnect disabled
if (!self.connected || !self.enabled('reconnect')) {
debug('gateway connection closed to %s:%d', opts.host, opts.port);
self.emit([ 'gateway', 'close' ]);
if (self.connected && recon) {
debug('(gateway) disconnected - %s:%d', opts.host, opts.port);
self.connected = false;
setTimeout(reconnect, ms(delay));
} else {
debug('(gateway) closed - %s:%d', opts.host, opts.port);
self.connected = false;
self.emit('gateway:close');
}
});
// if user DID NOT trigger disconnect
else if (self.connected && self.enabled('reconnect')) {
debug('gateway connection unexpectedly closed to %s:%d', opts.host, opts.port);
setTimeout(function () {
debug('gateway triggering reconnect');
self.connect(function () {
var host = self.gatewayOpts.host
, port = self.gatewayOpts.port;
debug('gateway reconnected successful to %s:%d', host, port);
self.emit([ 'gateway', 'reconnect' ], host, port);
});
}, self.get('reconnect delay'));
}
self.connected = false;
// handle incoming data
gateway.on('data', function (buf) {
debug('(gateway) data: %d bytes', buf.length);
self.decoder.write(buf);
});

@@ -140,4 +161,4 @@

gateway.on('error', function (err) {
debug('gateway socket error: %s', err.message || 'Unspecified Error');
self.emit([ 'gateway', 'error' ], err);
debug('(gateway) error: %s', err.message || 'Unspecified Error');
self.emit('gateway:error', err);
});

@@ -147,2 +168,3 @@

this.gateway = gateway;
return this;
};

@@ -159,25 +181,56 @@

Agent.prototype.close = function () {
if (!this.connected) return;
var host = this.gatewayOpts.host
, port = this.gatewayOpts.port;
debug('closing gateway connection to %s:%d', host, port);
Agent.prototype.close = function (cb) {
cb = cb || function () {};
// leave if nothing needs to be done
if (!this.connected) {
process.nextTick(cb);
return this;
}
var self = this
, drain = this.queue.drain;
// wait for queue to finish processing current
this.queue.drain = function () {
debug('(gateway) disconnecting');
self.cache.pause();
self.gateway.once('close', cb);
self.gateway.destroy();
self.queue.drain = drain;
};
// set things in motion
this.connected = false;
this.queue.pause();
this.gateway.destroy();
return this;
};
Agent.prototype.queueIterator = function (buf, next) {
Agent.prototype._queueIterator = function (obj, next) {
// requeue if not connected
if (!this.gateway || !this.connected) {
debug('socket write queue pausing self');
this.queue.pause()
this.queue.push(buf);
debug('(queue) pause: not connected');
this.queue.pause();
this.queue.pushAt(0, obj);
return next();
}
debug('writing message to socket');
this.gateway.write(buf, function () {
debug('writing message success');
next();
var cache = this.cache
, encoder = this.encoder
, gateway = this.gateway
, id = obj.json.identifier;
// wait for encoded message
encoder.once('data', function (buf) {
debug('(gateway) write: %d', id);
gateway.write(buf, function () {
debug('(cache) push: %d', id);
cache.push(id, obj);
next();
});
});
// encode message
debug('(encoder) write: %d', id);
encoder.write(obj.codec, obj.json);
};

@@ -13,2 +13,3 @@ /*!

, inherits = require('tea-inherits')
, ms = require('tea-ms')
, lotus = require('lotus');

@@ -70,8 +71,32 @@

var self = this
, delay = this.get('reconnect delay')
, opts = util.gatewayOptions(this)
, recon = this.enabled('reconnect')
, ttl = this.get('cache ttl')
, gateway;
debug('mock gateway initializing');
this.gatewayOpts = opts;
// how to perform a reconnect
function reconnect () {
var gwe = self.gatewayError
, pos = 0;
if (gwe && 'undefined' !== typeof gwe.identifier) {
debug('(cache) since: %d', gwe.identifier);
self.cache.sinceId(gwe.identifier, function (obj, id) {
debug('(queue) push: %d', id);
self.queue.pushAt(pos++, obj);
});
}
debug('(gateway) reconnecting');
self.connect(function (err) {
if (err) return;
debug('(gateway) reconnected');
self.emit('gateway:reconnect');
});
}
// reset state
this.gatewayError = null;
// mock gateway parses the outgoing buffers back to json

@@ -82,6 +107,18 @@ gateway = lotus.createReaderStream();

// simulate async connect
debug('(gateway) connecting - mock');
process.nextTick(function () {
debug('(gateway) connected - mock');
self.connected = true;
self.cache.ttl = ttl;
self.cache.resume();
self.queue.resume();
self.emit('gateway:connect');
cb();
});
// data event is emitted for each message
gateway.on('data', function (json) {
debug('mock gateway incoming message', json);
self.emit([ 'mock', 'message' ], json);
debug('(gateway) incoming message', json);
self.emit('mock:message', json);
});

@@ -91,4 +128,4 @@

gateway.on('error', function (err) {
debug('mock gateway "socket" error: %s', err.message || 'Unspecified Error');
self.emit([ 'gateway', 'error' ], err);
debug('(gateway) error: %s', err.message || 'Unspecified Error');
self.emit('gateway:error', err);
});

@@ -98,38 +135,20 @@

gateway.on('end', function () {
self.cache.pause();
self.queue.pause();
self.gatewayOpts = null;
self.gateway = null;
// if user DID trigger disconnect or reconnect disabled
if (!self.connected || !self.enabled('reconnect')) {
debug('mock gateway connection closed');
self.emit([ 'gateway', 'close' ]);
if (self.connected && recon) {
debug('(gateway) disconnected - mock');
self.connected = false;
setTimeout(reconnect, ms(delay));
} else {
debug('(gateway) closed - mock');
self.connected = false;
self.emit('gateway:close');
}
// if user DID NOT trigger disconnect
else if (self.connected && self.enabled('reconnect')) {
debug('mock gateway connection unexpectedly closed');
setTimeout(function () {
debug('mock gateway triggering reconnect');
self.connect(function () {
debug('mock gateway reconnected successful');
self.emit([ 'gateway', 'reconnect' ], null, null);
});
}, self.get('reconnect delay'));
}
self.connected = false;
});
// simulate async connect
process.nextTick(function () {
debug('mock gateway connection established');
self.connected = true;
self.queue.resume();
self.emit([ 'gateway', 'connect' ], null, null);
cb();
});
// mount
this.gateway = gateway;
return this;
};

@@ -146,21 +165,57 @@

Mock.prototype.close = function () {
debug('closing mock gateway connection');
Mock.prototype.close = function (cb) {
cb = cb || function () {};
// leave if nothing needs to be done
if (!this.connected) {
process.nextTick(cb);
return this;
}
var self = this
, drain = this.queue.drain;
// wait for queue to finish processing current
this.queue.drain = function () {
debug('(gateway) disconnecting');
self.cache.pause();
process.nextTick(cb);
self.gateway.end();
self.queue.drain = drain;
};
// set things in motion
this.connected = false;
this.queue.pause();
this.gateway.end();
return this;
};
Mock.prototype.queueIterator = function (buf, next) {
Mock.prototype._queueIterator = function (obj, next) {
// requeue if not connected
if (!this.gateway || !this.connected) {
debug('mock write queue pausing self');
this.queue.pause()
this.queue.push(buf);
debug('(queue) pause: not connected');
this.queue.pause();
this.queue.pushAt(0, obj);
return next();
}
debug('writing message to mock gateway');
this.gateway.write(buf);
debug('writing message success');
process.nextTick(next); // make async
var cache = this.cache
, encoder = this.encoder
, gateway = this.gateway
, id = obj.json.identifier;
// wait for encoded message
encoder.once('data', function (buf) {
debug('(gateway) write: %d', id);
gateway.write(buf);
process.nextTick(function () {
debug('(cache) push: %d', id);
cache.push(id, obj);
next();
});
});
// encode message
debug('(encoder) write: %d', id);
encoder.write(obj.codec, obj.json);
};

@@ -67,3 +67,3 @@ /*!

, id: 0
, mod: require('./simple')
, mod: require('./gateway.simple')
});

@@ -78,3 +78,13 @@

, id: 1
, mod: require('./enhanced')
, mod: require('./gateway.enhanced')
});
/*!
* Push `enhanced` gateway codec
*/
codecs.push({
name: 'gateway response'
, id: 8
, mod: require('./gateway.response')
});

@@ -19,2 +19,3 @@ /*!

'GatewayAuthorizationError'
, 'GatewayNotificationError'
, 'SerializationError'

@@ -21,0 +22,0 @@ ];

@@ -11,3 +11,4 @@ /*!

var extend = require('tea-extend');
var extend = require('tea-extend')
, ms = require('tea-ms');

@@ -18,3 +19,4 @@ /*!

var errors = require('./errors')
var Device = require('./device')
, errors = require('./errors')
, util = require('./util');

@@ -41,22 +43,44 @@

function Message (agent, codec, enc) {
function Message (agent, codec, opts) {
this._agent = agent;
this.encoding = enc || 'utf8';
this.meta = {
codec: codec
, identifier: this._agent
? this._agent.nextId()
: 0
};
this.encoding = 'utf8';
this.meta = {};
this.meta.codec = codec;
this.meta.device = new Device();
this.meta.expires = null;
this.settings = {};
this.payload = {};
this.aps = {};
}
Object.defineProperty(Message.prototype, 'id', {
get: function () {
return this.meta.identifier;
opts = opts || {};
// import custom encoding
if (opts.enc) this.encoding = opts.enc;
// import custom variables
for (var name in opts) {
if (name === 'aps' || name === 'enc') continue;
this.set(name, opts[name]);
}
if (opts.aps) {
// import badge/sound
if (opts.aps.badge) this.badge(opts.aps.badge);
if (opts.aps.sound) this.sound(opts.aps.sound);
// import alert
if (opts.aps.alert && 'string' === typeof opts.aps.alert) {
this.alert('body', opts.aps.alert);
} else if (opts.aps.alert) {
this.alert(opts.aps.alert);
}
});
}
if (agent && 'simple' !== codec) {
this.expires(agent.get('expires'));
}
}
/**

@@ -80,10 +104,9 @@ * .set (key, value)

Message.prototype.set = function (key, value) {
if ('string' == typeof key) {
if ('object' === typeof key) {
for (var name in key) {
this.set(name, key[name]);
}
} else {
if (key === 'aps') return;
this.payload[key] = value;
} else {
for (name in key) {
if (name === 'aps') continue;
this.payload[name] = key[name];
}
}

@@ -103,2 +126,9 @@

*
* Allowed keys:
* - `body`
* - `action-loc-key'
* - `log-key`
* - `loc-args`
* - `launch-image`
*
* @param {String|Object}

@@ -119,10 +149,11 @@ * @param {Mixed} value

if ('string' == typeof key) {
if ('object' === typeof key) {
for (var name in key) {
this.alert(name, key[name]);
}
} else if (arguments.length === 1) {
this.aps['body'] = key;
} else {
if (!~allowed.indexOf(key)) return this;
this.aps[key] = value;
} else {
for (var name in key) {
if (!~allowed.indexOf(name)) continue;
this.aps[name] = key[name];
}
}

@@ -147,7 +178,10 @@

Message.prototype.device = function (device) {
if ('string' === typeof device) {
device = new Buffer(device.replace(/\s/g, ''), 'hex');
if (!arguments.length) {
return this.meta.device;
} else if (device instanceof Device) {
this.meta.device = device;
} else {
this.meta.device.token = device;
}
this.meta.device = device;
return this;

@@ -157,22 +191,4 @@ };

/**
* .codec (name)
* .expires (time)
*
* Overwrite the default codec to be used when
* encoding for transfer.
*
* @param {String} codec name
* @returns {this} for chaining
* @api public
*/
Message.prototype.codec = function (name) {
this.meta.codec = name;
return this;
};
/**
* .id (id)
*
* > NOTE: not currently implemented
*
* Set the message expiration date when being used

@@ -184,3 +200,3 @@ * with the enhanced codec. If you are composing a

* Should be provided as the number of ms until expiration
* or as a string that can be converded, such as `1d`.
* or as a string that can be converted, such as `1d`.
*

@@ -195,3 +211,17 @@ * See APNS documentation for more information.

Message.prototype.expires = function (time) {
//TODO: implement this
if ('number' === typeof time) {
this.meta.expires = time === 0 ? time : ms.unix(time);
this.meta.codec = 'enhanced';
} else if (true === time) {
this.meta.expires = 0;
this.meta.codec = 'enhanced';
} else if (!time) {
this.meta.expires = null;
this.meta.codec = 'simple'
} else {
this.meta.expires = ms.unix(time);
this.meta.codec = 'enhanced';
}
return this;
};

@@ -247,3 +277,4 @@

Message.prototype.serialize = function () {
var enc = this.encoding
var codec = this.meta.codec
, enc = this.encoding
, payload = {}

@@ -253,5 +284,21 @@ , SE = errors.SerializationError

// check for device
if (!this.meta.device.toBuffer()) {
throw new SE('Message device not specified.', null, ssf);
}
// enhanced codec requires expiration
if ('enhanced' === codec && null === this.meta.expires) {
throw new SE('Message expiration not specified for enhanced codec delivery.', null, ssf);
}
// enchanced code requires agent to generate an id
if ('enhanced' === codec && !this._agent) {
throw new SE('Message agent not specified for enhanced codec delivery.', null, ssf);
}
// copy over extra variables
extend(payload, this.payload);
// set encoding if not utf8
if (enc !== 'utf8') {

@@ -273,2 +320,3 @@ payload.enc = this.encoding;

// check to ensure body is not to long, shorten if possible
var str = JSON.stringify(payload)

@@ -297,52 +345,14 @@ , len = Buffer.byteLength(str, enc);

if (!this.meta.device) {
throw new SE('Device must be specified', null, ssf);
}
return {
deviceToken: this.meta.device
, identifier: this.id
, payload: payload
};
// construct the response
var res = {};
res.deviceToken = this.meta.device.toBuffer();
res.expiration = this.meta.expires
res.identifier = this._agent
? this._agent.nextId()
: null;
res.payload = payload;
return res;
};
/**
* .import (json)
*
* Import a compatible payload into this message.
* If the message already has variables defined, they
* may be overwritten or merged with incoming values.
* Suggested use is only with an empty message.
*
* @param {Object} json payload
* @api public
*/
Message.prototype.import = function (json) {
// import custom encoding
if (json.enc) this.encoding = json.enc;
// import custom variables
for (var name in json) {
if (name === 'aps' || name === 'enc') continue;
this.set(name, json[name]);
}
if (json.aps) {
// import badge/sound
if (json.aps.badge) this.badge(json.aps.badge);
if (json.aps.sound) this.sound(json.aps.sound);
// import alert
if (json.aps.alert && 'string' === typeof json.aps.alert) {
this.alert('body', json.aps.alert);
} else if (json.aps.alert) {
this.alert(json.aps.alert);
}
}
return this;
};
/**
* .send (cb)

@@ -349,0 +359,0 @@ *

{
"name": "apnagent"
, "version": "0.3.1"
, "version": "0.4.0"
, "description": "Node adapter for Apple Push Notification (APN) Service."

@@ -32,9 +32,10 @@ , "author": "Jake Luer <jake@alogicalpardox.com> (http://alogicalparadox.com)"

, "dependencies": {
"breeze-queue": "0.2.x"
"breeze-queue": "0.4.x"
, "drip": "1.1.x"
, "facet": "0.3.x"
, "lotus": "0.3.x"
, "lotus": "0.4.x"
, "tea-error": "0.1.x"
, "tea-extend": "0.2.x"
, "tea-inherits": "0.1.x"
, "tea-ms": "0.1.x"
, "sherlock": "*"

@@ -44,4 +45,5 @@ }

"chai": "*"
, "chai-spies": "*"
, "mocha": "*"
}
}

@@ -19,3 +19,3 @@ # APN Agent [![Build Status](https://travis-ci.org/logicalparadox/apnagent.png?branch=master)](https://travis-ci.org/logicalparadox/apnagent)

- [apnagent-ios](https://github.com/logicalparadox/apnagent-ios): Tiny iOS application for use with the example(s).
- [apnagent-ios](https://github.com/logicalparadox/apnagent-ios): Tiny iOS application for use with the example(s) and live tests.

@@ -22,0 +22,0 @@ ## Installation

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc