diff options
Diffstat (limited to 'js')
-rw-r--r-- | js/detect-browser.js | 180 | ||||
-rw-r--r-- | js/main.js | 68 |
2 files changed, 240 insertions, 8 deletions
diff --git a/js/detect-browser.js b/js/detect-browser.js new file mode 100644 index 0000000..ca0f8d5 --- /dev/null +++ b/js/detect-browser.js @@ -0,0 +1,180 @@ +// @ts-nocheck +'use strict'; +// detect-browser.js v1.0.0 +// Get Browser Data + +// MIT License + +// Copyright (c) 2018 Ahmad Raza + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + + +function isMobile() { + return /Mobi/.test(navigator.userAgent); +} + +function getBrowserName() { + // Opera 8.0+ + if ((window.opr && window.opr.addons) + || window.opera + || navigator.userAgent.indexOf(' OPR/') >= 0) { + return 'Opera'; + } + + // Firefox 1.0+ + if (typeof InstallTrigger !== 'undefined') { + return 'Firefox'; + } + + // Safari 3.0+ "[object HTMLElementConstructor]" + if (/constructor/i.test(window.HTMLElement) || (function (p) { + return p.toString() === '[object SafariRemoteNotification]'; + })(!window['safari'])) { + return 'Safari'; + } + + // Internet Explorer 6-11 + if (/* @cc_on!@*/false || document.documentMode) { + return 'Internet Explorer'; + } + + // Edge 20+ + if (!(document.documentMode) && window.StyleMedia) { + return 'Microsoft Edge'; + } + + // Chrome + if (window.chrome) { + return 'Chrome'; + } +} + +function getOSName() { + var os; + if (isMobile()) { + if (/Windows/.test(navigator.userAgent)) { + os = 'Windows'; + if (/Phone 8.0/.test(navigator.userAgent)) { + os += ' Phone 8.0'; + } else if (/Phone 10.0/.test(navigator.userAgent)) { + os += ' Phone 10.0'; + } + } else if (/Android/.test(navigator.userAgent)) { + function androidVersion() { + if (/Android/.test(navigator.appVersion)) { + var v = (navigator.appVersion).match(/Android (\d+).(\d+)/); + return v; + } + } + + var ver = androidVersion(); + os = ver[0]; + } else if (/iPhone;/.test(navigator.userAgent)) { + function iOSversion() { + if (/iP(hone|od|ad)/.test(navigator.appVersion)) { + var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/); + return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)]; + } + } + + var ver = iOSversion(); + os = 'iOS ' + ver[0] + '.' + ver[1] + '.' + ver[2]; + } else if (/iPad;/.test(navigator.userAgent)) { + function iOSversion() { + if (/iP(hone|od|ad)/.test(navigator.appVersion)) { + var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/); + return [parseInt(v[1], 10), parseInt(v[2], 10), parseInt(v[3] || 0, 10)]; + } + } + + var ver = iOSversion(); + os = 'iOS ' + ver[0] + '.' + ver[1] + '.' + ver[2]; + } else if (/BBd*/.test(navigator.userAgent)) { + os = 'BlackBerry'; + } + } else { + if (/Windows/.test(navigator.userAgent)) { + os = 'Windows'; + if (/5.1;/.test(navigator.userAgent)) { + os += ' XP'; + } else if (/6.0;/.test(navigator.userAgent)) { + os += ' Vista'; + } else if (/6.1;/.test(navigator.userAgent)) { + os += ' 7'; + } else if (/6.2/.test(navigator.userAgent)) { + os += ' 8'; + } else if (/10.0;/.test(navigator.userAgent)) { + os += ' 10'; + } + + if (/64/.test(navigator.userAgent)) { + os += ' 64-bit'; + } else { + os += ' 32-bit'; + } + } else if (/Macintosh/.test(navigator.userAgent)) { + os = 'Macintosh'; + if (/OS X/.test(navigator.userAgent)) { + os += ' OS X'; + } + } + } + + return os; +} + +function getBrowserVersion() { + var ua = navigator.userAgent, tem, M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; + if (/trident/i.test(M[1])) { + tem = /\brv[ :]+(\d+)/g.exec(ua) || []; + return (tem[1] || ''); + } + if (M[1] === 'Chrome') { + tem = ua.match(/\bOPR|Edge\/(\d+)/) + if (tem != null) { + if (M.input && M.input.match(/Windows NT 10.0/)) { + return tem[1]; + } + return tem[1]; + } + } + M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?']; + if ((tem = ua.match(/version\/(\d+)/i)) != null) { + M.splice(1, 1, tem[1]); + } + return M[1]; +} + +function getBrowser() { + return { + os: getOSName(), + browser: getBrowserName(), + browserVersion: getBrowserVersion(), + language: navigator.language, + languages: navigator.languages, + user_agent: navigator.userAgent, + device: isMobile() ? 'Mobile' : 'Desktop', + referrer: document.referrer || 'N/A', + online: navigator.onLine, + timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, + screen_resolution: screen.width + ' x ' + screen.height, + cookie_enabled: navigator.cookieEnabled, + }; +}
\ No newline at end of file @@ -1,7 +1,14 @@ +// Variables for the Authorised Devices card +var clientIdentifier; // UID for the device being used +var plexProduct = "PASTA"; // X-Plex-Product - Application name +var pastaVersion = "1.2.2"; // X-Plex-Version - Application version +var pastaPlatform; // X-Plex-Platform - Web Browser +var pastaPlatformVersion; // X-Plex-Platform-Version - Web Browser version +var deviceInfo; // X-Plex-Device - Operation system? +var deviceName; // X-Plex-Device-Name - Main name shown +// End auth devices card variables var plexUrl; var plexToken; -var clientIdentifier; // UID for the device being used -var plexProduct = "PASTA-cglatot"; var backOffTimer = 0; var serverList = []; // save server information for pin login and multiple servers @@ -33,6 +40,17 @@ $(document).ready(() => { $("#insecureWarning").show(); } } + // SET THE VARIABLES FOR PLEX PIN AUTH REQUESTS + let browserInfo = getBrowser(); + // Set the clientID, this might get overridden if one is saved to localstorage + clientIdentifier = `PASTA-cglatot-${Date.now()}-${Math.round(Math.random() * 1000)}`; + // Set the OS + deviceInfo = browserInfo.os; + // Set the web browser and version + pastaPlatform = browserInfo.browser; + pastaPlatformVersion = browserInfo.browserVersion; + // Set the main display name + deviceName = `PASTA (${pastaPlatform})`; // Validation listeners on the Plex URL Input $('#plexUrl').on("input", () => { @@ -49,9 +67,6 @@ $(document).ready(() => { toggleAuthPages(this.value); }); - // Set the clientID, this might get overridden if one is saved to localstorage - clientIdentifier = `PASTA-cglatot-${Date.now()}-${Math.round(Math.random() * 1000)}`; - if (!localStorage.isPinAuth) { // Not using PIN auth, so must be using url / token if (localStorage.plexUrl && localStorage.plexUrl !== "") { @@ -69,7 +84,16 @@ $(document).ready(() => { // Display a PIN code for that authentication as well $.ajax({ - "url": `https://plex.tv/pins.xml?X-Plex-Product=${plexProduct}&X-Plex-Client-Identifier=${clientIdentifier}`, + "url": `https://plex.tv/pins.xml`, + "headers": { + "X-Plex-Client-Identifier": clientIdentifier, + "X-Plex-Product": plexProduct, + "X-Plex-Version": pastaVersion, + "X-Plex-Platform": pastaPlatform, + "X-Plex-Platform-Version": pastaPlatformVersion, + "X-Plex-Device": deviceInfo, + "X-Plex-Device-Name": deviceName + }, "method": "POST", "success": (data) => { let pinId = $(data).find('id')[0].innerHTML; @@ -117,7 +141,16 @@ function listenForValidPincode (pinId) { let currentTime = Date.now(); if ((currentTime - backOffTimer)/1000 < 180) { $.ajax({ - "url": `https://plex.tv/pins/${pinId}?X-Plex-Product=${plexProduct}&X-Plex-Client-Identifier=${clientIdentifier}`, + "url": `https://plex.tv/pins/${pinId}`, + "headers": { + "X-Plex-Client-Identifier": clientIdentifier, + "X-Plex-Product": plexProduct, + "X-Plex-Version": pastaVersion, + "X-Plex-Platform": pastaPlatform, + "X-Plex-Platform-Version": pastaPlatformVersion, + "X-Plex-Device": deviceInfo, + "X-Plex-Device-Name": deviceName + }, "method": "GET", "success": (data) => { if (data.pin.auth_token != null) { @@ -149,7 +182,7 @@ function listenForValidPincode (pinId) { function getServers () { $.ajax({ - "url": `https://plex.tv/pms/servers.xml?X-Plex-Product=${plexProduct}&X-Plex-Client-Identifier=${clientIdentifier}`, + "url": `https://plex.tv/pms/servers.xml?X-Plex-Client-Identifier=${clientIdentifier}`, "method": "GET", "headers": { "X-Plex-Token": plexToken @@ -176,6 +209,15 @@ function getServers () { "error": (data) => { console.log("ERROR L59"); console.log(data); + if (data.status == 401) { + console.log("Unauthorized"); + $("#pinAuthWarning").html(`<div class="alert alert-warning alert-dismissible fade show mt-3" role="alert"> + <strong>Warning:</strong> Unauthorized (401) - It looks like the old PIN code is no longer valid. Please choose the "Click here to logout" above to authorise again. + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div>`); + } } }); } @@ -298,6 +340,16 @@ function connectToPlex() { </button> </div>`); } + else if ((location.protocol == 'https:') && (localStorage.isPinAuth) && (plexUrl.indexOf('http:') > -1)) { + console.log("Trying to use http over a https site with PIN authentication"); + $("#pinAuthWarning").html(`<div class="alert alert-warning alert-dismissible fade show mt-3" role="alert"> + <strong>Warning:</strong> Error - You are trying to access a http server via the site in https. If you cannot see your libraries below, please load this site \ + over http by <a href="http://www.pastatool.com">clicking here</a>. + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div>`); + } else if ((location.protocol == 'https:') && (plexUrl.indexOf('http:') > -1)) { console.log("Trying to use http over a https site"); $("#authWarningText").html(`<div class="alert alert-warning alert-dismissible fade show mt-3" role="alert"> |