Users - the agents who sign in to ITFlow. Each row is who * they are, their role, whether they can sign in and how (MFA, browsers that * skip the code), the clients they can see and when they last signed in. The * pills split them: everyone, admins, no MFA, disabled - and the archived. * * The admin's own row is shown but not changed here: that is their Account * pages, so nobody locks themselves out by mistake. */ // Default Column Sortby Filter $sort = "user_name"; $order = "ASC"; require_once "includes/inc_all_admin.php"; // filter_header.php fills in canned_date=custom when no range was asked for - not a filter here, so not carried into links if (($_GET['canned_date'] ?? '') === 'custom' && empty($_GET['dtf'])) { unset($_GET['canned_date']); } $roles = userRoles(); $role_filter = isset($roles[intval($_GET['role'] ?? 0)]) ? intval($_GET['role']) : 0; $filters = "user_type = 1 AND (user_name LIKE '%$q%' OR user_email LIKE '%$q%' OR role_name LIKE '%$q%')" . ($role_filter ? " AND user_role_id = $role_filter" : ''); $joins = "LEFT JOIN user_roles ON user_role_id = role_id LEFT JOIN user_settings ON user_settings.user_id = users.user_id"; // The views $shows = [ '' => ['label' => 'Users', 'icon' => 'fa-users', 'where' => 'user_archived_at IS NULL', 'title' => 'Everyone not archived'], 'admins' => ['label' => 'Admins', 'icon' => 'fa-user-shield', 'where' => 'user_archived_at IS NULL AND role_is_admin = 1', 'title' => 'Every client and every setting'], 'nomfa' => ['label' => 'No MFA', 'icon' => 'fa-unlock', 'where' => "user_archived_at IS NULL AND user_status = 1 AND (user_token IS NULL OR user_token = '')", 'title' => 'Active, and signing in with a password alone'], 'disabled' => ['label' => 'Disabled', 'icon' => 'fa-ban', 'where' => 'user_archived_at IS NULL AND user_status <> 1', 'title' => 'Cannot sign in'], 'archived' => ['label' => 'Archived', 'icon' => 'fa-archive', 'where' => 'user_archived_at IS NOT NULL', 'title' => 'Gone - restore one with a new password'], ]; $show = isset($shows[$_GET['show'] ?? '']) ? ($_GET['show'] ?? '') : ''; // Only these sort - an unknown column would take the page down $last_login_sql = "(SELECT MAX(log_id) FROM logs WHERE log_user_id = users.user_id AND log_type = 'Login' AND log_action = 'Success')"; $sortable_columns = [ 'user_name' => "user_name $order", 'user_email' => "user_email $order", 'role_name' => "role_is_admin DESC, role_name $order, user_name ASC", 'user_status' => "user_status $order, user_name ASC", 'last_login' => "$last_login_sql IS NULL, $last_login_sql $order, user_name ASC", 'user_created_at' => "user_created_at $order, user_name ASC", ]; if (!isset($sortable_columns[$sort])) { $sort = 'user_name'; } $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS users.user_id, user_name, user_email, user_status, user_token, user_avatar, user_created_at, user_archived_at, user_role_id, role_name, role_is_admin, user_config_force_mfa FROM users $joins WHERE $filters AND {$shows[$show]['where']} ORDER BY {$sortable_columns[$sort]}, users.user_id ASC LIMIT $record_from, $record_to"); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); $users = []; while ($row = mysqli_fetch_assoc($sql)) { $users[intval($row['user_id'])] = $row; } $logins = userLastLogins(array_keys($users)); $access = userClientAccess(array_keys($users)); $remembered = userRememberCounts(array_keys($users)); // How many in each view, over what the search and role leave $view_counts = []; $row = mysqli_fetch_row(mysqli_query($mysqli, "SELECT " . implode(', ', array_map(function ($s) { return "COALESCE(SUM({$s['where']}), 0)"; }, $shows)) . " FROM users $joins WHERE $filters")); foreach (array_keys($shows) as $i => $key) { $view_counts[$key] = intval($row[$i]); } // Agent user limit (set in config.php, 0 / unset = unlimited) $agent_user_limit = getAgentUserLimit(); $agent_user_count = getActiveAgentUserCount(); $agent_user_limit_reached = $agent_user_limit > 0 && $agent_user_count >= $agent_user_limit; $filter_url = function ($changes) { $params = array_merge($_GET, $changes); unset($params['page']); return '?' . http_build_query(array_filter($params, function ($v) { return $v !== '' && $v !== null; })); }; $sort_link = function ($column, $label) use ($url_query_strings_sort, $sort, $disp, $order_icon) { return '' . $label . ($sort === $column ? " $order_icon" : '') . ''; }; $csrf = $_SESSION['csrf_token']; ?>

Users 0) { ?> of seats

text-nowrap table-light"> $row) { $is_self = $user_id === intval($session_user_id); $is_archived = !empty($row['user_archived_at']); $is_active = intval($row['user_status']) === 1 && !$is_archived; $is_admin = intval($row['role_is_admin']) === 1; $has_mfa = trim((string) $row['user_token']) !== ''; $display_name = $is_archived ? trim(str_replace(' (archived)', '', $row['user_name'])) : $row['user_name']; $name = escapeHtml($display_name); $quick_url = "modals/user/user.php?id=$user_id"; $user_access = $access[$user_id]; $access_title = $is_admin ? 'Admins see every client' : trim( ($user_access['allow'] ? 'Only: ' . implode(', ', $user_access['allow']) . '. ' : '') . ($user_access['deny'] ? 'Kept out of: ' . implode(', ', $user_access['deny']) . '.' : '') ); $remember_count = $remembered[$user_id] ?? 0; ?>
Clients
You
No role
remembered browser
No users match. Everyone active signs in with MFA. No archived users. Nobody is disabled. No users here.