Skip to content

Commit 794641f

Browse files
author
shihebaamrii
committed
feat: scaffold core application architecture and system monitoring dashboard with custom theme
1 parent 5d5adfb commit 794641f

18 files changed

Lines changed: 1337 additions & 678 deletions

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
public/Demo.mp4 filter=lfs diff=lfs merge=lfs -text
1+
public/DemoFinal.mp4 filter=lfs diff=lfs merge=lfs -text

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
- **Dynamic Log Monitors:** Interactive split-pane consoles for systemd services (`journalctl`) and Docker containers (`docker logs`).
12+
- **Telemetry Summary:** System telemetry grid in Dashboard displaying Hostname, OS Kernel Release, RAM space, and storage roots.
13+
- **Searchable Proxy Routes:** Search and filter functionality in Reverse Proxy manager, along with domain hyperlinks.
14+
- **Enhanced File Explorer:** Metadata inspector for binary assets, directory creation, recursive deletion, and direct `chmod` permission controller.
15+
16+
### Changed
17+
- **Visual Polish:** Redesigned layout with custom progress/gauge indicators and CSS status dots.
18+
- **Inline Demo Media:** Swapped static `.mp4` video redirect link in README for an auto-playing high-quality `.gif` preview.
19+
20+
### Security
21+
- **Strict Input Validation:** Added backend filters for all SSH filesystem APIs (preventing null-byte characters and path traversal injection).
22+
23+
## [1.0.0] - 2026-06-15
24+
25+
### Added
26+
- Initial release of Vessel.
27+
- Secure local SSH key management with OS-native credential vaults.
28+
- Basic telemetry gauges (CPU, RAM, Disk).
29+
- File explorer with remote editor.
30+
- Systemd and Docker supervisors.
31+
- Reverse proxy configs (Nginx/Caddy) and Certbot integrations.

README.md

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
</p>
1313

1414
<p align="center">
15-
<a href="https://github.com/shihebamrii/vessel/raw/main/public/Demo.mp4">
16-
🎥 Watch Demo
17-
</a>
15+
<img src="public/DemoFinal.gif" alt="Vessel Demo" width="800">
1816
</p>
1917

2018
---
@@ -72,6 +70,33 @@ Vessel leverages a secure, multi-threaded asynchronous architecture separating s
7270

7371
---
7472

73+
## 🆕 What's New (Latest Release Updates)
74+
75+
We've shipped significant upgrades since the initial release, focusing on host-level security, interactive log diagnostics, and deep dashboard telemetry.
76+
77+
### 🛡️ 1. Host-Level Security Hardening
78+
* **Input Sanitization:** Implemented strict backend validation across all filesystem endpoints (`read`, `write`, `delete`, `chmod`, `list`) to filter null-byte sequences and control characters.
79+
* **Command Injection Guard:** Prevent shell arguments expansion and path traversal vulnerabilities over the SSH connection.
80+
81+
### 📊 2. Dynamic Log Monitors (Split-Pane Layout)
82+
* **Real-time Diagnostics Console:** Both systemd Service Supervisor and Docker Container Supervisor now feature a high-fidelity split-pane dashboard with interactive log streams (`journalctl` and `docker logs`).
83+
* **Pulse Status Indicators:** Visual micro-animations showing running, inactive, or error states at a glance.
84+
* **Manual Log Fetching:** One-click telemetry retrieval directly inside the control plane.
85+
86+
### 📈 3. Extended System Telemetry Inventory
87+
* **Dashboard Summary:** A new dedicated system inventory panel displaying real-time Hostname, OS Kernel Release, Physical RAM capacity, and detailed Storage Root utilization.
88+
* **Custom Gauge Bars:** Replaced browser-default ranges with high-contrast, CSS-themed resource utilization visualizers.
89+
90+
### 🔍 4. Mapped Routes Search Engine
91+
* **Instant Filter Routing:** Added search indexing to the Reverse Proxy panel, letting you filter active Nginx/Caddy server blocks and local target ports in real-time.
92+
* **Inline Navigation Hub:** Clickable domain links with target external indicators to launch proxy sites directly from the dashboard.
93+
94+
### 📂 5. Refined Editor Workspace
95+
* **Binary File Protection:** Safe-fail dashboard preventing binary file corruption, showing file metadata (byte sizes, timestamps, access modes).
96+
* **Direct Permissions Tool:** An inline `chmod` permission configurator to toggle host access permissions instantly.
97+
98+
---
99+
75100
## 🛠️ Installation & Building
76101

77102
### 1. Download Pre-built Release

SECURITY.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Security Policy
2+
3+
## Supported Versions
4+
5+
We actively support and patch security issues for the following versions of Vessel:
6+
7+
| Version | Supported |
8+
| ------- | --------- |
9+
| >= 1.0.0 | :white_check_mark: |
10+
| < 1.0.0 | :x: |
11+
12+
## Reporting a Vulnerability
13+
14+
Vessel takes security very seriously. If you find a security vulnerability, please do NOT open a public GitHub issue. Instead, report it through the following process:
15+
16+
1. Send an email to the maintainer at security@shihebamrii.com (or open a private security advisory on GitHub if enabled).
17+
2. Include a detailed description of the vulnerability, steps to reproduce, and a proof-of-concept if possible.
18+
3. We will acknowledge receipt of your report within 48 hours and work with you to resolve the issue.
19+
20+
Please allow us reasonable time to investigate and fix the vulnerability before disclosing it publicly.

SUPPORT.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Support Policy
2+
3+
Thank you for using Vessel! Here is how you can get support, troubleshoot issues, or ask questions:
4+
5+
## 🔍 Frequently Asked Questions
6+
Before reaching out, check the [README](README.md) and open issues to see if your question or issue has already been discussed.
7+
8+
## 💬 GitHub Discussions
9+
For general questions, configuration help, and community discussions:
10+
- Visit [GitHub Discussions](https://github.com/shihebamrii/vessel/discussions) (if enabled).
11+
- Ask questions, share ideas, and showcase your VPS deployments.
12+
13+
## 🐛 Bug Reports & Feature Requests
14+
If you have found a bug or want to suggest a new feature:
15+
1. Search active issues to ensure it hasn't been reported.
16+
2. If it's a new issue, use the templates under the [Issues Page](https://github.com/shihebamrii/vessel/issues/new/choose).
17+
3. Provide as much context as possible (log outputs, operating system, and VPS configuration details).
18+
19+
## 🔒 Security Inquiries
20+
Do not report security vulnerabilities publicly. Please refer to our [Security Policy](SECURITY.md) for reporting guidelines.

public/Demo.mp4

-29.3 MB
Binary file not shown.

public/DemoFinal.gif

68.5 MB
Loading

public/DemoFinal.mp4

29.4 MB
Binary file not shown.

src-tauri/src/ssh.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ pub fn shell_escape(s: &str) -> String {
1111
format!("'{}'", escaped)
1212
}
1313

14+
pub fn validate_path(path: &str) -> Result<(), String> {
15+
if path.contains('\0') {
16+
return Err("Invalid path: contains null byte".to_string());
17+
}
18+
if path.contains('\n') || path.contains('\r') {
19+
return Err("Invalid path: contains newline characters".to_string());
20+
}
21+
Ok(())
22+
}
23+
1424
pub fn wrap_sudo(command: &str, password: Option<&str>) -> String {
1525
if let Some(pass) = password {
1626
let escaped_pass = shell_escape(pass);
@@ -248,6 +258,9 @@ pub fn disconnect_session(server_id: String) -> Result<(), String> {
248258

249259
#[tauri::command]
250260
pub async fn execute_command(server_id: String, command: String) -> Result<CommandResult, String> {
261+
if command.contains('\0') {
262+
return Err("Command contains null byte".to_string());
263+
}
251264
let handle_arc = {
252265
let sessions = get_sessions().lock().unwrap();
253266
sessions.get(&server_id).cloned()
@@ -311,6 +324,7 @@ pub async fn write_remote_file(
311324
path: String,
312325
base64_content: String,
313326
) -> Result<(), String> {
327+
validate_path(&path)?;
314328
let path_buf = std::path::Path::new(&path);
315329
let parent = path_buf.parent()
316330
.map(|p| p.to_string_lossy().into_owned())
@@ -374,6 +388,7 @@ pub async fn write_remote_file(
374388

375389
#[tauri::command]
376390
pub async fn read_remote_file(server_id: String, path: String) -> Result<String, String> {
391+
validate_path(&path)?;
377392
let escaped_path = shell_escape(&path);
378393
let cmd = format!("base64 {}", escaped_path);
379394

@@ -543,6 +558,7 @@ pub struct FileInfo {
543558

544559
#[tauri::command]
545560
pub async fn list_directory(server_id: String, path: String) -> Result<Vec<FileInfo>, String> {
561+
validate_path(&path)?;
546562
let escaped_path = shell_escape(&path);
547563

548564
let stat_script = format!(
@@ -589,6 +605,7 @@ pub async fn list_directory(server_id: String, path: String) -> Result<Vec<FileI
589605

590606
#[tauri::command]
591607
pub async fn chmod_file(server_id: String, path: String, mode: String) -> Result<(), String> {
608+
validate_path(&path)?;
592609
if !mode.chars().all(|c| c.is_digit(8)) || mode.is_empty() || mode.len() > 4 {
593610
return Err("Invalid permissions mode format".to_string());
594611
}
@@ -602,6 +619,7 @@ pub async fn chmod_file(server_id: String, path: String, mode: String) -> Result
602619

603620
#[tauri::command]
604621
pub async fn create_directory(server_id: String, path: String) -> Result<(), String> {
622+
validate_path(&path)?;
605623
let cmd = format!("mkdir -p {}", shell_escape(&path));
606624
let res = execute_command(server_id, cmd).await?;
607625
if res.exit_code != 0 {
@@ -612,6 +630,7 @@ pub async fn create_directory(server_id: String, path: String) -> Result<(), Str
612630

613631
#[tauri::command]
614632
pub async fn delete_file_or_directory(server_id: String, path: String, is_dir: bool) -> Result<(), String> {
633+
validate_path(&path)?;
615634
let cmd = if is_dir {
616635
format!("rm -rf {}", shell_escape(&path))
617636
} else {

0 commit comments

Comments
 (0)