Comparing version 1.3.8 to 1.4.0
## Changelog | ||
1.4.0: | ||
* New: Implements protocol launched with iOS 7 which permits specifying a notification priority. | ||
* New: Ability to truncate notification body to nearest whole word. | ||
* Fixed: TLS Connection stalled on node-0.11.x | ||
* Fixed: Documentation defects. | ||
1.3.8: | ||
@@ -4,0 +11,0 @@ |
var apn = require ('../index.js'); | ||
// Setup a connection to the feedback service using a custom interval (10 seconds) | ||
var feedback = new apn.feedback({ gateway:'feedback.sandbox.push.apple.com', interval: 10 }); | ||
var feedback = new apn.feedback({ address:'feedback.sandbox.push.apple.com', interval: 10 }); | ||
@@ -15,4 +15,4 @@ feedback.on('feedback', handleFeedback); | ||
console.log("Device: " + device.toString() + " has been unreachable, since: " + time); | ||
console.log("Device: " + device.toString('hex') + " has been unreachable, since: " + time); | ||
} | ||
} | ||
} |
@@ -19,3 +19,3 @@ var apn = require ('../index.js'); | ||
service.on('transmitted', function(notification, device) { | ||
console.log("Notification transmitted to:" + device.token.toString()); | ||
console.log("Notification transmitted to:" + device.token.toString('hex')); | ||
}); | ||
@@ -22,0 +22,0 @@ |
@@ -45,2 +45,3 @@ var Errors = require('./errors'); | ||
* @config {Boolean} [fastMode=false] Whether to aggresively empty the notification buffer while connected. | ||
* @config {Boolean} [legacy=false] Whether to use the old (pre-iOS 7) protocol format. | ||
*/ | ||
@@ -68,3 +69,5 @@ function Connection (options) { | ||
connectionTimeout: 0, | ||
buffersNotifications: true | ||
buffersNotifications: true, | ||
fastMode: false, | ||
legacy: false | ||
}; | ||
@@ -188,3 +191,3 @@ | ||
// event listeners below. | ||
socketOptions.socket = new net.Stream(); | ||
socketOptions.socket = new net.Socket(); | ||
@@ -214,3 +217,8 @@ this.socket = tls.connect( | ||
// been attached. | ||
socketOptions.socket.connect(this.options['port'], this.options['gateway']); | ||
if ("function" == typeof this.socket.connect ) { | ||
this.socket.connect(this.options['port'], this.options['gateway']); | ||
} | ||
else { | ||
socketOptions.socket.connect(this.options['port'], this.options['gateway']); | ||
} | ||
}.bind(this)).fail(function (error) { | ||
@@ -416,4 +424,4 @@ debug("Module initialisation error:", error); | ||
if (notification.retryLimit === 0) { | ||
this.raiseError(Errors['retryCountExceeded'], notification); | ||
this.emit('transmissionError', Errors['retryCountExceeded'], notification.notification, notification.recipient); | ||
this.raiseError(Errors['retryLimitExceeded'], notification); | ||
this.emit('transmissionError', Errors['retryLimitExceeded'], notification.notification, notification.recipient); | ||
return; | ||
@@ -567,33 +575,89 @@ } | ||
} | ||
if (this.options.enhanced) { | ||
data = new Buffer(1 + 4 + 4 + 2 + token.length + 2 + messageLength); | ||
// Command | ||
data[position] = 1; | ||
position++; | ||
if (this.options.legacy) { | ||
if (this.options.enhanced) { | ||
data = new Buffer(1 + 4 + 4 + 2 + token.length + 2 + messageLength); | ||
// Command | ||
data[position] = 1; | ||
position++; | ||
// Identifier | ||
data.writeUInt32BE(notification._uid, position); | ||
position += 4; | ||
// Identifier | ||
data.writeUInt32BE(notification._uid, position); | ||
position += 4; | ||
// Expiry | ||
data.writeUInt32BE(notification.notification.expiry, position); | ||
position += 4; | ||
this.cacheNotification(socket, notification); | ||
// Expiry | ||
data.writeUInt32BE(notification.notification.expiry, position); | ||
position += 4; | ||
this.cacheNotification(socket, notification); | ||
} | ||
else { | ||
data = new Buffer(1 + 2 + token.length + 2 + messageLength); | ||
//Command | ||
data[position] = 0; | ||
position++; | ||
} | ||
// Token Length | ||
data.writeUInt16BE(token.length, position); | ||
position += 2; | ||
// Device Token | ||
position += token.copy(data, position, 0); | ||
// Payload Length | ||
data.writeUInt16BE(messageLength, position); | ||
position += 2; | ||
//Payload | ||
position += data.write(message, position, encoding); | ||
} | ||
else { | ||
data = new Buffer(1 + 2 + token.length + 2 + messageLength); | ||
//Command | ||
data[position] = 0; | ||
position++; | ||
// New Protocol uses framed notifications consisting of multiple items | ||
// 1: Device Token | ||
// 2: Payload | ||
// 3: Notification Identifier | ||
// 4: Expiration Date | ||
// 5: Priority | ||
// Each item has a 3 byte header: Type (1), Length (2) followed by data | ||
var frameLength = 3 + 32 + 3 + messageLength + 3 + 4; | ||
if(notification.notification.expiry > 0) { | ||
frameLength += 3 + 4; | ||
} | ||
if(notification.notification.priority != 10) { | ||
frameLength += 3 + 1; | ||
} | ||
// Frame has a 5 byte header: Type (1), Length (4) followed by items. | ||
data = new Buffer(5 + frameLength); | ||
data[position] = 2; position += 1; | ||
// Frame Length | ||
data.writeUInt32BE(frameLength, position); position += 4; | ||
// Token Item | ||
data[position] = 1; position += 1; | ||
data.writeUInt16BE(token.length, position); position += 2; | ||
position += token.copy(data, position, 0); | ||
// Payload Item | ||
data[position] = 2; position += 1; | ||
data.writeUInt16BE(messageLength, position); position += 2; | ||
position += data.write(message, position, encoding); | ||
// Identifier Item | ||
data[position] = 3; position += 1; | ||
data.writeUInt16BE(4, position); position += 2; | ||
data.writeUInt32BE(notification._uid, position); position += 4; | ||
if(notification.notification.expiry > 0) { | ||
// Expiry Item | ||
data[position] = 4; position += 1; | ||
data.writeUInt16BE(4, position); position += 2; | ||
data.writeUInt32BE(notification.notification.expiry, position); position += 4; | ||
} | ||
if(notification.notification.priority != 10) { | ||
// Priority Item | ||
data[position] = 5; position += 1; | ||
data.writeUInt16BE(1, position); position += 2; | ||
data[position] = notification.notification.priority; position += 1; | ||
} | ||
this.cacheNotification(socket, notification); | ||
} | ||
// Token Length | ||
data.writeUInt16BE(token.length, position); | ||
position += 2; | ||
// Device Token | ||
position += token.copy(data, position, 0); | ||
// Payload Length | ||
data.writeUInt16BE(messageLength, position); | ||
position += 2; | ||
//Payload | ||
position += data.write(message, position, encoding); | ||
@@ -600,0 +664,0 @@ socket.busy = true; |
@@ -33,3 +33,3 @@ var Device = require('./device'); | ||
* @config {String} [address="feedback.push.apple.com"] The feedback server to connect to. | ||
* @config {Number} [port=2195] Feedback server port | ||
* @config {Number} [port=2196] Feedback server port | ||
* @config {Function} [feedback] Deprecated ** A callback which accepts 2 parameters (timestamp, {@link Device}) or an array of (timestamp, {@link Device}) object tuples, depending on the value of batchFeedback option. See: {@link <a href="https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW3">Communicating with APS</a>. | ||
@@ -36,0 +36,0 @@ * @config {Boolean} [batchFeedback=true] If true, the feedback callback will only be called once per connection with an array of timestamp and device token tuples. |
@@ -11,2 +11,3 @@ /** | ||
this.identifier = 0; | ||
this.priority = 10; | ||
@@ -29,2 +30,4 @@ this.retryLimit = -1; | ||
this.compiled = false; | ||
this.truncateAtWordEnd = false; | ||
} | ||
@@ -46,2 +49,3 @@ | ||
notification.identifier = this.identifier; | ||
notification.priority = this.priority; | ||
notification.device = device; | ||
@@ -55,2 +59,3 @@ | ||
notification.mdm = this.mdm; | ||
notification.truncateAtWordEnd = this.truncateAtWordEnd; | ||
@@ -71,2 +76,12 @@ return notification; | ||
/** | ||
* Set the priority | ||
* @param {Number} [priority=10] Priority value for the notification. | ||
* @since v1.3.9 | ||
*/ | ||
Notification.prototype.setPriority = function (priority) { | ||
this.priority = priority; | ||
return this; | ||
} | ||
/** | ||
* Set the "badge" value on the alert object | ||
@@ -198,2 +213,12 @@ * @param {Number} [badge] Badge Value | ||
/** | ||
* Set the 'truncateAtWordEnd' flag for truncation logic | ||
* @param {Boolean} [truncateAtWordEnd] Whether the truncateAtWordEnd flag should be set or not. | ||
*/ | ||
Notification.prototype.setTruncateAtWordEnd = function (truncateAtWordEnd) { | ||
this.truncateAtWordEnd = truncateAtWordEnd; | ||
return this; | ||
}; | ||
/** | ||
* If an alert object doesn't already exist create it and transfer any existing message into the .body property | ||
@@ -273,7 +298,18 @@ * @private | ||
Notification.prototype.truncateStringToLength = function (string, length) { | ||
// Convert to a buffer and back to a string with the correct encoding to truncate the unicode series correctly. | ||
var result = new Buffer(string, this.encoding || 'utf8').toString(this.encoding || 'utf8', 0, length); | ||
if (this.truncateAtWordEnd === true) { | ||
var lastSpaceIndexInResult = result.lastIndexOf(' '); | ||
// Only truncate the string further if the remainder isn't a whole word | ||
// which we can tell by checking the *next* character in the original string | ||
if(lastSpaceIndexInResult != -1 && string.charAt(result.length + 1) != ' '){ | ||
result=result.substr(0,lastSpaceIndexInResult); | ||
} | ||
} | ||
} | ||
// since we might have chopped off the end of a multi-byte sequence, remove any | ||
// invalid characters (represented as U+FFFD "REPLACEMENT CHARACTER") for UTF-8 | ||
// or orphaned lead surrogates for UTF-16 (UCS-2) - where only the tail surrogate | ||
// or orphaned lead surrogates for UTF-16 (UCS-2) - where only the tail surrogate | ||
// has been removed. | ||
@@ -280,0 +316,0 @@ var done = false; |
{ | ||
"name": "apn", | ||
"description": "An interface to the Apple Push Notification service for Node.js", | ||
"version": "1.3.8", | ||
"version": "1.4.0", | ||
"author": "Andrew Naylor <argon@mkbot.net>", | ||
@@ -6,0 +6,0 @@ "contributors": [ |
@@ -119,3 +119,3 @@ #node-apn | ||
Copyright (c) 2010 Andrew Naylor | ||
Copyright (c) 2013 Andrew Naylor | ||
@@ -122,0 +122,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1373
90069
1