* @property string $external_auth_id
* @property string $system_name
* @property Collection $roles
+ * @property Collection $mfaValues
*/
class User extends Model implements AuthenticatableContract, CanResetPasswordContract, Loggable, Sluggable
{
{
$this->checkPermissionOrCurrentUser('users-manage', $id);
- $user = $this->user->newQuery()->with(['apiTokens'])->findOrFail($id);
+ /** @var User $user */
+ $user = $this->user->newQuery()->with(['apiTokens', 'mfaValues'])->findOrFail($id);
$authMethod = ($user->system_name) ? 'system' : config('auth.method');
$activeSocialDrivers = $socialAuthService->getActiveDrivers();
- $mfaMethods = user()->mfaValues()->get(['id', 'method'])->groupBy('method');
+ $mfaMethods = $user->mfaValues->groupBy('method');
$this->setPageTitle(trans('settings.user_profile'));
$roles = $this->userRepo->getAllRoles();
<td class="text-center" style="line-height: 0;"><img class="avatar med" src="{{ $user->getAvatar(40)}}" alt="{{ $user->name }}"></td>
<td>
<a href="{{ url("/settings/users/{$user->id}") }}">
- {{ $user->name }} <br> <span class="text-muted">{{ $user->email }}</span>
+ {{ $user->name }}
+ <br>
+ <span class="text-muted">{{ $user->email }}</span>
+ @if($user->mfa_values_count > 0)
+ <span title="MFA Configured" class="text-pos">@icon('lock')</span>
+ @endif
</a>
</td>
<td>
namespace Tests\Auth;
use BookStack\Auth\Access\Mfa\MfaValue;
+use BookStack\Auth\User;
use PragmaRX\Google2FA\Google2FA;
use Tests\TestCase;
public function test_mfa_method_count_is_visible_on_user_edit_page()
{
- $admin = $this->getAdmin();
- $resp = $this->actingAs($admin)->get($admin->getEditUrl());
+ $user = $this->getEditor();
+ $resp = $this->actingAs($this->getAdmin())->get($user->getEditUrl());
$resp->assertSee('0 methods configured');
- MfaValue::upsertWithValue($admin, MfaValue::METHOD_TOTP, 'test');
- $resp = $this->actingAs($admin)->get($admin->getEditUrl());
+ MfaValue::upsertWithValue($user, MfaValue::METHOD_TOTP, 'test');
+ $resp = $this->get($user->getEditUrl());
$resp->assertSee('1 method configured');
- MfaValue::upsertWithValue($admin, MfaValue::METHOD_BACKUP_CODES, 'test');
- $resp = $this->actingAs($admin)->get($admin->getEditUrl());
+ MfaValue::upsertWithValue($user, MfaValue::METHOD_BACKUP_CODES, 'test');
+ $resp = $this->get($user->getEditUrl());
$resp->assertSee('2 methods configured');
}
$resp->assertElementNotExists('a[href$="/mfa/setup"]');
}
+ public function test_mfa_indicator_shows_in_user_list()
+ {
+ $admin = $this->getAdmin();
+ User::query()->where('id', '!=', $admin->id)->delete();
+
+ $resp = $this->actingAs($admin)->get('/settings/users');
+ $resp->assertElementNotExists('[title="MFA Configured"] svg');
+
+ MfaValue::upsertWithValue($admin, MfaValue::METHOD_TOTP, 'test');
+ $resp = $this->actingAs($admin)->get('/settings/users');
+ $resp->assertElementExists('[title="MFA Configured"] svg');
+ }
+
}
\ No newline at end of file