Skip to content

Revert "observation/FOUR-16703 Insecure email change mechanism" #7456

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions ProcessMaker/Http/Controllers/Admin/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use ProcessMaker\Models\JsonData;
use ProcessMaker\Models\Permission;
use ProcessMaker\Models\User;
use ProcessMaker\Package\Auth\Models\SsoUser;
use ProcessMaker\Traits\HasControllerAddons;

class UserController extends Controller
Expand Down Expand Up @@ -77,10 +76,6 @@ function ($result, $item) {
return $result;
}
);
$ssoUser = false;
if (class_exists(SsoUser::class)) {
$ssoUser = SsoUser::where('user_id', $user->id)->exists();
}

// Get global and valid 2FA preferences for the user
$enabled2FA = config('password-policies.2fa_enabled', false);
Expand Down Expand Up @@ -108,7 +103,6 @@ function ($result, $item) {
'is2FAEnabledForGroup',
'addons',
'addonsSettings',
'ssoUser',
));
}

Expand Down
47 changes: 0 additions & 47 deletions ProcessMaker/Http/Controllers/Api/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -329,27 +329,6 @@ public function update(User $user, Request $request)
return $response;
}
}
if ($fields['email'] !== $original['email']) {
if (!isset($fields['valpassword'])) {
return response([
'message' => __(
'A valid authentication is required for for update the email.'
),
'errors' => [
'email' => [
__(
'The password is required.'
),
],
],
], 422);
} else {
$response = $this->validateBeforeChange($user, $fields['valpassword']);
if ($response) {
return $response;
}
}
}
if (Auth::user()->is_administrator && $request->has('is_administrator')) {
// user must be an admin to make another user an admin
$user->is_administrator = $request->get('is_administrator');
Expand Down Expand Up @@ -402,32 +381,6 @@ private function validateCellPhoneNumber(User $user, $number)
return false;
}

/**
* Validate the phone number for SMS two-factor authentication.
*
* @param User $user User to validate
* @param mixed $password String to validate
*/
private function validateBeforeChange(User $user, $password)
{
if (!Hash::check($password, $user->password)) {
return response([
'message' => __(
'A valid authentication is required for for update the email.'
),
'errors' => [
'email' => [
__(
'The authentication is incorrect.'
),
],
],
], 422);
}

return false;
}

/**
* Update a user's pinned BPMN elements on Modeler
*
Expand Down
8 changes: 1 addition & 7 deletions ProcessMaker/Http/Controllers/ProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use ProcessMaker\i18nHelper;
use ProcessMaker\Models\JsonData;
use ProcessMaker\Models\User;
use ProcessMaker\Package\Auth\Models\SsoUser;
use ProcessMaker\Traits\HasControllerAddons;

class ProfileController extends Controller
Expand Down Expand Up @@ -51,11 +50,6 @@ function ($result, $item) {
}
);

$ssoUser = false;
if (class_exists(SsoUser::class)) {
$ssoUser = SsoUser::where('user_id', $currentUser->id)->exists();
}

// Get global and valid 2FA preferences for the user
$enabled2FA = config('password-policies.2fa_enabled', false);
$global2FAEnabled = config('password-policies.2fa_method', []);
Expand All @@ -66,7 +60,7 @@ function ($result, $item) {

return view('profile.edit',
compact('currentUser', 'states', 'timezones', 'countries', 'datetimeFormats', 'availableLangs',
'status', 'enabled2FA', 'global2FAEnabled', 'is2FAEnabledForGroup', 'addons', 'ssoUser'));
'status', 'enabled2FA', 'global2FAEnabled', 'is2FAEnabledForGroup', 'addons'));
}

/**
Expand Down
70 changes: 22 additions & 48 deletions resources/views/admin/users/edit.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@
image: '',
status: @json($status),
global2FAEnabled: @json($global2FAEnabled),
ssoUser:@json($ssoUser),
errors: {
username: null,
firstname: null,
Expand All @@ -283,8 +282,6 @@
groups: [],
userGroupsFilter: '',
focusErrors: 'errors',
originalEmail: '',
emailHasChanged: false,
}
},
created() {
Expand Down Expand Up @@ -345,7 +342,6 @@
if (created) {
ProcessMaker.alert(this.$t('The user was successfully created'), 'success');
}
this.originalEmail = this.formData.email;
},
watch: {
selectedPermissions: function () {
Expand Down Expand Up @@ -472,12 +468,28 @@
return true
},
profileUpdate($event) {
if(this.emailHasChanged && !this.ssoUser) {
$('#validateModal').modal('show');
} else {
this.saveProfileChanges();
this.resetErrors();
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
// User has not enabled two-factor authentication correctly
ProcessMaker.alert(
this.$t('The Two Step Authentication Method has not been set. Please contact your administrator.'),
'warning'
);
return false;
}

if (!this.validatePassword()) return false;
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1) return false;
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
.then(response => {
ProcessMaker.alert(this.$t('User Updated Successfully '), 'success');
if (this.formData.id == window.ProcessMaker.user.id) {
window.ProcessMaker.events.$emit('update-profile-avatar');
}
})
.catch(error => {
this.errors = error.response.data.errors;
});
},
permissionUpdate() {
ProcessMaker.apiClient.put("/permissions", {
Expand Down Expand Up @@ -552,44 +564,7 @@
.then(response => {
this.groups = response.data.data
});
},
showModal() {
$('#validateModal').modal('show');
},
closeModal() {
$('#validateModal').modal('hide');
},
saveProfileChanges() {
this.resetErrors();
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
// User has not enabled two-factor authentication correctly
ProcessMaker.alert(
this.$t('The Two Step Authentication Method has not been set. Please contact your administrator.'),
'warning'
);
return false;
}
if (!this.validatePassword()) return false;
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1) return false;
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
.then(response => {
ProcessMaker.alert(this.$t('User Updated Successfully '), 'success');
if (this.formData.id == window.ProcessMaker.user.id) {
window.ProcessMaker.events.$emit('update-profile-avatar');
this.originalEmail = this.formData.email;
this.formData.valpassword = "";
}
})
.catch(error => {
this.errors = error.response.data.errors;
});

this.closeModal();
},
checkEmailChange() {
this.emailHasChanged = this.formData.email !== this.originalEmail;
},
}
}
});
</script>
Expand Down Expand Up @@ -652,4 +627,3 @@
}
</style>
@endsection

80 changes: 27 additions & 53 deletions resources/views/profile/edit.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@
states: @json($states),
status: @json($status),
global2FAEnabled: @json($global2FAEnabled),
ssoUser:@json($ssoUser),
errors: {
username: null,
firstname: null,
Expand All @@ -147,8 +146,6 @@
},
confPassword: '',
image: '',
originalEmail: '',
emailHasChanged: false,
options: [
{
src: @json($currentUser['avatar']),
Expand All @@ -172,19 +169,37 @@
});
}
},
mounted() {
this.originalEmail = this.formData.email;
},
methods: {
openAvatarModal() {
modalVueInstance.$refs.updateAvatarModal.show();
},
profileUpdate() {
if(this.emailHasChanged && !this.ssoUser) {
$('#validateModal').modal('show');
} else {
this.saveProfileChanges();
}
this.resetErrors();
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
let message = 'The Two Step Authentication Method has not been set. ' +
'Please contact your administrator.';
// User has not enabled two-factor authentication correctly
ProcessMaker.alert(this.$t($message), 'warning');
return false;
}
if (!this.validatePassword()) return false;
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1)
return false;
if (this.image) {
this.formData.avatar = this.image;
}
if (this.image === false) {
this.formData.avatar = false;
}
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
.then((response) => {
ProcessMaker.alert(this.$t('Your profile was saved.'), 'success')
window.ProcessMaker.events.$emit('update-profile-avatar');
})
.catch(error => {
this.errors = error.response.data.errors;
});
},
deleteAvatar() {
let optionValues = formVueInstance.$data.options[0];
Expand Down Expand Up @@ -227,47 +242,6 @@
onClose() {
window.location.href = '/admin/users';
},
showModal() {
$('#validateModal').modal('show');
},
closeModal() {
$('#validateModal').modal('hide');
},
saveProfileChanges() {
this.resetErrors();
if (@json($enabled2FA) && this.global2FAEnabled.length === 0) {
let message = 'The Two Step Authentication Method has not been set. ' +
'Please contact your administrator.';
// User has not enabled two-factor authentication correctly
ProcessMaker.alert(this.$t($message), 'warning');
return false;
}
if (!this.validatePassword()) return false;
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1)
return false;
if (this.image) {
this.formData.avatar = this.image;
}
if (this.image === false) {
this.formData.avatar = false;
}
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
.then((response) => {
ProcessMaker.alert(this.$t('Your profile was saved.'), 'success')
window.ProcessMaker.events.$emit('update-profile-avatar');
this.originalEmail = this.formData.email;
this.formData.valpassword = "";
})
.catch(error => {
this.errors = error.response.data.errors;
});

this.closeModal();
},
checkEmailChange() {
this.emailHasChanged = this.formData.email !== this.originalEmail;
},
},
computed: {
state2FA() {
Expand Down Expand Up @@ -405,7 +379,7 @@

//TODO: HANDLE CONNECTION UPDATE
this.onCloseModal;
},
}
}
});
</script>
Expand Down
28 changes: 1 addition & 27 deletions resources/views/shared/users/profile.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ class="mb-2"
{!! Form::email('email', null, ['id' => 'email', 'rows' => 4, 'class'=>
'form-control', 'v-model'
=> 'formData.email', 'v-bind:class' => '{\'form-control\':true,
\'is-invalid\':errors.email}', 'required', 'aria-required' => 'true',
'@input' => 'checkEmailChange']) !!}
\'is-invalid\':errors.email}', 'required', 'aria-required' => 'true']) !!}
<div class="invalid-feedback" role="alert" v-if="errors.email">@{{errors.email[0]}}
</div>
</div>
Expand Down Expand Up @@ -160,28 +159,3 @@ class="mb-2"
@endforeach
@endif
</div>

<div class="modal fade" id="validateModal" tabindex="-1" role="dialog" aria-labelledby="modalValidate" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalLabel">Confirm Identity</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="form-group col">
{!! Form::label('valpassword', __('Password')) !!}
{!! Form::password('valpassword', ['id' => 'valpassword', 'rows' => 4, 'class'=> 'form-control', 'v-model'
=> 'formData.valpassword']) !!}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @click="closeModal">Cancel</button>
<button type="button" class="btn btn-primary" @click="saveProfileChanges">Save</button>
</div>
</div>
</div>
</div>

Loading
Loading