Merge branch 'master' into enable_renaming
This commit is contained in:
commit
b7e7fd1b68
13 changed files with 160 additions and 63 deletions
|
@ -64,6 +64,7 @@ Developed based on [Snapdrop](https://github.com/RobinLinus/snapdrop)
|
|||
* Automatic restart on error (Thanks [@KaKi87](https://github.com/KaKi87))
|
||||
* Lots of stability fixes (Thanks [@MWY001](https://github.com/MWY001) [@skiby7](https://github.com/skiby7) and [@willstott101](https://github.com/willstott101))
|
||||
* To host PairDrop on your local network (e.g. on Raspberry Pi): [All peers connected with private IPs are discoverable by each other](https://github.com/RobinLinus/snapdrop/pull/558)
|
||||
* When hosting PairDrop yourself you can [set your own STUN/TURN servers](/docs/host-your-own.md#specify-stunturn-servers)
|
||||
|
||||
## Screenshots
|
||||
<div align="center">
|
||||
|
|
|
@ -17,7 +17,7 @@ docker run -d --restart=unless-stopped --name=pairdrop -p 127.0.0.1:3000:3000 ls
|
|||
Set options by using the following flags in the `docker run` command:
|
||||
|
||||
##### Port
|
||||
```
|
||||
```bash
|
||||
-p 127.0.0.1:8080:3000
|
||||
```
|
||||
> Specify the port used by the docker image
|
||||
|
@ -30,7 +30,7 @@ Set options by using the following flags in the `docker run` command:
|
|||
> Limits clients to 1000 requests per 5 min
|
||||
|
||||
##### Websocket Fallback (for VPN)
|
||||
```
|
||||
```bash
|
||||
-e WS_FALLBACK=true
|
||||
```
|
||||
> Provides PairDrop to clients with an included websocket fallback if the peer to peer WebRTC connection is not available to the client.
|
||||
|
@ -42,6 +42,36 @@ Set options by using the following flags in the `docker run` command:
|
|||
> Beware that the traffic routed via this fallback is readable by the server. Only ever use this on instances you can trust.
|
||||
> Additionally, beware that all traffic using this fallback debits the servers data plan.
|
||||
|
||||
##### Specify STUN/TURN Servers
|
||||
```bash
|
||||
-e RTC_CONFIG="rtc_config.json"
|
||||
```
|
||||
|
||||
> Specify the STUN/TURN servers PairDrop clients use by setting `RTC_CONFIG` to a JSON file including the configuration.
|
||||
> You can use `pairdrop/rtc_config_example.json` as a starting point.
|
||||
>
|
||||
> Default configuration:
|
||||
> ```json
|
||||
> {
|
||||
> "sdpSemantics": "unified-plan",
|
||||
> "iceServers": [
|
||||
> {
|
||||
> "urls": "stun:stun.l.google.com:19302"
|
||||
> },
|
||||
> {
|
||||
> "urls": "stun:openrelay.metered.ca:80"
|
||||
> },
|
||||
> {
|
||||
> "urls": "turn:openrelay.metered.ca:443",
|
||||
> "username": "openrelayproject",
|
||||
> "credential": "openrelayproject"
|
||||
> }
|
||||
> ]
|
||||
> }
|
||||
> ```
|
||||
|
||||
<br>
|
||||
|
||||
### Docker Image from GHCR
|
||||
```bash
|
||||
docker run -d --restart=unless-stopped --name=pairdrop -p 127.0.0.1:3000:3000 ghcr.io/schlagmichdoch/pairdrop npm run start:prod
|
||||
|
@ -141,6 +171,38 @@ $env:PORT=3010; npm start
|
|||
```
|
||||
> Specify the port PairDrop is running on. (Default: 3000)
|
||||
|
||||
#### Specify STUN/TURN Server
|
||||
On Unix based systems
|
||||
```bash
|
||||
RTC_CONFIG="rtc_config.json" npm start
|
||||
```
|
||||
On Windows
|
||||
```bash
|
||||
$env:RTC_CONFIG="rtc_config.json"; npm start
|
||||
```
|
||||
> Specify the STUN/TURN servers PairDrop clients use by setting `RTC_CONFIG` to a JSON file including the configuration.
|
||||
> You can use `pairdrop/rtc_config_example.json` as a starting point.
|
||||
>
|
||||
> Default configuration:
|
||||
> ```json
|
||||
> {
|
||||
> "sdpSemantics": "unified-plan",
|
||||
> "iceServers": [
|
||||
> {
|
||||
> "urls": "stun:stun.l.google.com:19302"
|
||||
> },
|
||||
> {
|
||||
> "urls": "stun:openrelay.metered.ca:80"
|
||||
> },
|
||||
> {
|
||||
> "urls": "turn:openrelay.metered.ca:443",
|
||||
> "username": "openrelayproject",
|
||||
> "credential": "openrelayproject"
|
||||
> }
|
||||
> ]
|
||||
> }
|
||||
> ```
|
||||
|
||||
### Options / Flags
|
||||
#### Local Run
|
||||
```bash
|
||||
|
@ -262,13 +324,13 @@ server {
|
|||
|
||||
### Using Apache
|
||||
install modules `proxy`, `proxy_http`, `mod_proxy_wstunnel`
|
||||
```shell
|
||||
```bash
|
||||
a2enmod proxy
|
||||
```
|
||||
```shell
|
||||
```bash
|
||||
a2enmod proxy_http
|
||||
```
|
||||
```shell
|
||||
```bash
|
||||
a2enmod proxy_wstunnel
|
||||
```
|
||||
|
||||
|
@ -278,7 +340,7 @@ Create a new configuration file under `/etc/apache2/sites-available` (on debian)
|
|||
|
||||
**pairdrop.conf**
|
||||
#### Allow http and https requests
|
||||
```
|
||||
```apacheconf
|
||||
<VirtualHost *:80>
|
||||
ProxyPass / http://127.0.0.1:3000/
|
||||
RewriteEngine on
|
||||
|
@ -295,7 +357,7 @@ Create a new configuration file under `/etc/apache2/sites-available` (on debian)
|
|||
</VirtualHost>
|
||||
```
|
||||
#### Automatic http to https redirect:
|
||||
```
|
||||
```apacheconf
|
||||
<VirtualHost *:80>
|
||||
Redirect permanent / https://127.0.0.1:3000/
|
||||
</VirtualHost>
|
||||
|
@ -308,10 +370,10 @@ Create a new configuration file under `/etc/apache2/sites-available` (on debian)
|
|||
</VirtualHost>
|
||||
```
|
||||
Activate the new virtual host and reload apache:
|
||||
```shell
|
||||
```bash
|
||||
a2ensite pairdrop
|
||||
```
|
||||
```shell
|
||||
```bash
|
||||
service apache2 reload
|
||||
```
|
||||
|
||||
|
@ -322,7 +384,7 @@ All files needed for developing are available on the branch `dev`.
|
|||
First, [Install docker with docker-compose.](https://docs.docker.com/compose/install/)
|
||||
|
||||
Then, clone the repository and run docker-compose:
|
||||
```shell
|
||||
```bash
|
||||
git clone https://github.com/schlagmichdoch/PairDrop.git
|
||||
|
||||
cd PairDrop
|
||||
|
@ -347,7 +409,7 @@ The nginx container creates a CA certificate and a website certificate for you.
|
|||
|
||||
If you want to test PWA features, you need to trust the CA of the certificate for your local deployment. For your convenience, you can download the crt file from `http://<Your FQDN>:8080/ca.crt`. Install that certificate to the trust store of your operating system.
|
||||
- On Windows, make sure to install it to the `Trusted Root Certification Authorities` store.
|
||||
- On MacOS, double click the installed CA certificate in `Keychain Access`, expand `Trust`, and select `Always Trust` for SSL.
|
||||
- On macOS, double-click the installed CA certificate in `Keychain Access`, expand `Trust`, and select `Always Trust` for SSL.
|
||||
- Firefox uses its own trust store. To install the CA, point Firefox at `http://<Your FQDN>:8080/ca.crt`. When prompted, select `Trust this CA to identify websites` and click OK.
|
||||
- When using Chrome, you need to restart Chrome so it reloads the trust store (`chrome://restart`). Additionally, after installing a new cert, you need to clear the Storage (DevTools -> Application -> Clear storage -> Clear site data).
|
||||
|
||||
|
|
24
index.js
24
index.js
|
@ -2,6 +2,7 @@ const process = require('process')
|
|||
const crypto = require('crypto')
|
||||
const {spawn} = require('child_process')
|
||||
const WebSocket = require('ws');
|
||||
const fs = require('fs');
|
||||
|
||||
// Handle SIGINT
|
||||
process.on('SIGINT', () => {
|
||||
|
@ -50,6 +51,25 @@ if (process.argv.includes('--auto-restart')) {
|
|||
);
|
||||
}
|
||||
|
||||
const rtcConfig = process.env.RTC_CONFIG
|
||||
? fs.readFileSync(process.env.RTC_CONFIG, 'utf8')
|
||||
: {
|
||||
"sdpSemantics": "unified-plan",
|
||||
"iceServers": [
|
||||
{
|
||||
"urls": "stun:stun.l.google.com:19302"
|
||||
},
|
||||
{
|
||||
"urls": "stun:openrelay.metered.ca:80"
|
||||
},
|
||||
{
|
||||
"urls": "turn:openrelay.metered.ca:443",
|
||||
"username": "openrelayproject",
|
||||
"credential": "openrelayproject"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const express = require('express');
|
||||
const RateLimit = require('express-rate-limit');
|
||||
const http = require('http');
|
||||
|
@ -113,6 +133,10 @@ class PairDropServer {
|
|||
peer.socket.on('message', message => this._onMessage(peer, message));
|
||||
peer.socket.onerror = e => console.error(e);
|
||||
this._keepAlive(peer);
|
||||
this._send(peer, {
|
||||
type: 'rtc-config',
|
||||
config: rtcConfig
|
||||
});
|
||||
this._joinRoom(peer);
|
||||
|
||||
// send displayName
|
||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.2.2",
|
||||
"version": "1.3.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "pairdrop",
|
||||
"version": "1.2.2",
|
||||
"version": "1.3.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "pairdrop",
|
||||
"version": "1.2.2",
|
||||
"version": "1.3.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
|
|
@ -246,14 +246,14 @@
|
|||
</div>
|
||||
<!-- About Page -->
|
||||
<x-about id="about" class="full center column">
|
||||
<header class="row-reverse fade-in">
|
||||
<a href="#" class="close icon-button">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#close-icon" />
|
||||
</svg>
|
||||
</a>
|
||||
</header>
|
||||
<section class="center column fade-in">
|
||||
<header class="row-reverse">
|
||||
<a href="#" class="close icon-button">
|
||||
<svg class="icon">
|
||||
<use xlink:href="#close-icon" />
|
||||
</svg>
|
||||
</a>
|
||||
</header>
|
||||
<svg class="icon logo">
|
||||
<use xlink:href="#wifi-tethering" />
|
||||
</svg>
|
||||
|
|
|
@ -54,16 +54,23 @@ class ServerConnection {
|
|||
|
||||
_onPairDeviceJoin(roomKey) {
|
||||
if (!this._isConnected()) {
|
||||
setTimeout(_ => this._onPairDeviceJoin(roomKey), 5000);
|
||||
setTimeout(_ => this._onPairDeviceJoin(roomKey), 1000);
|
||||
return;
|
||||
}
|
||||
this.send({ type: 'pair-device-join', roomKey: roomKey })
|
||||
}
|
||||
|
||||
_setRtcConfig(config) {
|
||||
window.rtcConfig = config;
|
||||
}
|
||||
|
||||
_onMessage(msg) {
|
||||
msg = JSON.parse(msg);
|
||||
if (msg.type !== 'ping') console.log('WS:', msg);
|
||||
switch (msg.type) {
|
||||
case 'rtc-config':
|
||||
this._setRtcConfig(msg.config);
|
||||
break;
|
||||
case 'peers':
|
||||
Events.fire('peers', msg);
|
||||
break;
|
||||
|
@ -140,7 +147,7 @@ class ServerConnection {
|
|||
console.log('WS: server disconnected');
|
||||
Events.fire('notify-user', 'Connecting..');
|
||||
clearTimeout(this._reconnectTimer);
|
||||
this._reconnectTimer = setTimeout(_ => this._connect(), 5000);
|
||||
this._reconnectTimer = setTimeout(_ => this._connect(), 1000);
|
||||
Events.fire('ws-disconnected');
|
||||
this._isReconnect = true;
|
||||
}
|
||||
|
@ -507,7 +514,7 @@ class RTCPeer extends Peer {
|
|||
_openConnection(peerId, isCaller) {
|
||||
this._isCaller = isCaller;
|
||||
this._peerId = peerId;
|
||||
this._conn = new RTCPeerConnection(RTCPeer.config);
|
||||
this._conn = new RTCPeerConnection(window.rtcConfig);
|
||||
this._conn.onicecandidate = e => this._onIceCandidate(e);
|
||||
this._conn.onconnectionstatechange = _ => this._onConnectionStateChange();
|
||||
this._conn.oniceconnectionstatechange = e => this._onIceConnectionStateChange(e);
|
||||
|
@ -887,20 +894,3 @@ class Events {
|
|||
return window.removeEventListener(type, callback, false);
|
||||
}
|
||||
}
|
||||
|
||||
RTCPeer.config = {
|
||||
'sdpSemantics': 'unified-plan',
|
||||
'iceServers': [
|
||||
{
|
||||
urls: 'stun:stun.l.google.com:19302'
|
||||
},
|
||||
{
|
||||
urls: 'stun:openrelay.metered.ca:80'
|
||||
},
|
||||
{
|
||||
urls: 'turn:openrelay.metered.ca:443',
|
||||
username: 'openrelayproject',
|
||||
credential: 'openrelayproject',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const cacheVersion = 'v1.2.2';
|
||||
const cacheVersion = 'v1.3.0';
|
||||
const cacheTitle = `pairdrop-cache-${cacheVersion}`;
|
||||
const urlsToCache = [
|
||||
'index.html',
|
||||
|
|
|
@ -970,6 +970,13 @@ button::-moz-focus-inner {
|
|||
margin: 8px 8px -16px;
|
||||
}
|
||||
|
||||
#about section {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#about header {
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
/* Loading Indicator */
|
||||
|
||||
|
|
|
@ -52,16 +52,23 @@ class ServerConnection {
|
|||
|
||||
_onPairDeviceJoin(roomKey) {
|
||||
if (!this._isConnected()) {
|
||||
setTimeout(_ => this._onPairDeviceJoin(roomKey), 5000);
|
||||
setTimeout(_ => this._onPairDeviceJoin(roomKey), 1000);
|
||||
return;
|
||||
}
|
||||
this.send({ type: 'pair-device-join', roomKey: roomKey })
|
||||
}
|
||||
|
||||
_setRtcConfig(config) {
|
||||
window.rtcConfig = config;
|
||||
}
|
||||
|
||||
_onMessage(msg) {
|
||||
msg = JSON.parse(msg);
|
||||
if (msg.type !== 'ping') console.log('WS:', msg);
|
||||
switch (msg.type) {
|
||||
case 'rtc-config':
|
||||
this._setRtcConfig(msg.config);
|
||||
break;
|
||||
case 'peers':
|
||||
Events.fire('peers', msg);
|
||||
break;
|
||||
|
@ -151,7 +158,7 @@ class ServerConnection {
|
|||
console.log('WS: server disconnected');
|
||||
Events.fire('notify-user', 'Connecting..');
|
||||
clearTimeout(this._reconnectTimer);
|
||||
this._reconnectTimer = setTimeout(_ => this._connect(), 5000);
|
||||
this._reconnectTimer = setTimeout(_ => this._connect(), 1000);
|
||||
Events.fire('ws-disconnected');
|
||||
this._isReconnect = true;
|
||||
}
|
||||
|
@ -517,7 +524,7 @@ class RTCPeer extends Peer {
|
|||
_openConnection(peerId, isCaller) {
|
||||
this._isCaller = isCaller;
|
||||
this._peerId = peerId;
|
||||
this._conn = new RTCPeerConnection(RTCPeer.config);
|
||||
this._conn = new RTCPeerConnection(window.rtcConfig);
|
||||
this._conn.onicecandidate = e => this._onIceCandidate(e);
|
||||
this._conn.onconnectionstatechange = _ => this._onConnectionStateChange();
|
||||
this._conn.oniceconnectionstatechange = e => this._onIceConnectionStateChange(e);
|
||||
|
@ -967,20 +974,3 @@ class Events {
|
|||
return window.removeEventListener(type, callback, false);
|
||||
}
|
||||
}
|
||||
|
||||
RTCPeer.config = {
|
||||
'sdpSemantics': 'unified-plan',
|
||||
'iceServers': [
|
||||
{
|
||||
urls: 'stun:stun.l.google.com:19302'
|
||||
},
|
||||
{
|
||||
urls: 'stun:openrelay.metered.ca:80'
|
||||
},
|
||||
{
|
||||
urls: 'turn:openrelay.metered.ca:443',
|
||||
username: 'openrelayproject',
|
||||
credential: 'openrelayproject',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const cacheVersion = 'v1.2.2';
|
||||
const cacheVersion = 'v1.3.0';
|
||||
const cacheTitle = `pairdrop-included-ws-fallback-cache-${cacheVersion}`;
|
||||
const urlsToCache = [
|
||||
'index.html',
|
||||
|
|
|
@ -996,6 +996,13 @@ button::-moz-focus-inner {
|
|||
margin: 8px 8px -16px;
|
||||
}
|
||||
|
||||
#about section {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
#about header {
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
/* Loading Indicator */
|
||||
|
||||
|
|
16
rtc_config_example.json
Normal file
16
rtc_config_example.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"sdpSemantics": "unified-plan",
|
||||
"iceServers": [
|
||||
{
|
||||
"urls": "stun:stun.l.google.com:19302"
|
||||
},
|
||||
{
|
||||
"urls": "stun:openrelay.metered.ca:80"
|
||||
},
|
||||
{
|
||||
"urls": "turn:openrelay.metered.ca:443",
|
||||
"username": "openrelayproject",
|
||||
"credential": "openrelayproject"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue