forked from gauntface/simple-push-demo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
139 lines (115 loc) · 4.03 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
'use strict';
/* eslint-disable dot-notation */
var request = require('request-promise');
var express = require('express');
var bodyParser = require('body-parser');
var EncryptionHelper = require('./encryption-helper');
var urlBase64 = require('urlsafe-base64');
const GCM_USE_WEB_PUSH = true;
const GCM_ENDPOINT = 'https://android.googleapis.com/gcm/send';
const GCM_WEB_PUSH_ENDPOINT = 'https://jmt17.google.com/gcm/demo-webpush-00';
const GCM_AUTHORIZATION = 'AIzaSyBBh4ddPa96rQQNxqiq_qQj7sq1JdsNQUQ';
var app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.use('/', express.static('./dist'));
function handleGCMAPI(endpoint, encryptionHelper, encryptedDataBuffer) {
var options = {
uri: endpoint,
method: 'POST',
headers: {}
};
if (encryptionHelper !== null && encryptedDataBuffer !== null) {
// Add required headers
options.headers['Crypto-Key'] = 'dh=' +
urlBase64.encode(encryptionHelper.getServerKeys().public);
options.headers['Encryption'] = 'salt=' +
urlBase64.encode(encryptionHelper.getSalt());
}
// Proprietary GCM
var endpointParts = endpoint.split('/');
var gcmRegistrationId = endpointParts[endpointParts.length - 1];
if (GCM_USE_WEB_PUSH) {
var webPushEndpoint = GCM_WEB_PUSH_ENDPOINT + '/' + gcmRegistrationId;
return handleWebPushAPI(webPushEndpoint,
encryptionHelper, encryptedDataBuffer);
}
// The registration ID cannot be included on the end of the GCM endpoint
options.uri = GCM_ENDPOINT;
options.headers['Content-Type'] = 'application/json';
options.headers['Authorization'] = 'key=' + GCM_AUTHORIZATION;
options.body = JSON.stringify({
'to': gcmRegistrationId,
'raw_data': encryptedDataBuffer.toString('base64')
});
return request(options);
}
function handleWebPushAPI(endpoint, encryptionHelper, encryptedDataBuffer) {
var options = {
uri: endpoint,
method: 'POST',
headers: {}
};
// GCM web push NEEDS this
if (endpoint.indexOf(GCM_WEB_PUSH_ENDPOINT) === 0) {
options.headers['Authorization'] = 'key=' + GCM_AUTHORIZATION;
} else {
// GCM web push FAILS with this, but firefox NEEDS this
options.headers['Content-Encoding'] = 'aesgcm';
}
if (encryptionHelper !== null && encryptedDataBuffer !== null) {
// Add required headers
options.headers['Crypto-Key'] = 'dh=' +
urlBase64.encode(encryptionHelper.getServerKeys().public);
options.headers['Encryption'] = 'salt=' +
urlBase64.encode(encryptionHelper.getSalt());
}
options.body = encryptedDataBuffer;
return request(options);
}
function sendPushMessage(endpoint, keys) {
let encryptionHelper = null;
let encryptedDataBuffer = null;
if (keys) {
encryptionHelper = new EncryptionHelper({keys: keys});
encryptedDataBuffer = encryptionHelper.encryptMessage('hello');
}
if (endpoint.indexOf('https://android.googleapis.com/gcm/send') === 0) {
// Handle Proprietary GCM API
return handleGCMAPI(endpoint, encryptionHelper, encryptedDataBuffer);
}
// Handle Web Push API
return handleWebPushAPI(endpoint, encryptionHelper, encryptedDataBuffer);
}
/**
*
* Massive h/t to Martin Thompson for his web-push-client code
* https://github.com/martinthomson/webpush-client/
*
*/
app.post('/send_web_push', function(req, res) {
var endpoint = req.body.endpoint;
var keys = req.body.keys;
if (!endpoint) {
// If there is no endpoint we can't send anything
return res.status(404).json({success: false});
}
sendPushMessage(endpoint, keys)
.then((responseText) => {
console.log('Request success', responseText);
// Check the response from GCM
res.json({success: true});
})
.catch((err) => {
console.log('Problem with request');
res.json({success: false});
});
});
var server = app.listen(3000, () => {
var port = server.address().port;
console.log('Server is listening at http://localhost:%s', port);
});
// Maybe prime256v1
// Maybe secp256k1
// var serverKeys = crypto.diffieHellman.generateKeys('binary');
// console.log(crypto.getCurves());