Lightly massage some of the generated JavaScript

This commit is contained in:
Arlo Breault 2019-07-06 15:20:07 +02:00
parent 31ad9566e6
commit 1867a3f121
19 changed files with 986 additions and 989 deletions

View file

@ -1,26 +1,44 @@
// Generated by CoffeeScript 2.4.1
var FILES, FILES_SPEC, INITS, OUTFILE, STATIC, compileCoffee, copyStaticFiles, exec, execSync, fs, spawn;
fs = require('fs'); var fs = require('fs');
var { exec, spawn, execSync } = require('child_process');
({exec, spawn, execSync} = require('child_process'));
// All coffeescript files required. // All coffeescript files required.
FILES = ['broker.coffee', 'config.coffee', 'proxypair.coffee', 'snowflake.coffee', 'ui.coffee', 'util.coffee', 'websocket.coffee', 'shims.coffee']; var FILES = [
'broker.coffee',
'config.coffee',
'proxypair.coffee',
'snowflake.coffee',
'ui.coffee',
'util.coffee',
'websocket.coffee',
'shims.coffee'
];
INITS = ['init-badge.coffee', 'init-node.coffee', 'init-webext.coffee']; var INITS = [
'init-badge.coffee',
'init-node.coffee',
'init-webext.coffee'
];
FILES_SPEC = ['spec/broker.spec.coffee', 'spec/init.spec.coffee', 'spec/proxypair.spec.coffee', 'spec/snowflake.spec.coffee', 'spec/ui.spec.coffee', 'spec/util.spec.coffee', 'spec/websocket.spec.coffee']; var FILES_SPEC = [
'spec/broker.spec.coffee',
'spec/init.spec.coffee',
'spec/proxypair.spec.coffee',
'spec/snowflake.spec.coffee',
'spec/ui.spec.coffee',
'spec/util.spec.coffee',
'spec/websocket.spec.coffee'
];
OUTFILE = 'snowflake.js'; var OUTFILE = 'snowflake.js';
STATIC = 'static'; var STATIC = 'static';
copyStaticFiles = function() { var copyStaticFiles = function() {
return exec('cp ' + STATIC + '/* build/'); return exec('cp ' + STATIC + '/* build/');
}; };
compileCoffee = function(outDir, init) { var compileCoffee = function(outDir, init) {
var files; var files;
files = FILES.concat('init-' + init + '.coffee'); files = FILES.concat('init-' + init + '.coffee');
return exec('cat ' + files.join(' ') + ' | coffee -cs > ' + outDir + '/' + OUTFILE, function(err, stdout, stderr) { return exec('cat ' + files.join(' ') + ' | coffee -cs > ' + outDir + '/' + OUTFILE, function(err, stdout, stderr) {

View file

@ -1,15 +1,13 @@
// Generated by CoffeeScript 2.4.1
/* /*
Communication with the snowflake broker. Communication with the snowflake broker.
Browser snowflakes must register with the broker in order Browser snowflakes must register with the broker in order
to get assigned to clients. to get assigned to clients.
*/ */
var Broker;
Broker = (function() { // Represents a broker running remotely.
// Represents a broker running remotely. class Broker {
class Broker {
// When interacting with the Broker, snowflake must generate a unique session // When interacting with the Broker, snowflake must generate a unique session
// ID so the Broker can keep track of each proxy's signalling channels. // ID so the Broker can keep track of each proxy's signalling channels.
// On construction, this Broker object does not do anything until // On construction, this Broker object does not do anything until
@ -106,21 +104,17 @@ Broker = (function() {
return xhr.send(payload); return xhr.send(payload);
} }
}; };
Broker.STATUS = { Broker.STATUS = {
OK: 200, OK: 200,
GONE: 410, GONE: 410,
GATEWAY_TIMEOUT: 504 GATEWAY_TIMEOUT: 504
}; };
Broker.MESSAGE = { Broker.MESSAGE = {
TIMEOUT: 'Timed out waiting for a client offer.', TIMEOUT: 'Timed out waiting for a client offer.',
UNEXPECTED: 'Unexpected status.' UNEXPECTED: 'Unexpected status.'
}; };
Broker.prototype.clients = 0; Broker.prototype.clients = 0;
return Broker;
}).call(this);

View file

@ -1,43 +1,36 @@
// Generated by CoffeeScript 2.4.1
var Config;
Config = (function() { class Config {};
class Config {};
Config.prototype.brokerUrl = 'snowflake-broker.bamsoftware.com'; Config.prototype.brokerUrl = 'snowflake-broker.bamsoftware.com';
Config.prototype.relayAddr = { Config.prototype.relayAddr = {
host: 'snowflake.bamsoftware.com', host: 'snowflake.bamsoftware.com',
port: '443' port: '443'
}; };
// Original non-wss relay: // Original non-wss relay:
// host: '192.81.135.242' // host: '192.81.135.242'
// port: 9902 // port: 9902
Config.prototype.cookieName = "snowflake-allow"; Config.prototype.cookieName = "snowflake-allow";
// Bytes per second. Set to undefined to disable limit. // Bytes per second. Set to undefined to disable limit.
Config.prototype.rateLimitBytes = void 0; Config.prototype.rateLimitBytes = void 0;
Config.prototype.minRateLimit = 10 * 1024; Config.prototype.minRateLimit = 10 * 1024;
Config.prototype.rateLimitHistory = 5.0; Config.prototype.rateLimitHistory = 5.0;
Config.prototype.defaultBrokerPollInterval = 5.0 * 1000; Config.prototype.defaultBrokerPollInterval = 5.0 * 1000;
Config.prototype.maxNumClients = 1; Config.prototype.maxNumClients = 1;
Config.prototype.connectionsPerClient = 1; Config.prototype.connectionsPerClient = 1;
// TODO: Different ICE servers. // TODO: Different ICE servers.
Config.prototype.pcConfig = { Config.prototype.pcConfig = {
iceServers: [ iceServers: [
{ {
urls: ['stun:stun.l.google.com:19302'] urls: ['stun:stun.l.google.com:19302']
} }
] ]
}; };
return Config;
}).call(this);

View file

@ -1,37 +1,35 @@
// Generated by CoffeeScript 2.4.1
/* /*
Entry point. Entry point.
*/ */
var dbg, debug, init, log, query, silenceNotifications, snowflake;
if (((typeof TESTING === "undefined" || TESTING === null) || !TESTING) && !Util.featureDetect()) { if (((typeof TESTING === "undefined" || TESTING === null) || !TESTING) && !Util.featureDetect()) {
console.log('webrtc feature not detected. shutting down'); console.log('webrtc feature not detected. shutting down');
return; return;
} }
snowflake = null; var snowflake = null;
query = Query.parse(location); var query = Query.parse(location);
debug = Params.getBool(query, 'debug', false); var debug = Params.getBool(query, 'debug', false);
silenceNotifications = Params.getBool(query, 'silent', false); var silenceNotifications = Params.getBool(query, 'silent', false);
// Log to both console and UI if applicable. // Log to both console and UI if applicable.
// Requires that the snowflake and UI objects are hooked up in order to // Requires that the snowflake and UI objects are hooked up in order to
// log to console. // log to console.
log = function(msg) { var log = function(msg) {
console.log('Snowflake: ' + msg); console.log('Snowflake: ' + msg);
return snowflake != null ? snowflake.ui.log(msg) : void 0; return snowflake != null ? snowflake.ui.log(msg) : void 0;
}; };
dbg = function(msg) { var dbg = function(msg) {
if (debug || ((snowflake != null ? snowflake.ui : void 0) instanceof DebugUI)) { if (debug || ((snowflake != null ? snowflake.ui : void 0) instanceof DebugUI)) {
return log(msg); return log(msg);
} }
}; };
init = function() { var init = function() {
var broker, config, ui; var broker, config, ui;
config = new Config; config = new Config;
if ('off' !== query['ratelimit']) { if ('off' !== query['ratelimit']) {

View file

@ -1,22 +1,20 @@
// Generated by CoffeeScript 2.4.1
/* /*
Entry point. Entry point.
*/ */
var broker, config, dbg, log, snowflake, ui;
config = new Config; var config = new Config;
ui = new UI(); var ui = new UI();
broker = new Broker(config.brokerUrl); var broker = new Broker(config.brokerUrl);
snowflake = new Snowflake(config, ui, broker); var snowflake = new Snowflake(config, ui, broker);
log = function(msg) { var log = function(msg) {
return console.log('Snowflake: ' + msg); return console.log('Snowflake: ' + msg);
}; };
dbg = log; var dbg = log;
log('== snowflake proxy =='); log('== snowflake proxy ==');

View file

@ -1,28 +1,26 @@
// Generated by CoffeeScript 2.4.1
/* /*
Entry point. Entry point.
*/ */
var broker, config, dbg, debug, init, log, snowflake, ui, update;
debug = false; var debug = false;
snowflake = null; var snowflake = null;
config = null; var config = null;
broker = null; var broker = null;
ui = null; var ui = null;
// Log to both console and UI if applicable. // Log to both console and UI if applicable.
// Requires that the snowflake and UI objects are hooked up in order to // Requires that the snowflake and UI objects are hooked up in order to
// log to console. // log to console.
log = function(msg) { var log = function(msg) {
console.log('Snowflake: ' + msg); console.log('Snowflake: ' + msg);
return snowflake != null ? snowflake.ui.log(msg) : void 0; return snowflake != null ? snowflake.ui.log(msg) : void 0;
}; };
dbg = function(msg) { var dbg = function(msg) {
if (debug) { if (debug) {
return log(msg); return log(msg);
} }
@ -37,7 +35,7 @@ if (!Util.featureDetect()) {
return; return;
} }
init = function() { var init = function() {
config = new Config; config = new Config;
ui = new WebExtUI(); ui = new WebExtUI();
broker = new Broker(config.brokerUrl); broker = new Broker(config.brokerUrl);
@ -46,7 +44,7 @@ init = function() {
return ui.initToggle(); return ui.initToggle();
}; };
update = function() { var update = function() {
if (!ui.enabled) { if (!ui.enabled) {
// Do not activate the proxy if any number of conditions are true. // Do not activate the proxy if any number of conditions are true.
snowflake.disable(); snowflake.disable();

View file

@ -1,4 +1,3 @@
// Generated by CoffeeScript 2.4.1
/* /*
Represents a single: Represents a single:
@ -7,10 +6,9 @@ Represents a single:
Every ProxyPair has a Snowflake ID, which is necessary when responding to the Every ProxyPair has a Snowflake ID, which is necessary when responding to the
Broker with an WebRTC answer. Broker with an WebRTC answer.
*/ */
var ProxyPair;
ProxyPair = (function() { class ProxyPair {
class ProxyPair {
/* /*
Constructs a ProxyPair where: Constructs a ProxyPair where:
- @relayAddr is the destination relay - @relayAddr is the destination relay
@ -235,28 +233,24 @@ ProxyPair = (function() {
return void 0 === ws || WebSocket.CLOSED === ws.readyState; return void 0 === ws || WebSocket.CLOSED === ws.readyState;
} }
}; };
ProxyPair.prototype.MAX_BUFFER = 10 * 1024 * 1024; ProxyPair.prototype.MAX_BUFFER = 10 * 1024 * 1024;
ProxyPair.prototype.pc = null; ProxyPair.prototype.pc = null;
ProxyPair.prototype.client = null; // WebRTC Data channel ProxyPair.prototype.client = null; // WebRTC Data channel
ProxyPair.prototype.relay = null; // websocket ProxyPair.prototype.relay = null; // websocket
ProxyPair.prototype.timer = 0; ProxyPair.prototype.timer = 0;
ProxyPair.prototype.running = true; ProxyPair.prototype.running = true;
ProxyPair.prototype.active = false; // Whether serving a client. ProxyPair.prototype.active = false; // Whether serving a client.
ProxyPair.prototype.flush_timeout_id = null; ProxyPair.prototype.flush_timeout_id = null;
ProxyPair.prototype.onCleanup = null; ProxyPair.prototype.onCleanup = null;
ProxyPair.prototype.id = null; ProxyPair.prototype.id = null;
return ProxyPair;
}).call(this);

View file

@ -1,8 +1,6 @@
// Generated by CoffeeScript 2.4.1
/* /*
WebRTC shims for multiple browsers. WebRTC shims for multiple browsers.
*/ */
var IceCandidate, PeerConnection, SessionDescription, WebSocket, XMLHttpRequest, chrome, document, location, webrtc, window;
if (typeof module !== "undefined" && module !== null ? module.exports : void 0) { if (typeof module !== "undefined" && module !== null ? module.exports : void 0) {
window = {}; window = {};
@ -19,10 +17,9 @@ if (typeof module !== "undefined" && module !== null ? module.exports : void 0)
IceCandidate = webrtc.RTCIceCandidate; IceCandidate = webrtc.RTCIceCandidate;
SessionDescription = webrtc.RTCSessionDescription; SessionDescription = webrtc.RTCSessionDescription;
WebSocket = require('ws'); WebSocket = require('ws');
({XMLHttpRequest} = require('xmlhttprequest')); ({ XMLHttpRequest } = require('xmlhttprequest'));
} }
} else { } else {
window = this;
document = window.document; document = window.document;
chrome = window.chrome; chrome = window.chrome;
location = window.location.search.substr(1); location = window.location.search.substr(1);

View file

@ -1,4 +1,3 @@
// Generated by CoffeeScript 2.4.1
/* /*
A Coffeescript WebRTC snowflake proxy A Coffeescript WebRTC snowflake proxy
@ -9,11 +8,10 @@ this proxy must always act as the answerer.
TODO: More documentation TODO: More documentation
*/ */
var Snowflake;
Snowflake = (function() { // Minimum viable snowflake for now - just 1 client.
// Minimum viable snowflake for now - just 1 client. class Snowflake {
class Snowflake {
// Prepare the Snowflake with a Broker (to find clients) and optional UI. // Prepare the Snowflake with a Broker (to find clients) and optional UI.
constructor(config, ui, broker) { constructor(config, ui, broker) {
// Receive an SDP offer from some client assigned by the Broker, // Receive an SDP offer from some client assigned by the Broker,
@ -156,27 +154,23 @@ Snowflake = (function() {
return results; return results;
} }
}; };
Snowflake.prototype.relayAddr = null; Snowflake.prototype.relayAddr = null;
Snowflake.prototype.rateLimit = null; Snowflake.prototype.rateLimit = null;
Snowflake.prototype.pollInterval = null; Snowflake.prototype.pollInterval = null;
Snowflake.prototype.retries = 0; Snowflake.prototype.retries = 0;
// Janky state machine // Janky state machine
Snowflake.MODE = { Snowflake.MODE = {
INIT: 0, INIT: 0,
WEBRTC_CONNECTING: 1, WEBRTC_CONNECTING: 1,
WEBRTC_READY: 2 WEBRTC_READY: 2
}; };
Snowflake.MESSAGE = { Snowflake.MESSAGE = {
CONFIRMATION: 'You\'re currently serving a Tor user via Snowflake.' CONFIRMATION: 'You\'re currently serving a Tor user via Snowflake.'
}; };
return Snowflake;
}).call(this);

View file

@ -1,39 +1,32 @@
// Generated by CoffeeScript 2.4.1
/* /*
jasmine tests for Snowflake broker jasmine tests for Snowflake broker
*/ */
var XMLHttpRequest;
XMLHttpRequest = (function() { // fake xhr
// fake xhr // class XMLHttpRequest
// class XMLHttpRequest class XMLHttpRequest {
class XMLHttpRequest {
constructor() { constructor() {
this.onreadystatechange = null; this.onreadystatechange = null;
} }
open() {} open() {}
setRequestHeader() {} setRequestHeader() {}
send() {} send() {}
};
}; XMLHttpRequest.prototype.DONE = 1;
XMLHttpRequest.prototype.DONE = 1;
return XMLHttpRequest;
}).call(this);
describe('Broker', function() { describe('Broker', function() {
it('can be created', function() { it('can be created', function() {
var b; var b;
b = new Broker('fake'); b = new Broker('fake');
expect(b.url).toEqual('https://fake/'); expect(b.url).toEqual('https://fake/');
return expect(b.id).not.toBeNull(); expect(b.id).not.toBeNull();
}); });
describe('getClientOffer', function() { describe('getClientOffer', function() {
it('polls and promises a client offer', function(done) { it('polls and promises a client offer', function(done) {
var b, poll; var b, poll;
b = new Broker('fake'); b = new Broker('fake');
@ -55,6 +48,7 @@ describe('Broker', function() {
return done(); return done();
}); });
}); });
it('rejects if the broker timed-out', function(done) { it('rejects if the broker timed-out', function(done) {
var b, poll; var b, poll;
b = new Broker('fake'); b = new Broker('fake');
@ -75,7 +69,8 @@ describe('Broker', function() {
return done(); return done();
}); });
}); });
return it('rejects on any other status', function(done) {
it('rejects on any other status', function(done) {
var b, poll; var b, poll;
b = new Broker('fake'); b = new Broker('fake');
// fake timed-out request from broker // fake timed-out request from broker
@ -95,18 +90,20 @@ describe('Broker', function() {
expect(b._xhr.status).toBe(1337); expect(b._xhr.status).toBe(1337);
return done(); return done();
}); });
}); });
}); });
it('responds to the broker with answer', function() { it('responds to the broker with answer', function() {
var b; var b = new Broker('fake');
b = new Broker('fake');
spyOn(b, '_postRequest'); spyOn(b, '_postRequest');
b.sendAnswer('fake id', 123); b.sendAnswer('fake id', 123);
return expect(b._postRequest).toHaveBeenCalledWith('fake id', jasmine.any(Object), 'answer', '123'); expect(b._postRequest).toHaveBeenCalledWith('fake id', jasmine.any(Object), 'answer', '123');
}); });
return it('POST XMLHttpRequests to the broker', function() {
var b; it('POST XMLHttpRequests to the broker', function() {
b = new Broker('fake'); var b = new Broker('fake');
b._xhr = new XMLHttpRequest(); b._xhr = new XMLHttpRequest();
spyOn(b._xhr, 'open'); spyOn(b._xhr, 'open');
spyOn(b._xhr, 'setRequestHeader'); spyOn(b._xhr, 'setRequestHeader');
@ -114,6 +111,7 @@ describe('Broker', function() {
b._postRequest(0, b._xhr, 'test', 'data'); b._postRequest(0, b._xhr, 'test', 'data');
expect(b._xhr.open).toHaveBeenCalled(); expect(b._xhr.open).toHaveBeenCalled();
expect(b._xhr.setRequestHeader).toHaveBeenCalled(); expect(b._xhr.setRequestHeader).toHaveBeenCalled();
return expect(b._xhr.send).toHaveBeenCalled(); expect(b._xhr.send).toHaveBeenCalled();
}); });
}); });

View file

@ -1,8 +1,6 @@
// Generated by CoffeeScript 2.4.1
// Fake snowflake to interact with // Fake snowflake to interact with
var snowflake;
snowflake = { var snowflake = {
ui: new UI, ui: new UI,
broker: { broker: {
sendAnswer: function() {} sendAnswer: function() {}
@ -11,24 +9,25 @@ snowflake = {
}; };
describe('Init', function() { describe('Init', function() {
it('gives a dialog when closing, only while active', function() { it('gives a dialog when closing, only while active', function() {
var msg, silenceNotifications;
silenceNotifications = false; silenceNotifications = false;
snowflake.state = Snowflake.MODE.WEBRTC_READY; snowflake.state = Snowflake.MODE.WEBRTC_READY;
msg = window.onbeforeunload(); var msg = window.onbeforeunload();
expect(snowflake.state).toBe(Snowflake.MODE.WEBRTC_READY); expect(snowflake.state).toBe(Snowflake.MODE.WEBRTC_READY);
expect(msg).toBe(Snowflake.MESSAGE.CONFIRMATION); expect(msg).toBe(Snowflake.MESSAGE.CONFIRMATION);
snowflake.state = Snowflake.MODE.INIT; snowflake.state = Snowflake.MODE.INIT;
msg = window.onbeforeunload(); msg = window.onbeforeunload();
expect(snowflake.state).toBe(Snowflake.MODE.INIT); expect(snowflake.state).toBe(Snowflake.MODE.INIT);
return expect(msg).toBe(null); expect(msg).toBe(null);
}); });
return it('does not give a dialog when silent flag is on', function() {
var msg, silenceNotifications; it('does not give a dialog when silent flag is on', function() {
silenceNotifications = true; silenceNotifications = true;
snowflake.state = Snowflake.MODE.WEBRTC_READY; snowflake.state = Snowflake.MODE.WEBRTC_READY;
msg = window.onbeforeunload(); var msg = window.onbeforeunload();
expect(snowflake.state).toBe(Snowflake.MODE.WEBRTC_READY); expect(snowflake.state).toBe(Snowflake.MODE.WEBRTC_READY);
return expect(msg).toBe(null); expect(msg).toBe(null);
}); });
}); });

View file

@ -1,17 +1,15 @@
// Generated by CoffeeScript 2.4.1
/* /*
jasmine tests for Snowflake proxypair jasmine tests for Snowflake proxypair
*/ */
var MessageEvent, arrayMatching;
// Replacement for MessageEvent constructor. // Replacement for MessageEvent constructor.
// https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/MessageEvent // https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/MessageEvent
MessageEvent = function(type, init) { var MessageEvent = function(type, init) {
return init; return init;
}; };
// Asymmetic matcher that checks that two arrays have the same contents. // Asymmetic matcher that checks that two arrays have the same contents.
arrayMatching = function(sample) { var arrayMatching = function(sample) {
return { return {
asymmetricMatch: function(other) { asymmetricMatch: function(other) {
var _, a, b, i, j, len; var _, a, b, i, j, len;
@ -35,46 +33,57 @@ arrayMatching = function(sample) {
}; };
describe('ProxyPair', function() { describe('ProxyPair', function() {
var config, destination, fakeRelay, pp, rateLimit; var config, destination, fakeRelay, pp, rateLimit;
fakeRelay = Parse.address('0.0.0.0:12345'); fakeRelay = Parse.address('0.0.0.0:12345');
rateLimit = new DummyRateLimit; rateLimit = new DummyRateLimit;
config = new Config; config = new Config;
destination = []; destination = [];
// Using the mock PeerConnection definition from spec/snowflake.spec.coffee. // Using the mock PeerConnection definition from spec/snowflake.spec.coffee.
pp = new ProxyPair(fakeRelay, rateLimit, config.pcConfig); var pp = new ProxyPair(fakeRelay, rateLimit, config.pcConfig);
beforeEach(function() { beforeEach(function() {
return pp.begin(); return pp.begin();
}); });
it('begins webrtc connection', function() { it('begins webrtc connection', function() {
return expect(pp.pc).not.toBeNull(); return expect(pp.pc).not.toBeNull();
}); });
describe('accepts WebRTC offer from some client', function() { describe('accepts WebRTC offer from some client', function() {
beforeEach(function() { beforeEach(function() {
return pp.begin(); return pp.begin();
}); });
it('rejects invalid offers', function() { it('rejects invalid offers', function() {
expect(typeof pp.pc.setRemoteDescription).toBe("function"); expect(typeof pp.pc.setRemoteDescription).toBe("function");
expect(pp.pc).not.toBeNull(); expect(pp.pc).not.toBeNull();
expect(pp.receiveWebRTCOffer({})).toBe(false); expect(pp.receiveWebRTCOffer({})).toBe(false);
return expect(pp.receiveWebRTCOffer({ expect(pp.receiveWebRTCOffer({
type: 'answer' type: 'answer'
})).toBe(false); })).toBe(false);
}); });
return it('accepts valid offers', function() {
it('accepts valid offers', function() {
expect(pp.pc).not.toBeNull(); expect(pp.pc).not.toBeNull();
return expect(pp.receiveWebRTCOffer({ expect(pp.receiveWebRTCOffer({
type: 'offer', type: 'offer',
sdp: 'foo' sdp: 'foo'
})).toBe(true); })).toBe(true);
}); });
}); });
it('responds with a WebRTC answer correctly', function() { it('responds with a WebRTC answer correctly', function() {
spyOn(snowflake.broker, 'sendAnswer'); spyOn(snowflake.broker, 'sendAnswer');
pp.pc.onicecandidate({ pp.pc.onicecandidate({
candidate: null candidate: null
}); });
return expect(snowflake.broker.sendAnswer).toHaveBeenCalled(); expect(snowflake.broker.sendAnswer).toHaveBeenCalled();
}); });
it('handles a new data channel correctly', function() { it('handles a new data channel correctly', function() {
expect(pp.client).toBeNull(); expect(pp.client).toBeNull();
pp.pc.ondatachannel({ pp.pc.ondatachannel({
@ -84,21 +93,25 @@ describe('ProxyPair', function() {
expect(pp.client.onopen).not.toBeNull(); expect(pp.client.onopen).not.toBeNull();
expect(pp.client.onclose).not.toBeNull(); expect(pp.client.onclose).not.toBeNull();
expect(pp.client.onerror).not.toBeNull(); expect(pp.client.onerror).not.toBeNull();
return expect(pp.client.onmessage).not.toBeNull(); expect(pp.client.onmessage).not.toBeNull();
}); });
it('connects to the relay once datachannel opens', function() { it('connects to the relay once datachannel opens', function() {
spyOn(pp, 'connectRelay'); spyOn(pp, 'connectRelay');
pp.client.onopen(); pp.client.onopen();
return expect(pp.connectRelay).toHaveBeenCalled(); expect(pp.connectRelay).toHaveBeenCalled();
}); });
it('connects to a relay', function() { it('connects to a relay', function() {
pp.connectRelay(); pp.connectRelay();
expect(pp.relay.onopen).not.toBeNull(); expect(pp.relay.onopen).not.toBeNull();
expect(pp.relay.onclose).not.toBeNull(); expect(pp.relay.onclose).not.toBeNull();
expect(pp.relay.onerror).not.toBeNull(); expect(pp.relay.onerror).not.toBeNull();
return expect(pp.relay.onmessage).not.toBeNull(); expect(pp.relay.onmessage).not.toBeNull();
}); });
return describe('flushes data between client and relay', function() {
describe('flushes data between client and relay', function() {
it('proxies data from client to relay', function() { it('proxies data from client to relay', function() {
var msg; var msg;
pp.pc.ondatachannel({ pp.pc.ondatachannel({
@ -116,8 +129,9 @@ describe('ProxyPair', function() {
pp.onClientToRelayMessage(msg); pp.onClientToRelayMessage(msg);
pp.flush(); pp.flush();
expect(pp.client.send).not.toHaveBeenCalled(); expect(pp.client.send).not.toHaveBeenCalled();
return expect(pp.relay.send).toHaveBeenCalledWith(arrayMatching([1, 2, 3])); expect(pp.relay.send).toHaveBeenCalledWith(arrayMatching([1, 2, 3]));
}); });
it('proxies data from relay to client', function() { it('proxies data from relay to client', function() {
var msg; var msg;
spyOn(pp.client, 'send'); spyOn(pp.client, 'send');
@ -128,16 +142,19 @@ describe('ProxyPair', function() {
pp.onRelayToClientMessage(msg); pp.onRelayToClientMessage(msg);
pp.flush(); pp.flush();
expect(pp.client.send).toHaveBeenCalledWith(arrayMatching([4, 5, 6])); expect(pp.client.send).toHaveBeenCalledWith(arrayMatching([4, 5, 6]));
return expect(pp.relay.send).not.toHaveBeenCalled(); expect(pp.relay.send).not.toHaveBeenCalled();
}); });
return it('sends nothing with nothing to flush', function() {
it('sends nothing with nothing to flush', function() {
spyOn(pp.client, 'send'); spyOn(pp.client, 'send');
spyOn(pp.relay, 'send'); spyOn(pp.relay, 'send');
pp.flush(); pp.flush();
expect(pp.client.send).not.toHaveBeenCalled(); expect(pp.client.send).not.toHaveBeenCalled();
return expect(pp.relay.send).not.toHaveBeenCalled(); expect(pp.relay.send).not.toHaveBeenCalled();
}); });
}); });
}); });
// TODO: rate limit tests // TODO: rate limit tests

View file

@ -1,62 +1,43 @@
// Generated by CoffeeScript 2.4.1
/* /*
jasmine tests for Snowflake jasmine tests for Snowflake
*/ */
var FakeBroker, PeerConnection, SessionDescription, WebSocket, config, log, ui;
// Fake browser functionality: // Fake browser functionality:
PeerConnection = class PeerConnection { class PeerConnection {
setRemoteDescription() { setRemoteDescription() {
return true; return true;
} }
send(data) {} send(data) {}
}; };
SessionDescription = (function() { class SessionDescription {};
class SessionDescription {}; SessionDescription.prototype.type = 'offer';
SessionDescription.prototype.type = 'offer'; class WebSocket {
return SessionDescription;
}).call(this);
WebSocket = (function() {
class WebSocket {
constructor() { constructor() {
this.bufferedAmount = 0; this.bufferedAmount = 0;
} }
send(data) {} send(data) {}
};
WebSocket.prototype.OPEN = 1;
WebSocket.prototype.CLOSED = 0;
}; var log = function() {};
WebSocket.prototype.OPEN = 1; var config = new Config;
WebSocket.prototype.CLOSED = 0; var ui = new UI;
return WebSocket; class FakeBroker {
}).call(this);
log = function() {};
config = new Config;
ui = new UI;
FakeBroker = class FakeBroker {
getClientOffer() { getClientOffer() {
return new Promise(function(F, R) { return new Promise(function(F, R) {
return {}; return {};
}); });
} }
}; };
describe('Snowflake', function() { describe('Snowflake', function() {
it('constructs correctly', function() { it('constructs correctly', function() {
var s; var s;
s = new Snowflake(config, ui, { s = new Snowflake(config, ui, {
@ -67,22 +48,25 @@ describe('Snowflake', function() {
fake: 'broker' fake: 'broker'
}); });
expect(s.ui).not.toBeNull(); expect(s.ui).not.toBeNull();
return expect(s.retries).toBe(0); expect(s.retries).toBe(0);
}); });
it('sets relay address correctly', function() { it('sets relay address correctly', function() {
var s; var s;
s = new Snowflake(config, ui, null); s = new Snowflake(config, ui, null);
s.setRelayAddr('foo'); s.setRelayAddr('foo');
return expect(s.relayAddr).toEqual('foo'); expect(s.relayAddr).toEqual('foo');
}); });
it('initalizes WebRTC connection', function() { it('initalizes WebRTC connection', function() {
var s; var s;
s = new Snowflake(config, ui, new FakeBroker()); s = new Snowflake(config, ui, new FakeBroker());
spyOn(s.broker, 'getClientOffer').and.callThrough(); spyOn(s.broker, 'getClientOffer').and.callThrough();
s.beginWebRTC(); s.beginWebRTC();
expect(s.retries).toBe(1); expect(s.retries).toBe(1);
return expect(s.broker.getClientOffer).toHaveBeenCalled(); expect(s.broker.getClientOffer).toHaveBeenCalled();
}); });
it('receives SDP offer and sends answer', function() { it('receives SDP offer and sends answer', function() {
var pair, s; var pair, s;
s = new Snowflake(config, ui, new FakeBroker()); s = new Snowflake(config, ui, new FakeBroker());
@ -92,8 +76,9 @@ describe('Snowflake', function() {
spyOn(pair, 'receiveWebRTCOffer').and.returnValue(true); spyOn(pair, 'receiveWebRTCOffer').and.returnValue(true);
spyOn(s, 'sendAnswer'); spyOn(s, 'sendAnswer');
s.receiveOffer(pair, '{"type":"offer","sdp":"foo"}'); s.receiveOffer(pair, '{"type":"offer","sdp":"foo"}');
return expect(s.sendAnswer).toHaveBeenCalled(); expect(s.sendAnswer).toHaveBeenCalled();
}); });
it('does not send answer when receiving invalid offer', function() { it('does not send answer when receiving invalid offer', function() {
var pair, s; var pair, s;
s = new Snowflake(config, ui, new FakeBroker()); s = new Snowflake(config, ui, new FakeBroker());
@ -103,12 +88,14 @@ describe('Snowflake', function() {
spyOn(pair, 'receiveWebRTCOffer').and.returnValue(false); spyOn(pair, 'receiveWebRTCOffer').and.returnValue(false);
spyOn(s, 'sendAnswer'); spyOn(s, 'sendAnswer');
s.receiveOffer(pair, '{"type":"not a good offer","sdp":"foo"}'); s.receiveOffer(pair, '{"type":"not a good offer","sdp":"foo"}');
return expect(s.sendAnswer).not.toHaveBeenCalled(); expect(s.sendAnswer).not.toHaveBeenCalled();
}); });
return it('can make a proxypair', function() {
it('can make a proxypair', function() {
var s; var s;
s = new Snowflake(config, ui, new FakeBroker()); s = new Snowflake(config, ui, new FakeBroker());
s.makeProxyPair(); s.makeProxyPair();
return expect(s.proxyPairs.length).toBe(1); expect(s.proxyPairs.length).toBe(1);
}); });
}); });

View file

@ -1,10 +1,7 @@
// Generated by CoffeeScript 2.4.1
/* /*
jasmine tests for Snowflake UI jasmine tests for Snowflake UI
*/ */
var document; var document = {
document = {
getElementById: function(id) { getElementById: function(id) {
return {}; return {};
}, },
@ -14,6 +11,7 @@ document = {
}; };
describe('UI', function() { describe('UI', function() {
it('activates debug mode when badge does not exist', function() { it('activates debug mode when badge does not exist', function() {
var u; var u;
spyOn(document, 'getElementById').and.callFake(function(id) { spyOn(document, 'getElementById').and.callFake(function(id) {
@ -25,8 +23,9 @@ describe('UI', function() {
u = new DebugUI(); u = new DebugUI();
expect(document.getElementById.calls.count()).toEqual(2); expect(document.getElementById.calls.count()).toEqual(2);
expect(u.$status).not.toBeNull(); expect(u.$status).not.toBeNull();
return expect(u.$msglog).not.toBeNull(); expect(u.$msglog).not.toBeNull();
}); });
it('is not debug mode when badge exists', function() { it('is not debug mode when badge exists', function() {
var u; var u;
spyOn(document, 'getElementById').and.callFake(function(id) { spyOn(document, 'getElementById').and.callFake(function(id) {
@ -38,8 +37,9 @@ describe('UI', function() {
u = new BadgeUI(); u = new BadgeUI();
expect(document.getElementById).toHaveBeenCalled(); expect(document.getElementById).toHaveBeenCalled();
expect(document.getElementById.calls.count()).toEqual(1); expect(document.getElementById.calls.count()).toEqual(1);
return expect(u.$badge).not.toBeNull(); expect(u.$badge).not.toBeNull();
}); });
it('sets status message when in debug mode', function() { it('sets status message when in debug mode', function() {
var u; var u;
u = new DebugUI(); u = new DebugUI();
@ -50,16 +50,18 @@ describe('UI', function() {
} }
}; };
u.setStatus('test'); u.setStatus('test');
return expect(u.$status.innerHTML).toEqual('Status: test'); expect(u.$status.innerHTML).toEqual('Status: test');
}); });
it('sets message log css correctly for debug mode', function() { it('sets message log css correctly for debug mode', function() {
var u; var u;
u = new DebugUI(); u = new DebugUI();
u.setActive(true); u.setActive(true);
expect(u.$msglog.className).toEqual('active'); expect(u.$msglog.className).toEqual('active');
u.setActive(false); u.setActive(false);
return expect(u.$msglog.className).toEqual(''); expect(u.$msglog.className).toEqual('');
}); });
it('sets badge css correctly for non-debug mode', function() { it('sets badge css correctly for non-debug mode', function() {
var u; var u;
u = new BadgeUI(); u = new BadgeUI();
@ -67,9 +69,10 @@ describe('UI', function() {
u.setActive(true); u.setActive(true);
expect(u.$badge.className).toEqual('active'); expect(u.$badge.className).toEqual('active');
u.setActive(false); u.setActive(false);
return expect(u.$badge.className).toEqual(''); expect(u.$badge.className).toEqual('');
}); });
return it('logs to the textarea correctly when debug mode', function() {
it('logs to the textarea correctly when debug mode', function() {
var u; var u;
u = new DebugUI(); u = new DebugUI();
u.$msglog = { u.$msglog = {
@ -79,6 +82,7 @@ describe('UI', function() {
}; };
u.log('test'); u.log('test');
expect(u.$msglog.value).toEqual('test\n'); expect(u.$msglog.value).toEqual('test\n');
return expect(u.$msglog.scrollTop).toEqual(1337); expect(u.$msglog.scrollTop).toEqual(1337);
}); });
}); });

View file

@ -1,10 +1,12 @@
// Generated by CoffeeScript 2.4.1
/* /*
jasmine tests for Snowflake utils jasmine tests for Snowflake utils
*/ */
describe('Parse', function() { describe('Parse', function() {
describe('cookie', function() { describe('cookie', function() {
return it('parses correctly', function() {
it('parses correctly', function() {
expect(Parse.cookie('')).toEqual({}); expect(Parse.cookie('')).toEqual({});
expect(Parse.cookie('a=b')).toEqual({ expect(Parse.cookie('a=b')).toEqual({
a: 'b' a: 'b'
@ -30,12 +32,15 @@ describe('Parse', function() {
expect(Parse.cookie('key=%26%20')).toEqual({ expect(Parse.cookie('key=%26%20')).toEqual({
key: '& ' key: '& '
}); });
return expect(Parse.cookie('a=\'\'')).toEqual({ expect(Parse.cookie('a=\'\'')).toEqual({
a: '\'\'' a: '\'\''
}); });
}); });
}); });
describe('address', function() { describe('address', function() {
it('parses IPv4', function() { it('parses IPv4', function() {
expect(Parse.address('')).toBeNull(); expect(Parse.address('')).toBeNull();
expect(Parse.address('3.3.3.3:4444')).toEqual({ expect(Parse.address('3.3.3.3:4444')).toEqual({
@ -45,9 +50,10 @@ describe('Parse', function() {
expect(Parse.address('3.3.3.3')).toBeNull(); expect(Parse.address('3.3.3.3')).toBeNull();
expect(Parse.address('3.3.3.3:0x1111')).toBeNull(); expect(Parse.address('3.3.3.3:0x1111')).toBeNull();
expect(Parse.address('3.3.3.3:-4444')).toBeNull(); expect(Parse.address('3.3.3.3:-4444')).toBeNull();
return expect(Parse.address('3.3.3.3:65536')).toBeNull(); expect(Parse.address('3.3.3.3:65536')).toBeNull();
}); });
return it('parses IPv6', function() {
it('parses IPv6', function() {
expect(Parse.address('[1:2::a:f]:4444')).toEqual({ expect(Parse.address('[1:2::a:f]:4444')).toEqual({
host: '1:2::a:f', host: '1:2::a:f',
port: 4444 port: 4444
@ -56,15 +62,17 @@ describe('Parse', function() {
expect(Parse.address('[1:2::a:f]:0x1111')).toBeNull(); expect(Parse.address('[1:2::a:f]:0x1111')).toBeNull();
expect(Parse.address('[1:2::a:f]:-4444')).toBeNull(); expect(Parse.address('[1:2::a:f]:-4444')).toBeNull();
expect(Parse.address('[1:2::a:f]:65536')).toBeNull(); expect(Parse.address('[1:2::a:f]:65536')).toBeNull();
return expect(Parse.address('[1:2::ffff:1.2.3.4]:4444')).toEqual({ expect(Parse.address('[1:2::ffff:1.2.3.4]:4444')).toEqual({
host: '1:2::ffff:1.2.3.4', host: '1:2::ffff:1.2.3.4',
port: 4444 port: 4444
}); });
}); });
}); });
return describe('ipFromSDP', function() {
var testCases; describe('ipFromSDP', function() {
testCases = [
var testCases = [
{ {
// https://tools.ietf.org/html/rfc4566#section-5 // https://tools.ietf.org/html/rfc4566#section-5
sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 224.2.17.12/127\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000", sdp: "v=0\no=jdoe 2890844526 2890842807 IN IP4 10.47.16.5\ns=SDP Seminar\ni=A Seminar on the session description protocol\nu=http://www.example.com/seminars/sdp.pdf\ne=j.doe@example.com (Jane Doe)\nc=IN IP4 224.2.17.12/127\nt=2873397496 2873404696\na=recvonly\nm=audio 49170 RTP/AVP 0\nm=video 51372 RTP/AVP 99\na=rtpmap:99 h263-1998/90000",
@ -128,7 +136,8 @@ describe('Parse', function() {
expected: void 0 expected: void 0
} }
]; ];
return it('parses SDP', function() {
it('parses SDP', function() {
var i, len, ref, ref1, results, test; var i, len, ref, ref1, results, test;
results = []; results = [];
for (i = 0, len = testCases.length; i < len; i++) { for (i = 0, len = testCases.length; i < len; i++) {
@ -143,10 +152,13 @@ describe('Parse', function() {
} }
return results; return results;
}); });
}); });
}); });
describe('query string', function() { describe('query string', function() {
it('should parse correctly', function() { it('should parse correctly', function() {
expect(Query.parse('')).toEqual({}); expect(Query.parse('')).toEqual({});
expect(Query.parse('a=b')).toEqual({ expect(Query.parse('a=b')).toEqual({
@ -178,11 +190,12 @@ describe('query string', function() {
expect(Query.parse('a+b=c')).toEqual({ expect(Query.parse('a+b=c')).toEqual({
'a b': 'c' 'a b': 'c'
}); });
return expect(Query.parse('a=b+c+d')).toEqual({ expect(Query.parse('a=b+c+d')).toEqual({
a: 'b c d' a: 'b c d'
}); });
}); });
return it('uses the first appearance of duplicate key', function() {
it('uses the first appearance of duplicate key', function() {
expect(Query.parse('a=b&c=d&a=e')).toEqual({ expect(Query.parse('a=b&c=d&a=e')).toEqual({
a: 'b', a: 'b',
c: 'd' c: 'd'
@ -201,21 +214,24 @@ describe('query string', function() {
a: 'b', a: 'b',
'': '' '': ''
}); });
return expect(Query.parse('a=b&&c=d')).toEqual({ expect(Query.parse('a=b&&c=d')).toEqual({
a: 'b', a: 'b',
'': '', '': '',
c: 'd' c: 'd'
}); });
}); });
}); });
describe('Params', function() { describe('Params', function() {
describe('bool', function() { describe('bool', function() {
var getBool;
getBool = function(query) { var getBool = function(query) {
return Params.getBool(Query.parse(query), 'param', false); return Params.getBool(Query.parse(query), 'param', false);
}; };
return it('parses correctly', function() {
it('parses correctly', function() {
expect(getBool('param=true')).toBe(true); expect(getBool('param=true')).toBe(true);
expect(getBool('param')).toBe(true); expect(getBool('param')).toBe(true);
expect(getBool('param=')).toBe(true); expect(getBool('param=')).toBe(true);
@ -223,19 +239,23 @@ describe('Params', function() {
expect(getBool('param=0')).toBe(false); expect(getBool('param=0')).toBe(false);
expect(getBool('param=false')).toBe(false); expect(getBool('param=false')).toBe(false);
expect(getBool('param=unexpected')).toBeNull(); expect(getBool('param=unexpected')).toBeNull();
return expect(getBool('pram=true')).toBe(false); expect(getBool('pram=true')).toBe(false);
}); });
}); });
return describe('address', function() {
var DEFAULT, getAddress; describe('address', function() {
DEFAULT = {
var DEFAULT = {
host: '1.1.1.1', host: '1.1.1.1',
port: 2222 port: 2222
}; };
getAddress = function(query) {
var getAddress = function(query) {
return Params.getAddress(query, 'addr', DEFAULT); return Params.getAddress(query, 'addr', DEFAULT);
}; };
return it('parses correctly', function() {
it('parses correctly', function() {
expect(getAddress({})).toEqual(DEFAULT); expect(getAddress({})).toEqual(DEFAULT);
expect(getAddress({ expect(getAddress({
addr: '3.3.3.3:4444' addr: '3.3.3.3:4444'
@ -246,9 +266,11 @@ describe('Params', function() {
expect(getAddress({ expect(getAddress({
x: '3.3.3.3:4444' x: '3.3.3.3:4444'
})).toEqual(DEFAULT); })).toEqual(DEFAULT);
return expect(getAddress({ expect(getAddress({
addr: '---' addr: '---'
})).toBeNull(); })).toBeNull();
}); });
}); });
}); });

View file

@ -1,32 +1,39 @@
// Generated by CoffeeScript 2.4.1
/* /*
jasmine tests for Snowflake websocket jasmine tests for Snowflake websocket
*/ */
describe('BuildUrl', function() { describe('BuildUrl', function() {
it('should parse just protocol and host', function() { it('should parse just protocol and host', function() {
return expect(WS.buildUrl('http', 'example.com')).toBe('http://example.com'); expect(WS.buildUrl('http', 'example.com')).toBe('http://example.com');
}); });
it('should handle different ports', function() { it('should handle different ports', function() {
expect(WS.buildUrl('http', 'example.com', 80)).toBe('http://example.com'); expect(WS.buildUrl('http', 'example.com', 80)).toBe('http://example.com');
expect(WS.buildUrl('http', 'example.com', 81)).toBe('http://example.com:81'); expect(WS.buildUrl('http', 'example.com', 81)).toBe('http://example.com:81');
expect(WS.buildUrl('http', 'example.com', 443)).toBe('http://example.com:443'); expect(WS.buildUrl('http', 'example.com', 443)).toBe('http://example.com:443');
return expect(WS.buildUrl('http', 'example.com', 444)).toBe('http://example.com:444'); expect(WS.buildUrl('http', 'example.com', 444)).toBe('http://example.com:444');
}); });
it('should handle paths', function() { it('should handle paths', function() {
expect(WS.buildUrl('http', 'example.com', 80, '/')).toBe('http://example.com/'); expect(WS.buildUrl('http', 'example.com', 80, '/')).toBe('http://example.com/');
expect(WS.buildUrl('http', 'example.com', 80, '/test?k=%#v')).toBe('http://example.com/test%3Fk%3D%25%23v'); expect(WS.buildUrl('http', 'example.com', 80, '/test?k=%#v')).toBe('http://example.com/test%3Fk%3D%25%23v');
return expect(WS.buildUrl('http', 'example.com', 80, '/test')).toBe('http://example.com/test'); expect(WS.buildUrl('http', 'example.com', 80, '/test')).toBe('http://example.com/test');
}); });
it('should handle params', function() { it('should handle params', function() {
expect(WS.buildUrl('http', 'example.com', 80, '/test', [['k', '%#v']])).toBe('http://example.com/test?k=%25%23v'); expect(WS.buildUrl('http', 'example.com', 80, '/test', [['k', '%#v']])).toBe('http://example.com/test?k=%25%23v');
return expect(WS.buildUrl('http', 'example.com', 80, '/test', [['a', 'b'], ['c', 'd']])).toBe('http://example.com/test?a=b&c=d'); expect(WS.buildUrl('http', 'example.com', 80, '/test', [['a', 'b'], ['c', 'd']])).toBe('http://example.com/test?a=b&c=d');
}); });
it('should handle ips', function() { it('should handle ips', function() {
expect(WS.buildUrl('http', '1.2.3.4')).toBe('http://1.2.3.4'); expect(WS.buildUrl('http', '1.2.3.4')).toBe('http://1.2.3.4');
return expect(WS.buildUrl('http', '1:2::3:4')).toBe('http://[1:2::3:4]'); expect(WS.buildUrl('http', '1:2::3:4')).toBe('http://[1:2::3:4]');
}); });
return it('should handle bogus', function() {
it('should handle bogus', function() {
expect(WS.buildUrl('http', 'bog][us')).toBe('http://bog%5D%5Bus'); expect(WS.buildUrl('http', 'bog][us')).toBe('http://bog%5D%5Bus');
return expect(WS.buildUrl('http', 'bog:u]s')).toBe('http://bog%3Au%5Ds'); expect(WS.buildUrl('http', 'bog:u]s')).toBe('http://bog%3Au%5Ds');
}); });
}); });

View file

@ -1,12 +1,9 @@
// Generated by CoffeeScript 2.4.1 /*
/* All of Snowflake's DOM manipulation and inputs.
All of Snowflake's DOM manipulation and inputs. */
*/
var BadgeUI, DebugUI, UI, WebExtUI, class UI {
boundMethodCheck = function(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new Error('Bound instance method accessed before binding'); } };
UI = (function() {
class UI {
setStatus(msg) {} setStatus(msg) {}
setActive(connected) { setActive(connected) {
@ -15,18 +12,15 @@ UI = (function() {
log(msg) {} log(msg) {}
}; };
UI.prototype.active = false; UI.prototype.active = false;
UI.prototype.enabled = true; UI.prototype.enabled = true;
return UI;
}).call(this); class BadgeUI extends UI {
BadgeUI = (function() {
class BadgeUI extends UI {
constructor() { constructor() {
super(); super();
this.$badge = document.getElementById('badge'); this.$badge = document.getElementById('badge');
@ -37,16 +31,13 @@ BadgeUI = (function() {
return this.$badge.className = connected ? 'active' : ''; return this.$badge.className = connected ? 'active' : '';
} }
}; };
BadgeUI.prototype.$badge = null; BadgeUI.prototype.$badge = null;
return BadgeUI;
}).call(this); class DebugUI extends UI {
DebugUI = (function() {
class DebugUI extends UI {
constructor() { constructor() {
super(); super();
// Setup other DOM handlers if it's debug mode. // Setup other DOM handlers if it's debug mode.
@ -76,19 +67,16 @@ DebugUI = (function() {
return this.$msglog.scrollTop = this.$msglog.scrollHeight; return this.$msglog.scrollTop = this.$msglog.scrollHeight;
} }
}; };
// DOM elements references. // DOM elements references.
DebugUI.prototype.$msglog = null; DebugUI.prototype.$msglog = null;
DebugUI.prototype.$status = null; DebugUI.prototype.$status = null;
return DebugUI;
}).call(this); class WebExtUI extends UI {
WebExtUI = (function() {
class WebExtUI extends UI {
constructor() { constructor() {
super(); super();
this.onConnect = this.onConnect.bind(this); this.onConnect = this.onConnect.bind(this);
@ -131,7 +119,6 @@ WebExtUI = (function() {
} }
onConnect(port) { onConnect(port) {
boundMethodCheck(this, WebExtUI);
this.port = port; this.port = port;
port.onDisconnect.addListener(this.onDisconnect); port.onDisconnect.addListener(this.onDisconnect);
port.onMessage.addListener(this.onMessage); port.onMessage.addListener(this.onMessage);
@ -140,7 +127,6 @@ WebExtUI = (function() {
onMessage(m) { onMessage(m) {
var storing; var storing;
boundMethodCheck(this, WebExtUI);
this.enabled = m.enabled; this.enabled = m.enabled;
this.setEnabled(this.enabled); this.setEnabled(this.enabled);
this.postActive(); this.postActive();
@ -152,7 +138,6 @@ WebExtUI = (function() {
} }
onDisconnect(port) { onDisconnect(port) {
boundMethodCheck(this, WebExtUI);
return this.port = null; return this.port = null;
} }
@ -186,12 +171,8 @@ WebExtUI = (function() {
}); });
} }
}; };
WebExtUI.prototype.port = null; WebExtUI.prototype.port = null;
WebExtUI.prototype.stats = null; WebExtUI.prototype.stats = null;
return WebExtUI;
}).call(this);

View file

@ -1,13 +1,11 @@
// Generated by CoffeeScript 2.4.1
/* /*
A Coffeescript WebRTC snowflake proxy A Coffeescript WebRTC snowflake proxy
Contains helpers for parsing query strings and other utilities. Contains helpers for parsing query strings and other utilities.
*/ */
var BucketRateLimit, DummyRateLimit, Params, Parse, Query, Util;
Util = (function() { class Util {
class Util {
static mightBeTBB() { static mightBeTBB() {
return Util.TBB_UAS.indexOf(window.navigator.userAgent) > -1 && (window.navigator.mimeTypes && window.navigator.mimeTypes.length === 0); return Util.TBB_UAS.indexOf(window.navigator.userAgent) > -1 && (window.navigator.mimeTypes && window.navigator.mimeTypes.length === 0);
} }
@ -36,18 +34,21 @@ Util = (function() {
return typeof PeerConnection === 'function'; return typeof PeerConnection === 'function';
} }
}; };
// It would not be effective for Tor Browser users to run the proxy. // It would not be effective for Tor Browser users to run the proxy.
// Do we seem to be running in Tor Browser? Check the user-agent string and for // Do we seem to be running in Tor Browser? Check the user-agent string and for
// no listing of supported MIME types. // no listing of supported MIME types.
Util.TBB_UAS = ['Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0', 'Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0', 'Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0', 'Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0']; Util.TBB_UAS = [
'Mozilla/5.0 (Windows NT 6.1; rv:10.0) Gecko/20100101 Firefox/10.0',
'Mozilla/5.0 (Windows NT 6.1; rv:17.0) Gecko/20100101 Firefox/17.0',
'Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0',
'Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0'
];
return Util;
}).call(this); class Query {
Query = class Query {
/* /*
Parse a URL query string or application/x-www-form-urlencoded body. The Parse a URL query string or application/x-www-form-urlencoded body. The
return type is an object mapping string keys to string values. By design, return type is an object mapping string keys to string values. By design,
@ -100,7 +101,9 @@ Query = class Query {
}; };
Parse = class Parse {
class Parse {
// Parse a cookie data string (usually document.cookie). The return type is an // Parse a cookie data string (usually document.cookie). The return type is an
// object mapping cookies names to values. Returns null on error. // object mapping cookies names to values. Returns null on error.
// http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-8747038 // http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-8747038
@ -202,7 +205,9 @@ Parse = class Parse {
}; };
Params = class Params {
class Params {
static getBool(query, param, defaultValue) { static getBool(query, param, defaultValue) {
var val; var val;
val = query[param]; val = query[param];
@ -254,8 +259,9 @@ Params = class Params {
}; };
BucketRateLimit = (function() {
class BucketRateLimit { class BucketRateLimit {
constructor(capacity, time) { constructor(capacity, time) {
this.capacity = capacity; this.capacity = capacity;
this.time = time; this.time = time;
@ -289,18 +295,16 @@ BucketRateLimit = (function() {
return this.amount > this.capacity; return this.amount > this.capacity;
} }
}; };
BucketRateLimit.prototype.amount = 0.0; BucketRateLimit.prototype.amount = 0.0;
BucketRateLimit.prototype.lastUpdate = new Date(); BucketRateLimit.prototype.lastUpdate = new Date();
return BucketRateLimit;
}).call(this);
// A rate limiter that never limits. // A rate limiter that never limits.
DummyRateLimit = class DummyRateLimit { class DummyRateLimit {
constructor(capacity, time) { constructor(capacity, time) {
this.capacity = capacity; this.capacity = capacity;
this.time = time; this.time = time;

View file

@ -1,11 +1,9 @@
// Generated by CoffeeScript 2.4.1
/* /*
Only websocket-specific stuff. Only websocket-specific stuff.
*/ */
var WS;
WS = (function() { class WS {
class WS {
// Build an escaped URL string from unescaped components. Only scheme and host // Build an escaped URL string from unescaped components. Only scheme and host
// are required. See RFC 3986, section 3. // are required. See RFC 3986, section 3.
static buildUrl(scheme, host, port, path, params) { static buildUrl(scheme, host, port, path, params) {
@ -56,15 +54,11 @@ WS = (function() {
return ws; return ws;
} }
}; };
WS.WSS_ENABLED = true; WS.WSS_ENABLED = true;
WS.DEFAULT_PORTS = { WS.DEFAULT_PORTS = {
http: 80, http: 80,
https: 443 https: 443
}; };
return WS;
}).call(this);