fxa-auth-server/test/push_helper.js

97 строки
2.5 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict'
var WebSocket = require('ws')
var P = require('../lib/promise')
/**
* PushManager, helps create subscriptions against a push server
*
* Built based on https://github.com/websockets/wscat
* Built based on Service Worker Push APIs
*
* @param options
* Push Manager options
* @param options.server
* Push server setting. i.e wss://push.services.mozilla.com/
* @param options.channelId
* Push channel id, uuid4 format.
* @constructor
*/
function PushManager(options) {
if (! options || ! options.server) {
throw new Error('Server is required')
}
this.server = options.server
this.channelId = options.channelId
}
/**
* Gets a subscription from the push server
* Returns a promise which resolves to a subscription object.
*
* Based on https://developer.mozilla.org/en-US/docs/Web/API/PushManager/getSubscription
* @returns {Promise}
*/
PushManager.prototype.getSubscription = function getSubscription() {
var self = this
var d = P.defer()
var ws = new WebSocket(this.server)
// Registration is a two-step handshake.
// We send and receive a "hello" message, then send and receive a "register" message.
// See http://mozilla-push-service.readthedocs.io/en/latest/design/#simplepush-protocol
function send(msg) {
ws.send(JSON.stringify(msg), { mask: true }, function(err) {
if (err) onError(err)
})
}
function onError(err) {
d.reject(err)
ws.close()
}
var handlers = {
'hello': function() {
send({
messageType: 'register',
channelID: self.channelId
})
},
'register': function(data) {
d.resolve({
endpoint: data.pushEndpoint
})
ws.close()
},
'': function(data) {
onError(new Error('Unexpected ws message: ' + JSON.stringify(data)))
}
}
ws.on('open', function open() {
send({
messageType: 'hello',
use_webpush: true
})
}).on('error', function error(code, description) {
onError(new Error(code + description))
}).on('message', function message(data, flags) {
data = JSON.parse(data)
if (data && data.messageType) {
var handler = handlers[data.messageType] || handlers['']
handler(data)
}
})
return d.promise
}
module.exports.PushManager = PushManager