This commit is contained in:
usmannasir
2025-06-02 16:27:07 +05:00
parent 43439996e1
commit 2f771f2b7e
3 changed files with 114 additions and 113 deletions

View File

@@ -868,18 +868,37 @@ app.controller('OnboardingCP', function ($scope, $http, $timeout, $window) {
}); });
app.controller('dashboardStatsController', function ($scope, $http, $timeout) { app.controller('dashboardStatsController', function ($scope, $http) {
// Card values // Card values
$scope.totalSites = 0; $scope.totalSites = 0;
$scope.totalWPSites = 0; $scope.totalWPSites = 0;
$scope.totalDBs = 0; $scope.totalDBs = 0;
$scope.totalEmails = 0; $scope.totalEmails = 0;
// SSH Logins
$scope.sshLogins = [];
$scope.loadingSSHLogins = true;
$scope.errorSSHLogins = '';
$scope.refreshSSHLogins = function() {
$scope.loadingSSHLogins = true;
$http.get('/base/getRecentSSHLogins').then(function (response) {
$scope.loadingSSHLogins = false;
if (response.data && response.data.logins) {
$scope.sshLogins = response.data.logins;
} else {
$scope.sshLogins = [];
}
}, function (err) {
$scope.loadingSSHLogins = false;
$scope.errorSSHLogins = 'Failed to load SSH logins.';
});
};
// SSH Logs // SSH Logs
$scope.sshLogs = []; $scope.sshLogs = [];
$scope.loadingSSHLogs = true; $scope.loadingSSHLogs = true;
$scope.errorSSHLogs = ''; $scope.errorSSHLogs = '';
function fetchSSHLogs() { $scope.refreshSSHLogs = function() {
$scope.loadingSSHLogs = true; $scope.loadingSSHLogs = true;
$http.get('/base/getRecentSSHLogs').then(function (response) { $http.get('/base/getRecentSSHLogs').then(function (response) {
$scope.loadingSSHLogs = false; $scope.loadingSSHLogs = false;
@@ -892,35 +911,11 @@ app.controller('dashboardStatsController', function ($scope, $http, $timeout) {
$scope.loadingSSHLogs = false; $scope.loadingSSHLogs = false;
$scope.errorSSHLogs = 'Failed to load SSH logs.'; $scope.errorSSHLogs = 'Failed to load SSH logs.';
}); });
}
fetchSSHLogs();
setInterval(fetchSSHLogs, 10000);
// SSH Logins
$scope.sshLogins = [];
$scope.loadingSSHLogins = true;
$scope.errorSSHLogins = '';
function fetchSSHLogins() {
$scope.loadingSSHLogins = true;
$http.get('/base/getRecentSSHLogins').then(function (response) {
$scope.loadingSSHLogins = false;
if (response.data && response.data.logins) {
$scope.sshLogins = response.data.logins;
} else {
$scope.sshLogins = [];
}
}, function (error) {
$scope.loadingSSHLogins = false;
$scope.sshLogins = [];
$scope.errorSSHLogins = 'Failed to load SSH logins.';
});
}
fetchSSHLogins();
var sshPoller = function() {
fetchSSHLogins();
$timeout(sshPoller, 10000);
}; };
$timeout(sshPoller, 10000);
// Initial fetch
$scope.refreshSSHLogins();
$scope.refreshSSHLogs();
// Chart.js chart objects // Chart.js chart objects
var trafficChart, diskIOChart, cpuChart; var trafficChart, diskIOChart, cpuChart;

View File

@@ -108,7 +108,7 @@
" "
> >
{$ totalSites $} {$ totalSites $}
</div> </div>
<div <div
style=" style="
font-size: 1rem; font-size: 1rem;
@@ -118,12 +118,12 @@
" "
> >
Total Sites Total Sites
</div>
</div>
</div>
</div> </div>
</div> </div>
</a> </div>
</div>
</div>
</a>
<!-- WordPress Sites Card --> <!-- WordPress Sites Card -->
<a <a
@@ -167,7 +167,7 @@
" "
> >
{$ totalWPSites $} {$ totalWPSites $}
</div> </div>
<div <div
style=" style="
font-size: 1rem; font-size: 1rem;
@@ -177,12 +177,12 @@
" "
> >
WordPress Sites WordPress Sites
</div>
</div>
</div>
</div> </div>
</div> </div>
</a> </div>
</div>
</div>
</a>
<!-- Total Databases Card --> <!-- Total Databases Card -->
<a <a
@@ -239,9 +239,9 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</a> </a>
<!-- Total Emails Card --> <!-- Total Emails Card -->
<a <a
@@ -298,12 +298,12 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</a> </a>
</div> </div>
{% if admin %} {% if admin %}
<div ng-controller="homePageStatus" style="margin-bottom: 40px;"> <div ng-controller="homePageStatus" style="margin-bottom: 40px;">
<div style="display: flex; justify-content: center; gap: 30px; align-items: stretch; flex-wrap: wrap;" class="system-stats-row"> <div style="display: flex; justify-content: center; gap: 30px; align-items: stretch; flex-wrap: wrap;" class="system-stats-row">
<!-- CPU Usage --> <!-- CPU Usage -->
@@ -312,41 +312,41 @@
<div style="display: flex; justify-content: center;"> <div style="display: flex; justify-content: center;">
<div id="redcircle" class="c100 red p{$ cpuUsage $}"> <div id="redcircle" class="c100 red p{$ cpuUsage $}">
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ cpuUsage $}%</span> <span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ cpuUsage $}%</span>
<div class="slice"> <div class="slice">
<div class="bar"></div> <div class="bar"></div>
<div class="fill"></div> <div class="fill"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- RAM Usage --> <!-- RAM Usage -->
<div style="background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 30px 40px; flex: 1 1 0; min-width: 0; text-align: center; border: 1px solid #e9ecef;"> <div style="background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 30px 40px; flex: 1 1 0; min-width: 0; text-align: center; border: 1px solid #e9ecef;">
<div style="font-size: 1rem; color: #43a047; font-weight: 600; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Ram Usage" %}</div> <div style="font-size: 1rem; color: #43a047; font-weight: 600; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Ram Usage" %}</div>
<div style="display: flex; justify-content: center;"> <div style="display: flex; justify-content: center;">
<div id="greencircle" class="c100 p{$ ramUsage $} green"> <div id="greencircle" class="c100 p{$ ramUsage $} green">
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ ramUsage $}%</span> <span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ ramUsage $}%</span>
<div class="slice"> <div class="slice">
<div class="bar"></div> <div class="bar"></div>
<div class="fill"></div> <div class="fill"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- Disk Usage --> <!-- Disk Usage -->
<div style="background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 30px 40px; flex: 1 1 0; min-width: 0; text-align: center; border: 1px solid #e9ecef;"> <div style="background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 30px 40px; flex: 1 1 0; min-width: 0; text-align: center; border: 1px solid #e9ecef;">
<div style="font-size: 1rem; color: #d81b60; font-weight: 600; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Disk Usage '/'" %}</div> <div style="font-size: 1rem; color: #d81b60; font-weight: 600; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Disk Usage '/'" %}</div>
<div style="display: flex; justify-content: center;"> <div style="display: flex; justify-content: center;">
<div id="pinkcircle" class="c100 pink p{$ diskUsage $}"> <div id="pinkcircle" class="c100 pink p{$ diskUsage $}">
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ diskUsage $}%</span> <span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ diskUsage $}%</span>
<div class="slice"> <div class="slice">
<div class="bar"></div> <div class="bar"></div>
<div class="fill"></div> <div class="fill"></div>
</div>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div>
</div>
</div>
</div>
{% endif %} {% endif %}
<!-- <!--
@@ -449,7 +449,7 @@
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<!-- Tab Content --> <!-- Tab Content -->
<div <div
@@ -484,68 +484,74 @@
<canvas id="cpuChart" height="80"></canvas> <canvas id="cpuChart" height="80"></canvas>
</div> </div>
</div> </div>
</div> </div>
<!-- SSH Logins and Logs Row (side by side) --> <!-- SSH Logins and Logs Row (side by side) -->
{% if admin %} {% if admin %}
<div style="display: flex; gap: 30px; justify-content: center; align-items: flex-start; flex-wrap: wrap; margin-bottom: 40px;"> <div style="display: flex; gap: 30px; justify-content: center; align-items: flex-start; flex-wrap: wrap; margin-bottom: 40px;">
<!-- Recent SSH Logins Widget --> <!-- Recent SSH Logins Widget -->
<div style="flex: 1 1 420px; min-width: 320px; max-width: 600px; background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 25px 30px; border: 1px solid #e9ecef;"> <div style="flex: 1 1 420px; min-width: 320px; max-width: 600px; background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 25px 30px; border: 1px solid #e9ecef;">
<div style="font-size: 1.25rem; font-weight: 700; color: #333; letter-spacing: 0.5px; margin-bottom: 18px;">Recent SSH Logins</div> <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<div ng-if="loadingSSHLogins" style="text-align: center; padding: 20px; color: #888;">Loading recent SSH logins...</div> <div style="font-size: 1.25rem; font-weight: 700; color: #333;">Recent SSH Logins</div>
<div ng-if="!loadingSSHLogins && sshLogins.length === 0" style="text-align: center; color: #888; padding: 20px;">No recent SSH logins found.</div> <button class="btn btn-sm btn-outline-primary" ng-click="refreshSSHLogins()" title="Refresh"><span style="font-size:1.2em;">&#x21bb;</span> Refresh</button>
<div ng-if="!loadingSSHLogins && sshLogins.length > 0" style="overflow-x: auto;"> </div>
<table style="width: 100%; border-collapse: collapse; min-width: 320px;"> <div ng-if="loadingSSHLogins" style="text-align:center; color:#888; padding:20px;">Loading...</div>
<div ng-if="errorSSHLogins" style="color:#e53935;">{$ errorSSHLogins $}</div>
<div ng-if="!loadingSSHLogins && !errorSSHLogins && sshLogins.length === 0" style="text-align:center; color:#888; padding:20px;">No recent SSH logins found.</div>
<div style="overflow-x:auto;">
<table class="table table-striped table-hover" style="margin-bottom:0;">
<thead> <thead>
<tr style="background: #4c5fad; color: #fff;"> <tr style="background:#f1f3f6;">
<th style="padding: 12px 15px; border-radius: 8px 0 0 8px; text-align: left; font-weight: 600;">User</th> <th>User</th>
<th style="padding: 12px 15px; text-align: left; font-weight: 600;">IP</th> <th>IP</th>
<th style="padding: 12px 15px; text-align: left; font-weight: 600;">Country</th> <th>Country</th>
<th style="padding: 12px 15px; text-align: left; font-weight: 600;">Date/Time</th> <th>Date</th>
<th style="padding: 12px 15px; border-radius: 0 8px 8px 0; text-align: left; font-weight: 600;">Session</th> <th>Session</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="login in sshLogins" class="ssh-login-row" style="background: #f8f9fa; border-bottom: 1px solid #e9ecef; transition: background 0.2s;"> <tr ng-repeat="login in sshLogins" style="background: #f8f9fa; border-bottom: 1px solid #e9ecef;">
<td style="padding: 10px 15px; font-weight: 600; color: #333;">{$ login.user $}</td> <td style="padding: 8px 8px; font-weight: 600; color: #333;">{$ login.user $}</td>
<td style="padding: 10px 15px; color: #555;">{$ login.ip $}</td> <td style="padding: 8px 8px; color: #555;">{$ login.ip $}</td>
<td style="padding: 10px 15px;"> <td style="padding: 8px 8px;">
<span ng-if="login.flag"><img ng-src="{$ login.flag $}" alt="{$ login.country $}" style="height: 18px; margin-right: 6px; vertical-align: middle; border-radius: 2px;" /></span> <span ng-if="login.flag"><img ng-src="{$ login.flag $}" alt="{$ login.country $}" style="height: 18px; margin-right: 6px; vertical-align: middle;" /></span>
<span ng-if="!login.flag && login.country">{$ login.country $}</span> <span ng-if="!login.flag && login.country">{$ login.country $}</span>
<span ng-if="!login.flag && !login.country">-</span>
</td> </td>
<td style="padding: 10px 15px; color: #555;">{$ login.date $}</td> <td style="padding: 8px 8px;">{$ login.date $}</td>
<td style="padding: 10px 15px; color: #888;">{$ login.session $}</td> <td style="padding: 8px 8px;">{$ login.session $}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<!-- Recent SSH Logs Widget --> <!-- Recent SSH Logs Widget -->
<div style="flex: 1 1 420px; min-width: 320px; max-width: 600px; background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 25px 30px; border: 1px solid #e9ecef;"> <div style="flex: 1 1 520px; min-width: 380px; max-width: 900px; background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 25px 30px; border: 1px solid #e9ecef; min-height: 480px; max-height: 600px; display: flex; flex-direction: column;">
<div style="font-size: 1.25rem; font-weight: 700; color: #333; letter-spacing: 0.5px; margin-bottom: 18px;">Recent SSH Logs</div> <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
<div ng-if="loadingSSHLogs" style="text-align: center; padding: 20px; color: #888;">Loading recent SSH logs...</div> <div style="font-size: 1.25rem; font-weight: 700; color: #333;">Recent SSH Logs</div>
<div ng-if="errorSSHLogs" style="text-align: center; color: #d81b60; padding: 20px;">{$ errorSSHLogs $}</div> <button class="btn btn-sm btn-outline-primary" ng-click="refreshSSHLogs()" title="Refresh"><span style="font-size:1.2em;">&#x21bb;</span> Refresh</button>
<div ng-if="!loadingSSHLogs && sshLogs.length === 0 && !errorSSHLogs" style="text-align: center; color: #888; padding: 20px;">No recent SSH logs found.</div> </div>
<div ng-if="!loadingSSHLogs && sshLogs.length > 0" style="overflow-x: auto; max-height: 350px;"> <div ng-if="loadingSSHLogs" style="text-align:center; color:#888; padding:20px;">Loading...</div>
<table style="width: 100%; border-collapse: collapse; min-width: 320px;"> <div ng-if="errorSSHLogs" style="color:#e53935;">{$ errorSSHLogs $}</div>
<div ng-if="!loadingSSHLogs && !errorSSHLogs && sshLogs.length === 0" style="text-align:center; color:#888; padding:20px;">No recent SSH logs found.</div>
<div style="overflow-y:auto; flex:1; max-height: 480px;">
<table class="table table-striped table-hover" style="margin-bottom:0;">
<thead> <thead>
<tr style="background: #4c5fad; color: #fff;"> <tr style="background:#f1f3f6;">
<th style="padding: 12px 15px; border-radius: 8px 0 0 8px; text-align: left; font-weight: 600;">Timestamp</th> <th style="width: 160px;">Timestamp</th>
<th style="padding: 12px 15px; border-radius: 0 8px 8px 0; text-align: left; font-weight: 600;">Message</th> <th>Message</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr ng-repeat="log in sshLogs" style="background: #f8f9fa; border-bottom: 1px solid #e9ecef; transition: background 0.2s;"> <tr ng-repeat="log in sshLogs">
<td style="padding: 10px 15px; color: #555; white-space: nowrap;">{$ log.timestamp $}</td> <td style="padding: 8px 8px; color: #555;">{$ log.timestamp $}</td>
<td style="padding: 10px 15px; color: #333;">{$ log.message $}</td> <td style="padding: 8px 8px; font-family: monospace;">{$ log.message $}</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
{% endif %} {% endif %}
</div> </div>
<!-- End Dashboard Stats Section --> <!-- End Dashboard Stats Section -->

View File

@@ -612,16 +612,16 @@ def getRecentSSHLogs(request):
lines = output.split('\n') lines = output.split('\n')
logs = [] logs = []
for line in lines: for line in lines:
if 'sshd' in line: if not line.strip():
# Try to split into timestamp and message continue
parts = line.split() parts = line.split()
if len(parts) > 4: if len(parts) > 4:
timestamp = ' '.join(parts[:3]) timestamp = ' '.join(parts[:3])
message = ' '.join(parts[4:]) message = ' '.join(parts[4:])
else: else:
timestamp = '' timestamp = ''
message = line message = line
logs.append({'timestamp': timestamp, 'message': message, 'raw': line}) logs.append({'timestamp': timestamp, 'message': message, 'raw': line})
return HttpResponse(json.dumps({'logs': logs}), content_type='application/json') return HttpResponse(json.dumps({'logs': logs}), content_type='application/json')
except Exception as e: except Exception as e:
return HttpResponse(json.dumps({'error': str(e)}), content_type='application/json', status=500) return HttpResponse(json.dumps({'error': str(e)}), content_type='application/json', status=500)