Update mobile app with the same stat changes and remove rate limiting
This commit is contained in:
@@ -8,10 +8,7 @@ import {sshData, sshCredentials} from '../database/db/schema.js';
|
|||||||
import {eq, and} from 'drizzle-orm';
|
import {eq, and} from 'drizzle-orm';
|
||||||
import { statsLogger } from '../utils/logger.js';
|
import { statsLogger } from '../utils/logger.js';
|
||||||
|
|
||||||
// Rate limiting
|
// Rate limiting removed - not needed for internal application
|
||||||
const requestCounts = new Map<string, { count: number; resetTime: number }>();
|
|
||||||
const RATE_LIMIT_WINDOW = 15 * 60 * 1000; // 15 minutes
|
|
||||||
const RATE_LIMIT_MAX = 100; // 100 requests per window
|
|
||||||
|
|
||||||
// Connection pooling
|
// Connection pooling
|
||||||
interface PooledConnection {
|
interface PooledConnection {
|
||||||
@@ -271,27 +268,7 @@ type StatusEntry = {
|
|||||||
lastChecked: string;
|
lastChecked: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rate limiting middleware
|
// Rate limiting middleware removed
|
||||||
function rateLimitMiddleware(req: express.Request, res: express.Response, next: express.NextFunction) {
|
|
||||||
const clientId = req.ip || 'unknown';
|
|
||||||
const now = Date.now();
|
|
||||||
const clientData = requestCounts.get(clientId);
|
|
||||||
|
|
||||||
if (!clientData || now > clientData.resetTime) {
|
|
||||||
requestCounts.set(clientId, { count: 1, resetTime: now + RATE_LIMIT_WINDOW });
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clientData.count >= RATE_LIMIT_MAX) {
|
|
||||||
return res.status(429).json({
|
|
||||||
error: 'Too many requests',
|
|
||||||
retryAfter: Math.ceil((clientData.resetTime - now) / 1000)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
clientData.count++;
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Input validation middleware
|
// Input validation middleware
|
||||||
function validateHostId(req: express.Request, res: express.Response, next: express.NextFunction) {
|
function validateHostId(req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||||
@@ -318,7 +295,6 @@ app.use((req, res, next) => {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
app.use(express.json({ limit: '1mb' })); // Add request size limit
|
app.use(express.json({ limit: '1mb' })); // Add request size limit
|
||||||
app.use(rateLimitMiddleware);
|
|
||||||
|
|
||||||
|
|
||||||
const hostStatuses: Map<number, StatusEntry> = new Map();
|
const hostStatuses: Map<number, StatusEntry> = new Map();
|
||||||
|
|||||||
@@ -88,10 +88,23 @@ export function Server({
|
|||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error: any) {
|
||||||
console.error('Failed to fetch server status:', error);
|
console.error('Failed to fetch server status:', error);
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setServerStatus('offline');
|
// Handle different error types from the new backend
|
||||||
|
if (error?.response?.status === 503) {
|
||||||
|
// Server is offline
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else if (error?.response?.status === 504) {
|
||||||
|
// Timeout - treat as degraded
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else if (error?.response?.status === 404) {
|
||||||
|
// Host not found
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else {
|
||||||
|
// Other errors - treat as offline
|
||||||
|
setServerStatus('offline');
|
||||||
|
}
|
||||||
toast.error(t('serverStats.failedToFetchStatus'));
|
toast.error(t('serverStats.failedToFetchStatus'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,8 +203,21 @@ export function Server({
|
|||||||
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
||||||
const data = await getServerMetricsById(currentHostConfig.id);
|
const data = await getServerMetricsById(currentHostConfig.id);
|
||||||
setMetrics(data);
|
setMetrics(data);
|
||||||
} catch {
|
} catch (error: any) {
|
||||||
setServerStatus('offline');
|
// Handle different error types from the new backend
|
||||||
|
if (error?.response?.status === 503) {
|
||||||
|
// Server is offline
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else if (error?.response?.status === 504) {
|
||||||
|
// Timeout - treat as offline
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else if (error?.response?.status === 404) {
|
||||||
|
// Host not found
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else {
|
||||||
|
// Other errors - treat as offline
|
||||||
|
setServerStatus('offline');
|
||||||
|
}
|
||||||
setMetrics(null);
|
setMetrics(null);
|
||||||
} finally {
|
} finally {
|
||||||
setIsRefreshing(false);
|
setIsRefreshing(false);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {ButtonGroup} from "@/components/ui/button-group.tsx";
|
|||||||
import {Server, Terminal} from "lucide-react";
|
import {Server, Terminal} from "lucide-react";
|
||||||
import {useTabs} from "@/ui/Desktop/Navigation/Tabs/TabContext.tsx";
|
import {useTabs} from "@/ui/Desktop/Navigation/Tabs/TabContext.tsx";
|
||||||
import {getServerStatusById} from "@/ui/main-axios.ts";
|
import {getServerStatusById} from "@/ui/main-axios.ts";
|
||||||
import type { SSHHost, HostProps } from '../../../types/index.js';
|
import type { HostProps } from '../../../../types/index.js';
|
||||||
|
|
||||||
export function Host({host}: HostProps): React.ReactElement {
|
export function Host({host}: HostProps): React.ReactElement {
|
||||||
const {addTab} = useTabs();
|
const {addTab} = useTabs();
|
||||||
@@ -25,8 +25,18 @@ export function Host({host}: HostProps): React.ReactElement {
|
|||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error: any) {
|
||||||
if (!cancelled) setServerStatus('offline');
|
if (!cancelled) {
|
||||||
|
if (error?.response?.status === 503) {
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else if (error?.response?.status === 504) {
|
||||||
|
setServerStatus('degraded');
|
||||||
|
} else if (error?.response?.status === 404) {
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else {
|
||||||
|
setServerStatus('offline');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,34 +5,7 @@ import {ButtonGroup} from "@/components/ui/button-group.tsx";
|
|||||||
import {Server, Terminal} from "lucide-react";
|
import {Server, Terminal} from "lucide-react";
|
||||||
import {getServerStatusById} from "@/ui/main-axios.ts";
|
import {getServerStatusById} from "@/ui/main-axios.ts";
|
||||||
import {useTabs} from "@/ui/Mobile/Apps/Navigation/Tabs/TabContext.tsx";
|
import {useTabs} from "@/ui/Mobile/Apps/Navigation/Tabs/TabContext.tsx";
|
||||||
|
import type { HostProps } from '../../../../../types/index.js';
|
||||||
interface SSHHost {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
ip: string;
|
|
||||||
port: number;
|
|
||||||
username: string;
|
|
||||||
folder: string;
|
|
||||||
tags: string[];
|
|
||||||
pin: boolean;
|
|
||||||
authType: string;
|
|
||||||
password?: string;
|
|
||||||
key?: string;
|
|
||||||
keyPassword?: string;
|
|
||||||
keyType?: string;
|
|
||||||
enableTerminal: boolean;
|
|
||||||
enableTunnel: boolean;
|
|
||||||
enableFileManager: boolean;
|
|
||||||
defaultPath: string;
|
|
||||||
tunnelConnections: any[];
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface HostProps {
|
|
||||||
host: SSHHost;
|
|
||||||
onHostConnect: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Host({host, onHostConnect}: HostProps): React.ReactElement {
|
export function Host({host, onHostConnect}: HostProps): React.ReactElement {
|
||||||
const {addTab} = useTabs();
|
const {addTab} = useTabs();
|
||||||
@@ -52,8 +25,18 @@ export function Host({host, onHostConnect}: HostProps): React.ReactElement {
|
|||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error: any) {
|
||||||
if (!cancelled) setServerStatus('offline');
|
if (!cancelled) {
|
||||||
|
if (error?.response?.status === 503) {
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else if (error?.response?.status === 504) {
|
||||||
|
setServerStatus('degraded');
|
||||||
|
} else if (error?.response?.status === 404) {
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else {
|
||||||
|
setServerStatus('offline');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,34 +5,7 @@ import {ButtonGroup} from "@/components/ui/button-group.tsx";
|
|||||||
import {Server, Terminal} from "lucide-react";
|
import {Server, Terminal} from "lucide-react";
|
||||||
import {getServerStatusById} from "@/ui/main-axios.ts";
|
import {getServerStatusById} from "@/ui/main-axios.ts";
|
||||||
import {useTabs} from "@/ui/Mobile/Navigation/Tabs/TabContext.tsx";
|
import {useTabs} from "@/ui/Mobile/Navigation/Tabs/TabContext.tsx";
|
||||||
|
import type { HostProps } from '../../../../types/index.js';
|
||||||
interface SSHHost {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
ip: string;
|
|
||||||
port: number;
|
|
||||||
username: string;
|
|
||||||
folder: string;
|
|
||||||
tags: string[];
|
|
||||||
pin: boolean;
|
|
||||||
authType: string;
|
|
||||||
password?: string;
|
|
||||||
key?: string;
|
|
||||||
keyPassword?: string;
|
|
||||||
keyType?: string;
|
|
||||||
enableTerminal: boolean;
|
|
||||||
enableTunnel: boolean;
|
|
||||||
enableFileManager: boolean;
|
|
||||||
defaultPath: string;
|
|
||||||
tunnelConnections: any[];
|
|
||||||
createdAt: string;
|
|
||||||
updatedAt: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface HostProps {
|
|
||||||
host: SSHHost;
|
|
||||||
onHostConnect: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Host({host, onHostConnect}: HostProps): React.ReactElement {
|
export function Host({host, onHostConnect}: HostProps): React.ReactElement {
|
||||||
const {addTab} = useTabs();
|
const {addTab} = useTabs();
|
||||||
@@ -52,8 +25,18 @@ export function Host({host, onHostConnect}: HostProps): React.ReactElement {
|
|||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
setServerStatus(res?.status === 'online' ? 'online' : 'offline');
|
||||||
}
|
}
|
||||||
} catch {
|
} catch (error: any) {
|
||||||
if (!cancelled) setServerStatus('offline');
|
if (!cancelled) {
|
||||||
|
if (error?.response?.status === 503) {
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else if (error?.response?.status === 504) {
|
||||||
|
setServerStatus('degraded');
|
||||||
|
} else if (error?.response?.status === 404) {
|
||||||
|
setServerStatus('offline');
|
||||||
|
} else {
|
||||||
|
setServerStatus('offline');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user