mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-01-26 09:19:05 +01:00
Fix session status logic: Add IDLE state for logged-in users without processes, improve process detection with TTY filtering, enhance status messages with clearer explanations
This commit is contained in:
@@ -839,7 +839,12 @@
|
||||
<tr ng-repeat="login in sshLogins">
|
||||
<td>{$ login.user $}</td>
|
||||
<td>{$ login.ip $}</td>
|
||||
<td>{$ login.country $}</td>
|
||||
<td>
|
||||
<div style="display: flex; align-items: center; gap: 6px;">
|
||||
<img ng-if="login.flag" ng-src="{$ login.flag $}" alt="{$ login.country $}" style="width: 24px; height: 18px; border: 1px solid #e8e9ff; border-radius: 2px;" />
|
||||
<span>{$ login.country $}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>{$ login.date $}</td>
|
||||
<td>
|
||||
<span ng-if="login.is_active" class="session-status active-session">
|
||||
@@ -1103,6 +1108,43 @@
|
||||
</div>
|
||||
|
||||
<div ng-if="!loadingSSHActivity && !errorSSHActivity">
|
||||
<!-- Session Status Info -->
|
||||
<div style="background: #f8f9ff; border-left: 4px solid #5b5fcf; padding: 12px 16px; border-radius: 6px; margin-bottom: 20px;">
|
||||
<div style="display: flex; align-items: center; gap: 10px; margin-bottom: 8px;">
|
||||
<i class="fas fa-info-circle" style="color: #5b5fcf;"></i>
|
||||
<strong style="color: #2f3640;">Session Status:</strong>
|
||||
<span ng-if="isActiveSession && sshActivity.processes && sshActivity.processes.length > 0" style="color: #10b981; font-weight: 600;">
|
||||
<i class="fas fa-circle" style="font-size: 8px;"></i> ACTIVE - User is logged in with running processes
|
||||
</span>
|
||||
<span ng-if="isActiveSession && (!sshActivity.processes || sshActivity.processes.length === 0) && sshActivity.w && sshActivity.w.length > 0" style="color: #f59e0b; font-weight: 600;">
|
||||
<i class="fas fa-circle" style="font-size: 8px;"></i> IDLE - User is logged in but no processes running (shell waiting)
|
||||
</span>
|
||||
<span ng-if="isActiveSession && (!sshActivity.processes || sshActivity.processes.length === 0) && (!sshActivity.w || sshActivity.w.length === 0)" style="color: #ef4444; font-weight: 600;">
|
||||
<i class="fas fa-circle" style="font-size: 8px;"></i> INCONSISTENT - Marked as active but no processes or sessions found
|
||||
</span>
|
||||
<span ng-if="!isActiveSession" style="color: #ef4444; font-weight: 600;">
|
||||
<i class="fas fa-circle" style="font-size: 8px;"></i> INACTIVE - Session has ended
|
||||
</span>
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #64748b; margin-left: 24px;">
|
||||
<div ng-if="sshActivityStatus">
|
||||
<strong>Login Status:</strong> {$ sshActivityStatus $}
|
||||
</div>
|
||||
<div ng-if="sshActivity.processes && sshActivity.processes.length > 0" style="margin-top: 4px;">
|
||||
<strong>Running Processes:</strong> {$ sshActivity.processes.length $} process(es) found
|
||||
</div>
|
||||
<div ng-if="sshActivity.w && sshActivity.w.length > 0" style="margin-top: 4px;">
|
||||
<strong>Active Sessions (w command):</strong> {$ sshActivity.w.length $} session(s) detected
|
||||
</div>
|
||||
<div ng-if="(!sshActivity.processes || sshActivity.processes.length === 0) && sshActivity.w && sshActivity.w.length > 0" style="margin-top: 4px; color: #f59e0b;">
|
||||
<em>⚠️ User is logged in (detected by 'w' command) but no processes found. This usually means the shell is idle, waiting for input.</em>
|
||||
</div>
|
||||
<div ng-if="(!sshActivity.processes || sshActivity.processes.length === 0) && (!sshActivity.w || sshActivity.w.length === 0)" style="margin-top: 4px; color: #ef4444;">
|
||||
<em>⚠️ No processes or active sessions found. The session may have just ended or the user logged out.</em>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Processes List -->
|
||||
<div ng-if="sshActivity.processes && sshActivity.processes.length > 0" class="process-list">
|
||||
<h4 style="font-size: 14px; font-weight: 600; color: #2f3640; margin-bottom: 12px; display: flex; align-items: center; gap: 8px;">
|
||||
@@ -1166,17 +1208,19 @@
|
||||
<!-- Only show Kill Session button for active sessions -->
|
||||
<button class="kill-session-btn"
|
||||
ng-click="killSSHSession(sshActivityUser, sshActivityTTY)"
|
||||
ng-disabled="killingSession || !isActiveSession"
|
||||
ng-if="isActiveSession"
|
||||
ng-disabled="killingSession || !isActiveSession || !sshActivity.processes || sshActivity.processes.length === 0"
|
||||
ng-if="isActiveSession && sshActivity.processes && sshActivity.processes.length > 0"
|
||||
title="Kill All Processes for This Active Session">
|
||||
<i class="fas fa-power-off" ng-if="!killingSession"></i>
|
||||
<i class="fas fa-spinner fa-spin" ng-if="killingSession"></i>
|
||||
<span ng-if="!killingSession">Kill Session</span>
|
||||
<span ng-if="killingSession">Killing...</span>
|
||||
</button>
|
||||
<div ng-if="!isActiveSession" style="color: #94a3b8; font-size: 13px; padding: 10px 20px; display: inline-flex; align-items: center; gap: 8px;">
|
||||
<div ng-if="!isActiveSession || (isActiveSession && (!sshActivity.processes || sshActivity.processes.length === 0))" style="color: #94a3b8; font-size: 13px; padding: 10px 20px; display: inline-flex; align-items: center; gap: 8px;">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<span>Session is not active (no processes running)</span>
|
||||
<span ng-if="!isActiveSession">Session is inactive - cannot kill an ended session</span>
|
||||
<span ng-if="isActiveSession && (!sshActivity.processes || sshActivity.processes.length === 0) && sshActivity.w && sshActivity.w.length > 0">User is logged in but idle (no processes to kill) - shell is waiting for input</span>
|
||||
<span ng-if="isActiveSession && (!sshActivity.processes || sshActivity.processes.length === 0) && (!sshActivity.w || sshActivity.w.length === 0)">No processes or sessions found - session may have just ended</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-actions-right">
|
||||
|
||||
@@ -714,13 +714,34 @@ def getRecentSSHLogins(request):
|
||||
date_str = date_match.group(1) if date_match else ''
|
||||
session_info = ''
|
||||
is_active = False
|
||||
if '-' in line:
|
||||
# Session ended
|
||||
session_info = line.split('-')[-1].strip()
|
||||
is_active = False
|
||||
elif 'still logged in' in line:
|
||||
if 'still logged in' in line:
|
||||
session_info = 'still logged in'
|
||||
is_active = True
|
||||
elif '-' in line:
|
||||
# Session ended - parse the end time and duration
|
||||
# Format: "Tue May 27 11:34 - 13:47 (02:13)" or "crash (00:40)"
|
||||
end_part = line.split('-')[-1].strip()
|
||||
# Check if it's a crash or normal logout
|
||||
if 'crash' in end_part.lower():
|
||||
# Extract crash duration if available
|
||||
crash_match = re.search(r'crash\s*\(([^)]+)\)', end_part, re.IGNORECASE)
|
||||
if crash_match:
|
||||
session_info = f"crash ({crash_match.group(1)})"
|
||||
else:
|
||||
session_info = 'crash'
|
||||
else:
|
||||
# Normal session end - try to extract duration
|
||||
duration_match = re.search(r'\(([^)]+)\)', end_part)
|
||||
if duration_match:
|
||||
session_info = f"ended ({duration_match.group(1)})"
|
||||
else:
|
||||
# Just show the end time
|
||||
time_match = re.search(r'([A-Za-z]{3}\s+[A-Za-z]{3}\s+\d+\s+[\d:]+)', end_part)
|
||||
if time_match:
|
||||
session_info = f"ended at {time_match.group(1)}"
|
||||
else:
|
||||
session_info = 'ended'
|
||||
is_active = False
|
||||
# GeoIP lookup (cache per request) - support both IPv4 and IPv6
|
||||
country = flag = ''
|
||||
# Check if IP is IPv4
|
||||
@@ -1279,9 +1300,15 @@ def getSSHUserActivity(request):
|
||||
w_lines = []
|
||||
|
||||
# Get processes for the user (limit to 50 for speed)
|
||||
# If TTY is specified, filter by TTY; otherwise get all user processes
|
||||
processes = []
|
||||
try:
|
||||
ps_cmd = f"ps -u {user} -o pid,ppid,tty,time,cmd --no-headers 2>/dev/null | head -50"
|
||||
if tty:
|
||||
# Filter by specific TTY
|
||||
ps_cmd = f"ps -u {user} -o pid,ppid,tty,time,cmd --no-headers 2>/dev/null | grep '{tty}' | head -50"
|
||||
else:
|
||||
# Get all processes for user
|
||||
ps_cmd = f"ps -u {user} -o pid,ppid,tty,time,cmd --no-headers 2>/dev/null | head -50"
|
||||
ps_output = ProcessUtilities.outputExecutioner(ps_cmd)
|
||||
if ps_output:
|
||||
for line in ps_output.strip().split('\n'):
|
||||
@@ -1290,6 +1317,7 @@ def getSSHUserActivity(request):
|
||||
parts = line.split(None, 4)
|
||||
if len(parts) >= 5:
|
||||
pid, ppid, tty_val, time_val, cmd = parts[0], parts[1], parts[2], parts[3], parts[4]
|
||||
# Additional TTY check if tty was specified
|
||||
if tty and tty not in tty_val:
|
||||
continue
|
||||
# Skip CWD lookup for speed
|
||||
|
||||
Reference in New Issue
Block a user