vibecarbon 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +663 -0
- package/README.md +188 -0
- package/carbon/.claude/hooks/task-completed-gate.sh +19 -0
- package/carbon/.claude/hooks/teammate-idle-gate.sh +29 -0
- package/carbon/.claude/settings.json +29 -0
- package/carbon/.cursor/rules/vibecarbon.mdc +6 -0
- package/carbon/.dockerignore +57 -0
- package/carbon/.env.example +219 -0
- package/carbon/.github/copilot-instructions.md +3 -0
- package/carbon/.github/workflows/deploy.yml +346 -0
- package/carbon/.github/workflows/vibecarbon-build.yml +81 -0
- package/carbon/.windsurfrules +74 -0
- package/carbon/AGENTS.md +422 -0
- package/carbon/CLAUDE.md +3 -0
- package/carbon/DEVELOPMENT.md +187 -0
- package/carbon/Dockerfile +98 -0
- package/carbon/LICENSE +21 -0
- package/carbon/PRODUCTION.md +364 -0
- package/carbon/README.md +193 -0
- package/carbon/TESTING.md +138 -0
- package/carbon/backup/Dockerfile +75 -0
- package/carbon/backup/backup.sh +95 -0
- package/carbon/backup/compose-backup.sh +140 -0
- package/carbon/biome.json +83 -0
- package/carbon/cloud-init/docker-ce-setup.yaml +55 -0
- package/carbon/cloud-init/k3s/master-init.sh +215 -0
- package/carbon/cloud-init/k3s/supabase-init.sh +167 -0
- package/carbon/cloud-init/k3s/worker-init.sh +147 -0
- package/carbon/components.json +24 -0
- package/carbon/content/blog/authentication-guide.mdx +34 -0
- package/carbon/content/blog/getting-started.mdx +41 -0
- package/carbon/content/changelog/v0-1-0.mdx +40 -0
- package/carbon/content/docs/analytics.mdx +90 -0
- package/carbon/content/docs/authentication.mdx +231 -0
- package/carbon/content/docs/background-jobs.mdx +116 -0
- package/carbon/content/docs/cli.mdx +630 -0
- package/carbon/content/docs/database.mdx +236 -0
- package/carbon/content/docs/deployment.mdx +227 -0
- package/carbon/content/docs/development.mdx +238 -0
- package/carbon/content/docs/environments.mdx +84 -0
- package/carbon/content/docs/getting-started.mdx +112 -0
- package/carbon/content/docs/legal/privacy-policy.mdx +89 -0
- package/carbon/content/docs/legal/terms-of-service.mdx +99 -0
- package/carbon/content/docs/optional-services.mdx +160 -0
- package/carbon/db/Dockerfile +23 -0
- package/carbon/docker-compose.dev-init.yml +5 -0
- package/carbon/docker-compose.metabase.override.yml +14 -0
- package/carbon/docker-compose.metabase.prod.yml +28 -0
- package/carbon/docker-compose.metabase.yml +84 -0
- package/carbon/docker-compose.n8n.override.yml +14 -0
- package/carbon/docker-compose.n8n.prod.yml +31 -0
- package/carbon/docker-compose.n8n.yml +97 -0
- package/carbon/docker-compose.observability.override.yml +18 -0
- package/carbon/docker-compose.observability.prod.yml +28 -0
- package/carbon/docker-compose.observability.yml +125 -0
- package/carbon/docker-compose.override.yml +28 -0
- package/carbon/docker-compose.prod.yml +294 -0
- package/carbon/docker-compose.yml +508 -0
- package/carbon/docker-entrypoint.sh +12 -0
- package/carbon/ha/activate-standby.sh +52 -0
- package/carbon/ha/primary-init.sql +36 -0
- package/carbon/ha/standby-init.sh +74 -0
- package/carbon/k8s/LICENSE +99 -0
- package/carbon/k8s/README.md +272 -0
- package/carbon/k8s/base/app/deployment.yaml +130 -0
- package/carbon/k8s/base/app/hpa.yaml +44 -0
- package/carbon/k8s/base/app/kustomization.yaml +10 -0
- package/carbon/k8s/base/app/network-policy.yaml +124 -0
- package/carbon/k8s/base/app/pdb.yaml +14 -0
- package/carbon/k8s/base/app/rbac.yaml +36 -0
- package/carbon/k8s/base/app/service.yaml +16 -0
- package/carbon/k8s/base/backup/cronjob.yaml +120 -0
- package/carbon/k8s/base/backup/kustomization.yaml +7 -0
- package/carbon/k8s/base/backup/network-policy.yaml +31 -0
- package/carbon/k8s/base/backup/rbac.yaml +7 -0
- package/carbon/k8s/base/cluster-autoscaler/deployment.yaml +103 -0
- package/carbon/k8s/base/cluster-autoscaler/kustomization.yaml +17 -0
- package/carbon/k8s/base/cluster-autoscaler/rbac.yaml +109 -0
- package/carbon/k8s/base/config/configmap.yaml +48 -0
- package/carbon/k8s/base/config/kustomization.yaml +8 -0
- package/carbon/k8s/base/hetzner-ccm/kustomization.yaml +9 -0
- package/carbon/k8s/base/hetzner-csi/kustomization.yaml +9 -0
- package/carbon/k8s/base/kustomization.yaml +43 -0
- package/carbon/k8s/base/namespace.yaml +7 -0
- package/carbon/k8s/base/network-policies.yaml +95 -0
- package/carbon/k8s/base/registry/kustomization.yaml +5 -0
- package/carbon/k8s/base/registry/local-registry.yaml +193 -0
- package/carbon/k8s/base/traefik/certificate.yaml +21 -0
- package/carbon/k8s/base/traefik/configmap.yaml +13 -0
- package/carbon/k8s/base/traefik/deployment.yaml +165 -0
- package/carbon/k8s/base/traefik/ingressroute.yaml +141 -0
- package/carbon/k8s/base/traefik/kustomization.yaml +11 -0
- package/carbon/k8s/base/traefik/middleware.yaml +109 -0
- package/carbon/k8s/base/traefik/network-policy.yaml +92 -0
- package/carbon/k8s/base/traefik/service.yaml +38 -0
- package/carbon/k8s/flux/README.md +49 -0
- package/carbon/k8s/flux/clusters/primary/vibecarbon.yaml +128 -0
- package/carbon/k8s/flux/clusters/standby/vibecarbon.yaml +83 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-release.yaml +38 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/helm-repository.yaml +16 -0
- package/carbon/k8s/gitops/cert-manager-webhook-hetzner/kustomization.yaml +10 -0
- package/carbon/k8s/gitops/supabase/helm-release.yaml +66 -0
- package/carbon/k8s/gitops/supabase/helm-repository.yaml +18 -0
- package/carbon/k8s/gitops/supabase/kustomization.yaml +33 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-cloudflare.yaml +51 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-hetzner.yaml +59 -0
- package/carbon/k8s/infra/cert-manager-resources/cluster-issuers-manual.yaml +43 -0
- package/carbon/k8s/infra/cert-manager-resources/kustomization.yaml +15 -0
- package/carbon/k8s/infra/kustomization.yaml +21 -0
- package/carbon/k8s/infra/traefik-crds/kustomization.yaml +10 -0
- package/carbon/k8s/overlays/local/configmap.yaml +23 -0
- package/carbon/k8s/overlays/local/ingressroute-studio.yaml +104 -0
- package/carbon/k8s/overlays/local/kustomization.yaml +215 -0
- package/carbon/k8s/overlays/local/namespace.yaml +8 -0
- package/carbon/k8s/overlays/local/secrets.yaml +32 -0
- package/carbon/k8s/overlays/production/kustomization.yaml +34 -0
- package/carbon/k8s/test-local.sh +318 -0
- package/carbon/k8s/values/supabase.values.yaml +133 -0
- package/carbon/package.json +154 -0
- package/carbon/runtime.Dockerfile +17 -0
- package/carbon/scripts/_dev-jwt.mjs +45 -0
- package/carbon/scripts/check-rls.ts +53 -0
- package/carbon/scripts/dev-init.js +191 -0
- package/carbon/scripts/dev.js +191 -0
- package/carbon/scripts/docker-down.js +63 -0
- package/carbon/scripts/docker-logs.js +59 -0
- package/carbon/scripts/docker-up.js +222 -0
- package/carbon/scripts/generate-dev-configs.sh +131 -0
- package/carbon/scripts/generate-rss.ts +116 -0
- package/carbon/scripts/generate-sitemap.ts +102 -0
- package/carbon/scripts/k8s-apply.js +71 -0
- package/carbon/scripts/k8s-delete.js +75 -0
- package/carbon/scripts/lib/manifest.js +176 -0
- package/carbon/scripts/secret-scan.mjs +278 -0
- package/carbon/scripts/validate-dev-configs.sh +101 -0
- package/carbon/src/client/App.tsx +202 -0
- package/carbon/src/client/assets/hyperformant-dark.svg +29 -0
- package/carbon/src/client/assets/hyperformant-light.svg +29 -0
- package/carbon/src/client/assets/logos/aider.svg +1 -0
- package/carbon/src/client/assets/logos/antigravity.svg +1 -0
- package/carbon/src/client/assets/logos/bolt.svg +1 -0
- package/carbon/src/client/assets/logos/claude-code.svg +1 -0
- package/carbon/src/client/assets/logos/copilot.svg +1 -0
- package/carbon/src/client/assets/logos/cursor.svg +1 -0
- package/carbon/src/client/assets/logos/gemini-cli.svg +1 -0
- package/carbon/src/client/assets/logos/lovable.svg +1 -0
- package/carbon/src/client/assets/logos/openai-codex.svg +1 -0
- package/carbon/src/client/assets/logos/v0.svg +1 -0
- package/carbon/src/client/assets/logos/windsurf.svg +1 -0
- package/carbon/src/client/assets/vibecarbon-icon.svg +19 -0
- package/carbon/src/client/assets/vibecarbon-logo-dark.svg +29 -0
- package/carbon/src/client/assets/vibecarbon-logo-light.svg +29 -0
- package/carbon/src/client/components/AIIntegrationSection.tsx +120 -0
- package/carbon/src/client/components/AppSidebar.tsx +760 -0
- package/carbon/src/client/components/ArchitectureSection.tsx +46 -0
- package/carbon/src/client/components/CTAFooter.tsx +59 -0
- package/carbon/src/client/components/ComparisonSection.tsx +132 -0
- package/carbon/src/client/components/ContentPanel.tsx +66 -0
- package/carbon/src/client/components/ContentSkeleton.tsx +21 -0
- package/carbon/src/client/components/ErrorBoundary.tsx +46 -0
- package/carbon/src/client/components/FAQSection.tsx +76 -0
- package/carbon/src/client/components/FileUpload.tsx +210 -0
- package/carbon/src/client/components/HeaderActions.tsx +17 -0
- package/carbon/src/client/components/Hero.tsx +608 -0
- package/carbon/src/client/components/ImpersonationBanner.tsx +31 -0
- package/carbon/src/client/components/LanguageSwitcher.tsx +67 -0
- package/carbon/src/client/components/Logo.tsx +87 -0
- package/carbon/src/client/components/LogoStrip.tsx +76 -0
- package/carbon/src/client/components/MetricsStrip.tsx +48 -0
- package/carbon/src/client/components/Nav.tsx +195 -0
- package/carbon/src/client/components/NewsletterSignup.tsx +147 -0
- package/carbon/src/client/components/NotificationDrawer.tsx +171 -0
- package/carbon/src/client/components/PageHeader.tsx +24 -0
- package/carbon/src/client/components/PlanGate.tsx +36 -0
- package/carbon/src/client/components/PricingSection.tsx +371 -0
- package/carbon/src/client/components/SEO.tsx +34 -0
- package/carbon/src/client/components/SmoothScroll.tsx +45 -0
- package/carbon/src/client/components/TechStackSection.tsx +165 -0
- package/carbon/src/client/components/WorkflowSection.tsx +604 -0
- package/carbon/src/client/components/admin/DockerLogs.tsx +276 -0
- package/carbon/src/client/components/admin/PerformanceMetrics.tsx +230 -0
- package/carbon/src/client/components/admin/ServiceCard.tsx +45 -0
- package/carbon/src/client/components/admin/ServicesStatus.tsx +296 -0
- package/carbon/src/client/components/architecture/ArchitectureDiagram.tsx +413 -0
- package/carbon/src/client/components/auth/AuthProvider.tsx +466 -0
- package/carbon/src/client/components/effects/FilmGrainOverlay.tsx +35 -0
- package/carbon/src/client/components/effects/FresnelEdge.tsx +49 -0
- package/carbon/src/client/components/effects/GlowTracker.tsx +46 -0
- package/carbon/src/client/components/effects/SparkBurst.tsx +145 -0
- package/carbon/src/client/components/effects/VGlowEffect.tsx +83 -0
- package/carbon/src/client/components/effects/index.ts +2 -0
- package/carbon/src/client/components/layouts/SidebarLayout.tsx +20 -0
- package/carbon/src/client/components/scroll/ScrollSection.tsx +76 -0
- package/carbon/src/client/components/scroll/ScrollytellingProvider.tsx +81 -0
- package/carbon/src/client/components/scroll/index.ts +2 -0
- package/carbon/src/client/components/ui/accordion.tsx +71 -0
- package/carbon/src/client/components/ui/alert-dialog.tsx +162 -0
- package/carbon/src/client/components/ui/alert.tsx +73 -0
- package/carbon/src/client/components/ui/aspect-ratio.tsx +22 -0
- package/carbon/src/client/components/ui/avatar.tsx +91 -0
- package/carbon/src/client/components/ui/badge.tsx +50 -0
- package/carbon/src/client/components/ui/breadcrumb.tsx +100 -0
- package/carbon/src/client/components/ui/button-group.tsx +78 -0
- package/carbon/src/client/components/ui/button.tsx +120 -0
- package/carbon/src/client/components/ui/calendar.tsx +182 -0
- package/carbon/src/client/components/ui/card.tsx +85 -0
- package/carbon/src/client/components/ui/carousel.tsx +227 -0
- package/carbon/src/client/components/ui/chart.tsx +357 -0
- package/carbon/src/client/components/ui/checkbox.tsx +27 -0
- package/carbon/src/client/components/ui/collapsible.tsx +15 -0
- package/carbon/src/client/components/ui/command.tsx +178 -0
- package/carbon/src/client/components/ui/context-menu.tsx +233 -0
- package/carbon/src/client/components/ui/dialog.tsx +132 -0
- package/carbon/src/client/components/ui/drawer.tsx +118 -0
- package/carbon/src/client/components/ui/dropdown-menu.tsx +242 -0
- package/carbon/src/client/components/ui/empty.tsx +94 -0
- package/carbon/src/client/components/ui/field.tsx +226 -0
- package/carbon/src/client/components/ui/hover-card.tsx +44 -0
- package/carbon/src/client/components/ui/input-group.tsx +146 -0
- package/carbon/src/client/components/ui/input-otp.tsx +83 -0
- package/carbon/src/client/components/ui/input.tsx +20 -0
- package/carbon/src/client/components/ui/item.tsx +188 -0
- package/carbon/src/client/components/ui/kbd.tsx +26 -0
- package/carbon/src/client/components/ui/label.tsx +21 -0
- package/carbon/src/client/components/ui/menubar.tsx +250 -0
- package/carbon/src/client/components/ui/navigation-menu.tsx +155 -0
- package/carbon/src/client/components/ui/pagination.tsx +102 -0
- package/carbon/src/client/components/ui/popover.tsx +75 -0
- package/carbon/src/client/components/ui/progress.tsx +66 -0
- package/carbon/src/client/components/ui/radio-group.tsx +36 -0
- package/carbon/src/client/components/ui/resizable.tsx +46 -0
- package/carbon/src/client/components/ui/scroll-area.tsx +48 -0
- package/carbon/src/client/components/ui/select.tsx +186 -0
- package/carbon/src/client/components/ui/separator.tsx +21 -0
- package/carbon/src/client/components/ui/sheet.tsx +124 -0
- package/carbon/src/client/components/ui/sidebar.tsx +702 -0
- package/carbon/src/client/components/ui/skeleton.tsx +13 -0
- package/carbon/src/client/components/ui/slider.tsx +57 -0
- package/carbon/src/client/components/ui/sonner.tsx +45 -0
- package/carbon/src/client/components/ui/spinner.tsx +15 -0
- package/carbon/src/client/components/ui/switch.tsx +30 -0
- package/carbon/src/client/components/ui/table.tsx +89 -0
- package/carbon/src/client/components/ui/tabs.tsx +73 -0
- package/carbon/src/client/components/ui/textarea.tsx +18 -0
- package/carbon/src/client/components/ui/toggle-group.tsx +87 -0
- package/carbon/src/client/components/ui/toggle.tsx +44 -0
- package/carbon/src/client/components/ui/tooltip.tsx +56 -0
- package/carbon/src/client/hooks/api/index.ts +14 -0
- package/carbon/src/client/hooks/api/useAuthSettings.ts +80 -0
- package/carbon/src/client/hooks/api/useSubscription.ts +87 -0
- package/carbon/src/client/hooks/use-mobile.ts +21 -0
- package/carbon/src/client/hooks/useMousePosition.ts +91 -0
- package/carbon/src/client/hooks/useNotifications.tsx +124 -0
- package/carbon/src/client/hooks/useOrganizationMembers.ts +127 -0
- package/carbon/src/client/hooks/useOrganizations.tsx +230 -0
- package/carbon/src/client/hooks/usePackageManager.ts +69 -0
- package/carbon/src/client/hooks/useReducedMotion.ts +20 -0
- package/carbon/src/client/hooks/useRunningServices.ts +114 -0
- package/carbon/src/client/hooks/useScrollProgress.ts +56 -0
- package/carbon/src/client/index.css +467 -0
- package/carbon/src/client/index.html +56 -0
- package/carbon/src/client/lib/admin-services.ts +151 -0
- package/carbon/src/client/lib/api.ts +32 -0
- package/carbon/src/client/lib/blog.ts +35 -0
- package/carbon/src/client/lib/changelog.ts +33 -0
- package/carbon/src/client/lib/docs-search.ts +101 -0
- package/carbon/src/client/lib/docs.ts +37 -0
- package/carbon/src/client/lib/i18n.ts +32 -0
- package/carbon/src/client/lib/supabase.ts +72 -0
- package/carbon/src/client/lib/tailwind-colors.ts +357 -0
- package/carbon/src/client/lib/theme.ts +117 -0
- package/carbon/src/client/lib/utils.ts +22 -0
- package/carbon/src/client/locales/de.json +529 -0
- package/carbon/src/client/locales/en.json +461 -0
- package/carbon/src/client/locales/es.json +529 -0
- package/carbon/src/client/locales/fr.json +529 -0
- package/carbon/src/client/locales/pt.json +529 -0
- package/carbon/src/client/main.tsx +56 -0
- package/carbon/src/client/mdx.d.ts +13 -0
- package/carbon/src/client/pages/ApiDocs.tsx +76 -0
- package/carbon/src/client/pages/AuthCallback.tsx +34 -0
- package/carbon/src/client/pages/Blog.tsx +167 -0
- package/carbon/src/client/pages/Changelog.tsx +171 -0
- package/carbon/src/client/pages/Charts.tsx +388 -0
- package/carbon/src/client/pages/Checkout.tsx +227 -0
- package/carbon/src/client/pages/Contact.tsx +174 -0
- package/carbon/src/client/pages/Dashboard.tsx +368 -0
- package/carbon/src/client/pages/Docs.tsx +372 -0
- package/carbon/src/client/pages/ForgotPassword.tsx +111 -0
- package/carbon/src/client/pages/Home.tsx +187 -0
- package/carbon/src/client/pages/Legal.tsx +100 -0
- package/carbon/src/client/pages/Login.tsx +408 -0
- package/carbon/src/client/pages/MFAVerify.tsx +156 -0
- package/carbon/src/client/pages/NotFound.tsx +21 -0
- package/carbon/src/client/pages/Onboarding.tsx +246 -0
- package/carbon/src/client/pages/ResetPassword.tsx +200 -0
- package/carbon/src/client/pages/UIComponents.tsx +390 -0
- package/carbon/src/client/pages/admin/ContactSubmissions.tsx +220 -0
- package/carbon/src/client/pages/admin/Dashboard.tsx +24 -0
- package/carbon/src/client/pages/admin/Infrastructure.tsx +257 -0
- package/carbon/src/client/pages/admin/Jobs.tsx +225 -0
- package/carbon/src/client/pages/admin/Logs.tsx +18 -0
- package/carbon/src/client/pages/admin/Newsletter.tsx +300 -0
- package/carbon/src/client/pages/admin/Notifications.tsx +603 -0
- package/carbon/src/client/pages/admin/Organizations.tsx +306 -0
- package/carbon/src/client/pages/admin/Settings.tsx +314 -0
- package/carbon/src/client/pages/admin/Theme.tsx +465 -0
- package/carbon/src/client/pages/admin/Users.tsx +365 -0
- package/carbon/src/client/pages/api-docs.css +156 -0
- package/carbon/src/client/pages/organizations/Details.tsx +200 -0
- package/carbon/src/client/pages/organizations/Members.tsx +402 -0
- package/carbon/src/client/pages/settings/Billing.tsx +473 -0
- package/carbon/src/client/pages/settings/Profile.tsx +160 -0
- package/carbon/src/client/pages/settings/Security.tsx +341 -0
- package/carbon/src/client/public/favicon.svg +19 -0
- package/carbon/src/client/public/robots.txt +8 -0
- package/carbon/src/server/billing/index.ts +104 -0
- package/carbon/src/server/billing/provider.ts +81 -0
- package/carbon/src/server/billing/providers/paddle.ts +314 -0
- package/carbon/src/server/billing/providers/polar.ts +325 -0
- package/carbon/src/server/billing/providers/stripe.ts +233 -0
- package/carbon/src/server/emails/templates.ts +116 -0
- package/carbon/src/server/index.ts +554 -0
- package/carbon/src/server/lib/auth.ts +6 -0
- package/carbon/src/server/lib/email.ts +64 -0
- package/carbon/src/server/lib/env.ts +112 -0
- package/carbon/src/server/lib/errors.ts +21 -0
- package/carbon/src/server/lib/logger.ts +17 -0
- package/carbon/src/server/lib/rate-limiter.ts +288 -0
- package/carbon/src/server/lib/request.ts +34 -0
- package/carbon/src/server/lib/stripe.ts +42 -0
- package/carbon/src/server/lib/supabase.ts +65 -0
- package/carbon/src/server/middleware/requirePlan.ts +80 -0
- package/carbon/src/server/routes/_internal/services-status.ts +958 -0
- package/carbon/src/server/routes/_internal/verify-role.ts +185 -0
- package/carbon/src/server/routes/health.ts +48 -0
- package/carbon/src/server/routes/v1/admin/contact.ts +128 -0
- package/carbon/src/server/routes/v1/admin/jobs.ts +171 -0
- package/carbon/src/server/routes/v1/admin/newsletter.ts +237 -0
- package/carbon/src/server/routes/v1/auth.ts +390 -0
- package/carbon/src/server/routes/v1/billing.ts +718 -0
- package/carbon/src/server/routes/v1/contact.ts +93 -0
- package/carbon/src/server/routes/v1/index.ts +1333 -0
- package/carbon/src/server/routes/v1/newsletter.ts +181 -0
- package/carbon/src/server/routes/v1/performance.ts +157 -0
- package/carbon/src/server/routes/v1/stats.ts +170 -0
- package/carbon/src/server/routes/v1/theme.ts +106 -0
- package/carbon/src/server/routes/webhooks/billing.ts +376 -0
- package/carbon/src/server/routes/webhooks/stripe.ts +276 -0
- package/carbon/src/server/types.ts +11 -0
- package/carbon/src/shared/pricing.ts +155 -0
- package/carbon/src/shared/types.ts +338 -0
- package/carbon/supabase/migrations/00001_init.sql +717 -0
- package/carbon/supabase/migrations/00002_theme_settings.sql +13 -0
- package/carbon/supabase/migrations/00003_pg_cron.sql +121 -0
- package/carbon/supabase/migrations/00004_contact_newsletter.sql +81 -0
- package/carbon/supabase/migrations/00005_localization_languages.sql +22 -0
- package/carbon/supabase/seed.sql +16 -0
- package/carbon/tests/_helpers/app.ts +45 -0
- package/carbon/tests/_helpers/env.ts +37 -0
- package/carbon/tests/_helpers/factories.ts +69 -0
- package/carbon/tests/_helpers/jwt.ts +23 -0
- package/carbon/tests/_helpers/setup-integration.ts +20 -0
- package/carbon/tests/_helpers/setup-rtl.ts +12 -0
- package/carbon/tests/component/ErrorBoundary.test.tsx +53 -0
- package/carbon/tests/component/use-auth-settings.test.tsx +119 -0
- package/carbon/tests/integration/server/routes/contact.test.ts +162 -0
- package/carbon/tests/integration/server/routes/health.test.ts +61 -0
- package/carbon/tests/structural/i18n-parity.test.ts +42 -0
- package/carbon/tests/unit/client/utils.test.ts +49 -0
- package/carbon/tests/unit/shared/pricing.test.ts +93 -0
- package/carbon/tsconfig.json +27 -0
- package/carbon/tsconfig.server.json +27 -0
- package/carbon/tsconfig.test.json +9 -0
- package/carbon/vite.config.ts +110 -0
- package/carbon/vitest.config.ts +74 -0
- package/carbon/volumes/db/jwt.sql +57 -0
- package/carbon/volumes/db/metabase-init.sh +29 -0
- package/carbon/volumes/db/n8n-init.sh +25 -0
- package/carbon/volumes/db/realtime.sql +33 -0
- package/carbon/volumes/db/roles.sql +93 -0
- package/carbon/volumes/db/set-passwords.sh +12 -0
- package/carbon/volumes/db/super-admin.dev.sql +113 -0
- package/carbon/volumes/db/super-admin.generated.sql +113 -0
- package/carbon/volumes/db/super-admin.sql +114 -0
- package/carbon/volumes/grafana/dashboards/logs.json +179 -0
- package/carbon/volumes/grafana/dashboards/overview.json +523 -0
- package/carbon/volumes/grafana/dashboards/postgresql.json +337 -0
- package/carbon/volumes/grafana/dashboards.dev/logs.json +179 -0
- package/carbon/volumes/grafana/dashboards.dev/overview.json +156 -0
- package/carbon/volumes/grafana/dashboards.dev/postgresql.json +337 -0
- package/carbon/volumes/grafana/provisioning/dashboards/dashboards.dev.yml +16 -0
- package/carbon/volumes/grafana/provisioning/dashboards/dashboards.yml +16 -0
- package/carbon/volumes/grafana/provisioning/datasources/datasources.yml +43 -0
- package/carbon/volumes/kong/docker-entrypoint.sh +9 -0
- package/carbon/volumes/kong/kong.yml +208 -0
- package/carbon/volumes/loki/loki-config.yml +58 -0
- package/carbon/volumes/n8n/hooks.js +131 -0
- package/carbon/volumes/n8n/scripts/setup.sh +66 -0
- package/carbon/volumes/prometheus/prometheus.yml +43 -0
- package/carbon/volumes/promtail/promtail-config.yml +64 -0
- package/carbon/volumes/traefik/middlewares.dev.yml +83 -0
- package/carbon/volumes/traefik/middlewares.yml +95 -0
- package/carbon/volumes/traefik/vite-dev.yml +20 -0
- package/package.json +95 -0
- package/src/access.js +354 -0
- package/src/activate.js +187 -0
- package/src/add.js +718 -0
- package/src/backup.js +786 -0
- package/src/cli.js +350 -0
- package/src/configure.js +967 -0
- package/src/console.js +155 -0
- package/src/create.js +1499 -0
- package/src/deploy.js +311 -0
- package/src/destroy.js +2033 -0
- package/src/diagnose.js +735 -0
- package/src/down.js +80 -0
- package/src/failover.js +1032 -0
- package/src/lib/backup-s3.js +179 -0
- package/src/lib/build.js +33 -0
- package/src/lib/checksum.js +28 -0
- package/src/lib/ci-setup.js +666 -0
- package/src/lib/cli/help.js +129 -0
- package/src/lib/cli/parse-flags.js +160 -0
- package/src/lib/cli/select-action.js +65 -0
- package/src/lib/cli/select-environment.js +108 -0
- package/src/lib/cli/tty-guard.js +75 -0
- package/src/lib/cloudflare.js +447 -0
- package/src/lib/colors.js +52 -0
- package/src/lib/command.js +361 -0
- package/src/lib/config.js +359 -0
- package/src/lib/cost.js +103 -0
- package/src/lib/deploy/bundle.js +231 -0
- package/src/lib/deploy/compose/acme-verify.js +121 -0
- package/src/lib/deploy/compose/build-args.js +78 -0
- package/src/lib/deploy/compose/ha.js +1874 -0
- package/src/lib/deploy/compose/index.js +1294 -0
- package/src/lib/deploy/compose/reconcile.js +74 -0
- package/src/lib/deploy/github.js +382 -0
- package/src/lib/deploy/image.js +191 -0
- package/src/lib/deploy/index.js +119 -0
- package/src/lib/deploy/k8s/LICENSE +99 -0
- package/src/lib/deploy/k8s/gitops-deploy.js +298 -0
- package/src/lib/deploy/k8s/ha/index.js +1000 -0
- package/src/lib/deploy/k8s/index.js +62 -0
- package/src/lib/deploy/k8s/k3s.js +2515 -0
- package/src/lib/deploy/orchestrator.js +1401 -0
- package/src/lib/deploy/prompts.js +545 -0
- package/src/lib/deploy/remote-build.js +130 -0
- package/src/lib/deploy/state.js +120 -0
- package/src/lib/deploy/utils.js +328 -0
- package/src/lib/deploy-logger.js +93 -0
- package/src/lib/dns-propagation.js +48 -0
- package/src/lib/environment.js +58 -0
- package/src/lib/fetch-retry.js +103 -0
- package/src/lib/github-environments.js +335 -0
- package/src/lib/hetzner-dns.js +377 -0
- package/src/lib/hetzner-guided-setup.js +275 -0
- package/src/lib/host-keys.js +37 -0
- package/src/lib/iac/cloud-init.js +52 -0
- package/src/lib/iac/index.js +325 -0
- package/src/lib/iac/programs/hetzner-compose.js +130 -0
- package/src/lib/iac/programs/hetzner-k8s.js +320 -0
- package/src/lib/kubectl.js +81 -0
- package/src/lib/licensing/index.js +259 -0
- package/src/lib/licensing/tiers.js +181 -0
- package/src/lib/licensing/validator.js +171 -0
- package/src/lib/merge-package-json.js +90 -0
- package/src/lib/operator-ip.js +381 -0
- package/src/lib/package-manager.js +111 -0
- package/src/lib/perf.js +71 -0
- package/src/lib/project-guard.js +39 -0
- package/src/lib/project.js +334 -0
- package/src/lib/providers/base.js +276 -0
- package/src/lib/providers/hetzner-s3.js +656 -0
- package/src/lib/providers/hetzner.js +755 -0
- package/src/lib/providers/index.js +164 -0
- package/src/lib/s3.js +510 -0
- package/src/lib/secret-scan.js +583 -0
- package/src/lib/secrets.js +63 -0
- package/src/lib/server-types.js +195 -0
- package/src/lib/shell.js +91 -0
- package/src/lib/ssh.js +241 -0
- package/src/lib/tracker.js +242 -0
- package/src/lib/upgrade-policy.js +170 -0
- package/src/lib/validators.js +105 -0
- package/src/lib/version.js +5 -0
- package/src/remove.js +292 -0
- package/src/reset.js +97 -0
- package/src/restore.js +871 -0
- package/src/scale.js +1734 -0
- package/src/shell.js +222 -0
- package/src/status.js +981 -0
- package/src/up.js +264 -0
- package/src/upgrade.js +721 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* n8n ForwardAuth SSO Hook
|
|
3
|
+
*
|
|
4
|
+
* Reads X-User-Email set by Traefik ForwardAuth, looks up or auto-creates
|
|
5
|
+
* the n8n user, and issues a session cookie — bypassing n8n's login page.
|
|
6
|
+
*
|
|
7
|
+
* When ForwardAuth headers are absent (dev mode without Traefik, or direct
|
|
8
|
+
* container access), falls through to n8n's normal login flow.
|
|
9
|
+
*
|
|
10
|
+
* Loaded via EXTERNAL_HOOK_FILES environment variable.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const SKIP_PATHS = ['/healthz', '/webhook', '/assets', '/rest/oauth2-credential'];
|
|
14
|
+
|
|
15
|
+
function shouldSkip(url) {
|
|
16
|
+
return SKIP_PATHS.some((p) => url.startsWith(p));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = {
|
|
20
|
+
n8n: {
|
|
21
|
+
ready: [
|
|
22
|
+
async function (server) {
|
|
23
|
+
const userRepo = this.dbCollections?.User;
|
|
24
|
+
if (!userRepo) {
|
|
25
|
+
console.warn('[hooks.js] User repository not available — SSO hook disabled');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Get AuthService from DI container for issueCookie
|
|
30
|
+
let authService;
|
|
31
|
+
try {
|
|
32
|
+
const { Container } = require('@n8n/di');
|
|
33
|
+
const { AuthService } = require('/usr/local/lib/node_modules/n8n/dist/auth/auth.service');
|
|
34
|
+
authService = Container.get(AuthService);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
console.warn('[hooks.js] Could not resolve AuthService:', err.message);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const app = server.app;
|
|
40
|
+
if (!app) {
|
|
41
|
+
console.warn('[hooks.js] server.app not available');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Express 5 uses app.router.stack, Express 4 uses app._router.stack
|
|
46
|
+
const layers = app.router?.stack ?? app._router?.stack;
|
|
47
|
+
if (!layers) {
|
|
48
|
+
console.warn('[hooks.js] Could not access Express router stack — SSO hook disabled');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let cookieParserIdx = -1;
|
|
53
|
+
for (let i = 0; i < layers.length; i++) {
|
|
54
|
+
if (layers[i].name === 'cookieParser') {
|
|
55
|
+
cookieParserIdx = i;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const middleware = async (req, res, next) => {
|
|
61
|
+
try {
|
|
62
|
+
if (shouldSkip(req.url)) return next();
|
|
63
|
+
|
|
64
|
+
// Skip if session already exists
|
|
65
|
+
if (req.cookies?.['n8n-auth']) return next();
|
|
66
|
+
|
|
67
|
+
const email = req.headers['x-user-email'];
|
|
68
|
+
if (!email) return next(); // No ForwardAuth headers — normal login
|
|
69
|
+
|
|
70
|
+
let user = await userRepo.findOne({
|
|
71
|
+
where: { email },
|
|
72
|
+
relations: ['role'],
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
if (!user) {
|
|
76
|
+
// Auto-create user with owner role and random password
|
|
77
|
+
const crypto = require('node:crypto');
|
|
78
|
+
const { hashSync } = require('bcryptjs');
|
|
79
|
+
const randomPassword = crypto.randomBytes(32).toString('hex');
|
|
80
|
+
|
|
81
|
+
user = userRepo.create({
|
|
82
|
+
email,
|
|
83
|
+
firstName: email.split('@')[0],
|
|
84
|
+
lastName: '',
|
|
85
|
+
password: hashSync(randomPassword, 10),
|
|
86
|
+
roleSlug: 'global:owner',
|
|
87
|
+
});
|
|
88
|
+
user = await userRepo.save(user);
|
|
89
|
+
// Reload with role relation
|
|
90
|
+
user = await userRepo.findOne({
|
|
91
|
+
where: { email },
|
|
92
|
+
relations: ['role'],
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!user) return next();
|
|
97
|
+
|
|
98
|
+
// Issue session cookie via AuthService
|
|
99
|
+
if (authService) {
|
|
100
|
+
try {
|
|
101
|
+
authService.issueCookie(res, user, false, undefined);
|
|
102
|
+
} catch (cookieErr) {
|
|
103
|
+
console.error('[hooks.js] SSO: issueCookie failed:', cookieErr.message);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return next();
|
|
108
|
+
} catch (err) {
|
|
109
|
+
console.error('[hooks.js] ForwardAuth SSO error:', err.message);
|
|
110
|
+
return next();
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// Inject middleware after cookie-parser so req.cookies is available.
|
|
115
|
+
// Must create a proper Layer instance (Express 5 router calls layer.match()).
|
|
116
|
+
if (cookieParserIdx >= 0) {
|
|
117
|
+
try {
|
|
118
|
+
const Layer = require('router/lib/layer');
|
|
119
|
+
const layer = new Layer('/', { end: false }, middleware);
|
|
120
|
+
layers.splice(cookieParserIdx + 1, 0, layer);
|
|
121
|
+
console.log('[hooks.js] ForwardAuth SSO middleware installed');
|
|
122
|
+
} catch (err) {
|
|
123
|
+
console.warn('[hooks.js] Could not create router Layer:', err.message);
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
console.warn('[hooks.js] cookie-parser not found — SSO hook disabled');
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# n8n DB-Only Setup Script
|
|
3
|
+
# Updates the skeleton owner user that n8n creates during migration,
|
|
4
|
+
# setting email/name so n8n's setup wizard is skipped.
|
|
5
|
+
# In dev, uses a default password (changeme). In production, ForwardAuth + hooks.js
|
|
6
|
+
# handles SSO so the password is just a placeholder.
|
|
7
|
+
# Added via: vibecarbon add n8n
|
|
8
|
+
|
|
9
|
+
set -e
|
|
10
|
+
|
|
11
|
+
DB_HOST="${N8N_DB_HOST:-db}"
|
|
12
|
+
DB_NAME="${N8N_DB_NAME:-n8n}"
|
|
13
|
+
DB_USER="${N8N_DB_USER:-n8n}"
|
|
14
|
+
DB_PASSWORD="${N8N_DB_PASSWORD}"
|
|
15
|
+
ADMIN_EMAIL="${N8N_ADMIN_EMAIL:-admin@localhost}"
|
|
16
|
+
|
|
17
|
+
# Pre-computed bcrypt hash of "changeme" — used as default dev password.
|
|
18
|
+
# In production, ForwardAuth SSO bypasses the login page entirely.
|
|
19
|
+
DEFAULT_PW_HASH='$2a$10$K7L1OJ45/4Y2nIvhRVpCe.FSmhDdWoXehVzJtl/Q0T1FWYvv1nWi2'
|
|
20
|
+
|
|
21
|
+
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >&2; }
|
|
22
|
+
|
|
23
|
+
if [ -z "$DB_PASSWORD" ]; then
|
|
24
|
+
log "ERROR: N8N_DB_PASSWORD is required"
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Wait for n8n's user table to exist (created by n8n's own migrations)
|
|
29
|
+
log "Waiting for n8n user table..."
|
|
30
|
+
for i in $(seq 1 60); do
|
|
31
|
+
if PGPASSWORD="$DB_PASSWORD" psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" -tAc \
|
|
32
|
+
"SELECT 1 FROM information_schema.tables WHERE table_name='user'" 2>/dev/null | grep -q 1; then
|
|
33
|
+
break
|
|
34
|
+
fi
|
|
35
|
+
[ "$i" -eq 60 ] && { log "ERROR: user table not found after 5 minutes"; exit 1; }
|
|
36
|
+
sleep 5
|
|
37
|
+
done
|
|
38
|
+
|
|
39
|
+
# n8n v2.x creates a skeleton owner row (no email) during migration.
|
|
40
|
+
# Update it with the admin email so the setup wizard is skipped.
|
|
41
|
+
PGPASSWORD="$DB_PASSWORD" psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" -q <<SQL
|
|
42
|
+
-- Update the skeleton owner (n8n v2.x creates one with no email during migration).
|
|
43
|
+
-- Set email, name, bcrypt password, and lastActiveAt.
|
|
44
|
+
-- n8n's hasInstanceOwner() requires password IS NOT NULL or lastActiveAt IS NOT NULL.
|
|
45
|
+
UPDATE "user"
|
|
46
|
+
SET email = '${ADMIN_EMAIL}',
|
|
47
|
+
"firstName" = 'Admin',
|
|
48
|
+
"lastName" = 'User',
|
|
49
|
+
password = '${DEFAULT_PW_HASH}',
|
|
50
|
+
"lastActiveAt" = CURRENT_DATE
|
|
51
|
+
WHERE "roleSlug" = 'global:owner' AND (email IS NULL OR email = '')
|
|
52
|
+
AND NOT EXISTS (SELECT 1 FROM "user" WHERE email = '${ADMIN_EMAIL}');
|
|
53
|
+
|
|
54
|
+
-- If no skeleton owner existed (or email was already set), ensure one exists.
|
|
55
|
+
INSERT INTO "user" (email, "firstName", "lastName", password, "roleSlug", "lastActiveAt")
|
|
56
|
+
SELECT '${ADMIN_EMAIL}', 'Admin', 'User', '${DEFAULT_PW_HASH}', 'global:owner', CURRENT_DATE
|
|
57
|
+
WHERE NOT EXISTS (SELECT 1 FROM "user" WHERE email = '${ADMIN_EMAIL}')
|
|
58
|
+
ON CONFLICT (email) DO NOTHING;
|
|
59
|
+
|
|
60
|
+
-- Mark instance owner as set up so n8n skips the setup wizard.
|
|
61
|
+
-- n8n checks both this setting and hasInstanceOwner() on every request.
|
|
62
|
+
UPDATE settings SET value = 'true'
|
|
63
|
+
WHERE key = 'userManagement.isInstanceOwnerSetUp' AND value != 'true';
|
|
64
|
+
SQL
|
|
65
|
+
|
|
66
|
+
log "n8n owner setup complete (email: ${ADMIN_EMAIL})"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Prometheus Configuration for Vibecarbon
|
|
2
|
+
# Scrapes metrics from all stack components
|
|
3
|
+
|
|
4
|
+
global:
|
|
5
|
+
scrape_interval: 15s
|
|
6
|
+
evaluation_interval: 15s
|
|
7
|
+
|
|
8
|
+
scrape_configs:
|
|
9
|
+
# Prometheus self-monitoring
|
|
10
|
+
- job_name: 'prometheus'
|
|
11
|
+
static_configs:
|
|
12
|
+
- targets: ['localhost:9090']
|
|
13
|
+
|
|
14
|
+
# PostgreSQL database metrics via postgres-exporter
|
|
15
|
+
- job_name: 'postgres'
|
|
16
|
+
static_configs:
|
|
17
|
+
- targets: ['postgres-exporter:9187']
|
|
18
|
+
|
|
19
|
+
# Kong API Gateway metrics
|
|
20
|
+
# Note: Requires Kong prometheus plugin to be enabled
|
|
21
|
+
- job_name: 'kong'
|
|
22
|
+
static_configs:
|
|
23
|
+
- targets: ['kong:8001']
|
|
24
|
+
metrics_path: '/metrics'
|
|
25
|
+
scrape_interval: 30s
|
|
26
|
+
|
|
27
|
+
# n8n workflow automation (if enabled)
|
|
28
|
+
# n8n exposes metrics at /metrics when N8N_METRICS=true
|
|
29
|
+
- job_name: 'n8n'
|
|
30
|
+
static_configs:
|
|
31
|
+
- targets: ['n8n:5678']
|
|
32
|
+
metrics_path: '/metrics'
|
|
33
|
+
scrape_interval: 30s
|
|
34
|
+
# Fail silently if n8n is not running
|
|
35
|
+
honor_labels: true
|
|
36
|
+
|
|
37
|
+
# Application metrics (optional)
|
|
38
|
+
# Uncomment if your app exposes Prometheus metrics
|
|
39
|
+
# - job_name: 'app'
|
|
40
|
+
# static_configs:
|
|
41
|
+
# - targets: ['app:3000']
|
|
42
|
+
# metrics_path: '/api/metrics'
|
|
43
|
+
# scrape_interval: 30s
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Promtail Configuration for Vibecarbon
|
|
2
|
+
# Collects logs from all Docker containers
|
|
3
|
+
|
|
4
|
+
server:
|
|
5
|
+
http_listen_port: 9080
|
|
6
|
+
grpc_listen_port: 0
|
|
7
|
+
|
|
8
|
+
positions:
|
|
9
|
+
filename: /tmp/positions.yaml
|
|
10
|
+
|
|
11
|
+
clients:
|
|
12
|
+
- url: http://loki:3100/loki/api/v1/push
|
|
13
|
+
|
|
14
|
+
scrape_configs:
|
|
15
|
+
# Discover and scrape all Docker containers
|
|
16
|
+
- job_name: docker
|
|
17
|
+
docker_sd_configs:
|
|
18
|
+
- host: unix:///var/run/docker.sock
|
|
19
|
+
refresh_interval: 5s
|
|
20
|
+
relabel_configs:
|
|
21
|
+
# Extract container name (remove leading /)
|
|
22
|
+
- source_labels: ['__meta_docker_container_name']
|
|
23
|
+
regex: '/(.*)'
|
|
24
|
+
target_label: 'container'
|
|
25
|
+
|
|
26
|
+
# Extract compose service name
|
|
27
|
+
- source_labels: ['__meta_docker_container_label_com_docker_compose_service']
|
|
28
|
+
target_label: 'service'
|
|
29
|
+
|
|
30
|
+
# Extract compose project name
|
|
31
|
+
- source_labels: ['__meta_docker_container_label_com_docker_compose_project']
|
|
32
|
+
target_label: 'project'
|
|
33
|
+
|
|
34
|
+
# Extract container ID (short form)
|
|
35
|
+
- source_labels: ['__meta_docker_container_id']
|
|
36
|
+
regex: '(.{12}).*'
|
|
37
|
+
target_label: 'container_id'
|
|
38
|
+
|
|
39
|
+
# Add environment label if present
|
|
40
|
+
- source_labels: ['__meta_docker_container_label_environment']
|
|
41
|
+
target_label: 'environment'
|
|
42
|
+
|
|
43
|
+
pipeline_stages:
|
|
44
|
+
# Parse JSON logs if present
|
|
45
|
+
- json:
|
|
46
|
+
expressions:
|
|
47
|
+
level: level
|
|
48
|
+
msg: msg
|
|
49
|
+
message: message
|
|
50
|
+
timestamp: timestamp
|
|
51
|
+
time: time
|
|
52
|
+
|
|
53
|
+
# Extract log level for filtering
|
|
54
|
+
- labels:
|
|
55
|
+
level:
|
|
56
|
+
|
|
57
|
+
# Handle plain text logs
|
|
58
|
+
- match:
|
|
59
|
+
selector: '{service=~".+"}'
|
|
60
|
+
stages:
|
|
61
|
+
- regex:
|
|
62
|
+
expression: '(?P<level>INFO|WARN|ERROR|DEBUG|FATAL)'
|
|
63
|
+
- labels:
|
|
64
|
+
level:
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Traefik Dynamic Configuration (Development)
|
|
2
|
+
# Middlewares for admin routes with ForwardAuth authentication
|
|
3
|
+
# Uses host.docker.internal to reach the app running on the host via pnpm dev
|
|
4
|
+
|
|
5
|
+
http:
|
|
6
|
+
middlewares:
|
|
7
|
+
# Strip X-User-* headers from client requests before ForwardAuth sets real values.
|
|
8
|
+
# Prevents spoofing if a request bypasses Traefik or hits the service directly.
|
|
9
|
+
strip-proxy-headers:
|
|
10
|
+
headers:
|
|
11
|
+
customRequestHeaders:
|
|
12
|
+
X-User-Id: ""
|
|
13
|
+
X-User-Email: ""
|
|
14
|
+
X-User-Role: ""
|
|
15
|
+
|
|
16
|
+
# ForwardAuth - verifies user is authenticated with admin role
|
|
17
|
+
admin-forward-auth:
|
|
18
|
+
forwardAuth:
|
|
19
|
+
address: "http://host.docker.internal:3000/api/_internal/verify-role?role=admin"
|
|
20
|
+
authRequestHeaders:
|
|
21
|
+
- "Cookie"
|
|
22
|
+
- "Authorization"
|
|
23
|
+
- "Accept"
|
|
24
|
+
authResponseHeaders:
|
|
25
|
+
- "X-User-Id"
|
|
26
|
+
- "X-User-Email"
|
|
27
|
+
- "X-User-Role"
|
|
28
|
+
trustForwardHeader: true
|
|
29
|
+
|
|
30
|
+
# Chain: strip spoofed headers → verify admin role
|
|
31
|
+
admin-auth:
|
|
32
|
+
chain:
|
|
33
|
+
middlewares:
|
|
34
|
+
- strip-proxy-headers
|
|
35
|
+
- admin-forward-auth
|
|
36
|
+
|
|
37
|
+
# ForwardAuth - verifies user is authenticated with super_admin role
|
|
38
|
+
# Used for sensitive admin tools: n8n, Metabase
|
|
39
|
+
super-admin-forward-auth:
|
|
40
|
+
forwardAuth:
|
|
41
|
+
address: "http://host.docker.internal:3000/api/_internal/verify-role?role=super_admin"
|
|
42
|
+
authRequestHeaders:
|
|
43
|
+
- "Cookie"
|
|
44
|
+
- "Authorization"
|
|
45
|
+
- "Accept"
|
|
46
|
+
authResponseHeaders:
|
|
47
|
+
- "X-User-Id"
|
|
48
|
+
- "X-User-Email"
|
|
49
|
+
- "X-User-Role"
|
|
50
|
+
trustForwardHeader: true
|
|
51
|
+
|
|
52
|
+
# Chain: strip spoofed headers → verify super_admin role
|
|
53
|
+
super-admin-auth:
|
|
54
|
+
chain:
|
|
55
|
+
middlewares:
|
|
56
|
+
- strip-proxy-headers
|
|
57
|
+
- super-admin-forward-auth
|
|
58
|
+
|
|
59
|
+
# Strip prefix middlewares for path-based admin routing
|
|
60
|
+
strip-admin-studio:
|
|
61
|
+
stripPrefix:
|
|
62
|
+
prefixes:
|
|
63
|
+
- "/admin/studio"
|
|
64
|
+
|
|
65
|
+
strip-admin-traefik:
|
|
66
|
+
stripPrefix:
|
|
67
|
+
prefixes:
|
|
68
|
+
- "/admin/traefik"
|
|
69
|
+
|
|
70
|
+
strip-admin-grafana:
|
|
71
|
+
stripPrefix:
|
|
72
|
+
prefixes:
|
|
73
|
+
- "/admin/grafana"
|
|
74
|
+
|
|
75
|
+
strip-admin-n8n:
|
|
76
|
+
stripPrefix:
|
|
77
|
+
prefixes:
|
|
78
|
+
- "/admin/n8n"
|
|
79
|
+
|
|
80
|
+
strip-admin-metabase:
|
|
81
|
+
stripPrefix:
|
|
82
|
+
prefixes:
|
|
83
|
+
- "/admin/metabase"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Traefik Dynamic Configuration
|
|
2
|
+
# Middlewares for admin routes with ForwardAuth authentication
|
|
3
|
+
|
|
4
|
+
http:
|
|
5
|
+
middlewares:
|
|
6
|
+
# Strip X-User-* headers from client requests before ForwardAuth sets real values.
|
|
7
|
+
# Prevents spoofing if a request bypasses Traefik or hits the service directly.
|
|
8
|
+
strip-proxy-headers:
|
|
9
|
+
headers:
|
|
10
|
+
customRequestHeaders:
|
|
11
|
+
X-User-Id: ""
|
|
12
|
+
X-User-Email: ""
|
|
13
|
+
X-User-Role: ""
|
|
14
|
+
|
|
15
|
+
# ForwardAuth - verifies user is authenticated with admin role
|
|
16
|
+
admin-forward-auth:
|
|
17
|
+
forwardAuth:
|
|
18
|
+
address: "http://app:3000/api/_internal/verify-role?role=admin"
|
|
19
|
+
authRequestHeaders:
|
|
20
|
+
- "Cookie"
|
|
21
|
+
- "Authorization"
|
|
22
|
+
- "Accept"
|
|
23
|
+
authResponseHeaders:
|
|
24
|
+
- "X-User-Id"
|
|
25
|
+
- "X-User-Email"
|
|
26
|
+
- "X-User-Role"
|
|
27
|
+
trustForwardHeader: true
|
|
28
|
+
|
|
29
|
+
# Chain: strip spoofed headers → verify admin role
|
|
30
|
+
admin-auth:
|
|
31
|
+
chain:
|
|
32
|
+
middlewares:
|
|
33
|
+
- strip-proxy-headers
|
|
34
|
+
- admin-forward-auth
|
|
35
|
+
|
|
36
|
+
# ForwardAuth - verifies user is authenticated with super_admin role
|
|
37
|
+
# Used for sensitive admin tools: n8n, Metabase
|
|
38
|
+
super-admin-forward-auth:
|
|
39
|
+
forwardAuth:
|
|
40
|
+
address: "http://app:3000/api/_internal/verify-role?role=super_admin"
|
|
41
|
+
authRequestHeaders:
|
|
42
|
+
- "Cookie"
|
|
43
|
+
- "Authorization"
|
|
44
|
+
- "Accept"
|
|
45
|
+
authResponseHeaders:
|
|
46
|
+
- "X-User-Id"
|
|
47
|
+
- "X-User-Email"
|
|
48
|
+
- "X-User-Role"
|
|
49
|
+
trustForwardHeader: true
|
|
50
|
+
|
|
51
|
+
# Chain: strip spoofed headers → verify super_admin role
|
|
52
|
+
super-admin-auth:
|
|
53
|
+
chain:
|
|
54
|
+
middlewares:
|
|
55
|
+
- strip-proxy-headers
|
|
56
|
+
- super-admin-forward-auth
|
|
57
|
+
|
|
58
|
+
# Strip prefix middlewares for path-based admin routing
|
|
59
|
+
strip-admin-studio:
|
|
60
|
+
stripPrefix:
|
|
61
|
+
prefixes:
|
|
62
|
+
- "/admin/studio"
|
|
63
|
+
|
|
64
|
+
strip-admin-traefik:
|
|
65
|
+
stripPrefix:
|
|
66
|
+
prefixes:
|
|
67
|
+
- "/admin/traefik"
|
|
68
|
+
|
|
69
|
+
strip-admin-grafana:
|
|
70
|
+
stripPrefix:
|
|
71
|
+
prefixes:
|
|
72
|
+
- "/admin/grafana"
|
|
73
|
+
|
|
74
|
+
strip-admin-n8n:
|
|
75
|
+
stripPrefix:
|
|
76
|
+
prefixes:
|
|
77
|
+
- "/admin/n8n"
|
|
78
|
+
|
|
79
|
+
strip-admin-metabase:
|
|
80
|
+
stripPrefix:
|
|
81
|
+
prefixes:
|
|
82
|
+
- "/admin/metabase"
|
|
83
|
+
|
|
84
|
+
# Security headers — applied to admin services (Grafana, n8n, etc.)
|
|
85
|
+
security-headers:
|
|
86
|
+
headers:
|
|
87
|
+
browserXssFilter: true
|
|
88
|
+
contentTypeNosniff: true
|
|
89
|
+
frameDeny: true
|
|
90
|
+
stsIncludeSubdomains: true
|
|
91
|
+
stsPreload: true
|
|
92
|
+
stsSeconds: 31536000
|
|
93
|
+
customFrameOptionsValue: "SAMEORIGIN"
|
|
94
|
+
customResponseHeaders:
|
|
95
|
+
X-Robots-Tag: "noindex,nofollow,nosnippet,noarchive,notranslate,noimageindex"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Traefik Dynamic Configuration for Vite Dev Server
|
|
2
|
+
# Routes app.localhost to the Vite dev server running on the host
|
|
3
|
+
#
|
|
4
|
+
# This enables ForwardAuth to work in development by ensuring all services
|
|
5
|
+
# (app, n8n, metabase, etc.) are accessed via *.localhost subdomains,
|
|
6
|
+
# allowing auth cookies to be shared across all services.
|
|
7
|
+
|
|
8
|
+
http:
|
|
9
|
+
routers:
|
|
10
|
+
vite-dev:
|
|
11
|
+
rule: "Host(`app.localhost`)"
|
|
12
|
+
entrypoints:
|
|
13
|
+
- web
|
|
14
|
+
service: vite-dev
|
|
15
|
+
|
|
16
|
+
services:
|
|
17
|
+
vite-dev:
|
|
18
|
+
loadBalancer:
|
|
19
|
+
servers:
|
|
20
|
+
- url: "http://host.docker.internal:5173"
|
package/package.json
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vibecarbon",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Create and manage production-ready Vibecarbon applications",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": "./src/cli.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"src",
|
|
9
|
+
"carbon"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"lint": "node scripts/check-shell-safety.js && node scripts/check-stale-deploy-references.js && biome check src/ tests/",
|
|
13
|
+
"lint:shell": "node scripts/check-shell-safety.js",
|
|
14
|
+
"lint:stale-deploy": "node scripts/check-stale-deploy-references.js",
|
|
15
|
+
"lint:fix": "biome check --write src/ tests/",
|
|
16
|
+
"format": "biome format --write src/ tests/",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest",
|
|
19
|
+
"test:unit": "vitest run --project unit",
|
|
20
|
+
"test:integration": "vitest run --project integration",
|
|
21
|
+
"test:cli": "vitest run --project integration tests/integration/cli",
|
|
22
|
+
"test:docker": "DOCKER_INTEGRATION=true vitest run --project integration tests/integration/docker",
|
|
23
|
+
"test:template": "vitest run --project integration tests/integration/template",
|
|
24
|
+
"test:modules": "vitest run --project integration tests/integration/modules",
|
|
25
|
+
"test:coverage": "vitest run --coverage",
|
|
26
|
+
"test:loadtest": "tsx tests/loadtest/cli.ts",
|
|
27
|
+
"test:ci": "vitest run --reporter=junit --outputFile=test-results.xml",
|
|
28
|
+
"test:e2e": "REAL_INFRA=true tsx tests/e2e/runner.ts",
|
|
29
|
+
"test:e2e:batch": "REAL_INFRA=true tsx tests/e2e/runner.ts --batch",
|
|
30
|
+
"test:e2e:expanded": "REAL_INFRA=true tsx tests/e2e/runner.ts --batch --expanded",
|
|
31
|
+
"test:e2e:single": "REAL_INFRA=true vitest run --project e2e tests/e2e/single",
|
|
32
|
+
"test:e2e:ci": "REAL_INFRA=true vitest run --project e2e",
|
|
33
|
+
"test:e2e:report": "tsx tests/e2e/metrics/reporter.ts",
|
|
34
|
+
"bump:patch": "node scripts/bump.js patch",
|
|
35
|
+
"bump:minor": "node scripts/bump.js minor",
|
|
36
|
+
"bump:major": "node scripts/bump.js major",
|
|
37
|
+
"prepare": "git config core.hooksPath git-hooks",
|
|
38
|
+
"test:prepush": "pnpm lint && pnpm test:unit && pnpm test:integration",
|
|
39
|
+
"prepublishOnly": "pnpm test:unit && pnpm lint"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"vibecarbon",
|
|
43
|
+
"react",
|
|
44
|
+
"hono",
|
|
45
|
+
"vite",
|
|
46
|
+
"supabase",
|
|
47
|
+
"saas",
|
|
48
|
+
"starter",
|
|
49
|
+
"boilerplate"
|
|
50
|
+
],
|
|
51
|
+
"author": "",
|
|
52
|
+
"license": "AGPL-3.0-only",
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "https://github.com/hyperformant/vibecarbon.git"
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@aws-sdk/client-s3": "^3.1017.0",
|
|
59
|
+
"@clack/prompts": "^1.1.0",
|
|
60
|
+
"@pulumi/hcloud": "^1.32.2",
|
|
61
|
+
"@pulumi/pulumi": "^3.231.0",
|
|
62
|
+
"bcryptjs": "^3.0.3",
|
|
63
|
+
"undici": "^8.1.0",
|
|
64
|
+
"which": "^6.0.1"
|
|
65
|
+
},
|
|
66
|
+
"pnpm": {
|
|
67
|
+
"onlyBuiltDependencies": [
|
|
68
|
+
"better-sqlite3"
|
|
69
|
+
],
|
|
70
|
+
"overrides": {
|
|
71
|
+
"postcss@<8.5.10": ">=8.5.10",
|
|
72
|
+
"uuid@<14.0.0": ">=14.0.0",
|
|
73
|
+
"fast-xml-parser@<5.7.0": ">=5.7.0",
|
|
74
|
+
"fast-xml-builder@<1.1.7": ">=1.1.7",
|
|
75
|
+
"ip-address@<10.1.1": ">=10.1.1",
|
|
76
|
+
"protobufjs@<7.5.6": "^7.5.6",
|
|
77
|
+
"@protobufjs/utf8@<1.1.1": "^1.1.1"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@biomejs/biome": "^2.4.9",
|
|
82
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
83
|
+
"@semantic-release/git": "^10.0.1",
|
|
84
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
85
|
+
"@vitest/coverage-v8": "^4.1.1",
|
|
86
|
+
"autocannon": "^8.0.0",
|
|
87
|
+
"better-sqlite3": "^12.8.0",
|
|
88
|
+
"msw": "^2.12.14",
|
|
89
|
+
"semantic-release": "^23.0.8",
|
|
90
|
+
"tsx": "^4.21.0",
|
|
91
|
+
"vite": "^7.3.2",
|
|
92
|
+
"vitest": "^4.1.1",
|
|
93
|
+
"zod": "^4.3.6"
|
|
94
|
+
}
|
|
95
|
+
}
|