Skip to content

Commit 6557413

Browse files
committed
FOUR-11415 Password Policy Configuration
1 parent 4b628ff commit 6557413

7 files changed

Lines changed: 39 additions & 33 deletions

File tree

‎ProcessMaker/Http/Controllers/Auth/LoginController.php‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class LoginController extends Controller
3838
*/
3939
protected $redirectTo = '/';
4040

41+
protected $maxAttempts;
42+
4143
/**
4244
* Create a new controller instance.
4345
*
@@ -46,6 +48,7 @@ class LoginController extends Controller
4648
public function __construct()
4749
{
4850
$this->middleware('guest')->except(['logout', 'beforeLogout', 'keepAlive']);
51+
$this->maxAttempts = (int) config('password-policies.login_attempts');
4952
}
5053

5154
/**

‎ProcessMaker/Models/User.php‎

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
use Illuminate\Foundation\Auth\User as Authenticatable;
99
use Illuminate\Notifications\Notifiable;
1010
use Illuminate\Validation\Rule;
11+
use Illuminate\Validation\Rules\Password;
1112
use Laravel\Passport\HasApiTokens;
1213
use ProcessMaker\Models\EmptyModel;
1314
use ProcessMaker\Notifications\ResetPassword as ResetPasswordNotification;
1415
use ProcessMaker\Query\Traits\PMQL;
1516
use ProcessMaker\Rules\StringHasAtLeastOneUpperCaseCharacter;
16-
use ProcessMaker\Rules\StringHasNumberOrSpecialCharacter;
1717
use ProcessMaker\Traits\Exportable;
1818
use ProcessMaker\Traits\HasAuthorization;
1919
use ProcessMaker\Traits\HideSystemResources;
@@ -183,13 +183,28 @@ public static function rules(self $existing = null)
183183
*/
184184
public static function passwordRules(self $existing = null)
185185
{
186-
return array_filter([
186+
// Mandatory policies
187+
$passwordPolicies = [
187188
'required',
188189
$existing ? 'sometimes' : '',
189-
'min:8',
190-
new StringHasNumberOrSpecialCharacter(),
191-
new StringHasAtLeastOneUpperCaseCharacter(),
192-
]);
190+
];
191+
// Configurable policies
192+
$passwordRules = Password::min(config('password-policies.minimum_length'));
193+
if (config('password-policies.maximum_length')) {
194+
$passwordPolicies[] = 'max:' . config('password-policies.maximum_length');
195+
}
196+
if (config('password-policies.numbers')) {
197+
$passwordRules->numbers();
198+
}
199+
if (config('password-policies.uppercase')) {
200+
$passwordPolicies[] = new StringHasAtLeastOneUpperCaseCharacter();
201+
}
202+
if (config('password-policies.special')) {
203+
$passwordRules->symbols();
204+
}
205+
$passwordPolicies[] = $passwordRules;
206+
207+
return $passwordPolicies;
193208
}
194209

195210
/**

‎config/password-policies.php‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
return [
4+
'minimum_length' => env('PASSWORD_POLICY_MINIMUM_LENGTH', 8),
5+
'maximum_length' => env('PASSWORD_POLICY_MAXIMUM_LENGTH', null),
6+
'numbers' => env('PASSWORD_POLICY_NUMBERS', true),
7+
'uppercase' => env('PASSWORD_POLICY_UPPERCASE', true),
8+
'special' => env('PASSWORD_POLICY_SPECIAL', true),
9+
//'expiration_days' => env('PASSWORD_POLICY_EXPIRATION_DAYS', 0), // 0 never expires
10+
'login_attempts' => env('PASSWORD_POLICY_LOGIN_ATTEMPTS', 5),
11+
];

‎resources/views/admin/users/edit.blade.php‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,12 +396,6 @@
396396
delete this.formData.password;
397397
return true
398398
}
399-
if (this.formData.password.trim().length > 0 && this.formData.password.trim().length < 8) {
400-
this.errors.password = ['Password must be at least 8 characters']
401-
this.password = ''
402-
this.submitted = false
403-
return false
404-
}
405399
if (this.formData.password !== this.formData.confPassword) {
406400
this.errors.password = ['Passwords must match']
407401
this.password = ''

‎resources/views/auth/passwords/change.blade.php‎

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
'v-bind:class' => '{\'form-control\':true, \'is-invalid\':errors.password}']) !!}
4646
</div>
4747
</vue-password>
48-
<small v-if="errors && errors.password && errors.password.length" class="text-danger">@{{ errors.password[0] }}</small>
48+
<small v-for="(error, index) in errors.password" class="text-danger">@{{ error }}</small>
4949
</div>
5050
<div class="form-group">
5151
{!!Form::label('confpassword', __('Confirm Password'))!!}<small class="ml-1">*</small>
@@ -94,11 +94,6 @@
9494
});
9595
},
9696
validatePassword() {
97-
if (this.$refs.passwordStrength.strength.score < 2) {
98-
this.errors.password = ['Password is too weak']
99-
return false
100-
}
101-
10297
if (!this.formData.password && !this.formData.confpassword) {
10398
return false;
10499
}
@@ -107,12 +102,6 @@
107102
return false
108103
}
109104
110-
if (this.formData.password.trim().length > 0 && this.formData.password.trim().length < 8) {
111-
this.errors.password = ['Password must be at least 8 characters']
112-
this.formData.password = ''
113-
return false
114-
}
115-
116105
if (this.formData.password !== this.formData.confpassword) {
117106
this.errors.password = ['Passwords must match']
118107
return false

‎resources/views/profile/edit.blade.php‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,6 @@
151151
delete this.formData.password;
152152
return true
153153
}
154-
if (this.formData.password.trim().length > 0 && this.formData.password.trim().length < 8) {
155-
this.errors.password = ['Password must be at least 8 characters']
156-
this.password = ''
157-
this.submitted = false
158-
return false
159-
}
160154
if (this.formData.password !== this.formData.confPassword) {
161155
this.errors.password = ['Passwords must match']
162156
this.password = ''

‎resources/views/shared/users/sidebar.blade.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
</div>
2323
</div>
2424
<div class="card card-body mt-3">
25-
<fieldset :disabled="{{ \Auth::user()->hasPermission('edit-user-and-password') || \Auth::user()->is_administrator ? 'false' : 'true' }}">
26-
<legend>
25+
<fieldset :disabled="{{ \Auth::user()->hasPermission('edit-user-and-password') || \Auth::user()->is_administrator ? 'false' : 'true' }}">
26+
<legend>
2727
<h5 class="mb-3 font-weight-bold">{{__('Login Information')}}</h5>
2828
</legend>
2929
<div class="form-group">
@@ -54,7 +54,7 @@
5454
{!! Form::label('confPassword', __('Confirm Password')) !!}
5555
{!! Form::password('confPassword', ['id' => 'confPassword', 'rows' => 4, 'class'=> 'form-control', 'v-model'
5656
=> 'formData.confPassword', 'autocomplete' => 'new-password', 'v-bind:class' => '{\'form-control\':true, \'is-invalid\':errors.password}']) !!}
57-
<div class="invalid-feedback" :style="{display: (errors.password) ? 'block' : 'none' }" role="alert" v-if="errors.password">@{{errors.password[0]}}</div>
57+
<div class="invalid-feedback" :style="{display: (errors.password) ? 'block' : 'none' }" role="alert" v-for="(error, index) in errors.password">@{{error}}</div>
5858
</div>
5959
@cannot('edit-user-and-password')
6060
<div class="form-group">

0 commit comments

Comments
 (0)