Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

apns2

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apns2 - npm Package Compare versions

Comparing version 3.0.1 to 4.0.0

CHANGELOG.md

116

lib/apns.js
const _ = require('lodash')
const apnsErrors = require('./errors')
const EventEmitter = require('events').EventEmitter
const Promise = require('bluebird')
const { EventEmitter } = require('events')
const { Pool } = require('tarn')
const jwt = require('jsonwebtoken')
const Promise = require('bluebird')
// Notifications
const Http2Client = require('./http2-client')
const Errors = require('./errors')
const Notification = require('./notifications/notification')

@@ -12,13 +12,2 @@ const BasicNotification = require('./notifications/basic-notification')

// HTTP/2 Client
const HTTP2Client = (() => {
try {
// try native module
return require('./http2-client')
} catch(err) {
// else fallback to spdy
return require('./spdy-client')
}
})()
/**

@@ -34,3 +23,3 @@ * @const

*/
const MAX_CONNECTIONS = 8
const MAX_CONNECTIONS = 10

@@ -41,3 +30,3 @@ /**

*/
const CONCURRENCY = 32
const CONCURRENCY = 64

@@ -74,34 +63,2 @@ /**

/**
* @static
* @prop {Class} Notification
*/
static get Notification() {
return Notification
}
/**
* @static
* @prop {Class} BasicNotification
*/
static get BasicNotification() {
return BasicNotification
}
/**
* @static
* @prop {Class} SilentNotification
*/
static get SilentNotification() {
return SilentNotification
}
/**
* @static
* @prop {Object} errors
*/
static get errors() {
return apnsErrors
}
/**
* @constructor

@@ -126,9 +83,34 @@ * @param {Object} options

this._concurrency = concurrency
this._clients = _.times(connections, () => new HTTP2Client(host, port))
this._clientIndex = 0
this._clients = this._createClientPool({ host, port, connections })
this._interval = setInterval(() => this._resetSigningToken(), RESET_TOKEN_INTERVAL).unref()
this.on(apnsErrors.expiredProviderToken, () => this._resetSigningToken())
this.on(Errors.expiredProviderToken, () => this._resetSigningToken())
}
/**
* @private
* @method _createClientPool
* @param {String} host
* @param {Number} port
* @return {Pool}
*/
_createClientPool({ host, port, connections }) {
return new Pool({
create: cb => new Http2Client(host, port).connect().asCallback(cb),
validate: client => client.ready,
destroy: client => client.destroy(),
min: 0,
max: connections
})
}
/**
* @private
* @method _acquireClient
* @return {Promise}
*/
_acquireClient() {
return Promise.resolve(this._clients.acquire().promise)
}
/**
* @method send

@@ -152,13 +134,2 @@ * @param {Array<Notification>|Notification} notifications

* @private
* @param {HTTP2Client} _nextClient
*/
get _nextClient() {
let client = this._clients[this._clientIndex]
let nextIndex = this._clientIndex + 1
this._clientIndex = nextIndex < this._clients.length ? nextIndex : 0
return client
}
/**
* @private
* @method _send

@@ -188,3 +159,4 @@ * @param {Notification} notification

return this._nextClient.post(options, body)
return this._acquireClient()
.then(client => client.post(options, body))
.then(res => this._handleServerResponse(res, notification))

@@ -209,3 +181,3 @@ }

} catch(err) {
json = { reason: apnsErrors.unknownError }
json = { reason: Errors.unknownError }
}

@@ -217,3 +189,3 @@

this.emit(json.reason, json)
this.emit(apnsErrors.error, json)
this.emit(Errors.error, json)

@@ -254,3 +226,3 @@ return Promise.reject(json)

token = this._token = null
this.emit(apnsErrors.invalidSigningKey)
this.emit(Errors.invalidSigningKey)
}

@@ -271,2 +243,8 @@

module.exports = APNS
module.exports = {
APNS,
Errors,
Notification,
BasicNotification,
SilentNotification
}

@@ -6,3 +6,5 @@ const { URL } = require('url')

// Check to make sure this is the native http2
if (!http2.constants || !http2.constants.NGHTTP2_SESSION_CLIENT) throw new Error('Invalid http2 library')
if (!http2.constants || !http2.constants.NGHTTP2_SESSION_CLIENT) {
throw new Error('Invalid http2 library, must be running Node v8.10 or later')
}

@@ -27,6 +29,47 @@ const {

this._timeout = timeout
this.client()
this._ready = false
this._session = null
}
/**
* @param {Boolean} ready
*/
get ready() {
return this._ready && this._session && !this._session.destroyed
}
/**
* @param {Http2Session}
*/
get session() {
return this._session
}
/**
* @method connect
* @return {Promise}
*/
connect() {
return new Promise((resolve, reject) => {
let session = http2.connect(this._url)
session.once('socketError', reject)
session.once('connect', () => {
this._connected(session)
resolve(this)
})
})
}
/**
* @method destroy
*/
destroy() {
if (this._session && !this._session.destroyed) {
this._session.destroy()
}
this._ready = false
this._session = null
}
/**
* @method get

@@ -72,4 +115,5 @@ */

request({ method, path, headers={} }, body=null) {
if (!method) return Promise.reject(`method is required`)
if (!path) return Promise.reject(`path is required`)
if (!method) throw new Error('method is required')
if (!path) throw new Error('path is required')
if (!this._session) throw new Error('Must call connect() before making a request')

@@ -79,5 +123,5 @@ return new Promise((resolve, reject) => {

headers[HTTP2_HEADER_PATH] = path
let req = this.client().request(headers)
let req = this._session.request(headers)
// Cancel request after timeout

@@ -89,5 +133,5 @@ req.setTimeout(this._timeout, () => req.rstWithCancel())

let body = ''
req.on('data', chunk => body += chunk)
req.on('end', () => {

@@ -117,16 +161,13 @@ resolve({

* @private
* @return {Http2Session}
* @method _connected
* @param {Http2Session} session
*/
client() {
if (this._client && this._client.destroyed === false) {
return this._client
}
// Create client
let client = this._client = http2.connect(this._url)
// Events
client.on('goaway', () => client.destroy())
return client
_connected(session) {
session.on('close', () => this.destroy())
session.on('frameError', () => this.destroy())
session.on('goaway', () => this.destroy())
session.on('socketError', () => this.destroy())
session.on('timeout', () => this.destroy())
this._session = session
this._ready = true
}

@@ -133,0 +174,0 @@ }

{
"name": "apns2",
"version": "3.0.1",
"version": "4.0.0",
"description": "Node client for connecting to Apple's Push Notification Service using the new HTTP/2 protocol with JSON web tokens.",

@@ -10,3 +10,3 @@ "author": "Andrew Barba <abarba.77@gmail.com>",

"engines": {
"node": ">=6.0.0"
"node": ">=8.10.0"
},

@@ -17,16 +17,16 @@ "repository": {

"dependencies": {
"bluebird": "^3.4.1",
"jsonwebtoken": "^7.0.1",
"lodash": "^4.13.1",
"spdy": "^3.4.7"
"bluebird": "3.5.1",
"jsonwebtoken": "8.2.1",
"lodash": "4.17.10",
"tarn": "1.1.4"
},
"devDependencies": {
"eslint": "^4.5.0",
"mocha": "^3.3.0",
"should": "^12.0.0"
"eslint": "4.19.1",
"mocha": "5.1.1",
"should": "13.2.1"
},
"scripts": {
"lint": "make lint",
"test": "make test-all"
"lint": "npx eslint ./",
"test": "npx mocha --exit --bail --slow 1000 --timeout 5000 ./test/test.js"
}
}

@@ -9,6 +9,4 @@ APNS2

> Now uses the native `http2` module in Node.js v8.4.0 when exposed with `--expose-http2`
> Now uses the native `http2` module in Node.js v8.10 or later
> On earlier versions of Node.js we fallback to the `node-spdy` module
---

@@ -21,3 +19,3 @@

```javascript
const APNS = require('apns2');
const { APNS } = require('apns2')

@@ -29,3 +27,3 @@ let client = new APNS({

defaultTopic: `com.tablelist.Tablelist`
});
})
```

@@ -40,5 +38,5 @@

```javascript
const { BasicNotification } = APNS;
const { BasicNotification } = require('apns2')
let bn = new BasicNotification(deviceToken, 'Hello, World');
let bn = new BasicNotification(deviceToken, 'Hello, World')

@@ -48,4 +46,4 @@ client.send(bn).then(() => {

}).catch(err => {
console.error(err.reason);
});
console.error(err.reason)
})
```

@@ -56,3 +54,3 @@

```javascript
const { BasicNotification } = APNS;
const { BasicNotification } = require('apns2')

@@ -64,3 +62,3 @@ let bn = new BasicNotification(deviceToken, 'Hello, World', {

}
});
})

@@ -70,4 +68,4 @@ client.send(bn).then(() => {

}).catch(err => {
console.error(err.reason);
});
console.error(err.reason)
})
```

@@ -80,5 +78,5 @@

```javascript
const { SilentNotification } = APNS;
const { SilentNotification } = require('apns2')
let sn = new SilentNotification(deviceToken);
let sn = new SilentNotification(deviceToken)

@@ -88,7 +86,7 @@ client.send(sn).then(() => {

}).catch(err => {
console.error(err.reason);
});
console.error(err.reason)
})
```
Note: [Apple recommends](https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH107-SW1) that no options other than the `content-available` flag be sent in order for a notification to truly be silent and wake up your app in the background. Therefore this class does not accept any additional options in the constructor.
Note: [Apple recommends](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html#//apple_ref/doc/uid/TP40008194-CH10-SW8) that no options other than the `content-available` flag be sent in order for a notification to truly be silent and wake up your app in the background. Therefore this class does not accept any additional options in the constructor.

@@ -100,7 +98,7 @@ #### Advanced

```javascript
const { Notification } = APNS;
const { Notification } = require('apns2')
let notification = new Notification(deviceToken, {
aps: { ... }
});
})

@@ -110,4 +108,4 @@ client.send(notification).then(() => {

}).catch(err => {
console.error(err.reason);
});
console.error(err.reason)
})
```

@@ -124,15 +122,15 @@

```javascript
const errors = APNS.errors;
const { Errors } = require('apns2')
// Listen for a specific error
client.on(errors.badDeviceToken, err => {
client.on(Errors.badDeviceToken, err => {
// Handle accordingly...
// Perhaps delete token from your database
console.error(err.reason, err.statusCode, err.notification.deviceToken);
});
console.error(err.reason, err.statusCode, err.notification.deviceToken)
})
// Listen for any error
client.on(errors.error, err => {
console.error(err.reason, err.statusCode, err.notification.deviceToken);
});
client.on(Errors.error, err => {
console.error(err.reason, err.statusCode, err.notification.deviceToken)
})
```

@@ -149,3 +147,3 @@

...
});
})
```

@@ -159,3 +157,3 @@

...
});
})
```

@@ -165,6 +163,2 @@

`apns2` requires Node.js v6
#### Native http2
To use the new built in `http2` library in Node.js v8.4.0 you must start your node process with `node --expose-http2`. apns2 will automatically pick up the native module and use it instead of `node-spdy`.
`apns2` requires Node.js v8.10 or later

@@ -5,11 +5,10 @@ const fs = require('fs')

// Package
const APNS = require('../')
const errors = APNS.errors
const HTTP2Client = (() => {
try {
return require('../lib/http2-client')
} catch(err) {
return require('../lib/spdy-client')
}
})()
const HTTP2Client = require('../lib/http2-client')
const {
APNS,
Notification,
BasicNotification,
SilentNotification,
Errors
} = require('../')

@@ -23,2 +22,3 @@ describe('http2', () => {

client = new HTTP2Client('www.google.com', 443)
return client.connect()
})

@@ -50,10 +50,8 @@

it('should not make a get request', () => {
return client.get({
path: '/'
}).then(() => {
throw new Error('Failed')
}).catch(() => {
// good
})
it('should not connect', () => {
return client.connect()
.then(() => {
throw new Error('Failed')
})
.catch(() => {})
})

@@ -81,3 +79,3 @@ })

it('should send a basic notification', () => {
let basicNotification = new APNS.BasicNotification(deviceToken, `Hello, Basic`)
let basicNotification = new BasicNotification(deviceToken, `Hello, Basic`)
return apns.send(basicNotification)

@@ -87,3 +85,3 @@ })

it('should send a basic notification with options', () => {
let basicNotification = new APNS.BasicNotification(deviceToken, `Hello, 1`, {
let basicNotification = new BasicNotification(deviceToken, `Hello, 1`, {
badge: 1

@@ -95,3 +93,3 @@ })

it('should send a basic notification with additional data', () => {
let basicNotification = new APNS.BasicNotification(deviceToken, `Hello, ICON`, {
let basicNotification = new BasicNotification(deviceToken, `Hello, ICON`, {
badge: 0,

@@ -106,3 +104,3 @@ data: {

it('should send a silent notification', () => {
let silentNotification = new APNS.SilentNotification(deviceToken)
let silentNotification = new SilentNotification(deviceToken)
return apns.send(silentNotification)

@@ -112,3 +110,3 @@ })

it('should send a notification', () => {
let notification = new APNS.Notification(deviceToken, {
let notification = new Notification(deviceToken, {
aps: {

@@ -124,4 +122,4 @@ alert: {

it('should send both notifications', () => {
let basicNotification = new APNS.BasicNotification(deviceToken, `Hello, Multiple`)
let silentNotification = new APNS.SilentNotification(deviceToken)
let basicNotification = new BasicNotification(deviceToken, `Hello, Multiple`)
let silentNotification = new SilentNotification(deviceToken)
return apns.send([basicNotification, silentNotification]).then(result => {

@@ -134,6 +132,6 @@ should.exist(result)

it('should fail to send a notification', () => {
let noti = new APNS.BasicNotification(`fakedevicetoken`, `Hello, bad token`)
let noti = new BasicNotification(`fakedevicetoken`, `Hello, bad token`)
return apns.send(noti).catch(err => {
should.exist(err)
err.reason.should.equal(errors.badDeviceToken)
err.reason.should.equal(Errors.badDeviceToken)
})

@@ -144,9 +142,9 @@ })

apns.once(errors.error, err => {
apns.once(Errors.error, err => {
should.exist(err)
err.reason.should.equal(errors.badDeviceToken)
err.reason.should.equal(Errors.badDeviceToken)
done()
})
let noti = new APNS.BasicNotification(`fakedevicetoken`, `Hello, bad token`)
let noti = new BasicNotification(`fakedevicetoken`, `Hello, bad token`)
apns.send(noti).catch(err => {

@@ -159,9 +157,9 @@ should.exist(err)

apns.once(errors.badDeviceToken, err => {
apns.once(Errors.badDeviceToken, err => {
should.exist(err)
err.reason.should.equal(errors.badDeviceToken)
err.reason.should.equal(Errors.badDeviceToken)
done()
})
let noti = new APNS.BasicNotification(`fakedevicetoken`, `Hello, bad token`)
let noti = new BasicNotification(`fakedevicetoken`, `Hello, bad token`)
apns.send(noti).catch(err => {

@@ -168,0 +166,0 @@ should.exist(err)

Sorry, the diff of this file is not supported yet

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