Browse Source

Merge pull request #1586 from causefx/v2-develop

V2 develop
causefx 5 years ago
parent
commit
12357eeb0d

+ 12 - 4
api/classes/organizr.class.php

@@ -60,7 +60,7 @@ class Organizr
 	
 	// ===================================
 	// Organizr Version
-	public $version = '2.1.184';
+	public $version = '2.1.195';
 	// ===================================
 	// Quick php Version check
 	public $minimumPHP = '7.2';
@@ -2375,11 +2375,19 @@ class Organizr
 				array(
 					'type' => 'input',
 					'name' => 'jellyfinURL',
-					'label' => 'Jellyfin URL',
+					'label' => 'Jellyfin API URL',
 					'value' => $this->config['jellyfinURL'],
-					'help' => 'Please make sure to use the same (sub)domain to access Jellyfin as Organizr\'s',
+					'help' => 'Please make sure to use the local address to the API',
 					'placeholder' => 'http(s)://hostname:port'
 				),
+				array(
+					'type' => 'input',
+					'name' => 'jellyfinSSOURL',
+					'label' => 'Jellyfin SSO URL',
+					'value' => $this->config['jellyfinSSOURL'],
+					'help' => 'Please make sure to use the same (sub)domain to access Jellyfin as Organizr\'s',
+					'placeholder' => 'http(s)://domain.com'
+				),
 				array(
 					'type' => 'switch',
 					'name' => 'ssoJellyfin',
@@ -2877,7 +2885,7 @@ class Organizr
 		->issuedAt(time())// Configures the time that the token was issue (iat claim)
 		->expiresAt(time() + (86400 * $days))// Configures the expiration time of the token (exp claim)
 		//->withClaim('username', $result['username'])// Configures a new claim, called "username"
-		//->withClaim('group', $result['group'])// Configures a new claim, called "group"
+		->withClaim('group', $result['group'])// Configures a new claim, called "group"
 		//->withClaim('groupID', $result['group_id'])// Configures a new claim, called "groupID"
 		//->withClaim('email', $result['email'])// Configures a new claim, called "email"
 		//->withClaim('image', $result['image'])// Configures a new claim, called "image"

+ 3 - 0
api/config/default.php

@@ -46,6 +46,7 @@ return array(
 	'jellyfinTabName' => '',
 	'jellyfinURL' => '',
 	'jellyfinToken' => '',
+	'jellyfinSSOURL' => '',
 	'plexID' => '',
 	'tautulliURL' => '',
 	'ombiURL' => '',
@@ -98,6 +99,7 @@ return array(
 	'transmissionHideSeeding' => false,
 	'transmissionHideCompleted' => false,
 	'transmissionCombine' => false,
+	'transmissionDisableCertCheck' => false,
 	'delugeURL' => '',
 	'delugePassword' => '',
 	'delugeHideSeeding' => false,
@@ -112,6 +114,7 @@ return array(
 	'qBittorrentReverseSorting' => false,
 	'qBittorrentCombine' => false,
 	'qBittorrentApiVersion' => '1',
+	'qBittorrentDisableCertCheck' => false,
 	'rTorrentURL' => '',
 	'rTorrentURLOverride' => '',
 	'rTorrentUsername' => '',

+ 20 - 6
api/functions/log-functions.php

@@ -2,9 +2,23 @@
 
 trait LogFunctions
 {
-
-}
-
-
-
-
+	public function info($msg, $username = null)
+	{
+		$this->writeLog('info', $msg, $username);
+	}
+	
+	public function error($msg, $username = null)
+	{
+		$this->writeLog('error', $msg, $username);
+	}
+	
+	public function warning($msg, $username = null)
+	{
+		$this->writeLog('warning', $msg, $username);
+	}
+	
+	public function debug($msg, $username = null)
+	{
+		$this->writeLog('debug', $msg, $username);
+	}
+}

+ 3 - 1
api/functions/sso-functions.php

@@ -53,6 +53,7 @@ trait SSOFunctions
 		$token = null;
 		try {
 			$url = $this->qualifyURL($this->config['jellyfinURL']);
+			$ssoUrl = $this->qualifyURL($this->config['jellyfinSSOURL']);
 			$headers = array(
 				'X-Emby-Authorization' => 'MediaBrowser Client="Organizr Jellyfin Tab", Device="Organizr_PHP", DeviceId="Organizr_SSO", Version="1.0"',
 				"Accept" => "application/json",
@@ -68,13 +69,14 @@ trait SSOFunctions
 			if ($response->success) {
 				$token = json_decode($response->body, true);
 				$this->writeLog('success', 'Jellyfin Token Function - Grabbed token.', $username);
+				return '{"Servers":[{"ManualAddress":"' . $ssoUrl . '","Id":"' . $token['ServerId'] . '","UserId":"' . $token['User']['Id'] . '","AccessToken":"' . $token['AccessToken'] . '"}]}';
 			} else {
 				$this->writeLog('error', 'Jellyfin Token Function - Jellyfin did not return Token', $username);
 			}
 		} catch (Requests_Exception $e) {
 			$this->writeLog('error', 'Jellyfin Token Function - Error: ' . $e->getMessage(), $username);
 		}
-		return '{"Servers":[{"ManualAddress":"' . $url . '","Id":"' . $token['ServerId'] . '","UserId":"' . $token['User']['Id'] . '","AccessToken":"' . $token['AccessToken'] . '"}]}';
+		return false;
 	}
 	
 	public function getOmbiToken($username, $password, $oAuthToken = null, $fallback = false)

+ 1 - 1
api/functions/token-functions.php

@@ -26,7 +26,7 @@ trait TokenFunctions
 				if ($jwttoken->validate($data)) {
 					$result['valid'] = true;
 					//$result['username'] = $jwttoken->getClaim('username');
-					//$result['group'] = $jwttoken->getClaim('group');
+					$result['group'] = ($jwttoken->hasClaim('group')) ? $jwttoken->getClaim('group') : 'N/A';
 					//$result['groupID'] = $jwttoken->getClaim('groupID');
 					$result['userID'] = $jwttoken->getClaim('userID');
 					//$result['email'] = $jwttoken->getClaim('email');

+ 8 - 2
api/homepage/qbittorrent.php

@@ -34,6 +34,12 @@ trait QBitTorrentHomepageItem
 						'help' => 'Please make sure to use local IP address and port - You also may use local dns name too.',
 						'placeholder' => 'http(s)://hostname:port'
 					),
+					array(
+						'type' => 'switch',
+						'name' => 'qBittorrentDisableCertCheck',
+						'label' => 'Disable Certificate Check',
+						'value' => $this->config['qBittorrentDisableCertCheck']
+					),
 					array(
 						'type' => 'select',
 						'name' => 'qBittorrentApiVersion',
@@ -123,7 +129,7 @@ trait QBitTorrentHomepageItem
 		$apiVersionQuery = ($this->config['qBittorrentApiVersion'] == '1') ? '/query/torrents?sort=' : '/api/v2/torrents/info?sort=';
 		$url = $digest['scheme'] . '://' . $digest['host'] . $digest['port'] . $digest['path'] . $apiVersionLogin;
 		try {
-			$options = ($this->localURL($this->config['qBittorrentURL'])) ? array('verify' => false) : array();
+			$options = $this->requestOptions($this->config['qBittorrentURL'], $this->config['qBittorrentDisableCertCheck'], $this->config['homepageDownloadRefresh']);
 			$response = Requests::post($url, array(), $data, $options);
 			$reflection = new ReflectionClass($response->cookies);
 			$cookie = $reflection->getProperty("cookies");
@@ -215,7 +221,7 @@ trait QBitTorrentHomepageItem
 		$apiVersionQuery = ($this->config['qBittorrentApiVersion'] == '1') ? '/query/torrents?sort=' : '/api/v2/torrents/info?sort=';
 		$url = $digest['scheme'] . '://' . $digest['host'] . $digest['port'] . $digest['path'] . $apiVersionLogin;
 		try {
-			$options = ($this->localURL($this->config['qBittorrentURL'])) ? array('verify' => false) : array();
+			$options = $this->requestOptions($this->config['qBittorrentURL'], $this->config['qBittorrentDisableCertCheck'], $this->config['homepageDownloadRefresh']);
 			$response = Requests::post($url, array(), $data, $options);
 			$reflection = new ReflectionClass($response->cookies);
 			$cookie = $reflection->getProperty("cookies");

+ 9 - 3
api/homepage/transmission.php

@@ -34,6 +34,12 @@ trait TransmissionHomepageItem
 						'help' => 'Please do not included /web in URL.  Please make sure to use local IP address and port - You also may use local dns name too.',
 						'placeholder' => 'http(s)://hostname:port'
 					),
+					array(
+						'type' => 'switch',
+						'name' => 'transmissionDisableCertCheck',
+						'label' => 'Disable Certificate Check',
+						'value' => $this->config['transmissionDisableCertCheck']
+					),
 					array(
 						'type' => 'input',
 						'name' => 'transmissionUsername',
@@ -101,7 +107,7 @@ trait TransmissionHomepageItem
 		$passwordInclude = ($this->config['transmissionUsername'] != '' && $this->config['transmissionPassword'] != '') ? $this->config['transmissionUsername'] . ':' . $this->decrypt($this->config['transmissionPassword']) . "@" : '';
 		$url = $digest['scheme'] . '://' . $passwordInclude . $digest['host'] . $digest['port'] . $digest['path'] . '/rpc';
 		try {
-			$options = ($this->localURL($this->config['transmissionURL'])) ? array('verify' => false) : array();
+			$options = $this->requestOptions($this->config['transmissionURL'], $this->config['transmissionDisableCertCheck'], $this->config['homepageDownloadRefresh']);
 			$response = Requests::get($url, array(), $options);
 			if ($response->headers['x-transmission-session-id']) {
 				$headers = array(
@@ -189,7 +195,7 @@ trait TransmissionHomepageItem
 		$passwordInclude = ($this->config['transmissionUsername'] != '' && $this->config['transmissionPassword'] != '') ? $this->config['transmissionUsername'] . ':' . $this->decrypt($this->config['transmissionPassword']) . "@" : '';
 		$url = $digest['scheme'] . '://' . $passwordInclude . $digest['host'] . $digest['port'] . $digest['path'] . '/rpc';
 		try {
-			$options = ($this->localURL($this->config['transmissionURL'])) ? array('verify' => false) : array();
+			$options = $this->requestOptions($this->config['transmissionURL'], $this->config['transmissionDisableCertCheck'], $this->config['homepageDownloadRefresh']);
 			$response = Requests::get($url, array(), $options);
 			if ($response->headers['x-transmission-session-id']) {
 				$headers = array(
@@ -245,4 +251,4 @@ trait TransmissionHomepageItem
 		$this->setAPIResponse('success', null, 200, $api);
 		return $api;
 	}
-}
+}

+ 1 - 1
api/pages/settings-user-manage-users.php

@@ -303,4 +303,4 @@ function get_page_settings_user_manage_users($Organizr)
     <div class="clearfix"></div>
 </form>
 ';
-}
+}

+ 35 - 0
api/pages/tabs.php

@@ -0,0 +1,35 @@
+<?php
+$GLOBALS['organizrPages'][] = 'tabs';
+function get_page_tabs($Organizr)
+{
+	if (!$Organizr) {
+		$Organizr = new Organizr();
+	}
+	return '
+<script>
+</script>
+<div class="container-fluid">
+    <div class="row bg-title">
+        <div class="col-lg-3 col-md-4 col-sm-4 col-xs-12">
+            <h4 class="page-title" lang="en">No Tabs Available</h4>
+        </div>
+        <!-- /.col-lg-12 -->
+    </div>
+    <!--.row-->
+    <div class="row">
+        <div class="col-lg-12">
+            <div class="panel panel-warning">
+                <div class="panel-heading"> <i class="ti-alert fa-fw"></i> <span lang="en">No Tabs Available</span></div>
+                <div class="panel-wrapper collapse in" aria-expanded="true">
+                    <div class="panel-body">
+                        <p lang="en">There are no available tabs for your group - please contact the Administrator</p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!--./row-->
+</div>
+<!-- /.container-fluid -->
+';
+}

+ 3 - 3
api/pages/wizard.php

@@ -24,8 +24,8 @@ function get_page_wizard($Organizr)
                                     message: \'The username must be more than 2 and less than 30 characters long\'
                                 },
                                 regexp: {
-                                    regexp: /^[a-zA-Z0-9_\.]+$/,
-                                    message: \'The username can only consist of alphabetical, number, dot and underscore\'
+                                    regexp: /^[a-zA-Z0-9_\.\@]+$/,
+                                    message: \'The username can only consist of alphabetical, number, at sign, dot and underscore\'
                                 }
                             }
                         },
@@ -386,4 +386,4 @@ function get_page_wizard($Organizr)
 </div>
 <!-- /.container-fluid -->
 ';
-}
+}

+ 4 - 42
css/organizr.css

@@ -122,6 +122,7 @@ span.jsgrid-pager-page.jsgrid-pager-current-page.btn.btn-primary{
 .organizr-area-right {
     height: calc(100vh - 40px);
     position: absolute;
+    width: 100%;
 }
 /* Larger Images */
 
@@ -1216,6 +1217,9 @@ ul.nav.customtab.nav-tabs.nav-low-margin {
     -webkit-animation-iteration-count: infinite;
     animation-iteration-count: infinite;
 }
+.heartbit.depend-heartbit {
+    top: -37.5px;
+}
 .ping .point {
     width: 6px;
     height: 6px;
@@ -4326,48 +4330,6 @@ html {
 .accordion > .card .card-header {
     margin-bottom: 0px; }
 
-@keyframes spinner-border {
-    to {
-        transform: rotate(360deg); } }
-
-.spinner-border {
-    display: inline-block;
-    width: 2rem;
-    height: 2rem;
-    vertical-align: text-bottom;
-    border: 0.25em solid currentColor;
-    border-right-color: transparent;
-    border-radius: 50%;
-    animation: spinner-border .75s linear infinite; }
-
-.spinner-border-sm {
-    width: 1rem;
-    height: 1rem;
-    border-width: 0.2em; }
-
-@keyframes spinner-grow {
-    0% {
-        transform: scale(0);
-    }
-    50% {
-        opacity: 1;
-    }
-}
-
-.spinner-grow {
-    display: inline-block;
-    width: 2rem;
-    height: 2rem;
-    vertical-align: text-bottom;
-    background-color: currentColor;
-    border-radius: 50%;
-    opacity: 0;
-    animation: spinner-grow .75s linear infinite; }
-
-.spinner-grow-sm {
-    width: 1rem;
-    height: 1rem; }
-
 .pollen-wrapper {
     display: flex;
     flex-direction: column;

File diff suppressed because it is too large
+ 0 - 0
css/organizr.min.css


+ 1 - 1
index.php

@@ -139,7 +139,7 @@ $Organizr = new Organizr();
     <div class="error-page bg-org"></div>
     <div class="login-area hidden"></div>
     <div class="p-0" id="page-wrapper">
-        <div class="organizr-area"></div>
+        <div class="organizr-area hidden"></div>
         <div class="plugin-listing p-0 hidden"></div>
         <div class="internal-listing p-0 hidden"></div>
         <div class="iFrame-listing p-0 hidden"></div>

+ 1 - 0
js/custom.js

@@ -584,6 +584,7 @@ $(document).on("click", ".addNewUser", function () {
 		message('User Created',response.message,activeInfo.settings.notifications.position,"#FFF","success","5000");
 		if(callbacks){ callbacks.fire(); }
 		clearForm('#new-user-form');
+		$('#jsGrid-Users').jsGrid('render');
 		$.magnificPopup.close();
 	}).fail(function(xhr) {
 		OrganizrApiError(xhr, 'API Error');

File diff suppressed because it is too large
+ 0 - 0
js/custom.min.js


+ 20 - 13
js/functions.js

@@ -498,16 +498,18 @@ function cleanClass(string){
 // What the hell is this?  I don't remember this lol
 function noTabs(arrayItems){
 	if (arrayItems.data.user.loggedin === true) {
-		organizrConnect('api/?v1/no_tabs').success(function(data) {
-            try {
-                var response = JSON.parse(data);
-            }catch(e) {
-	            organizrCatchError(e,data);
-            }
-			console.log("Organizr Function: No Tabs Available");
-			$(response.data).appendTo($('.organizr-area'));
+		organizrAPI2('GET','api/v2/page/tabs').success(function(data) {
+			try {
+				var json = data.response;
+				organizrConsole('Organizr Function','No tabs available');
+				$(json.data).appendTo($('.organizr-area'));
+				$('.organizr-area').removeClass('hidden');
+				$("#preloader").fadeOut();
+			}catch(e) {
+				organizrCatchError(e,data);
+			}
 		}).fail(function(xhr) {
-			OrganizrApiError(xhr);
+			OrganizrApiError(xhr, 'Error');
 		});
 	}else {
 		$('.show-login').trigger('click');
@@ -3876,7 +3878,6 @@ function countdown(remaining) {
 function dockerUpdate(){
     if(activeInfo.settings.misc.docker){
 	    showUpdateBar();
-        //$(updateBar()).appendTo('.organizr-area');
         updateUpdateBar('Starting Download','20%');
         messageSingle(window.lang.translate('[DO NOT CLOSE WINDOW]'),window.lang.translate('Starting Update Process'),activeInfo.settings.notifications.position,'#FFF','success','60000');
         organizrAPI2('GET','api/v2/update/docker').success(function(data) {
@@ -3890,7 +3891,6 @@ function dockerUpdate(){
 function windowsUpdate(){
     if(activeInfo.serverOS == 'win'){
 	    showUpdateBar();
-    	//$(updateBar()).appendTo('.organizr-area');
         updateUpdateBar('Starting Download','20%');
         messageSingle(window.lang.translate('[DO NOT CLOSE WINDOW]'),window.lang.translate('Starting Update Process'),activeInfo.settings.notifications.position,'#FFF','success','60000');
         organizrAPI2('GET','api/v2/update/windows').success(function(data) {
@@ -3913,7 +3913,6 @@ function updateNow(){
     }
 	organizrConsole('Update Function','Starting Update Process');
 	showUpdateBar();
-	//$(updateBar()).appendTo('.organizr-area');
 	updateUpdateBar('Starting Download','5%');
 	messageSingle(window.lang.translate('[DO NOT CLOSE WINDOW]'),window.lang.translate('Starting Update Process'),activeInfo.settings.notifications.position,'#FFF','success','60000');
 	organizrAPI2('GET','api/v2/update/download/'+ activeInfo.branch).success(function(data) {
@@ -4183,6 +4182,7 @@ function buildWizard(){
         }
 		organizrConsole('Organizr Function','Starting Install Wizard');
 		$(json.data).appendTo($('.organizr-area'));
+		$('.organizr-area').removeClass('hidden');
 	}).fail(function(xhr) {
 		OrganizrApiError(xhr, 'Wiizard Error');
 	});
@@ -4197,6 +4197,7 @@ function buildDependencyCheck(orgdata){
         }
 		organizrConsole('Organizr Function','Starting Dependencies Check');
 		$(json.data).appendTo($('.organizr-area'));
+		$('.organizr-area').removeClass('hidden');
 		$(buildBrowserInfo()).appendTo($('#browser-info'));
 		$('#web-folder').html(buildWebFolder(orgdata));
 		$('#php-version-check').html(buildPHPCheck(orgdata));
@@ -4212,7 +4213,7 @@ function buildDependencyInfo(arrayItems){
 			listing += '<li class="depenency-item" data-name="'+v+'"><a href="javascript:void(0)"><i class="fa fa-check text-success"></i> '+v+'</a></li>';
 		});
 	$.each(arrayItems.data.status.dependenciesInactive, function(i,v) {
-		listing += '<li class="depenency-item" data-name="'+v+'"><a href="javascript:void(0)"><i class="fa fa-close text-danger"><div class="notify"><span class="heartbit"></span></div></i> '+v+'</a></li>';
+		listing += '<li class="depenency-item" data-name="'+v+'"><a href="javascript:void(0)"><i class="fa fa-close text-danger"><div class="notify"><span class="heartbit depend-heartbit"></span></div></i> '+v+'</a></li>';
 	});
 	return listing;
 }
@@ -4343,6 +4344,12 @@ function logIcon(type){
 		case "success":
 			return '<i class="fa fa-check text-success"></i><span class="hidden">Success</span>';
 			break;
+		case "info":
+			return '<i class="fa fa-info text-info"></i><span class="hidden">Info</span>';
+			break;
+		case "debug":
+			return '<i class="fa fa-code text-primary"></i><span class="hidden">Debug</span>';
+			break;
 		case "warning":
 			return '<i class="fa fa-exclamation-triangle text-warning"></i><span class="hidden">Warning</span>';
 			break;

+ 7 - 0
js/version.json

@@ -334,5 +334,12 @@
     "new": "",
     "fixed": "Missing variable",
     "notes": "This is a quick hotfix"
+  },
+  "2.1.195": {
+    "date": "2021-02-01 20:00",
+    "title": "Weekly Update",
+    "new": "ignore cert to transmission (#1177)|ignore cert to qbit (#1177)|no tabs api function|log functions",
+    "fixed": "Jellyfin SSO fails behind reverse proxy (#1585)|Unable to use \"@\" in username during initial account setup (#1584)|Re-add JWT claims removed from token (#1577)|heart on dependency|refresh to add new user|organizr-area css",
+    "notes": "remove spinner css classes"
   }
 }

Some files were not shown because too many files changed in this diff