diff --git a/data/interfaces/default/base.html b/data/interfaces/default/base.html
index 71526a5b..898348f1 100644
--- a/data/interfaces/default/base.html
+++ b/data/interfaces/default/base.html
@@ -291,6 +291,7 @@ ${next.modalIncludes()}
+
diff --git a/data/interfaces/default/js/script.js b/data/interfaces/default/js/script.js
index 91b9bb2e..f7fc8c8b 100644
--- a/data/interfaces/default/js/script.js
+++ b/data/interfaces/default/js/script.js
@@ -489,4 +489,145 @@ function PopupCenter(url, title, w, h) {
}
return newWindow;
+}
+
+if (!localStorage.getItem('Tautulli_ClientId')) {
+ localStorage.setItem('Tautulli_ClientId', uuidv4());
+}
+
+function uuidv4() {
+ return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
+ (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
+ )
+}
+
+var x_plex_headers = {
+ 'Accept': 'application/json',
+ 'X-Plex-Product': '',
+ 'X-Plex-Version': '',
+ 'X-Plex-Client-Identifier': localStorage.getItem('Tautulli_ClientId'),
+ 'X-Plex-Platform': platform.name,
+ 'X-Plex-Platform-Version': platform.version,
+ 'X-Plex-Device': platform.os.toString(),
+ 'X-Plex-Device-Name': platform.name
+};
+
+var plex_oauth_window = null;
+const plex_oauth_loader = '' +
+ '
' +
+ '
' +
+ '
' +
+ '
' +
+ 'Redirecting to Plex Login...' +
+ '
' +
+ '
';
+
+function closePlexOAuthWindow() {
+ if (plex_oauth_window) {
+ plex_oauth_window.close();
+ }
+}
+
+getPlexOAuthPin = function () {
+ var deferred = $.Deferred();
+
+ $.ajax({
+ url: 'https://plex.tv/api/v2/pins?strong=true',
+ type: 'POST',
+ headers: x_plex_headers,
+ success: function(data) {
+ plex_oauth_window.location = 'https://app.plex.tv/auth/#!?clientID=' + x_plex_headers['X-Plex-Client-Identifier'] + '&code=' + data.code;
+ deferred.resolve({pin: data.id, code: data.code});
+ },
+ error: function() {
+ closePlexOAuthWindow();
+ deferred.reject();
+ }
+ });
+ return deferred;
+};
+
+var polling = null;
+
+function PlexOAuth(success, error, pre) {
+ if (typeof pre === "function") {
+ pre()
+ }
+ clearTimeout(polling);
+ closePlexOAuthWindow();
+ plex_oauth_window = PopupCenter('', 'Plex-OAuth', 600, 700);
+ $(plex_oauth_window.document.body).html(plex_oauth_loader);
+
+ getPlexOAuthPin().then(function (data) {
+ const pin = data.pin;
+ const code = data.code;
+ var keep_polling = true;
+
+ (function poll() {
+ polling = setTimeout(function () {
+ $.ajax({
+ url: 'https://plex.tv/api/v2/pins/' + pin,
+ type: 'GET',
+ headers: x_plex_headers,
+ success: function (data) {
+ if (data.authToken){
+ keep_polling = false;
+ closePlexOAuthWindow();
+ if (typeof success === "function") {
+ success(data.authToken)
+ }
+ }
+ },
+ error: function () {
+ keep_polling = false;
+ closePlexOAuthWindow();
+ if (typeof error === "function") {
+ error()
+ }
+ },
+ complete: function () {
+ if (keep_polling){
+ poll();
+ } else {
+ clearTimeout(polling);
+ }
+ },
+ timeout: 1000
+ });
+ }, 1000);
+ })();
+ }, function () {
+ closePlexOAuthWindow();
+ if (typeof error === "function") {
+ error()
+ }
+ });
}
\ No newline at end of file
diff --git a/data/interfaces/default/login.html b/data/interfaces/default/login.html
index 354ac624..7e0c6ed2 100644
--- a/data/interfaces/default/login.html
+++ b/data/interfaces/default/login.html
@@ -116,90 +116,17 @@
+