Issues (29)

Security Analysis    no vulnerabilities found

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

pages/admin.php (1 issue)

Severity
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      admin.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\PerformChecks\PerformChecks;
36
use TeampassClasses\ConfigManager\ConfigManager;
37
38
// Load functions
39
require_once __DIR__.'/../sources/main.functions.php';
40
41
// init
42
loadClasses('DB');
43
$session = SessionManager::getSession();
44
$request = SymfonyRequest::createFromGlobals();
45
$lang = new Language($session->get('user-language') ?? 'english');
46
47
// Load config
48
$configManager = new ConfigManager();
49
$SETTINGS = $configManager->getAllSettings();
50
51
// Do checks
52
$checkUserAccess = new PerformChecks(
53
    dataSanitizer(
54
        [
55
            'type' => htmlspecialchars($request->request->get('type', ''), ENT_QUOTES, 'UTF-8'),
56
        ],
57
        [
58
            'type' => 'trim|escape',
59
        ],
60
    ),
61
    [
62
        'user_id' => returnIfSet($session->get('user-id'), null),
63
        'user_key' => returnIfSet($session->get('key'), null),
64
    ]
65
);
66
67
// Handle the case
68
echo $checkUserAccess->caseHandler();
69
if ($checkUserAccess->checkSession() === false || $checkUserAccess->userAccessPage('admin') === 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
<!-- Content Header (Page header) -->
86
<div class="content-header">
87
    <div class="container-fluid">
88
        <div class="row mb-2">
89
            <div class="col-sm-6">
90
                <h1 class="m-0 text-dark">
91
                    <i class="fas fa-tachometer-alt"></i> <?php echo $lang->get('dashboard'); ?>
92
                </h1>
93
            </div>
94
            <div class="col-sm-6">
95
                <ol class="breadcrumb float-sm-right">
96
                    <li class="breadcrumb-item"><a href="index.php?page=items"><?php echo $lang->get('home'); ?></a></li>
97
                    <li class="breadcrumb-item active"><?php echo $lang->get('admin'); ?></li>
98
                </ol>
99
            </div>
100
        </div>
101
    </div>
102
</div>
103
104
<!-- Main content -->
105
<section class="content">
106
    <div class="container-fluid">
107
        
108
        <!-- Info Box for last update and GitHub link -->
109
        <div class="row mb-3">
110
            <div class="col-12">
111
                <div class="alert alert-info alert-dismissible">
112
                    <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
113
                    <h5>
114
                        <i class="icon fas fa-info"></i> <?php echo $lang->get('admin_info_header'); ?>
115
                    </h5>
116
                    <span>
117
                        <i class="fa-regular fa-eye mr-2"></i><?php echo $lang->get('currently_using_version')." <b>".TP_VERSION.".<i>".TP_VERSION_MINOR."</i></b>"; ?>
118
                    </span> | 
119
                    <span id="admin-last-refresh"><?php echo $lang->get('admin_last_refresh'); ?>: <span class="badge badge-light" id="last-refresh-time">--:--:--</span></span>
120
                     | 
121
                    <span class="ml-3">
122
                        <a href="https://github.com/nilsteampassnet/TeamPass/releases" target="_blank" class="text-white">
123
                            <i class="fab fa-github"></i> <?php echo $lang->get('admin_view_changelog_github'); ?>
124
                        </a>
125
                    </span>
126
                </div>
127
            </div>
128
        </div>
129
130
        <!-- Main tabs card -->
131
        <div class="card card-primary card-outline card-outline-tabs">
132
            <div class="card-body">
133
                <div class="tab-content" id="admin-tabs-content">
134
                    
135
                    <!-- ============================================ -->
136
                    <!-- DASHBOARD TAB -->
137
                    <!-- ============================================ -->
138
                    <div class="tab-pane fade show active" id="tab-dashboard" role="tabpanel" aria-labelledby="tab-dashboard-link">
139
                        
140
                        <!-- Statistics Cards Row -->
141
                        <div class="row">
142
                            <!-- Users Statistics -->
143
                            <div class="col-lg-3 col-6">
144
                                <div class="small-box bg-info">
145
                                    <div class="inner">
146
                                        <h3 id="stat-users-active">-</h3>
147
                                        <p><?php echo $lang->get('active_users'); ?></p>
148
                                        <div class="small text-white">
149
                                            <span><?php echo $lang->get('online'); ?>: <strong id="stat-users-online">-</strong></span><br>
150
                                            <span><?php echo $lang->get('blocked'); ?>: <strong id="stat-users-blocked">-</strong></span>
151
                                        </div>
152
                                    </div>
153
                                    <div class="icon">
154
                                        <i class="fas fa-users"></i>
155
                                    </div>
156
                                    <a href="index.php?page=users" class="small-box-footer">
157
                                        <?php echo $lang->get('open'); ?> <i class="fas fa-arrow-circle-right"></i>
158
                                    </a>
159
                                    <div class="overlay" id="loading-stat-users" style="display:none;">
160
                                        <i class="fas fa-sync fa-spin"></i>
161
                                    </div>
162
                                </div>
163
                            </div>
164
                            
165
                            <!-- Items Statistics -->
166
                            <div class="col-lg-3 col-6">
167
                                <div class="small-box bg-success">
168
                                    <div class="inner">
169
                                        <h3 id="stat-items-total">-</h3>
170
                                        <p><?php echo $lang->get('total_items'); ?></p>
171
                                        <div class="small text-white">
172
                                            <span><?php echo $lang->get('shared'); ?>: <strong id="stat-items-shared">-</strong></span><br>
173
                                            <span><?php echo $lang->get('personal'); ?>: <strong id="stat-items-personal">-</strong></span>
174
                                        </div>
175
                                    </div>
176
                                    <div class="icon">
177
                                        <i class="fas fa-key"></i>
178
                                    </div>
179
                                    <a href="index.php?page=utilities.deletion" class="small-box-footer">
180
                                        <?php echo $lang->get('open'); ?> <i class="fas fa-arrow-circle-right"></i>
181
                                    </a>
182
                                    <div class="overlay" id="loading-stat-items" style="display:none;">
183
                                        <i class="fas fa-sync fa-spin"></i>
184
                                    </div>
185
                                </div>
186
                            </div>
187
                            
188
                            <!-- Folders Statistics -->
189
                            <div class="col-lg-3 col-6">
190
                                <div class="small-box bg-warning">
191
                                    <div class="inner">
192
                                        <h3 id="stat-folders-total">-</h3>
193
                                        <p><?php echo $lang->get('total_folders'); ?></p>
194
                                        <div class="small text-white">
195
                                            <span><?php echo $lang->get('public'); ?>: <strong id="stat-folders-public">-</strong></span><br>
196
                                            <span><?php echo $lang->get('personal'); ?>: <strong id="stat-folders-personal">-</strong></span>
197
                                        </div>
198
                                    </div>
199
                                    <div class="icon">
200
                                        <i class="fas fa-folder-open"></i>
201
                                    </div>
202
                                    <a href="index.php?page=folders" class="small-box-footer">
203
                                        <?php echo $lang->get('open'); ?> <i class="fas fa-arrow-circle-right"></i>
204
                                    </a>
205
                                    <div class="overlay" id="loading-stat-folders" style="display:none;">
206
                                        <i class="fas fa-sync fa-spin"></i>
207
                                    </div>
208
                                </div>
209
                            </div>
210
                            
211
                            <!-- Logs Statistics -->
212
                            <div class="col-lg-3 col-6">
213
                                <div class="small-box bg-danger">
214
                                    <div class="inner">
215
                                        <h3 id="stat-logs-actions">-</h3>
216
                                        <p><?php echo $lang->get('logs_24h'); ?></p>
217
                                        <div class="small text-white">
218
                                            <span><?php echo $lang->get('accesses'); ?>: <strong id="stat-logs-accesses">-</strong></span><br>
219
                                            <span><?php echo $lang->get('errors'); ?>: <strong id="stat-logs-errors">-</strong></span>
220
                                        </div>
221
                                    </div>
222
                                    <div class="icon">
223
                                        <i class="fas fa-file-alt"></i>
224
                                    </div>
225
                                    <a href="index.php?page=utilities.logs" class="small-box-footer">
226
                                        <?php echo $lang->get('open'); ?> <i class="fas fa-arrow-circle-right"></i>
227
                                    </a>
228
                                    <div class="overlay" id="loading-stat-logs" style="display:none;">
229
                                        <i class="fas fa-sync fa-spin"></i>
230
                                    </div>
231
                                </div>
232
                            </div>
233
                        </div>
234
                        
235
                        <!-- System Health and Teampass Information Row -->
236
                        <div class="row">
237
                            <!-- System Health Card -->
238
                            <div class="col-lg-5">
239
                                <div class="card card-success">
240
                                    <div class="card-header">
241
                                        <h3 class="card-title">
242
                                            <i class="fas fa-heartbeat"></i> 
243
                                            <?php echo $lang->get('system_health'); ?>
244
                                        </h3>
245
                                    </div>
246
                                    <div class="card-body">
247
                                        <ul class="list-group list-group-flush">
248
                                            <li class="list-group-item d-flex justify-content-between align-items-center">
249
                                                <span><i class="fas fa-lock text-success"></i> <?php echo $lang->get('health_encryption'); ?></span>
250
                                                <span class="badge badge-success" id="health-encryption">-</span>
251
                                            </li>
252
                                            <!--
253
                                            <li class="list-group-item d-flex justify-content-between align-items-center">
254
                                                <span><i class="fas fa-file-code text-success"></i> <?php echo $lang->get('database_integrity'); ?></span>
255
                                                <span class="badge badge-success" id="health-database-integrity">-</span>
256
                                            </li>
257
-->
258
                                            <li class="list-group-item d-flex justify-content-between align-items-center">
259
                                                <span><i class="fas fa-user-clock text-success"></i> <?php echo $lang->get('health_sessions'); ?></span>
260
                                                <span class="badge badge-info" id="health-sessions">-</span>
261
                                            </li>
262
                                            <li class="list-group-item d-flex justify-content-between align-items-center">
263
                                                <span><i class="fas fa-history text-success"></i> <?php echo $lang->get('health_cron'); ?></span>
264
                                                <span class="badge badge-success" id="health-cron">-</span>
265
                                            </li>
266
                                            <li class="list-group-item d-flex justify-content-between align-items-center">
267
                                                <span><i class="fas fa-file-code text-warning"></i> <?php echo $lang->get('health_unknown_files'); ?></span>
268
                                                <span class="badge badge-warning" id="health-unknown-files">-</span>
269
                                            </li>
270
                                        </ul>
271
                                    </div>
272
                                    <div class="overlay" id="loading-health" style="display:none;">
273
                                        <i class="fas fa-sync fa-spin"></i>
274
                                    </div>
275
                                </div>
276
                            </div>
277
                            
278
                            <!-- Teampass Information Card -->
279
                            <div class="col-lg-7">
280
                                <div class="card card-default">
281
                                    <div class="card-header">
282
                                        <h3 class="card-title">
283
                                            <i class="fa-solid fa-barcode"></i>
284
                                            <?php echo $lang->get('teampass_information'); ?>
285
                                        </h3>
286
                                    </div>
287
                                    <div class="card-body">
288
                                        <ul class="list-group list-group-flush">                                
289
                                        <?php   
290
                                        if (isset($SETTINGS['enable_tasks_manager']) === true && (int) $SETTINGS['enable_tasks_manager'] === 0) {
291
                                            echo '<div class="alert bg-orange disabled" role="alert">
292
                                                <h5><i class="fa-solid fa-exclamation-triangle mr-2"></i>Since 3.0.0.23, TASKS manager is enabled by default and is mandatory.</h5>
293
                                                <p>Please ensure that cron job is set and enabled.<br />Open Tasks page and check status.</p>
294
                                                <p><a href="https://documentation.teampass.net/#/manage/tasks" target="_blank"><i class="fa-solid fa-book mr-2"></i>Check documentation</a>.</p>
295
                                            </div>';
296
                                        } else {
297
                                            ?>
298
                                            <div class="">
299
                                        <?php
300
                                        
301
                                        ?>
302
                                            </div>
303
                                        <?php                        
304
                                        }
305
                                        ?>
306
307
308
                                        <li class="list-group-item d-flex justify-content-between align-items-center">
309
                                            <span><i class="fa-solid fa-file-shield text-info"></i> <?php echo $lang->get('perform_file_integrity_check'); ?></span>
310
                                            <span>
311
                                                <button type="button" class="btn btn-primary btn-sm ml-2" id="check-project-files-btn" onclick="performProjectFilesIntegrityCheck()">
312
                                                <i class="fas fa-caret-right"></i>
313
                                            </button>
314
                                            </span>
315
                                        </li>
316
                                        <?php
317
318
                                        // Has the transparent recovery migration been done?
319
                                        DB::query(
320
                                            "SELECT id FROM " . prefixTable('users') . "
321
                                            WHERE (user_derivation_seed IS NULL
322
                                            OR private_key_backup IS NULL)
323
                                            AND disabled = 0"
324
                                        );
325
                                        if (DB::count() !== 0) {
326
                                            ?>
327
                                        <li class="list-group-item d-flex justify-content-between align-items-center">
328
                                            <span><i class="fa-solid fa-chart-bar text-info"></i> <?php echo $lang->get('perform_transparent_recovery_check'); ?></span>
329
                                            <span>
330
                                                <button type="button" class="btn btn-primary btn-sm ml-2" id="check-transparent-recovery-btn" onclick="performTransparentRecoveryCheck()">
331
                                                <i class="fas fa-caret-right"></i>
332
                                            </button>
333
                                            </span>
334
                                        </li>
335
                                            <?php
336
                                        }
337
338
                                        // Has the personal items migration been done for users?
339
                                        $stats = DB::query(
340
                                            "SELECT 
341
                                                COUNT(*) as total_users,
342
                                                SUM(CASE WHEN personal_items_migrated = 1 THEN 1 ELSE 0 END) as migrated_users,
343
                                                SUM(CASE WHEN personal_items_migrated = 0 THEN 1 ELSE 0 END) as pending_users
344
                                            FROM " . prefixTable('users') . "
345
                                            WHERE disabled = 0 AND deleted_at IS NULL"
346
                                        );
347
                                        $progressPercent = ($stats[0]['migrated_users'] / $stats[0]['total_users']) * 100;
348
                                        if ($progressPercent !== 100) {
349
                                            ?>
350
                                        <li class="list-group-item d-flex justify-content-between align-items-center">
351
                                            <span><i class="fa-solid fa-chart-bar text-info"></i> <?php echo $lang->get('get_personal_items_migration_status'); ?></span>
352
                                            <span>
353
                                                <button type="button" class="btn btn-primary btn-sm ml-2" id="personal-items-migration-btn" onclick="performPersonalItemsMigrationCheck()">
354
                                                <i class="fas fa-caret-right"></i>
355
                                            </button>
356
                                            </span>
357
                                        </li>
358
                                            <?php
359
                                        }
360
                                        // Status on users passwords migration to new encryption Symfony Password
361
                                        $excluded_ids = array(9999991, 9999997, 9999998, 9999999);
362
                                        $user_results = DB::query(
363
                                            "SELECT login 
364
                                            FROM ".prefixTable('users')."
365
                                            WHERE pw LIKE %s
366
                                            AND pw NOT LIKE %s
367
                                            AND id NOT IN %ls
368
                                            AND (login NOT LIKE %s OR deleted_at IS NULL)",
369
                                            '$2y$10$%',
370
                                            '$2y$13$%',
371
                                            $excluded_ids,
372
                                            '%_deleted_%'
373
                                        );
374
                                        if (DB::count() > 0) {
375
                                            $logins_array = array_column($user_results, 'login');
376
                                            $logins_list = implode(', ', $logins_array);
377
                                            ?>
378
                                        <li class="list-group-item d-flex justify-content-between align-items-center">
379
                                            <span><i class="fa-solid fa-hand text-warning"></i>
380
                                            Password Encryption Migration Required <span class="badge badge-warning"><?php echo DB::count();?> remaing users</span>
381
                                            </span>
382
                                            <span>
383
                                            <i class="fa-solid fa-info-circle text-primary open-info" data-info="<?php echo DB::count();?> user accounts still use the legacy encryption library and must be migrated before upgrading to version 3.2.0.<br>
384
                                            To migrate: Users must either log in once or have their password updated via the Users management page.<p class='mt-2'>List of remaining users: <?php echo $logins_list;?></p>" data-size="lg" data-title="Importante notice"></i>
385
                                            </span>
386
                                        </li>
387
                                            <?php
388
                                        }
389
390
                                        // Check if tp.config.php file is still present
391
                                        if (file_exists(__DIR__.'/../includes/config/tp.config.php') === true) {
392
                                            echo '<div class="mt-3 alert alert-warning" role="alert"><i class="fa-solid fa-circle-exclamation mr-2"></i>File tp.config.php requires to be deleted. Please do it and refresh this page. This warning shall not be visible anymore.</div>';
393
                                        }
394
                                        ?>
395
                                        </ul>
396
                                    </div>
397
                                </div>
398
                            </div>
399
                        </div>
400
                        
401
                        <!-- Live Activity and System Status Row -->
402
                        <div class="row">
403
                            <!-- Live Activity Card -->
404
                            <div class="col-lg-6">
405
                                <div class="card card-warning">
406
                                    <div class="card-header">
407
                                        <h3 class="card-title">
408
                                            <i class="fas fa-circle text-danger blink"></i> 
409
                                            <?php echo $lang->get('live_activity'); ?>
410
                                        </h3>
411
                                        <div class="card-tools">
412
                                            <span class="badge badge-warning" id="activity-refresh-countdown">10s</span>
413
                                        </div>
414
                                    </div>
415
                                    <div class="card-body p-0" style="max-height: 350px; overflow-y: auto;">
416
                                        <ul class="list-group list-group-flush" id="live-activity-list">
417
                                            <li class="list-group-item text-center text-muted">
418
                                                <i class="fas fa-sync fa-spin"></i> <?php echo $lang->get('loading'); ?>
419
                                            </li>
420
                                        </ul>
421
                                    </div>
422
                                    <div class="card-footer clearfix">
423
                                        <a href="index.php?page=utilities.logs#items" class="btn btn-sm btn-warning float-right">
424
                                            <?php echo $lang->get('view_all_logs'); ?>
425
                                        </a>
426
                                    </div>
427
                                    <div class="overlay" id="loading-activity" style="display:none;">
428
                                        <i class="fas fa-sync fa-spin"></i>
429
                                    </div>
430
                                </div>
431
                            </div>
432
                            
433
                            <!-- System Status Card -->
434
                            <div class="col-lg-6">
435
                                <div class="card card-primary">
436
                                    <div class="card-header">
437
                                        <h3 class="card-title">
438
                                            <i class="fas fa-server"></i> 
439
                                            <?php echo $lang->get('admin_tasks_status'); ?>
440
                                        </h3>
441
                                        <div class="card-tools">
442
                                            <span class="badge badge-primary" id="status-refresh-countdown">60s</span>
443
                                        </div>
444
                                    </div>
445
                                    <div class="card-body">
446
                                        <div class="row mt-3">
447
                                            <div class="col-6">
448
                                                <div class="description-block">
449
                                                    <h5 class="description-header" id="system-last-cron">--</h5>
450
                                                    <span class="description-text"><?php echo $lang->get('system_last_cron'); ?></span>
451
                                                </div>
452
                                            </div>
453
                                            <div class="col-6">
454
                                                <div class="description-block">
455
                                                    <h5 class="description-header" id="system-tasks">-</h5>
456
                                                    <span class="description-text"><?php echo $lang->get('tasks_queue'); ?></span>
457
                                                </div>
458
                                            </div>
459
                                        </div>
460
                                        <div class="row mt-3">
461
                                            <div class="col-12">
462
                                                <div class="alert alert-warning hidden" id="task_duration_status"></div>
463
                                            </div>
464
                                        </div>
465
                                        <?php
466
// Instantiate the adapter and repository
467
try {
468
    // Get last cron execution timestamp
469
    DB::query(
470
        'SELECT valeur
471
        FROM ' . prefixTable('misc') . '
472
        WHERE type = %s AND intitule = %s and valeur >= %d',
473
        'admin',
474
        'last_cron_exec',
475
        time() - 600 // max 10 minutes
476
    );
477
478
    if (DB::count() === 0) {
479
        ?>
480
                                        <div class="row mt-3">
481
                                            <div class="col-12">
482
                                            <div class="callout callout-info alert-dismissible mt-3" role="alert">
483
                                                <h5><i class="fa-solid fa-info mr-2"></i><?php echo $lang->get('information'); ?></h5>
484
                                                <?php echo str_replace("#teampass_path#", $SETTINGS['cpassman_dir'], $lang->get('tasks_information')); ?>
485
                                                <div class="mt-2">
486
                                                    <a href="index.php?page=tasks#settings" class="btn btn-info" role="button"><i class="fa-solid fa-arrow-up-right-from-square mr-2"></i><?php echo $lang->get('open_tasks_settings'); ?></a>
487
                                                </div>
488
                                            </div>
489
                                            </div>
490
                                        </div>
491
        <?php
492
    }
493
}
494
catch (Exception $e) {
495
    if (defined('LOG_TO_SERVER') && LOG_TO_SERVER === true) {
496
        error_log('TEAMPASS Error - admin page - '.$e->getMessage());
497
    }
498
    echo 'An error occurred. Please refer to server logs.';
499
}
500
?>
501
                                    </div>
502
                                    <div class="card-footer">
503
                                        <a href="index.php?page=tasks#settings" class="btn btn-sm btn-primary">
504
                                            <?php echo $lang->get('view_tasks'); ?>
505
                                        </a>
506
                                    </div>
507
                                    <div class="overlay" id="loading-status" style="display:none;">
508
                                        <i class="fas fa-sync fa-spin"></i>
509
                                    </div>
510
                                </div>
511
                            </div>
512
                        </div>
513
514
<?php
515
// Get server information
516
$serverVersionFull = DB::serverVersion();
517
$dbType = (stripos($serverVersionFull, 'MariaDB') !== false) ? 'MariaDB' : 'MySQL';
518
$versionParts = explode('-', $serverVersionFull);
519
$dbVersion = $versionParts[0];
520
521
// Get database size
522
$dbSize = DB::queryFirstField(
523
    "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size 
524
    FROM information_schema.TABLES 
525
    WHERE table_schema = DATABASE()"
526
);
527
$dbSizeFormatted = $dbSize . ' MB';
528
529
// Get other PHP info
530
$phpVersion = phpversion();
531
$memoryLimit = ini_get('memory_limit');
532
$memoryUsage = round(memory_get_usage() / 1024, 2) . ' KB';
533
$maxExecutionTime = ini_get('max_execution_time') . 's';
534
$maxUploadSize = ini_get('upload_max_filesize');
535
536
// Get OS info
537
$osInfo = php_uname('s') . ' ' . php_uname('r');
538
539
// Get timezone
540
$timezone = date_default_timezone_get();
541
$serverTime = date('H:i:s');
542
543
// Check internet connection (optional)
544
$internetStatus = @fsockopen("www.google.com", 80, $errno, $errstr, 3);
545
$internetConnected = ($internetStatus !== false);
546
if ($internetStatus) {
0 ignored issues
show
$internetStatus is of type false|resource, thus it always evaluated to false.
Loading history...
547
    fclose($internetStatus);
548
}
549
?>
550
551
                        <!-- Server Information Row -->
552
                        <div class="row">
553
                            <div class="col-lg-12">
554
                                <div class="card card-info">
555
                                    <div class="card-header">
556
                                        <h3 class="card-title">
557
                                            <i class="fas fa-server"></i> 
558
                                            Server Information
559
                                        </h3>
560
                                    </div>
561
                                    <div class="card-body">
562
                                        <div class="row">
563
                                            <!-- System & Network -->
564
                                            <div class="col-lg-3 col-md-6 col-sm-12">
565
                                                <h6 class="text-muted mb-3">
566
                                                    <i class="fas fa-desktop text-info"></i> System & Network
567
                                                </h6>
568
                                                <div class="mb-2">
569
                                                    <i class="fab fa-linux text-primary"></i>
570
                                                    <small class="text-muted">OS:</small>
571
                                                    <span class="float-right"><strong><?php echo $osInfo; ?></strong></span>
572
                                                </div>
573
                                                <div class="mb-2">
574
                                                    <i class="fas fa-globe text-<?php echo $internetConnected ? 'success' : 'danger'; ?>"></i>
575
                                                    <small class="text-muted">Internet:</small>
576
                                                    <span class="float-right">
577
                                                        <span class="badge badge-<?php echo $internetConnected ? 'success' : 'danger'; ?>">
578
                                                            <i class="fas fa-<?php echo $internetConnected ? 'check' : 'times'; ?>"></i> 
579
                                                            <?php echo $internetConnected ? 'Connected' : 'Disconnected'; ?>
580
                                                        </span>
581
                                                    </span>
582
                                                </div>
583
                                            </div>
584
                                            
585
                                            <!-- PHP Configuration -->
586
                                            <div class="col-lg-3 col-md-6 col-sm-12">
587
                                                <h6 class="text-muted mb-3">
588
                                                    <i class="fab fa-php text-info"></i> PHP Configuration
589
                                                </h6>
590
                                                <div class="mb-2">
591
                                                    <i class="fas fa-code text-primary"></i>
592
                                                    <small class="text-muted">Version:</small>
593
                                                    <span class="float-right"><strong><?php echo $phpVersion; ?></strong></span>
594
                                                </div>
595
                                                <div class="mb-2">
596
                                                    <i class="fas fa-memory text-warning"></i>
597
                                                    <small class="text-muted">Memory limit:</small>
598
                                                    <span class="float-right"><strong><?php echo $memoryLimit; ?></strong></span>
599
                                                </div>
600
                                                <div class="mb-2">
601
                                                    <i class="fas fa-chart-area text-success"></i>
602
                                                    <small class="text-muted">Memory usage:</small>
603
                                                    <span class="float-right"><strong><?php echo $memoryUsage; ?></strong></span>
604
                                                </div>
605
                                            </div>
606
                                            
607
                                            <!-- PHP Limits -->
608
                                            <div class="col-lg-3 col-md-6 col-sm-12">
609
                                                <h6 class="text-muted mb-3">
610
                                                    <i class="fas fa-sliders-h text-info"></i> PHP Limits
611
                                                </h6>
612
                                                <div class="mb-2">
613
                                                    <i class="fas fa-clock text-warning"></i>
614
                                                    <small class="text-muted">Max execution:</small>
615
                                                    <span class="float-right"><strong><?php echo $maxExecutionTime; ?></strong></span>
616
                                                </div>
617
                                                <div class="mb-2">
618
                                                    <i class="fas fa-file-upload text-primary"></i>
619
                                                    <small class="text-muted">Max upload:</small>
620
                                                    <span class="float-right"><strong><?php echo $maxUploadSize; ?></strong></span>
621
                                                </div>
622
                                            </div>
623
                                            
624
                                            <!-- Database & Time -->
625
                                            <div class="col-lg-3 col-md-6 col-sm-12">
626
                                                <h6 class="text-muted mb-3">
627
                                                    <i class="fas fa-database text-info"></i> Database & Time
628
                                                </h6>
629
                                                <div class="mb-2">
630
                                                    <i class="fas fa-server text-success"></i>
631
                                                    <small class="text-muted"><?php echo $dbType; ?>:</small>
632
                                                    <span class="float-right"><strong><?php echo $dbVersion; ?></strong></span>
633
                                                </div>
634
                                                <div class="mb-2">
635
                                                    <i class="fas fa-hdd text-warning"></i>
636
                                                    <small class="text-muted">DB size:</small>
637
                                                    <span class="float-right"><strong><?php echo $dbSizeFormatted; ?></strong></span>
638
                                                </div>
639
                                                <div class="mb-2">
640
                                                    <i class="fas fa-clock text-primary"></i>
641
                                                    <small class="text-muted">Server time:</small>
642
                                                    <span class="float-right"><strong><?php echo $serverTime; ?></strong></span>
643
                                                </div>
644
                                                <div class="mb-2">
645
                                                    <i class="fas fa-map-marker-alt text-danger"></i>
646
                                                    <small class="text-muted">Timezone:</small>
647
                                                    <span class="float-right"><strong><?php echo $timezone; ?></strong></span>
648
                                                </div>
649
                                            </div>
650
                                        </div>
651
                                    </div>
652
                                </div>
653
                            </div>
654
                        </div>
655
656
                        <!-- Sponsoring Row -->
657
                        <div class="row">
658
                            <div class="col-lg-12">
659
                                <div class="card card-outline card-primary">
660
                                    <div class="card-header">
661
                                        <h3 class="card-title">
662
                                            <i class="fas fa-heart text-danger"></i> 
663
                                            <?php echo $lang->get('admin_support_teampass'); ?>
664
                                        </h3>
665
                                    </div>
666
                                    <div class="card-body">
667
                                        <div class="row align-items-center">
668
                                            <div class="col-md-8">
669
                                                <p class="mb-2">
670
                                                    <strong><?php echo $lang->get('admin_support_message'); ?></strong>
671
                                                </p>
672
                                                <p class="text-muted mb-3">
673
                                                    <?php echo $lang->get('admin_support_description'); ?>
674
                                                </p>
675
                                            </div>
676
                                            <div class="col-md-4 text-center">
677
                                                <a href="https://github.com/sponsors/nilsteampassnet" target="_blank" class="btn btn-danger btn-lg">
678
                                                    <i class="fab fa-github"></i> <?php echo $lang->get('admin_support_github_sponsors'); ?>
679
                                                </a>
680
                                                <br>
681
                                                <a href="https://www.paypal.com/donate/?hosted_button_id=XUVWYJ7J92X6L" target="_blank" class="btn btn-primary btn-lg mt-2">
682
                                                    <i class="fab fa-paypal"></i> <?php echo $lang->get('admin_support_paypal'); ?>
683
                                                </a>
684
                                                <p class="text-muted mt-3 small">
685
                                                    <i class="fas fa-users"></i> <?php echo $lang->get('admin_support_thank_you'); ?>
686
                                                </p>
687
                                            </div>
688
                                        </div>
689
                                    </div>
690
                                </div>
691
                            </div>
692
                        </div>
693
                        
694
                    </div>
695
                    
696
                </div>
697
            </div>
698
        </div>
699
        
700
    </div>
701
</section>
702
703
<!-- Info Modal -->
704
<div class="modal fade" id="info-modal" tabindex="-1" role="dialog" aria-labelledby="info-modal-title" aria-hidden="true">
705
    <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
706
        <div class="modal-content">
707
            <div class="modal-header bg-info">
708
                <h5 class="modal-title" id="info-modal-title">
709
                    <i class="fas fa-info-circle"></i> Information
710
                </h5>
711
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
712
                    <span aria-hidden="true">&times;</span>
713
                </button>
714
            </div>
715
            <div class="modal-body" id="info-modal-body">
716
                <!-- Content will be inserted here -->
717
            </div>
718
            <div class="modal-footer">
719
                <button type="button" class="btn btn-secondary" data-dismiss="modal">
720
                    <i class="fas fa-times"></i> Close
721
                </button>
722
            </div>
723
        </div>
724
    </div>
725
</div>
726