Skip to content

Commit 602625e

Browse files
Added an authentication when the user wants to change the email
1 parent e4fd303 commit 602625e

6 files changed

Lines changed: 186 additions & 51 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
@@ -76,6 +77,10 @@ function ($result, $item) {
7677
return $result;
7778
}
7879
);
80+
$ssoUser = false;
81+
if (!class_exists(SsoUser::class)) {
82+
$ssoUser = SsoUser::where('user_id', $user->id)->exists();
83+
}
7984

8085
// Get global and valid 2FA preferences for the user
8186
$enabled2FA = config('password-policies.2fa_enabled', false);
@@ -103,6 +108,7 @@ function ($result, $item) {
103108
'is2FAEnabledForGroup',
104109
'addons',
105110
'addonsSettings',
111+
'ssoUser',
106112
));
107113
}
108114

‎ProcessMaker/Http/Controllers/Api/UserController.php‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,27 @@ public function update(User $user, Request $request)
329329
return $response;
330330
}
331331
}
332+
if ($fields['email'] !== $original['email']) {
333+
if (!isset($fields['valpassword'])) {
334+
return response([
335+
'message' => __(
336+
'A valid authentication is required for for update the email.'
337+
),
338+
'errors' => [
339+
'email' => [
340+
__(
341+
'The password is required.'
342+
),
343+
],
344+
],
345+
], 422);
346+
} else {
347+
$response = $this->validateBeforeChange($user, $fields['valpassword']);
348+
if ($response) {
349+
return $response;
350+
}
351+
}
352+
}
332353
if (Auth::user()->is_administrator && $request->has('is_administrator')) {
333354
// user must be an admin to make another user an admin
334355
$user->is_administrator = $request->get('is_administrator');
@@ -381,6 +402,32 @@ private function validateCellPhoneNumber(User $user, $number)
381402
return false;
382403
}
383404

405+
/**
406+
* Validate the phone number for SMS two-factor authentication.
407+
*
408+
* @param User $user User to validate
409+
* @param mixed $password String to validate
410+
*/
411+
private function validateBeforeChange(User $user, $password)
412+
{
413+
if (!Hash::check($password, $user->password)) {
414+
return response([
415+
'message' => __(
416+
'A valid authentication is required for for update the email.'
417+
),
418+
'errors' => [
419+
'email' => [
420+
__(
421+
'The authentication is incorrect.'
422+
),
423+
],
424+
],
425+
], 422);
426+
}
427+
428+
return false;
429+
}
430+
384431
/**
385432
* Update a user's pinned BPMN elements on Modeler
386433
*

‎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
@@ -50,6 +51,11 @@ function ($result, $item) {
5051
}
5152
);
5253

54+
$ssoUser = false;
55+
if (!class_exists(SsoUser::class)) {
56+
$ssoUser = SsoUser::where('user_id', $user->id)->exists();
57+
}
58+
5359
// Get global and valid 2FA preferences for the user
5460
$enabled2FA = config('password-policies.2fa_enabled', false);
5561
$global2FAEnabled = config('password-policies.2fa_method', []);
@@ -60,7 +66,7 @@ function ($result, $item) {
6066

6167
return view('profile.edit',
6268
compact('currentUser', 'states', 'timezones', 'countries', 'datetimeFormats', 'availableLangs',
63-
'status', 'enabled2FA', 'global2FAEnabled', 'is2FAEnabledForGroup', 'addons'));
69+
'status', 'enabled2FA', 'global2FAEnabled', 'is2FAEnabledForGroup', 'addons', 'ssoUser'));
6470
}
6571

6672
/**

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

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@
257257
image: '',
258258
status: @json($status),
259259
global2FAEnabled: @json($global2FAEnabled),
260+
ssoUser:@json($ssoUser),
260261
errors: {
261262
username: null,
262263
firstname: null,
@@ -282,6 +283,8 @@
282283
groups: [],
283284
userGroupsFilter: '',
284285
focusErrors: 'errors',
286+
originalEmail: '',
287+
emailHasChanged: false,
285288
}
286289
},
287290
created() {
@@ -342,6 +345,7 @@
342345
if (created) {
343346
ProcessMaker.alert(this.$t('The user was successfully created'), 'success');
344347
}
348+
this.originalEmail = this.formData.email;
345349
},
346350
watch: {
347351
selectedPermissions: function () {
@@ -468,28 +472,12 @@
468472
return true
469473
},
470474
profileUpdate($event) {
471-
this.resetErrors();
472-
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
473-
// User has not enabled two-factor authentication correctly
474-
ProcessMaker.alert(
475-
this.$t('The Two Step Authentication Method has not been set. Please contact your administrator.'),
476-
'warning'
477-
);
478-
return false;
475+
if(this.emailHasChanged && !this.ssoUser) {
476+
$('#validateModal').modal('show');
477+
} else {
478+
this.saveProfileChanges();
479479
}
480-
if (!this.validatePassword()) return false;
481-
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
482-
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1) return false;
483-
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
484-
.then(response => {
485-
ProcessMaker.alert(this.$t('User Updated Successfully '), 'success');
486-
if (this.formData.id == window.ProcessMaker.user.id) {
487-
window.ProcessMaker.events.$emit('update-profile-avatar');
488-
}
489-
})
490-
.catch(error => {
491-
this.errors = error.response.data.errors;
492-
});
480+
493481
},
494482
permissionUpdate() {
495483
ProcessMaker.apiClient.put("/permissions", {
@@ -564,7 +552,43 @@
564552
.then(response => {
565553
this.groups = response.data.data
566554
});
567-
}
555+
},
556+
showModal() {
557+
$('#validateModal').modal('show');
558+
},
559+
closeModal() {
560+
$('#validateModal').modal('hide');
561+
},
562+
saveProfileChanges() {
563+
this.resetErrors();
564+
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
565+
// User has not enabled two-factor authentication correctly
566+
ProcessMaker.alert(
567+
this.$t('The Two Step Authentication Method has not been set. Please contact your administrator.'),
568+
'warning'
569+
);
570+
return false;
571+
}
572+
if (!this.validatePassword()) return false;
573+
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
574+
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1) return false;
575+
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
576+
.then(response => {
577+
ProcessMaker.alert(this.$t('User Updated Successfully '), 'success');
578+
if (this.formData.id == window.ProcessMaker.user.id) {
579+
window.ProcessMaker.events.$emit('update-profile-avatar');
580+
this.originalEmail = this.formData.email;
581+
}
582+
})
583+
.catch(error => {
584+
this.errors = error.response.data.errors;
585+
});
586+
587+
this.closeModal();
588+
},
589+
checkEmailChange() {
590+
this.emailHasChanged = this.formData.email !== this.originalEmail;
591+
},
568592
}
569593
});
570594
</script>
@@ -627,3 +651,4 @@
627651
}
628652
</style>
629653
@endsection
654+

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

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
states: @json($states),
137137
status: @json($status),
138138
global2FAEnabled: @json($global2FAEnabled),
139+
ssoUser:@json($ssoUser),
139140
errors: {
140141
username: null,
141142
firstname: null,
@@ -146,6 +147,8 @@
146147
},
147148
confPassword: '',
148149
image: '',
150+
originalEmail: '',
151+
emailHasChanged: false,
149152
options: [
150153
{
151154
src: @json($currentUser['avatar']),
@@ -169,37 +172,19 @@
169172
});
170173
}
171174
},
175+
mounted() {
176+
this.originalEmail = this.formData.email;
177+
},
172178
methods: {
173179
openAvatarModal() {
174180
modalVueInstance.$refs.updateAvatarModal.show();
175181
},
176182
profileUpdate() {
177-
this.resetErrors();
178-
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
179-
let message = 'The Two Step Authentication Method has not been set. ' +
180-
'Please contact your administrator.';
181-
// User has not enabled two-factor authentication correctly
182-
ProcessMaker.alert(this.$t($message), 'warning');
183-
return false;
184-
}
185-
if (!this.validatePassword()) return false;
186-
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
187-
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1)
188-
return false;
189-
if (this.image) {
190-
this.formData.avatar = this.image;
191-
}
192-
if (this.image === false) {
193-
this.formData.avatar = false;
194-
}
195-
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
196-
.then((response) => {
197-
ProcessMaker.alert(this.$t('Your profile was saved.'), 'success')
198-
window.ProcessMaker.events.$emit('update-profile-avatar');
199-
})
200-
.catch(error => {
201-
this.errors = error.response.data.errors;
202-
});
183+
if(this.emailHasChanged && !this.ssoUser) {
184+
$('#validateModal').modal('show');
185+
} else {
186+
this.saveProfileChanges();
187+
}
203188
},
204189
deleteAvatar() {
205190
let optionValues = formVueInstance.$data.options[0];
@@ -242,6 +227,46 @@
242227
onClose() {
243228
window.location.href = '/admin/users';
244229
},
230+
showModal() {
231+
$('#validateModal').modal('show');
232+
},
233+
closeModal() {
234+
$('#validateModal').modal('hide');
235+
},
236+
saveProfileChanges() {
237+
this.resetErrors();
238+
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
239+
let message = 'The Two Step Authentication Method has not been set. ' +
240+
'Please contact your administrator.';
241+
// User has not enabled two-factor authentication correctly
242+
ProcessMaker.alert(this.$t($message), 'warning');
243+
return false;
244+
}
245+
if (!this.validatePassword()) return false;
246+
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
247+
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1)
248+
return false;
249+
if (this.image) {
250+
this.formData.avatar = this.image;
251+
}
252+
if (this.image === false) {
253+
this.formData.avatar = false;
254+
}
255+
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
256+
.then((response) => {
257+
ProcessMaker.alert(this.$t('Your profile was saved.'), 'success')
258+
window.ProcessMaker.events.$emit('update-profile-avatar');
259+
this.originalEmail = this.formData.email;
260+
})
261+
.catch(error => {
262+
this.errors = error.response.data.errors;
263+
});
264+
265+
this.closeModal();
266+
},
267+
checkEmailChange() {
268+
this.emailHasChanged = this.formData.email !== this.originalEmail;
269+
},
245270
},
246271
computed: {
247272
state2FA() {
@@ -379,7 +404,7 @@
379404
380405
//TODO: HANDLE CONNECTION UPDATE
381406
this.onCloseModal;
382-
}
407+
},
383408
}
384409
});
385410
</script>

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class="mb-2"
4444
{!! Form::email('email', null, ['id' => 'email', 'rows' => 4, 'class'=>
4545
'form-control', 'v-model'
4646
=> 'formData.email', 'v-bind:class' => '{\'form-control\':true,
47-
\'is-invalid\':errors.email}', 'required', 'aria-required' => 'true']) !!}
47+
\'is-invalid\':errors.email}', 'required', 'aria-required' => 'true',
48+
'@input' => 'checkEmailChange']) !!}
4849
<div class="invalid-feedback" role="alert" v-if="errors.email">@{{errors.email[0]}}
4950
</div>
5051
</div>
@@ -159,3 +160,28 @@ class="mb-2"
159160
@endforeach
160161
@endif
161162
</div>
163+
164+
<div class="modal fade" id="validateModal" tabindex="-1" role="dialog" aria-labelledby="modalValidate" aria-hidden="true">
165+
<div class="modal-dialog" role="document">
166+
<div class="modal-content">
167+
<div class="modal-header">
168+
<h5 class="modal-title" id="modalLabel">Confirm Identity</h5>
169+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
170+
<span aria-hidden="true">&times;</span>
171+
</button>
172+
</div>
173+
<div class="modal-body">
174+
<div class="form-group col">
175+
{!! Form::label('valpassword', __('Password')) !!}
176+
{!! Form::password('valpassword', ['id' => 'valpassword', 'rows' => 4, 'class'=> 'form-control', 'v-model'
177+
=> 'formData.valpassword']) !!}
178+
</div>
179+
</div>
180+
<div class="modal-footer">
181+
<button type="button" class="btn btn-secondary" @click="closeModal">Cancel</button>
182+
<button type="button" class="btn btn-primary" @click="saveProfileChanges">Save</button>
183+
</div>
184+
</div>
185+
</div>
186+
</div>
187+

0 commit comments

Comments
 (0)