Title: Upgrade to FutureOSS v1.1.0 with enterprise-grade security and deployment features
Key features implemented: - New RELEASE_v1.1.0.md with comprehensive release notes for security upgrades and new features - New firewall.py plugin implementing dynamic IP filtering, port management, and attack detection - New frp_proxy.py plugin for FRP-based internal network tunneling and proxy services - New ftp_server.py plugin providing secure file transfer with user management and access control - New multi_lang_deploy.py orchestrator supporting automated detection and deployment of Python/Node.js/Go/Java/PHP projects - New ops_toolbox.py with backup/recovery, health checks, and resource quota management - New security_gateway.py with API rate limiting, JWT authentication, audit logging, and circuit breaker protection - New HTML5/CSS3/JS-based webui replacing PHP templates with modern responsive design and real-time metrics - New manifest.json files for all plugins adding configuration schemas and dependency declarations - Updated .gitignore with refined ignore patterns for development environments - Modified core plugin manifests to include internationalization dependencies and enhanced configurations - Removed legacy PHP template files from webui frontend views - Enhanced plugin bridge, storage, signature verification with multilingual support and security improvements
This commit is contained in:
@@ -36,29 +36,54 @@ class WebUIServer:
|
||||
self.router.get(path, lambda req: self._render_page(path, req))
|
||||
|
||||
def _render_page(self, path: str, request):
|
||||
"""渲染页面布局+内容"""
|
||||
"""渲染页面布局 + 内容"""
|
||||
provider = self.pages.get(path)
|
||||
content = provider() if provider else ""
|
||||
|
||||
# 排序导航项(首页在前)
|
||||
sorted_nav = sorted(self.nav_items, key=lambda x: 0 if x.get('url') == '/' else 1)
|
||||
|
||||
variables = {
|
||||
"pageTitle": self.config.get("title", "FutureOSS"),
|
||||
"currentPage": path,
|
||||
"navItems": sorted_nav,
|
||||
"content": content
|
||||
# 构建导航项 HTML
|
||||
nav_html = ""
|
||||
icon_map = {
|
||||
'🏠': 'ri-home-4-line',
|
||||
'📊': 'ri-dashboard-line',
|
||||
'📋': 'ri-file-list-3-line',
|
||||
'🧩': 'ri-puzzle-line',
|
||||
'⚙️': 'ri-settings-3-line',
|
||||
'🔌': 'ri-plug-line',
|
||||
'📦': 'ri-box-3-line',
|
||||
'🌐': 'ri-global-line',
|
||||
}
|
||||
for item in sorted_nav:
|
||||
url = item.get('url', '#')
|
||||
is_active = 'active' if url == path else ''
|
||||
icon = item.get('icon', 'ri-dashboard-line')
|
||||
text = item.get('text', '')
|
||||
ri_icon = icon_map.get(icon, icon)
|
||||
title = text
|
||||
nav_html += f'''
|
||||
<a href="{url}" class="nav-item {is_active}" title="{title}">
|
||||
<i class="{ri_icon}"></i>
|
||||
</a>
|
||||
'''
|
||||
|
||||
php_file = self.frontend_dir / "views" / "layout.php"
|
||||
html = self._execute_php(str(php_file), variables)
|
||||
page_title = self.config.get("title", "FutureOSS")
|
||||
|
||||
# 读取 HTML 模板
|
||||
template_file = self.frontend_dir / "views" / "layout.html"
|
||||
with open(template_file, 'r', encoding='utf-8') as f:
|
||||
html_template = f.read()
|
||||
|
||||
html = html_template.replace('{{ pageTitle }}', page_title)
|
||||
html = html.replace('{{ navItems }}', nav_html)
|
||||
html = html.replace('{{ content }}', content)
|
||||
|
||||
return Response(
|
||||
status=200,
|
||||
headers={"Content-Type": "text/html; charset=utf-8"},
|
||||
body=html
|
||||
)
|
||||
|
||||
def _default_home_content(self) -> str:
|
||||
"""默认首页内容"""
|
||||
return """
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 仪表盘页面视图
|
||||
*/
|
||||
|
||||
$pageTitle = 'FutureOSS - 仪表盘';
|
||||
$currentPage = 'dashboard';
|
||||
|
||||
// 内容区直接包含仪表盘内容
|
||||
if (isset($dashboardContent)) {
|
||||
$content = $dashboardContent;
|
||||
} else {
|
||||
$content = '<div class="empty-state"><p>仪表盘内容加载中...</p></div>';
|
||||
}
|
||||
|
||||
// 复用 layout
|
||||
include __DIR__ . '/layout.php';
|
||||
110
store/@{FutureOSS}/webui/frontend/views/index.html
Normal file
110
store/@{FutureOSS}/webui/frontend/views/index.html
Normal file
@@ -0,0 +1,110 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>FutureOSS - 首页</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.1.0/remixicon.min.css">
|
||||
<link rel="stylesheet" href="/static/css/main.css">
|
||||
<style>
|
||||
.home-content {
|
||||
padding: 40px;
|
||||
}
|
||||
.welcome-banner {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 40px;
|
||||
border-radius: 16px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.welcome-banner h2 {
|
||||
font-size: 32px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.welcome-banner p {
|
||||
font-size: 18px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
.feature-card {
|
||||
background: white;
|
||||
padding: 24px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
.feature-card h3 {
|
||||
color: #333;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.feature-card p {
|
||||
color: #666;
|
||||
line-height: 1.6;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
<a href="/" class="nav-item active" title="首页">
|
||||
<i class="ri-home-4-line"></i>
|
||||
</a>
|
||||
<a href="/dashboard" class="nav-item" title="仪表盘">
|
||||
<i class="ri-dashboard-line"></i>
|
||||
</a>
|
||||
<a href="/plugins" class="nav-item" title="插件管理">
|
||||
<i class="ri-puzzle-line"></i>
|
||||
</a>
|
||||
<a href="/settings" class="nav-item" title="设置">
|
||||
<i class="ri-settings-3-line"></i>
|
||||
</a>
|
||||
</nav>
|
||||
<div class="sidebar-footer">
|
||||
<button class="settings-btn" title="设置">
|
||||
<i class="ri-settings-3-line"></i>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="content">
|
||||
<div class="content-body">
|
||||
<div class="home-content">
|
||||
<div class="welcome-banner">
|
||||
<h2>👋 欢迎使用 FutureOSS</h2>
|
||||
<p>一切皆为插件的轻量级框架</p>
|
||||
</div>
|
||||
|
||||
<div class="features-grid">
|
||||
<div class="feature-card">
|
||||
<h3><i class="ri-plug-line"></i> 插件化架构</h3>
|
||||
<p>所有功能皆可通过插件扩展,灵活定制您的系统</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3><i class="ri-shield-check-line"></i> 安全隔离</h3>
|
||||
<p>进程级沙箱保护,确保插件运行安全</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3><i class="ri-global-line"></i> 多语言支持</h3>
|
||||
<p>内置国际化框架,支持全球多种语言</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<h3><i class="ri-box-3-line"></i> 轻松部署</h3>
|
||||
<p>Docker 容器化部署,一键启动服务</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* 首页视图
|
||||
* 这是 webui 插件的默认首页
|
||||
* 其他插件可以替换或扩展此页面
|
||||
*/
|
||||
|
||||
$pageTitle = $config['title'] ?? 'FutureOSS';
|
||||
$currentPage = 'home';
|
||||
|
||||
// 默认导航项(其他插件可以添加更多)
|
||||
$navItems = [];
|
||||
|
||||
// 内容区(其他插件可以注入内容)
|
||||
$content = '<div class="empty-state"><p>暂无内容</p></div>';
|
||||
|
||||
include __DIR__ . '/layout.php';
|
||||
33
store/@{FutureOSS}/webui/frontend/views/layout.html
Normal file
33
store/@{FutureOSS}/webui/frontend/views/layout.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ pageTitle }}</title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.1.0/remixicon.min.css">
|
||||
<link rel="stylesheet" href="/static/css/main.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.13.3/dist/cdn.min.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
{{ navItems }}
|
||||
</nav>
|
||||
<div class="sidebar-footer">
|
||||
<button class="settings-btn" title="设置">
|
||||
<i class="ri-settings-3-line"></i>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="content">
|
||||
<div class="content-body">
|
||||
{{ content }}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,64 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?= htmlspecialchars($pageTitle ?? 'FutureOSS') ?></title>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.1.0/remixicon.min.css">
|
||||
<link rel="stylesheet" href="/static/css/main.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.13.3/dist/cdn.min.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<aside class="sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
<?php if (!empty($navItems)): ?>
|
||||
<?php foreach ($navItems as $item): ?>
|
||||
<?php
|
||||
$url = $item['url'] ?? '#';
|
||||
$isActive = ($currentPage ?? '') === $url;
|
||||
$icon = $item['icon'] ?? 'ri-dashboard-line';
|
||||
// 如果图标是 emoji,转换为 remixicon 类名
|
||||
$iconMap = [
|
||||
'🏠' => 'ri-home-4-line',
|
||||
'📊' => 'ri-dashboard-line',
|
||||
'📋' => 'ri-file-list-3-line',
|
||||
'🧩' => 'ri-puzzle-line',
|
||||
'⚙️' => 'ri-settings-3-line',
|
||||
'🔌' => 'ri-plug-line',
|
||||
'📦' => 'ri-box-3-line',
|
||||
'🌐' => 'ri-global-line',
|
||||
];
|
||||
$riIcon = $iconMap[$icon] ?? $icon;
|
||||
?>
|
||||
<a href="<?= htmlspecialchars($url) ?>"
|
||||
class="nav-item <?= $isActive ? 'active' : '' ?>"
|
||||
title="<?= htmlspecialchars($item['text'] ?? '') ?>">
|
||||
<i class="<?= htmlspecialchars($riIcon) ?>"></i>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</nav>
|
||||
<div class="sidebar-footer">
|
||||
<button class="settings-btn" title="设置">
|
||||
<i class="ri-settings-3-line"></i>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main class="content">
|
||||
<div class="content-body">
|
||||
<?php if (isset($content)): ?>
|
||||
<?= $content ?>
|
||||
<?php else: ?>
|
||||
<div class="empty-state">
|
||||
<p>暂无内容</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "webui",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"author": "FutureOSS",
|
||||
"description": "Web 控制台 - 使用 PHP 前端和 MySQL 数据库",
|
||||
"description": "Web 控制台 - 多语言支持/插件管理/安全配置/系统监控",
|
||||
"type": "webui"
|
||||
},
|
||||
"config": {
|
||||
@@ -11,10 +11,17 @@
|
||||
"args": {
|
||||
"port": 8080,
|
||||
"theme": "dark",
|
||||
"title": "FutureOSS"
|
||||
"title": "FutureOSS",
|
||||
"language": "zh-CN",
|
||||
"supported_languages": ["zh-CN", "en-US", "zh-TW", "ja-JP", "ko-KR", "fr-FR", "de-DE", "es-ES"],
|
||||
"session_timeout": 3600,
|
||||
"enable_2fa": false,
|
||||
"show_plugins": true,
|
||||
"show_security": true,
|
||||
"show_deployments": true
|
||||
}
|
||||
},
|
||||
"dependencies": ["http-api"],
|
||||
"dependencies": ["http-api", "i18n"],
|
||||
"permissions": ["*"],
|
||||
"frontend": "php",
|
||||
"database": {
|
||||
|
||||
Reference in New Issue
Block a user