Commit a dist folder
This commit is contained in:
parent
dce88a309d
commit
0551df6c40
12 changed files with 22916 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,5 +1,4 @@
|
|||
node_modules
|
||||
dist
|
||||
bower_components
|
||||
.tmp
|
||||
.publish/
|
||||
|
|
23
dist/index.js
vendored
Normal file
23
dist/index.js
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
var express = require('express');
|
||||
var compression = require('compression');
|
||||
var app = express();
|
||||
var http = require('http');
|
||||
var ExpressPeerServer = require('peer').ExpressPeerServer;
|
||||
var wsServer = require('./server/ws-server.js');
|
||||
|
||||
var server = http.createServer(app);
|
||||
|
||||
// Serve up content from public directory
|
||||
app.use(compression());
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
var port = process.env.PORT || 3002;
|
||||
server.listen(port);
|
||||
wsServer.create(server);
|
||||
app.use('/peerjs', ExpressPeerServer(server, {
|
||||
debug: true
|
||||
}));
|
||||
|
||||
|
||||
console.log('listening on port ' + port);
|
14
dist/package.json
vendored
Normal file
14
dist/package.json
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"binaryjs": "^0.2.1",
|
||||
"compression": "^1.6.0",
|
||||
"express": "^4.13.3",
|
||||
"peer": "^0.2.8",
|
||||
"ua-parser-js": "^0.7.10",
|
||||
"ws": "^1.1.1"
|
||||
}
|
||||
}
|
22671
dist/public/elements/elements.html
vendored
Normal file
22671
dist/public/elements/elements.html
vendored
Normal file
File diff suppressed because one or more lines are too long
18
dist/public/index.html
vendored
Normal file
18
dist/public/index.html
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!doctype html><html lang="en"><head>
|
||||
<meta charset="utf-8"><meta name="viewport" content="width=device-width initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><meta name="generator" content="Snapdrop"><title>Snapdrop</title><link rel="shortcut icon" href="favicon.ico?v=3"><meta name="theme-color" content="#3367d6"><link rel="manifest" href="manifest.json"><meta name="msapplication-TileColor" content="#3372DF"><meta name="mobile-web-app-capable" content="yes"><meta name="application-name" content="PSK"><link rel="icon" sizes="192x192" href="images/touch/chrome-touch-icon-192x192.png"><link rel="fluid-icon" type="image/png" href="images/touch/chrome-touch-icon-192x192.png"><meta name="description" content="Snapdrop is an easy way to transfer files. Instantly share images, video, PDF, and links across devices. Peer2Peer, Private, Secure and Open Source. No Setup, No Signup."><meta property="og:image" content="https://snapdrop.net/images/touch/chrome-splashscreen-icon-384x384.png"><meta property="og:url" content="https://snapdrop.net/"><meta name="twitter:image" content="https://snapdrop.net/images/touch/chrome-splashscreen-icon-384x384.png"><meta name="twitter:author" content="@RobinLinus"><meta property="og:type" content="article"><meta property="og:author" content="https://facebook.com/RobinLinus"><meta property="fb:pages" content="451189218422617"><meta property="fb:profile_id" content="451189218422617"><meta name="twitter:description" content="Snapdrop is an easy way to transfer files. Instantly share images, video, PDF, and links across devices. Peer2Peer, Private, Secure and Open Source. No Setup, No Signup."><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-title" content="Snapdrop"><link rel="apple-touch-icon" href="images/touch/apple-touch-icon.png"><meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png"><link rel="stylesheet" href="styles/main.css"><script src="bower_components/webcomponentsjs/webcomponents-lite.min.js" async="" foo="1"></script><link rel="import" href="elements/elements.html" async="true"></head><body class="layout vertical">
|
||||
<script>"use strict";!function(){function n(){u=window.innerWidth,m=window.innerHeight,a.width=u,a.height=m;var n=m>370?100:65;w=u/2,d=m-n,c=Math.max(u,m,1e3)/13,i()}function t(n){s.beginPath();var t=Math.round(255*(1-n/Math.max(u,m)));s.strokeStyle="rgba("+t+","+t+","+t+",0.1)",s.arc(w,d,n,0,2*Math.PI),s.stroke(),s.lineWidth=2}function i(){s.clearRect(0,0,u,m);for(var n=0;8>n;n++)t(c*n+h%c);h+=1}function e(){(f||c-5>h%c)&&o(function(){i(),e()})}var o=function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(n){window.setTimeout(n,1e3/60)}}(),a=document.createElement("canvas");document.body.appendChild(a);var r=a.style;r.width="100%",r.position="absolute";var w,d,u,m,c,s=a.getContext("2d");window.onresize=n;var h=0,f=!0;window.anim=function(n){f=n,e()},n(),e()}();</script><span id="browser-sync-binding"></span><template is="dom-bind" id="app"><connection-wrapper me="{{me}}" loading="{{loading}}" buddies="{{buddies}}"></connection-wrapper><neon-animated-pages id="pages" selected="0"><x-cards on-switch="_showAbout"><div><paper-progress indeterminate="" hidden$="{{!loading}}"></paper-progress><buddy-finder me="{{me}}" active$="{{loading}}" buddies="{{buddies}}"></buddy-finder></div></x-cards><about-page on-switch="_showApp"></about-page></neon-animated-pages><file-receiver></file-receiver><paper-toast id="toast" duration="6000"></paper-toast><paper-toast id="caching-complete" duration="6000" text="Caching complete! This app will work offline."></paper-toast><donate-dialog></donate-dialog><platinum-sw-register auto-register="" clients-claim="" skip-waiting="" base-uri="bower_components/platinum-sw/bootstrap" on-service-worker-installed="displayInstalledToast"><platinum-sw-cache default-cache-strategy="fastest" cache-config-file="cache-config.json"></platinum-sw-cache></platinum-sw-register></template><script src="scripts/app.js"></script><script>
|
||||
(function(i, s, o, g, r, a, m) {
|
||||
i['GoogleAnalyticsObject'] = r;
|
||||
i[r] = i[r] || function() {
|
||||
(i[r].q = i[r].q || []).push(arguments)
|
||||
}, i[r].l = 1 * new Date();
|
||||
a = s.createElement(o),
|
||||
m = s.getElementsByTagName(o)[0];
|
||||
a.async = 1;
|
||||
a.src = g;
|
||||
m.parentNode.insertBefore(a, m)
|
||||
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
|
||||
|
||||
ga('create', 'UA-71686975-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script></body></html>
|
29
dist/public/manifest.json
vendored
Normal file
29
dist/public/manifest.json
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"name": "Snapdrop",
|
||||
"short_name": "Snapdrop",
|
||||
"icons": [{
|
||||
"src": "images/touch/icon-128x128.png",
|
||||
"sizes": "128x128",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/touch/apple-touch-icon.png",
|
||||
"sizes": "152x152",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/touch/ms-touch-icon-144x144-precomposed.png",
|
||||
"sizes": "144x144",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/touch/chrome-touch-icon-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
}, {
|
||||
"src": "images/touch/chrome-splashscreen-icon-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
}],
|
||||
"background_color": "#3367d6",
|
||||
"start_url": "index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#3367d6"
|
||||
}
|
1
dist/public/scripts/app.js
vendored
Normal file
1
dist/public/scripts/app.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
!function(e){"use strict";var o=e.querySelector("#app");o.baseUrl="/",""===window.location.port,o.displayInstalledToast=function(){Polymer.dom(e).querySelector("platinum-sw-cache").disabled||Polymer.dom(e).querySelector("#caching-complete").show()},o.displayToast=function(o){var t=Polymer.dom(e).querySelector("#toast");t.text=o,t.show()},o.addEventListener("dom-change",function(){console.log("Our app is ready to rock!"),o.conn=e.querySelector("connection-wrapper")}),window.addEventListener("WebComponentsReady",function(){}),o._showAbout=function(){e.querySelector("#pages").select(1)},o._showAbout=function(){e.querySelector("#pages").select(0)}}(document);
|
BIN
dist/public/sounds/blop.mp3
vendored
Executable file
BIN
dist/public/sounds/blop.mp3
vendored
Executable file
Binary file not shown.
BIN
dist/public/sounds/blop.ogg
vendored
Normal file
BIN
dist/public/sounds/blop.ogg
vendored
Normal file
Binary file not shown.
1
dist/public/styles/main.css
vendored
Normal file
1
dist/public/styles/main.css
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
body,html{height:100%;width:100%;padding:0;margin:0}body{background:#fafafa;font-family:Roboto,'Helvetica Neue',Helvetica,Arial,sans-serif;color:#333;-webkit-font-smoothing:antialiased;overflow-x:hidden}#ads,#ads2{display:none}@media screen and (min-width:520px){#ads{display:block;position:absolute;top:8px;left:50%;margin-left:-150px}}@media screen and (min-width:720px){#ads{display:none}#ads2{display:block;position:absolute;bottom:4px;left:4px}}
|
5
dist/readme.md
vendored
Normal file
5
dist/readme.md
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Run a Snapdrop Server
|
||||
- `npm install`
|
||||
- `node index.js`
|
||||
- TODO: SSL connection (i.e nginx)
|
||||
- ( Please do a PR if you've build an alternative index.js with a self-signed cert )
|
154
dist/server/ws-server.js
vendored
Normal file
154
dist/server/ws-server.js
vendored
Normal file
|
@ -0,0 +1,154 @@
|
|||
'use strict';
|
||||
var parser = require('ua-parser-js');
|
||||
|
||||
// Start Binary.js server
|
||||
var BinaryServer = require('binaryjs').BinaryServer;
|
||||
|
||||
exports.create = function(server) {
|
||||
|
||||
// link it to express
|
||||
var bs = BinaryServer({
|
||||
server: server,
|
||||
path: '/binary'
|
||||
});
|
||||
|
||||
function guid() {
|
||||
function s4() {
|
||||
return Math.floor((1 + Math.random()) * 0x10000)
|
||||
.toString(16)
|
||||
.substring(1);
|
||||
}
|
||||
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||
s4() + '-' + s4() + s4() + s4();
|
||||
}
|
||||
|
||||
function getDeviceName(req) {
|
||||
var ua = parser(req.headers['user-agent']);
|
||||
return {
|
||||
model: ua.device.model,
|
||||
os: ua.os.name,
|
||||
browser: ua.browser.name,
|
||||
type: ua.device.type
|
||||
};
|
||||
}
|
||||
|
||||
function hash(text) {
|
||||
// A string hashing function based on Daniel J. Bernstein's popular 'times 33' hash algorithm.
|
||||
var h = 5381,
|
||||
index = text.length;
|
||||
while (index) {
|
||||
h = (h * 33) ^ text.charCodeAt(--index);
|
||||
}
|
||||
return h >>> 0;
|
||||
}
|
||||
|
||||
function getIP(socket) {
|
||||
return socket.upgradeReq.headers['x-forwarded-for'] || socket.upgradeReq.connection.remoteAddress;
|
||||
}
|
||||
// Wait for new user connections
|
||||
bs.on('connection', function(client) {
|
||||
|
||||
client.uuidRaw = guid();
|
||||
//ip is hashed to prevent injections by spoofing the 'x-forwarded-for' header
|
||||
// client.hashedIp = 1; //use this to test locally
|
||||
client.hashedIp = hash(getIP(client._socket));
|
||||
|
||||
client.deviceName = getDeviceName(client._socket.upgradeReq);
|
||||
|
||||
// Incoming stream from browsers
|
||||
client.on('stream', function(stream, meta) {
|
||||
if (meta && meta.serverMsg === 'rtc-support') {
|
||||
client.uuid = (meta.rtc ? 'rtc_' : '') + client.uuidRaw;
|
||||
client.send({
|
||||
isSystemEvent: true,
|
||||
type: 'handshake',
|
||||
name: client.deviceName,
|
||||
uuid: client.uuid
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (meta && meta.serverMsg === 'device-name') {
|
||||
//max name length = 40
|
||||
if (meta.name && meta.name.length > 40) {
|
||||
return;
|
||||
}
|
||||
client.name = meta.name;
|
||||
return;
|
||||
}
|
||||
|
||||
meta.from = client.uuid;
|
||||
|
||||
// broadcast to the other client
|
||||
for (var id in bs.clients) {
|
||||
if (bs.clients.hasOwnProperty(id)) {
|
||||
var otherClient = bs.clients[id];
|
||||
if (otherClient !== client && meta.toPeer === otherClient.uuid) {
|
||||
var send = otherClient.createStream(meta);
|
||||
stream.pipe(send, meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function forEachClient(fn) {
|
||||
for (var id in bs.clients) {
|
||||
if (bs.clients.hasOwnProperty(id)) {
|
||||
var client = bs.clients[id];
|
||||
fn(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function notifyBuddies() {
|
||||
var locations = {};
|
||||
//group all clients by location (by public ip address)
|
||||
forEachClient(function(client) {
|
||||
var ip = client.hashedIp;
|
||||
locations[ip] = locations[ip] || [];
|
||||
locations[ip].push({
|
||||
socket: client,
|
||||
contact: {
|
||||
peerId: client.uuid,
|
||||
name: client.name || client.deviceName,
|
||||
device: client.name ? client.deviceName : undefined
|
||||
}
|
||||
});
|
||||
});
|
||||
//notify every location
|
||||
Object.keys(locations).forEach(function(locationKey) {
|
||||
//notify every client of all other clients in this location
|
||||
var location = locations[locationKey];
|
||||
location.forEach(function(client) {
|
||||
//all other clients
|
||||
var buddies = location.reduce(function(result, otherClient) {
|
||||
if (otherClient !== client) {
|
||||
result.push(otherClient.contact);
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
var currState = hash(JSON.stringify(buddies));
|
||||
console.log(currState);
|
||||
var socket = client.socket;
|
||||
//protocol
|
||||
var msg = {
|
||||
buddies: buddies,
|
||||
isSystemEvent: true,
|
||||
type: 'buddies'
|
||||
};
|
||||
//send only if state changed
|
||||
if (currState !== socket.lastState) {
|
||||
socket.send(msg);
|
||||
socket.lastState = currState;
|
||||
return;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(notifyBuddies, 3000);
|
||||
};
|
Loading…
Reference in a new issue