Browse Source

Adding minimum password length configuration option

Also improved the Advanced configuration tab's usefulness
Fixes #150
Alan Hardman 4 years ago
parent
commit
edaf63cea6
5 changed files with 50 additions and 29 deletions
  1. 3 2
      app/controller/admin.php
  2. 3 2
      app/controller/user.php
  3. 8 4
      app/dict/en.ini
  4. 35 21
      app/view/admin/config.html
  5. 1 0
      config-base.ini

+ 3 - 2
app/controller/admin.php

@@ -198,8 +198,9 @@ class Admin extends \Controller {
 				$this->_render("admin/users/edit.html");
 				return;
 			}
-			if(strlen($f3->get("POST.password")) < 6) {
-				$f3->set("error", "Passwords must be at least 6 characters");
+			$min = $f3->get("security.min_pass_len");
+			if(strlen($f3->get("POST.password")) < $min) {
+				$f3->set("error", "Passwords must be at least {$min} characters");
 				$this->_render("admin/users/edit.html");
 				return;
 			}

+ 3 - 2
app/controller/user.php

@@ -147,7 +147,8 @@ class User extends \Controller {
 
 			// Update password
 			if($security->hash($post["old_pass"], $user->salt) == $user->password) {
-				if(strlen($post["new_pass"]) >= 6) {
+				$min = $f3->get("security.min_pass_len");
+				if(strlen($post["new_pass"]) >= $min) {
 					if($post["new_pass"] == $post["new_pass_confirm"]) {
 						$user->salt = $security->salt();
 						$user->password = $security->hash($post["new_pass"], $user->salt);
@@ -156,7 +157,7 @@ class User extends \Controller {
 						$f3->set("error", "New passwords do not match");
 					}
 				} else {
-					$f3->set("error", "New password must be at least 6 characters.");
+					$f3->set("error", "New password must be at least {$min} characters.");
 				}
 			} else {
 				$f3->set("error", "Current password entered is not valid.");

+ 8 - 4
app/dict/en.ini

@@ -318,13 +318,17 @@ incoming_mail=Incoming Mail (IMAP)
 hostname=Hostname
 debug_level=Debug Level (DEBUG)
 cache_mode=Cache Mode (CACHE)
-cookie_expiration=Cookie Expiration (JAR.expire)
-max_upload_size=Max Upload Size (files.maxsize)
-censor_credit_card_numbers=Censor Credit Card Numbers (security.block_ccs)
+cookie_expiration=Cookie Expiration (seconds)
+max_upload_size=Max Upload Size (bytes)
+censor_credit_card_numbers=Censor Credit Card Numbers
 demo_user=Demo User (site.demo)
 config_note=Note
-imap_truncate_lines=IMAP Message Truncate Lines (mail.truncate_lines)
+imap_truncate_lines=IMAP Message Truncate Lines
 package_mail_config_note={0} uses your default PHP mail configuration for outgoing email.
 imap_settings_note=IMAP settings here will have no effect unless the {0} cron is being run.
 email_leave_blank=Leave blank to disable outgoing email
 advanced_config_note=These values can be changed by editing the values in the {0} database table.
+min_pass_len=Minimum Password Length
+security=Security
+general=General
+core=Core

+ 35 - 21
app/view/admin/config.html

@@ -42,15 +42,6 @@
 						<label class="control-label" for="site-logo">{{ @dict.logo }}</label>
 						<input type="text" class="form-control input-sm" name="site-logo" placeholder="(Site Name)" value="{{ @site.logo }}">
 					</div>
-					<div class="form-group">
-						<div class="checkbox">
-							<label>
-								<!-- TODO: Set checked attribute on current value, rather than default -->
-								<input type="checkbox" name="site-public_registration" value="1" {{ @site.public_registration ? 'checked' : '' }}>
-								{{ @dict.allow_public_registration }}
-							</label>
-						</div>
-					</div>
 				</div>
 
 				<div role="tabpanel" class="tab-pane fade" id="config-parse">
@@ -131,38 +122,61 @@
 							<label class="control-label" for="imap-password">{{ @dict.password }}</label>
 							<input type="text" class="form-control input-sm" name="imap-password" value="{{ str_repeat('*', strlen(@imap.password)) }}">
 						</div>
+						<div class="form-group">
+							<label class="control-label" for="mail-truncate_lines">{{ @dict.imap_truncate_lines }}</label>
+							<textarea class="form-control input-sm" name="mail-truncate_lines" rows="4">{{ implode("\n", is_array(@mail.truncate_lines) ? @mail.truncate_lines : \Base::instance()->split(@mail.truncate_lines)) | esc }}</textarea>
+						</div>
 						<p class="alert alert-info"><strong>{{ @dict.config_note }}:</strong> {{ @dict.imap_settings_note, '<code>checkmail.php</code>' | format }}</p>
 					</fieldset>
 				</div>
 
 				<div role="tabpanel" class="tab-pane fade" id="config-advanced">
+					<h3>{{ @dict.security }}</h3>
 					<div class="form-group">
-						<label class="control-label">{{ @dict.debug_level }}</label>
-						<input type="text" class="form-control input-sm" value="{{ @DEBUG }}" readonly>
+						<label class="control-label">{{ @dict.min_pass_len }}</label>
+						<input type="number" class="form-control input-sm" name="security-min_pass_len" value="{{ @security.min_pass_len }}">
 					</div>
 					<div class="form-group">
-						<label class="control-label">{{ @dict.cache_mode }}</label>
-						<input type="text" class="form-control input-sm" value="{{ @CACHE }}" readonly>
+						<div class="checkbox">
+							<label>
+								<input type="checkbox" name="security-block_ccs" value="1" {{ @security.block_ccs ? 'checked' : '' }}>
+								{{ @dict.censor_credit_card_numbers }}
+							</label>
+						</div>
 					</div>
+
+					<h3>{{ @dict.general }}</h3>
 					<div class="form-group">
 						<label class="control-label">{{ @dict.cookie_expiration }}</label>
-						<input type="text" class="form-control input-sm" value="{{ @JAR.expire }}" readonly>
+						<input type="text" class="form-control input-sm" value="{{ @JAR.expire }}">
 					</div>
 					<div class="form-group">
 						<label class="control-label">{{ @dict.max_upload_size }}</label>
-						<input type="text" class="form-control input-sm" value="{{ @files.maxsize }}" readonly>
+						<input type="text" class="form-control input-sm" value="{{ @files.maxsize }}">
 					</div>
 					<div class="form-group">
-						<label class="control-label">{{ @dict.censor_credit_card_numbers }}</label>
-						<input type="text" class="form-control input-sm" value="{{ @security.block_ccs ? 'Enabled' : 'Disabled' }}" readonly>
+						<div class="checkbox">
+							<label>
+								<input type="checkbox" name="site-public_registration" value="1" {{ @site.public_registration ? 'checked' : '' }}>
+								{{ @dict.allow_public_registration }}
+							</label>
+						</div>
 					</div>
+
+					<hr>
+
+					<h3>{{ @dict.core }}</h3>
 					<div class="form-group">
-						<label class="control-label">{{ @dict.demo_user }}</label>
-						<input type="text" class="form-control input-sm" value="{{ @site.demo ?: 'Disabled' }}" readonly>
+						<label class="control-label">{{ @dict.debug_level }}</label>
+						<input type="text" class="form-control input-sm" value="{{ @DEBUG }}" readonly>
 					</div>
 					<div class="form-group">
-						<label class="control-label" for="mail-truncate_lines">{{ @dict.imap_truncate_lines }}</label>
-						<textarea class="form-control input-sm" rows="4" readonly>{{ implode("\n", is_array(@mail.truncate_lines) ? @mail.truncate_lines : \Base::instance()->split(@mail.truncate_lines)) | esc }}</textarea>
+						<label class="control-label">{{ @dict.cache_mode }}</label>
+						<input type="text" class="form-control input-sm" value="{{ @CACHE }}" readonly>
+					</div>
+					<div class="form-group">
+						<label class="control-label">{{ @dict.demo_user }}</label>
+						<input type="text" class="form-control input-sm" value="{{ @site.demo ?: 'Disabled' }}" readonly>
 					</div>
 					<p class="alert alert-info">{{ @dict.advanced_config_note,'<code>config</code>' | format }}</p>
 				</div>

+ 1 - 0
config-base.ini

@@ -38,6 +38,7 @@ site.public_registration=0
 
 ; Block posting of credit card numbers
 security.block_ccs=0
+security.min_pass_len=6
 
 ; Project/task type IDs
 ; These should usually be left alone