Files
UXP-Fixed/dom/push/test/xpcshell/test_notification_data.js
2018-02-02 04:16:08 -05:00

281 lines
8.3 KiB
JavaScript

/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
'use strict';
const {PushDB, PushService, PushServiceWebSocket} = serviceExports;
let db;
let userAgentID = 'f5b47f8d-771f-4ea3-b999-91c135f8766d';
function run_test() {
do_get_profile();
setPrefs({
userAgentID: userAgentID,
});
run_next_test();
}
function putRecord(channelID, scope, publicKey, privateKey, authSecret) {
return db.put({
channelID: channelID,
pushEndpoint: 'https://example.org/push/' + channelID,
scope: scope,
pushCount: 0,
lastPush: 0,
originAttributes: '',
quota: Infinity,
systemRecord: true,
p256dhPublicKey: ChromeUtils.base64URLDecode(publicKey, {
padding: "reject",
}),
p256dhPrivateKey: privateKey,
authenticationSecret: ChromeUtils.base64URLDecode(authSecret, {
padding: "reject",
}),
});
}
let ackDone;
let server;
add_task(function* test_notification_ack_data_setup() {
db = PushServiceWebSocket.newPushDB();
do_register_cleanup(() => {return db.drop().then(_ => db.close());});
yield putRecord(
'subscription1',
'https://example.com/page/1',
'BPCd4gNQkjwRah61LpdALdzZKLLnU5UAwDztQ5_h0QsT26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA',
{
crv: 'P-256',
d: '1jUPhzVsRkzV0vIzwL4ZEsOlKdNOWm7TmaTfzitJkgM',
ext: true,
key_ops: ["deriveBits"],
kty: "EC",
x: '8J3iA1CSPBFqHrUul0At3NkosudTlQDAPO1Dn-HRCxM',
y: '26jk0IFbqcK6-JxhHAm-rsHEwy0CyVJjtnfOcqc1tgA'
},
'c_sGN6uCv9Hu7JOQT34jAQ'
);
yield putRecord(
'subscription2',
'https://example.com/page/2',
'BPnWyUo7yMnuMlyKtERuLfWE8a09dtdjHSW2lpC9_BqR5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E',
{
crv: 'P-256',
d: 'lFm4nPsUKYgNGBJb5nXXKxl8bspCSp0bAhCYxbveqT4',
ext: true,
key_ops: ["deriveBits"],
kty: 'EC',
x: '-dbJSjvIye4yXIq0RG4t9YTxrT1212MdJbaWkL38GpE',
y: '5TZ1rK8Ldih6ljyxVwnBA-nygQHGRpEmu1jV5K8437E'
},
't3P246Gj9vjKDHHRYaY6hw'
);
yield putRecord(
'subscription3',
'https://example.com/page/3',
'BDhUHITSeVrWYybFnb7ylVTCDDLPdQWMpf8gXhcWwvaaJa6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI',
{
crv: 'P-256',
d: 'Q1_SE1NySTYzjbqgWwPgrYh7XRg3adqZLkQPsy319G8',
ext: true,
key_ops: ["deriveBits"],
kty: 'EC',
x: 'OFQchNJ5WtZjJsWdvvKVVMIMMs91BYyl_yBeFxbC9po',
y: 'Ja6n3YH8TOcH8narDF6t8mKVvg2ioLW-8MH5O4dzGcI'
},
'E0qiXGWvFSR0PS352ES1_Q'
);
let setupDone;
let setupDonePromise = new Promise(r => setupDone = r);
PushService.init({
serverURI: "wss://push.example.org/",
db,
makeWebSocket(uri) {
return new MockWebSocket(uri, {
onHello(request) {
equal(request.uaid, userAgentID,
'Should send matching device IDs in handshake');
this.serverSendMsg(JSON.stringify({
messageType: 'hello',
uaid: userAgentID,
status: 200,
use_webpush: true,
}));
server = this;
setupDone();
},
onACK(request) {
if (ackDone) {
ackDone(request);
}
}
});
}
});
yield setupDonePromise;
});
add_task(function* test_notification_ack_data() {
let allTestData = [
{
channelID: 'subscription1',
version: 'v1',
send: {
headers: {
encryption_key: 'keyid="notification1"; dh="BO_tgGm-yvYAGLeRe16AvhzaUcpYRiqgsGOlXpt0DRWDRGGdzVLGlEVJMygqAUECarLnxCiAOHTP_znkedrlWoU"',
encryption: 'keyid="notification1";salt="uAZaiXpOSfOLJxtOCZ09dA"',
encoding: 'aesgcm128',
},
data: 'NwrrOWPxLE8Sv5Rr0Kep7n0-r_j3rsYrUw_CXPo',
version: 'v1',
},
ackCode: 100,
receive: {
scope: 'https://example.com/page/1',
data: 'Some message'
}
},
{
channelID: 'subscription2',
version: 'v2',
send: {
headers: {
encryption_key: 'keyid="notification2"; dh="BKVdQcgfncpNyNWsGrbecX0zq3eHIlHu5XbCGmVcxPnRSbhjrA6GyBIeGdqsUL69j5Z2CvbZd-9z1UBH0akUnGQ"',
encryption: 'keyid="notification2";salt="vFn3t3M_k42zHBdpch3VRw"',
encoding: 'aesgcm128',
},
data: 'Zt9dEdqgHlyAL_l83385aEtb98ZBilz5tgnGgmwEsl5AOCNgesUUJ4p9qUU',
},
ackCode: 100,
receive: {
scope: 'https://example.com/page/2',
data: 'Some message'
}
},
{
channelID: 'subscription3',
version: 'v3',
send: {
headers: {
encryption_key: 'keyid="notification3";dh="BD3xV_ACT8r6hdIYES3BJj1qhz9wyv7MBrG9vM2UCnjPzwE_YFVpkD-SGqE-BR2--0M-Yf31wctwNsO1qjBUeMg"',
encryption: 'keyid="notification3"; salt="DFq188piWU7osPBgqn4Nlg"; rs=24',
encoding: 'aesgcm128',
},
data: 'LKru3ZzxBZuAxYtsaCfaj_fehkrIvqbVd1iSwnwAUgnL-cTeDD-83blxHXTq7r0z9ydTdMtC3UjAcWi8LMnfY-BFzi0qJAjGYIikDA',
},
ackCode: 100,
receive: {
scope: 'https://example.com/page/3',
data: 'Some message'
}
},
// A message encoded with `aesgcm` (2 bytes of padding, authenticated).
{
channelID: 'subscription1',
version: 'v5',
send: {
headers: {
crypto_key: 'keyid=v4;dh="BMh_vsnqu79ZZkMTYkxl4gWDLdPSGE72Lr4w2hksSFW398xCMJszjzdblAWXyhSwakRNEU_GopAm4UGzyMVR83w"',
encryption: 'keyid="v4";salt="C14Wb7rQTlXzrgcPHtaUzw"',
encoding: 'aesgcm',
},
data: 'pus4kUaBWzraH34M-d_oN8e0LPpF_X6acx695AMXovDe',
},
ackCode: 100,
receive: {
scope: 'https://example.com/page/1',
data: 'Another message'
}
},
// A message with 17 bytes of padding and rs of 24
{
channelID: 'subscription2',
version: 'v5',
send: {
headers: {
crypto_key: 'keyid="v5"; dh="BOp-DpyR9eLY5Ci11_loIFqeHzWfc_0evJmq7N8NKzgp60UAMMM06XIi2VZp2_TSdw1omk7E19SyeCCwRp76E-U"',
encryption: 'keyid=v5;salt="TvjOou1TqJOQY_ZsOYV3Ww";rs=24',
encoding: 'aesgcm',
},
data: 'rG9WYQ2ZwUgfj_tMlZ0vcIaNpBN05FW-9RUBZAM-UUZf0_9eGpuENBpUDAw3mFmd2XJpmvPvAtLVs54l3rGwg1o',
},
ackCode: 100,
receive: {
scope: 'https://example.com/page/2',
data: 'Some message'
}
},
// A message without key identifiers.
{
channelID: 'subscription3',
version: 'v6',
send: {
headers: {
crypto_key: 'dh="BEEjwWbF5jZKCgW0kmUWgG-wNcRvaa9_3zZElHAF8przHwd4cp5_kQsc-IMNZcVA0iUix31jxuMOytU-5DwWtyQ"',
encryption: 'salt=aAQcr2khAksgNspPiFEqiQ',
encoding: 'aesgcm',
},
data: 'pEYgefdI-7L46CYn5dR9TIy2AXGxe07zxclbhstY',
},
ackCode: 100,
receive: {
scope: 'https://example.com/page/3',
data: 'Some message'
}
},
// A malformed encrypted message.
{
channelID: 'subscription3',
version: 'v7',
send: {
headers: {
crypto_key: 'dh=AAAAAAAA',
encryption: 'salt=AAAAAAAA',
},
data: 'AAAAAAAA',
},
ackCode: 101,
receive: null,
},
];
let sendAndReceive = testData => {
let messageReceived = testData.receive ? promiseObserverNotification(PushServiceComponent.pushTopic, (subject, data) => {
let notification = subject.QueryInterface(Ci.nsIPushMessage).data;
equal(notification.text(), testData.receive.data,
'Check data for notification ' + testData.version);
equal(data, testData.receive.scope,
'Check scope for notification ' + testData.version);
return true;
}) : Promise.resolve();
let ackReceived = new Promise(resolve => ackDone = resolve)
.then(ackData => {
deepEqual({
messageType: 'ack',
updates: [{
channelID: testData.channelID,
version: testData.version,
code: testData.ackCode,
}],
}, ackData, 'Check updates for acknowledgment ' + testData.version);
});
let msg = JSON.parse(JSON.stringify(testData.send));
msg.messageType = 'notification';
msg.channelID = testData.channelID;
msg.version = testData.version;
server.serverSendMsg(JSON.stringify(msg));
return Promise.all([messageReceived, ackReceived]);
};
yield allTestData.reduce((p, testData) => {
return p.then(_ => sendAndReceive(testData));
}, Promise.resolve());
});