Skip to content

Commit a03440b

Browse files
authored
Merge pull request ProcessMaker#5980 from ProcessMaker/FOUR-13085
FOUR-13085 A user cannot configure in their profile how to receive their OTP
2 parents 2994353 + c5eb5f0 commit a03440b

9 files changed

Lines changed: 93 additions & 5 deletions

File tree

ProcessMaker/Http/Controllers/Admin/UserController.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ function ($result, $item) {
7777
}
7878
);
7979

80+
// Get global and valid 2FA preferences for the user
81+
$enabled2FA = config('password-policies.2fa_enabled', false);
82+
$global2FAEnabled = config('password-policies.2fa_method', []);
83+
$user->preferences_2fa = $user->getValid2FAPreferences();
84+
8085
$addons = $this->getPluginAddons('edit', compact(['user']));
8186
$addonsSettings = $this->getPluginAddons('edit.settings', compact(['user']));
8287

@@ -92,6 +97,8 @@ function ($result, $item) {
9297
'datetimeFormats',
9398
'availableLangs',
9499
'status',
100+
'enabled2FA',
101+
'global2FAEnabled',
95102
'addons',
96103
'addonsSettings',
97104
));

ProcessMaker/Http/Controllers/Auth/TwoFactorAuthController.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Illuminate\Support\Facades\Mail;
99
use ProcessMaker\Http\Controllers\Controller;
1010
use ProcessMaker\Mail\TestEmailServer;
11+
use ProcessMaker\Models\User;
1112
use ProcessMaker\TwoFactorAuthentication;
1213
use Twilio\Rest\Client;
1314

@@ -46,7 +47,7 @@ public function displayTwoFactorAuthForm(Request $request)
4647
}
4748

4849
// Set informative message
49-
$methodsNames = $this->friendlyMethodsNames();
50+
$methodsNames = $this->friendlyMethodsNames($user);
5051
$message = __('Enter the security code from :methods. If incorrect, please retry with the latest code provided.',
5152
['methods' => $methodsNames]);
5253
session()->put(self::TFA_MESSAGE, $message);
@@ -208,7 +209,7 @@ private function testSmsServer()
208209
return true;
209210
}
210211

211-
private function friendlyMethodsNames()
212+
private function friendlyMethodsNames(User $user)
212213
{
213214
// Define the friendly names for each method
214215
$friendlyNames = [
@@ -218,7 +219,7 @@ private function friendlyMethodsNames()
218219
];
219220

220221
// Get enabled methods to send the code
221-
$enabledMethods = config('password-policies.2fa_method', []);
222+
$enabledMethods = $user->getValid2FAPreferences();
222223

223224
// Return the friendly names for enabled methods
224225
$methods = array_map(function($method) use ($friendlyNames) {

ProcessMaker/Http/Controllers/ProfileController.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,16 @@ function ($result, $item) {
5050
}
5151
);
5252

53+
// Get global and valid 2FA preferences for the user
54+
$enabled2FA = config('password-policies.2fa_enabled', false);
55+
$global2FAEnabled = config('password-policies.2fa_method', []);
56+
$currentUser->preferences_2fa = $currentUser->getValid2FAPreferences();
57+
5358
$addons = $this->getPluginAddons('edit', []);
5459

5560
return view('profile.edit',
5661
compact('currentUser', 'states', 'timezones', 'countries', 'datetimeFormats', 'availableLangs',
57-
'status', 'addons'));
62+
'status', 'enabled2FA', 'global2FAEnabled', 'addons'));
5863
}
5964

6065
/**

ProcessMaker/Models/User.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class User extends Authenticatable implements HasMedia
125125
'force_change_password',
126126
'password_changed_at',
127127
'connected_accounts',
128+
'preferences_2fa',
128129
];
129130

130131
protected $appends = [
@@ -136,6 +137,7 @@ class User extends Authenticatable implements HasMedia
136137
'meta' => 'object',
137138
'active_at' => 'datetime',
138139
'schedule' => 'array',
140+
'preferences_2fa' => 'array',
139141
];
140142

141143
/**
@@ -519,4 +521,16 @@ public function sessions(): HasMany
519521
{
520522
return $this->hasMany(UserSession::class);
521523
}
524+
525+
public function getValid2FAPreferences(): array
526+
{
527+
// Get global and user values
528+
$global2FAEnabled = config('password-policies.2fa_method', []);
529+
$user2FAEnabled = !is_null($this->preferences_2fa) ? $this->preferences_2fa : [];
530+
531+
// Get valid values
532+
$aux = array_intersect($global2FAEnabled, $user2FAEnabled);
533+
534+
return !empty($aux) ? array_values($aux) : $global2FAEnabled;
535+
}
522536
}

ProcessMaker/TwoFactorAuthentication.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class TwoFactorAuthentication
2424
public function sendCode(User $user): void
2525
{
2626
// Get methods to send the code
27-
$methods = config('password-policies.2fa_method', []);
27+
$methods = $user->getValid2FAPreferences();
2828

2929
if (in_array(self::EMAIL, $methods) || in_array(self::SMS, $methods)) {
3030
// Get code
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::table('users', function (Blueprint $table) {
15+
$table->json('preferences_2fa')->nullable();
16+
});
17+
}
18+
19+
/**
20+
* Reverse the migrations.
21+
*/
22+
public function down(): void
23+
{
24+
Schema::table('users', function (Blueprint $table) {
25+
$table->dropColumn('preferences_2fa');
26+
});
27+
}
28+
};

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@
256256
userId: @json($user->id),
257257
image: '',
258258
status: @json($status),
259+
global2FAEnabled: @json($global2FAEnabled),
259260
errors: {
260261
username: null,
261262
firstname: null,
@@ -316,6 +317,10 @@
316317
states() {
317318
return this.formatDataSelect(this.statesValues);
318319
},
320+
state2FA() {
321+
return typeof this.formData.preferences_2fa != "undefined" && this.formData.preferences_2fa != null
322+
&& this.formData.preferences_2fa.length > 0;
323+
}
319324
},
320325
mounted() {
321326
let created = (new URLSearchParams(window.location.search)).get('created');
@@ -407,6 +412,8 @@
407412
profileUpdate($event) {
408413
this.resetErrors();
409414
if (!this.validatePassword()) return false;
415+
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
416+
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1) return false;
410417
ProcessMaker.apiClient.put('users/' + this.formData.id, this.formData)
411418
.then(response => {
412419
ProcessMaker.alert(this.$t('User Updated Successfully '), 'success');

resources/views/profile/edit.blade.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
countries: @json($countries),
136136
states: @json($states),
137137
status: @json($status),
138+
global2FAEnabled: @json($global2FAEnabled),
138139
errors: {
139140
username: null,
140141
firstname: null,
@@ -175,6 +176,9 @@
175176
profileUpdate() {
176177
this.resetErrors();
177178
if (!this.validatePassword()) return false;
179+
if (@json($enabled2FA) && typeof this.formData.preferences_2fa != "undefined" &&
180+
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length < 1)
181+
return false;
178182
if (this.image) {
179183
this.formData.avatar = this.image;
180184
}
@@ -231,6 +235,12 @@
231235
onClose() {
232236
window.location.href = '/admin/users';
233237
},
238+
},
239+
computed: {
240+
state2FA() {
241+
return typeof this.formData.preferences_2fa != "undefined" &&
242+
this.formData.preferences_2fa != null && this.formData.preferences_2fa.length > 0;
243+
}
234244
}
235245
});
236246
</script>

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@
6060
<div class="invalid-feedback" :style="{display: (errors.password) ? 'block' : 'none' }" role="alert"
6161
v-for="(error, index) in errors.password">@{{error}}</div>
6262
</div>
63+
64+
@if (config('password-policies.2fa_enabled', false) && count($global2FAEnabled) > 0)
65+
<div class="form-group">
66+
{!! Form::label('preferences_2fa', __('Two Factor Authentication')) !!}
67+
<b-form-checkbox-group
68+
id="preferences_2fa"
69+
v-model="formData.preferences_2fa"
70+
:options="global2FAEnabled"
71+
:state="state2FA"
72+
switches
73+
required
74+
>
75+
</b-form-checkbox-group>
76+
</div>
77+
@endif
78+
6379
@endif
6480
@cannot('edit-user-and-password')
6581
<div class="form-group">

0 commit comments

Comments
 (0)