Skip to content

Commit c236ffe

Browse files
authored
Merge pull request #7728 from ProcessMaker/FOUR-20103
FOUR-20103 confirm identity validation does not work when email field is updated
2 parents 2286619 + 3380468 commit c236ffe

7 files changed

Lines changed: 236 additions & 59 deletions

File tree

ProcessMaker/Http/Controllers/Admin/UserController.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use ProcessMaker\Models\JsonData;
1010
use ProcessMaker\Models\Permission;
1111
use ProcessMaker\Models\User;
12+
use ProcessMaker\Package\Auth\Models\SsoUser;
1213
use ProcessMaker\Traits\HasControllerAddons;
1314

1415
class UserController extends Controller
@@ -66,6 +67,10 @@ function ($result, $item) {
6667
return $result;
6768
}
6869
);
70+
$ssoUser = false;
71+
if (class_exists(SsoUser::class)) {
72+
$ssoUser = SsoUser::where('user_id', $user->id)->exists();
73+
}
6974

7075
// Get global and valid 2FA preferences for the user
7176
$enabled2FA = config('password-policies.2fa_enabled', false);
@@ -92,6 +97,7 @@ function ($result, $item) {
9297
'is2FAEnabledForGroup',
9398
'addons',
9499
'addonsSettings',
100+
'ssoUser',
95101
));
96102
}
97103

ProcessMaker/Http/Controllers/Api/UserController.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,27 @@ public function update(User $user, Request $request)
417417
return $response;
418418
}
419419
}
420+
if ($fields['email'] !== $original['email']) {
421+
if (!isset($fields['valpassword'])) {
422+
return response([
423+
'message' => __(
424+
'A valid authentication is required for for update the email.'
425+
),
426+
'errors' => [
427+
'email' => [
428+
__(
429+
'The password is required.'
430+
),
431+
],
432+
],
433+
], 422);
434+
} else {
435+
$response = $this->validateBeforeChange(Auth::user(), $fields['valpassword']);
436+
if ($response) {
437+
return $response;
438+
}
439+
}
440+
}
420441
if (Auth::user()->is_administrator && $request->has('is_administrator')) {
421442
// user must be an admin to make another user an admin
422443
$user->is_administrator = $request->get('is_administrator');
@@ -469,6 +490,32 @@ private function validateCellPhoneNumber(User $user, $number)
469490
return false;
470491
}
471492

493+
/**
494+
* Validate the phone number for SMS two-factor authentication.
495+
*
496+
* @param User $user User to validate
497+
* @param mixed $password String to validate
498+
*/
499+
private function validateBeforeChange(User $user, $password)
500+
{
501+
if (!Hash::check($password, $user->password)) {
502+
return response([
503+
'message' => __(
504+
'A valid authentication is required for for update the email.'
505+
),
506+
'errors' => [
507+
'email' => [
508+
__(
509+
'The authentication is incorrect.'
510+
),
511+
],
512+
],
513+
], 422);
514+
}
515+
516+
return false;
517+
}
518+
472519
/**
473520
* Update a user's pinned BPMN elements on Modeler
474521
*

ProcessMaker/Http/Controllers/ProfileController.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use ProcessMaker\i18nHelper;
77
use ProcessMaker\Models\JsonData;
88
use ProcessMaker\Models\User;
9+
use ProcessMaker\Package\Auth\Models\SsoUser;
910
use ProcessMaker\Traits\HasControllerAddons;
1011

1112
class ProfileController extends Controller
@@ -43,6 +44,11 @@ function ($result, $item) {
4344
}
4445
);
4546

47+
$ssoUser = false;
48+
if (class_exists(SsoUser::class)) {
49+
$ssoUser = SsoUser::where('user_id', $currentUser->id)->exists();
50+
}
51+
4652
// Get global and valid 2FA preferences for the user
4753
$enabled2FA = config('password-policies.2fa_enabled', false);
4854
$global2FAEnabled = config('password-policies.2fa_method', []);
@@ -53,7 +59,7 @@ function ($result, $item) {
5359

5460
return view('profile.edit',
5561
compact('currentUser', 'states', 'timezones', 'countries', 'datetimeFormats',
56-
'status', 'enabled2FA', 'global2FAEnabled', 'is2FAEnabledForGroup', 'addons'));
62+
'status', 'enabled2FA', 'global2FAEnabled', 'is2FAEnabledForGroup', 'addons', 'ssoUser'));
5763
}
5864

5965
/**

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

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@
256256
image: '',
257257
status: @json($status),
258258
global2FAEnabled: @json($global2FAEnabled),
259+
ssoUser:@json($ssoUser),
259260
errors: {
260261
username: null,
261262
firstname: null,
@@ -281,6 +282,8 @@
281282
groups: [],
282283
userGroupsFilter: '',
283284
focusErrors: 'errors',
285+
originalEmail: '',
286+
emailHasChanged: false,
284287
}
285288
},
286289
created() {
@@ -338,6 +341,15 @@
338341
if (created) {
339342
ProcessMaker.alert(this.$t('The user was successfully created'), 'success');
340343
}
344+
this.originalEmail = this.formData.email;
345+
const togglePassword = document.querySelector('#togglePassword');
346+
const password = document.querySelector('#valpassword');
347+
348+
togglePassword.addEventListener('click', function (e) {
349+
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
350+
password.setAttribute('type', type);
351+
this.classList.toggle('fa-eye-slash');
352+
});
341353
},
342354
watch: {
343355
selectedPermissions: function () {
@@ -464,28 +476,12 @@
464476
return true
465477
},
466478
profileUpdate($event) {
467-
this.resetErrors();
468-
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
469-
// User has not enabled two-factor authentication correctly
470-
ProcessMaker.alert(
471-
this.$t('The Two Step Authentication Method has not been set. Please contact your administrator.'),
472-
'warning'
473-
);
474-
return false;
479+
if(this.emailHasChanged && !this.ssoUser) {
480+
$('#validateModal').modal('show');
481+
} else {
482+
this.saveProfileChanges();
475483
}
476-
if (!this.validatePassword()) return false;
477-
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
478-
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1) return false;
479-
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
480-
.then(response => {
481-
ProcessMaker.alert(this.$t('User Updated Successfully '), 'success');
482-
if (this.formData.id == window.ProcessMaker.user.id) {
483-
window.ProcessMaker.events.$emit('update-profile-avatar');
484-
}
485-
})
486-
.catch(error => {
487-
this.errors = error.response.data.errors;
488-
});
484+
489485
},
490486
permissionUpdate() {
491487
ProcessMaker.apiClient.put("/permissions", {
@@ -560,7 +556,45 @@
560556
.then(response => {
561557
this.groups = response.data.data
562558
});
563-
}
559+
},
560+
showModal() {
561+
$('#validateModal').modal('show');
562+
},
563+
closeModal() {
564+
$('#validateModal').modal('hide');
565+
},
566+
saveProfileChanges() {
567+
this.resetErrors();
568+
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
569+
// User has not enabled two-factor authentication correctly
570+
ProcessMaker.alert(
571+
this.$t('The Two Step Authentication Method has not been set. Please contact your administrator.'),
572+
'warning'
573+
);
574+
return false;
575+
}
576+
if (!this.validatePassword()) return false;
577+
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
578+
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1) return false;
579+
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
580+
.then(response => {
581+
ProcessMaker.alert(this.$t('User Updated Successfully '), 'success');
582+
this.originalEmail = this.formData.email;
583+
this.emailHasChanged = false;
584+
if (this.formData.id == window.ProcessMaker.user.id) {
585+
window.ProcessMaker.events.$emit('update-profile-avatar');
586+
this.formData.valpassword = "";
587+
}
588+
})
589+
.catch(error => {
590+
this.errors = error.response.data.errors;
591+
});
592+
593+
this.closeModal();
594+
},
595+
checkEmailChange() {
596+
this.emailHasChanged = this.formData.email !== this.originalEmail;
597+
},
564598
}
565599
});
566600
</script>
@@ -623,3 +657,4 @@
623657
}
624658
</style>
625659
@endsection
660+

resources/views/profile/edit.blade.php

Lines changed: 63 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
states: @json($states),
136136
status: @json($status),
137137
global2FAEnabled: @json($global2FAEnabled),
138+
ssoUser:@json($ssoUser),
138139
errors: {
139140
username: null,
140141
firstname: null,
@@ -145,6 +146,8 @@
145146
},
146147
confPassword: '',
147148
image: '',
149+
originalEmail: '',
150+
emailHasChanged: false,
148151
options: [
149152
{
150153
src: @json($currentUser['avatar']),
@@ -168,37 +171,27 @@
168171
});
169172
}
170173
},
174+
mounted() {
175+
this.originalEmail = this.formData.email;
176+
const togglePassword = document.querySelector('#togglePassword');
177+
const password = document.querySelector('#valpassword');
178+
179+
togglePassword.addEventListener('click', function (e) {
180+
const type = password.getAttribute('type') === 'password' ? 'text' : 'password';
181+
password.setAttribute('type', type);
182+
this.classList.toggle('fa-eye-slash');
183+
});
184+
},
171185
methods: {
172186
openAvatarModal() {
173187
modalVueInstance.$refs.updateAvatarModal.show();
174188
},
175189
profileUpdate() {
176-
this.resetErrors();
177-
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
178-
let message = 'The Two Step Authentication Method has not been set. ' +
179-
'Please contact your administrator.';
180-
// User has not enabled two-factor authentication correctly
181-
ProcessMaker.alert(this.$t($message), 'warning');
182-
return false;
183-
}
184-
if (!this.validatePassword()) return false;
185-
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
186-
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1)
187-
return false;
188-
if (this.image) {
189-
this.formData.avatar = this.image;
190-
}
191-
if (this.image === false) {
192-
this.formData.avatar = false;
193-
}
194-
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
195-
.then((response) => {
196-
ProcessMaker.alert(this.$t('Your profile was saved.'), 'success')
197-
window.ProcessMaker.events.$emit('update-profile-avatar');
198-
})
199-
.catch(error => {
200-
this.errors = error.response.data.errors;
201-
});
190+
if(this.emailHasChanged && !this.ssoUser) {
191+
$('#validateModal').modal('show');
192+
} else {
193+
this.saveProfileChanges();
194+
}
202195
},
203196
deleteAvatar() {
204197
let optionValues = formVueInstance.$data.options[0];
@@ -241,6 +234,48 @@
241234
onClose() {
242235
window.location.href = '/admin/users';
243236
},
237+
showModal() {
238+
$('#validateModal').modal('show');
239+
},
240+
closeModal() {
241+
$('#validateModal').modal('hide');
242+
},
243+
saveProfileChanges() {
244+
this.resetErrors();
245+
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
246+
let message = 'The Two Step Authentication Method has not been set. ' +
247+
'Please contact your administrator.';
248+
// User has not enabled two-factor authentication correctly
249+
ProcessMaker.alert(this.$t($message), 'warning');
250+
return false;
251+
}
252+
if (!this.validatePassword()) return false;
253+
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
254+
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1)
255+
return false;
256+
if (this.image) {
257+
this.formData.avatar = this.image;
258+
}
259+
if (this.image === false) {
260+
this.formData.avatar = false;
261+
}
262+
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
263+
.then((response) => {
264+
ProcessMaker.alert(this.$t('Your profile was saved.'), 'success')
265+
window.ProcessMaker.events.$emit('update-profile-avatar');
266+
this.originalEmail = this.formData.email;
267+
this.emailHasChanged = false;
268+
this.formData.valpassword = "";
269+
})
270+
.catch(error => {
271+
this.errors = error.response.data.errors;
272+
});
273+
274+
this.closeModal();
275+
},
276+
checkEmailChange() {
277+
this.emailHasChanged = this.formData.email !== this.originalEmail;
278+
},
244279
},
245280
computed: {
246281
state2FA() {
@@ -378,8 +413,8 @@
378413
379414
//TODO: HANDLE CONNECTION UPDATE
380415
this.onCloseModal;
381-
}
416+
},
382417
}
383418
});
384419
</script>
385-
@endsection
420+
@endsection

0 commit comments

Comments
 (0)