소스 검색

renamed group_id_min to group_id_max
removed old column group_id_min
added matchUserIP to security settings for tokens
added checkIfColumnExists dropColumnFromDatabase functions

CauseFX 3 년 전
부모
커밋
216033b891
8개의 변경된 파일101개의 추가작업 그리고 33개의 파일을 삭제
  1. 14 6
      api/classes/organizr.class.php
  2. 2 1
      api/config/default.php
  3. 66 6
      api/functions/upgrade-functions.php
  4. 5 6
      api/pages/settings-tab-editor-tabs.php
  5. 5 5
      js/custom.js
  6. 0 0
      js/custom.min.js
  7. 4 4
      js/functions.js
  8. 5 5
      js/version.json

+ 14 - 6
api/classes/organizr.class.php

@@ -65,7 +65,7 @@ class Organizr
 
 	// ===================================
 	// Organizr Version
-	public $version = '2.1.2000';
+	public $version = '2.1.2200';
 	// ===================================
 	// Quick php Version check
 	public $minimumPHP = '7.4';
@@ -1702,6 +1702,13 @@ class Organizr
 						return false;
 					}
 				}
+				if ($allTokens[$tokenKey]['ip'] !== $this->userIP()) {
+					if ($this->config['matchUserIP']) {
+						$this->setLoggerChannel('Authentication')->warning('Mismatch of user IP', ['token' => $allTokens[$tokenKey]['ip'], 'user' => $this->userIP()]);
+						$this->invalidToken($token);
+						return false;
+					}
+				}
 				if ($api) {
 					$this->setResponse(200, 'Token is valid');
 				}
@@ -2393,6 +2400,7 @@ class Organizr
 				$this->settingsOption('select', 'lockoutMinAuth', ['label' => 'Lockout Groups From', 'options' => $this->groupSelect()]),
 				$this->settingsOption('select', 'lockoutMaxAuth', ['label' => 'Lockout Groups To', 'options' => $this->groupSelect()]),
 				$this->settingsOption('switch', 'matchUserAgents', ['label' => 'Match UserAgent', 'help' => 'Match Browser UserAgent to Token UserAgent - Can be very aggressive on matching']),
+				$this->settingsOption('switch', 'matchUserIP', ['label' => 'Match User IP', 'help' => 'Match User IP to Token IP']),
 				$this->settingsOption('switch', 'traefikAuthEnable', ['label' => 'Enable Traefik Auth Redirect', 'help' => 'This will enable the webserver to forward errors so traefik will accept them']),
 				$this->settingsOption('input', 'traefikDomainOverride', ['label' => 'Traefik Domain for Return Override', 'help' => 'Please use a FQDN on this URL Override', 'placeholder' => 'http(s)://domain']),
 				$this->settingsOption('select', 'debugAreaAuth', ['label' => 'Minimum Authentication for Debug Area', 'options' => $this->groupSelect(), 'settings' => '{}']),
@@ -3287,7 +3295,7 @@ class Organizr
 					`default`	INTEGER,
 					`enabled`	INTEGER,
 					`group_id`	INTEGER,
-					`group_id_min` INTEGER DEFAULT \'0\',
+					`group_id_max` INTEGER DEFAULT \'0\',
 					`add_to_admin`	INTEGER DEFAULT \'0\',
 					`image`	TEXT,
 					`type`	INTEGER,
@@ -4049,7 +4057,7 @@ class Organizr
 			array(
 				'function' => 'fetchAll',
 				'query' => array(
-					'SELECT * FROM tabs WHERE `group_id` >= ? AND `group_id_min` <= ? AND `enabled` = 1 ORDER BY `order` ' . $sort,
+					'SELECT * FROM tabs WHERE `group_id` >= ? AND `group_id_max` <= ? AND `enabled` = 1 ORDER BY `order` ' . $sort,
 					$this->user['groupID'],
 					$this->user['groupID'],
 				),
@@ -5185,15 +5193,15 @@ class Organizr
 			}
 		}
 		if (array_key_exists('group_id', $array)) {
-			$groupCheck = (array_key_exists('group_id_min', $array)) ? $array['group_id_min'] : $tabInfo['group_id_min'];
+			$groupCheck = (array_key_exists('group_id_max', $array)) ? $array['group_id_max'] : $tabInfo['group_id_max'];
 			if ($array['group_id'] < $groupCheck) {
 				$this->setAPIResponse('error', 'Tab name: ' . $tabInfo['name'] . ' cannot have a lower Group Id Max than Group Id Min', 409);
 				return false;
 			}
 		}
-		if (array_key_exists('group_id_min', $array)) {
+		if (array_key_exists('group_id_max', $array)) {
 			$groupCheck = (array_key_exists('group_id', $array)) ? $array['group_id'] : $tabInfo['group_id'];
-			if ($array['group_id_min'] > $groupCheck) {
+			if ($array['group_id_max'] > $groupCheck) {
 				$this->setAPIResponse('error', 'Tab name: ' . $tabInfo['name'] . ' cannot have a higher Group Id Min than Group Id Max', 409);
 				return false;
 			}

+ 2 - 1
api/config/default.php

@@ -664,5 +664,6 @@ return [
 	'slackLogLevel' => 'WARNING',
 	'slackLogWebhook' => '',
 	'slackLogWebHookChannel' => '',
-	'matchUserAgents' => false
+	'matchUserAgents' => false,
+	'matchUserIP' => true
 ];

+ 66 - 6
api/functions/upgrade-functions.php

@@ -89,7 +89,7 @@ trait UpgradeFunctions
 			}
 			// End Upgrade check start for version above
 			// Upgrade check start for version below
-			$versionCheck = '2.1.2000';
+			$versionCheck = '2.1.2200';
 			if ($compare->lessThan($oldVer, $versionCheck)) {
 				$updateDB = false;
 				$oldVer = $versionCheck;
@@ -113,6 +113,56 @@ trait UpgradeFunctions
 		}
 	}
 
+	public function dropColumnFromDatabase($table = '', $columnName = '')
+	{
+		if ($table == '' || $columnName == '') {
+			return false;
+		}
+		if ($this->hasDB()) {
+			$columnExists = $this->checkIfColumnExists($table, $columnName);
+			if ($columnExists) {
+				$columnAlter = [
+					array(
+						'function' => 'query',
+						'query' => ['ALTER TABLE %n DROP %n',
+							(string)$table,
+							(string)$columnName,
+						]
+					)
+				];
+				$AlterQuery = $this->processQueries($columnAlter);
+				return (boolean)($AlterQuery);
+			}
+		}
+		return false;
+	}
+
+	public function checkIfColumnExists($table = '', $columnName = '')
+	{
+		if ($table == '' || $columnName == '') {
+			return false;
+		}
+		if ($this->hasDB()) {
+			if ($this->config['driver'] === 'sqlite3') {
+				$term = 'SELECT COUNT(*) AS has_column FROM pragma_table_info(?) WHERE name=?';
+			} else {
+				$term = 'SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = "' . $this->config['dbName'] . '" AND TABLE_NAME=? AND COLUMN_NAME=?';
+			}
+			$tableInfo = [
+				array(
+					'function' => 'fetchSingle',
+					'query' => array(
+						$term,
+						(string)$table,
+						(string)$columnName
+					)
+				)
+			];
+			$query = $this->processQueries($tableInfo);
+			return (boolean)($query);
+		}
+	}
+
 	public function addColumnToDatabase($table = '', $columnName = '', $definition = 'TEXT')
 	{
 		if ($table == '' || $columnName == '' || $definition == '') {
@@ -359,9 +409,9 @@ trait UpgradeFunctions
 			case '2.1.1860':
 				$this->upgradePluginsToDataFolder();
 				break;
-			case '2.1.2000':
+			case '2.1.2200':
 				$this->backupOrganizr();
-				$this->addGroupIdMinToDatabase();
+				$this->addGroupIdMaxToDatabase();
 				$this->addAddToAdminToDatabase();
 				break;
 		}
@@ -634,12 +684,22 @@ trait UpgradeFunctions
 		return false;
 	}
 
-	public function addGroupIdMinToDatabase()
+	public function addGroupIdMaxToDatabase()
 	{
 		$this->setLoggerChannel('Database Migration')->info('Starting database update');
-		$addColumn = $this->addColumnToDatabase('tabs', 'group_id_min', 'INTEGER DEFAULT \'0\'');
+		$hasOldColumn = $this->checkIfColumnExists('tabs', 'group_id_min');
+		if ($hasOldColumn) {
+			$this->setLoggerChannel('Database Migration')->info('Cleaning up database by removing old group_id_min');
+			$removeColumn = $this->dropColumnFromDatabase('tabs', 'group_id_min');
+			if ($removeColumn) {
+				$this->setLoggerChannel('Database Migration')->info('Removed group_id_min from database');
+			} else {
+				$this->setLoggerChannel('Database Migration')->warning('Error removing group_id_min from database');
+			}
+		}
+		$addColumn = $this->addColumnToDatabase('tabs', 'group_id_max', 'INTEGER DEFAULT \'0\'');
 		if ($addColumn) {
-			$this->setLoggerChannel('Database Migration')->notice('Added group_id_min to database');
+			$this->setLoggerChannel('Database Migration')->notice('Added group_id_max to database');
 			return true;
 		} else {
 			$this->setLoggerChannel('Database Migration')->warning('Could not update database');

+ 5 - 6
api/pages/settings-tab-editor-tabs.php

@@ -67,7 +67,6 @@ function get_page_settings_tab_editor_tabs($Organizr)
 	return '
 	<script>
 	buildTabEditor();
-	
 	' . $iconSelectors . '
 	</script>
 	<div class="panel bg-org panel-info">
@@ -85,10 +84,10 @@ function get_page_settings_tab_editor_tabs($Organizr)
 							<th width="20" class="text-center"></th>
 							<th width="70" class="text-center"></th>
 							<th lang="en">NAME</th>
-							<th lang="en">CATEGORY</th>
-							<th lang="en">GROUP FROM</th>
-							<th lang="en">GROUP TO</th>
-							<th lang="en">TYPE</th>
+							<th class="text-center" lang="en">CATEGORY</th>
+							<th class="text-center" lang="en">MIN GROUP</th>
+							<th class="text-center" lang="en">MAX GROUP</th>
+							<th class="text-center" lang="en">TYPE</th>
 							<th lang="en" style="text-align:center">DEFAULT</th>
 							<th lang="en" style="text-align:center">ACTIVE</th>
 							<th lang="en" style="text-align:center">SPLASH</th>
@@ -100,7 +99,7 @@ function get_page_settings_tab_editor_tabs($Organizr)
 						</tr>
 					</thead>
 					<tbody id="tabEditorTable">
-						<td class="text-center" colspan="12"><i class="fa fa-spin fa-spinner"></i></td>
+						<td class="text-center" colspan="15"><i class="fa fa-spin fa-spinner"></i></td>
 					</tbody>
 				</table>
 			</form>

+ 5 - 5
js/custom.js

@@ -680,24 +680,24 @@ $(document).on("click", ".deleteUser", function () {
     });
 });
 // CHANGE TAB GROUP MIN
-$(document).on("change", ".tabGroupSelectMin", function (event) {
+$(document).on("change", ".tabGroupSelectMax", function (event) {
 	var id = $(this).parent().parent().attr("data-id");
 	var groupID = $(this).find("option:selected").val();
 	var callbacks = $.Callbacks();
-	organizrAPI2('PUT','api/v2/tabs/' + id, {"group_id_min":groupID},true).success(function(data) {
+	organizrAPI2('PUT','api/v2/tabs/' + id, {"group_id_max":groupID},true).success(function(data) {
 		try {
 			var response = data.response;
 		}catch(e) {
 			organizrCatchError(e,data);
 		}
-		message('Tab Group Min Updated',response.message,activeInfo.settings.notifications.position,"#FFF","success","5000");
+		message('Tab Group Max Updated',response.message,activeInfo.settings.notifications.position,"#FFF","success","5000");
 		if(callbacks){ callbacks.fire(); }
 	}).fail(function(xhr) {
 		OrganizrApiError(xhr, 'Tab Group Error');
 	});
 });
 // CHANGE TAB GROUP MAX
-$(document).on("change", ".tabGroupSelectMax", function (event) {
+$(document).on("change", ".tabGroupSelectMin", function (event) {
 	var id = $(this).parent().parent().attr("data-id");
 	var groupID = $(this).find("option:selected").val();
 	var callbacks = $.Callbacks();
@@ -707,7 +707,7 @@ $(document).on("change", ".tabGroupSelectMax", function (event) {
 		}catch(e) {
 			organizrCatchError(e,data);
 		}
-		message('Tab Group Max Updated',response.message,activeInfo.settings.notifications.position,"#FFF","success","5000");
+		message('Tab Group Min Updated',response.message,activeInfo.settings.notifications.position,"#FFF","success","5000");
 		if(callbacks){ callbacks.fire(); }
 	}).fail(function(xhr) {
 		OrganizrApiError(xhr, 'Tab Group Error');

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
js/custom.min.js


+ 4 - 4
js/functions.js

@@ -1320,7 +1320,7 @@ function buildPluginsItem(array, type = 'enabled'){
 			var settings = '';
 		}
 		var plugin = `
-		<div class="col-lg-2 col-md-2 col-sm-4 col-xs-4">
+		<div class="col-lg-2 col-md-2 col-sm-6 col-xs-6 m-b-10">
 			<div class="white-box m-0">
 				<div class="el-card-item p-0">
 					<div class="el-card-avatar el-overlay-1 m-0"> <img class="lazyload" data-src="`+v.image+`">
@@ -3303,7 +3303,7 @@ function buildUserGroupSelect(array, userID, groupID){
 function buildTabGroupSelect(array, tabID, groupID, type){
 	var groupSelect = '';
 	var selected = '';
-	let name = (type == 'tabGroupSelectMin') ? 'group_id_min' : 'group_id';
+	let name = (type == 'tabGroupSelectMax') ? 'group_id_max' : 'group_id';
 	$.each(array, function(i,v) {
 		selected = '';
 		if(v.group_id == groupID){
@@ -3490,8 +3490,8 @@ function buildTabEditorItem(array){
 			</td>
 			<td><span class="tooltip-info" data-toggle="tooltip" data-placement="right" title="" data-original-title="`+v.url+`">`+v.name+`</span><span id="checkTabHomepageItem-`+v.id+`" data-url="`+v.url+`" data-url-local="`+v.url_local+`" data-name="`+v.name+`" class="checkTabHomepageItem mouse label label-rouded label-inverse pull-right"></span></td>
 			`+buildTabCategorySelect(array.categories,v.id, v.category_id)+`
-			`+buildTabGroupSelect(array.groups,v.id, v.group_id_min, 'tabGroupSelectMin')+`
-			`+buildTabGroupSelect(array.groups,v.id, v.group_id, 'tabGroupSelectMax')+`
+			`+buildTabGroupSelect(array.groups,v.id, v.group_id, 'tabGroupSelectMin')+`
+			`+buildTabGroupSelect(array.groups,v.id, v.group_id_max, 'tabGroupSelectMax')+`
 			`+buildTabTypeSelect(v.id, v.type, typeDisabled)+`
 			<td style="text-align:center"><div class="radio radio-purple"><input onclick="radioLoop(this);" type="radio" class="defaultSwitch" id="tab[`+v.id+`].default" name="tab[`+v.id+`].default" value="true" `+tof(v.default,'c')+`><label for="tab[`+v.id+`].default"></label></div></td>
 

+ 5 - 5
js/version.json

@@ -573,11 +573,11 @@
     "fixed": "Version number not updating",
     "notes": ""
   },
-  "2.1.2000": {
-    "date": "2022-05-11 16:49",
+  "2.1.2200": {
+    "date": "2022-05-18 15:11",
     "title": "New Group Min Max for Tabs",
-    "new": "added addGroupIdMinToDatabase and addAddToAdminToDatabase to upgrade functions|added configToken and validationConstraints function for new version of JWT|added config values for sendLogsToSlack, slackLogLevel, slackLogWebhook, slackLogWebHookChannel|added config values to organizr settings options for SlackWebhookHandler|added debug logging to OAuth pre-checks|added existing headers to oauth debug output|added functions isXML and testAndFormatString|added getLogLevelClass function|added GROUP MAX and GROUP MIN to tab settings headers|added group_id_min and add_to_admin to tabs database table|added group_id_min and add_to_admin to tab settings|added new handling for checking plex servers owned to catch error if not successful|added setChannel and setUsername functions to Logger|added slack-logs test connection to api and settings|added slack/discord webhook support for logs|added slackLogLevel config item|added slack logs to api docs|added SlackWebhookHandlerBuilder to PhpJsonLogger|added SlackWebhookHandler to MonologCreator|added SlackWebhookHandler to OrganizrLogger class|added tabGroupSelectMin - tabGroupSelectMax - addToAdminSwitch to tab settings ajax calls|added type to buildTabGroupSelect function",
-    "fixed": "fixed if webserver does not have access to plugin folder|fixed issue loading next tab if hash was still OrganizrLogin|fixed key missing from plugin css file|fixed stripos of getImagesSelect function|fixed time display issues with tokens",
-    "notes": "changed js and css for plugin files to use plugin version instead of organizr version|removed browser from api and token view page|removed left over console log from loadCustomJava|reworked getallheaders to return only lowercase array|temp return logger|tweaked convertIPToRange function|tweaked error handler to log errors as well|tweaked getAllUserTokens function to have option to not return browser field|tweaked validateToken function to match token browser with db token browser for extra security|updated createToken and jwtParse function to reflect new version of JWT|updated JWT to 4.1.5|wrapped user variable around function checkForOrganizrOAuth"
+    "new": "added addGroupIdMinToDatabase and addAddToAdminToDatabase to upgrade functions|added alias function log|added backup db to 2.1.2000|added block ui to wizard submission|added boolean variable loggerSetup|added check for has db on error handler|added check on checkForOrganizrOAuth function for db|added configToken and validationConstraints function for new version of JWT|added config values for sendLogsToSlack, slackLogLevel, slackLogWebhook, slackLogWebHookChannel|added config values to organizr settings options for SlackWebhookHandler|added debug logging to OAuth pre-checks|added existing headers to oauth debug output|added function addDatabaseToPaths|added functions isXML and testAndFormatString|added getLogLevelClass function|added GROUP MAX and GROUP MIN to tab settings headers|added group_id_min and add_to_admin to tabs database table|added group_id_min and add_to_admin to tab settings|added logging to upgradeToVersion function|added new handling for checking plex servers owned to catch error if not successful|added qualifyLength function to test against user inputted strings|added setChannel and setUsername functions to Logger|added slack-logs test connection to api and settings|added slack/discord webhook support for logs|added slackLogLevel config item|added slack logs to api docs|added SlackWebhookHandlerBuilder to PhpJsonLogger|added SlackWebhookHandler to MonologCreator|added SlackWebhookHandler to OrganizrLogger class|added sqlite db to backup check|added tabGroupSelectMin - tabGroupSelectMax - addToAdminSwitch to tab settings ajax calls|added toggle for matchUserAgents|added type to buildTabGroupSelect function|added UA to logger when mismatch",
+    "fixed": "fix default tab load if first tab has group|fixed formatting on debug area for object|fixed getTautulliFriendlyNames if error occurs|fixed icon term on select|fixed if webserver does not have access to plugin folder|fixed issue loading next tab if hash was still OrganizrLogin|fixed key missing from plugin css file|fixed sort issue with tabs caused by update|fixed stripos of getImagesSelect function|fixed tab name for groups in settings page|fixed time display issues with tokens|fix more lengths of user inputs|fix tautulli homepage errors if not connected",
+    "notes": "changed config items log to reflect only changed keys|changed group_id_min from 0 to 1|changed js and css for plugin files to use plugin version instead of organizr version|changed logging for backup|Display only php errors in organizr logs - full errors still in webserver logs|limit bookmark name and category to char 50|minimum php 7.4 needed now|missing semi-colon|moved the majority of old log entries to new logger|removed browser from api and token view page|removed function writeLog|removed left over console log from loadCustomJava|removed variable organizrLog and organizrLoginLog|renamed Group Min and Group Max to Group From and Group To|renamed variable log to logFile|reordered organizr constructor|Reverted group_id_min back to 0 from 1|reworked getallheaders to return only lowercase array|temp return logger|tweaked convertIPToRange function|tweaked error handler to log errors as well|tweaked getAllUserTokens function to have option to not return browser field|tweaked refresh list return|tweaked showHTML function|tweaked validateToken function to match token browser with db token browser for extra security|updated createToken and jwtParse function to reflect new version of JWT|updated JWT to 4.1.5|updated komga logger items to new logger|updated uuid framework for uuid (#1835)|update message and messageSingle functions|update news|version 2.1.2000|wrapped user variable around function checkForOrganizrOAuth"
   }
 }

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.