diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..c181abf --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,75 @@ +name: Deploy Documentation + +on: + push: + branches: [ main ] + paths: + - 'apps/docs/**' + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Setup pnpm + uses: pnpm/action-setup@v3 + with: + version: 8 + + - name: Get pnpm store directory + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV + + - name: Setup pnpm cache + uses: actions/cache@v4 + with: + path: ${{ env.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build documentation + run: pnpm --filter nginx-love-docs build + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: apps/docs/.vitepress/dist + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + if: github.ref == 'refs/heads/main' + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore new file mode 100644 index 0000000..f95ea57 --- /dev/null +++ b/apps/docs/.gitignore @@ -0,0 +1 @@ +.vitepress/cache/ \ No newline at end of file diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts new file mode 100644 index 0000000..d61db82 --- /dev/null +++ b/apps/docs/.vitepress/config.ts @@ -0,0 +1,231 @@ +import { defineConfig } from 'vitepress' + +export default defineConfig({ + title: 'nginx-love Documentation', + description: 'Enterprise Nginx + ModSecurity Management Platform', + lang: 'en-US', + + // Theme appearance + appearance: 'dark', + + // SEO Configuration + head: [ + ['meta', { name: 'keywords', content: 'nginx, modsecurity, enterprise, security, web server, management platform' }], + ['meta', { name: 'author', content: 'nginx-love team' }], + ['meta', { property: 'og:title', content: 'nginx-love Documentation' }], + ['meta', { property: 'og:description', content: 'Enterprise Nginx + ModSecurity Management Platform' }], + ['meta', { property: 'og:type', content: 'website' }], + ['meta', { property: 'og:image', content: '/og-image.png' }], + ['meta', { name: 'twitter:card', content: 'summary_large_image' }], + ['meta', { name: 'twitter:title', content: 'nginx-love Documentation' }], + ['meta', { name: 'twitter:description', content: 'Enterprise Nginx + ModSecurity Management Platform' }], + ['meta', { name: 'twitter:image', content: '/og-image.png' }], + ['link', { rel: 'icon', href: '/favicon.ico' }] + ], + + themeConfig: { + // Enhanced navigation with dropdown menus + nav: [ + { text: 'Home', link: '/' }, + { + text: 'Documentation', + items: [ + { text: 'Getting Started', link: '/guide/introduction' }, + { text: 'Installation', link: '/guide/installation' }, + { text: 'Quick Start', link: '/guide/quick-start' } + ] + }, + { + text: 'Features', + items: [ + { text: 'Domain Management', link: '/guide/domains' }, + { text: 'SSL Management', link: '/guide/ssl' }, + { text: 'ModSecurity', link: '/guide/modsecurity' }, + { text: 'Performance', link: '/guide/performance' }, + { text: 'Log Analysis', link: '/guide/logs' } + ] + }, + { + text: 'API Reference', + items: [ + { text: 'Authentication', link: '/api/auth' }, + { text: 'Domains', link: '/api/domains' }, + { text: 'SSL', link: '/api/ssl' }, + { text: 'ModSecurity', link: '/api/modsecurity' }, + { text: 'Performance', link: '/api/performance' }, + { text: 'Logs', link: '/api/logs' }, + { text: 'Users', link: '/api/users' } + ] + }, + { + text: 'Resources', + items: [ + { text: 'Configuration', link: '/reference/configuration' }, + { text: 'Troubleshooting', link: '/reference/troubleshooting' }, + { text: 'FAQ', link: '/reference/faq' } + ] + } + ], + + // Enhanced sidebar with collapsible sections + sidebar: { + '/guide/': [ + { + text: 'Getting Started', + collapsed: false, + items: [ + { text: 'Introduction', link: '/guide/introduction' }, + { text: 'Installation', link: '/guide/installation' }, + { text: 'Quick Start', link: '/guide/quick-start' } + ] + }, + { + text: 'Core Features', + collapsed: false, + items: [ + { text: 'Domain Management', link: '/guide/domains' }, + { text: 'SSL Management', link: '/guide/ssl' }, + { text: 'ModSecurity', link: '/guide/modsecurity' }, + { text: 'Performance Monitoring', link: '/guide/performance' }, + { text: 'Log Analysis', link: '/guide/logs' } + ] + } + ], + '/api/': [ + { + text: 'Authentication', + collapsed: false, + items: [ + { text: 'Overview', link: '/api/auth' } + ] + }, + { + text: 'Domain Management', + collapsed: false, + items: [ + { text: 'API Reference', link: '/api/domains' } + ] + }, + { + text: 'SSL Management', + collapsed: false, + items: [ + { text: 'API Reference', link: '/api/ssl' } + ] + }, + { + text: 'Security', + collapsed: false, + items: [ + { text: 'ModSecurity', link: '/api/modsecurity' } + ] + }, + { + text: 'Monitoring', + collapsed: false, + items: [ + { text: 'Performance', link: '/api/performance' }, + { text: 'Logs', link: '/api/logs' } + ] + }, + { + text: 'User Management', + collapsed: false, + items: [ + { text: 'API Reference', link: '/api/users' } + ] + } + ], + '/reference/': [ + { + text: 'Reference', + collapsed: false, + items: [ + { text: 'Configuration', link: '/reference/configuration' }, + { text: 'Troubleshooting', link: '/reference/troubleshooting' }, + { text: 'FAQ', link: '/reference/faq' } + ] + } + ] + }, + + // Search configuration + search: { + provider: 'local', + }, + + // Edit link configuration + editLink: { + pattern: 'https://github.com/nginx-love/nginx-love/edit/main/apps/docs/:path', + text: 'Edit this page on GitHub' + }, + + // Enhanced social links + socialLinks: [ + { icon: 'github', link: 'https://github.com/TinyActive/nginx-love' }, + ], + + // Enhanced footer + footer: { + message: 'Released under the Apache 2.0 License.', + copyright: `Copyright © 2025-${new Date().getFullYear()} nginx-love` + }, + + // Custom theme colors + // Note: appearance is now set at the root level + + // Additional configurations + outline: { + label: 'Page navigation', + level: [2, 3] + }, + + // Table of contents + docFooter: { + prev: 'Previous page', + next: 'Next page' + }, + + // Return to top button + returnToTopLabel: 'Back to top', + + // External link indicator + externalLinkIcon: true, + + // Last updated text + lastUpdated: { + text: 'Last updated', + formatOptions: { + dateStyle: 'short', + timeStyle: 'medium' + } + } + }, + + // Markdown configuration + markdown: { + theme: { + light: 'github-light', + dark: 'github-dark' + }, + lineNumbers: true, + config: (md) => { + // Add any markdown-it plugins here + } + }, + + // Vite configuration + vite: { + define: { + __VUE_OPTIONS_API__: false + }, + server: { + host: true, + port: 5173 + }, + build: { + minify: 'terser', + chunkSizeWarningLimit: 1000 + } + } +}) \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/README.md b/apps/docs/.vitepress/theme/README.md new file mode 100644 index 0000000..f5346c0 --- /dev/null +++ b/apps/docs/.vitepress/theme/README.md @@ -0,0 +1,126 @@ +# nginx-love Documentation Theme + +This is a custom VitePress theme for the nginx-love documentation, built on top of the default VitePress theme with enterprise-ready enhancements. + +## Features + +- Enhanced navigation with dropdown menus +- Custom components for better content presentation +- Enterprise-ready color scheme and design +- Responsive design with mobile optimization +- Dark mode support +- Search functionality +- Custom styling for better readability + +## Custom Components + +### Badge + +Displays a small badge with different types for emphasis. + +```vue +Success +Warning +Danger +Info +``` + +### Callout + +Creates a callout box with different types for highlighting important information. + +```vue + + This is an informational callout. + + + + This is a warning callout. + + + + This is a danger callout. + + + + This is a tip callout. + +``` + +### Card + +Creates a styled card container for content. + +```vue + + This is the card content. + +``` + +### CardGrid + +Creates a responsive grid layout for cards. + +```vue + + Content 1 + Content 2 + Content 3 + +``` + +### FeatureGrid + +Creates a responsive grid layout for feature sections. + +```vue + + Description 1 + Description 2 + Description 3 + +``` + +### TeamSection + +Displays a team section with member information. + +```vue + +``` + +## Custom Styles + +The theme includes custom CSS variables and styles defined in: + +- `styles/variables.css` - CSS variables for colors, spacing, and typography +- `styles/custom.css` - Custom styles for components and layout + +## Configuration + +The theme is configured in `.vitepress/config.ts` with: + +- Enhanced navigation structure +- Search functionality +- Social links +- Footer configuration +- SEO optimizations +- Sidebar with collapsible sections + +## Usage + +To use this theme, ensure your VitePress configuration extends the default theme and imports the custom styles and components as shown in `index.ts`. \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/components.d.ts b/apps/docs/.vitepress/theme/components.d.ts new file mode 100644 index 0000000..4ca75b5 --- /dev/null +++ b/apps/docs/.vitepress/theme/components.d.ts @@ -0,0 +1,5 @@ +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/components/Badge.vue b/apps/docs/.vitepress/theme/components/Badge.vue new file mode 100644 index 0000000..a887d44 --- /dev/null +++ b/apps/docs/.vitepress/theme/components/Badge.vue @@ -0,0 +1,46 @@ + + + + + \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/components/Callout.vue b/apps/docs/.vitepress/theme/components/Callout.vue new file mode 100644 index 0000000..66fa65b --- /dev/null +++ b/apps/docs/.vitepress/theme/components/Callout.vue @@ -0,0 +1,113 @@ + + + + + \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/components/Card.vue b/apps/docs/.vitepress/theme/components/Card.vue new file mode 100644 index 0000000..7e2e389 --- /dev/null +++ b/apps/docs/.vitepress/theme/components/Card.vue @@ -0,0 +1,35 @@ + + + + + \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/components/CardGrid.vue b/apps/docs/.vitepress/theme/components/CardGrid.vue new file mode 100644 index 0000000..6091c4b --- /dev/null +++ b/apps/docs/.vitepress/theme/components/CardGrid.vue @@ -0,0 +1,20 @@ + + + \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/components/FeatureGrid.vue b/apps/docs/.vitepress/theme/components/FeatureGrid.vue new file mode 100644 index 0000000..90e47fa --- /dev/null +++ b/apps/docs/.vitepress/theme/components/FeatureGrid.vue @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/index.ts b/apps/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..2e89807 --- /dev/null +++ b/apps/docs/.vitepress/theme/index.ts @@ -0,0 +1,24 @@ +import DefaultTheme from 'vitepress/theme' +import type { Theme } from 'vitepress' +import './components.d.ts' +import './styles/variables.css' +import './styles/custom.css' + +// Custom components +import CustomBadge from './components/Badge.vue' +import Callout from './components/Callout.vue' +import Card from './components/Card.vue' +import CardGrid from './components/CardGrid.vue' +import FeatureGrid from './components/FeatureGrid.vue' + +export default { + extends: DefaultTheme, + enhanceApp({ app, router, siteData }) { + // Register custom components globally + app.component('CustomBadge', CustomBadge) + app.component('Callout', Callout) + app.component('Card', Card) + app.component('CardGrid', CardGrid) + app.component('FeatureGrid', FeatureGrid) + } +} satisfies Theme \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/styles/custom.css b/apps/docs/.vitepress/theme/styles/custom.css new file mode 100644 index 0000000..6f52283 --- /dev/null +++ b/apps/docs/.vitepress/theme/styles/custom.css @@ -0,0 +1,289 @@ +/** + * Custom Styles for nginx-love Documentation + * Using design tokens from the web application + */ + +/* Global Styles */ +body { + font-family: var(--enterprise-font-family); + font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11'; + letter-spacing: var(--tracking-normal, 0em); +} + +/* Enhanced Typography */ +.VPDoc h1 { + font-weight: 700; + letter-spacing: -0.02em; + margin-bottom: 1.5rem; +} + +.VPDoc h2 { + font-weight: 600; + letter-spacing: -0.01em; + margin-top: 2.5rem; + margin-bottom: 1rem; + padding-bottom: 0.5rem; + border-bottom: 1px solid var(--vp-c-border); +} + +.VPDoc h3 { + font-weight: 600; + margin-top: 2rem; + margin-bottom: 0.75rem; +} + +/* Enhanced Code Blocks */ +.vp-code-group .tabs { + border-radius: var(--enterprise-radius-lg) var(--enterprise-radius-lg) 0 0; + border: 1px solid var(--vp-c-border); + border-bottom: none; +} + +div[class*='language-'] { + border-radius: 0 0 var(--enterprise-radius-lg) var(--enterprise-radius-lg); + border: 1px solid var(--vp-c-border); + border-top: none; + margin: 0; +} + +/* Custom Badge Styles */ +.custom-badge { + display: inline-flex; + align-items: center; + padding: 0.25rem 0.5rem; + font-size: 0.75rem; + font-weight: 500; + border-radius: var(--enterprise-radius-sm); + background-color: var(--enterprise-primary); + color: white; + margin-left: 0.5rem; +} + +.custom-badge.success { + background-color: var(--enterprise-success); +} + +.custom-badge.warning { + background-color: var(--enterprise-warning); + color: #000; +} + +.custom-badge.danger { + background-color: var(--enterprise-danger); +} + +.custom-badge.info { + background-color: var(--enterprise-info); +} + +/* Enhanced Callout Styles */ +.vp-callout { + border-radius: var(--enterprise-radius-lg); + border-left: 4px solid; + margin: 1rem 0; + padding: 1rem 1.25rem; + background-color: var(--vp-c-bg-soft); +} + +.vp-callout.info { + border-color: var(--enterprise-info); + background-color: oklch(0.6898 0.1581 290.4107 / 0.1); +} + +.vp-callout.warning { + border-color: var(--enterprise-warning); + background-color: oklch(0.8816 0.0276 93.1280 / 0.1); +} + +.vp-callout.danger { + border-color: var(--enterprise-danger); + background-color: oklch(0.1908 0.0020 106.5859 / 0.1); +} + +.vp-callout.tip { + border-color: var(--enterprise-success); + background-color: oklch(0.5583 0.1276 42.9956 / 0.1); +} + +/* Custom Card Styles */ +.custom-card { + border: 1px solid var(--vp-c-border); + border-radius: var(--enterprise-radius-lg); + padding: 1.5rem; + background-color: var(--vp-c-bg-elv); + box-shadow: var(--shadow-sm); + transition: all 0.3s ease; +} + +.custom-card:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-md); +} + +.custom-card h3 { + margin-top: 0; + color: var(--enterprise-primary); +} + +/* Enhanced Navigation */ +.VPNav { + border-bottom: 1px solid var(--vp-c-border); +} + +.VPNavBarTitle { + font-weight: 600; + font-size: 1.1rem; +} + +.VPNavBarMenu .VPNavBarMenuLink { + font-weight: 500; + padding: 0 0.75rem; + transition: color 0.2s ease; +} + +.VPNavBarMenu .VPNavBarMenuLink:hover { + color: var(--enterprise-primary); +} + +/* Enhanced Sidebar */ +.VPSidebar { + border-right: 1px solid var(--vp-c-border); +} + +.VPSidebarItem { + border-radius: var(--enterprise-radius-md); + margin: 0.25rem 0.5rem; + padding: 0.25rem 0.75rem; + transition: all 0.2s ease; +} + +.VPSidebarItem:hover { + background-color: var(--vp-c-bg-soft); +} + +.VPSidebarItem.active { + background-color: oklch(0.6171 0.1375 39.0427 / 0.1); + color: var(--enterprise-primary); + font-weight: 500; +} + +/* Custom Grid Layout */ +.feature-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 1.5rem; + margin: 2rem 0; +} + +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + gap: 1rem; + margin: 1.5rem 0; +} + +/* Enhanced Buttons */ +.VPButton { + border-radius: var(--enterprise-radius-md); + font-weight: 500; + padding: 0.5rem 1rem; + transition: all 0.2s ease; +} + +.VPButton.primary { + background-color: var(--enterprise-primary); + border-color: var(--enterprise-primary); +} + +.VPButton.primary:hover { + background-color: var(--enterprise-primary-hover); + border-color: var(--enterprise-primary-hover); + transform: translateY(-1px); +} + +/* Custom Table Styles */ +.VPDoc table { + border-radius: var(--enterprise-radius-lg); + overflow: hidden; + border: 1px solid var(--vp-c-border); + margin: 1.5rem 0; +} + +.VPDoc table th { + background-color: var(--vp-c-bg-soft); + font-weight: 600; + padding: 0.75rem 1rem; + border-bottom: 2px solid var(--vp-c-border); +} + +.VPDoc table td { + padding: 0.75rem 1rem; + border-bottom: 1px solid var(--vp-c-border-light); +} + +.VPDoc table tr:last-child td { + border-bottom: none; +} + +/* Enhanced Footer */ +.VPFooter { + border-top: 1px solid var(--vp-c-border); + background-color: var(--vp-c-bg-soft); +} + +/* Custom Animations */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +.fade-in-up { + animation: fadeInUp 0.6s ease-out; +} + +/* Responsive Design */ +@media (max-width: 768px) { + .feature-grid { + grid-template-columns: 1fr; + gap: 1rem; + } + + .card-grid { + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + } +} + +/* Dark Mode Specific Adjustments */ +.dark .custom-card { + box-shadow: var(--shadow-md); +} + +.dark .custom-card:hover { + box-shadow: var(--shadow-lg); +} + +/* Custom Scrollbar */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: var(--vp-c-bg-alt); +} + +::-webkit-scrollbar-thumb { + background: var(--vp-c-border); + border-radius: var(--enterprise-radius-sm); +} + +::-webkit-scrollbar-thumb:hover { + background: var(--vp-c-border-dark); +} \ No newline at end of file diff --git a/apps/docs/.vitepress/theme/styles/variables.css b/apps/docs/.vitepress/theme/styles/variables.css new file mode 100644 index 0000000..346d9f7 --- /dev/null +++ b/apps/docs/.vitepress/theme/styles/variables.css @@ -0,0 +1,115 @@ +/** + * CSS Variables for nginx-love Documentation + * Using design tokens from the web application + */ + +:root { + /* Brand Colors - Using web app primary color */ + --vp-c-brand: oklch(0.6171 0.1375 39.0427); + --vp-c-brand-light: oklch(0.7171 0.1375 39.0427); + --vp-c-brand-lighter: oklch(0.8171 0.1375 39.0427); + --vp-c-brand-dark: oklch(0.5171 0.1375 39.0427); + --vp-c-brand-darker: oklch(0.4171 0.1375 39.0427); + + /* Background Colors - Using web app background */ + --vp-c-bg: oklch(0.9818 0.0054 95.0986); + --vp-c-bg-alt: oklch(0.9663 0.0080 98.8792); + --vp-c-bg-elv: oklch(0.9818 0.0054 95.0986); + --vp-c-bg-soft: oklch(0.9341 0.0153 90.2390); + + /* Text Colors - Using web app foreground */ + --vp-c-text-1: oklch(0.3438 0.0269 95.7226); + --vp-c-text-2: oklch(0.6059 0.0075 97.4233); + --vp-c-text-3: oklch(0.7621 0.0156 98.3528); + --vp-c-text-4: oklch(0.8847 0.0069 97.3627); + + /* Border Colors - Using web app border */ + --vp-c-border: oklch(0.8847 0.0069 97.3627); + --vp-c-border-light: oklch(0.9245 0.0138 92.9892); + --vp-c-border-lighter: oklch(0.9341 0.0153 90.2390); + --vp-c-border-dark: oklch(0.7621 0.0156 98.3528); + + /* Shadow Colors - Using web app shadow */ + --vp-c-shadow: oklch(0 0 0 / 0.1); + --vp-c-shadow-light: oklch(0 0 0 / 0.05); + --vp-c-shadow-lighter: oklch(0 0 0 / 0.03); + + /* Custom Enterprise Colors - Using web app colors */ + --enterprise-primary: oklch(0.6171 0.1375 39.0427); + --enterprise-primary-hover: oklch(0.5171 0.1375 39.0427); + --enterprise-primary-dark: oklch(0.2679 0.0036 106.6427); + --enterprise-secondary: oklch(0.9245 0.0138 92.9892); + --enterprise-success: oklch(0.5583 0.1276 42.9956); + --enterprise-warning: oklch(0.8816 0.0276 93.1280); + --enterprise-danger: oklch(0.1908 0.0020 106.5859); + --enterprise-info: oklch(0.6898 0.1581 290.4107); + + /* Custom Spacing - Using web app spacing */ + --enterprise-spacing-xs: calc(var(--spacing) * 1); + --enterprise-spacing-sm: calc(var(--spacing) * 2); + --enterprise-spacing-md: calc(var(--spacing) * 4); + --enterprise-spacing-lg: calc(var(--spacing) * 6); + --enterprise-spacing-xl: calc(var(--spacing) * 8); + --enterprise-spacing-xxl: calc(var(--spacing) * 12); + + /* Custom Border Radius - Using web app radius */ + --enterprise-radius-sm: var(--radius-sm); + --enterprise-radius-md: var(--radius-md); + --enterprise-radius-lg: var(--radius-lg); + --enterprise-radius-xl: var(--radius-xl); + + /* Custom Typography - Using web app fonts */ + --enterprise-font-family: var(--font-sans); + --enterprise-font-mono: var(--font-mono); + --enterprise-font-serif: var(--font-serif); + + /* Web App Design Tokens */ + --radius: 0.5rem; + --spacing: 0.25rem; + --font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + --font-serif: ui-serif, Georgia, Cambria, "Times New Roman", Times, serif; +} + +/* Dark Theme Variables - Using web app dark theme */ +.dark { + /* Brand Colors */ + --vp-c-brand: oklch(0.6724 0.1308 38.7559); + --vp-c-brand-light: oklch(0.7724 0.1308 38.7559); + --vp-c-brand-lighter: oklch(0.8724 0.1308 38.7559); + --vp-c-brand-dark: oklch(0.5724 0.1308 38.7559); + --vp-c-brand-darker: oklch(0.4724 0.1308 38.7559); + + /* Background Colors */ + --vp-c-bg: oklch(0.2679 0.0036 106.6427); + --vp-c-bg-alt: oklch(0.2357 0.0024 67.7077); + --vp-c-bg-elv: oklch(0.3085 0.0035 106.6039); + --vp-c-bg-soft: oklch(0.2213 0.0038 106.7070); + + /* Text Colors */ + --vp-c-text-1: oklch(0.8074 0.0142 93.0137); + --vp-c-text-2: oklch(0.7713 0.0169 99.0657); + --vp-c-text-3: oklch(0.4336 0.0113 100.2195); + --vp-c-text-4: oklch(0.3618 0.0101 106.8928); + + /* Border Colors */ + --vp-c-border: oklch(0.3618 0.0101 106.8928); + --vp-c-border-light: oklch(0.4336 0.0113 100.2195); + --vp-c-border-lighter: oklch(0.2213 0.0038 106.7070); + --vp-c-border-dark: oklch(0.4954 0.0125 106.8928); + + /* Shadow Colors */ + --vp-c-shadow: oklch(0 0 0 / 0.3); + --vp-c-shadow-light: oklch(0 0 0 / 0.2); + --vp-c-shadow-lighter: oklch(0 0 0 / 0.1); + + /* Custom Enterprise Colors (Dark Theme) */ + --enterprise-primary: oklch(0.6724 0.1308 38.7559); + --enterprise-primary-hover: oklch(0.5724 0.1308 38.7559); + --enterprise-primary-dark: oklch(0.3085 0.0035 106.6039); + --enterprise-secondary: oklch(0.9818 0.0054 95.0986); + --enterprise-success: oklch(0.5583 0.1276 42.9956); + --enterprise-warning: oklch(0.8816 0.0276 93.1280); + --enterprise-danger: oklch(0.6368 0.2078 25.3313); + --enterprise-info: oklch(0.6898 0.1581 290.4107); +} \ No newline at end of file diff --git a/apps/docs/api/auth.md b/apps/docs/api/auth.md new file mode 100644 index 0000000..da5dc30 --- /dev/null +++ b/apps/docs/api/auth.md @@ -0,0 +1,152 @@ +# Authentication API + +The authentication API provides endpoints for user authentication and authorization. + +## Base URL + +``` +https://your-domain.com/api/auth +``` + +## Endpoints + +### Login + +Authenticate a user and receive a JWT token. + +**Endpoint:** `POST /login` + +**Request Body:** +```json +{ + "email": "user@example.com", + "password": "password123" +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "user": { + "id": 1, + "email": "user@example.com", + "name": "John Doe", + "role": "admin" + } + } +} +``` + +### Logout + +Invalidate the current session. + +**Endpoint:** `POST /logout` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Logged out successfully" +} +``` + +### Refresh Token + +Refresh an existing JWT token. + +**Endpoint:** `POST /refresh` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + } +} +``` + +### Register + +Create a new user account. + +**Endpoint:** `POST /register` + +**Request Body:** +```json +{ + "name": "John Doe", + "email": "user@example.com", + "password": "password123", + "confirmPassword": "password123" +} +``` + +**Response:** +```json +{ + "success": true, + "message": "User registered successfully" +} +``` + +### Get Current User + +Get information about the currently authenticated user. + +**Endpoint:** `GET /me` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "name": "John Doe", + "email": "user@example.com", + "role": "admin", + "createdAt": "2023-01-01T00:00:00Z" + } +} +``` + +## Error Responses + +All endpoints may return the following error responses: + +### 401 Unauthorized +```json +{ + "success": false, + "error": "Invalid credentials" +} +``` + +### 403 Forbidden +```json +{ + "success": false, + "error": "Insufficient permissions" +} +``` + +### 422 Validation Error +```json +{ + "success": false, + "error": "Validation failed", + "details": { + "email": "Email is required", + "password": "Password must be at least 8 characters" + } +} \ No newline at end of file diff --git a/apps/docs/api/domains.md b/apps/docs/api/domains.md new file mode 100644 index 0000000..e3beb8d --- /dev/null +++ b/apps/docs/api/domains.md @@ -0,0 +1,209 @@ +# Domains API + +The domains API provides endpoints for managing Nginx domains. + +## Base URL + +``` +https://your-domain.com/api/domains +``` + +## Endpoints + +### List Domains + +Get a list of all domains. + +**Endpoint:** `GET /` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `search` (string): Search term + +**Response:** +```json +{ + "success": true, + "data": { + "domains": [ + { + "id": 1, + "name": "example.com", + "documentRoot": "/var/www/example.com", + "listenPort": 80, + "serverAlias": ["www.example.com"], + "sslEnabled": false, + "modSecurityEnabled": true, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +### Get Domain + +Get a specific domain by ID. + +**Endpoint:** `GET /:id` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "name": "example.com", + "documentRoot": "/var/www/example.com", + "listenPort": 80, + "serverAlias": ["www.example.com"], + "sslEnabled": false, + "modSecurityEnabled": true, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +### Create Domain + +Create a new domain. + +**Endpoint:** `POST /` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "name": "example.com", + "documentRoot": "/var/www/example.com", + "listenPort": 80, + "serverAlias": ["www.example.com"], + "sslEnabled": false, + "modSecurityEnabled": true +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "name": "example.com", + "documentRoot": "/var/www/example.com", + "listenPort": 80, + "serverAlias": ["www.example.com"], + "sslEnabled": false, + "modSecurityEnabled": true, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +### Update Domain + +Update an existing domain. + +**Endpoint:** `PUT /:id` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "name": "example.com", + "documentRoot": "/var/www/example.com", + "listenPort": 80, + "serverAlias": ["www.example.com"], + "sslEnabled": false, + "modSecurityEnabled": true +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "name": "example.com", + "documentRoot": "/var/www/example.com", + "listenPort": 80, + "serverAlias": ["www.example.com"], + "sslEnabled": false, + "modSecurityEnabled": true, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +### Delete Domain + +Delete a domain. + +**Endpoint:** `DELETE /:id` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Domain deleted successfully" +} +``` + +### Reload Nginx + +Reload Nginx configuration. + +**Endpoint:** `POST /reload` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Nginx reloaded successfully" +} +``` + +## Error Responses + +All endpoints may return the following error responses: + +### 404 Not Found +```json +{ + "success": false, + "error": "Domain not found" +} +``` + +### 422 Validation Error +```json +{ + "success": false, + "error": "Validation failed", + "details": { + "name": "Domain name is required", + "documentRoot": "Document root is required" + } +} \ No newline at end of file diff --git a/apps/docs/api/logs.md b/apps/docs/api/logs.md new file mode 100644 index 0000000..6c429cc --- /dev/null +++ b/apps/docs/api/logs.md @@ -0,0 +1,346 @@ +# Logs API + +The logs API provides endpoints for accessing and analyzing Nginx logs. + +## Base URL + +``` +https://your-domain.com/api/logs +``` + +## Endpoints + +### Get Access Logs + +Get access logs for a domain. + +**Endpoint:** `GET /domains/:domainId/access` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `startDate` (string): Start date (ISO 8601) +- `endDate` (string): End date (ISO 8601) +- `statusCode` (number): Filter by status code +- `ipAddress` (string): Filter by IP address +- `url` (string): Filter by URL pattern +- `method` (string): Filter by HTTP method + +**Response:** +```json +{ + "success": true, + "data": { + "logs": [ + { + "id": 1, + "timestamp": "2023-01-01T12:00:00Z", + "ipAddress": "192.168.1.1", + "method": "GET", + "url": "/", + "protocol": "HTTP/1.1", + "statusCode": 200, + "responseSize": 1024, + "referrer": "https://example.com", + "userAgent": "Mozilla/5.0...", + "responseTime": 150 + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +### Get Error Logs + +Get error logs for a domain. + +**Endpoint:** `GET /domains/:domainId/error` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `startDate` (string): Start date (ISO 8601) +- `endDate` (string): End date (ISO 8601) +- `level` (string): Filter by log level (error, warn, info, debug) + +**Response:** +```json +{ + "success": true, + "data": { + "logs": [ + { + "id": 1, + "timestamp": "2023-01-01T12:00:00Z", + "level": "error", + "message": "Connection refused to upstream server", + "context": { + "upstream": "127.0.0.1:8080", + "host": "example.com", + "request": "GET /api/data HTTP/1.1" + } + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +### Get Log Statistics + +Get log statistics for a domain. + +**Endpoint:** `GET /domains/:domainId/stats` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `period` (string): Time period (1h, 24h, 7d, 30d) + +**Response:** +```json +{ + "success": true, + "data": { + "period": "24h", + "totalRequests": 10000, + "uniqueVisitors": 1000, + "averageResponseTime": 150, + "errorRate": 0.05, + "topUrls": [ + { + "url": "/", + "requests": 1000, + "percentage": 10 + } + ], + "topStatusCodes": [ + { + "code": 200, + "count": 8000, + "percentage": 80 + } + ], + "topUserAgents": [ + { + "userAgent": "Mozilla/5.0...", + "requests": 5000, + "percentage": 50 + } + ], + "topReferrers": [ + { + "referrer": "https://google.com", + "requests": 1000, + "percentage": 10 + } + ] + } +} +``` + +### Search Logs + +Search logs for a domain. + +**Endpoint:** `POST /domains/:domainId/search` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "query": "error", + "fields": ["message", "url"], + "startDate": "2023-01-01T00:00:00Z", + "endDate": "2023-01-02T00:00:00Z", + "limit": 20 +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "logs": [ + { + "id": 1, + "timestamp": "2023-01-01T12:00:00Z", + "level": "error", + "message": "Connection refused to upstream server", + "context": { + "upstream": "127.0.0.1:8080", + "host": "example.com", + "request": "GET /api/data HTTP/1.1" + } + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +### Export Logs + +Export logs for a domain. + +**Endpoint:** `POST /domains/:domainId/export` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "type": "access", + "startDate": "2023-01-01T00:00:00Z", + "endDate": "2023-01-02T00:00:00Z", + "format": "csv", + "filters": { + "statusCode": [200, 404, 500], + "method": ["GET", "POST"] + } +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "downloadUrl": "https://your-domain.com/api/downloads/log-export-123.csv", + "expiresAt": "2023-01-02T00:00:00Z" + } +} +``` + +### Create Log Alert + +Create a log-based alert for a domain. + +**Endpoint:** `POST /domains/:domainId/alerts` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "name": "High Error Rate Alert", + "condition": "errorRate", + "operator": "greaterThan", + "threshold": 0.1, + "duration": 300, + "notificationMethod": "email", + "notificationTarget": "admin@example.com", + "enabled": true +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "name": "High Error Rate Alert", + "condition": "errorRate", + "operator": "greaterThan", + "threshold": 0.1, + "duration": 300, + "notificationMethod": "email", + "notificationTarget": "admin@example.com", + "enabled": true, + "createdAt": "2023-01-01T00:00:00Z" + } +} +``` + +### List Log Alerts + +Get a list of log alerts for a domain. + +**Endpoint:** `GET /domains/:domainId/alerts` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "alerts": [ + { + "id": 1, + "name": "High Error Rate Alert", + "condition": "errorRate", + "operator": "greaterThan", + "threshold": 0.1, + "duration": 300, + "notificationMethod": "email", + "notificationTarget": "admin@example.com", + "enabled": true, + "createdAt": "2023-01-01T00:00:00Z" + } + ] + } +} +``` + +### Delete Log Alert + +Delete a log alert. + +**Endpoint:** `DELETE /domains/:domainId/alerts/:alertId` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Alert deleted successfully" +} +``` + +## Error Responses + +All endpoints may return the following error responses: + +### 404 Not Found +```json +{ + "success": false, + "error": "Domain not found" +} +``` + +### 422 Validation Error +```json +{ + "success": false, + "error": "Validation failed", + "details": { + "query": "Search query is required", + "startDate": "Start date is required" + } +} \ No newline at end of file diff --git a/apps/docs/api/modsecurity.md b/apps/docs/api/modsecurity.md new file mode 100644 index 0000000..900a316 --- /dev/null +++ b/apps/docs/api/modsecurity.md @@ -0,0 +1,318 @@ +# ModSecurity API + +The ModSecurity API provides endpoints for managing ModSecurity rules and configurations. + +## Base URL + +``` +https://your-domain.com/api/modsecurity +``` + +## Endpoints + +### List Rule Sets + +Get a list of all ModSecurity rule sets. + +**Endpoint:** `GET /rule-sets` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `search` (string): Search term + +**Response:** +```json +{ + "success": true, + "data": { + "ruleSets": [ + { + "id": 1, + "name": "OWASP CRS", + "version": "3.3.0", + "paranoiaLevel": 1, + "enabled": true, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +### Get Domain ModSecurity Settings + +Get ModSecurity settings for a specific domain. + +**Endpoint:** `GET /domains/:domainId` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "domainId": 1, + "enabled": true, + "ruleSetId": 1, + "paranoiaLevel": 1, + "customRules": [ + { + "id": 1, + "ruleId": 100001, + "message": "Custom rule example", + "action": "deny", + "expression": "@rx attack", + "enabled": true + } + ], + "exclusions": [ + { + "id": 1, + "ruleId": 941100, + "uri": "/api/sensitive-endpoint", + "method": "POST", + "ipAddress": null + } + ] + } +} +``` + +### Update Domain ModSecurity Settings + +Update ModSecurity settings for a domain. + +**Endpoint:** `PUT /domains/:domainId` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "enabled": true, + "ruleSetId": 1, + "paranoiaLevel": 1 +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "domainId": 1, + "enabled": true, + "ruleSetId": 1, + "paranoiaLevel": 1 + } +} +``` + +### Add Custom Rule + +Add a custom ModSecurity rule to a domain. + +**Endpoint:** `POST /domains/:domainId/rules` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "ruleId": 100001, + "message": "Custom rule example", + "action": "deny", + "expression": "@rx attack", + "enabled": true +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "ruleId": 100001, + "message": "Custom rule example", + "action": "deny", + "expression": "@rx attack", + "enabled": true + } +} +``` + +### Update Custom Rule + +Update a custom ModSecurity rule. + +**Endpoint:** `PUT /domains/:domainId/rules/:ruleId` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "message": "Updated rule message", + "action": "deny", + "expression": "@rx updated-attack", + "enabled": false +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "ruleId": 100001, + "message": "Updated rule message", + "action": "deny", + "expression": "@rx updated-attack", + "enabled": false + } +} +``` + +### Delete Custom Rule + +Delete a custom ModSecurity rule. + +**Endpoint:** `DELETE /domains/:domainId/rules/:ruleId` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Rule deleted successfully" +} +``` + +### Add Rule Exclusion + +Add a rule exclusion for a domain. + +**Endpoint:** `POST /domains/:domainId/exclusions` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "ruleId": 941100, + "uri": "/api/sensitive-endpoint", + "method": "POST", + "ipAddress": null +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "ruleId": 941100, + "uri": "/api/sensitive-endpoint", + "method": "POST", + "ipAddress": null + } +} +``` + +### Delete Rule Exclusion + +Delete a rule exclusion. + +**Endpoint:** `DELETE /domains/:domainId/exclusions/:exclusionId` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Exclusion deleted successfully" +} +``` + +### Get ModSecurity Logs + +Get ModSecurity logs for a domain. + +**Endpoint:** `GET /domains/:domainId/logs` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `startDate` (string): Start date (ISO 8601) +- `endDate` (string): End date (ISO 8601) +- `ruleId` (number): Filter by rule ID +- `action` (string): Filter by action (deny, allow, log) + +**Response:** +```json +{ + "success": true, + "data": { + "logs": [ + { + "id": 1, + "timestamp": "2023-01-01T12:00:00Z", + "ruleId": 941100, + "message": "XSS Attack Detected", + "action": "deny", + "ipAddress": "192.168.1.1", + "uri": "/api/test", + "method": "POST", + "data": "request data" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +## Error Responses + +All endpoints may return the following error responses: + +### 404 Not Found +```json +{ + "success": false, + "error": "Domain not found" +} +``` + +### 422 Validation Error +```json +{ + "success": false, + "error": "Validation failed", + "details": { + "ruleId": "Rule ID is required", + "expression": "Rule expression is required" + } +} \ No newline at end of file diff --git a/apps/docs/api/performance.md b/apps/docs/api/performance.md new file mode 100644 index 0000000..04c0edb --- /dev/null +++ b/apps/docs/api/performance.md @@ -0,0 +1,318 @@ +# Performance API + +The performance API provides endpoints for accessing performance metrics and monitoring data. + +## Base URL + +``` +https://your-domain.com/api/performance +``` + +## Endpoints + +### Get Performance Metrics + +Get performance metrics for a domain. + +**Endpoint:** `GET /domains/:domainId/metrics` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `startDate` (string): Start date (ISO 8601) +- `endDate` (string): End date (ISO 8601) +- `interval` (string): Data interval (1m, 5m, 1h, 1d) +- `metrics` (string): Comma-separated list of metrics + +**Response:** +```json +{ + "success": true, + "data": { + "metrics": [ + { + "timestamp": "2023-01-01T12:00:00Z", + "requestRate": 100, + "responseTime": 150, + "errorRate": 0.05, + "activeConnections": 50, + "incomingTraffic": 1024, + "outgoingTraffic": 2048 + } + ] + } +} +``` + +### Get Performance Summary + +Get a performance summary for a domain. + +**Endpoint:** `GET /domains/:domainId/summary` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `period` (string): Time period (1h, 24h, 7d, 30d) + +**Response:** +```json +{ + "success": true, + "data": { + "period": "24h", + "requestRate": { + "avg": 100, + "min": 50, + "max": 200 + }, + "responseTime": { + "avg": 150, + "min": 50, + "max": 500, + "p50": 120, + "p95": 300, + "p99": 450 + }, + "errorRate": { + "avg": 0.05, + "min": 0, + "max": 0.1 + }, + "activeConnections": { + "avg": 50, + "min": 20, + "max": 100 + }, + "traffic": { + "incoming": { + "total": 1024000, + "avg": 1024 + }, + "outgoing": { + "total": 2048000, + "avg": 2048 + } + } + } +} +``` + +### Get Top URLs + +Get the most requested URLs for a domain. + +**Endpoint:** `GET /domains/:domainId/top-urls` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `period` (string): Time period (1h, 24h, 7d, 30d) +- `limit` (number): Number of URLs to return (default: 10) + +**Response:** +```json +{ + "success": true, + "data": { + "urls": [ + { + "url": "/", + "requests": 1000, + "percentage": 50, + "avgResponseTime": 150, + "errorRate": 0.05 + }, + { + "url": "/api/data", + "requests": 500, + "percentage": 25, + "avgResponseTime": 200, + "errorRate": 0.1 + } + ] + } +} +``` + +### Get Status Code Distribution + +Get the distribution of HTTP status codes for a domain. + +**Endpoint:** `GET /domains/:domainId/status-codes` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `period` (string): Time period (1h, 24h, 7d, 30d) + +**Response:** +```json +{ + "success": true, + "data": { + "statusCodes": [ + { + "code": 200, + "count": 1000, + "percentage": 80 + }, + { + "code": 404, + "count": 100, + "percentage": 8 + }, + { + "code": 500, + "count": 50, + "percentage": 4 + } + ] + } +} +``` + +### Get Geographic Distribution + +Get the geographic distribution of requests for a domain. + +**Endpoint:** `GET /domains/:domainId/geographic` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `period` (string): Time period (1h, 24h, 7d, 30d) + +**Response:** +```json +{ + "success": true, + "data": { + "countries": [ + { + "country": "United States", + "code": "US", + "requests": 500, + "percentage": 50 + }, + { + "country": "Germany", + "code": "DE", + "requests": 200, + "percentage": 20 + } + ] + } +} +``` + +### Create Performance Alert + +Create a performance alert for a domain. + +**Endpoint:** `POST /domains/:domainId/alerts` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "name": "High Response Time Alert", + "metric": "responseTime", + "operator": "greaterThan", + "threshold": 500, + "duration": 300, + "notificationMethod": "email", + "notificationTarget": "admin@example.com", + "enabled": true +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "name": "High Response Time Alert", + "metric": "responseTime", + "operator": "greaterThan", + "threshold": 500, + "duration": 300, + "notificationMethod": "email", + "notificationTarget": "admin@example.com", + "enabled": true, + "createdAt": "2023-01-01T00:00:00Z" + } +} +``` + +### List Performance Alerts + +Get a list of performance alerts for a domain. + +**Endpoint:** `GET /domains/:domainId/alerts` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "alerts": [ + { + "id": 1, + "name": "High Response Time Alert", + "metric": "responseTime", + "operator": "greaterThan", + "threshold": 500, + "duration": 300, + "notificationMethod": "email", + "notificationTarget": "admin@example.com", + "enabled": true, + "createdAt": "2023-01-01T00:00:00Z" + } + ] + } +} +``` + +### Delete Performance Alert + +Delete a performance alert. + +**Endpoint:** `DELETE /domains/:domainId/alerts/:alertId` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Alert deleted successfully" +} +``` + +## Error Responses + +All endpoints may return the following error responses: + +### 404 Not Found +```json +{ + "success": false, + "error": "Domain not found" +} +``` + +### 422 Validation Error +```json +{ + "success": false, + "error": "Validation failed", + "details": { + "threshold": "Threshold is required", + "notificationMethod": "Notification method is required" + } +} \ No newline at end of file diff --git a/apps/docs/api/ssl.md b/apps/docs/api/ssl.md new file mode 100644 index 0000000..b90cd45 --- /dev/null +++ b/apps/docs/api/ssl.md @@ -0,0 +1,213 @@ +# SSL API + +The SSL API provides endpoints for managing SSL certificates. + +## Base URL + +``` +https://your-domain.com/api/ssl +``` + +## Endpoints + +### List SSL Certificates + +Get a list of all SSL certificates. + +**Endpoint:** `GET /` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `search` (string): Search term + +**Response:** +```json +{ + "success": true, + "data": { + "certificates": [ + { + "id": 1, + "domainId": 1, + "domainName": "example.com", + "provider": "letsencrypt", + "status": "active", + "issuedAt": "2023-01-01T00:00:00Z", + "expiresAt": "2023-04-01T00:00:00Z", + "autoRenew": true, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +### Get SSL Certificate + +Get a specific SSL certificate by ID. + +**Endpoint:** `GET /:id` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "domainId": 1, + "domainName": "example.com", + "provider": "letsencrypt", + "status": "active", + "issuedAt": "2023-01-01T00:00:00Z", + "expiresAt": "2023-04-01T00:00:00Z", + "autoRenew": true, + "certificate": "-----BEGIN CERTIFICATE-----\n...", + "privateKey": "-----BEGIN PRIVATE KEY-----\n...", + "certificateChain": "-----BEGIN CERTIFICATE-----\n...", + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +### Issue SSL Certificate + +Issue a new SSL certificate. + +**Endpoint:** `POST /issue` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "domainId": 1, + "provider": "letsencrypt", + "email": "admin@example.com", + "autoRenew": true +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "domainId": 1, + "domainName": "example.com", + "provider": "letsencrypt", + "status": "pending", + "issuedAt": null, + "expiresAt": null, + "autoRenew": true, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +### Renew SSL Certificate + +Renew an SSL certificate. + +**Endpoint:** `POST /:id/renew` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Certificate renewal initiated" +} +``` + +### Revoke SSL Certificate + +Revoke an SSL certificate. + +**Endpoint:** `POST /:id/revoke` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "Certificate revoked successfully" +} +``` + +### Upload Custom Certificate + +Upload a custom SSL certificate. + +**Endpoint:** `POST /upload` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "domainId": 1, + "certificate": "-----BEGIN CERTIFICATE-----\n...", + "privateKey": "-----BEGIN PRIVATE KEY-----\n...", + "certificateChain": "-----BEGIN CERTIFICATE-----\n...", + "autoRenew": false +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "domainId": 1, + "domainName": "example.com", + "provider": "custom", + "status": "active", + "issuedAt": "2023-01-01T00:00:00Z", + "expiresAt": "2023-04-01T00:00:00Z", + "autoRenew": false, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +## Error Responses + +All endpoints may return the following error responses: + +### 404 Not Found +```json +{ + "success": false, + "error": "Certificate not found" +} +``` + +### 422 Validation Error +```json +{ + "success": false, + "error": "Validation failed", + "details": { + "domainId": "Domain ID is required", + "certificate": "Certificate is required" + } +} \ No newline at end of file diff --git a/apps/docs/api/users.md b/apps/docs/api/users.md new file mode 100644 index 0000000..f2cb548 --- /dev/null +++ b/apps/docs/api/users.md @@ -0,0 +1,350 @@ +# Users API + +The users API provides endpoints for managing user accounts and permissions. + +## Base URL + +``` +https://your-domain.com/api/users +``` + +## Endpoints + +### List Users + +Get a list of all users. + +**Endpoint:** `GET /` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `search` (string): Search term +- `role` (string): Filter by role (admin, user) + +**Response:** +```json +{ + "success": true, + "data": { + "users": [ + { + "id": 1, + "name": "John Doe", + "email": "john@example.com", + "role": "admin", + "active": true, + "lastLoginAt": "2023-01-01T12:00:00Z", + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +### Get User + +Get a specific user by ID. + +**Endpoint:** `GET /:id` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 1, + "name": "John Doe", + "email": "john@example.com", + "role": "admin", + "active": true, + "lastLoginAt": "2023-01-01T12:00:00Z", + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +### Create User + +Create a new user. + +**Endpoint:** `POST /` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "name": "Jane Doe", + "email": "jane@example.com", + "password": "password123", + "role": "user", + "active": true +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 2, + "name": "Jane Doe", + "email": "jane@example.com", + "role": "user", + "active": true, + "lastLoginAt": null, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +### Update User + +Update an existing user. + +**Endpoint:** `PUT /:id` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "name": "Jane Smith", + "email": "jane.smith@example.com", + "role": "admin", + "active": true +} +``` + +**Response:** +```json +{ + "success": true, + "data": { + "id": 2, + "name": "Jane Smith", + "email": "jane.smith@example.com", + "role": "admin", + "active": true, + "lastLoginAt": null, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } +} +``` + +### Delete User + +Delete a user. + +**Endpoint:** `DELETE /:id` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "message": "User deleted successfully" +} +``` + +### Update User Password + +Update a user's password. + +**Endpoint:** `PUT /:id/password` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "currentPassword": "oldpassword123", + "newPassword": "newpassword123", + "confirmPassword": "newpassword123" +} +``` + +**Response:** +```json +{ + "success": true, + "message": "Password updated successfully" +} +``` + +### Reset User Password + +Reset a user's password (admin only). + +**Endpoint:** `POST /:id/reset-password` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "email": "user@example.com" +} +``` + +**Response:** +```json +{ + "success": true, + "message": "Password reset email sent" +} +``` + +### Get User Permissions + +Get permissions for a user. + +**Endpoint:** `GET /:id/permissions` + +**Headers:** `Authorization: Bearer ` + +**Response:** +```json +{ + "success": true, + "data": { + "permissions": [ + { + "resource": "domains", + "actions": ["read", "create", "update", "delete"] + }, + { + "resource": "ssl", + "actions": ["read", "create", "update", "delete"] + }, + { + "resource": "modsecurity", + "actions": ["read", "update"] + } + ] + } +} +``` + +### Update User Permissions + +Update permissions for a user. + +**Endpoint:** `PUT /:id/permissions` + +**Headers:** `Authorization: Bearer ` + +**Request Body:** +```json +{ + "permissions": [ + { + "resource": "domains", + "actions": ["read", "create", "update", "delete"] + }, + { + "resource": "ssl", + "actions": ["read", "create", "update", "delete"] + }, + { + "resource": "modsecurity", + "actions": ["read", "update"] + } + ] +} +``` + +**Response:** +```json +{ + "success": true, + "message": "Permissions updated successfully" +} +``` + +### Get User Activity + +Get activity log for a user. + +**Endpoint:** `GET /:id/activity` + +**Headers:** `Authorization: Bearer ` + +**Query Parameters:** +- `page` (number): Page number (default: 1) +- `limit` (number): Items per page (default: 20) +- `startDate` (string): Start date (ISO 8601) +- `endDate` (string): End date (ISO 8601) + +**Response:** +```json +{ + "success": true, + "data": { + "activities": [ + { + "id": 1, + "action": "login", + "resource": "auth", + "details": "User logged in", + "ipAddress": "192.168.1.1", + "userAgent": "Mozilla/5.0...", + "timestamp": "2023-01-01T12:00:00Z" + } + ], + "pagination": { + "page": 1, + "limit": 20, + "total": 1, + "pages": 1 + } + } +} +``` + +## Error Responses + +All endpoints may return the following error responses: + +### 404 Not Found +```json +{ + "success": false, + "error": "User not found" +} +``` + +### 403 Forbidden +```json +{ + "success": false, + "error": "Insufficient permissions" +} +``` + +### 422 Validation Error +```json +{ + "success": false, + "error": "Validation failed", + "details": { + "email": "Email is required", + "password": "Password must be at least 8 characters" + } +} \ No newline at end of file diff --git a/apps/docs/guide/domains.md b/apps/docs/guide/domains.md new file mode 100644 index 0000000..5b4a12d --- /dev/null +++ b/apps/docs/guide/domains.md @@ -0,0 +1,462 @@ +# Domain Management Guide + +This comprehensive guide covers all aspects of domain management in the Nginx WAF Management Platform, including adding domains, configuring upstream servers, load balancing, and advanced domain configurations. + +## Overview + +The domain management system allows you to: +- Add and configure multiple domains +- Set up load balancing with multiple upstream servers +- Configure health checks and failover +- Manage SSL certificates for each domain +- Enable ModSecurity WAF protection +- Monitor domain performance and availability + +## Domain Management Interface + +Access the domain management by clicking **Domains** in the sidebar navigation: + +![Domain Management](/reference/screenshots/Domain_Management.png) + +The interface provides: +- **Domain List**: Overview of all configured domains +- **Status Indicators**: Visual indicators for domain health +- **Quick Actions**: Common tasks for each domain +- **Search and Filter**: Find specific domains quickly + +## Adding a New Domain + +### Basic Domain Configuration + +1. Click the **Add Domain** button +2. Fill in the basic domain information: + +![Add Domain](/reference/screenshots/domain_add.png) + +**Required Fields:** +- **Domain Name**: The domain name (e.g., `example.com`, `api.example.com`) +- **Upstream Servers**: At least one backend server + +**Optional Settings:** +- **Status**: Active or Inactive +- **SSL Enabled**: Enable/disable SSL for this domain +- **ModSecurity Enabled**: Enable/disable WAF protection + +### Domain Name Configuration + +When entering a domain name, follow these guidelines: + +- **Valid Characters**: Letters (a-z), numbers (0-9), hyphens (-) +- **Cannot Start/End**: Cannot start or end with a hyphen +- **Subdomains**: Use dot notation for subdomains (e.g., `api.example.com`) +- **Wildcards**: Wildcard domains are supported (*.example.com) + +**Examples of Valid Domain Names:** +``` +example.com +api.example.com +www.example.com +*.example.com +my-app.example.org +``` + +## Upstream Server Configuration + +Upstream servers are the backend servers that handle the actual requests. Each domain must have at least one upstream server configured. + +### Adding Upstream Servers + +For each upstream server, configure the following: + +#### Basic Configuration +- **Host**: IP address or hostname of the backend server +- **Port**: Port number (1-65535) +- **Protocol**: HTTP or HTTPS +- **Weight**: Load balancing weight (default: 1) +- **Max Fails**: Maximum failed attempts before marking as down (default: 3) +- **Fail Timeout**: Timeout in seconds before retrying (default: 10) + +#### Advanced Configuration +- **SSL Verify**: Verify SSL certificates for HTTPS backends +- **Backup**: Mark server as backup (only used when all primary servers are down) +- **Down**: Manually mark server as down for maintenance + +### Upstream Server Examples + +#### Single Backend Server +``` +Host: 192.168.1.100 +Port: 8080 +Protocol: HTTP +Weight: 1 +Max Fails: 3 +Fail Timeout: 10 +SSL Verify: Yes +``` + +#### Multiple Backend Servers (Load Balancing) +``` +Server 1: + Host: 192.168.1.100 + Port: 8080 + Weight: 3 + +Server 2: + Host: 192.168.1.101 + Port: 8080 + Weight: 2 + +Server 3 (Backup): + Host: 192.168.1.102 + Port: 8080 + Weight: 1 + Backup: Yes +``` + +#### HTTPS Backend with SSL Verification +``` +Host: api.backend.com +Port: 443 +Protocol: HTTPS +Weight: 1 +SSL Verify: Yes +``` + +## Load Balancing Configuration + +The platform supports multiple load balancing algorithms to distribute traffic across upstream servers. + +### Load Balancing Algorithms + +#### Round Robin (Default) +Requests are distributed evenly across all available servers. + +```nginx +upstream backend { + server 192.168.1.100:8080 weight=1; + server 192.168.1.101:8080 weight=1; +} +``` + +#### Least Connections +Requests are sent to the server with the fewest active connections. + +```nginx +upstream backend { + least_conn; + server 192.168.1.100:8080 weight=1; + server 192.168.1.101:8080 weight=1; +} +``` + +#### IP Hash +Client IP address is used to determine which server receives the request, ensuring session persistence. + +```nginx +upstream backend { + ip_hash; + server 192.168.1.100:8080; + server 192.168.1.101:8080; +} +``` + +### Configuring Load Balancing + +1. Select your domain from the list +2. Click the **Load Balancer** tab +3. Choose the appropriate algorithm +4. Configure health check settings + +### Health Check Configuration + +Health checks ensure that only healthy backend servers receive traffic. + +#### Health Check Settings +- **Enabled**: Enable/disable health checks +- **Interval**: Check interval in seconds (default: 30) +- **Timeout**: Request timeout in seconds (default: 5) +- **Path**: Health check endpoint path (default: /) +- **Success Criteria**: HTTP status codes considered healthy (default: 200, 204) + +#### Health Check Example +``` +Enabled: Yes +Interval: 30 seconds +Timeout: 5 seconds +Path: /health +Success Criteria: 200, 204 +``` + +## Advanced Domain Configuration + +### Custom Nginx Configuration + +For advanced use cases, you can add custom Nginx configuration directives: + +1. Select your domain from the list +2. Click the **Advanced** tab +3. Add custom configuration in the text area + +#### Example Custom Configuration +```nginx +# Custom headers +add_header X-Frame-Options "SAMEORIGIN" always; +add_header X-Content-Type-Options "nosniff" always; +add_header X-XSS-Protection "1; mode=block" always; + +# CORS configuration +if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain; charset=utf-8'; + add_header 'Content-Length' 0; + return 204; +} + +# Rate limiting +limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; +limit_req zone=api burst=20 nodelay; +``` + +### URL Rewriting and Redirects + +Configure URL rewriting and redirects for your domain: + +#### Permanent Redirect (301) +```nginx +# Redirect old domain to new domain +server_name old-domain.com; +return 301 $scheme://new-domain.com$request_uri; +``` + +#### Temporary Redirect (302) +```nginx +# Temporary maintenance redirect +return 302 /maintenance.html; +``` + +#### URL Rewriting +```nginx +# Rewrite rules +location /old-path/ { + rewrite ^/old-path/(.*)$ /new-path/$1 permanent; +} +``` + +## Domain Status and Monitoring + +### Domain Status Indicators + +Each domain displays status indicators: + +- **Active**: Domain is online and accepting traffic +- **Inactive**: Domain is disabled and not accepting traffic +- **Error**: Domain has configuration errors or all upstreams are down + +### Upstream Server Status + +Upstream servers show individual health status: + +- **Up**: Server is healthy and accepting traffic +- **Down**: Server is not responding or has failed health checks +- **Checking**: Health check is in progress + +### Domain Performance Metrics + +Monitor domain performance through the **Performance** tab: + +- **Request Rate**: Requests per second +- **Response Time**: Average response time +- **Error Rate**: Percentage of failed requests +- **Bandwidth**: Data transfer statistics + +## Domain Operations + +### Editing a Domain + +1. Select the domain from the list +2. Click the **Edit** button +3. Make your changes +4. Click **Save** to apply changes + +### Toggling Domain Status + +Quickly enable or disable a domain: + +1. Select the domain from the list +2. Click the **Toggle Status** button +3. Confirm the action + +### Deleting a Domain + +⚠️ **Warning**: Deleting a domain will remove all configuration and cannot be undone. + +1. Select the domain from the list +2. Click the **Delete** button +3. Confirm the deletion + +### Reloading Nginx Configuration + +After making changes to domain configuration, you may need to reload Nginx: + +1. Click the **Reload Nginx** button in the domain list +2. Or use the system-wide reload in **System** settings + +## Troubleshooting Domain Issues + +### Common Issues and Solutions + +#### Domain Not Accessible + +**Symptoms**: 502 Bad Gateway, connection refused + +**Possible Causes**: +- All upstream servers are down +- Incorrect upstream configuration +- Network connectivity issues + +**Solutions**: +1. Check upstream server status +2. Verify host and port configuration +3. Test connectivity to upstream servers +4. Check firewall rules + +#### SSL Certificate Issues + +**Symptoms**: SSL warnings, certificate errors + +**Possible Causes**: +- Expired SSL certificate +- Incorrect certificate configuration +- Domain mismatch + +**Solutions**: +1. Check SSL certificate validity +2. Verify certificate matches domain +3. Renew or reissue certificate +4. Check certificate chain + +#### Load Balancing Not Working + +**Symptoms**: All traffic going to one server + +**Possible Causes**: +- Incorrect load balancing algorithm +- Server weights not configured +- Health checks failing + +**Solutions**: +1. Verify load balancing algorithm +2. Check server weights +3. Review health check configuration +4. Monitor server health status + +### Debug Mode + +Enable debug mode for detailed logging: + +1. Go to **System** settings +2. Enable **Debug Mode** +3. Check logs in **Logs** section +4. Disable debug mode when finished + +## Best Practices + +### Domain Configuration + +1. **Use Descriptive Names**: Make domain names clear and descriptive +2. **Organize by Environment**: Separate production, staging, and development domains +3. **Document Configuration**: Keep records of special configurations +4. **Regular Backups**: Backup domain configurations regularly + +### Upstream Server Management + +1. **Multiple Servers**: Always configure at least two upstream servers for redundancy +2. **Health Checks**: Enable health checks for all production domains +3. **Weight Distribution**: Use appropriate weights based on server capacity +4. **Backup Servers**: Configure backup servers for high availability + +### Security + +1. **SSL Everywhere**: Enable SSL for all production domains +2. **ModSecurity**: Enable WAF protection for all public-facing domains +3. **Access Control**: Use ACLs to restrict access as needed +4. **Regular Updates**: Keep SSL certificates and security rules updated + +### Performance + +1. **Monitor Metrics**: Regularly check performance metrics +2. **Optimize Configuration**: Tune settings based on traffic patterns +3. **Load Testing**: Test configuration under load +4. **Capacity Planning**: Plan for growth and scale accordingly + +## API Integration + +For programmatic domain management, use the REST API: + +### List Domains +```bash +curl -X GET http://localhost:3001/api/domains \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Create Domain +```bash +curl -X POST http://localhost:3001/api/domains \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "api.example.com", + "status": "active", + "upstreams": [ + { + "host": "192.168.1.100", + "port": 8080, + "weight": 1 + } + ] + }' +``` + +### Update Domain +```bash +curl -X PUT http://localhost:3001/api/domains/DOMAIN_ID \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "status": "active", + "upstreams": [ + { + "host": "192.168.1.100", + "port": 8080, + "weight": 2 + } + ] + }' +``` + +### Delete Domain +```bash +curl -X DELETE http://localhost:3001/api/domains/DOMAIN_ID \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +For complete API documentation, see the [API Reference](/api/domains). + +## Conclusion + +Domain management is a core feature of the Nginx WAF Management Platform. By following this guide, you should be able to: + +- Add and configure domains effectively +- Set up reliable load balancing +- Monitor domain performance +- Troubleshoot common issues +- Implement best practices for production use + +For more information on related topics: +- [SSL Certificate Management](/guide/ssl) +- [ModSecurity WAF Configuration](/guide/modsecurity) +- [Performance Monitoring](/guide/performance) +- [Log Analysis](/guide/logs) \ No newline at end of file diff --git a/apps/docs/guide/installation.md b/apps/docs/guide/installation.md new file mode 100644 index 0000000..984a6f6 --- /dev/null +++ b/apps/docs/guide/installation.md @@ -0,0 +1,466 @@ +# Installation Guide + +This comprehensive guide will walk you through installing the Nginx WAF Management Platform on your system. + +## Prerequisites + +Before you begin, ensure you have the following: + +### System Requirements +- **Operating System**: Ubuntu/Debian (22.04+ recommended) +- **Memory**: 2GB RAM minimum (4GB+ recommended) +- **Storage**: 10GB free space minimum +- **Network**: Internet connection for package downloads and Let's Encrypt certificates +- **Access**: Root/sudo privileges for production installation + +### Software Requirements (for manual installation) +- **Node.js**: 18.x or higher +- **pnpm**: 8.15.0 or higher +- **Docker**: Latest version +- **Docker Compose**: Latest version +- **PostgreSQL**: 15+ (if not using Docker) +- **Nginx**: Latest stable version +- **ModSecurity**: 3.x with OWASP CRS + +## Installation Methods + +Choose the appropriate installation method based on your use case: + +| Use Case | Installation Method | Description | +|----------|-------------------|-------------| +| **New Server (Production)** | Automated Script | Full installation with systemd services | +| **Development/Testing** | Quick Start Script | Development mode without root requirements | +| **Manual Setup** | Manual Installation | Step-by-step manual configuration | + +--- + +## Method 1: Automated Production Installation + +This method is recommended for new servers and production environments. + +### 1. Clone the Repository + +```bash +git clone https://github.com/TinyActive/nginx-love.git +cd nginx-love +``` + +### 2. Run the Deployment Script + +```bash +bash scripts/deploy.sh +``` + +The script will automatically install and configure: +- ✅ Node.js 20.x (if not present) +- ✅ pnpm 8.15.0 (if not present) +- ✅ Docker + Docker Compose (if not present) +- ✅ PostgreSQL 15 container with auto-generated credentials +- ✅ Nginx + ModSecurity + OWASP CRS +- ✅ Backend API + Frontend (production build) +- ✅ Systemd services with auto-start +- ✅ CORS configuration with Public IP + +### 3. Access Your Credentials + +After installation, credentials are saved at: +```bash +/root/.nginx-love-credentials +``` + +### 4. Verify Installation + +Once completed, you can access: +- **Frontend**: http://YOUR_IP:8080 +- **Backend API**: http://YOUR_IP:3001 +- **API Documentation**: http://YOUR_IP:3001/api-docs +- **Health Check**: http://YOUR_IP:3001/api/health + +--- + +## Method 2: Development Quick Start + +This method is ideal for development and testing environments. + +### 1. Clone the Repository + +```bash +git clone https://github.com/TinyActive/nginx-love.git +cd nginx-love +``` + +### 2. Run the Quick Start Script + +```bash +./scripts/quickstart.sh +``` + +This will: +- Install all dependencies +- Start PostgreSQL in Docker (optional) +- Run database migrations and seeding +- Start backend on http://localhost:3001 +- Start frontend on http://localhost:8080 (dev mode) + +### 3. Stop Services + +Press `Ctrl+C` to stop all services. + +--- + +## Method 3: Manual Installation + +This method provides full control over the installation process. + +### 1. System Preparation + +```bash +# Update system packages +sudo apt update && sudo apt upgrade -y + +# Install essential packages +sudo apt install -y curl wget git build-essential +``` + +### 2. Install Node.js and pnpm + +```bash +# Install Node.js 20.x +curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - +sudo apt-get install -y nodejs + +# Install pnpm +npm install -g pnpm@8.15.0 + +# Verify installations +node --version +pnpm --version +``` + +### 3. Install Docker and Docker Compose + +```bash +# Install Docker +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh + +# Add user to docker group +sudo usermod -aG docker $USER + +# Install Docker Compose +sudo apt install -y docker-compose-plugin + +# Verify installation +docker --version +docker compose version +``` + +### 4. Clone and Setup the Project + +```bash +# Clone repository +git clone https://github.com/TinyActive/nginx-love.git +cd nginx-love + +# Install dependencies +pnpm install +``` + +### 5. Database Setup + +```bash +# Start PostgreSQL container +docker-compose -f docker-compose.db.yml up -d + +# Configure environment +cd apps/api +cp .env.example .env + +# Edit .env file with your database settings +nano .env +``` + +Example `.env` configuration: +```env +# Database +DATABASE_URL="postgresql://nginx_love_user:your_password@localhost:5432/nginx_love_db" + +# JWT +JWT_SECRET="your-super-secret-jwt-key" +JWT_REFRESH_SECRET="your-super-secret-refresh-key" + +# Server +PORT=3001 +NODE_ENV=production + +# Email (optional) +SMTP_HOST="smtp.gmail.com" +SMTP_PORT=587 +SMTP_USER="your-email@gmail.com" +SMTP_PASS="your-app-password" +``` + +### 6. Database Migration and Seeding + +```bash +cd apps/api + +# Generate Prisma client +pnpm prisma generate + +# Run migrations +pnpm prisma migrate deploy + +# Seed initial data +pnpm prisma:seed +``` + +### 7. Build and Start Applications + +```bash +# Build backend +cd apps/api +pnpm build + +# Build frontend +cd ../web +pnpm build + +# Start production servers +cd ../../ +# Backend +cd apps/api && pnpm start & + +# Frontend +cd ../web && pnpm preview & +``` + +--- + +## Docker Installation + +For containerized deployments, use Docker Compose: + +### 1. Clone Repository + +```bash +git clone https://github.com/TinyActive/nginx-love.git +cd nginx-love +``` + +### 2. Configure Environment + +```bash +cp .env.example .env +# Edit .env with your configuration +``` + +### 3. Start with Docker Compose + +```bash +# Start all services +docker-compose up -d + +# Check status +docker-compose ps + +# View logs +docker-compose logs -f +``` + +--- + +## Default Login Credentials + +After installation, use these default credentials: + +``` +Username: admin +Password: admin123 +``` + +⚠️ **Important**: Change the default password immediately after first login! + +--- + +## Post-Installation Configuration + +### 1. Firewall Configuration + +```bash +# Configure UFW firewall +sudo ufw allow 22/tcp # SSH +sudo ufw allow 80/tcp # HTTP +sudo ufw allow 443/tcp # HTTPS +sudo ufw allow 3001/tcp # Backend API (if needed) +sudo ufw allow 8080/tcp # Frontend (if not behind proxy) +sudo ufw enable +``` + +### 2. SSL Certificate Setup + +For production use, configure SSL certificates: + +```bash +# Option 1: Let's Encrypt (recommended) +sudo apt install certbot +sudo certbot --nginx -d yourdomain.com + +# Option 2: Self-signed (for testing) +sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout /etc/ssl/private/nginx-selfsigned.key \ + -out /etc/ssl/certs/nginx-selfsigned.crt +``` + +### 3. Nginx Reverse Proxy (Optional) + +Configure Nginx as a reverse proxy: + +```nginx +server { + listen 80; + server_name yourdomain.com; + return 301 https://$server_name$request_uri; +} + +server { + listen 443 ssl http2; + server_name yourdomain.com; + + ssl_certificate /path/to/your/certificate.crt; + ssl_certificate_key /path/to/your/private.key; + + location / { + proxy_pass http://localhost:8080; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /api { + proxy_pass http://localhost:3001; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} +``` + +--- + +## Service Management + +### Production (systemd services) + +```bash +# PostgreSQL Database +docker start nginx-love-postgres +docker stop nginx-love-postgres +docker restart nginx-love-postgres +docker logs -f nginx-love-postgres + +# Backend API Service +sudo systemctl start nginx-love-backend +sudo systemctl stop nginx-love-backend +sudo systemctl restart nginx-love-backend +sudo systemctl status nginx-love-backend + +# Frontend Service +sudo systemctl start nginx-love-frontend +sudo systemctl stop nginx-love-frontend +sudo systemctl restart nginx-love-frontend +sudo systemctl status nginx-love-frontend + +# Nginx Web Server +sudo systemctl start nginx +sudo systemctl stop nginx +sudo systemctl restart nginx +sudo systemctl status nginx +sudo nginx -t # Test configuration +sudo nginx -s reload # Reload configuration +``` + +### Development Environment + +```bash +# Start development servers +cd nginx-love + +# Backend (Terminal 1) +cd apps/api && pnpm dev + +# Frontend (Terminal 2) +cd apps/web && pnpm dev + +# Database operations +cd apps/api +pnpm prisma:studio # Open Prisma Studio +pnpm prisma:migrate # Run migrations +pnpm prisma:seed # Seed database + +# Stop services +Ctrl+C # In each terminal + +# Or force kill processes +npx kill-port 3001 # Backend port +npx kill-port 8080 # Frontend port (dev & prod) +npx kill-port 5555 # Prisma Studio port +``` + +--- + +## Verification + +To verify your installation is working correctly: + +### 1. Health Check + +```bash +curl http://localhost:3001/api/health +``` + +Expected response: +```json +{ + "success": true, + "message": "API is running", + "timestamp": "2025-10-04T09:53:00.000Z" +} +``` + +### 2. Access the Web Interface + +Open your browser and navigate to: +- Development: http://localhost:8080 +- Production: http://YOUR_IP:8080 + +### 3. Test API Documentation + +Visit http://localhost:3001/api-docs to view the Swagger documentation. + +--- + +## Troubleshooting + +If you encounter issues during installation: + +1. **Port Conflicts**: Check if ports 3001, 8080, or 5432 are already in use +2. **Permission Issues**: Ensure you have proper sudo/root privileges +3. **Database Connection**: Verify PostgreSQL is running and credentials are correct +4. **Node.js Version**: Ensure you're using Node.js 18.x or higher + +For detailed troubleshooting, see the [Troubleshooting Guide](/reference/troubleshooting). + +--- + +## Next Steps + +After successful installation: + +1. [Configure your first domain](/guide/domains) +2. [Set up SSL certificates](/guide/ssl) +3. [Configure ModSecurity WAF](/guide/modsecurity) +4. [Create additional users](/guide/users) +5. [Set up monitoring and alerts](/guide/performance) \ No newline at end of file diff --git a/apps/docs/guide/introduction.md b/apps/docs/guide/introduction.md new file mode 100644 index 0000000..086415a --- /dev/null +++ b/apps/docs/guide/introduction.md @@ -0,0 +1,43 @@ +# Introduction + +nginx-love is a comprehensive management platform for Nginx and ModSecurity. It provides a user-friendly web interface to manage Nginx configurations, SSL certificates, ModSecurity rules, and monitor server performance. + +## What is nginx-love? + +nginx-love is designed to simplify the management of Nginx web servers with the following key features: + +- **Domain Management**: Easily add, configure, and manage Nginx domains +- **SSL Certificate Management**: Automate SSL certificate issuance and renewal with Let's Encrypt +- **ModSecurity WAF**: Configure and manage Web Application Firewall rules +- **Performance Monitoring**: Monitor server performance and analyze traffic patterns +- **Log Analysis**: Analyze access and error logs to identify issues +- **Multi-User Support**: Manage multiple users with role-based access control + +## Who is this for? + +nginx-love is designed for: + +- System administrators managing multiple Nginx instances +- DevOps engineers looking for a centralized Nginx management solution +- Security professionals needing to configure ModSecurity rules +- Web developers who want to manage their own Nginx configurations + +## Key Concepts + +### Domains +In nginx-love, a domain represents a website or application served by Nginx. Each domain has its own configuration, SSL certificates, and settings. + +### SSL Certificates +nginx-love integrates with Let's Encrypt to provide free SSL certificates. It automates the process of obtaining, renewing, and installing certificates. + +### ModSecurity +ModSecurity is a web application firewall that helps protect your applications from various attacks. nginx-love provides an interface to manage ModSecurity rules and configurations. + +### Performance Monitoring +nginx-love collects and displays performance metrics for your Nginx servers, helping you identify bottlenecks and optimize performance. + +## Next Steps + +- [Installation Guide](/guide/installation) - Learn how to install nginx-love +- [Quick Start](/guide/quick-start) - Get up and running quickly +- [Features](/guide/features) - Explore all available features \ No newline at end of file diff --git a/apps/docs/guide/logs.md b/apps/docs/guide/logs.md new file mode 100644 index 0000000..4555617 --- /dev/null +++ b/apps/docs/guide/logs.md @@ -0,0 +1,443 @@ +# Log Analysis Guide + +This comprehensive guide covers log analysis in the Nginx WAF Management Platform, including viewing different log types, filtering and searching logs, analyzing security events, and troubleshooting issues through log data. + +## Overview + +The log analysis system provides: +- **Centralized Logging**: Access to all system logs in one interface +- **Real-time Viewing**: Live log streaming for real-time monitoring +- **Advanced Filtering**: Filter logs by type, domain, time range, and more +- **Search Capabilities**: Search logs using keywords and patterns +- **Security Analysis**: Identify security threats and attack patterns +- **Export Functionality**: Export logs for external analysis + +## Log Analysis Interface + +Access log analysis by clicking **Logs** in the sidebar navigation: + +![Domain Logs](/reference/screenshots/domain_log.png) + +The log analysis interface provides: +- **Log Type Selection**: Choose between different log types +- **Filter Options**: Filter logs by various criteria +- **Search Bar**: Search for specific log entries +- **Log Display**: Formatted log entries with highlighting +- **Export Options**: Download logs in various formats + +## Log Types + +The platform collects and analyzes several types of logs: + +### Access Logs + +Access logs record all HTTP requests to your domains: + +**Log Format**: +``` +192.168.1.100 - - [04/Oct/2025:10:00:00 +0000] "GET /api/users HTTP/1.1" 200 1234 "https://example.com/dashboard" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" +``` + +**Access Log Fields**: +- **Remote Address**: Client IP address +- **Remote User**: Authenticated username (if any) +- **Timestamp**: Request date and time +- **Request**: HTTP method, path, and protocol +- **Status**: HTTP response status code +- **Body Size**: Response body size in bytes +- **Referer**: Referring page +- **User Agent**: Client browser information + +### Error Logs + +Error logs record server errors and issues: + +**Log Format**: +``` +2025/10/04 10:00:00 [error] 1234#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 192.168.1.100, server: example.com, request: "GET /api/data HTTP/1.1", upstream: "http://192.168.1.200:8080/api/data" +``` + +**Error Log Fields**: +- **Timestamp**: Error date and time +- **Log Level**: Error severity (error, warn, info, debug) +- **Process ID**: Nginx process ID +- **Connection ID**: Connection identifier +- **Error Message**: Detailed error description +- **Client Information**: Client IP and request details +- **Upstream Information**: Backend server details + +### ModSecurity Logs + +ModSecurity logs record security events and rule matches: + +**Log Format**: +``` +[04/Oct/2025:10:00:00 +0000] [-] [error] [client 192.168.1.100] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Rx' with parameter `(?i:(?:[.;&\\|`'"]|(?:%[0-9a-f]{2}))+select(?:[\\s]+(?:distinct|all))?)" against variable "ARGS:sql" (Value: "';SELECT * FROM users;--") [file "/etc/nginx/modsec/REQUEST-942-APPLICATION-ATTACK-SQLI.conf"] [line "173"] [id "942100"] [rev ""] [msg "SQL Injection Attack Detected"] [data "Matched Data: ';SELECT found within ARGS:sql"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-sqli"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSec/REGEX/941100"] [hostname "example.com"] [uri "/api/search"] [unique_id "X123456"] +``` + +**ModSecurity Log Fields**: +- **Timestamp**: Event date and time +- **Client IP**: Source IP address +- **Action**: Action taken (deny, allow, etc.) +- **Phase**: Processing phase (1-5) +- **Match Details**: Rule match information +- **Rule Information**: Rule ID, file, line number +- **Message**: Rule description +- **Data**: Matched data +- **Severity**: Event severity +- **Tags**: Event tags and categories + +### System Logs + +System logs record application and system events: + +**Log Format**: +``` +2025-10-04T10:00:00.000Z [INFO] (nginx-love-api) User admin logged in successfully from 192.168.1.100 +``` + +**System Log Fields**: +- **Timestamp**: Event date and time (ISO 8601) +- **Log Level**: Event severity (INFO, WARN, ERROR, DEBUG) +- **Component**: System component generating the log +- **Message**: Event description +- **Metadata**: Additional event data + +## Viewing Logs + +### Selecting Log Types + +1. Click **Logs** in the sidebar +2. Select the log type from the dropdown: + - **Access**: HTTP access logs + - **Error**: Server error logs + - **ModSecurity**: Security event logs + - **System**: Application and system logs + +### Filtering Logs + +Filter logs to find specific information: + +#### By Domain + +1. Select a domain from the **Domain** dropdown +2. Only logs for that domain will be displayed +3. Select "All Domains" to view logs for all domains + +#### By Time Range + +1. Select a time range from the **Time Range** dropdown: + - **Last Hour**: Recent log entries + - **Last 24 Hours**: Logs from the past day + - **Last 7 Days**: Logs from the past week + - **Last 30 Days**: Logs from the past month + - **Custom Range**: Specific date and time range + +2. For custom ranges, select start and end dates + +#### By Log Level + +1. Select log levels from the **Log Level** dropdown: + - **Error**: Error messages and critical issues + - **Warning**: Warning messages and potential issues + - **Info**: Informational messages + - **Debug**: Debug messages (verbose) + +2. Multiple levels can be selected + +#### By Status Code (Access Logs) + +1. Select status codes from the **Status Code** dropdown: + - **2xx**: Success responses (200-299) + - **3xx**: Redirection responses (300-399) + - **4xx**: Client errors (400-499) + - **5xx**: Server errors (500-599) + +### Searching Logs + +Search for specific log entries using the search bar: + +#### Text Search + +Enter keywords to search for in log messages: +``` +search term +``` + +#### Regular Expression Search + +Use regular expressions for advanced searching: +``` +regex:(error|warning|critical) +``` + +#### Field-Specific Search + +Search specific log fields: +``` +status:404 +ip:192.168.1.100 +user:admin +``` + +#### Combined Search + +Combine multiple search criteria: +``` +status:5xx ip:192.168.1.100 +``` + +## Log Analysis + +### Analyzing Access Patterns + +Analyze access logs to understand traffic patterns: + +#### Traffic Volume + +Monitor request volume over time: +- **Peak Hours**: Identify busiest times +- **Traffic Sources**: Identify top referrers +- **Popular Pages**: Identify most requested content +- **User Agents**: Identify browser and OS distribution + +#### Geographic Analysis + +Analyze traffic by geographic location: +- **Top Countries**: Countries with most traffic +- **Top Cities**: Cities with most traffic +- **Unusual Locations**: Identify unexpected geographic sources + +#### Response Code Analysis + +Analyze HTTP response codes: +- **Success Rate**: Percentage of successful requests +- **Error Rate**: Percentage of error responses +- **Redirect Rate**: Percentage of redirects +- **Client Errors**: 4xx error analysis +- **Server Errors**: 5xx error analysis + +### Security Analysis + +Analyze security logs to identify threats: + +#### Attack Detection + +Identify potential attacks in ModSecurity logs: +- **SQL Injection**: Look for SQL injection patterns +- **XSS Attacks**: Look for cross-site scripting attempts +- **Command Injection**: Look for command execution attempts +- **Path Traversal**: Look for directory traversal attempts +- **Brute Force**: Look for repeated login attempts + +#### IP Analysis + +Analyze source IP addresses: +- **Top Attackers**: IPs with most security events +- **Geographic Distribution**: Attack sources by country +- **Attack Patterns**: Common attack vectors by IP +- **Reputation**: Check IP reputation against threat intelligence + +#### Attack Trends + +Analyze attack trends over time: +- **Attack Volume**: Number of attacks over time +- **Attack Types**: Most common attack types +- **Targeted Resources**: Most attacked endpoints +- **Success Rate**: Percentage of successful attacks + +### Performance Analysis + +Analyze logs to identify performance issues: + +#### Response Time Analysis + +Analyze response times from access logs: +- **Average Response Time**: Overall performance metric +- **Slow Requests**: Identify slow endpoints +- **Response Time Distribution**: Performance distribution +- **Performance Trends**: Performance over time + +#### Error Analysis + +Analyze error logs to identify issues: +- **Error Frequency**: Most common errors +- **Error Patterns**: Error occurrence patterns +- **Error Impact**: Impact of errors on users +- **Error Resolution**: Error resolution time + +#### Upstream Analysis + +Analyze upstream server performance: +- **Upstream Response Times**: Backend server performance +- **Upstream Errors**: Backend server errors +- **Upstream Failures**: Backend server failures +- **Load Balancing**: Load distribution across upstreams + +## Log Export + +Export logs for external analysis and compliance: + +### Export Formats + +1. Click **Logs** in the sidebar +2. Apply desired filters +3. Click **Export** button +4. Choose export format: + - **JSON**: Structured data format + - **CSV**: Comma-separated values + - **TXT**: Plain text format + - **Syslog**: Standard syslog format + +### Export Options + +Configure export options: +- **Date Range**: Select specific date range +- **Log Types**: Choose which log types to export +- **Fields**: Select specific fields to include +- **Compression**: Compress export file + +### Scheduled Exports + +Configure scheduled log exports: +1. Go to **System** settings +2. Click **Log Export** tab +3. Configure scheduled export: + - **Frequency**: Daily, weekly, monthly + - **Format**: Export file format + - **Destination**: Export destination (email, FTP, etc.) + - **Retention**: Export file retention period + +## Log Retention + +Configure log retention policies: + +### Retention Policies + +1. Go to **System** settings +2. Click **Log Retention** tab +3. Configure retention policies: + - **Access Logs**: Retention period (default: 30 days) + - **Error Logs**: Retention period (default: 90 days) + - **ModSecurity Logs**: Retention period (default: 180 days) + - **System Logs**: Retention period (default: 90 days) + +### Storage Management + +Monitor log storage usage: +- **Disk Usage**: Current disk usage by logs +- **Growth Rate**: Log growth rate over time +- **Storage Forecast**: Predicted storage needs +- **Cleanup Actions**: Automatic cleanup actions + +## Troubleshooting with Logs + +Use logs to troubleshoot common issues: + +### Connection Issues + +**Symptoms**: Users cannot connect to the server + +**Log Analysis**: +1. Check error logs for connection refused messages +2. Check access logs for connection attempts +3. Check system logs for service status +4. Identify firewall or network issues + +### Performance Issues + +**Symptoms**: Slow response times + +**Log Analysis**: +1. Check access logs for response times +2. Check error logs for timeout messages +3. Check ModSecurity logs for rule processing time +4. Identify bottlenecks and optimization opportunities + +### SSL Issues + +**Symptoms**: SSL certificate errors + +**Log Analysis**: +1. Check error logs for SSL handshake errors +2. Check access logs for HTTPS requests +3. Check system logs for certificate status +4. Identify certificate configuration issues + +### Security Issues + +**Symptoms**: Security breaches or attacks + +**Log Analysis**: +1. Check ModSecurity logs for attack patterns +2. Check access logs for suspicious requests +3. Check system logs for authentication events +4. Identify attack sources and methods + +## API Integration + +For programmatic log access, use the REST API: + +### Get Logs +```bash +curl -X GET "http://localhost:3001/api/logs?type=access&domain=example.com&limit=100" \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Get Log Statistics +```bash +curl -X GET "http://localhost:3001/api/logs/stats?type=modsecurity&timeframe=24h" \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Get Available Domains +```bash +curl -X GET http://localhost:3001/api/logs/domains \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Download Logs +```bash +curl -X GET "http://localhost:3001/api/logs/download?type=error&format=json" \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -o logs.json +``` + +## Best Practices + +### Log Management + +1. **Regular Review**: Regularly review logs for issues +2. **Proactive Monitoring**: Set up alerts for critical log events +3. **Log Retention**: Implement appropriate log retention policies +4. **Log Security**: Secure log files and limit access + +### Security Analysis + +1. **Threat Detection**: Use logs to detect security threats +2. **Incident Response**: Use logs for incident response +3. **Forensics**: Maintain logs for forensic analysis +4. **Compliance**: Ensure logs meet compliance requirements + +### Performance Optimization + +1. **Bottleneck Identification**: Use logs to identify performance bottlenecks +2. **Trend Analysis**: Analyze performance trends over time +3. **Capacity Planning**: Use logs for capacity planning +4. **Optimization**: Optimize based on log analysis + +## Conclusion + +Log analysis is essential for maintaining system security, performance, and reliability. By following this guide, you should be able to: + +- View and filter different types of logs +- Search for specific log entries +- Analyze access patterns and security events +- Troubleshoot issues using log data +- Export logs for external analysis + +For more information on related topics: +- [Domain Management](/guide/domains) +- [SSL Certificate Management](/guide/ssl) +- [ModSecurity WAF Configuration](/guide/modsecurity) +- [Performance Monitoring](/guide/performance) \ No newline at end of file diff --git a/apps/docs/guide/modsecurity.md b/apps/docs/guide/modsecurity.md new file mode 100644 index 0000000..3e54010 --- /dev/null +++ b/apps/docs/guide/modsecurity.md @@ -0,0 +1,582 @@ +# ModSecurity WAF Guide + +This comprehensive guide covers ModSecurity Web Application Firewall (WAF) configuration in the Nginx WAF Management Platform, including OWASP Core Rule Set (CRS) management, custom rule creation, and advanced security configurations. + +## Overview + +ModSecurity is a web application firewall that protects your web applications from various attacks, including: + +- **SQL Injection (SQLi)**: Prevents database injection attacks +- **Cross-Site Scripting (XSS)**: Blocks malicious script injection +- **Remote File Inclusion (RFI)**: Prevents inclusion of remote files +- **Local File Inclusion (LFI)**: Blocks local file access attempts +- **Command Injection**: Prevents system command execution +- **Session Fixation**: Protects against session hijacking +- **Authentication Bypass**: Blocks unauthorized access attempts + +## ModSecurity Interface + +Access ModSecurity settings by: +1. Click **Domains** in the sidebar +2. Select a domain from the list +3. Click the **ModSecurity** tab + +![ModSecurity](/reference/screenshots/modsecurity.png) + +The ModSecurity interface provides: +- **Global Settings**: Enable/disable ModSecurity globally +- **CRS Rules**: OWASP Core Rule Set management +- **Custom Rules**: User-defined security rules +- **Rule Categories**: Organized rule categories +- **Paranoia Levels**: Security sensitivity settings + +## Enabling ModSecurity + +### Global ModSecurity Settings + +1. Click **ModSecurity** in the sidebar +2. Configure global settings: + - **Enable ModSecurity**: Turn on WAF protection + - **Default Paranoia Level**: Set default security level + - **Audit Logging**: Enable/disable security event logging + +### Domain-Specific ModSecurity + +1. Select a domain from the list +2. Click the **ModSecurity** tab +3. Toggle **Enable ModSecurity** for this domain +4. Configure domain-specific settings + +## OWASP Core Rule Set (CRS) + +The OWASP CRS is a set of generic attack detection rules that provide protection against many common attack categories. + +### CRS Rule Categories + +#### 1. Request Rule Set +- **REQUEST-910-IP-REPUTATION**: IP reputation blocking +- **REQUEST-911-METHOD-ENFORCEMENT**: HTTP method enforcement +- **REQUEST-912-DOS-PROTECTION**: Denial of service protection +- **REQUEST-913-SCANNER-DETECTION**: Web scanner detection +- **REQUEST-920-PROTOCOL-ENFORCEMENT**: Protocol validation +- **REQUEST-921-PROTOCOL-ATTACK**: Protocol attack detection +- **REQUEST-930-APPLICATION-ATTACK-LFI**: Local file inclusion attacks +- **REQUEST-931-APPLICATION-ATTACK-RFI**: Remote file inclusion attacks +- **REQUEST-932-APPLICATION-ATTACK-RCE**: Remote code execution attacks +- **REQUEST-933-APPLICATION-ATTACK-PHP**: PHP injection attacks +- **REQUEST-934-APPLICATION-ATTACK-NODEJS**: Node.js injection attacks +- **REQUEST-941-APPLICATION-ATTACK-XSS**: Cross-site scripting attacks +- **REQUEST-942-APPLICATION-ATTACK-SQLI**: SQL injection attacks +- **REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION**: Session fixation attacks +- **REQUEST-944-APPLICATION-ATTACK-JAVA**: Java injection attacks +- **REQUEST-949-BLOCKING-EVALUATION**: Rule evaluation and blocking + +#### 2. Response Rule Set +- **RESPONSE-950-DATA-LEAKAGES**: Data leakage detection +- **RESPONSE-951-DATA-LEAKAGES-SQL**: SQL error message detection +- **RESPONSE-952-DATA-LEAKAGES-JAVA**: Java error message detection +- **RESPONSE-953-DATA-LEAKAGES-PHP**: PHP error message detection +- **RESPONSE-954-DATA-LEAKAGES-IIS**: IIS error message detection +- **RESPONSE-959-BLOCKING-EVALUATION**: Response blocking evaluation + +### Managing CRS Rules + +#### Enable/Disable Rule Categories + +1. Select your domain +2. Click the **ModSecurity** tab +3. View available rule categories +4. Toggle categories on/off as needed + +#### Configure Individual Rules + +1. Click on a rule category to expand it +2. View individual rules within the category +3. Toggle specific rules on/off +4. Configure rule-specific settings + +### Paranoia Levels + +Paranoia levels determine the sensitivity of the WAF rules: + +#### Level 1 (Default) +- **Description**: Basic protection with minimal false positives +- **Use Case**: Production environments with standard applications +- **Rules**: Core protection rules only +- **False Positives**: Very low + +#### Level 2 +- **Description**: Enhanced protection with some false positives possible +- **Use Case**: Production environments requiring higher security +- **Rules**: All Level 1 rules + additional detection rules +- **False Positives**: Low + +#### Level 3 +- **Description**: High security with more false positives +- **Use Case**: High-security environments or sensitive applications +- **Rules**: All Level 2 rules + aggressive detection rules +- **False Positives**: Medium + +#### Level 4 +- **Description**: Maximum security with many false positives +- **Use Case**: High-risk environments or testing +- **Rules**: All Level 3 rules + experimental rules +- **False Positives**: High + +### Configuring Paranoia Levels + +1. Select your domain +2. Click the **ModSecurity** tab +3. Choose the appropriate paranoia level +4. Click **Save** + +⚠️ **Warning**: Higher paranoia levels may block legitimate traffic. Test thoroughly before deploying in production. + +## Custom Rules + +Create custom ModSecurity rules for application-specific security requirements. + +### Rule Syntax + +ModSecurity rules follow this syntax: +```modsecurity +SecRule VARIABLES OPERATOR [ACTIONS] +``` + +#### Example Custom Rules + +#### Block SQL Injection Attempts +```modsecurity +SecRule ARGS "@detectSQLi" \ + "id:1001,\ + phase:2,\ + block,\ + msg:'SQL Injection Attack Detected',\ + logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-sqli'" +``` + +#### Block XSS Attempts +```modsecurity +SecRule ARGS "@detectXSS" \ + "id:1002,\ + phase:2,\ + block,\ + msg:'XSS Attack Detected',\ + logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-xss'" +``` + +#### Block Bad User Agents +```modsecurity +SecRule REQUEST_HEADERS:User-Agent "@pmFromFile bad-user-agents.data" \ + "id:1003,\ + phase:1,\ + block,\ + msg:'Bad User Agent Blocked',\ + logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-useragent'" +``` + +#### Rate Limiting +```modsecurity +SecRule IP:@ipMatch "192.168.1.0/24" \ + "id:1004,\ + phase:1,\ + nolog,\ + pass,\ + ctl:ruleEngine=Off" +``` + +### Creating Custom Rules + +1. Select your domain +2. Click the **ModSecurity** tab +3. Click **Add Custom Rule** +4. Fill in rule details: + - **Name**: Descriptive rule name + - **Category**: Rule category (e.g., "Custom Security") + - **Rule Content**: ModSecurity rule syntax + - **Description**: What the rule does + - **Enabled**: Enable/disable the rule + +5. Click **Save** + +### Rule Variables + +ModSecurity provides various variables for rule matching: + +#### Request Variables +- `ARGS`: All request parameters +- `ARGS_NAMES`: Parameter names +- `ARGS_GET`: GET parameters +- `ARGS_POST`: POST parameters +- `REQUEST_HEADERS`: Request headers +- `REQUEST_COOKIES`: Request cookies +- `REQUEST_URI`: Request URI +- `REQUEST_METHOD`: HTTP method +- `REQUEST_BODY`: Request body + +#### Response Variables +- `RESPONSE_HEADERS`: Response headers +- `RESPONSE_BODY`: Response body +- `RESPONSE_STATUS`: HTTP status code + +### Operators + +ModSecurity provides various operators for pattern matching: + +#### String Operators +- `@rx`: Regular expression match +- `@pm`: Phrase match (any of the phrases) +- `@pmFromFile`: Phrase match from file +- `@contains`: Contains string +- `@beginsWith`: Begins with string +- `@endsWith`: Ends with string + +#### Numeric Operators +- `@eq`: Equal to +- `@gt`: Greater than +- `@lt`: Less than +- `@ge`: Greater than or equal to +- `@le`: Less than or equal to + +#### Special Operators +- `@detectSQLi`: SQL injection detection +- `@detectXSS`: XSS detection +- `@validateUtf8Encoding`: UTF-8 validation +- `@validateByteRange`: Byte range validation + +## Rule Actions + +ModSecurity supports various actions for rule processing: + +### Disruptive Actions +- **deny**: Deny the request with a 403 status +- **block**: Block the request (depends on configuration) +- **drop**: Drop the connection +- **redirect**: Redirect to another URL +- **pass**: Continue processing (no action) + +### Flow Actions +- **phase**: Set processing phase (1-5) +- **t:none**: No transformation +- **t:lowercase`: Convert to lowercase +- **t:urlDecode`: URL decode +- **t:htmlEntityDecode`: HTML entity decode + +### Data Actions +- **log**: Log the rule match +- **nolog**: Do not log the rule match +- **auditlog**: Write to audit log +- **noauditlog**: Do not write to audit log + +### Metadata Actions +- **id**: Unique rule identifier +- **msg**: Rule message +- **logdata**: Additional log data +- **tag**: Rule tags +- **severity**: Rule severity (1-5) + +## Advanced Configuration + +### Exception Handling + +Create exceptions for legitimate traffic that might be blocked: + +#### IP Whitelist +```modsecurity +SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \ + "id:2001,\ + phase:1,\ + nolog,\ + pass,\ + ctl:ruleEngine=Off" +``` + +#### URI Whitelist +```modsecurity +SecRule REQUEST_URI "@beginsWith /api/public/" \ + "id:2002,\ + phase:1,\ + nolog,\ + pass,\ + ctl:ruleRemoveById 941100" +``` + +#### Parameter Whitelist +```modsecurity +SecRule ARGS:product_code "@rx ^[A-Z0-9-]+$" \ + "id:2003,\ + phase:2,\ + nolog,\ + pass,\ + ctl:ruleRemoveTargetById 942100;ARGS:product_code" +``` + +### Anomaly Scoring + +Configure anomaly scoring for advanced threat detection: + +```modsecurity +# Set anomaly score threshold +SecAction "id:9001,\ + phase:1,\ + nolog,\ + pass,\ + t:none,\ + setvar:tx.anomaly_score_threshold=5" + +# Increase anomaly score for suspicious requests +SecRule ARGS "@detectSQLi" \ + "id:9002,\ + phase:2,\ + pass,\ + msg:'SQL Injection Attempt',\ + logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ + tag:'attack-sqli',\ + setvar:tx.anomaly_score=+3" + +# Block high anomaly scores +SecRule TX:ANOMALY_SCORE "@gt %{tx.anomaly_score_threshold}" \ + "id:9003,\ + phase:2,\ + block,\ + msg:'Anomaly Score Exceeded'" +``` + +## Monitoring and Logging + +### ModSecurity Logs + +Monitor ModSecurity activity through the system logs: + +1. Click **Logs** in the sidebar +2. Filter by **ModSecurity** log type +3. View security events and blocked requests + +### Audit Log Configuration + +Configure audit logging for detailed security analysis: + +1. Select your domain +2. Click the **ModSecurity** tab +3. Configure audit logging settings: + - **Enable Audit Log**: Turn on detailed logging + - **Log Parts**: Select which parts to log (A, B, C, D, E, F, G, H, I, J, K, Z) + - **Relevant Only**: Log only relevant requests + +### Log Parts + +- **A**: Audit log header +- **B**: Request headers +- **C**: Request body +- **D**: Reserved for intermediary response headers +- **E**: Intermediary response body +- **F**: Final response headers +- **G**: Final response body +- **H**: Audit log trailer +- **I**: Request bytes (minus) +- **J**: Response bytes (minus) +- **K**: Final boundary +- **Z**: Final boundary + +## Performance Considerations + +### Rule Optimization + +Optimize ModSecurity rules for better performance: + +1. **Use Specific Variables**: Target specific variables instead of generic ones +2. **Order Rules Efficiently**: Place most common rules first +3. **Use Appropriate Operators**: Choose the most efficient operator for the task +4. **Limit Rule Scope**: Apply rules only where needed + +### Performance Tuning + +Configure ModSecurity for optimal performance: + +```nginx +# ModSecurity configuration +modsecurity on; +modsecurity_rules_file /etc/nginx/modsec/main.conf; + +# Performance settings +SecRuleEngine On +SecAuditEngine RelevantOnly +SecAuditLogRelevantStatus "^(?:5|4(?!04))" +SecAuditLogParts ABIJDEFHZ +SecAuditLog /var/log/modsec_audit.log + +# Connection settings +SecConnReadStateLimit 100 +SecConnWriteStateLimit 100 +``` + +## Troubleshooting + +### Common Issues + +#### False Positives + +**Symptoms**: Legitimate requests are being blocked + +**Solutions**: +1. Identify the blocking rule from logs +2. Create an exception rule +3. Adjust paranoia level +4. Fine-tune specific rules + +#### Performance Issues + +**Symptoms**: Slow response times, high CPU usage + +**Solutions**: +1. Optimize rule order +2. Use more specific variables +3. Disable unnecessary rules +4. Enable rule caching + +#### Rule Conflicts + +**Symptoms**: Rules not working as expected + +**Solutions**: +1. Check rule IDs for conflicts +2. Verify rule execution phases +3. Review rule execution order +4. Test rules individually + +### Debug Mode + +Enable ModSecurity debug mode for detailed logging: + +1. Go to **System** settings +2. Enable **ModSecurity Debug Mode** +3. Set debug log level (0-9) +4. Check debug logs in **Logs** section +5. Disable debug mode when finished + +### Testing Rules + +Test ModSecurity rules before deployment: + +```bash +# Test rule syntax +modsec-rules-check /etc/nginx/modsec/custom_rules.conf + +# Test with curl +curl -X POST http://example.com/ \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "param=test' OR 1=1--" +``` + +## Best Practices + +### Rule Management + +1. **Use Unique IDs**: Ensure each rule has a unique ID +2. **Document Rules**: Add clear descriptions and tags +3. **Version Control**: Keep rules under version control +4. **Regular Updates**: Update CRS rules regularly + +### Security + +1. **Defense in Depth**: Use multiple layers of security +2. **Regular Testing**: Test rules in staging before production +3. **Monitor Logs**: Regularly review security logs +4. **Update Signatures**: Keep attack signatures updated + +### Performance + +1. **Optimize Rules**: Keep rules efficient and targeted +2. **Monitor Performance**: Track WAF performance impact +3. **Use Caching**: Enable rule caching where possible +4. **Regular Maintenance**: Remove unused or redundant rules + +## API Integration + +For programmatic ModSecurity management, use the REST API: + +### List CRS Rules +```bash +curl -X GET http://localhost:3001/api/modsec/crs-rules \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Toggle CRS Rule +```bash +curl -X PATCH http://localhost:3001/api/modsec/crs/rules/RULE_FILE/toggle \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "enabled": false + }' +``` + +### List Custom Rules +```bash +curl -X GET http://localhost:3001/api/modsec/rules \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Create Custom Rule +```bash +curl -X POST http://localhost:3001/api/modsec/rules \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "Block SQL Injection", + "category": "Security", + "ruleContent": "SecRule ARGS \"@detectSQLi\" \"id:1001,phase:2,block,msg:\"SQL Injection Attack Detected\"\"", + "description": "Blocks SQL injection attempts", + "enabled": true + }' +``` + +### Update Custom Rule +```bash +curl -X PUT http://localhost:3001/api/modsec/rules/RULE_ID \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "Block SQL Injection", + "category": "Security", + "ruleContent": "SecRule ARGS \"@detectSQLi\" \"id:1001,phase:2,block,msg:\"SQL Injection Attack Detected\"\"", + "description": "Blocks SQL injection attempts", + "enabled": false + }' +``` + +### Delete Custom Rule +```bash +curl -X DELETE http://localhost:3001/api/modsec/rules/RULE_ID \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +For complete API documentation, see the [API Reference](/api/modsecurity). + +## Conclusion + +ModSecurity WAF is a powerful tool for protecting your web applications. By following this guide, you should be able to: + +- Configure ModSecurity for optimal protection +- Manage OWASP CRS rules effectively +- Create custom security rules +- Monitor and analyze security events +- Troubleshoot common WAF issues + +For more information on related topics: +- [Domain Management](/guide/domains) +- [SSL Certificate Management](/guide/ssl) +- [Log Analysis](/guide/logs) +- [Performance Monitoring](/guide/performance) \ No newline at end of file diff --git a/apps/docs/guide/performance.md b/apps/docs/guide/performance.md new file mode 100644 index 0000000..7c47a08 --- /dev/null +++ b/apps/docs/guide/performance.md @@ -0,0 +1,531 @@ +# Performance Monitoring Guide + +This comprehensive guide covers performance monitoring in the Nginx WAF Management Platform, including system metrics, domain performance tracking, alert configuration, and performance optimization. + +## Overview + +The performance monitoring system provides: +- **Real-time Metrics**: Live system and domain performance data +- **Historical Analysis**: Performance trends over time +- **Alert System**: Configurable alerts for performance issues +- **Performance Reports**: Detailed performance analytics +- **Bottleneck Identification**: Tools to identify performance issues +- **Capacity Planning**: Data for scaling decisions + +## Performance Monitoring Interface + +Access performance monitoring by clicking **Performance** in the sidebar navigation: + +![Performance](/reference/screenshots/Performance.png) + +The performance interface provides: +- **System Metrics**: CPU, memory, network, and disk usage +- **Domain Performance**: Request rates, response times, error rates +- **Historical Data**: Performance trends over time +- **Alert Status**: Active and recent performance alerts +- **Performance Reports**: Detailed analytics and insights + +## System Metrics + +Monitor overall system performance through key metrics: + +### CPU Usage + +Track CPU utilization across all cores: + +- **Current Usage**: Real-time CPU percentage +- **Core Distribution**: Usage per CPU core +- **Process Breakdown**: CPU usage by process +- **Historical Trends**: CPU usage over time + +**Normal Range**: 0-70% for healthy systems +**Warning Range**: 70-85% for systems under load +**Critical Range**: 85-100% for systems in distress + +### Memory Usage + +Monitor memory utilization and allocation: + +- **Total Memory**: System RAM capacity +- **Used Memory**: Currently allocated memory +- **Free Memory**: Available memory +- **Cached Memory**: Memory used for caching +- **Swap Usage**: Virtual memory usage + +**Memory Types**: +- **RAM**: Physical memory +- **Swap**: Virtual memory on disk +- **Buffers**: Memory for I/O operations +- **Cache**: Memory for frequently accessed data + +### Network Usage + +Track network traffic and connectivity: + +- **Bandwidth**: Incoming and outgoing traffic +- **Connection Count**: Active network connections +- **Packet Loss**: Percentage of lost packets +- **Latency**: Network response times + +**Network Metrics**: +- **Throughput**: Data transfer rate (Mbps/Gbps) +- **Connections**: Active TCP/UDP connections +- **Errors**: Network errors and retransmissions +- **Interface Stats**: Per-network interface statistics + +### Disk Usage + +Monitor disk space and I/O performance: + +- **Disk Space**: Used and available disk space +- **I/O Operations**: Read/write operations per second +- **Disk Latency**: Average response times +- **Disk Queue**: Pending I/O operations + +**Disk Metrics**: +- **Usage Percentage**: Disk space utilization +- **Read/Write Speed**: Data transfer rates +- **IOPS**: Input/output operations per second +- **Queue Depth**: Number of pending operations + +## Domain Performance + +Monitor performance metrics for individual domains: + +### Request Metrics + +Track request volume and patterns: + +- **Request Rate**: Requests per second (RPS) +- **Request Count**: Total requests over time period +- **Request Methods**: Distribution of GET, POST, PUT, DELETE +- **Request Size**: Average request payload size + +### Response Metrics + +Monitor response performance: + +- **Response Time**: Average time to first byte (TTFB) +- **Response Size**: Average response payload size +- **Response Codes**: Distribution of HTTP status codes +- **Response Rate**: Responses per second + +### Error Metrics + +Track errors and issues: + +- **Error Rate**: Percentage of failed requests +- **4xx Errors**: Client-side errors (400-499) +- **5xx Errors**: Server-side errors (500-599) +- **Timeouts**: Request timeout occurrences + +### SSL Metrics + +Monitor SSL/TLS performance: + +- **Handshake Time**: SSL negotiation time +- **Session Resumption**: SSL session reuse rate +- **Cipher Usage**: Distribution of SSL ciphers +- **Protocol Usage**: SSL/TLS protocol versions + +## Performance Dashboard + +The main performance dashboard provides an overview of system health: + +### System Overview + +- **CPU Usage**: Real-time CPU utilization +- **Memory Usage**: Current memory consumption +- **Network Traffic**: Incoming/outgoing bandwidth +- **Disk Usage**: Storage utilization +- **Load Average**: System load over time periods + +### Domain Performance + +- **Top Domains**: Domains by request volume +- **Response Times**: Average response times by domain +- **Error Rates**: Error percentages by domain +- **Throughput**: Data transfer rates by domain + +### Recent Alerts + +- **Active Alerts**: Currently unresolved performance issues +- **Recent History**: Recently resolved alerts +- **Alert Severity**: Critical, warning, or info alerts +- **Alert Sources**: System components generating alerts + +## Historical Analysis + +Analyze performance trends over time: + +### Time Range Selection + +Select custom time ranges for analysis: +- **Last Hour**: Recent performance data +- **Last 24 Hours**: Daily performance patterns +- **Last 7 Days**: Weekly performance trends +- **Last 30 Days**: Monthly performance analysis +- **Custom Range**: Specific date and time range + +### Performance Graphs + +Visualize performance data with interactive graphs: + +- **Line Graphs**: Trends over time +- **Bar Charts**: Comparisons between categories +- **Heat Maps**: Performance patterns by time +- **Area Charts**: Cumulative metrics + +### Performance Reports + +Generate detailed performance reports: + +#### System Performance Report + +- **Executive Summary**: Key performance indicators +- **Resource Utilization**: CPU, memory, disk, network usage +- **Performance Trends**: Historical performance data +- **Bottleneck Analysis**: Identified performance issues +- **Recommendations**: Optimization suggestions + +#### Domain Performance Report + +- **Traffic Analysis**: Request patterns and volume +- **Response Performance**: Response times and throughput +- **Error Analysis**: Error rates and types +- **SSL Performance**: SSL/TLS metrics +- **User Experience**: Page load times and availability + +## Alert Configuration + +Configure alerts to notify you of performance issues: + +### Alert Types + +#### System Alerts + +- **High CPU Usage**: CPU utilization exceeds threshold +- **High Memory Usage**: Memory utilization exceeds threshold +- **Low Disk Space**: Available disk space below threshold +- **Network Issues**: High latency or packet loss + +#### Domain Alerts + +- **High Response Time**: Response time exceeds threshold +- **High Error Rate**: Error percentage exceeds threshold +- **Low Throughput**: Request rate below threshold +- **SSL Certificate Expiry**: Certificate expiring soon + +### Creating Alert Rules + +1. Click **Alerts** in the sidebar +2. Go to **Alert Rules** tab +3. Click **Add Alert Rule** +4. Configure alert parameters: + +![Alert Rule](/reference/screenshots/alert_rule.png) + +**Alert Configuration**: +- **Name**: Descriptive alert name +- **Condition**: Performance metric to monitor +- **Threshold**: Alert trigger value +- **Severity**: Critical, warning, or info +- **Check Interval**: How often to check the condition + +**Example Alert Rules**: + +1. **High CPU Usage**: + ``` + Name: High CPU Usage + Condition: cpu > 80 + Threshold: 80% + Severity: Warning + Check Interval: 300 seconds (5 minutes) + ``` + +2. **Slow Response Time**: + ``` + Name: Slow Response Time + Condition: response_time > 1000 + Threshold: 1000ms + Severity: Warning + Check Interval: 60 seconds (1 minute) + ``` + +3. **High Error Rate**: + ``` + Name: High Error Rate + Condition: error_rate > 5 + Threshold: 5% + Severity: Critical + Check Interval: 60 seconds (1 minute) + ``` + +### Notification Channels + +Configure how alerts are delivered: + +#### Email Notifications + +1. Click **Alerts** in the sidebar +2. Go to **Notification Channels** tab +3. Click **Add Channel** +4. Select **Email** as channel type + +![Alert Channel](/reference/screenshots/alert_chanel.png) + +**Email Configuration**: +- **Name**: Channel name (e.g., "Email Alerts") +- **SMTP Server**: Mail server address +- **SMTP Port**: Mail server port (587 for TLS) +- **Username**: SMTP username +- **Password**: SMTP password or app password +- **Recipients**: Email addresses to receive alerts + +#### Telegram Notifications + +1. Click **Add Channel** +2. Select **Telegram** as channel type + +**Telegram Configuration**: +- **Name**: Channel name (e.g., "Telegram Bot") +- **Bot Token**: Telegram bot token +- **Chat ID**: Telegram chat ID for notifications + +### Alert Management + +#### Viewing Alerts + +1. Click **Alerts** in the sidebar +2. View active and historical alerts +3. Filter by severity, source, or time range + +#### Acknowledging Alerts + +1. Select an alert from the list +2. Click **Acknowledge** +3. Add acknowledgment notes +4. Alert will be marked as acknowledged + +#### Resolving Alerts + +1. Select an alert from the list +2. Click **Resolve** +3. Add resolution notes +4. Alert will be marked as resolved + +## Performance Optimization + +Use performance data to optimize your system: + +### Identifying Bottlenecks + +Analyze performance metrics to identify bottlenecks: + +#### CPU Bottlenecks + +**Symptoms**: +- High CPU utilization (>80%) +- Slow response times +- High load averages + +**Solutions**: +- Optimize application code +- Enable caching +- Scale horizontally (add more servers) +- Upgrade CPU resources + +#### Memory Bottlenecks + +**Symptoms**: +- High memory utilization (>80%) +- Swap usage +- Out-of-memory errors + +**Solutions**: +- Optimize memory usage +- Increase memory allocation +- Fix memory leaks +- Implement memory caching + +#### Network Bottlenecks + +**Symptoms**: +- High network latency +- Packet loss +- Low throughput + +**Solutions**: +- Optimize network configuration +- Increase bandwidth +- Implement CDN +- Optimize application protocols + +#### Disk Bottlenecks + +**Symptoms**: +- High disk I/O wait +- Slow disk operations +- Low disk space + +**Solutions**: +- Optimize disk usage +- Implement disk caching +- Upgrade to faster storage +- Clean up unnecessary files + +### Performance Tuning + +#### Nginx Optimization + +Optimize Nginx configuration for better performance: + +```nginx +# Worker processes (equal to CPU cores) +worker_processes auto; + +# Worker connections +worker_connections 1024; + +# Keep alive timeout +keepalive_timeout 65; + +# Enable gzip compression +gzip on; +gzip_vary on; +gzip_min_length 1024; +gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + +# Enable caching +location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { + expires 1y; + add_header Cache-Control "public, immutable"; +} +``` + +#### Application Optimization + +Optimize your backend applications: + +- **Database Optimization**: Optimize queries, add indexes +- **Caching**: Implement Redis or Memcached +- **Connection Pooling**: Reuse database connections +- **Code Optimization**: Profile and optimize slow code + +#### SSL Optimization + +Optimize SSL/TLS configuration: + +```nginx +# SSL session cache +ssl_session_cache shared:SSL:10m; +ssl_session_timeout 10m; + +# SSL protocols +ssl_protocols TLSv1.2 TLSv1.3; + +# SSL ciphers +ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; + +# Enable OCSP stapling +ssl_stapling on; +ssl_stapling_verify on; +``` + +## Capacity Planning + +Use performance data for capacity planning: + +### Resource Scaling + +Plan resource scaling based on performance trends: + +- **CPU Scaling**: Add CPU cores when utilization exceeds 70% +- **Memory Scaling**: Add RAM when usage exceeds 80% +- **Disk Scaling**: Add storage when usage exceeds 80% +- **Network Scaling**: Increase bandwidth when utilization exceeds 70% + +### Load Balancing + +Optimize load balancing for better performance: + +- **Algorithm Selection**: Choose appropriate load balancing algorithm +- **Health Checks**: Configure proper health checks +- **Session Persistence**: Implement sticky sessions if needed +- **Failover**: Configure proper failover mechanisms + +### Performance Monitoring + +Implement continuous performance monitoring: + +- **Baseline Metrics**: Establish performance baselines +- **Trend Analysis**: Monitor performance trends over time +- **Anomaly Detection**: Identify unusual performance patterns +- **Predictive Analysis**: Forecast future resource needs + +## API Integration + +For programmatic performance monitoring, use the REST API: + +### Get Performance Metrics +```bash +curl -X GET "http://localhost:3001/api/performance/metrics?metric=cpu&timeframe=1h" \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Get Performance Stats +```bash +curl -X GET http://localhost:3001/api/performance/stats \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Get Performance History +```bash +curl -X GET "http://localhost:3001/api/performance/history?domain=example.com&timeframe=24h" \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Cleanup Old Metrics +```bash +curl -X DELETE http://localhost:3001/api/performance/cleanup \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +## Best Practices + +### Performance Monitoring + +1. **Set Baselines**: Establish performance baselines for comparison +2. **Monitor Continuously**: Implement continuous monitoring +3. **Configure Alerts**: Set up appropriate alerts for issues +4. **Review Regularly**: Regularly review performance data + +### Performance Optimization + +1. **Identify Bottlenecks**: Use data to identify performance issues +2. **Optimize Systematically**: Address issues systematically +3. **Test Changes**: Test optimizations before deployment +4. **Monitor Impact**: Monitor the impact of optimizations + +### Capacity Planning + +1. **Plan for Growth**: Plan for future growth requirements +2. **Monitor Trends**: Monitor performance trends over time +3. **Scale Proactively**: Scale resources before issues occur +4. **Document Decisions**: Document scaling decisions and rationale + +## Conclusion + +Performance monitoring is essential for maintaining system health and optimizing user experience. By following this guide, you should be able to: + +- Monitor system and domain performance effectively +- Configure alerts for performance issues +- Analyze performance trends and identify bottlenecks +- Optimize system performance based on data +- Plan for future capacity needs + +For more information on related topics: +- [Domain Management](/guide/domains) +- [SSL Certificate Management](/guide/ssl) +- [ModSecurity WAF Configuration](/guide/modsecurity) +- [Log Analysis](/guide/logs) \ No newline at end of file diff --git a/apps/docs/guide/quick-start.md b/apps/docs/guide/quick-start.md new file mode 100644 index 0000000..0962ace --- /dev/null +++ b/apps/docs/guide/quick-start.md @@ -0,0 +1,417 @@ +# Quick Start Guide + +This guide will help you get up and running with the Nginx WAF Management Platform quickly. We'll walk you through the essential steps to configure your first domain and enable security features. + +## Prerequisites + +Before you begin, ensure you have: +- Completed the [installation](/guide/installation) process +- Access to the web interface (http://localhost:8080 or http://YOUR_IP:8080) +- Default login credentials (admin/admin123) + +## Step 1: First Login + +### Access the Login Page + +Open your web browser and navigate to the nginx-love interface: +- **Development**: http://localhost:8080 +- **Production**: http://YOUR_IP:8080 + +You'll see the login screen: + +![Login Screen](/reference/screenshots/login.png) + +### Initial Login + +Use the default credentials: +``` +Username: admin +Password: admin123 +``` + +⚠️ **Security Warning**: You'll be prompted to change the default password immediately after login. + +### Change Default Password + +1. After successful login, you'll be redirected to the profile page +2. Enter your current password (admin123) +3. Set a strong new password with at least 8 characters +4. Confirm the new password +5. Click "Change Password" + +## Step 2: Dashboard Overview + +After changing your password, you'll be taken to the main dashboard: + +![Dashboard](/reference/screenshots/Dashboard.png) + +The dashboard provides: +- **System Overview**: CPU, Memory, and Network statistics +- **Domain Statistics**: Active domains, SSL status, and security alerts +- **Recent Activity**: Latest system events and configuration changes +- **Quick Actions**: Easy access to common tasks + +## Step 3: Add Your First Domain + +### Navigate to Domain Management + +1. Click on **Domains** in the sidebar navigation +2. You'll see the domain management interface: + +![Domain Management](/reference/screenshots/Domain_Management.png) + +### Create a New Domain + +1. Click the **Add Domain** button +2. Fill in the domain details: + +![Add Domain](/reference/screenshots/domain_add.png) + +**Required Fields:** +- **Domain Name**: e.g., `example.com` or `api.example.com` +- **Upstream Servers**: At least one backend server + +**Upstream Configuration:** +- **Host**: IP address or hostname of your backend server +- **Port**: Port number (e.g., 80, 8080, 3000) +- **Protocol**: HTTP or HTTPS +- **Weight**: Load balancing weight (default: 1) +- **Max Fails**: Maximum failed attempts before marking as down (default: 3) +- **Fail Timeout**: Timeout in seconds before retrying (default: 10) + +**Example Configuration:** +``` +Domain Name: api.example.com +Upstream Server 1: + Host: 192.168.1.100 + Port: 8080 + Protocol: HTTP + Weight: 1 + Max Fails: 3 + Fail Timeout: 10 +``` + +3. Click **Save** to create the domain + +### Verify Domain Creation + +After saving, you'll see your new domain in the list with status indicators: +- **Status**: Active/Inactive/Error +- **SSL**: Enabled/Disabled +- **ModSecurity**: Enabled/Disabled +- **Upstreams**: Health status of backend servers + +## Step 4: Configure SSL Certificate + +### Enable SSL for Your Domain + +1. Select your domain from the list +2. Click the **SSL** tab +3. Click **Enable SSL** + +### Choose SSL Method + +You have two options for SSL certificates: + +#### Option 1: Let's Encrypt (Recommended) + +![Add SSL](/reference/screenshots/ssl_add.png) + +1. Select **Let's Encrypt** as the certificate provider +2. Enter your email address for certificate notifications +3. Ensure your domain points to this server (DNS A record) +4. Click **Save and Issue Certificate** + +The system will: +- Validate domain ownership +- Generate a certificate +- Configure automatic renewal (default: 30 days before expiry) + +#### Option 2: Manual Certificate Upload + +1. Select **Manual Upload** +2. Upload your certificate files: + - **Certificate**: Your domain certificate (.crt or .pem) + - **Private Key**: Your private key (.key) + - **Chain**: Certificate chain (optional) +3. Enter issuer information +4. Click **Save** + +### Verify SSL Configuration + +After successful configuration, you'll see: + +![SSL Certificate](/reference/screenshots/ssl_cert.png) + +- **Certificate Details**: Common name, SANs, issuer, validity period +- **Auto-renewal Status**: Enabled/Disabled +- **Certificate Status**: Valid/Expiring/Expired + +## Step 5: Configure ModSecurity WAF + +### Enable ModSecurity + +1. Select your domain from the list +2. Click the **ModSecurity** tab +3. Toggle **Enable ModSecurity** + +![ModSecurity](/reference/screenshots/modsecurity.png) + +### Configure OWASP CRS Rules + +1. **Rule Categories**: View available rule categories + - SQL Injection Protection + - Cross-Site Scripting (XSS) + - Remote File Inclusion + - PHP Injection + - Session Fixation + +2. **Paranoia Level**: Choose security level + - **Level 1**: Default (recommended for most applications) + - **Level 2**: Higher security, some false positives possible + - **Level 3**: Very high security, more false positives + - **Level 4**: Maximum security, requires extensive testing + +3. **Enable/Disable Rules**: Toggle individual rules as needed + +### Add Custom Rules (Optional) + +1. Click **Add Custom Rule** +2. Enter rule details: + - **Name**: Descriptive rule name + - **Category**: Rule category + - **Rule Content**: ModSecurity rule syntax + - **Description**: What the rule does +3. Click **Save** + +Example custom rule: +``` +SecRule REQUEST_HEADERS:User-Agent "@rx bot|crawler|scanner" \ + "id:1001,\ + phase:1,\ + deny,\ + status:403,\ + msg:'Block known bots and scanners'" +``` + +## Step 6: Configure Access Control Lists (ACL) + +### Navigate to ACL Settings + +1. Click **ACL** in the sidebar +2. You'll see the ACL management interface: + +![ACL](/reference/screenshots/acl.png) + +### Create ACL Rules + +1. Click **Add ACL Rule** +2. Configure rule parameters: + +![Add ACL](/reference/screenshots/ACL_add.png) + +**Rule Configuration:** +- **Name**: Descriptive rule name +- **Type**: Whitelist or Blacklist +- **Condition Field**: IP, GeoIP, User-Agent, URL, Method, Header +- **Operator**: Equals, Contains, Regex +- **Condition Value**: The value to match +- **Action**: Allow, Deny, Challenge + +**Example Rules:** + +1. **Block Specific IP**: + ``` + Name: Block Malicious IP + Type: Blacklist + Field: IP + Operator: Equals + Value: 192.168.1.50 + Action: Deny + ``` + +2. **Allow Internal Network**: + ``` + Name: Allow Internal Network + Type: Whitelist + Field: IP + Operator: Regex + Value: ^192\.168\.1\. + Action: Allow + ``` + +3. **Block Bad Bots**: + ``` + Name: Block Bad Bots + Type: Blacklist + Field: User-Agent + Operator: Contains + Value: malware + Action: Deny + ``` + +## Step 7: Set Up Monitoring and Alerts + +### Configure Notification Channels + +1. Click **Alerts** in the sidebar +2. Go to **Notification Channels** tab +3. Click **Add Channel** + +![Alert Channel](/reference/screenshots/alert_chanel.png) + +**Email Channel Configuration:** +- **Name**: Email Notifications +- **Type**: Email +- **SMTP Settings**: Server, port, username, password +- **Recipients**: Email addresses to receive alerts + +**Telegram Channel Configuration:** +- **Name**: Telegram Bot +- **Type**: Telegram +- **Bot Token**: Your Telegram bot token +- **Chat ID**: Telegram chat ID for notifications + +### Create Alert Rules + +1. Go to **Alert Rules** tab +2. Click **Add Rule** + +![Alert Rule](/reference/screenshots/alert_rule.png) + +**Common Alert Rules:** + +1. **High CPU Usage**: + ``` + Name: High CPU Usage + Condition: cpu > 80 + Threshold: 80 + Severity: Warning + Check Interval: 300 seconds + ``` + +2. **Backend Server Down**: + ``` + Name: Backend Server Down + Condition: upstream_status == down + Threshold: 1 + Severity: Critical + Check Interval: 60 seconds + ``` + +3. **SSL Certificate Expiry**: + ``` + Name: SSL Certificate Expiring + Condition: ssl_days_to_expiry < 30 + Threshold: 30 + Severity: Warning + Check Interval: 86400 seconds (24 hours) + ``` + +## Step 8: User Management + +### Create Additional Users + +1. Click **Users** in the sidebar +2. You'll see the user management interface: + +![User Management](/reference/screenshots/User_Management.png) + +3. Click **Add User** +4. Fill in user details: + - **Username**: Unique username + - **Email**: Email address + - **Full Name**: Display name + - **Role**: Admin, Moderator, or Viewer + - **Password**: Initial password + - **Status**: Active or Inactive + +**User Roles:** +- **Admin**: Full access to all features and settings +- **Moderator**: Can manage domains, SSL, and security rules +- **Viewer**: Read-only access to dashboards and reports + +## Step 9: Performance Monitoring + +### View Performance Metrics + +1. Click **Performance** in the sidebar +2. You'll see performance monitoring: + +![Performance](/reference/screenshots/Performance.png) + +**Available Metrics:** +- **Response Time**: Average response time over time +- **Throughput**: Requests per second +- **Error Rate**: Percentage of failed requests +- **Bandwidth**: Network usage statistics + +### Analyze Domain Performance + +1. Select a specific domain from the dropdown +2. View detailed metrics for that domain +3. Identify performance bottlenecks +4. Monitor trends over time + +## Step 10: Log Analysis + +### View System Logs + +1. Click **Logs** in the sidebar +2. Filter logs by: + - **Type**: Access, Error, ModSecurity, System + - **Domain**: Specific domain + - **Time Range**: Custom date range + - **Severity**: Error, Warning, Info + +![Domain Logs](/reference/screenshots/domain_log.png) + +### Search and Filter Logs + +1. Use the search bar to find specific log entries +2. Apply filters to narrow down results +3. Export logs for further analysis +4. Monitor security events in real-time + +## What's Next? + +Congratulations! You've successfully set up your first domain with the Nginx WAF Management Platform. Here are some recommended next steps: + +### Additional Configuration + +1. **Set Up Backup**: Configure regular backups of your configuration +2. **Fine-tune Security**: Adjust ModSecurity rules based on your application needs +3. **Optimize Performance**: Monitor and optimize load balancing settings +4. **Configure Additional Domains**: Add more domains to manage + +### Advanced Features + +- [**SSL Certificate Management**](/guide/ssl): Learn about advanced SSL configurations +- [**ModSecurity Rules**](/guide/modsecurity): Create custom WAF rules +- [**Performance Optimization**](/guide/performance): Advanced monitoring and optimization +- [**Log Analysis**](/guide/logs): Deep dive into log analysis and troubleshooting +- [**API Integration**](/api/): Integrate with external systems via REST API + +### Maintenance and Monitoring + +- Regularly check system health and performance +- Monitor SSL certificate expiry dates +- Review security logs for potential threats +- Keep the system updated with latest security patches + +## Need Help? + +If you encounter any issues or have questions: + +- Check our [troubleshooting guide](/reference/troubleshooting) +- Review the [FAQ](/reference/faq) +- Browse our [API documentation](/api/) +- Contact support for assistance + +## Installation Complete + +The installation wizard will show a completion screen when all components are successfully installed: + +![Installation Complete](/reference/screenshots/installation_complete.png) + +Your nginx-love platform is now ready for production use! \ No newline at end of file diff --git a/apps/docs/guide/ssl.md b/apps/docs/guide/ssl.md new file mode 100644 index 0000000..46b4130 --- /dev/null +++ b/apps/docs/guide/ssl.md @@ -0,0 +1,462 @@ +# SSL Certificate Management Guide + +This comprehensive guide covers SSL certificate management in the Nginx WAF Management Platform, including Let's Encrypt automation, manual certificate uploads, renewal processes, and troubleshooting. + +## Overview + +The SSL management system provides: +- **Automated Let's Encrypt Certificates**: Free, automated SSL certificates +- **Manual Certificate Upload**: Support for custom certificates +- **Automatic Renewal**: Configurable auto-renewal with alerts +- **Certificate Monitoring**: Track expiry dates and status +- **Multi-Domain Support**: SAN certificates and wildcard domains +- **Certificate Chain Management**: Complete certificate chain handling + +## SSL Management Interface + +Access SSL management by: +1. Click **Domains** in the sidebar +2. Select a domain from the list +3. Click the **SSL** tab + +![SSL Certificate](/reference/screenshots/ssl_cert.png) + +The SSL interface provides: +- **Certificate Status**: Visual indicators for certificate validity +- **Certificate Details**: Complete certificate information +- **Renewal Settings**: Auto-renewal configuration +- **Quick Actions**: Common SSL operations + +## Let's Encrypt Certificates + +Let's Encrypt provides free, automated SSL certificates that are ideal for most use cases. + +### Prerequisites for Let's Encrypt + +Before requesting a Let's Encrypt certificate, ensure: + +1. **Domain DNS**: Your domain must point to this server's IP address +2. **Port 80 Access**: Port 80 must be accessible for domain validation +3. **Email Address**: Valid email for certificate notifications +4. **Domain Ownership**: You must control the domain + +### Requesting a Let's Encrypt Certificate + +1. Select your domain from the list +2. Click the **SSL** tab +3. Click **Enable SSL** +4. Select **Let's Encrypt** as the certificate provider + +![Add SSL](/reference/screenshots/ssl_add.png) + +5. Configure the certificate settings: + - **Email Address**: For certificate notifications and recovery + - **Auto-Renew**: Enable automatic renewal (recommended) + - **Renewal Days**: Days before expiry to renew (default: 30) + +6. Click **Save and Issue Certificate** + +### Certificate Validation Process + +Let's Encrypt uses the HTTP-01 challenge to validate domain ownership: + +1. **Challenge File**: A temporary file is created in `/.well-known/acme-challenge/` +2. **Domain Verification**: Let's Encrypt attempts to access this file +3. **Certificate Issuance**: If successful, the certificate is issued +4. **Installation**: Certificate is automatically installed and configured + +### Let's Encrypt Certificate Types + +#### Single Domain Certificate +Covers only the specific domain name: +``` +Domain: example.com +Covers: example.com +``` + +#### SAN Certificate (Multiple Domains) +Covers multiple domains in one certificate: +``` +Domains: example.com, www.example.com, api.example.com +Covers: All listed domains +``` + +#### Wildcard Certificate +Covers a domain and all its subdomains: +``` +Domain: *.example.com +Covers: example.com, www.example.com, api.example.com, etc. +``` + +⚠️ **Note**: Wildcard certificates require DNS validation, which may need manual configuration. + +## Manual Certificate Upload + +For scenarios where Let's Encrypt isn't suitable, you can upload custom certificates. + +### When to Use Manual Certificates + +- **Internal Domains**: Private/internal domain names +- **Corporate Certificates**: Organization-specific certificates +- **Extended Validation (EV)**: EV certificates that require special validation +- **Special Requirements**: Custom certificate requirements + +### Uploading a Manual Certificate + +1. Select your domain from the list +2. Click the **SSL** tab +3. Click **Enable SSL** +4. Select **Manual Upload** as the certificate provider + +5. Upload the certificate files: + - **Certificate**: Your domain certificate (.crt or .pem file) + - **Private Key**: Your private key (.key file) + - **Certificate Chain**: Optional intermediate certificates + +6. Enter certificate details: + - **Issuer**: Certificate authority (e.g., "DigiCert", "GlobalSign") + - **Auto-Renew**: Enable/disable auto-renewal (if applicable) + +7. Click **Save** + +### Certificate File Formats + +#### Certificate File (.crt, .pem) +``` +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJAKoKHHqH1+5cMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +... +-----END CERTIFICATE----- +``` + +#### Private Key File (.key) +``` +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5... +-----END PRIVATE KEY----- +``` + +#### Certificate Chain File (.ca-bundle) +``` +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJAKoKHHqH1+5cMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +... +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJAKoKHHqH1+5cMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV +... +-----END CERTIFICATE----- +``` + +## Certificate Management + +### Certificate Status Indicators + +Certificates display status indicators: + +- **Valid**: Certificate is valid and not expiring soon +- **Expiring**: Certificate expires within 30 days +- **Expired**: Certificate has expired +- **Error**: Certificate has configuration errors + +### Certificate Details + +View comprehensive certificate information: + +- **Common Name**: Primary domain name +- **Subject Alternative Names (SANs)**: Additional domains covered +- **Issuer**: Certificate authority +- **Valid From**: Certificate issue date +- **Valid To**: Certificate expiry date +- **Serial Number**: Certificate serial number +- **Signature Algorithm**: Encryption algorithm used +- **Fingerprint**: Certificate fingerprint for verification + +### Certificate Operations + +#### Renew Certificate +1. Select the certificate +2. Click **Renew Certificate** +3. Confirm the renewal action + +#### Replace Certificate +1. Select the certificate +2. Click **Replace Certificate** +3. Upload new certificate files +4. Click **Save** + +#### Delete Certificate +⚠️ **Warning**: This will disable SSL for the domain. + +1. Select the certificate +2. Click **Delete Certificate** +3. Confirm the deletion + +## Automatic Renewal + +Configure automatic renewal to ensure certificates never expire. + +### Renewal Configuration + +1. Select your domain +2. Click the **SSL** tab +3. Configure renewal settings: + - **Auto-Renew**: Enable/disable automatic renewal + - **Renewal Days**: Days before expiry to renew (default: 30) + - **Notification Email**: Email for renewal notifications + +### Renewal Process + +The automatic renewal process: + +1. **Expiry Check**: System checks certificate expiry daily +2. **Renewal Trigger**: Renewal starts when certificate is within renewal period +3. **Certificate Request**: New certificate is requested from Let's Encrypt +4. **Validation**: Domain ownership is validated +5. **Installation**: New certificate is installed +6. **Notification**: Success/failure notification is sent + +### Renewal Notifications + +Configure notifications for renewal events: + +- **Success Notifications**: Certificate renewed successfully +- **Failure Notifications**: Renewal failed, manual intervention required +- **Expiry Warnings**: Certificate expiring soon (if auto-renewal fails) + +## Advanced SSL Configuration + +### SSL Protocols and Ciphers + +Configure SSL protocols and ciphers for enhanced security: + +1. Select your domain +2. Click the **Advanced** tab +3. Configure SSL settings + +#### Recommended SSL Configuration +```nginx +# SSL Protocols +ssl_protocols TLSv1.2 TLSv1.3; + +# SSL Ciphers +ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; + +# Prefer Server Ciphers +ssl_prefer_server_ciphers off; + +# SSL Session Cache +ssl_session_cache shared:SSL:10m; +ssl_session_timeout 10m; + +# OCSP Stapling +ssl_stapling on; +ssl_stapling_verify on; +``` + +### HTTP to HTTPS Redirect + +Automatically redirect HTTP traffic to HTTPS: + +1. Select your domain +2. Click the **Advanced** tab +3. Enable **Force HTTPS Redirect** + +#### Redirect Configuration +```nginx +server { + listen 80; + server_name example.com www.example.com; + return 301 https://$server_name$request_uri; +} +``` + +### HSTS (HTTP Strict Transport Security) + +Enable HSTS to enforce HTTPS connections: + +1. Select your domain +2. Click the **Advanced** tab +3. Enable **HSTS** +4. Configure HSTS settings: + - **Max Age**: Time in seconds (default: 31536000 = 1 year) + - **Include Subdomains**: Apply to all subdomains + - **Preload**: Include in browser preload list + +#### HSTS Configuration +```nginx +add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; +``` + +## Troubleshooting SSL Issues + +### Common SSL Problems + +#### Certificate Validation Failed + +**Symptoms**: Let's Encrypt certificate issuance fails + +**Possible Causes**: +- Domain doesn't point to server IP +- Port 80 blocked by firewall +- DNS propagation not complete +- Nginx configuration errors + +**Solutions**: +1. Verify DNS A record points to server IP +2. Check port 80 accessibility: `telnet yourdomain.com 80` +3. Wait for DNS propagation (up to 48 hours) +4. Check Nginx configuration: `nginx -t` + +#### Certificate Chain Issues + +**Symptoms**: Browser shows certificate warnings + +**Possible Causes**: +- Missing intermediate certificates +- Incorrect certificate order +- Incomplete certificate chain + +**Solutions**: +1. Upload complete certificate chain +2. Verify certificate order (domain cert first, then intermediates) +3. Use certificate chain checker tools + +#### Mixed Content Errors + +**Symptoms**: Browser shows mixed content warnings + +**Possible Causes**: +- HTTP resources on HTTPS page +- Insecure content loading + +**Solutions**: +1. Update all resource URLs to HTTPS +2. Use protocol-relative URLs: `//example.com/resource` +3. Implement content security policy + +### Debug Mode + +Enable SSL debug mode for detailed logging: + +1. Go to **System** settings +2. Enable **SSL Debug Mode** +3. Check logs in **Logs** section +4. Disable debug mode when finished + +### SSL Certificate Testing + +Test your SSL configuration with these tools: + +#### Online SSL Testers +- **SSL Labs**: https://www.ssllabs.com/ssltest/ +- **Qualys SSL Test**: Comprehensive SSL analysis +- **Why No Padlock**: https://www.whynopadlock.com/ + +#### Command Line Tools +```bash +# Check certificate details +openssl s_client -connect example.com:443 -servername example.com + +# Verify certificate chain +openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt certificate.crt + +# Check certificate expiry +openssl x509 -in certificate.crt -noout -dates +``` + +## Best Practices + +### Certificate Management + +1. **Auto-Renewal**: Always enable automatic renewal +2. **Monitoring**: Regularly check certificate status +3. **Backup**: Keep backup copies of certificates +4. **Documentation**: Document certificate configurations + +### Security + +1. **Strong Ciphers**: Use modern, secure cipher suites +2. **Protocol Versions**: Disable outdated protocols (SSLv2, SSLv3, TLSv1.0, TLSv1.1) +3. **HSTS**: Enable HSTS for enhanced security +4. **OCSP Stapling**: Enable OCSP stapling for performance + +### Performance + +1. **Session Cache**: Configure SSL session cache +2. **Session Tickets**: Enable SSL session tickets +3. **HTTP/2**: Enable HTTP/2 for better performance +4. **Certificate Size**: Use appropriate certificate key size (2048-bit minimum) + +### Monitoring + +1. **Expiry Alerts**: Configure alerts for certificate expiry +2. **Renewal Monitoring**: Monitor automatic renewal process +3. **Performance Metrics**: Track SSL performance metrics +4. **Error Tracking**: Monitor SSL-related errors + +## API Integration + +For programmatic SSL management, use the REST API: + +### List SSL Certificates +```bash +curl -X GET http://localhost:3001/api/ssl \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Issue Let's Encrypt Certificate +```bash +curl -X POST http://localhost:3001/api/ssl/auto \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "domainId": "DOMAIN_ID", + "email": "admin@example.com", + "autoRenew": true + }' +``` + +### Upload Manual Certificate +```bash +curl -X POST http://localhost:3001/api/ssl/manual \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "domainId": "DOMAIN_ID", + "certificate": "-----BEGIN CERTIFICATE-----\n...", + "privateKey": "-----BEGIN PRIVATE KEY-----\n...", + "chain": "-----BEGIN CERTIFICATE-----\n...", + "issuer": "Custom CA" + }' +``` + +### Renew Certificate +```bash +curl -X POST http://localhost:3001/api/ssl/CERTIFICATE_ID/renew \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Delete Certificate +```bash +curl -X DELETE http://localhost:3001/api/ssl/CERTIFICATE_ID \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +For complete API documentation, see the [API Reference](/api/ssl). + +## Conclusion + +SSL certificate management is crucial for securing your web applications. By following this guide, you should be able to: + +- Configure Let's Encrypt certificates automatically +- Upload and manage custom certificates +- Set up automatic renewal with monitoring +- Troubleshoot common SSL issues +- Implement SSL best practices + +For more information on related topics: +- [Domain Management](/guide/domains) +- [ModSecurity WAF Configuration](/guide/modsecurity) +- [Performance Monitoring](/guide/performance) +- [Log Analysis](/guide/logs) \ No newline at end of file diff --git a/apps/docs/guide/users.md b/apps/docs/guide/users.md new file mode 100644 index 0000000..2dd03a4 --- /dev/null +++ b/apps/docs/guide/users.md @@ -0,0 +1,520 @@ +# User Management Guide + +This comprehensive guide covers user management in the Nginx WAF Management Platform, including creating users, managing roles and permissions, configuring Two-Factor Authentication (2FA), and monitoring user activity. + +## Overview + +The user management system provides: +- **Role-Based Access Control**: Three-tier permission system +- **User Authentication**: Secure login with JWT tokens +- **Two-Factor Authentication**: Enhanced security with 2FA +- **Activity Logging**: Comprehensive audit trail +- **Session Management**: Control active user sessions +- **Password Policies**: Enforce strong password requirements + +## User Management Interface + +Access user management by clicking **Users** in the sidebar navigation: + +![User Management](/reference/screenshots/User_Management.png) + +The user management interface provides: +- **User List**: Overview of all system users +- **User Status**: Visual indicators for user status +- **Role Indicators**: User role badges +- **Quick Actions**: Common user management tasks + +## User Roles and Permissions + +The platform uses a three-tier role-based access control system: + +### Administrator (Admin) + +**Full System Access** - Complete control over all aspects of the system: + +**Domain Management** +- Create, edit, and delete domains +- Configure upstream servers and load balancing +- Manage SSL certificates +- Configure ModSecurity rules + +**User Management** +- Create, edit, and delete users +- Assign roles and permissions +- Reset user passwords +- Manage user sessions + +**System Configuration** +- Configure system settings +- Manage notification channels +- Set up alert rules +- View system logs and metrics + +**Security** +- Configure ACL rules +- Manage WAF settings +- Access security logs +- Configure 2FA settings + +### Moderator + +**Operational Access** - Manage domains and security settings: + +**Domain Management** +- Create, edit, and delete domains +- Configure upstream servers and load balancing +- Manage SSL certificates +- Configure ModSecurity rules + +**Security** +- Configure ACL rules +- Manage WAF settings +- Access security logs + +**Limited System Access** +- View system metrics and logs +- Manage notification channels +- Set up alert rules + +**Restrictions** +- Cannot manage other users +- Cannot modify system settings +- Cannot access user management + +### Viewer + +**Read-Only Access** - View system status and reports: + +**Monitoring** +- View dashboard and metrics +- Check domain status +- View performance reports +- Access log files + +**Limited Configuration** +- View but not modify settings +- Export reports and logs +- Check SSL certificate status + +**Restrictions** +- Cannot make any configuration changes +- Cannot access user management +- Cannot modify security settings + +## Creating Users + +### Add a New User + +1. Click **Users** in the sidebar +2. Click the **Add User** button +3. Fill in the user details: + +**Required Information:** +- **Username**: Unique username (alphanumeric, underscores, hyphens) +- **Email**: Valid email address +- **Full Name**: Display name for the user +- **Role**: Admin, Moderator, or Viewer +- **Password**: Initial password (or auto-generate) +- **Status**: Active or Inactive + +**Optional Information:** +- **Phone**: Contact phone number +- **Timezone**: User's timezone (default: Asia/Ho_Chi_Minh) +- **Language**: Interface language (default: en) + +### Username Requirements + +- **Length**: 3-50 characters +- **Characters**: Letters (a-z, A-Z), numbers (0-9), underscores (_), hyphens (-) +- **Unique**: Must be unique across all users +- **Case-sensitive**: Usernames are case-sensitive + +### Password Requirements + +- **Minimum Length**: 8 characters +- **Complexity**: Must include: + - At least one uppercase letter (A-Z) + - At least one lowercase letter (a-z) + - At least one number (0-9) + - At least one special character (!@#$%^&*) +- **Common Passwords**: Cannot use common passwords +- **Personal Information**: Cannot contain username or email + +## User Account Management + +### Editing User Information + +1. Select the user from the list +2. Click the **Edit** button +3. Update the required fields +4. Click **Save** to apply changes + +### Changing User Roles + +1. Select the user from the list +2. Click the **Edit** button +3. Change the **Role** field +4. Click **Save** to apply changes + +⚠️ **Warning**: Changing a user's role will immediately affect their permissions. + +### Toggling User Status + +Quickly enable or disable user accounts: + +1. Select the user from the list +2. Click the **Toggle Status** button +3. Confirm the action + +**Status Types:** +- **Active**: User can log in and access the system +- **Inactive**: User cannot log in (account disabled) +- **Suspended**: User account suspended (admin only) + +### Resetting User Passwords + +1. Select the user from the list +2. Click the **Reset Password** button +3. Choose reset option: + - **Auto-generate**: System generates a secure password + - **Manual**: Specify a new password +4. Click **Reset Password** +5. Communicate the new password to the user + +### Deleting Users + +⚠️ **Warning**: Deleting a user is permanent and cannot be undone. + +1. Select the user from the list +2. Click the **Delete** button +3. Confirm the deletion +4. Choose what to do with user data: + - **Delete**: Remove all user data + - **Archive**: Archive user data for compliance + +## Two-Factor Authentication (2FA) + +Two-Factor Authentication adds an extra layer of security by requiring a second form of verification. + +### Supported 2FA Methods + +#### Time-Based One-Time Password (TOTP) +- **Apps**: Google Authenticator, Authy, Microsoft Authenticator +- **Setup**: QR code or manual entry +- **Backup Codes**: Generated for recovery + +#### Email-Based 2FA +- **Method**: One-time code sent to email +- **Expiration**: Codes expire after 10 minutes +- **Rate Limiting**: Prevents email flooding + +### Setting Up 2FA for Users + +#### User Self-Setup + +1. Log in to the user account +2. Navigate to **Profile** settings +3. Click **Enable 2FA** +4. Choose 2FA method (TOTP recommended) +5. Follow the setup instructions: + - Scan QR code with authenticator app + - Enter verification code + - Save backup codes securely + +#### Admin-Forced 2FA + +Administrators can require 2FA for specific users: + +1. Select the user from the list +2. Click **Edit** button +3. Enable **Require 2FA** +4. Choose grace period for setup +5. Click **Save** + +### Managing 2FA + +#### Disable 2FA + +1. Select the user from the list +2. Click **Edit** button +3. Disable **Require 2FA** +4. Click **Save** + +#### Regenerate Backup Codes + +1. Select the user from the list +2. Click **Manage 2FA** +3. Click **Regenerate Backup Codes** +4. Securely communicate new codes to user + +#### Reset 2FA + +If a user loses access to their 2FA device: + +1. Select the user from the list +2. Click **Reset 2FA** +3. Confirm the reset +4. User will need to set up 2FA again on next login + +## Session Management + +Monitor and control active user sessions for security. + +### Viewing Active Sessions + +1. Select a user from the list +2. Click **View Sessions** +3. See active sessions with details: + - **Session ID**: Unique session identifier + - **IP Address**: Login IP address + - **Device**: Device type and browser + - **Location**: Geographic location (if available) + - **Last Active**: Last activity timestamp + - **Expires**: Session expiration time + +### Revoking Sessions + +1. Select the user from the list +2. Click **View Sessions** +3. Select the session to revoke +4. Click **Revoke Session** +5. Confirm the action + +### Force Logout + +Immediately log out a user from all devices: + +1. Select the user from the list +2. Click **Force Logout** +3. Confirm the action +4. User will need to log in again + +## Activity Monitoring + +Track user activity for security and compliance. + +### Viewing Activity Logs + +1. Select a user from the list +2. Click **View Activity** +3. Filter activities by: + - **Date Range**: Custom date range + - **Activity Type**: Login, logout, configuration changes + - **Success Status**: Successful or failed actions + - **IP Address**: Filter by specific IP + +### Activity Types + +- **Login**: User login attempts +- **Logout**: User logout actions +- **Config Change**: Configuration modifications +- **User Action**: User management actions +- **Security**: Security-related events + +### Monitoring Security Events + +Pay special attention to: + +- **Failed Login Attempts**: Potential brute force attacks +- **Multiple IPs**: Potential account sharing +- **Unusual Activity**: Actions outside normal patterns +- **Privilege Escalation**: Role changes or permission modifications + +## User Statistics + +Monitor user activity and system usage through statistics. + +### User Statistics Dashboard + +Access user statistics by clicking **Users** and then **Statistics**: + +**User Overview** +- Total users by role +- Active vs inactive users +- 2FA adoption rate +- Recent activity trends + +**Login Statistics** +- Daily/weekly/monthly login counts +- Failed login attempts +- Geographic distribution +- Device and browser statistics + +**Activity Statistics** +- Configuration changes by user +- Most active users +- Feature usage patterns +- Time-based activity analysis + +## Best Practices + +### User Management + +1. **Principle of Least Privilege**: Assign minimum necessary permissions +2. **Regular Reviews**: Periodically review user roles and permissions +3. **Account Cleanup**: Remove inactive or unused accounts +4. **Strong Passwords**: Enforce strong password policies + +### Security + +1. **Enable 2FA**: Require 2FA for all admin and moderator accounts +2. **Monitor Activity**: Regularly review user activity logs +3. **Session Management**: Monitor and manage active sessions +4. **Failed Login Tracking**: Monitor for suspicious login attempts + +### Compliance + +1. **Audit Trail**: Maintain complete audit logs +2. **Data Retention**: Follow data retention policies +3. **Access Controls**: Implement proper access controls +4. **Regular Audits**: Conduct regular security audits + +## API Integration + +For programmatic user management, use the REST API: + +### List Users +```bash +curl -X GET http://localhost:3001/api/users \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Create User +```bash +curl -X POST http://localhost:3001/api/users \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "username": "newuser", + "email": "newuser@example.com", + "fullName": "New User", + "role": "moderator", + "password": "SecurePassword123!", + "status": "active" + }' +``` + +### Update User +```bash +curl -X PUT http://localhost:3001/api/users/USER_ID \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "fullName": "Updated Name", + "email": "updated@example.com", + "role": "admin" + }' +``` + +### Delete User +```bash +curl -X DELETE http://localhost:3001/api/users/USER_ID \ + -H "Authorization: Bearer YOUR_TOKEN" +``` + +### Reset Password +```bash +curl -X POST http://localhost:3001/api/users/USER_ID/reset-password \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "newPassword": "NewSecurePassword123!" + }' +``` + +### Toggle User Status +```bash +curl -X PATCH http://localhost:3001/api/users/USER_ID/status \ + -H "Authorization: Bearer YOUR_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{ + "status": "inactive" + }' +``` + +## Troubleshooting + +### Common User Issues + +#### Login Failures + +**Symptoms**: User cannot log in with correct credentials + +**Possible Causes**: +- Account is inactive or suspended +- Password expired or changed +- 2FA verification failing +- Account locked due to failed attempts + +**Solutions**: +1. Check user status in user management +2. Reset user password +3. Reset 2FA if needed +4. Check for account lockout + +#### Permission Issues + +**Symptoms**: User cannot access expected features + +**Possible Causes**: +- Incorrect role assignment +- Role permissions changed +- User account issues + +**Solutions**: +1. Verify user role assignment +2. Check role permissions +3. Review user account status +4. Check activity logs for changes + +#### 2FA Issues + +**Symptoms**: User cannot complete 2FA verification + +**Possible Causes**: +- Time sync issues with authenticator app +- Lost authenticator device +- Backup codes lost + +**Solutions**: +1. Check device time synchronization +2. Reset 2FA for the user +3. Generate new backup codes +4. Use alternative 2FA method + +### Security Incidents + +#### Suspicious Activity + +If you detect suspicious user activity: + +1. **Immediate Actions**: + - Force logout of suspicious user + - Reset user password + - Revoke all active sessions + +2. **Investigation**: + - Review activity logs + - Check login IP addresses + - Verify configuration changes + +3. **Prevention**: + - Enable 2FA if not already enabled + - Review and tighten permissions + - Implement additional monitoring + +## Conclusion + +User management is critical for maintaining system security and proper access controls. By following this guide, you should be able to: + +- Create and manage user accounts effectively +- Implement proper role-based access control +- Configure Two-Factor Authentication for enhanced security +- Monitor user activity and manage sessions +- Troubleshoot common user issues + +For more information on related topics: +- [Domain Management](/guide/domains) +- [SSL Certificate Management](/guide/ssl) +- [ModSecurity WAF Configuration](/guide/modsecurity) +- [Log Analysis](/guide/logs) \ No newline at end of file diff --git a/apps/docs/index.md b/apps/docs/index.md new file mode 100644 index 0000000..a157536 --- /dev/null +++ b/apps/docs/index.md @@ -0,0 +1,37 @@ +--- +layout: home +hero: + name: nginx-love + text: Nginx + ModSecurity Management Platform + tagline: A comprehensive platform for managing Nginx configurations, SSL certificates, and ModSecurity rules + actions: + - theme: brand + text: Get Started + link: /guide/introduction + - theme: alt + text: View on GitHub + link: https://github.com/nginx-love/nginx-love +features: + - title: 🚀 Easy Management + details: Simplify your Nginx configuration management with an intuitive web interface + - title: 🔒 SSL Certificate Management + details: Automate SSL certificate issuance, renewal, and management with Let's Encrypt integration + - title: 🛡️ ModSecurity WAF + details: Protect your applications with advanced Web Application Firewall rules and monitoring + - title: 📊 Performance Monitoring + details: Monitor server performance, analyze traffic patterns, and optimize your setup + - title: 📝 Log Analysis + details: Analyze access and error logs to identify issues and optimize performance + - title: 👥 Multi-User Support + details: Manage multiple users with role-based access control and permissions +--- + +## Quick Start + +To get started with nginx-love, follow our [installation guide](/guide/installation) and check out the [quick start tutorial](/guide/quick-start). + +## Documentation + +- [Guide](/guide/) - Learn how to use nginx-love +- [API Reference](/api/) - Explore the REST API +- [Reference](/reference/) - Find configuration options and troubleshooting tips \ No newline at end of file diff --git a/apps/docs/package.json b/apps/docs/package.json new file mode 100644 index 0000000..2e47dc9 --- /dev/null +++ b/apps/docs/package.json @@ -0,0 +1,19 @@ +{ + "name": "nginx-love-docs", + "version": "1.0.0", + "description": "Documentation for nginx-love platform", + "scripts": { + "dev": "vitepress dev", + "build": "vitepress build", + "preview": "vitepress preview", + "serve": "vitepress serve" + }, + "dependencies": { + "vue": "^3.3.4" + }, + "devDependencies": { + "vitepress": "^2.0.0-alpha.12", + "typescript": "^5.2.2", + "vue-tsc": "^1.8.8" + } +} \ No newline at end of file diff --git a/apps/docs/public/favicon.ico b/apps/docs/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/apps/docs/reference/configuration.md b/apps/docs/reference/configuration.md new file mode 100644 index 0000000..7511d67 --- /dev/null +++ b/apps/docs/reference/configuration.md @@ -0,0 +1,267 @@ +# Configuration + +This section covers the configuration options available in nginx-love. + +## Environment Variables + +nginx-love can be configured using environment variables. These can be set in a `.env` file or directly in the environment. + +### Database Configuration + +```bash +# Database connection +DB_HOST=localhost +DB_PORT=5432 +DB_NAME=nginx_love +DB_USER=nginx_love +DB_PASSWORD=password + +# Database SSL (optional) +DB_SSL=false +DB_SSL_CERT=/path/to/cert.pem +DB_SSL_KEY=/path/to/key.pem +DB_SSL_CA=/path/to/ca.pem +``` + +### Application Configuration + +```bash +# Application +NODE_ENV=production +PORT=3000 +HOST=0.0.0.0 + +# JWT Secret +JWT_SECRET=your-secret-key +JWT_EXPIRES_IN=7d + +# Encryption +ENCRYPTION_KEY=your-encryption-key +``` + +### Nginx Configuration + +```bash +# Nginx +NGINX_CONFIG_PATH=/etc/nginx/nginx.conf +NGINX_SITES_PATH=/etc/nginx/sites-available +NGINX_LOG_PATH=/var/log/nginx + +# Nginx reload command +NGINX_RELOAD_COMMAND=systemctl reload nginx +``` + +### Let's Encrypt Configuration + +```bash +# Let's Encrypt +LETSENCRYPT_EMAIL=admin@example.com +LETSENCRYPT_STAGING=false +LETSENCRYPT_RENEWAL_THRESHOLD=30 +``` + +### Email Configuration + +```bash +# SMTP +SMTP_HOST=smtp.example.com +SMTP_PORT=587 +SMTP_SECURE=false +SMTP_USER=noreply@example.com +SMTP_PASSWORD=password +SMTP_FROM=noreply@example.com +``` + +### Monitoring Configuration + +```bash +# Monitoring +METRICS_ENABLED=true +METRICS_PORT=9090 +LOG_LEVEL=info +``` + +## Configuration File + +nginx-love can also be configured using a configuration file. By default, it looks for `config/config.json` in the application directory. + +```json +{ + "database": { + "host": "localhost", + "port": 5432, + "name": "nginx_love", + "user": "nginx_love", + "password": "password", + "ssl": false + }, + "application": { + "port": 3000, + "host": "0.0.0.0", + "jwtSecret": "your-secret-key", + "jwtExpiresIn": "7d", + "encryptionKey": "your-encryption-key" + }, + "nginx": { + "configPath": "/etc/nginx/nginx.conf", + "sitesPath": "/etc/nginx/sites-available", + "logPath": "/var/log/nginx", + "reloadCommand": "systemctl reload nginx" + }, + "letsencrypt": { + "email": "admin@example.com", + "staging": false, + "renewalThreshold": 30 + }, + "email": { + "smtp": { + "host": "smtp.example.com", + "port": 587, + "secure": false, + "user": "noreply@example.com", + "password": "password", + "from": "noreply@example.com" + } + }, + "monitoring": { + "metricsEnabled": true, + "metricsPort": 9090, + "logLevel": "info" + } +} +``` + +## Nginx Configuration Templates + +nginx-love uses templates to generate Nginx configuration files. These templates can be customized to meet your specific needs. + +### Basic Domain Template + +```nginx +server { + listen 80; + server_name {{domain.name}} {{domain.serverAlias}}; + + root {{domain.documentRoot}}; + index index.html index.php; + + access_log {{domain.accessLog}}; + error_log {{domain.errorLog}}; + + location / { + try_files $uri $uri/ =404; + } + + {{#domain.sslEnabled}} + listen 443 ssl; + ssl_certificate {{domain.sslCertificate}}; + ssl_certificate_key {{domain.sslPrivateKey}}; + {{/domain.sslEnabled}} + + {{#domain.modSecurityEnabled}} + ModSecurityEnabled on; + ModSecurityConfig /etc/nginx/modsec/main.conf; + {{/domain.modSecurityEnabled}} +} +``` + +### PHP-FPM Template + +```nginx +server { + listen 80; + server_name {{domain.name}} {{domain.serverAlias}}; + + root {{domain.documentRoot}}; + index index.php index.html; + + access_log {{domain.accessLog}}; + error_log {{domain.errorLog}}; + + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + location ~ \.php$ { + fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + {{#domain.sslEnabled}} + listen 443 ssl; + ssl_certificate {{domain.sslCertificate}}; + ssl_certificate_key {{domain.sslPrivateKey}}; + {{/domain.sslEnabled}} +} +``` + +### Reverse Proxy Template + +```nginx +server { + listen 80; + server_name {{domain.name}} {{domain.serverAlias}}; + + access_log {{domain.accessLog}}; + error_log {{domain.errorLog}}; + + location / { + proxy_pass {{domain.proxyUrl}}; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + {{#domain.sslEnabled}} + listen 443 ssl; + ssl_certificate {{domain.sslCertificate}}; + ssl_certificate_key {{domain.sslPrivateKey}}; + {{/domain.sslEnabled}} +} +``` + +## ModSecurity Configuration + +nginx-love provides default ModSecurity configuration that can be customized. + +### Main Configuration + +```nginx +SecRuleEngine On +SecRequestBodyAccess On +SecResponseBodyAccess On +SecRequestBodyLimit 13107200 +SecRequestBodyNoFilesLimit 131072 +SecRequestBodyInMemoryLimit 131072 +SecResponseBodyLimit 524288 +SecResponseBodyMimeType text/plain text/html text/xml application/json +``` + +### OWASP CRS Configuration + +```nginx +Include /etc/nginx/modsec/crs-setup.conf +Include /etc/nginx/modsec/rules/*.conf +``` + +## SSL Configuration + +nginx-love provides default SSL configuration that can be customized. + +### SSL Configuration + +```nginx +ssl_protocols TLSv1.2 TLSv1.3; +ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; +ssl_prefer_server_ciphers off; +ssl_session_cache shared:SSL:10m; +ssl_session_timeout 10m; +``` + +### HSTS Configuration + +```nginx +add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; \ No newline at end of file diff --git a/apps/docs/reference/faq.md b/apps/docs/reference/faq.md new file mode 100644 index 0000000..60fac2b --- /dev/null +++ b/apps/docs/reference/faq.md @@ -0,0 +1,174 @@ +# Frequently Asked Questions + +This section covers common questions about nginx-love. + +## General Questions + +### What is nginx-love? + +nginx-love is a comprehensive management platform for Nginx and ModSecurity. It provides a user-friendly web interface to manage Nginx configurations, SSL certificates, ModSecurity rules, and monitor server performance. + +### What are the system requirements? + +nginx-love requires: +- Node.js 18 or higher +- PostgreSQL 12 or higher +- Nginx 1.18 or higher +- ModSecurity 2.9 or higher (optional) +- 2GB RAM minimum +- 10GB disk space minimum + +### Is nginx-love free? + +Yes, nginx-love is open-source and released under the MIT License. + +### Can I use nginx-love in production? + +Yes, nginx-love is designed for production use. However, always test in a staging environment first. + +## Installation Questions + +### How do I install nginx-love? + +See the [installation guide](/guide/installation) for detailed installation instructions. + +### Can I install nginx-love on Docker? + +Yes, nginx-love provides Docker images for easy deployment. See the installation guide for Docker instructions. + +### Do I need to install Nginx separately? + +Yes, nginx-love manages existing Nginx installations but does not include Nginx itself. + +## Domain Management Questions + +### Can I manage multiple domains? + +Yes, nginx-love is designed to manage multiple domains from a single interface. + +### Can I use nginx-love with existing Nginx configurations? + +Yes, nginx-love can import existing Nginx configurations. However, some manual adjustments may be needed. + +### Can I create custom Nginx configurations? + +Yes, nginx-love allows you to add custom Nginx directives for advanced configurations. + +## SSL Questions + +### Does nginx-love support wildcard certificates? + +Yes, nginx-love supports wildcard certificates from Let's Encrypt and custom certificates. + +### Can I use my own SSL certificates? + +Yes, nginx-love allows you to upload and manage custom SSL certificates. + +### How does automatic certificate renewal work? + +nginx-love automatically renews Let's Encrypt certificates before they expire. You can configure the renewal threshold in the settings. + +## ModSecurity Questions + +### Do I need to install ModSecurity separately? + +Yes, nginx-love manages ModSecurity configurations but does not include ModSecurity itself. + +### Can I use custom ModSecurity rules? + +Yes, nginx-love allows you to create and manage custom ModSecurity rules. + +### What is the OWASP CRS? + +The OWASP Core Rule Set (CRS) is a set of generic attack detection rules for ModSecurity. nginx-love supports the OWASP CRS with different paranoia levels. + +## Performance Questions + +### Does nginx-love impact Nginx performance? + +nginx-love has minimal impact on Nginx performance. The main performance consideration is ModSecurity, which can add some overhead. + +### Can I monitor performance metrics? + +Yes, nginx-love provides comprehensive performance monitoring capabilities. + +### How far back is performance data retained? + +Performance data is retained for: +- Real-time: Last hour with 1-minute granularity +- Hourly: Last 24 hours with 1-hour granularity +- Daily: Last 30 days with 1-day granularity +- Monthly: Last 12 months with 1-month granularity + +## Security Questions + +### Is nginx-love secure? + +Yes, nginx-love is designed with security in mind. It uses JWT tokens for authentication, supports two-factor authentication, and follows security best practices. + +### Can I restrict access to specific features? + +Yes, nginx-love supports role-based access control to restrict access to specific features. + +### Does nginx-love store sensitive data? + +nginx-love encrypts sensitive data such as passwords and private keys using AES-256 encryption. + +## Integration Questions + +### Can I integrate nginx-love with my existing tools? + +Yes, nginx-love provides a REST API for integration with other tools. + +### Does nginx-love support webhooks? + +Yes, nginx-love supports webhooks for notifications and automation. + +### Can I export data from nginx-love? + +Yes, nginx-love allows you to export logs, configuration, and other data in various formats. + +## Troubleshooting Questions + +### Where can I find logs? + +nginx-love logs are stored in the application logs directory. The specific location depends on your installation method. + +### How do I report bugs? + +Please report bugs on the [nginx-love GitHub repository](https://github.com/nginx-love/nginx-love/issues). + +### Where can I get help? + +You can get help from: +- The [documentation](/) +- The [GitHub repository](https://github.com/nginx-love/nginx-love) +- The community forums + +## Licensing Questions + +### Can I use nginx-love commercially? + +Yes, nginx-love is released under the MIT License, which allows commercial use. + +### Do I need to provide attribution? + +The MIT License requires that you include the copyright notice and license text with any distribution of the software. + +### Can I modify nginx-love? + +Yes, the MIT License allows you to modify the software. + +## Support Questions + +### Is commercial support available? + +Commercial support options are available. Please contact us for more information. + +### How often is nginx-love updated? + +nginx-love is actively developed with regular releases. You can check the [GitHub repository](https://github.com/nginx-love/nginx-love) for the latest releases. + +### How do I stay updated with new releases? + +You can watch the [GitHub repository](https://github.com/nginx-love/nginx-love) to receive notifications about new releases. \ No newline at end of file diff --git a/screenshot/2FA.png b/apps/docs/reference/screenshots/2FA.png similarity index 100% rename from screenshot/2FA.png rename to apps/docs/reference/screenshots/2FA.png diff --git a/screenshot/ACL_add.png b/apps/docs/reference/screenshots/ACL_add.png similarity index 100% rename from screenshot/ACL_add.png rename to apps/docs/reference/screenshots/ACL_add.png diff --git a/screenshot/Change_password.png b/apps/docs/reference/screenshots/Change_password.png similarity index 100% rename from screenshot/Change_password.png rename to apps/docs/reference/screenshots/Change_password.png diff --git a/screenshot/Dashboard.png b/apps/docs/reference/screenshots/Dashboard.png similarity index 100% rename from screenshot/Dashboard.png rename to apps/docs/reference/screenshots/Dashboard.png diff --git a/screenshot/Domain_Management.png b/apps/docs/reference/screenshots/Domain_Management.png similarity index 100% rename from screenshot/Domain_Management.png rename to apps/docs/reference/screenshots/Domain_Management.png diff --git a/screenshot/Performance.png b/apps/docs/reference/screenshots/Performance.png similarity index 100% rename from screenshot/Performance.png rename to apps/docs/reference/screenshots/Performance.png diff --git a/screenshot/User_Management.png b/apps/docs/reference/screenshots/User_Management.png similarity index 100% rename from screenshot/User_Management.png rename to apps/docs/reference/screenshots/User_Management.png diff --git a/screenshot/WAF.jpg b/apps/docs/reference/screenshots/WAF.jpg similarity index 100% rename from screenshot/WAF.jpg rename to apps/docs/reference/screenshots/WAF.jpg diff --git a/screenshot/acl.png b/apps/docs/reference/screenshots/acl.png similarity index 100% rename from screenshot/acl.png rename to apps/docs/reference/screenshots/acl.png diff --git a/screenshot/alert_chanel.png b/apps/docs/reference/screenshots/alert_chanel.png similarity index 100% rename from screenshot/alert_chanel.png rename to apps/docs/reference/screenshots/alert_chanel.png diff --git a/screenshot/alert_rule.png b/apps/docs/reference/screenshots/alert_rule.png similarity index 100% rename from screenshot/alert_rule.png rename to apps/docs/reference/screenshots/alert_rule.png diff --git a/screenshot/domain_add.png b/apps/docs/reference/screenshots/domain_add.png similarity index 100% rename from screenshot/domain_add.png rename to apps/docs/reference/screenshots/domain_add.png diff --git a/screenshot/domain_log.png b/apps/docs/reference/screenshots/domain_log.png similarity index 100% rename from screenshot/domain_log.png rename to apps/docs/reference/screenshots/domain_log.png diff --git a/screenshot/domain_log_one_domain.png b/apps/docs/reference/screenshots/domain_log_one_domain.png similarity index 100% rename from screenshot/domain_log_one_domain.png rename to apps/docs/reference/screenshots/domain_log_one_domain.png diff --git a/screenshot/installation_complete.png b/apps/docs/reference/screenshots/installation_complete.png similarity index 100% rename from screenshot/installation_complete.png rename to apps/docs/reference/screenshots/installation_complete.png diff --git a/screenshot/log_login.png b/apps/docs/reference/screenshots/log_login.png similarity index 100% rename from screenshot/log_login.png rename to apps/docs/reference/screenshots/log_login.png diff --git a/screenshot/login.png b/apps/docs/reference/screenshots/login.png similarity index 100% rename from screenshot/login.png rename to apps/docs/reference/screenshots/login.png diff --git a/screenshot/modsecurity.png b/apps/docs/reference/screenshots/modsecurity.png similarity index 100% rename from screenshot/modsecurity.png rename to apps/docs/reference/screenshots/modsecurity.png diff --git a/screenshot/my_account.png b/apps/docs/reference/screenshots/my_account.png similarity index 100% rename from screenshot/my_account.png rename to apps/docs/reference/screenshots/my_account.png diff --git a/screenshot/ssl_add.png b/apps/docs/reference/screenshots/ssl_add.png similarity index 100% rename from screenshot/ssl_add.png rename to apps/docs/reference/screenshots/ssl_add.png diff --git a/screenshot/ssl_cert.png b/apps/docs/reference/screenshots/ssl_cert.png similarity index 100% rename from screenshot/ssl_cert.png rename to apps/docs/reference/screenshots/ssl_cert.png diff --git a/apps/docs/reference/troubleshooting.md b/apps/docs/reference/troubleshooting.md new file mode 100644 index 0000000..31ab267 --- /dev/null +++ b/apps/docs/reference/troubleshooting.md @@ -0,0 +1,238 @@ +# Troubleshooting + +This section covers common issues and their solutions when using nginx-love. + +## Installation Issues + +### Database Connection Failed + +**Problem:** nginx-love cannot connect to the database. + +**Solution:** +1. Check that your database server is running +2. Verify the database connection settings in your `.env` file +3. Ensure the database user has the necessary permissions +4. Check if the database exists + +```bash +# Check PostgreSQL status +sudo systemctl status postgresql + +# Check database connection +psql -h localhost -U nginx_love -d nginx_love +``` + +### Permission Denied + +**Problem:** nginx-love cannot access Nginx configuration files. + +**Solution:** +1. Ensure the nginx-love user has permission to access Nginx files +2. Add the nginx-love user to the appropriate groups + +```bash +# Add user to www-data group +sudo usermod -a -G www-data nginx-love + +# Set appropriate permissions +sudo chown -R www-data:www-data /etc/nginx +sudo chmod -R 755 /etc/nginx +``` + +## Domain Issues + +### Domain Not Working + +**Problem:** A newly created domain is not accessible. + +**Solution:** +1. Check that the DNS record for the domain is pointing to your server +2. Verify that Nginx configuration was generated correctly +3. Reload Nginx configuration + +```bash +# Check Nginx configuration +sudo nginx -t + +# Reload Nginx +sudo systemctl reload nginx +``` + +### SSL Certificate Not Issued + +**Problem:** Let's Encrypt certificate cannot be issued. + +**Solution:** +1. Ensure the domain is pointing to your server +2. Check that port 80 is accessible from the internet +3. Verify that Let's Encrypt can reach the validation file + +```bash +# Check if port 80 is accessible +telnet your-domain.com 80 + +# Check Nginx error logs +sudo tail -f /var/log/nginx/error.log +``` + +## ModSecurity Issues + +### ModSecurity Not Working + +**Problem:** ModSecurity rules are not being applied. + +**Solution:** +1. Verify that ModSecurity is installed and enabled +2. Check that the ModSecurity configuration is correct +3. Ensure the rule set is properly configured + +```bash +# Check ModSecurity status +sudo nginx -V | grep modsecurity + +# Check ModSecurity logs +sudo tail -f /var/log/modsec_audit.log +``` + +### False Positives + +**Problem:** Legitimate requests are being blocked by ModSecurity. + +**Solution:** +1. Review the ModSecurity logs to identify the rule causing the issue +2. Create exclusions for specific rules or endpoints +3. Consider lowering the paranoia level + +## Performance Issues + +### High Memory Usage + +**Problem:** nginx-love is using excessive memory. + +**Solution:** +1. Check for memory leaks +2. Optimize database queries +3. Implement caching + +```bash +# Check memory usage +ps aux | grep nginx-love + +# Check database connections +psql -h localhost -U nginx_love -d nginx_love -c "SELECT * FROM pg_stat_activity;" +``` + +### Slow Response Times + +**Problem:** nginx-love is responding slowly to requests. + +**Solution:** +1. Check system resources +2. Optimize database performance +3. Review Nginx configuration + +```bash +# Check system resources +top + +# Check database performance +psql -h localhost -U nginx_love -d nginx_love -c "SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;" +``` + +## Log Analysis Issues + +### Logs Not Appearing + +**Problem:** Access or error logs are not showing up in nginx-love. + +**Solution:** +1. Verify that log paths are correct in the configuration +2. Ensure the nginx-love user has permission to read log files +3. Check that log rotation is not interfering + +```bash +# Check log file permissions +ls -la /var/log/nginx/ + +# Check log rotation +sudo cat /etc/logrotate.d/nginx +``` + +### Log Parsing Errors + +**Problem:** nginx-love cannot parse log files correctly. + +**Solution:** +1. Verify that log format matches expected format +2. Check for corrupted log files +3. Review custom log format configuration + +## SSL Issues + +### Certificate Renewal Failed + +**Problem:** Let's Encrypt certificate renewal failed. + +**Solution:** +1. Check that the domain is still pointing to your server +2. Verify that the Let's Encrypt account is valid +3. Review renewal logs for specific error messages + +```bash +# Check renewal logs +sudo journalctl -u certbot +``` + +### Mixed Content Warning + +**Problem:** Browser shows mixed content warnings when using SSL. + +**Solution:** +1. Update all HTTP links to HTTPS +2. Implement HSTS headers +3. Review application code for hardcoded HTTP links + +## General Issues + +### Application Won't Start + +**Problem:** nginx-love application fails to start. + +**Solution:** +1. Check application logs for error messages +2. Verify that all required environment variables are set +3. Ensure all dependencies are installed + +```bash +# Check application logs +journalctl -u nginx-love + +# Check environment variables +env | grep NGINX_LOVE +``` + +### Cannot Access Web Interface + +**Problem:** Cannot access the nginx-love web interface. + +**Solution:** +1. Check that the application is running +2. Verify that the correct port is open +3. Check firewall settings + +```bash +# Check if application is listening +netstat -tlnp | grep :3000 + +# Check firewall settings +sudo ufw status +``` + +## Getting Help + +If you're still experiencing issues after trying these solutions: + +1. Check the [nginx-love GitHub repository](https://github.com/nginx-love/nginx-love) for known issues +2. Search the [documentation](/) for more specific information +3. Open an issue on GitHub with details about your problem +4. Join our community forums for additional support \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e9d9056..b840585 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -103,6 +103,22 @@ importers: specifier: ^5.5.4 version: 5.9.3 + apps/docs: + dependencies: + vue: + specifier: ^3.3.4 + version: 3.5.22(typescript@5.9.3) + devDependencies: + typescript: + specifier: ^5.2.2 + version: 5.9.3 + vitepress: + specifier: ^2.0.0-alpha.12 + version: 2.0.0-alpha.12(typescript@5.9.3) + vue-tsc: + specifier: ^1.8.8 + version: 1.8.27(typescript@5.9.3) + apps/web: dependencies: '@hookform/resolvers': @@ -924,12 +940,10 @@ packages: /@babel/helper-string-parser@7.27.1: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier@7.27.1: resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-option@7.27.1: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} @@ -950,7 +964,6 @@ packages: hasBin: true dependencies: '@babel/types': 7.28.4 - dev: true /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.28.4): resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} @@ -1066,7 +1079,6 @@ packages: dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - dev: true /@colors/colors@1.6.0: resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} @@ -1092,6 +1104,14 @@ packages: resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==} dev: false + /@docsearch/css@4.1.0: + resolution: {integrity: sha512-nuNKGjHj/FQeWgE9t+i83QD/V67QiaAmGY7xS9TVCRUiCqSljOgIKlsLoQZKKVwEG8f+OWKdznzZkJxGZ7d06A==} + dev: true + + /@docsearch/js@4.1.0: + resolution: {integrity: sha512-49+CzeGfOiwG85k+dDvKfOsXLd9PQACoY/FLrZfFOKmpWv166u7bAHmBLdzvxlk8nJ289UgpGf0k6GQZtC85Fg==} + dev: true + /@esbuild/aix-ppc64@0.25.10: resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} engines: {node: '>=18'} @@ -1459,6 +1479,16 @@ packages: engines: {node: '>=18.18'} dev: true + /@iconify-json/simple-icons@1.2.53: + resolution: {integrity: sha512-8GEW5mshsPAZpVAJmkBG/niR2qn8t4U03Wmz6aSD9R4VMZKTECqbOxH3z4inA0JfZOoTvP4qoK9T2VXAx2Xg5g==} + dependencies: + '@iconify/types': 2.0.0 + dev: true + + /@iconify/types@2.0.0: + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + dev: true + /@isaacs/fs-minipass@4.0.1: resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} @@ -1487,7 +1517,6 @@ packages: /@jridgewell/sourcemap-codec@1.5.5: resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - dev: true /@jridgewell/trace-mapping@0.3.31: resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -2773,6 +2802,10 @@ packages: resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} dev: false + /@rolldown/pluginutils@1.0.0-beta.29: + resolution: {integrity: sha512-NIJgOsMjbxAXvoGq/X0gD7VPMQ8j9g0BiDaNjVNVjvl+iKXxL3Jre0v31RmBYeLEmkbj2s02v8vFTbUXi5XS2Q==} + dev: true + /@rolldown/pluginutils@1.0.0-beta.35: resolution: {integrity: sha512-slYrCpoxJUqzFDDNlvrOYRazQUNRvWPjXA17dAOISY3rDMxX6k8K4cj2H+hEYMHF81HO3uNd5rHVigAWRM5dSg==} dev: true @@ -2953,6 +2986,60 @@ packages: dev: true optional: true + /@shikijs/core@3.13.0: + resolution: {integrity: sha512-3P8rGsg2Eh2qIHekwuQjzWhKI4jV97PhvYjYUzGqjvJfqdQPz+nMlfWahU24GZAyW1FxFI1sYjyhfh5CoLmIUA==} + dependencies: + '@shikijs/types': 3.13.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 + dev: true + + /@shikijs/engine-javascript@3.13.0: + resolution: {integrity: sha512-Ty7xv32XCp8u0eQt8rItpMs6rU9Ki6LJ1dQOW3V/56PKDcpvfHPnYFbsx5FFUP2Yim34m/UkazidamMNVR4vKg==} + dependencies: + '@shikijs/types': 3.13.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.3 + dev: true + + /@shikijs/engine-oniguruma@3.13.0: + resolution: {integrity: sha512-O42rBGr4UDSlhT2ZFMxqM7QzIU+IcpoTMzb3W7AlziI1ZF7R8eS2M0yt5Ry35nnnTX/LTLXFPUjRFCIW+Operg==} + dependencies: + '@shikijs/types': 3.13.0 + '@shikijs/vscode-textmate': 10.0.2 + dev: true + + /@shikijs/langs@3.13.0: + resolution: {integrity: sha512-672c3WAETDYHwrRP0yLy3W1QYB89Hbpj+pO4KhxK6FzIrDI2FoEXNiNCut6BQmEApYLfuYfpgOZaqbY+E9b8wQ==} + dependencies: + '@shikijs/types': 3.13.0 + dev: true + + /@shikijs/themes@3.13.0: + resolution: {integrity: sha512-Vxw1Nm1/Od8jyA7QuAenaV78BG2nSr3/gCGdBkLpfLscddCkzkL36Q5b67SrLLfvAJTOUzW39x4FHVCFriPVgg==} + dependencies: + '@shikijs/types': 3.13.0 + dev: true + + /@shikijs/transformers@3.13.0: + resolution: {integrity: sha512-833lcuVzcRiG+fXvgslWsM2f4gHpjEgui1ipIknSizRuTgMkNZupiXE5/TVJ6eSYfhNBFhBZKkReKWO2GgYmqA==} + dependencies: + '@shikijs/core': 3.13.0 + '@shikijs/types': 3.13.0 + dev: true + + /@shikijs/types@3.13.0: + resolution: {integrity: sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==} + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + dev: true + + /@shikijs/vscode-textmate@10.0.2: + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + dev: true + /@smithy/abort-controller@4.2.0: resolution: {integrity: sha512-PLUYa+SUKOEZtXFURBu/CNxlsxfaFGxSBPcStL13KpVeVWIfdezWyDqkz7iDLmwnxojXD0s5KzuB5HGHvt4Aeg==} engines: {node: '>=18.0.0'} @@ -3995,6 +4082,12 @@ packages: '@types/serve-static': 1.15.8 dev: true + /@types/hast@3.0.4: + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + dependencies: + '@types/unist': 3.0.3 + dev: true + /@types/http-errors@2.0.5: resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} dev: true @@ -4010,6 +4103,27 @@ packages: '@types/node': 20.19.19 dev: true + /@types/linkify-it@5.0.0: + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + dev: true + + /@types/markdown-it@14.1.2: + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + dev: true + + /@types/mdast@4.0.4: + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + dependencies: + '@types/unist': 3.0.3 + dev: true + + /@types/mdurl@2.0.0: + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + dev: true + /@types/mime@1.3.5: resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} dev: true @@ -4104,6 +4218,14 @@ packages: resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} dev: false + /@types/unist@3.0.3: + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + dev: true + + /@types/web-bluetooth@0.0.21: + resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + dev: true + /@typescript-eslint/eslint-plugin@8.45.0(@typescript-eslint/parser@8.45.0)(eslint@9.36.0)(typescript@5.9.3): resolution: {integrity: sha512-HC3y9CVuevvWCl/oyZuI47dOeDF9ztdMEfMH8/DW/Mhwa9cCLnK1oD7JoTVGW/u7kFzNZUKUoyJEqkaJh5y3Wg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4246,6 +4368,10 @@ packages: eslint-visitor-keys: 4.2.1 dev: true + /@ungap/structured-clone@1.3.0: + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + dev: true + /@vitejs/plugin-react-swc@4.1.0(vite@7.1.9): resolution: {integrity: sha512-Ff690TUck0Anlh7wdIcnsVMhofeEVgm44Y4OYdeeEEPSKyZHzDI9gfVBvySEhDfXtBp8tLCbfsVKPWEMEjq8/g==} engines: {node: ^20.19.0 || >=22.12.0} @@ -4259,6 +4385,217 @@ packages: - '@swc/helpers' dev: true + /@vitejs/plugin-vue@6.0.1(vite@7.1.9)(vue@3.5.22): + resolution: {integrity: sha512-+MaE752hU0wfPFJEUAIxqw18+20euHHdxVtMvbFcOEpjEyfqXH/5DCoTHiVJ0J29EhTJdoTkjEv5YBKU9dnoTw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 + vue: ^3.2.25 + dependencies: + '@rolldown/pluginutils': 1.0.0-beta.29 + vite: 7.1.9(@types/node@24.6.2) + vue: 3.5.22(typescript@5.9.3) + dev: true + + /@volar/language-core@1.11.1: + resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} + dependencies: + '@volar/source-map': 1.11.1 + dev: true + + /@volar/source-map@1.11.1: + resolution: {integrity: sha512-hJnOnwZ4+WT5iupLRnuzbULZ42L7BWWPMmruzwtLhJfpDVoZLjNBxHDi2sY2bgZXCKlpU5XcsMFoYrsQmPhfZg==} + dependencies: + muggle-string: 0.3.1 + dev: true + + /@volar/typescript@1.11.1: + resolution: {integrity: sha512-iU+t2mas/4lYierSnoFOeRFQUhAEMgsFuQxoxvwn5EdQopw43j+J27a4lt9LMInx1gLJBC6qL14WYGlgymaSMQ==} + dependencies: + '@volar/language-core': 1.11.1 + path-browserify: 1.0.1 + dev: true + + /@vue/compiler-core@3.5.22: + resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} + dependencies: + '@babel/parser': 7.28.4 + '@vue/shared': 3.5.22 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + /@vue/compiler-dom@3.5.22: + resolution: {integrity: sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==} + dependencies: + '@vue/compiler-core': 3.5.22 + '@vue/shared': 3.5.22 + + /@vue/compiler-sfc@3.5.22: + resolution: {integrity: sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==} + dependencies: + '@babel/parser': 7.28.4 + '@vue/compiler-core': 3.5.22 + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-ssr': 3.5.22 + '@vue/shared': 3.5.22 + estree-walker: 2.0.2 + magic-string: 0.30.19 + postcss: 8.5.6 + source-map-js: 1.2.1 + + /@vue/compiler-ssr@3.5.22: + resolution: {integrity: sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==} + dependencies: + '@vue/compiler-dom': 3.5.22 + '@vue/shared': 3.5.22 + + /@vue/devtools-api@8.0.2: + resolution: {integrity: sha512-RdwsaYoSTumwZ7XOt5yIPP1/T4O0bTs+c5XaEjmUB6f9x+FvDSL9AekxW1vuhK1lmA9TfewpXVt2r5LIax3LHw==} + dependencies: + '@vue/devtools-kit': 8.0.2 + dev: true + + /@vue/devtools-kit@8.0.2: + resolution: {integrity: sha512-yjZKdEmhJzQqbOh4KFBfTOQjDPMrjjBNCnHBvnTGJX+YLAqoUtY2J+cg7BE+EA8KUv8LprECq04ts75wCoIGWA==} + dependencies: + '@vue/devtools-shared': 8.0.2 + birpc: 2.6.1 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 2.0.0 + speakingurl: 14.0.1 + superjson: 2.2.2 + dev: true + + /@vue/devtools-shared@8.0.2: + resolution: {integrity: sha512-mLU0QVdy5Lp40PMGSixDw/Kbd6v5dkQXltd2r+mdVQV7iUog2NlZuLxFZApFZ/mObUBDhoCpf0T3zF2FWWdeHw==} + dependencies: + rfdc: 1.4.1 + dev: true + + /@vue/language-core@1.8.27(typescript@5.9.3): + resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@volar/language-core': 1.11.1 + '@volar/source-map': 1.11.1 + '@vue/compiler-dom': 3.5.22 + '@vue/shared': 3.5.22 + computeds: 0.0.1 + minimatch: 9.0.5 + muggle-string: 0.3.1 + path-browserify: 1.0.1 + typescript: 5.9.3 + vue-template-compiler: 2.7.16 + dev: true + + /@vue/reactivity@3.5.22: + resolution: {integrity: sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==} + dependencies: + '@vue/shared': 3.5.22 + + /@vue/runtime-core@3.5.22: + resolution: {integrity: sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==} + dependencies: + '@vue/reactivity': 3.5.22 + '@vue/shared': 3.5.22 + + /@vue/runtime-dom@3.5.22: + resolution: {integrity: sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==} + dependencies: + '@vue/reactivity': 3.5.22 + '@vue/runtime-core': 3.5.22 + '@vue/shared': 3.5.22 + csstype: 3.1.3 + + /@vue/server-renderer@3.5.22(vue@3.5.22): + resolution: {integrity: sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==} + peerDependencies: + vue: 3.5.22 + dependencies: + '@vue/compiler-ssr': 3.5.22 + '@vue/shared': 3.5.22 + vue: 3.5.22(typescript@5.9.3) + + /@vue/shared@3.5.22: + resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} + + /@vueuse/core@13.9.0(vue@3.5.22): + resolution: {integrity: sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA==} + peerDependencies: + vue: ^3.5.0 + dependencies: + '@types/web-bluetooth': 0.0.21 + '@vueuse/metadata': 13.9.0 + '@vueuse/shared': 13.9.0(vue@3.5.22) + vue: 3.5.22(typescript@5.9.3) + dev: true + + /@vueuse/integrations@13.9.0(focus-trap@7.6.5)(vue@3.5.22): + resolution: {integrity: sha512-SDobKBbPIOe0cVL7QxMzGkuUGHvWTdihi9zOrrWaWUgFKe15cwEcwfWmgrcNzjT6kHnNmWuTajPHoIzUjYNYYQ==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 || ^8 + vue: ^3.5.0 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + dependencies: + '@vueuse/core': 13.9.0(vue@3.5.22) + '@vueuse/shared': 13.9.0(vue@3.5.22) + focus-trap: 7.6.5 + vue: 3.5.22(typescript@5.9.3) + dev: true + + /@vueuse/metadata@13.9.0: + resolution: {integrity: sha512-1AFRvuiGphfF7yWixZa0KwjYH8ulyjDCC0aFgrGRz8+P4kvDFSdXLVfTk5xAN9wEuD1J6z4/myMoYbnHoX07zg==} + dev: true + + /@vueuse/shared@13.9.0(vue@3.5.22): + resolution: {integrity: sha512-e89uuTLMh0U5cZ9iDpEI2senqPGfbPRTHM/0AaQkcxnpqjkZqDYP8rpfm7edOz8s+pOCOROEy1PIveSW8+fL5g==} + peerDependencies: + vue: ^3.5.0 + dependencies: + vue: 3.5.22(typescript@5.9.3) + dev: true + /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: false @@ -4438,6 +4775,10 @@ packages: engines: {node: '>=8'} dev: true + /birpc@2.6.1: + resolution: {integrity: sha512-LPnFhlDpdSH6FJhJyn4M0kFO7vtQ5iPw24FnG0y21q09xC7e8+1LeR31S1MAIrDAHp4m7aas4bEkTDTvMAtebQ==} + dev: true + /body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -4536,6 +4877,10 @@ packages: resolution: {integrity: sha512-mzFa2DGIhuc5490Nd/G31xN1pnBnYMadtkyTjefPI7wzypqgCEpeWu9bJr0OnDsyKrW75zA9ZAt7pbQFmwLsQg==} dev: true + /ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + dev: true + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -4544,6 +4889,14 @@ packages: supports-color: 7.2.0 dev: true + /character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + dev: true + + /character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + dev: true + /chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -4652,6 +5005,14 @@ packages: delayed-stream: 1.0.0 dev: false + /comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + dev: true + + /computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + dev: true + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -4700,6 +5061,13 @@ packages: engines: {node: '>= 0.6'} dev: false + /copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + dependencies: + is-what: 4.1.16 + dev: true + /cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} @@ -4803,6 +5171,10 @@ packages: resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} dev: false + /de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + dev: true + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -4852,6 +5224,11 @@ packages: engines: {node: '>= 0.8'} dev: false + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -4865,6 +5242,12 @@ packages: resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} dev: false + /devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + dependencies: + dequal: 2.0.3 + dev: true + /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -4968,6 +5351,10 @@ packages: tapable: 2.3.0 dev: true + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + /es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -5169,6 +5556,9 @@ packages: engines: {node: '>=4.0'} dev: true + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -5348,6 +5738,12 @@ packages: resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} dev: false + /focus-trap@7.6.5: + resolution: {integrity: sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==} + dependencies: + tabbable: 6.2.0 + dev: true + /follow-redirects@1.15.11: resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} @@ -5538,6 +5934,33 @@ packages: dependencies: function-bind: 1.1.2 + /hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + dev: true + + /hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + dependencies: + '@types/hast': 3.0.4 + dev: true + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + /helmet@7.2.0: resolution: {integrity: sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==} engines: {node: '>=16.0.0'} @@ -5553,12 +5976,20 @@ packages: hermes-estree: 0.25.1 dev: true + /hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + dev: true + /html-parse-stringify@3.0.1: resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} dependencies: void-elements: 3.1.0 dev: false + /html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + dev: true + /http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -5693,6 +6124,11 @@ packages: engines: {node: '>=8'} dev: false + /is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + dev: true + /isbot@5.1.31: resolution: {integrity: sha512-DPgQshehErHAqSCKDb3rNW03pa2wS/v5evvUqtxt6TTnHRqAG8FdzcSSJs9656pK6Y+NT7K9R4acEYXLHYfpUQ==} engines: {node: '>=18'} @@ -5984,7 +6420,6 @@ packages: resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - dev: true /make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} @@ -5997,11 +6432,29 @@ packages: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} dev: true + /mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + dev: true + /math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} dev: false + /mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + dev: true + /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -6021,6 +6474,33 @@ packages: engines: {node: '>= 0.6'} dev: false + /micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + dev: true + + /micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + dev: true + + /micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + dev: true + + /micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + dev: true + + /micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + dev: true + /micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -6080,6 +6560,10 @@ packages: engines: {node: '>=16 || 14 >=14.17'} dev: true + /minisearch@7.2.0: + resolution: {integrity: sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==} + dev: true + /minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -6095,6 +6579,10 @@ packages: minipass: 7.1.2 dev: true + /mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + dev: true + /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} @@ -6120,11 +6608,14 @@ packages: /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + /muggle-string@0.3.1: + resolution: {integrity: sha512-ckmWDJjphvd/FvZawgygcUeQCxzvohjFO5RxTjj4eq8kw359gFF3E1brjfI+viLMxss5JrHTDRHZvu2/tuy0Qg==} + dev: true + /nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -6259,6 +6750,18 @@ packages: fn.name: 1.1.0 dev: false + /oniguruma-parser@0.12.1: + resolution: {integrity: sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==} + dev: true + + /oniguruma-to-es@4.3.3: + resolution: {integrity: sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==} + dependencies: + oniguruma-parser: 0.12.1 + regex: 6.0.1 + regex-recursion: 6.0.2 + dev: true + /optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -6316,6 +6819,10 @@ packages: engines: {node: '>= 0.8'} dev: false + /path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: true + /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -6341,9 +6848,12 @@ packages: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} dev: true + /perfect-debounce@2.0.0: + resolution: {integrity: sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==} + dev: true + /picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -6367,7 +6877,6 @@ packages: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 - dev: true /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -6398,6 +6907,10 @@ packages: react-is: 16.13.1 dev: false + /property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + dev: true + /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -6660,6 +7173,22 @@ packages: victory-vendor: 36.9.2 dev: false + /regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + dependencies: + regex-utilities: 2.3.0 + dev: true + + /regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + dev: true + + /regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + dependencies: + regex-utilities: 2.3.0 + dev: true + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -6693,6 +7222,10 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true + /rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + dev: true + /rimraf@2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -6841,6 +7374,19 @@ packages: engines: {node: '>=8'} dev: true + /shiki@3.13.0: + resolution: {integrity: sha512-aZW4l8Og16CokuCLf8CF8kq+KK2yOygapU5m3+hoGw0Mdosc6fPitjM+ujYarppj5ZIKGyPDPP1vqmQhr+5/0g==} + dependencies: + '@shikijs/core': 3.13.0 + '@shikijs/engine-javascript': 3.13.0 + '@shikijs/engine-oniguruma': 3.13.0 + '@shikijs/langs': 3.13.0 + '@shikijs/themes': 3.13.0 + '@shikijs/types': 3.13.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + dev: true + /side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -6906,7 +7452,6 @@ packages: /source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - dev: true /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -6925,6 +7470,10 @@ packages: engines: {node: '>= 12'} dev: true + /space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + dev: true + /speakeasy@2.0.0: resolution: {integrity: sha512-lW2A2s5LKi8rwu77ewisuUOtlCydF/hmQSOJjpTqTj1gZLkNgTaYnyvfxy2WBr4T/h+9c4g8HIITfj83OkFQFw==} engines: {node: '>= 0.10.0'} @@ -6932,6 +7481,11 @@ packages: base32.js: 0.0.1 dev: false + /speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + dev: true + /stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} dev: false @@ -6956,6 +7510,13 @@ packages: safe-buffer: 5.2.1 dev: false + /stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + dev: true + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -6982,6 +7543,13 @@ packages: resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} dev: true + /superjson@2.2.2: + resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} + engines: {node: '>=16'} + dependencies: + copy-anything: 3.0.5 + dev: true + /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -6994,6 +7562,10 @@ packages: engines: {node: '>= 0.4'} dev: true + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: true + /tailwind-merge@3.3.1: resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} dev: false @@ -7069,6 +7641,10 @@ packages: hasBin: true dev: true + /trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + dev: true + /triple-beam@1.4.1: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} engines: {node: '>= 14.0.0'} @@ -7274,6 +7850,39 @@ packages: resolution: {integrity: sha512-Ov2Rr9Sx+fRgagJ5AX0qvItZG/JKKoBRAVITs1zk7IqZGTJUwgUr7qoYBpWwakpWilTZFM98rG/AFRocu10iIQ==} dev: true + /unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + dependencies: + '@types/unist': 3.0.3 + dev: true + + /unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + dependencies: + '@types/unist': 3.0.3 + dev: true + + /unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + dependencies: + '@types/unist': 3.0.3 + dev: true + + /unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + dev: true + + /unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + dev: true + /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -7381,6 +7990,20 @@ packages: - '@types/react-dom' dev: false + /vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + dev: true + + /vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + dev: true + /victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} dependencies: @@ -7451,11 +8074,104 @@ packages: fsevents: 2.3.3 dev: true + /vitepress@2.0.0-alpha.12(typescript@5.9.3): + resolution: {integrity: sha512-yZwCwRRepcpN5QeAhwSnEJxS3I6zJcVixqL1dnm6km4cnriLpQyy2sXQDsE5Ti3pxGPbhU51nTMwI+XC1KNnJg==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + oxc-minify: ^0.82.1 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + oxc-minify: + optional: true + postcss: + optional: true + dependencies: + '@docsearch/css': 4.1.0 + '@docsearch/js': 4.1.0 + '@iconify-json/simple-icons': 1.2.53 + '@shikijs/core': 3.13.0 + '@shikijs/transformers': 3.13.0 + '@shikijs/types': 3.13.0 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 6.0.1(vite@7.1.9)(vue@3.5.22) + '@vue/devtools-api': 8.0.2 + '@vue/shared': 3.5.22 + '@vueuse/core': 13.9.0(vue@3.5.22) + '@vueuse/integrations': 13.9.0(focus-trap@7.6.5)(vue@3.5.22) + focus-trap: 7.6.5 + mark.js: 8.11.1 + minisearch: 7.2.0 + shiki: 3.13.0 + vite: 7.1.9(@types/node@24.6.2) + vue: 3.5.22(typescript@5.9.3) + transitivePeerDependencies: + - '@types/node' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jiti + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - sass + - sass-embedded + - sortablejs + - stylus + - sugarss + - terser + - tsx + - typescript + - universal-cookie + - yaml + dev: true + /void-elements@3.1.0: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} dev: false + /vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + dev: true + + /vue-tsc@1.8.27(typescript@5.9.3): + resolution: {integrity: sha512-WesKCAZCRAbmmhuGl3+VrdWItEvfoFIPXOvUJkjULi+x+6G/Dy69yO3TBRJDr9eUlmsNAwVmxsNZxvHKzbkKdg==} + hasBin: true + peerDependencies: + typescript: '*' + dependencies: + '@volar/typescript': 1.11.1 + '@vue/language-core': 1.8.27(typescript@5.9.3) + semver: 7.7.2 + typescript: 5.9.3 + dev: true + + /vue@3.5.22(typescript@5.9.3): + resolution: {integrity: sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@vue/compiler-dom': 3.5.22 + '@vue/compiler-sfc': 3.5.22 + '@vue/runtime-dom': 3.5.22 + '@vue/server-renderer': 3.5.22(vue@3.5.22) + '@vue/shared': 3.5.22 + typescript: 5.9.3 + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false @@ -7627,3 +8343,7 @@ packages: '@types/react': 19.2.0 react: 19.2.0 dev: false + + /zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + dev: true