Merge branch 'master' into copy-and-ux

This commit is contained in:
George Cordalis 2020-04-11 17:13:45 +12:00
commit a05e0d077b
6 changed files with 80 additions and 201 deletions

203
README.md
View File

@ -42,28 +42,7 @@ The host has complete control over a room. Commands they send to their client wi
* Password locked rooms
* Invite others via generated short link
* Movies and TV Shows (Music not supported)
## FAQ
* _I have to login to Plex.tv on the site, how come?_
* SyncLounge uses your Plex account to fetch details about your Plex Clients and Media Servers to use within the app.
* _Won't you have access to my username, password and Plex account?_
* All of your details are stored client side (in your browser). Absolutely none of your **confidential** data is sent to our server. You can verify this by inspecting the Network tab within Chrome developer tools or if you would like you can deploy SyncLounge yourself - read the 'Building and deploying' section below.
* _What is sent then?_
* When you've connected to a SyncLounge room, a few details are sent back and forth to the SyncLounge Server to enable syncing. The data sent contains the following:
* Plex Username
* Plex User Thumbnail URL
* Content playing title (Eg. Lord of the Rings: The Fellowship of the Ring)
* Current timestamp (Eg. 00:35:02)
* Maximum timestamp (Eg. 03:48:18)
* Host content ratingKey
* Host machineIdentifier
* Playerstate (Eg. paused, stopped, playing)
* Client response time (Ping time between you and your Plex Client)
* SL Server address, SL Server Room and SL Server Room Password are sent to the WebApp when you join a room to create shortened invite links.
* _What about the public server provided by SyncLounge? Is my data safe?_
* We log absolutely nothing to disk. Data is kept within the room instance until you leave or the server restarts. We have enabled SSL on our public servers but if privacy is a concern for you we strongly suggest running your own server. For more details read the 'Building and Deploying' section below.
* _Speaking of SSL, why isn't the site served over HTTPS?_
* By default SyncLounge is server via HTTP. While we do offer HTTPS, doing so forces modern browsers in to blocking all HTTP connections. This effectively stops all communication with Plex Clients which are all HTTP.
## Screenshots
Head to the [website](http://synclounge.tv)
@ -94,187 +73,9 @@ Some low powered clients may be hard to achieve a perfect sync with (for example
* PS3
* PS4
## Contributing
Please use the Issue tracker here on Github for Issues & Feature requests. We'll gladly merge Pull requests if you're keen to get hands on with the development.
## Documentation
## Building and deploying
### Arguments and ENV variables
The following can be used to change some of the settings in the application. Arguments are passed to the application by using `--<argument>=<value>` when running the application. ENV variables are mostly for Docker but can be set locally on your system.
| Argument | ENV | Description |
| ------ | ------ | ------ |
| webroot | WEB_ROOT | Change the base URL of the web app. Ex - `/lounge` |
| webapp_port | WEB_PORT | Change the port the web app uses. Defaults to `8088` |
| accessUrl | WEB_ACCESSURL | Set the URL the web app uses for things like invites. Ex - `http://mysynclounge.com` |
| autoJoin | AUTOJOIN_ENABLED | Set to `true` to enable auto joining. Defaults to `false` |
| autoJoinServer | AUTOJOIN_SERVERURL | Set this to the server URL you want the user to auto join. Required if auto join is enabled. Ex - `http://mysynclounge.com/slserver` |
| autoJoinRoom | AUTOJOIN_ROOM | Set this to the room name in the server that you want the users to auto join. Optional |
| autoJoinPassword | AUTOJOIN_PASSWORD | Set this to the room's password, if it has one. Optional |
| authentication | AUTHENTICATION | Configure authentication for the server. See below for more information. Optional |
| customServer | CUSTOM_SERVER | Override the custom server entry in the servers list. See below for more information. Optional |
| servers | SERVERS | Set your own servers list. See below for more information. Optional |
| serverroot | SERVER_ROOT | Change the base URL of the server app. Ex - `/server`. Defaults to `/slserver` |
| server_port | SERVER_PORT | Change the port the server app uses. Defaults to `8089` |
#### Authentication
To enable authentication, the following setting and format is used
```json
"authentication": {
"mechanism": "plex",
"type": ["server", "user"],
"authorized": [
"PLEX_SERVER_MACHINE_ID",
"PLEX_USER_EMAIL",
"PLEX_USER_NAME",
]
}
```
- `mechanism` specifies how SyncLounge should authenticate a user. This is mostly for future-proofing to allow other authentication mechanisms to be provided. Defaults to `none`.
- `type` is mechanism dependent. Since `plex` is the only one currently, either or both `server` and `user` can be specified.
- `server` checks against the plex server machine ID (`PLEX_SERVER_MACHINE_ID`). If the user has access to a server matching any of the IDs in the `authorized` list, they will be granted access.
- `user` checks against the user's email (`PLEX_USER_EMAIL`) or username (`PLEX_USER_NAME`). If either matches a value in the `authorized` list, they will be granted access.
- `authorized` is a list of information for who is authorized.
#### Customize the server list
##### Customize the Custom Server entry
Adding this to your settings will override the the custom server in the server list.
```json
"customServer": {
"name": "Custom Server 1",
"location": "Custom Location",
"url": "https://mycustomserver.com/server",
"image": "https://mycustomserver.com/logo.png"
}
```
![image](https://user-images.githubusercontent.com/1524443/76433720-19a3f180-638b-11ea-8c20-1997728e8325.png)
##### Customize servers list
The servers list can be modified with your own list of servers. If this setting is provided, it will ignore the `customServer` setting above. Also, if only one server is provided, it will automatically join it! A server entry can also handle a default Room, with or without password. If set, SyncLounge will attempt to auto-join the room when the server is selected by the user.
```json
"servers": [
{
"name": "Custom Server 1",
"location": "Custom Location",
"url": "https://1.mycustomserver.com/server",
"image": "https://mycustomserver.com/logo.png"
},
{
"name": "Custom Server 2",
"location": "Custom Location",
"url": "https://2.mycustomserver.com/server",
"image": "https://mycustomserver.com/logo-2.png",
"defaultRoom": "DefaultRoom"
},
{
"name": "Custom Server 3",
"location": "Custom Location",
"url": "https://3.mycustomserver.com/server",
"image": "https://mycustomserver.com/logo-3.png",
"defaultRoom": "DefaultRoom",
"defaultPassword": "DefaultPassword123"
}
]
```
![image](https://user-images.githubusercontent.com/1524443/76433958-6daed600-638b-11ea-9cf6-41ea79182dbc.png)
### Docker
This is the official Docker container for SyncLounge: https://hub.docker.com/r/starbix/synclounge
The following tags are available:
* latest / alpine: webapp and server based on alpine
* server: only server based on alpine
* dev: development version of webapp and server based on alpine
* nginx: latest + nginx reverse proxy
```
docker run \
--name=synclounge \
-p 8088:8088 \
-p 8089:8089 \
-e DOMAIN=example.com \
starbix/synclounge
```
Use this for the nginx tag:
```
docker run \
--name=plextogether_nginx \
-p 80:80 \
-e DOMAIN=example.com \
starbix/synclounge:nginx
```
### Building and running the webapp:
* Make sure you have Node v8.4.0+ installed
* ``git clone https://github.com/samcm/synclounge``
* ``cd synclounge``
* ``npm install``
* ``npm run build``
* ``node webapp.js --accessUrl=http://example.com``
* The SL web app will be running at http://ip:8088.
### Running the server:
* Make sure you have Node v8.4.0+ installed
* ``git clone https://github.com/samcm/synclounge``
* ``cd synclounge``
* ``npm install``
* ``npm run server``
* The SL server will be running at http://ip:8089/slserver.
### Deploying:
* To run both the SyncLounge webapp and the SyncLounge server through a web server like nginx you will need to make sure you proxy websockets. Example nginx.conf:
```
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:8088;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /slserver {
proxy_pass http://localhost:8089/slserver;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
```
## Developing
You need:
* Node v8.4.0+
* ``git clone https://github.com/samcm/SyncLounge``
* ``cd synclounge``
* ``npm install``
* ``npm run dev``
* Once Webpack has finished compiling, navigate to http://localhost:8080 in your web browser.
* Hot reload is enabled
* Suggested to install [Vue.js Devtools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en)
## Issues
If you run in to any issues:
* Raise an Issue here on Github. Try to be as detailed as possible by including details such as:
* Operating System
* Web Browser name and version
* Plex Media Server details
* Version
* Operating System
* Location (Local/Remote)
* Plex Client details
* Name
* Version
* Network connection (Wired/Wifi)
* Platform
* Join the [Discord Server](https://discord.gg/Cp9RPSJ) and raise your issue.
The FAQ, Self-Hosting, Development, Contributing, and other documentation has been move to [docs.synclounge.tv](http://docs.synclounge.tv)! Head there for more information!
## Contributors
[samcm](https://twitter.com/durksau) - Developer

View File

@ -79,6 +79,67 @@ module.exports = function () {
// console.log(`Settings: '${settings[setting.local]}'; '${setting.default}'`);
output[setting.local] = args[setting.env] || args[setting.local] || process.env[setting.env] || process.env[setting.local] || settings[setting.env] || settings[setting.local] || setting.default;
// Make sure these settings are properly formatted
if(output[setting.local]) {
// Make sure these settings are properly formatted to JSON
let jsonSettings = ['authentication', 'customServer'];
if(jsonSettings.includes(setting.local) && output[setting.local]) {
if(typeof output[setting.local] !== "object") {
console.log(`${setting.local}/${setting.env} must be a JSON object. Attempting to convert it for you.`);
try {
let parsed = JSON.parse(output[setting.local]);
output[setting.local] = parsed;
}
catch(e) {
console.log(`- Unable to parse '${output[setting.local]}'`);
console.log(`- Please check your syntax. Reverting to default.`);
}
console.log(`- Done.`);
}
}
// Make sure these settings are properly formatted to an Array
// This currently is only coded to handle the servers setting which is an Array of JSON objects
let arraySettings = ['servers'];
if(arraySettings.includes(setting.local)) {
if(!Array.isArray(output[setting.local])) {
console.log(`${setting.local}/${setting.env} must be an Array of JSON objects. Attempting to convert it for you.`);
let temp = output[setting.local].trim();
temp = temp.replace("[", "");
temp = temp.replace("]", "");
let tempArr = temp.split("},");
if(tempArr.length > 0) {
let tempOutArr = [];
tempArr.forEach(element => {
try {
if(!element.endsWith('}')) {
element = element + '}';
}
let parsed = JSON.parse(element);
tempOutArr.push(parsed);
}
catch(e) {
console.log(`- Unable to parse '${element}'`);
console.log(`- Please check your syntax. Skipping...`);
}
});
if(tempOutArr.length == 0) {
console.log(`- No elements to use. Reverting to default.`);
}
output[setting.local] = tempOutArr;
}
else {
console.log(`No array elements found =(. Reverting to default.`);
output[setting.local] = setting.default;
}
console.log(`- Done.`);
}
}
}
// Backwards compatibilty for PORT ENV setting
if(setting.local == 'webapp_port' && output[setting.local] == 8088) {
let port = args['PORT'] || process.env['PORT'] || settings['PORT'];
@ -92,17 +153,20 @@ module.exports = function () {
if ((setting.local == 'webroot' || setting.local == 'accessUrl') && output[setting.local].endsWith("/")) {
console.log(`${setting.local}/${setting.env} should not end in '/'. Removing trailing slash(es) for you.`);
output[setting.local] = output[setting.local].replace(/\/+$/, "");
console.log(`- Done.`);
}
// Add leading slash, if not provided
if (setting.local == 'webroot' && output[setting.local].length > 1 && !output[setting.local].startsWith("/")) {
console.log(`${setting.local}/${setting.env} should always start with '/'. Adding the leading slash for you.`);
// Make sure it starts with one leading slash
output[setting.local] = `/${output[setting.local]}`;
console.log(`- Done.`);
}
// Make sure 'webroot' and 'serverroot' aren't set to '/'. Revert to default if they do.
if ((setting.local == 'webroot' || setting.local == 'serverroot') && output[setting.local] == '/') {
console.log(`${setting.local}/${setting.env} cannot be set to '/'. Reverting to default: '${setting.default}'`);
output[setting.local] = setting.default;
console.log(`- Done.`);
}
process.env[setting.env] = output[setting.local];
}

5
package-lock.json generated
View File

@ -10729,6 +10729,11 @@
"clipboard": "^1.7.1"
}
},
"vue-cookies": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/vue-cookies/-/vue-cookies-1.7.0.tgz",
"integrity": "sha512-vuEUm6wYMMrFAHFCrkzIUAy8+MgPAbBGmYXnk2M6X6O2KHbMT1wuDD2izacmsSUp6ZM02e23MJRtPRobl88VMg=="
},
"vue-eslint-parser": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz",

View File

@ -26,6 +26,7 @@
"string-similarity": "^1.2.0",
"videojs-contrib-hls": "^5.15.0",
"vue": "^2.6.10",
"vue-cookies": "^1.7.0",
"vue-router": "^2.3.1",
"vuetify": "^1.5.14",
"vuex": "^2.3.1",

View File

@ -259,6 +259,9 @@ export default {
if (window.localStorage.getItem('myPlexAccessToken')) {
authToken = window.localStorage.getItem('myPlexAccessToken');
}
else if($cookies.get('mpt')) {
authToken = $cookies.get('mpt');
}
if (authToken) {
this.ticker = setInterval(async () => {

View File

@ -5,6 +5,7 @@ import { ObserveVisibility } from 'vue-observe-visibility/dist/vue-observe-visib
import VueVideoPlayer from 'vue-video-player';
import VueResource from 'vue-resource';
import VueClipboards from 'vue-clipboards';
import VueCookies from 'vue-cookies'
import App from './App';
import router from './router';
@ -31,6 +32,10 @@ Vue.use(Vuetify, {
});
Vue.config.productionTip = false;
Vue.use(VueCookies);
// set default config
Vue.$cookies.config('7d');
function nolog() {}
if (process.env.NODE_ENV !== 'development') {