Passed
Push — master ( b727b7...6bf24f )
by Nils
06:30
created

count_deleted_users()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Teampass - a collaborative passwords manager.
7
 * ---
8
 * This file is part of the TeamPass project.
9
 * 
10
 * TeamPass is free software: you can redistribute it and/or modify it
11
 * under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, version 3 of the License.
13
 * 
14
 * TeamPass is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU General Public License for more details.
18
 * 
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21
 * 
22
 * Certain components of this file may be under different licenses. For
23
 * details, see the `licenses` directory or individual file headers.
24
 * ---
25
 * @file      users.php
26
 * @author    Nils Laumaillé ([email protected])
27
 * @copyright 2009-2025 Teampass.net
28
 * @license   GPL-3.0
29
 * @see       https://www.teampass.net
30
 */
31
32
use TeampassClasses\SessionManager\SessionManager;
33
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
34
use TeampassClasses\Language\Language;
35
use TeampassClasses\NestedTree\NestedTree;
36
use TeampassClasses\PerformChecks\PerformChecks;
37
use TeampassClasses\ConfigManager\ConfigManager;
38
39
// Load functions
40
require_once __DIR__.'/../sources/main.functions.php';
41
42
// init
43
loadClasses('DB');
44
$session = SessionManager::getSession();
45
$request = SymfonyRequest::createFromGlobals();
46
$lang = new Language($session->get('user-language') ?? 'english');
47
48
// Load config
49
$configManager = new ConfigManager();
50
$SETTINGS = $configManager->getAllSettings();
51
52
// Do checks
53
$checkUserAccess = new PerformChecks(
54
    dataSanitizer(
55
        [
56
            'type' => htmlspecialchars($request->request->get('type', ''), ENT_QUOTES, 'UTF-8'),
57
        ],
58
        [
59
            'type' => 'trim|escape',
60
        ],
61
    ),
62
    [
63
        'user_id' => returnIfSet($session->get('user-id'), null),
64
        'user_key' => returnIfSet($session->get('key'), null),
65
    ]
66
);
67
// Handle the case
68
echo $checkUserAccess->caseHandler();
69
if ($checkUserAccess->checkSession() === false || $checkUserAccess->userAccessPage('users') === false) {
70
    // Not allowed page
71
    $session->set('system-error_code', ERR_NOT_ALLOWED);
72
    include $SETTINGS['cpassman_dir'] . '/error.php';
73
    exit;
74
}
75
76
// Define Timezone
77
date_default_timezone_set($SETTINGS['timezone'] ?? 'UTC');
78
79
// Set header properties
80
header('Content-type: text/html; charset=utf-8');
81
header('Cache-Control: no-cache, no-store, must-revalidate');
82
83
// --------------------------------- //
84
85
// Load tree
86
$tree = new NestedTree(prefixTable('nested_tree'), 'id', 'parent_id', 'title');
87
88
// PREPARE LIST OF OPTIONS
89
$optionsManagedBy = '';
90
$optionsRoles = '';
91
$userRoles = explode(';', $session->get('user-roles'));
92
// If administrator then all roles are shown
93
// else only the Roles the users is associated to.
94
if ((int) $session->get('user-admin') === 1) {
95
    $optionsManagedBy .= '<option value="0">' . $lang->get('administrators_only') . '</option>';
96
}
97
98
$rows = DB::query(
99
    'SELECT id, title, creator_id
100
    FROM ' . prefixTable('roles_title') . '
101
    ORDER BY title ASC'
102
);
103
foreach ($rows as $record) {
104
    if ((int) $session->get('user-admin') === 1 || in_array($record['id'], $session->get('user-roles_array')) === true) {
105
        $optionsManagedBy .= '<option value="' . $record['id'] . '">' . $lang->get('managers_of') . ' ' . addslashes($record['title']) . '</option>';
106
    }
107
    if (
108
        (int) $session->get('user-admin') === 1
109
        || (((int) $session->get('user-manager') === 1 || (int) $session->get('user-can_manage_all_users') === 1)
110
            && (in_array($record['id'], $userRoles) === true) || (int) $record['creator_id'] === (int) $session->get('user-id'))
111
    ) {
112
        $optionsRoles .= '<option value="' . $record['id'] . '">' . addslashes($record['title']) . '</option>';
113
    }
114
}
115
116
$treeDesc = $tree->getDescendants();
117
$foldersList = '';
118
foreach ($treeDesc as $t) {
119
    if (
120
        in_array($t->id, $session->get('user-accessible_folders')) === true
121
        && in_array($t->id, $session->get('user-personal_visible_folders')) === false
122
    ) {
123
        $ident = '';
124
        for ($y = 1; $y < $t->nlevel; ++$y) {
125
            $ident .= '&nbsp;&nbsp;';
126
        }
127
        $foldersList .= '<option value="' . $t->id . '">' . $ident . htmlspecialchars($t->title, ENT_COMPAT, 'UTF-8') . '</option>';
128
    }
129
}
130
131
// Should we show the new user form?
132
$showNewUser = $request->query->get('action') === 'new';
133
134
// Is there any deleted account?
135
/**
136
 * count_deleted_users
137
 *
138
 * Counts the number of users who are disabled (deleted) in the database.
139
 * Assumes the database connection is established and the table is {teampass_users}.
140
 *
141
 * @param void
142
 * @return int The count of disabled users.
143
 */
144
function count_deleted_users() : int
145
{
146
    // Table is teampass_users with the prefix {teampass_users} in MeekroDB context.
147
    // 'disabled = 1' indicates a deleted/disabled user account.
148
    return (int)DB::queryFirstField("SELECT COUNT(id) FROM " . prefixTable('users') . " WHERE deleted_at IS NOT NULL");
149
}
150
151
$deleted_users_count = count_deleted_users();
152
153
// Prepare the CSS class for blinking and the badge for the count.
154
$blink_class = '';
155
$count_badge_html = '';
156
157
if ($deleted_users_count > 0) {
158
    // Add the blinking class if there are deleted users
159
    $blink_class = 'blink_me';
160
161
    // Create the badge HTML with the count
162
    $count_badge_html = ' <span class="badge badge-danger ml-1">' . $deleted_users_count . '</span>';
163
}
164
?>
165
166
<!-- Content Header (Page header) -->
167
<div class="content-header">
168
    <div class="container-fluid">
169
        <div class="row mb-2">
170
            <div class="col-sm-6">
171
                <h1 class="m-0 text-dark">
172
                    <i class="fa-solid fa-users mr-2"></i><?php echo $lang->get('users'); ?>
173
                </h1>
174
            </div><!-- /.col -->
175
        </div><!-- /.row -->
176
    </div><!-- /.container-fluid -->
177
</div>
178
<!-- /.content-header -->
179
180
<section class="content">
181
    <div class="row" id="header-menu">
182
        <div class="col-12">
183
            <div class="card">
184
                <div class="card-header align-middle">
185
                    <h3 class="card-title">
186
                        <button type="button" class="btn btn-primary btn-sm tp-action mr-2" data-action="new">
187
                            <i class="fa-solid fa-plus mr-2"></i><?php echo $lang->get('new'); ?>
188
                        </button>
189
                        <button type="button" class="btn btn-primary btn-sm tp-action mr-2" data-action="propagate">
190
                            <i class="fa-solid fa-share-alt mr-2"></i><?php echo $lang->get('propagate'); ?>
191
                        </button>
192
                        <button type="button" class="btn btn-primary btn-sm tp-action mr-2" data-action="refresh">
193
                            <i class="fa-solid fa-sync-alt mr-2"></i><?php echo $lang->get('refresh'); ?>
194
                        </button><?php
195
                                    echo isset($SETTINGS['ldap_mode']) === true && (int) $SETTINGS['ldap_mode'] === 1 && (int) $session->get('user-admin') === 1 ?
196
                                        '<button type="button" class="btn btn-primary btn-sm tp-action mr-2" data-action="ldap-sync">
197
                            <i class="fa-solid fa-address-card mr-2"></i>' . $lang->get('ldap_synchronization') . '
198
                        </button>' : '';
199
                                    ?>
200
                        </button><?php
201
                                    echo isset($SETTINGS['oauth2_enabled']) === true && (int) $SETTINGS['oauth2_enabled'] === 1 && (int) $session->get('user-admin') === 1 ?
202
                                        '<button type="button" class="btn btn-primary btn-sm tp-action mr-2" data-action="oauth2-sync">
203
                            <i class="fa-solid fa-plug mr-2"></i>' . $lang->get('oauth2_synchronization') . '
204
                        </button>' : '';
205
                                    ?>
206
                        <button type="button" class="btn btn-primary btn-sm tp-action mr-2 <?php echo $blink_class; ?>" data-action="deleted-users">
207
                            <i class="fa-solid fa-user-xmark mr-2"></i><?php echo $lang->get('deleted_users'); ?><?php echo $count_badge_html; ?>
208
                        </button>
209
                    </h3>
210
                </div>
211
212
                <!-- /.card-header -->
213
                <div class="card-body form user-content with-header-menu <?php echo $showNewUser ? 'hidden' : '';?>" id="users-list" data-content="refresh">
214
                    <label><input type="checkbox" id="warnings_display" class="tp-action pointer" data-action="refresh"><span class="ml-2 pointer"><?php echo $lang->get('display_warning_icons');?></span></label>
215
                    <table id="table-users" class="table table-striped nowrap table-responsive-sm">
216
                        <thead>
217
                            <tr>
218
                                <th scope="col"></th>
219
                                <th scope="col"><?php echo $lang->get('user_login'); ?></th>
220
                                <th scope="col"><?php echo $lang->get('name'); ?></th>
221
                                <th scope="col"><?php echo $lang->get('lastname'); ?></th>
222
                                <th scope="col"><?php echo $lang->get('managed_by'); ?></th>
223
                                <th scope="col"><?php echo $lang->get('functions'); ?></th>
224
                                <th scope="col"><i class="fa-solid fa-theater-masks fa-lg fa-fw infotip" title="<?php echo $lang->get('privileges'); ?>"></i></th>
225
                                <th scope="col"><i class="fa-solid fa-code-branch fa-lg fa-fw infotip" title="<?php echo $lang->get('can_create_root_folder'); ?>"></i></th>
226
                                <th scope="col"><i class="fa-solid fa-hand-holding-heart fa-lg fa-fw infotip" title="<?php echo $lang->get('enable_personal_folder'); ?>"></i></th>
227
                            </tr>
228
                        </thead>
229
                        <tbody>
230
231
                        </tbody>
232
                    </table>
233
                </div>
234
            </div>
235
        </div>
236
    </div>
237
238
239
    <!-- USER LDAP SYNCHRONIZATION -->
240
    <div class="row hidden extra-form user-content with-header-menu" id="row-ldap" data-content="ldap-sync">
241
        <div class="col-12">
242
            <div class="card card-primary">
243
                <div class="card-header">
244
                    <h3 class="card-title"><?php echo $lang->get('ldap_synchronization'); ?> <span id="row-logs-title"></span></h3>
245
                </div>
246
247
                <!-- /.card-header -->
248
                <!-- table start -->
249
                <div class="card-body">
250
                    <div class="row col-12">
251
                        <button type="button" class="btn btn-secondary btn-sm tp-action mr-2" data-action="ldap-existing-users">
252
                            <i class="fa-solid fa-sync-alt mr-2"></i><?php echo $lang->get('list_users'); ?>
253
                        </button>
254
                        <button type="button" class="btn btn-secondary btn-sm tp-action mr-2" data-action="ldap-add-role">
255
                            <i class="fa-solid fa-graduation-cap mr-2"></i><?php echo $lang->get('add_role_tip'); ?>
256
                        </button>
257
                    </div>
258
                    <div class="row">
259
                        <div class="col-12">
260
                            <div class="card hidden mt-4 mb-5 card-info" id="ldap-new-role">
261
                                <div class="card-header">
262
                                    <i class="fa-solid fa-graduation-cap mr-2"></i><?php echo $lang->get('add_role_tip'); ?>
263
                                </div>
264
                                <div class="card-body">
265
                                    <div class="callout callout-info">
266
                                        <i class="fa-solid fa-info-circle text-info mr-2"></i><?php echo $lang->get('adding_ldap_role_to_teampass'); ?>
267
                                    </div>
268
                                    <div class="form-group row">
269
                                        <label for="ldap-new-role-selection"><?php echo $lang->get('select_role_to_create'); ?></label>
270
                                        <select class="form-control form-item-control" style="width:100%;" id="ldap-new-role-selection"></select>
271
                                    </div>
272
                                    <div class="form-group row">
273
                                        <label for="ldap-new-role-complexity"><?php echo $lang->get('complexity'); ?></label>
274
                                        <select id="ldap-new-role-complexity" class="form-control form-item-control" style="width:100%;">
275
                                            <?php
276
                                            foreach (TP_PW_COMPLEXITY as $entry) {
277
                                                echo '
278
                                            <option value="' . $entry[0] . '">' . addslashes($entry[1]) . '</option>';
279
                                            }
280
                                            ?>
281
                                        </select>
282
                                    </div>
283
                                </div>
284
                                <div class="card-footer">
285
                                    <button type="button" class="btn btn-default float-left tp-action btn-info" data-action="add-new-role"><?php echo $lang->get('submit'); ?></button>
286
                                    <button type="button" class="btn btn-default float-right tp-action" data-action="close-new-role"><?php echo $lang->get('close'); ?></button>
287
                                </div>
288
                            </div>
289
                            <div class="card-body table-responsive p-0" id="ldap-users-table">
290
                                <table class="table table-hover table-responsive">
291
                                    <thead>
292
                                        <tr>
293
                                            <th style="width: 25%;"><i class="fa-solid fa-id-badge mr-1"></i><?php echo $lang->get('login'); ?></th>
294
                                            <th style="width: 60px; text-align:center;"><i class="fa-solid fa-info infotip pointer" title="<?php echo $lang->get('more_information'); ?>"></i></th>
295
                                            <th style="width: 60px;"><i class="fa-solid fa-sync-alt infotip pointer" title="<?php echo $lang->get('synchronized'); ?>"></i></th>
296
                                            <th><i class="fa-solid fa-graduation-cap mr-1"></i><?php echo $lang->get('roles'); ?></th>
297
                                            <th style="width: 15%;"><i class="fa-solid fa-wrench mr-1"></i><?php echo $lang->get('action'); ?></th>
298
                                        </tr>
299
                                    </thead>
300
                                    <tbody id="row-ldap-body">
301
                                    </tbody>
302
                                </table>
303
                            </div>
304
                        </div>
305
                    </div>
306
307
                    <div class="card-footer">
308
                        <button type="button" class="btn btn-default float-right tp-action" data-action="close"><?php echo $lang->get('close'); ?></button>
309
                    </div>
310
                </div>
311
            </div>
312
        </div>
313
    </div>
314
315
316
    <!-- USER OAUTH2 SYNCHRONIZATION -->
317
    <div class="row hidden extra-form user-content with-header-menu" id="row-oauth2" data-content="oauth2-sync">
318
        <div class="col-12">
319
            <div class="card card-primary">
320
                <div class="card-header">
321
                    <h3 class="card-title"><?php echo $lang->get('oauth2_synchronization'); ?> <span id="row-logs-title"></span></h3>
322
                </div>
323
324
                <!-- /.card-header -->
325
                <!-- table start -->
326
                <div class="card-body">
327
                    <div class="row col-12">
328
                        <button type="button" class="btn btn-secondary btn-sm tp-action mr-2" data-action="oauth2-existing-users">
329
                            <i class="fa-solid fa-sync-alt mr-2"></i><?php echo $lang->get('list_users'); ?>
330
                        </button>
331
                        <button type="button" class="btn btn-secondary btn-sm tp-action mr-2" data-action="oauth2-add-role">
332
                            <i class="fa-solid fa-graduation-cap mr-2"></i><?php echo $lang->get('add_role_tip'); ?>
333
                        </button>
334
                    </div>
335
                    <div class="row">
336
                        <div class="col-12">
337
                            <div class="card hidden mt-4 mb-5 card-info" id="oauth2-new-role">
338
                                <div class="card-header">
339
                                    <i class="fa-solid fa-graduation-cap mr-2"></i><?php echo $lang->get('add_role_tip'); ?>
340
                                </div>
341
                                <div class="card-body">
342
                                    <div class="callout callout-info">
343
                                        <i class="fa-solid fa-info-circle text-info mr-2"></i><?php echo $lang->get('adding_ldap_role_to_teampass'); ?>
344
                                    </div>
345
                                    <div class="form-group row">
346
                                        <label for="oauth2-new-role-selection"><?php echo $lang->get('select_role_to_create'); ?></label>
347
                                        <select class="form-control form-item-control" style="width:100%;" id="oauth2-new-role-selection"></select>
348
                                    </div>
349
                                    <div class="form-group row">
350
                                        <label for="oauth2-new-role-complexity"><?php echo $lang->get('complexity'); ?></label>
351
                                        <select id="oauth2-new-role-complexity" class="form-control form-item-control" style="width:100%;">
352
                                            <?php
353
                                            foreach (TP_PW_COMPLEXITY as $entry) {
354
                                                echo '
355
                                            <option value="' . $entry[0] . '">' . addslashes($entry[1]) . '</option>';
356
                                            }
357
                                            ?>
358
                                        </select>
359
                                    </div>
360
                                </div>
361
                                <div class="card-footer">
362
                                    <button type="button" class="btn btn-default float-left tp-action btn-info" data-action="add-new-role-oauth2"><?php echo $lang->get('submit'); ?></button>
363
                                    <button type="button" class="btn btn-default float-right tp-action" data-action="close-new-role-oauth2"><?php echo $lang->get('close'); ?></button>
364
                                </div>
365
                            </div>
366
                            <div class="card-body table-responsive p-0" id="oauth2-users-table">
367
                                <table class="table table-hover table-responsive">
368
                                    <thead>
369
                                        <tr>
370
                                            <th style="width: 25%;"><i class="fa-solid fa-id-badge mr-1"></i><?php echo $lang->get('login'); ?></th>
371
                                            <th style="width: 60px; text-align:center;"><i class="fa-solid fa-info infotip pointer" title="<?php echo $lang->get('more_information'); ?>"></i></th>
372
                                            <th style="width: 60px;"><i class="fa-solid fa-sync-alt infotip pointer" title="<?php echo $lang->get('synchronized'); ?>"></i></th>
373
                                            <th><i class="fa-solid fa-graduation-cap mr-1"></i><?php echo $lang->get('roles'); ?></th>
374
                                            <th style="width: 15%;"><i class="fa-solid fa-wrench mr-1"></i><?php echo $lang->get('action'); ?></th>
375
                                        </tr>
376
                                    </thead>
377
                                    <tbody id="row-oauth2-body">
378
                                    </tbody>
379
                                </table>
380
                            </div>
381
                        </div>
382
                    </div>
383
384
                    <div class="card-footer">
385
                        <button type="button" class="btn btn-default float-right tp-action" data-action="close"><?php echo $lang->get('close'); ?></button>
386
                    </div>
387
                </div>
388
            </div>
389
        </div>
390
    </div>
391
392
    <!-- USER FORM -->
393
    <div class="row <?php echo $showNewUser ? '' : 'hidden';?> extra-form user-content" id="row-form" data-content="new" data-content-alternative="edit">
394
        <div class="col-12">
395
            <div class="card card-primary">
396
                <div class="card-header">
397
                    <h3 class="card-title"><?php echo $lang->get('user_definition'); ?></h3>
398
                </div>
399
400
                <!-- /.card-header -->
401
                <!-- form start -->
402
                <form role="form" id="form-user">
403
                    <div class="card-body">
404
                        <div class="row">
405
                            <div class="col-lg-6">
406
                                <div class="form-group">
407
                                    <label for="form-name"><?php echo $lang->get('name'); ?></label>
408
                                    <input type="text" class="form-control clear-me required track-change purify" id="form-name" data-field="name">
409
                                </div>
410
                                <div class="form-group">
411
                                    <label for="form-login"><?php echo $lang->get('login'); ?></label>
412
                                    <input type="text" class="form-control clear-me required build-login track-change purify" id="form-login" data-field="login">
413
                                    <input type="hidden" id="form-login-conform" value="0">
414
                                </div>
415
                            </div>
416
                            
417
                            <div class="col-lg-6">
418
                                <div class="form-group">
419
                                    <label for="form-lastname"><?php echo $lang->get('lastname'); ?></label>
420
                                    <input type="text" class="form-control clear-me required track-change purify" id="form-lastname" data-field="lastname">
421
                                </div>
422
                                <div class="form-group">
423
                                    <label for="form-login"><?php echo $lang->get('email'); ?></label>
424
                                    <input type="email" class="form-control clear-me required track-change validate-email purify" id="form-email" data-field="email">
425
                                </div>
426
                            </div>
427
                        </div>
428
                        <div class="form-group">
429
                            <label for="form-login" class="mr-2"><?php echo $lang->get('privileges'); ?></label>
430
                            <input type="radio" class="form-check-input form-control flat-blue only-admin track-change" name="privilege" id="privilege-admin">
431
                            <label class="form-check-label mr-2 pointer" for="privilege-admin"><?php echo $lang->get('administrator'); ?></label>
432
                            <input type="radio" class="form-check-input form-control flat-blue only-admin track-change" name="privilege" id="privilege-hr">
433
                            <label class="form-check-label mr-2 pointer" for="privilege-hr"><?php echo $lang->get('super_manager'); ?></label>
434
                            <input type="radio" class="form-check-input form-control flat-blue only-admin track-change" name="privilege" id="privilege-manager">
435
                            <label class="form-check-label mr-2 pointer" for="privilege-manager"><?php echo $lang->get('manager'); ?></label>
436
                            <input type="radio" class="form-check-input form-control flat-blue track-change" name="privilege" id="privilege-user">
437
                            <label class="form-check-label mr-2 pointer" for="privilege-user"><?php echo $lang->get('user'); ?></label>
438
                            <input type="radio" class="form-check-input form-control flat-blue track-change" name="privilege" id="privilege-ro">
439
                            <label class="form-check-label mr-2 pointer" for="privilege-ro"><?php echo $lang->get('read_only'); ?></label>
440
                        </div>
441
                        <div class="form-group not-for-admin">
442
                            <label for="form-roles"><?php echo $lang->get('roles'); ?></label>
443
                            <select id="form-roles" class="form-control form-item-control select2 no-root required track-change" style="width:100%;" multiple="multiple">
444
                                <?php echo $optionsRoles; ?>
445
                            </select>
446
                        </div>
447
                        <div class="form-group not-for-admin">
448
                            <label for="form-managedby"><?php echo $lang->get('managed_by'); ?></label>
449
                            <select id="form-managedby" class="form-control form-item-control select2 no-root required track-change" style="width:100%;">
450
                                <?php echo $optionsManagedBy; ?>
451
                            </select>
452
                        </div>
453
                        <div class="form-group not-for-admin">
454
                            <label for="form-auth"><?php echo $lang->get('authorized_groups'); ?></label>
455
                            <select id="form-auth" class="form-control form-item-control select2 no-root track-change" style="width:100%;" multiple="multiple">
456
                                <?php echo $foldersList; ?>
457
                            </select>
458
                        </div>
459
                        <div class="form-group not-for-admin">
460
                            <label for="form-forbid"><?php echo $lang->get('forbidden_groups'); ?></label>
461
                            <select id="form-forbid" class="form-control form-item-control select2 no-root track-change" style="width:100%;" multiple="multiple">
462
                                <?php echo $foldersList; ?>
463
                            </select>
464
                        </div>
465
                        <div class="form-group not-for-admin">
466
                            <label for="form-forbid"><?php echo $lang->get('special'); ?></label>
467
                        </div>
468
                        <div class="form-group not-for-admin">
469
                            <input type="checkbox" class="form-check-input form-control flat-blue track-change" id="form-create-root-folder">
470
                            <label class="form-check-label mr-2" for="form-create-root-folder"><?php echo $lang->get('can_create_root_folder'); ?></label>
471
                        </div>
472
                        <div class="form-group not-for-admin">
473
                            <input type="checkbox" class="form-check-input form-control flat-blue track-change" id="form-create-personal-folder">
474
                            <label class="form-check-label mr-2" for="form-create-personal-folder"><?php echo $lang->get('enable_personal_folder_for_this_user'); ?></label>
475
                        </div>
476
                        <div class="form-group not-for-admin" id="group-create-special-folder">
477
                            <input type="checkbox" class="form-check-input form-control flat-blue track-change" id="form-create-special-folder">
478
                            <label class="form-check-label mr-2" for="form-create-special-folder"><?php echo $lang->get('auto_create_folder_role'); ?></label>
479
                            <input type="text" class="form-control clear-me mt-1 purify" id="form-special-folder" data-field="" disabled="true" placeholder="<?php echo $lang->get('label'); ?>">
480
                        </div>
481
                        <div class="form-group not-for-admin" id="form-create-mfa-enabled-div">
482
                            <input type="checkbox" class="form-check-input form-control flat-blue track-change" id="form-create-mfa-enabled">
483
                            <label class="form-check-label mr-2" for="form-create-mfa-enabled"><?php echo $lang->get('mfa_enabled'); ?></label>
484
                        </div>
485
                    </div>
486
                    <!-- /.card-body -->
487
                </form>
488
489
                <div class="card-footer">
490
                    <button type="button" class="btn btn-primary tp-action" data-action="submit"><?php echo $lang->get('submit'); ?></button>
491
                    <button type="button" class="btn btn-default float-right tp-action" data-action="cancel"><?php echo $lang->get('cancel'); ?></button>
492
                </div>
493
            </div>
494
        </div>
495
    </div>
496
497
    <!-- USER LOGS -->
498
    <div class="row hidden extra-form user-content" id="row-logs" data-content="logs">
499
        <div class="col-12">
500
            <div class="card card-primary">
501
                <div class="card-header">
502
                    <h3 class="card-title"><?php echo $lang->get('logs_for_user'); ?> <span id="row-logs-title"></span></h3>
503
                </div>
504
505
                <!-- /.card-header -->
506
                <!-- table start -->
507
                <div class="card-body form" id="user-logs">
508
                    <table id="table-logs" class="table table-striped nowrap table-responsive p-0" style="width:100%">
509
                        <thead>
510
                            <tr>
511
                                <th scope="col"><?php echo $lang->get('date'); ?></th>
512
                                <th scope="col"><?php echo $lang->get('activity'); ?></th>
513
                                <th scope="col"><?php echo $lang->get('label'); ?></th>
514
                            </tr>
515
                        </thead>
516
                        <tbody>
517
518
                        </tbody>
519
                    </table>
520
                </div>
521
522
                <div class="card-footer">
523
                    <button type="button" class="btn btn-default float-right tp-action" data-action="cancel"><?php echo $lang->get('cancel'); ?></button>
524
                </div>
525
            </div>
526
        </div>
527
    </div>
528
529
    <!-- USER VISIBLE FOLDERS -->
530
    <div class="row hidden extra-form user-content" id="row-visible-folders" data-content="visible-folders">
531
        <div class="col-12">
532
            <div class="card card-primary">
533
                <div class="card-header">
534
                    <h3 class="card-title"><?php echo $lang->get('access_rights_for_user'); ?> <b><span id="row-folders-title"></span></b></h3>
535
                </div>
536
537
                <!-- /.card-header -->
538
                <!-- table start -->
539
                <div class="card-body" id="row-folders-results"></div>
540
541
                <div class="card-footer">
542
                    <button type="button" class="btn btn-default float-right tp-action" data-action="cancel"><?php echo $lang->get('cancel'); ?></button>
543
                </div>
544
            </div>
545
        </div>
546
    </div>
547
548
    <!-- PROPAGATE USER RIGHTS -->
549
    <div class="row hidden extra-form user-content with-header-menu" id="row-propagate" data-content="propagate">
550
        <div class="col-12">
551
            <div class="card card-primary">
552
                <div class="card-header">
553
                    <h3 class="card-title"><?php echo $lang->get('propagate_user_rights'); ?></h3>
554
                </div>
555
556
                <!-- /.card-header -->
557
                <div class="card-body">
558
                    <div class="row">
559
                        <div class="callout callout-info col-12">
560
                            <i class="fa-solid fa-info fa-lg mr-2"></i><?php echo $lang->get('share_rights_info'); ?>
561
                        </div>
562
                    </div>
563
564
                    <div class="form-group">
565
                        <label for="propagate-from"><?php echo $lang->get('share_rights_source'); ?></label>
566
                        <select id="propagate-from" class="form-control form-item-control select2" style="width:100%;">
567
                            <?php echo $optionsRoles; ?>
568
                        </select>
569
                    </div>
570
571
                    <div class="form-group ml-5">
572
                        <label><i class="far fa-hand-point-right fa-xs mr-2"></i><?php echo $lang->get('functions'); ?></label>
573
                        <span id="propagate-user-roles"></span>
574
                    </div>
575
576
                    <div class="form-group ml-5">
577
                        <label><i class="far fa-hand-point-right fa-xs mr-2"></i><?php echo $lang->get('managed_by'); ?></label>
578
                        <span id="propagate-user-managedby"></span>
579
                    </div>
580
581
                    <div class="form-group ml-5">
582
                        <label><i class="far fa-hand-point-right fa-xs mr-2"></i><?php echo $lang->get('authorized_groups'); ?></label>
583
                        <span id="propagate-user-allowed"></span>
584
                    </div>
585
586
                    <div class="form-group ml-5">
587
                        <label><i class="far fa-hand-point-right fa-xs mr-2"></i><?php echo $lang->get('forbidden_groups'); ?></label>
588
                        <span id="propagate-user-fordidden"></span>
589
                    </div>
590
591
                    <div class="form-group">
592
                        <label for="propagate-to"><?php echo $lang->get('share_rights_destination'); ?></label>
593
                        <select id="propagate-to" class="form-control form-item-control select2" style="width:100%;" multiple="multiple">
594
                            <?php echo $optionsRoles; ?>
595
                        </select>
596
                    </div>
597
598
                </div>
599
600
601
                <div class="card-footer">
602
                    <button type="button" class="btn btn-primary tp-action" data-action="do-propagate"><?php echo $lang->get('perform'); ?></button>
603
                    <button type="button" class="btn btn-default float-right tp-action" data-action="cancel"><?php echo $lang->get('cancel'); ?></button>
604
                </div>
605
606
            </div>
607
        </div>
608
    </div>
609
610
611
    <div class="row hidden extra-form user-content with-header-menu" id="deleted-users-section" data-content="deleted-users">
612
        <div class="card-header">
613
            <h5><?php echo $lang->get('deleted_users'); ?></h5>
614
        </div>
615
        <div class="card-body">
616
            <button type="button" 
617
                    class="btn btn-warning mb-3" 
618
                    id="btn-purge-old-users"
619
                    data-retention="90">
620
                <i class="fas fa-broom"></i> <?php echo $lang->get('purge_users_90days'); ?>
621
            </button>
622
            
623
            <div id="deleted-users-list">
624
                <table class="table table-striped" id="table-deleted-users">
625
                    <thead>
626
                        <tr>
627
                            <th><?php echo $lang->get('login'); ?></th>
628
                            <th><?php echo $lang->get('email'); ?></th>
629
                            <th><?php echo $lang->get('deleted_date'); ?></th>
630
                            <th><?php echo $lang->get('days_since'); ?></th>
631
                            <th><?php echo $lang->get('actions'); ?></th>
632
                        </tr>
633
                    </thead>
634
                    <tbody></tbody>
635
                </table>
636
            </div>
637
638
            <div class="card-footer">
639
                <button type="button" class="btn btn-default float-right btn-close-deleted-users"><?php echo $lang->get('cancel'); ?></button>
640
            </div>
641
        </div>
642
    </div>
643
644
</section>
645