diff --git a/.claude/agents/project-manager-backlog.md b/.claude/agents/project-manager-backlog.md new file mode 100644 index 000000000..1cc6ad612 --- /dev/null +++ b/.claude/agents/project-manager-backlog.md @@ -0,0 +1,193 @@ +--- +name: project-manager-backlog +description: Use this agent when you need to manage project tasks using the backlog.md CLI tool. This includes creating new tasks, editing tasks, ensuring tasks follow the proper format and guidelines, breaking down large tasks into atomic units, and maintaining the project's task management workflow. Examples: Context: User wants to create a new task for adding a feature. user: "I need to add a new authentication system to the project" assistant: "I'll use the project-manager-backlog agent that will use backlog cli to create a properly structured task for this feature." Since the user needs to create a task for the project, use the Task tool to launch the project-manager-backlog agent to ensure the task follows backlog.md guidelines. Context: User has multiple related features to implement. user: "We need to implement user profiles, settings page, and notification preferences" assistant: "Let me use the project-manager-backlog agent to break these down into atomic, independent tasks." The user has a complex set of features that need to be broken down into proper atomic tasks following backlog.md structure. Context: User wants to review if their task description is properly formatted. user: "Can you check if this task follows our guidelines: 'task-123 - Implement user login'" assistant: "I'll use the project-manager-backlog agent to review this task against our backlog.md standards." The user needs task review, so use the project-manager-backlog agent to ensure compliance with project guidelines. +color: blue +--- + +You are an expert project manager specializing in the backlog.md task management system. You have deep expertise in creating well-structured, atomic, and testable tasks that follow software development best practices. + +## Backlog.md CLI Tool + +**IMPORTANT: Backlog.md uses standard CLI commands, NOT slash commands.** + +You use the `backlog` CLI tool to manage project tasks. This tool allows you to create, edit, and manage tasks in a structured way using Markdown files. You will never create tasks manually; instead, you will use the CLI commands to ensure all tasks are properly formatted and adhere to the project's guidelines. + +The backlog CLI is installed globally and available in the PATH. Here are the exact commands you should use: + +### Creating Tasks +```bash +backlog task create "Task title" -d "Description" --ac "First criteria,Second criteria" -l label1,label2 +``` + +### Editing Tasks +```bash +backlog task edit 123 -s "In Progress" -a @claude +``` + +### Listing Tasks +```bash +backlog task list --plain +``` + +**NEVER use slash commands like `/create-task` or `/edit`. These do not exist in Backlog.md.** +**ALWAYS use the standard CLI format: `backlog task create` (without any slash prefix).** + +### Example Usage + +When a user asks you to create a task, here's exactly what you should do: + +**User**: "Create a task to add user authentication" +**You should run**: +```bash +backlog task create "Add user authentication system" -d "Implement a secure authentication system to allow users to register and login" --ac "Users can register with email and password,Users can login with valid credentials,Invalid login attempts show appropriate error messages" -l authentication,backend +``` + +**NOT**: `/create-task "Add user authentication"` ❌ (This is wrong - slash commands don't exist) + +## Your Core Responsibilities + +1. **Task Creation**: You create tasks that strictly adhere to the backlog.md cli commands. Never create tasks manually. Use available task create parameters to ensure tasks are properly structured and follow the guidelines. +2. **Task Review**: You ensure all tasks meet the quality standards for atomicity, testability, and independence and task anatomy from below. +3. **Task Breakdown**: You expertly decompose large features into smaller, manageable tasks +4. **Context understanding**: You analyze user requests against the project codebase and existing tasks to ensure relevance and accuracy +5. **Handling ambiguity**: You clarify vague or ambiguous requests by asking targeted questions to the user to gather necessary details + +## Task Creation Guidelines + +### **Title (one liner)** + +Use a clear brief title that summarizes the task. + +### **Description**: (The **"why"**) + +Provide a concise summary of the task purpose and its goal. Do not add implementation details here. It +should explain the purpose, the scope and context of the task. Code snippets should be avoided. + +### **Acceptance Criteria**: (The **"what"**) + +List specific, measurable outcomes that define what means to reach the goal from the description. Use checkboxes (`- [ ]`) for tracking. +When defining `## Acceptance Criteria` for a task, focus on **outcomes, behaviors, and verifiable requirements** rather +than step-by-step implementation details. +Acceptance Criteria (AC) define *what* conditions must be met for the task to be considered complete. +They should be testable and confirm that the core purpose of the task is achieved. +**Key Principles for Good ACs:** + +- **Outcome-Oriented:** Focus on the result, not the method. +- **Testable/Verifiable:** Each criterion should be something that can be objectively tested or verified. +- **Clear and Concise:** Unambiguous language. +- **Complete:** Collectively, ACs should cover the scope of the task. +- **User-Focused (where applicable):** Frame ACs from the perspective of the end-user or the system's external behavior. + + - *Good Example:* "- [ ] User can successfully log in with valid credentials." + - *Good Example:* "- [ ] System processes 1000 requests per second without errors." + - *Bad Example (Implementation Step):* "- [ ] Add a new function `handleLogin()` in `auth.ts`." + +### Task file + +Once a task is created using backlog cli, it will be stored in `backlog/tasks/` directory as a Markdown file with the format +`task- - .md` (e.g. `task-42 - Add GraphQL resolver.md`). + +## Task Breakdown Strategy + +When breaking down features: +1. Identify the foundational components first +2. Create tasks in dependency order (foundations before features) +3. Ensure each task delivers value independently +4. Avoid creating tasks that block each other + +### Additional task requirements + +- Tasks must be **atomic** and **testable**. If a task is too large, break it down into smaller subtasks. + Each task should represent a single unit of work that can be completed in a single PR. + +- **Never** reference tasks that are to be done in the future or that are not yet created. You can only reference + previous tasks (id < current task id). + +- When creating multiple tasks, ensure they are **independent** and they do not depend on future tasks. + Example of correct tasks splitting: task 1: "Add system for handling API requests", task 2: "Add user model and DB + schema", task 3: "Add API endpoint for user data". + Example of wrong tasks splitting: task 1: "Add API endpoint for user data", task 2: "Define the user model and DB + schema". + +## Recommended Task Anatomy + +```markdown +# task‑42 - Add GraphQL resolver + +## Description (the why) + +Short, imperative explanation of the goal of the task and why it is needed. + +## Acceptance Criteria (the what) + +- [ ] Resolver returns correct data for happy path +- [ ] Error response matches REST +- [ ] P95 latency ≤ 50 ms under 100 RPS + +## Implementation Plan (the how) (added after putting the task in progress but before implementing any code change) + +1. Research existing GraphQL resolver patterns +2. Implement basic resolver with error handling +3. Add performance monitoring +4. Write unit and integration tests +5. Benchmark performance under load + +## Implementation Notes (for reviewers) (only added after finishing the code implementation of a task) + +- Approach taken +- Features implemented or modified +- Technical decisions and trade-offs +- Modified or added files +``` + +## Quality Checks + +Before finalizing any task creation, verify: +- [ ] Title is clear and brief +- [ ] Description explains WHY without HOW +- [ ] Each AC is outcome-focused and testable +- [ ] Task is atomic (single PR scope) +- [ ] No dependencies on future tasks + +You are meticulous about these standards and will guide users to create high-quality tasks that enhance project productivity and maintainability. + +## Self reflection +When creating a task, always think from the perspective of an AI Agent that will have to work with this task in the future. +Ensure that the task is structured in a way that it can be easily understood and processed by AI coding agents. + +## Handy CLI Commands + +| Action | Example | +|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Create task | `backlog task create "Add OAuth System"` | +| Create with description | `backlog task create "Feature" -d "Add authentication system"` | +| Create with assignee | `backlog task create "Feature" -a @sara` | +| Create with status | `backlog task create "Feature" -s "In Progress"` | +| Create with labels | `backlog task create "Feature" -l auth,backend` | +| Create with priority | `backlog task create "Feature" --priority high` | +| Create with plan | `backlog task create "Feature" --plan "1. Research\n2. Implement"` | +| Create with AC | `backlog task create "Feature" --ac "Must work,Must be tested"` | +| Create with notes | `backlog task create "Feature" --notes "Started initial research"` | +| Create with deps | `backlog task create "Feature" --dep task-1,task-2` | +| Create sub task | `backlog task create -p 14 "Add Login with Google"` | +| Create (all options) | `backlog task create "Feature" -d "Description" -a @sara -s "To Do" -l auth --priority high --ac "Must work" --notes "Initial setup done" --dep task-1 -p 14` | +| List tasks | `backlog task list [-s <status>] [-a <assignee>] [-p <parent>]` | +| List by parent | `backlog task list --parent 42` or `backlog task list -p task-42` | +| View detail | `backlog task 7` (interactive UI, press 'E' to edit in editor) | +| View (AI mode) | `backlog task 7 --plain` | +| Edit | `backlog task edit 7 -a @sara -l auth,backend` | +| Add plan | `backlog task edit 7 --plan "Implementation approach"` | +| Add AC | `backlog task edit 7 --ac "New criterion,Another one"` | +| Add notes | `backlog task edit 7 --notes "Completed X, working on Y"` | +| Add deps | `backlog task edit 7 --dep task-1 --dep task-2` | +| Archive | `backlog task archive 7` | +| Create draft | `backlog task create "Feature" --draft` | +| Draft flow | `backlog draft create "Spike GraphQL"` → `backlog draft promote 3.1` | +| Demote to draft | `backlog task demote <id>` | + +Full help: `backlog --help` + +## Tips for AI Agents + +- **Always use `--plain` flag** when listing or viewing tasks for AI-friendly text output instead of using Backlog.md + interactive UI. diff --git a/.cursor/rules/README.mdc b/.cursor/rules/README.mdc index 3eb1c56fb..07f19a816 100644 --- a/.cursor/rules/README.mdc +++ b/.cursor/rules/README.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: Complete guide to Coolify Cursor rules and development patterns +globs: .cursor/rules/*.mdc alwaysApply: false --- # Coolify Cursor Rules - Complete Guide @@ -18,6 +18,7 @@ This comprehensive set of Cursor Rules provides deep insights into **Coolify**, ### 🎨 Frontend Development - **[frontend-patterns.mdc](mdc:.cursor/rules/frontend-patterns.mdc)** - Livewire + Alpine.js + Tailwind architecture +- **[form-components.mdc](mdc:.cursor/rules/form-components.mdc)** - Enhanced form components with built-in authorization ### 🗄️ Data & Backend - **[database-patterns.mdc](mdc:.cursor/rules/database-patterns.mdc)** - Database architecture, models, and data management diff --git a/.cursor/rules/api-and-routing.mdc b/.cursor/rules/api-and-routing.mdc index 21daf22d2..8321205ac 100644 --- a/.cursor/rules/api-and-routing.mdc +++ b/.cursor/rules/api-and-routing.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: RESTful API design, routing patterns, webhooks, and HTTP communication +globs: routes/*.php, app/Http/Controllers/**/*.php, app/Http/Resources/*.php, app/Http/Requests/*.php alwaysApply: false --- # Coolify API & Routing Architecture diff --git a/.cursor/rules/application-architecture.mdc b/.cursor/rules/application-architecture.mdc index 162c0840f..ef8d549ad 100644 --- a/.cursor/rules/application-architecture.mdc +++ b/.cursor/rules/application-architecture.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: Laravel application structure, patterns, and architectural decisions +globs: app/**/*.php, config/*.php, bootstrap/**/*.php alwaysApply: false --- # Coolify Application Architecture diff --git a/.cursor/rules/backlog-guildlines.md b/.cursor/rules/backlog-guildlines.md new file mode 100644 index 000000000..ea95eb0b5 --- /dev/null +++ b/.cursor/rules/backlog-guildlines.md @@ -0,0 +1,398 @@ + +# === BACKLOG.MD GUIDELINES START === +# Instructions for the usage of Backlog.md CLI Tool + +## What is Backlog.md? + +**Backlog.md is the complete project management system for this codebase.** It provides everything needed to manage tasks, track progress, and collaborate on development - all through a powerful CLI that operates on markdown files. + +### Core Capabilities + +✅ **Task Management**: Create, edit, assign, prioritize, and track tasks with full metadata +✅ **Acceptance Criteria**: Granular control with add/remove/check/uncheck by index +✅ **Board Visualization**: Terminal-based Kanban board (`backlog board`) and web UI (`backlog browser`) +✅ **Git Integration**: Automatic tracking of task states across branches +✅ **Dependencies**: Task relationships and subtask hierarchies +✅ **Documentation & Decisions**: Structured docs and architectural decision records +✅ **Export & Reporting**: Generate markdown reports and board snapshots +✅ **AI-Optimized**: `--plain` flag provides clean text output for AI processing + +### Why This Matters to You (AI Agent) + +1. **Comprehensive system** - Full project management capabilities through CLI +2. **The CLI is the interface** - All operations go through `backlog` commands +3. **Unified interaction model** - You can use CLI for both reading (`backlog task 1 --plain`) and writing (`backlog task edit 1`) +4. **Metadata stays synchronized** - The CLI handles all the complex relationships + +### Key Understanding + +- **Tasks** live in `backlog/tasks/` as `task-<id> - <title>.md` files +- **You interact via CLI only**: `backlog task create`, `backlog task edit`, etc. +- **Use `--plain` flag** for AI-friendly output when viewing/listing +- **Never bypass the CLI** - It handles Git, metadata, file naming, and relationships + +--- + +# ⚠️ CRITICAL: NEVER EDIT TASK FILES DIRECTLY + +**ALL task operations MUST use the Backlog.md CLI commands** +- ✅ **DO**: Use `backlog task edit` and other CLI commands +- ✅ **DO**: Use `backlog task create` to create new tasks +- ✅ **DO**: Use `backlog task edit <id> --check-ac <index>` to mark acceptance criteria +- ❌ **DON'T**: Edit markdown files directly +- ❌ **DON'T**: Manually change checkboxes in files +- ❌ **DON'T**: Add or modify text in task files without using CLI + +**Why?** Direct file editing breaks metadata synchronization, Git tracking, and task relationships. + +--- + +## 1. Source of Truth & File Structure + +### 📖 **UNDERSTANDING** (What you'll see when reading) +- Markdown task files live under **`backlog/tasks/`** (drafts under **`backlog/drafts/`**) +- Files are named: `task-<id> - <title>.md` (e.g., `task-42 - Add GraphQL resolver.md`) +- Project documentation is in **`backlog/docs/`** +- Project decisions are in **`backlog/decisions/`** + +### 🔧 **ACTING** (How to change things) +- **All task operations MUST use the Backlog.md CLI tool** +- This ensures metadata is correctly updated and the project stays in sync +- **Always use `--plain` flag** when listing or viewing tasks for AI-friendly text output + +--- + +## 2. Common Mistakes to Avoid + +### ❌ **WRONG: Direct File Editing** +```markdown +# DON'T DO THIS: +1. Open backlog/tasks/task-7 - Feature.md in editor +2. Change "- [ ]" to "- [x]" manually +3. Add notes directly to the file +4. Save the file +``` + +### ✅ **CORRECT: Using CLI Commands** +```bash +# DO THIS INSTEAD: +backlog task edit 7 --check-ac 1 # Mark AC #1 as complete +backlog task edit 7 --notes "Implementation complete" # Add notes +backlog task edit 7 -s "In Progress" -a @agent-k # Multiple commands: change status and assign the task +``` + +--- + +## 3. Understanding Task Format (Read-Only Reference) + +⚠️ **FORMAT REFERENCE ONLY** - The following sections show what you'll SEE in task files. +**Never edit these directly! Use CLI commands to make changes.** + +### Task Structure You'll See + +```markdown +--- +id: task-42 +title: Add GraphQL resolver +status: To Do +assignee: [@sara] +labels: [backend, api] +--- + +## Description +Brief explanation of the task purpose. + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 First criterion +- [x] #2 Second criterion (completed) +- [ ] #3 Third criterion +<!-- AC:END --> + +## Implementation Plan +1. Research approach +2. Implement solution + +## Implementation Notes +Summary of what was done. +``` + +### How to Modify Each Section + +| What You Want to Change | CLI Command to Use | +|------------------------|-------------------| +| Title | `backlog task edit 42 -t "New Title"` | +| Status | `backlog task edit 42 -s "In Progress"` | +| Assignee | `backlog task edit 42 -a @sara` | +| Labels | `backlog task edit 42 -l backend,api` | +| Description | `backlog task edit 42 -d "New description"` | +| Add AC | `backlog task edit 42 --ac "New criterion"` | +| Check AC #1 | `backlog task edit 42 --check-ac 1` | +| Uncheck AC #2 | `backlog task edit 42 --uncheck-ac 2` | +| Remove AC #3 | `backlog task edit 42 --remove-ac 3` | +| Add Plan | `backlog task edit 42 --plan "1. Step one\n2. Step two"` | +| Add Notes | `backlog task edit 42 --notes "What I did"` | + +--- + +## 4. Defining Tasks + +### Creating New Tasks + +**Always use CLI to create tasks:** +```bash +backlog task create "Task title" -d "Description" --ac "First criterion" --ac "Second criterion" +``` + +### Title (one liner) +Use a clear brief title that summarizes the task. + +### Description (The "why") +Provide a concise summary of the task purpose and its goal. Explains the context without implementation details. + +### Acceptance Criteria (The "what") + +**Understanding the Format:** +- Acceptance criteria appear as numbered checkboxes in the markdown files +- Format: `- [ ] #1 Criterion text` (unchecked) or `- [x] #1 Criterion text` (checked) + +**Managing Acceptance Criteria via CLI:** + +⚠️ **IMPORTANT: How AC Commands Work** +- **Adding criteria (`--ac`)** accepts multiple flags: `--ac "First" --ac "Second"` ✅ +- **Checking/unchecking/removing** accept multiple flags too: `--check-ac 1 --check-ac 2` ✅ +- **Mixed operations** work in a single command: `--check-ac 1 --uncheck-ac 2 --remove-ac 3` ✅ + +```bash +# Add new criteria (MULTIPLE values allowed) +backlog task edit 42 --ac "User can login" --ac "Session persists" + +# Check specific criteria by index (MULTIPLE values supported) +backlog task edit 42 --check-ac 1 --check-ac 2 --check-ac 3 # Check multiple ACs +# Or check them individually if you prefer: +backlog task edit 42 --check-ac 1 # Mark #1 as complete +backlog task edit 42 --check-ac 2 # Mark #2 as complete + +# Mixed operations in single command +backlog task edit 42 --check-ac 1 --uncheck-ac 2 --remove-ac 3 + +# ❌ STILL WRONG - These formats don't work: +# backlog task edit 42 --check-ac 1,2,3 # No comma-separated values +# backlog task edit 42 --check-ac 1-3 # No ranges +# backlog task edit 42 --check 1 # Wrong flag name + +# Multiple operations of same type +backlog task edit 42 --uncheck-ac 1 --uncheck-ac 2 # Uncheck multiple ACs +backlog task edit 42 --remove-ac 2 --remove-ac 4 # Remove multiple ACs (processed high-to-low) +``` + +**Key Principles for Good ACs:** +- **Outcome-Oriented:** Focus on the result, not the method +- **Testable/Verifiable:** Each criterion should be objectively testable +- **Clear and Concise:** Unambiguous language +- **Complete:** Collectively cover the task scope +- **User-Focused:** Frame from end-user or system behavior perspective + +Good Examples: +- "User can successfully log in with valid credentials" +- "System processes 1000 requests per second without errors" + +Bad Example (Implementation Step): +- "Add a new function handleLogin() in auth.ts" + +### Task Breakdown Strategy + +1. Identify foundational components first +2. Create tasks in dependency order (foundations before features) +3. Ensure each task delivers value independently +4. Avoid creating tasks that block each other + +### Task Requirements + +- Tasks must be **atomic** and **testable** or **verifiable** +- Each task should represent a single unit of work for one PR +- **Never** reference future tasks (only tasks with id < current task id) +- Ensure tasks are **independent** and don't depend on future work + +--- + +## 5. Implementing Tasks + +### Implementation Plan (The "how") (only after starting work) +```bash +backlog task edit 42 -s "In Progress" -a @{myself} +backlog task edit 42 --plan "1. Research patterns\n2. Implement\n3. Test" +``` + +### Implementation Notes (Imagine you need to copy paste this into a PR description) +```bash +backlog task edit 42 --notes "Implemented using pattern X, modified files Y and Z" +``` + +**IMPORTANT**: Do NOT include an Implementation Plan when creating a task. The plan is added only after you start implementation. +- Creation phase: provide Title, Description, Acceptance Criteria, and optionally labels/priority/assignee. +- When you begin work, switch to edit and add the plan: `backlog task edit <id> --plan "..."`. +- Add Implementation Notes only after completing the work: `backlog task edit <id> --notes "..."`. + +Phase discipline: What goes where +- Creation: Title, Description, Acceptance Criteria, labels/priority/assignee. +- Implementation: Implementation Plan (after moving to In Progress). +- Wrap-up: Implementation Notes, AC and Definition of Done checks. + +**IMPORTANT**: Only implement what's in the Acceptance Criteria. If you need to do more, either: +1. Update the AC first: `backlog task edit 42 --ac "New requirement"` +2. Or create a new task: `backlog task create "Additional feature"` + +--- + +## 6. Typical Workflow + +```bash +# 1. Identify work +backlog task list -s "To Do" --plain + +# 2. Read task details +backlog task 42 --plain + +# 3. Start work: assign yourself & change status +backlog task edit 42 -a @myself -s "In Progress" + +# 4. Add implementation plan +backlog task edit 42 --plan "1. Analyze\n2. Refactor\n3. Test" + +# 5. Work on the task (write code, test, etc.) + +# 6. Mark acceptance criteria as complete (supports multiple in one command) +backlog task edit 42 --check-ac 1 --check-ac 2 --check-ac 3 # Check all at once +# Or check them individually if preferred: +# backlog task edit 42 --check-ac 1 +# backlog task edit 42 --check-ac 2 +# backlog task edit 42 --check-ac 3 + +# 7. Add implementation notes +backlog task edit 42 --notes "Refactored using strategy pattern, updated tests" + +# 8. Mark task as done +backlog task edit 42 -s Done +``` + +--- + +## 7. Definition of Done (DoD) + +A task is **Done** only when **ALL** of the following are complete: + +### ✅ Via CLI Commands: +1. **All acceptance criteria checked**: Use `backlog task edit <id> --check-ac <index>` for each +2. **Implementation notes added**: Use `backlog task edit <id> --notes "..."` +3. **Status set to Done**: Use `backlog task edit <id> -s Done` + +### ✅ Via Code/Testing: +4. **Tests pass**: Run test suite and linting +5. **Documentation updated**: Update relevant docs if needed +6. **Code reviewed**: Self-review your changes +7. **No regressions**: Performance, security checks pass + +⚠️ **NEVER mark a task as Done without completing ALL items above** + +--- + +## 8. Quick Reference: DO vs DON'T + +### Viewing Tasks +| Task | ✅ DO | ❌ DON'T | +|------|-------|----------| +| View task | `backlog task 42 --plain` | Open and read .md file directly | +| List tasks | `backlog task list --plain` | Browse backlog/tasks folder | +| Check status | `backlog task 42 --plain` | Look at file content | + +### Modifying Tasks +| Task | ✅ DO | ❌ DON'T | +|------|-------|----------| +| Check AC | `backlog task edit 42 --check-ac 1` | Change `- [ ]` to `- [x]` in file | +| Add notes | `backlog task edit 42 --notes "..."` | Type notes into .md file | +| Change status | `backlog task edit 42 -s Done` | Edit status in frontmatter | +| Add AC | `backlog task edit 42 --ac "New"` | Add `- [ ] New` to file | + +--- + +## 9. Complete CLI Command Reference + +### Task Creation +| Action | Command | +|--------|---------| +| Create task | `backlog task create "Title"` | +| With description | `backlog task create "Title" -d "Description"` | +| With AC | `backlog task create "Title" --ac "Criterion 1" --ac "Criterion 2"` | +| With all options | `backlog task create "Title" -d "Desc" -a @sara -s "To Do" -l auth --priority high` | +| Create draft | `backlog task create "Title" --draft` | +| Create subtask | `backlog task create "Title" -p 42` | + +### Task Modification +| Action | Command | +|--------|---------| +| Edit title | `backlog task edit 42 -t "New Title"` | +| Edit description | `backlog task edit 42 -d "New description"` | +| Change status | `backlog task edit 42 -s "In Progress"` | +| Assign | `backlog task edit 42 -a @sara` | +| Add labels | `backlog task edit 42 -l backend,api` | +| Set priority | `backlog task edit 42 --priority high` | + +### Acceptance Criteria Management +| Action | Command | +|--------|---------| +| Add AC | `backlog task edit 42 --ac "New criterion" --ac "Another"` | +| Remove AC #2 | `backlog task edit 42 --remove-ac 2` | +| Remove multiple ACs | `backlog task edit 42 --remove-ac 2 --remove-ac 4` | +| Check AC #1 | `backlog task edit 42 --check-ac 1` | +| Check multiple ACs | `backlog task edit 42 --check-ac 1 --check-ac 3` | +| Uncheck AC #3 | `backlog task edit 42 --uncheck-ac 3` | +| Mixed operations | `backlog task edit 42 --check-ac 1 --uncheck-ac 2 --remove-ac 3 --ac "New"` | + +### Task Content +| Action | Command | +|--------|---------| +| Add plan | `backlog task edit 42 --plan "1. Step one\n2. Step two"` | +| Add notes | `backlog task edit 42 --notes "Implementation details"` | +| Add dependencies | `backlog task edit 42 --dep task-1 --dep task-2` | + +### Task Operations +| Action | Command | +|--------|---------| +| View task | `backlog task 42 --plain` | +| List tasks | `backlog task list --plain` | +| Filter by status | `backlog task list -s "In Progress" --plain` | +| Filter by assignee | `backlog task list -a @sara --plain` | +| Archive task | `backlog task archive 42` | +| Demote to draft | `backlog task demote 42` | + +--- + +## 10. Troubleshooting + +### If You Accidentally Edited a File Directly + +1. **DON'T PANIC** - But don't save or commit +2. Revert the changes +3. Make changes properly via CLI +4. If already saved, the metadata might be out of sync - use `backlog task edit` to fix + +### Common Issues + +| Problem | Solution | +|---------|----------| +| "Task not found" | Check task ID with `backlog task list --plain` | +| AC won't check | Use correct index: `backlog task 42 --plain` to see AC numbers | +| Changes not saving | Ensure you're using CLI, not editing files | +| Metadata out of sync | Re-edit via CLI to fix: `backlog task edit 42 -s <current-status>` | + +--- + +## Remember: The Golden Rule + +**🎯 If you want to change ANYTHING in a task, use the `backlog task edit` command.** +**📖 Only READ task files directly, never WRITE to them.** + +Full help available: `backlog --help` + +# === BACKLOG.MD GUIDELINES END === diff --git a/.cursor/rules/database-patterns.mdc b/.cursor/rules/database-patterns.mdc index 58934598b..a4f65f5fb 100644 --- a/.cursor/rules/database-patterns.mdc +++ b/.cursor/rules/database-patterns.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: Database architecture, models, migrations, relationships, and data management patterns +globs: app/Models/*.php, database/migrations/*.php, database/seeders/*.php, app/Actions/Database/*.php alwaysApply: false --- # Coolify Database Architecture & Patterns diff --git a/.cursor/rules/deployment-architecture.mdc b/.cursor/rules/deployment-architecture.mdc index 5174cbb99..35ae6699b 100644 --- a/.cursor/rules/deployment-architecture.mdc +++ b/.cursor/rules/deployment-architecture.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: Docker orchestration, deployment workflows, and containerization patterns +globs: app/Jobs/*.php, app/Actions/Application/*.php, app/Actions/Server/*.php, docker/*.*, *.yml, *.yaml alwaysApply: false --- # Coolify Deployment Architecture diff --git a/.cursor/rules/development-workflow.mdc b/.cursor/rules/development-workflow.mdc index dd38cbc3f..175b7d85a 100644 --- a/.cursor/rules/development-workflow.mdc +++ b/.cursor/rules/development-workflow.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: Development setup, coding standards, contribution guidelines, and best practices +globs: **/*.php, composer.json, package.json, *.md, .env.example alwaysApply: false --- # Coolify Development Workflow diff --git a/.cursor/rules/form-components.mdc b/.cursor/rules/form-components.mdc new file mode 100644 index 000000000..665ccfd98 --- /dev/null +++ b/.cursor/rules/form-components.mdc @@ -0,0 +1,452 @@ +--- +description: Enhanced form components with built-in authorization system +globs: resources/views/**/*.blade.php, app/View/Components/Forms/*.php +alwaysApply: true +--- + +# Enhanced Form Components with Authorization + +## Overview + +Coolify's form components now feature **built-in authorization** that automatically handles permission-based UI control, dramatically reducing code duplication and improving security consistency. + +## Enhanced Components + +All form components now support the `canGate` authorization system: + +- **[Input.php](mdc:app/View/Components/Forms/Input.php)** - Text, password, and other input fields +- **[Select.php](mdc:app/View/Components/Forms/Select.php)** - Dropdown selection components +- **[Textarea.php](mdc:app/View/Components/Forms/Textarea.php)** - Multi-line text areas +- **[Checkbox.php](mdc:app/View/Components/Forms/Checkbox.php)** - Boolean toggle components +- **[Button.php](mdc:app/View/Components/Forms/Button.php)** - Action buttons + +## Authorization Parameters + +### Core Parameters +```php +public ?string $canGate = null; // Gate name: 'update', 'view', 'deploy', 'delete' +public mixed $canResource = null; // Resource model instance to check against +public bool $autoDisable = true; // Automatically disable if no permission +``` + +### How It Works +```php +// Automatic authorization logic in each component +if ($this->canGate && $this->canResource && $this->autoDisable) { + $hasPermission = Gate::allows($this->canGate, $this->canResource); + + if (! $hasPermission) { + $this->disabled = true; + // For Checkbox: also sets $this->instantSave = false; + } +} +``` + +## Usage Patterns + +### ✅ Recommended: Single Line Pattern + +**Before (Verbose, 6+ lines per element):** +```html +@can('update', $application) + <x-forms.input id="application.name" label="Name" /> + <x-forms.checkbox instantSave id="application.settings.is_static" label="Static Site" /> + <x-forms.button type="submit">Save</x-forms.button> +@else + <x-forms.input disabled id="application.name" label="Name" /> + <x-forms.checkbox disabled id="application.settings.is_static" label="Static Site" /> +@endcan +``` + +**After (Clean, 1 line per element):** +```html +<x-forms.input canGate="update" :canResource="$application" id="application.name" label="Name" /> +<x-forms.checkbox instantSave canGate="update" :canResource="$application" id="application.settings.is_static" label="Static Site" /> +<x-forms.button canGate="update" :canResource="$application" type="submit">Save</x-forms.button> +``` + +**Result: 90% code reduction!** + +### Component-Specific Examples + +#### Input Fields +```html +<!-- Basic input with authorization --> +<x-forms.input + canGate="update" + :canResource="$application" + id="application.name" + label="Application Name" /> + +<!-- Password input with authorization --> +<x-forms.input + type="password" + canGate="update" + :canResource="$application" + id="application.database_password" + label="Database Password" /> + +<!-- Required input with authorization --> +<x-forms.input + required + canGate="update" + :canResource="$application" + id="application.fqdn" + label="Domain" /> +``` + +#### Select Dropdowns +```html +<!-- Build pack selection --> +<x-forms.select + canGate="update" + :canResource="$application" + id="application.build_pack" + label="Build Pack" + required> + <option value="nixpacks">Nixpacks</option> + <option value="static">Static</option> + <option value="dockerfile">Dockerfile</option> +</x-forms.select> + +<!-- Server selection --> +<x-forms.select + canGate="createAnyResource" + :canResource="auth()->user()->currentTeam" + id="server_id" + label="Target Server"> + @foreach($servers as $server) + <option value="{{ $server->id }}">{{ $server->name }}</option> + @endforeach +</x-forms.select> +``` + +#### Checkboxes with InstantSave +```html +<!-- Static site toggle --> +<x-forms.checkbox + instantSave + canGate="update" + :canResource="$application" + id="application.settings.is_static" + label="Is it a static site?" + helper="Enable if your application serves static files" /> + +<!-- Debug mode toggle --> +<x-forms.checkbox + instantSave + canGate="update" + :canResource="$application" + id="application.settings.is_debug_enabled" + label="Debug Mode" + helper="Enable debug logging for troubleshooting" /> + +<!-- Build server toggle --> +<x-forms.checkbox + instantSave + canGate="update" + :canResource="$application" + id="application.settings.is_build_server_enabled" + label="Use Build Server" + helper="Use a dedicated build server for compilation" /> +``` + +#### Textareas +```html +<!-- Configuration textarea --> +<x-forms.textarea + canGate="update" + :canResource="$application" + id="application.docker_compose_raw" + label="Docker Compose Configuration" + rows="10" + monacoEditorLanguage="yaml" + useMonacoEditor /> + +<!-- Custom commands --> +<x-forms.textarea + canGate="update" + :canResource="$application" + id="application.post_deployment_command" + label="Post-Deployment Commands" + placeholder="php artisan migrate" + helper="Commands to run after deployment" /> +``` + +#### Buttons +```html +<!-- Save button --> +<x-forms.button + canGate="update" + :canResource="$application" + type="submit"> + Save Configuration +</x-forms.button> + +<!-- Deploy button --> +<x-forms.button + canGate="deploy" + :canResource="$application" + wire:click="deploy"> + Deploy Application +</x-forms.button> + +<!-- Delete button --> +<x-forms.button + canGate="delete" + :canResource="$application" + wire:click="confirmDelete" + class="button-danger"> + Delete Application +</x-forms.button> +``` + +## Advanced Usage + +### Custom Authorization Logic +```html +<!-- Disable auto-control for complex permissions --> +<x-forms.input + canGate="update" + :canResource="$application" + autoDisable="false" + :disabled="$application->is_deployed || !$application->canModifySettings()" + id="deployment.setting" + label="Advanced Setting" /> +``` + +### Multiple Permission Checks +```html +<!-- Combine multiple authorization requirements --> +<x-forms.checkbox + canGate="deploy" + :canResource="$application" + autoDisable="false" + :disabled="!$application->hasDockerfile() || !Gate::allows('deploy', $application)" + id="docker.setting" + label="Docker-Specific Setting" /> +``` + +### Conditional Resources +```html +<!-- Different resources based on context --> +<x-forms.button + :canGate="$isEditing ? 'update' : 'view'" + :canResource="$resource" + type="submit"> + {{ $isEditing ? 'Save Changes' : 'View Details' }} +</x-forms.button> +``` + +## Supported Gates + +### Resource-Level Gates +- `view` - Read access to resource details +- `update` - Modify resource configuration and settings +- `deploy` - Deploy, restart, or manage resource state +- `delete` - Remove or destroy resource +- `clone` - Duplicate resource to another location + +### Global Gates +- `createAnyResource` - Create new resources of any type +- `manageTeam` - Team administration permissions +- `accessServer` - Server-level access permissions + +## Supported Resources + +### Primary Resources +- `$application` - Application instances and configurations +- `$service` - Docker Compose services and components +- `$database` - Database instances (PostgreSQL, MySQL, etc.) +- `$server` - Physical or virtual server instances + +### Container Resources +- `$project` - Project containers and environments +- `$environment` - Environment-specific configurations +- `$team` - Team and organization contexts + +### Infrastructure Resources +- `$privateKey` - SSH private keys and certificates +- `$source` - Git sources and repositories +- `$destination` - Deployment destinations and targets + +## Component Behavior + +### Input Components (Input, Select, Textarea) +When authorization fails: +- **disabled = true** - Field becomes non-editable +- **Visual styling** - Opacity reduction and disabled cursor +- **Form submission** - Values are ignored in forms +- **User feedback** - Clear visual indication of restricted access + +### Checkbox Components +When authorization fails: +- **disabled = true** - Checkbox becomes non-clickable +- **instantSave = false** - Automatic saving is disabled +- **State preservation** - Current value is maintained but read-only +- **Visual styling** - Disabled appearance with reduced opacity + +### Button Components +When authorization fails: +- **disabled = true** - Button becomes non-clickable +- **Event blocking** - Click handlers are ignored +- **Visual styling** - Disabled appearance and cursor +- **Loading states** - Loading indicators are disabled + +## Migration Guide + +### Converting Existing Forms + +**Old Pattern:** +```html +<form wire:submit='submit'> + @can('update', $application) + <x-forms.input id="name" label="Name" /> + <x-forms.select id="type" label="Type">...</x-forms.select> + <x-forms.checkbox instantSave id="enabled" label="Enabled" /> + <x-forms.button type="submit">Save</x-forms.button> + @else + <x-forms.input disabled id="name" label="Name" /> + <x-forms.select disabled id="type" label="Type">...</x-forms.select> + <x-forms.checkbox disabled id="enabled" label="Enabled" /> + @endcan +</form> +``` + +**New Pattern:** +```html +<form wire:submit='submit'> + <x-forms.input canGate="update" :canResource="$application" id="name" label="Name" /> + <x-forms.select canGate="update" :canResource="$application" id="type" label="Type">...</x-forms.select> + <x-forms.checkbox instantSave canGate="update" :canResource="$application" id="enabled" label="Enabled" /> + <x-forms.button canGate="update" :canResource="$application" type="submit">Save</x-forms.button> +</form> +``` + +### Gradual Migration Strategy + +1. **Start with new forms** - Use the new pattern for all new components +2. **Convert high-traffic areas** - Migrate frequently used forms first +3. **Batch convert similar forms** - Group similar authorization patterns +4. **Test thoroughly** - Verify authorization behavior matches expectations +5. **Remove old patterns** - Clean up legacy @can/@else blocks + +## Testing Patterns + +### Component Authorization Tests +```php +// Test authorization integration in components +test('input component respects authorization', function () { + $user = User::factory()->member()->create(); + $application = Application::factory()->create(); + + // Member should see disabled input + $component = Livewire::actingAs($user) + ->test(TestComponent::class, [ + 'canGate' => 'update', + 'canResource' => $application + ]); + + expect($component->get('disabled'))->toBeTrue(); +}); + +test('checkbox disables instantSave for unauthorized users', function () { + $user = User::factory()->member()->create(); + $application = Application::factory()->create(); + + $component = Livewire::actingAs($user) + ->test(CheckboxComponent::class, [ + 'instantSave' => true, + 'canGate' => 'update', + 'canResource' => $application + ]); + + expect($component->get('disabled'))->toBeTrue(); + expect($component->get('instantSave'))->toBeFalse(); +}); +``` + +### Integration Tests +```php +// Test full form authorization behavior +test('application form respects member permissions', function () { + $member = User::factory()->member()->create(); + $application = Application::factory()->create(); + + $this->actingAs($member) + ->get(route('application.edit', $application)) + ->assertSee('disabled') + ->assertDontSee('Save Configuration'); +}); +``` + +## Best Practices + +### Consistent Gate Usage +- Use `update` for configuration changes +- Use `deploy` for operational actions +- Use `view` for read-only access +- Use `delete` for destructive actions + +### Resource Context +- Always pass the specific resource being acted upon +- Use team context for creation permissions +- Consider nested resource relationships + +### Error Handling +- Provide clear feedback for disabled components +- Use helper text to explain permission requirements +- Consider tooltips for disabled buttons + +### Performance +- Authorization checks are cached per request +- Use eager loading for resource relationships +- Consider query optimization for complex permissions + +## Common Patterns + +### Application Configuration Forms +```html +<!-- Application settings with consistent authorization --> +<x-forms.input canGate="update" :canResource="$application" id="application.name" label="Name" /> +<x-forms.select canGate="update" :canResource="$application" id="application.build_pack" label="Build Pack">...</x-forms.select> +<x-forms.checkbox instantSave canGate="update" :canResource="$application" id="application.settings.is_static" label="Static Site" /> +<x-forms.button canGate="update" :canResource="$application" type="submit">Save</x-forms.button> +``` + +### Service Configuration Forms +```html +<!-- Service stack configuration with authorization --> +<x-forms.input canGate="update" :canResource="$service" id="service.name" label="Service Name" /> +<x-forms.input canGate="update" :canResource="$service" id="service.description" label="Description" /> +<x-forms.checkbox canGate="update" :canResource="$service" instantSave id="service.connect_to_docker_network" label="Connect To Predefined Network" /> +<x-forms.button canGate="update" :canResource="$service" type="submit">Save</x-forms.button> + +<!-- Service-specific fields --> +<x-forms.input canGate="update" :canResource="$service" type="{{ data_get($field, 'isPassword') ? 'password' : 'text' }}" + required="{{ str(data_get($field, 'rules'))?->contains('required') }}" + id="fields.{{ $serviceName }}.value"></x-forms.input> + +<!-- Service restart modal - wrapped with @can --> +@can('update', $service) + <x-modal-confirmation title="Confirm Service Application Restart?" + buttonTitle="Restart" + submitAction="restartApplication({{ $application->id }})" /> +@endcan +``` + +### Server Management Forms +```html +<!-- Server configuration with appropriate gates --> +<x-forms.input canGate="update" :canResource="$server" id="server.name" label="Server Name" /> +<x-forms.select canGate="update" :canResource="$server" id="server.type" label="Server Type">...</x-forms.select> +<x-forms.button canGate="delete" :canResource="$server" wire:click="deleteServer">Delete Server</x-forms.button> +``` + +### Resource Creation Forms +```html +<!-- New resource creation --> +<x-forms.input canGate="createAnyResource" :canResource="auth()->user()->currentTeam" id="name" label="Name" /> +<x-forms.select canGate="createAnyResource" :canResource="auth()->user()->currentTeam" id="server_id" label="Server">...</x-forms.select> +<x-forms.button canGate="createAnyResource" :canResource="auth()->user()->currentTeam" type="submit">Create Application</x-forms.button> +``` \ No newline at end of file diff --git a/.cursor/rules/frontend-patterns.mdc b/.cursor/rules/frontend-patterns.mdc index 45888eee4..663490d3b 100644 --- a/.cursor/rules/frontend-patterns.mdc +++ b/.cursor/rules/frontend-patterns.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: Livewire components, Alpine.js patterns, Tailwind CSS, and enhanced form components +globs: app/Livewire/**/*.php, resources/views/**/*.blade.php, resources/js/**/*.js, resources/css/**/*.css alwaysApply: false --- # Coolify Frontend Architecture & Patterns @@ -230,6 +230,41 @@ class ServerList extends Component - **Asset bundling** and compression - **CDN integration** for static assets +## Enhanced Form Components + +### Built-in Authorization System +Coolify features **enhanced form components** with automatic authorization handling: + +```html +<!-- ✅ New Pattern: Single line with built-in authorization --> +<x-forms.input canGate="update" :canResource="$application" id="application.name" label="Name" /> +<x-forms.checkbox instantSave canGate="update" :canResource="$application" id="application.settings.is_static" label="Static Site" /> +<x-forms.button canGate="update" :canResource="$application" type="submit">Save</x-forms.button> + +<!-- ❌ Old Pattern: Verbose @can/@else blocks (deprecated) --> +@can('update', $application) + <x-forms.input id="application.name" label="Name" /> +@else + <x-forms.input disabled id="application.name" label="Name" /> +@endcan +``` + +### Authorization Parameters +```php +// Available on all form components (Input, Select, Textarea, Checkbox, Button) +public ?string $canGate = null; // Gate name: 'update', 'view', 'deploy', 'delete' +public mixed $canResource = null; // Resource model instance to check against +public bool $autoDisable = true; // Automatically disable if no permission (default: true) +``` + +### Benefits +- **90% code reduction** for authorization-protected forms +- **Consistent security** across all form components +- **Automatic disabling** for unauthorized users +- **Smart behavior** (disables instantSave on checkboxes for unauthorized users) + +For complete documentation, see **[form-components.mdc](mdc:.cursor/rules/form-components.mdc)** + ## Form Handling Patterns ### Livewire Forms diff --git a/.cursor/rules/project-overview.mdc b/.cursor/rules/project-overview.mdc index 2be9f31e6..b615a5d3e 100644 --- a/.cursor/rules/project-overview.mdc +++ b/.cursor/rules/project-overview.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: High-level project mission, core concepts, and architectural overview +globs: README.md, CONTRIBUTING.md, CHANGELOG.md, *.md alwaysApply: false --- # Coolify Project Overview diff --git a/.cursor/rules/security-patterns.mdc b/.cursor/rules/security-patterns.mdc index 9cdbcaa0c..a7ab2ad69 100644 --- a/.cursor/rules/security-patterns.mdc +++ b/.cursor/rules/security-patterns.mdc @@ -1,7 +1,7 @@ --- -description: -globs: -alwaysApply: false +description: Security architecture, authentication, authorization patterns, and enhanced form component security +globs: app/Policies/*.php, app/View/Components/Forms/*.php, app/Http/Middleware/*.php, resources/views/**/*.blade.php +alwaysApply: true --- # Coolify Security Architecture & Patterns @@ -63,6 +63,323 @@ class User extends Authenticatable ## Authorization & Access Control +### Enhanced Form Component Authorization System + +Coolify now features a **centralized authorization system** built into all form components (`Input`, `Select`, `Textarea`, `Checkbox`, `Button`) that automatically handles permission-based UI control. + +#### Component Authorization Parameters +```php +// Available on all form components +public ?string $canGate = null; // Gate name (e.g., 'update', 'view', 'delete') +public mixed $canResource = null; // Resource to check against (model instance) +public bool $autoDisable = true; // Auto-disable if no permission (default: true) +``` + +#### Smart Authorization Logic +```php +// Automatic authorization handling in component constructor +if ($this->canGate && $this->canResource && $this->autoDisable) { + $hasPermission = Gate::allows($this->canGate, $this->canResource); + + if (! $hasPermission) { + $this->disabled = true; + // For Checkbox: also disables instantSave + } +} +``` + +#### Usage Examples + +**✅ Recommended Pattern (Single Line):** +```html +<!-- Input with automatic authorization --> +<x-forms.input + canGate="update" + :canResource="$application" + id="application.name" + label="Application Name" /> + +<!-- Select with automatic authorization --> +<x-forms.select + canGate="update" + :canResource="$application" + id="application.build_pack" + label="Build Pack"> + <option value="nixpacks">Nixpacks</option> + <option value="static">Static</option> +</x-forms.select> + +<!-- Checkbox with automatic instantSave control --> +<x-forms.checkbox + instantSave + canGate="update" + :canResource="$application" + id="application.settings.is_static" + label="Is Static Site?" /> + +<!-- Button with automatic disable --> +<x-forms.button + canGate="update" + :canResource="$application" + type="submit"> + Save Configuration +</x-forms.button> +``` + +**❌ Old Pattern (Verbose, Deprecated):** +```html +<!-- DON'T use this repetitive pattern anymore --> +@can('update', $application) + <x-forms.input id="application.name" label="Application Name" /> + <x-forms.button type="submit">Save</x-forms.button> +@else + <x-forms.input disabled id="application.name" label="Application Name" /> +@endcan +``` + +#### Advanced Usage with Custom Control + +**Custom Authorization Logic:** +```html +<!-- Disable auto-control, use custom logic --> +<x-forms.input + canGate="update" + :canResource="$application" + autoDisable="false" + :disabled="$application->is_deployed || !Gate::allows('update', $application)" + id="advanced.setting" + label="Advanced Setting" /> +``` + +**Multiple Permission Checks:** +```html +<!-- Complex permission requirements --> +<x-forms.checkbox + canGate="deploy" + :canResource="$application" + autoDisable="false" + :disabled="!$application->canDeploy() || !auth()->user()->hasAdvancedPermissions()" + id="deployment.setting" + label="Advanced Deployment Setting" /> +``` + +#### Supported Gates and Resources + +**Common Gates:** +- `view` - Read access to resource +- `update` - Modify resource configuration +- `deploy` - Deploy/restart resource +- `delete` - Remove resource +- `createAnyResource` - Create new resources + +**Resource Types:** +- `Application` - Application instances +- `Service` - Docker Compose services +- `Server` - Server instances +- `Project` - Project containers +- `Environment` - Environment contexts +- `Database` - Database instances + +#### Benefits + +**🔥 Massive Code Reduction:** +- **90% less code** for authorization-protected forms +- **Single line** instead of 6-12 lines per form element +- **No more @can/@else blocks** cluttering templates + +**🛡️ Consistent Security:** +- **Unified authorization logic** across all form components +- **Automatic disabling** for unauthorized users +- **Smart behavior** (like disabling instantSave on checkboxes) + +**🎨 Better UX:** +- **Consistent disabled styling** across all components +- **Proper visual feedback** for restricted access +- **Clean, professional interface** + +#### Implementation Details + +**Component Enhancement:** +```php +// Enhanced in all form components +use Illuminate\Support\Facades\Gate; + +public function __construct( + // ... existing parameters + public ?string $canGate = null, + public mixed $canResource = null, + public bool $autoDisable = true, +) { + // Handle authorization-based disabling + if ($this->canGate && $this->canResource && $this->autoDisable) { + $hasPermission = Gate::allows($this->canGate, $this->canResource); + + if (! $hasPermission) { + $this->disabled = true; + // For Checkbox: $this->instantSave = false; + } + } +} +``` + +**Backward Compatibility:** +- All existing form components continue to work unchanged +- New authorization parameters are optional +- Legacy @can/@else patterns still function but are discouraged + +### Custom Component Authorization Patterns + +When dealing with **custom Alpine.js components** or complex UI elements that don't use the standard `x-forms.*` components, manual authorization protection is required since the automatic `canGate` system only applies to enhanced form components. + +#### Common Custom Components Requiring Manual Protection + +**⚠️ Custom Components That Need Manual Authorization:** +- Custom dropdowns/selects with Alpine.js +- Complex form widgets with JavaScript interactions +- Multi-step wizards or dynamic forms +- Third-party component integrations +- Custom date/time pickers +- File upload components with drag-and-drop + +#### Manual Authorization Pattern + +**✅ Proper Manual Authorization:** +```html +<!-- Custom timezone dropdown example --> +<div class="w-full"> + <div class="flex items-center mb-1"> + <label for="customComponent">Component Label</label> + <x-helper helper="Component description" /> + </div> + @can('update', $resource) + <!-- Full interactive component for authorized users --> + <div x-data="{ + open: false, + value: '{{ $currentValue }}', + options: @js($options), + init() { /* Alpine.js initialization */ } + }"> + <input x-model="value" @focus="open = true" + wire:model="propertyName" class="w-full input"> + <div x-show="open"> + <!-- Interactive dropdown content --> + <template x-for="option in options" :key="option"> + <div @click="value = option; open = false; $wire.submit()" + x-text="option"></div> + </template> + </div> + </div> + @else + <!-- Read-only version for unauthorized users --> + <div class="relative"> + <input readonly disabled autocomplete="off" + class="w-full input opacity-50 cursor-not-allowed" + value="{{ $currentValue ?: 'No value set' }}"> + <svg class="absolute right-0 mr-2 w-4 h-4 opacity-50"> + <!-- Disabled icon --> + </svg> + </div> + @endcan +</div> +``` + +#### Implementation Checklist + +When implementing authorization for custom components: + +**🔍 1. Identify Custom Components:** +- Look for Alpine.js `x-data` declarations +- Find components not using `x-forms.*` prefix +- Check for JavaScript-heavy interactions +- Review complex form widgets + +**🛡️ 2. Wrap with Authorization:** +- Use `@can('gate', $resource)` / `@else` / `@endcan` structure +- Provide full functionality in the `@can` block +- Create disabled/readonly version in the `@else` block + +**🎨 3. Design Disabled State:** +- Apply `readonly disabled` attributes to inputs +- Add `opacity-50 cursor-not-allowed` classes for visual feedback +- Remove interactive JavaScript behaviors +- Show current value or appropriate placeholder + +**🔒 4. Backend Protection:** +- Ensure corresponding Livewire methods check authorization +- Add `$this->authorize('gate', $resource)` in relevant methods +- Validate permissions before processing any changes + +#### Real-World Examples + +**Custom Date Range Picker:** +```html +@can('update', $application) + <div x-data="dateRangePicker()" class="date-picker"> + <!-- Interactive date picker with calendar --> + </div> +@else + <div class="flex gap-2"> + <input readonly disabled value="{{ $startDate }}" class="input opacity-50"> + <input readonly disabled value="{{ $endDate }}" class="input opacity-50"> + </div> +@endcan +``` + +**Multi-Select Component:** +```html +@can('update', $server) + <div x-data="multiSelect({ options: @js($options) })"> + <!-- Interactive multi-select with checkboxes --> + </div> +@else + <div class="space-y-2"> + @foreach($selectedValues as $value) + <div class="px-3 py-1 bg-gray-100 rounded text-sm opacity-50"> + {{ $value }} + </div> + @endforeach + </div> +@endcan +``` + +**File Upload Widget:** +```html +@can('update', $application) + <div x-data="fileUploader()" @drop.prevent="handleDrop"> + <!-- Drag-and-drop file upload interface --> + </div> +@else + <div class="border-2 border-dashed border-gray-300 rounded-lg p-6 text-center opacity-50"> + <p class="text-gray-500">File upload restricted</p> + @if($currentFile) + <p class="text-sm">Current: {{ $currentFile }}</p> + @endif + </div> +@endcan +``` + +#### Key Principles + +**🎯 Consistency:** +- Maintain similar visual styling between enabled/disabled states +- Use consistent disabled patterns across the application +- Apply the same opacity and cursor styling + +**🔐 Security First:** +- Always implement backend authorization checks +- Never rely solely on frontend hiding/disabling +- Validate permissions on every server action + +**💡 User Experience:** +- Show current values in disabled state when appropriate +- Provide clear visual feedback about restricted access +- Maintain layout stability between states + +**🚀 Performance:** +- Minimize Alpine.js initialization for disabled components +- Avoid loading unnecessary JavaScript for unauthorized users +- Use simple HTML structures for read-only states + ### Team-Based Multi-Tenancy - **[Team.php](mdc:app/Models/Team.php)** - Multi-tenant organization structure (8.9KB, 308 lines) - **[TeamInvitation.php](mdc:app/Models/TeamInvitation.php)** - Secure team collaboration diff --git a/.cursor/rules/self_improve.mdc b/.cursor/rules/self_improve.mdc index 40b31b6ea..2bebaec75 100644 --- a/.cursor/rules/self_improve.mdc +++ b/.cursor/rules/self_improve.mdc @@ -31,19 +31,6 @@ alwaysApply: true - Related rules have been updated - Implementation details have changed -- **Example Pattern Recognition:** - ```typescript - // If you see repeated patterns like: - const data = await prisma.user.findMany({ - select: { id: true, email: true }, - where: { status: 'ACTIVE' } - }); - - // Consider adding to [prisma.mdc](mdc:.cursor/rules/prisma.mdc): - // - Standard select fields - // - Common where conditions - // - Performance optimization patterns - ``` - **Rule Quality Checks:** - Rules should be actionable and specific diff --git a/.cursor/rules/technology-stack.mdc b/.cursor/rules/technology-stack.mdc index 81a2e3bb3..2119a2ff1 100644 --- a/.cursor/rules/technology-stack.mdc +++ b/.cursor/rules/technology-stack.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: Complete technology stack, dependencies, and infrastructure components +globs: composer.json, package.json, docker-compose*.yml, config/*.php alwaysApply: false --- # Coolify Technology Stack diff --git a/.cursor/rules/testing-patterns.mdc b/.cursor/rules/testing-patterns.mdc index c3eabe09f..010b76544 100644 --- a/.cursor/rules/testing-patterns.mdc +++ b/.cursor/rules/testing-patterns.mdc @@ -1,6 +1,6 @@ --- -description: -globs: +description: Testing strategies with Pest PHP, Laravel Dusk, and quality assurance patterns +globs: tests/**/*.php, database/factories/*.php alwaysApply: false --- # Coolify Testing Architecture & Patterns diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml new file mode 100644 index 000000000..a2c92df59 --- /dev/null +++ b/.github/workflows/claude-code-review.yml @@ -0,0 +1,79 @@ +name: Claude Code Review + +on: + pull_request: + types: [opened, synchronize] + # Optional: Only run on specific file changes + # paths: + # - "src/**/*.ts" + # - "src/**/*.tsx" + # - "src/**/*.js" + # - "src/**/*.jsx" + +jobs: + claude-review: + if: false + # Optional: Filter by PR author + # if: | + # github.event.pull_request.user.login == 'external-contributor' || + # github.event.pull_request.user.login == 'new-developer' || + # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' + + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code Review + id: claude-review + uses: anthropics/claude-code-action@beta + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1) + # model: "claude-opus-4-1-20250805" + + # Direct prompt for automated review (no @claude mention needed) + direct_prompt: | + Please review this pull request and provide feedback on: + - Code quality and best practices + - Potential bugs or issues + - Performance considerations + - Security concerns + - Test coverage + + Be constructive and helpful in your feedback. + + # Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR + # use_sticky_comment: true + + # Optional: Customize review based on file types + # direct_prompt: | + # Review this PR focusing on: + # - For TypeScript files: Type safety and proper interface usage + # - For API endpoints: Security, input validation, and error handling + # - For React components: Performance, accessibility, and best practices + # - For tests: Coverage, edge cases, and test quality + + # Optional: Different prompts for different authors + # direct_prompt: | + # ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' && + # 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' || + # 'Please provide a thorough code review focusing on our coding standards and best practices.' }} + + # Optional: Add specific tools for running tests or linting + # allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)" + + # Optional: Skip review for certain conditions + # if: | + # !contains(github.event.pull_request.title, '[skip-review]') && + # !contains(github.event.pull_request.title, '[WIP]') + diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 000000000..bc773072b --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,64 @@ +name: Claude Code + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + issues: + types: [opened, assigned] + pull_request_review: + types: [submitted] + +jobs: + claude: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) || + (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + issues: read + id-token: write + actions: read # Required for Claude to read CI results on PRs + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run Claude Code + id: claude + uses: anthropics/claude-code-action@beta + with: + claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} + + # This is an optional setting that allows Claude to read CI results on PRs + additional_permissions: | + actions: read + + # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1) + # model: "claude-opus-4-1-20250805" + + # Optional: Customize the trigger phrase (default: @claude) + # trigger_phrase: "/claude" + + # Optional: Trigger when specific user is assigned to an issue + # assignee_trigger: "claude-bot" + + # Optional: Allow Claude to run specific commands + # allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)" + + # Optional: Add custom instructions for Claude to customize its behavior for your project + # custom_instructions: | + # Follow our coding standards + # Ensure all new code has tests + # Use TypeScript for new files + + # Optional: Custom environment variables for Claude + # claude_env: | + # NODE_ENV: test + diff --git a/.github/workflows/coolify-production-build.yml b/.github/workflows/coolify-production-build.yml index cd1f002b8..9286fdbb0 100644 --- a/.github/workflows/coolify-production-build.yml +++ b/.github/workflows/coolify-production-build.yml @@ -13,6 +13,7 @@ on: - docker/testing-host/Dockerfile - templates/** - CHANGELOG.md + - backlog/** env: GITHUB_REGISTRY: ghcr.io diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml index 09b1e9421..390eab000 100644 --- a/.github/workflows/coolify-staging-build.yml +++ b/.github/workflows/coolify-staging-build.yml @@ -16,6 +16,7 @@ on: - docker/testing-host/Dockerfile - templates/** - CHANGELOG.md + - backlog/** env: GITHUB_REGISTRY: ghcr.io diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 000000000..3baac76c1 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,252 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Coolify is an open-source, self-hostable platform for deploying applications and managing servers - an alternative to Heroku/Netlify/Vercel. It's built with Laravel (PHP) and uses Docker for containerization. + +## Development Commands + +### Frontend Development +- `npm run dev` - Start Vite development server for frontend assets +- `npm run build` - Build frontend assets for production + +### Backend Development +Only run artisan commands inside "coolify" container when in development. +- `php artisan serve` - Start Laravel development server +- `php artisan migrate` - Run database migrations +- `php artisan queue:work` - Start queue worker for background jobs +- `php artisan horizon` - Start Laravel Horizon for queue monitoring +- `php artisan tinker` - Start interactive PHP REPL + +### Code Quality +- `./vendor/bin/pint` - Run Laravel Pint for code formatting +- `./vendor/bin/phpstan` - Run PHPStan for static analysis +- `./vendor/bin/pest` - Run Pest tests + +## Architecture Overview + +### Technology Stack +- **Backend**: Laravel 12 (PHP 8.4) +- **Frontend**: Livewire 3.5+ with Alpine.js and Tailwind CSS 4.1+ +- **Database**: PostgreSQL 15 (primary), Redis 7 (cache/queues) +- **Real-time**: Soketi (WebSocket server) +- **Containerization**: Docker & Docker Compose +- **Queue Management**: Laravel Horizon + +### Key Components + +#### Core Models +- `Application` - Deployed applications with Git integration (74KB, highly complex) +- `Server` - Remote servers managed by Coolify (46KB, complex) +- `Service` - Docker Compose services (58KB, complex) +- `Database` - Standalone database instances (PostgreSQL, MySQL, MongoDB, Redis, etc.) +- `Team` - Multi-tenancy support +- `Project` - Grouping of environments and resources +- `Environment` - Environment isolation (staging, production, etc.) + +#### Job System +- Uses Laravel Horizon for queue management +- Key jobs: `ApplicationDeploymentJob`, `ServerCheckJob`, `DatabaseBackupJob` +- `ServerManagerJob` and `ServerConnectionCheckJob` handle job scheduling + +#### Deployment Flow +1. Git webhook triggers deployment +2. `ApplicationDeploymentJob` handles build and deployment +3. Docker containers are managed on target servers +4. Proxy configuration (Nginx/Traefik) is updated + +#### Server Management +- SSH-based server communication via `ExecuteRemoteCommand` trait +- Docker installation and management +- Proxy configuration generation +- Resource monitoring and cleanup + +### Directory Structure +- `app/Actions/` - Domain-specific actions (Application, Database, Server, etc.) +- `app/Jobs/` - Background queue jobs +- `app/Livewire/` - Frontend components (full-stack with Livewire) +- `app/Models/` - Eloquent models +- `app/Rules/` - Custom validation rules +- `app/Http/Middleware/` - HTTP middleware +- `bootstrap/helpers/` - Helper functions for various domains +- `database/migrations/` - Database schema evolution +- `routes/` - Application routing (web.php, api.php, webhooks.php, channels.php) +- `resources/views/livewire/` - Livewire component views +- `tests/` - Pest tests (Feature and Unit) + +## Development Guidelines + +### Frontend Philosophy +Coolify uses a **server-side first** approach with minimal JavaScript: +- **Livewire** for server-side rendering with reactive components +- **Alpine.js** for lightweight client-side interactions +- **Tailwind CSS** for utility-first styling with dark mode support +- **Enhanced Form Components** with built-in authorization system +- Real-time updates via WebSocket without page refreshes + +### Form Authorization Pattern +**IMPORTANT**: When creating or editing forms, ALWAYS include authorization: + +#### For Form Components (Input, Select, Textarea, Checkbox, Button): +Use `canGate` and `canResource` attributes for automatic authorization: +```html +<x-forms.input canGate="update" :canResource="$resource" id="name" label="Name" /> +<x-forms.select canGate="update" :canResource="$resource" id="type" label="Type">...</x-forms.select> +<x-forms.checkbox instantSave canGate="update" :canResource="$resource" id="enabled" label="Enabled" /> +<x-forms.button canGate="update" :canResource="$resource" type="submit">Save</x-forms.button> +``` + +#### For Modal Components: +Wrap with `@can` directives: +```html +@can('update', $resource) + <x-modal-confirmation title="Confirm Action?" buttonTitle="Confirm">...</x-modal-confirmation> + <x-modal-input buttonTitle="Edit" title="Edit Settings">...</x-modal-input> +@endcan +``` + +#### In Livewire Components: +Always add the `AuthorizesRequests` trait and check permissions: +```php +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; + +class MyComponent extends Component +{ + use AuthorizesRequests; + + public function mount() + { + $this->authorize('view', $this->resource); + } + + public function update() + { + $this->authorize('update', $this->resource); + // ... update logic + } +} +``` + +### Livewire Component Structure +- Components located in `app/Livewire/` +- Views in `resources/views/livewire/` +- State management handled on the server +- Use wire:model for two-way data binding +- Dispatch events for component communication + +### Code Organization Patterns +- **Actions Pattern**: Use Actions for complex business logic (`app/Actions/`) +- **Livewire Components**: Handle UI and user interactions +- **Jobs**: Handle asynchronous operations +- **Traits**: Provide shared functionality (e.g., `ExecuteRemoteCommand`) +- **Helper Functions**: Domain-specific helpers in `bootstrap/helpers/` + +### Database Patterns +- Use Eloquent ORM for database interactions +- Implement relationships properly (HasMany, BelongsTo, etc.) +- Use database transactions for critical operations +- Leverage query scopes for reusable queries +- Apply indexes for performance-critical queries + +### Security Best Practices +- **Authentication**: Multi-provider auth via Laravel Fortify & Sanctum +- **Authorization**: Team-based access control with policies and enhanced form components +- **Form Component Security**: Built-in `canGate` authorization system for UI components +- **API Security**: Token-based auth with IP allowlisting +- **Secrets Management**: Never log or expose sensitive data +- **Input Validation**: Always validate user input with Form Requests or Rules +- **SQL Injection Prevention**: Use Eloquent ORM or parameterized queries + +### API Development +- RESTful endpoints in `routes/api.php` +- Use API Resources for response formatting +- Implement rate limiting for public endpoints +- Version APIs when making breaking changes +- Document endpoints with clear examples + +### Testing Strategy +- **Framework**: Pest for expressive testing +- **Structure**: Feature tests for user flows, Unit tests for isolated logic +- **Coverage**: Test critical paths and edge cases +- **Mocking**: Use Laravel's built-in mocking for external services +- **Database**: Use RefreshDatabase trait for test isolation + +### Routing Conventions +- Group routes by middleware and prefix +- Use route model binding for cleaner controllers +- Name routes consistently (resource.action) +- Implement proper HTTP verbs (GET, POST, PUT, DELETE) + +### Error Handling +- Use `handleError()` helper for consistent error handling +- Log errors with appropriate context +- Return user-friendly error messages +- Implement proper HTTP status codes + +### Performance Considerations +- Use eager loading to prevent N+1 queries +- Implement caching for frequently accessed data +- Queue heavy operations +- Optimize database queries with proper indexes +- Use chunking for large data operations + +### Code Style +- Follow PSR-12 coding standards +- Use Laravel Pint for automatic formatting +- Write descriptive variable and method names +- Keep methods small and focused +- Document complex logic with clear comments + +## Cloud Instance Considerations + +We have a cloud instance of Coolify (hosted version) with: +- 2 Horizon worker servers +- Thousands of connected servers +- Thousands of active users +- High-availability requirements + +When developing features: +- Consider scalability implications +- Test with large datasets +- Implement efficient queries +- Use queues for heavy operations +- Consider rate limiting and resource constraints +- Implement proper error recovery mechanisms + +## Important Reminders + +- Always run code formatting: `./vendor/bin/pint` +- Test your changes: `./vendor/bin/pest` +- Check for static analysis issues: `./vendor/bin/phpstan` +- Use existing patterns and helpers +- Follow the established directory structure +- Maintain backward compatibility +- Document breaking changes +- Consider performance impact on large-scale deployments + +## Additional Documentation + +For more detailed guidelines and patterns, refer to the `.cursor/rules/` directory: + +### Architecture & Patterns +- [Application Architecture](.cursor/rules/application-architecture.mdc) - Detailed application structure +- [Deployment Architecture](.cursor/rules/deployment-architecture.mdc) - Deployment patterns and flows +- [Database Patterns](.cursor/rules/database-patterns.mdc) - Database design and query patterns +- [Frontend Patterns](.cursor/rules/frontend-patterns.mdc) - Livewire and Alpine.js patterns +- [API & Routing](.cursor/rules/api-and-routing.mdc) - API design and routing conventions + +### Development & Security +- [Development Workflow](.cursor/rules/development-workflow.mdc) - Development best practices +- [Security Patterns](.cursor/rules/security-patterns.mdc) - Security implementation details +- [Form Components](.cursor/rules/form-components.mdc) - Enhanced form components with authorization +- [Testing Patterns](.cursor/rules/testing-patterns.mdc) - Testing strategies and examples + +### Project Information +- [Project Overview](.cursor/rules/project-overview.mdc) - High-level project structure +- [Technology Stack](.cursor/rules/technology-stack.mdc) - Detailed tech stack information +- [Cursor Rules Guide](.cursor/rules/cursor_rules.mdc) - How to maintain cursor rules + +## Backlog.md Information +- [Backlog.md Guidelines](.cursor/rules/backlog-guildlines.md) - Backlog.md guidelines and commands diff --git a/README.md b/README.md index cf3dc21c3..f291a33e8 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ Thank you so much! ## Big Sponsors +* [CubePath](https://cubepath.com/?ref=coolify.io) - Dedicated Servers & Instant Deploy * [GlueOps](https://www.glueops.dev?ref=coolify.io) - DevOps automation and infrastructure management * [Algora](https://algora.io?ref=coolify.io) - Open source contribution platform * [Ubicloud](https://www.ubicloud.com?ref=coolify.io) - Open source cloud infrastructure platform @@ -87,8 +88,11 @@ Thank you so much! * [Gozunga](https://gozunga.com?ref=coolify.io) - Seriously Simple Cloud Infrastructure * [Macarne](https://macarne.com?ref=coolify.io) - Best IP Transit & Carrier Ethernet Solutions for Simplified Network Connectivity + ## Small Sponsors +<a href="https://open-elements.com/?utm_source=coolify.io"><img width="60px" alt="OpenElements" src="https://github.com/OpenElements.png"/></a> +<a href="https://xaman.app/?utm_source=coolify.io"><img width="60px" alt="XamanApp" src="https://github.com/XamanApp.png"/></a> <a href="https://www.uxwizz.com/?utm_source=coolify.io"><img width="60px" alt="UXWizz" src="https://github.com/UXWizz.png"/></a> <a href="https://evercam.io/?utm_source=coolify.io"><img width="60px" alt="Evercam" src="https://github.com/evercam.png"/></a> <a href="https://github.com/iujlaki"><img width="60px" alt="Imre Ujlaki" src="https://github.com/iujlaki.png"/></a> diff --git a/app/Actions/Application/StopApplication.php b/app/Actions/Application/StopApplication.php index 0ca703fce..ee3398b04 100644 --- a/app/Actions/Application/StopApplication.php +++ b/app/Actions/Application/StopApplication.php @@ -49,7 +49,7 @@ class StopApplication } if ($dockerCleanup) { - CleanupDocker::dispatch($server, true); + CleanupDocker::dispatch($server, false, false); } } catch (\Exception $e) { return $e->getMessage(); diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php index a40eac17b..4314ccd2f 100644 --- a/app/Actions/Database/StartPostgresql.php +++ b/app/Actions/Database/StartPostgresql.php @@ -185,6 +185,8 @@ class StartPostgresql } } + $command = ['postgres']; + if (filled($this->database->postgres_conf)) { $docker_compose['services'][$container_name]['volumes'] = array_merge( $docker_compose['services'][$container_name]['volumes'], @@ -195,29 +197,25 @@ class StartPostgresql 'read_only' => true, ]] ); - $docker_compose['services'][$container_name]['command'] = [ - 'postgres', - '-c', - 'config_file=/etc/postgresql/postgresql.conf', - ]; + $command = array_merge($command, ['-c', 'config_file=/etc/postgresql/postgresql.conf']); } if ($this->database->enable_ssl) { - $docker_compose['services'][$container_name]['command'] = [ - 'postgres', - '-c', - 'ssl=on', - '-c', - 'ssl_cert_file=/var/lib/postgresql/certs/server.crt', - '-c', - 'ssl_key_file=/var/lib/postgresql/certs/server.key', - ]; + $command = array_merge($command, [ + '-c', 'ssl=on', + '-c', 'ssl_cert_file=/var/lib/postgresql/certs/server.crt', + '-c', 'ssl_key_file=/var/lib/postgresql/certs/server.key', + ]); } // Add custom docker run options $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options); $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network); + if (count($command) > 1) { + $docker_compose['services'][$container_name]['command'] = $command; + } + $docker_compose = Yaml::dump($docker_compose, 10); $docker_compose_base64 = base64_encode($docker_compose); $this->commands[] = "echo '{$docker_compose_base64}' | base64 -d | tee $this->configuration_dir/docker-compose.yml > /dev/null"; diff --git a/app/Actions/Database/StopDatabase.php b/app/Actions/Database/StopDatabase.php index a03c9269e..5c881e743 100644 --- a/app/Actions/Database/StopDatabase.php +++ b/app/Actions/Database/StopDatabase.php @@ -18,7 +18,7 @@ class StopDatabase { use AsAction; - public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $database, bool $isDeleteOperation = false, bool $dockerCleanup = true) + public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $database, bool $dockerCleanup = true) { try { $server = $database->destination->server; @@ -29,7 +29,7 @@ class StopDatabase $this->stopContainer($database, $database->uuid, 30); if ($dockerCleanup) { - CleanupDocker::dispatch($server, true); + CleanupDocker::dispatch($server, false, false); } if ($database->is_public) { diff --git a/app/Actions/Proxy/CheckProxy.php b/app/Actions/Proxy/CheckProxy.php index d4b03ffc1..a06e547c5 100644 --- a/app/Actions/Proxy/CheckProxy.php +++ b/app/Actions/Proxy/CheckProxy.php @@ -66,7 +66,7 @@ class CheckProxy if ($server->id === 0) { $ip = 'host.docker.internal'; } - $portsToCheck = ['80', '443']; + $portsToCheck = []; try { if ($server->proxyType() !== ProxyTypes::NONE->value) { diff --git a/app/Actions/Server/CleanupDocker.php b/app/Actions/Server/CleanupDocker.php index 754feecb1..392562167 100644 --- a/app/Actions/Server/CleanupDocker.php +++ b/app/Actions/Server/CleanupDocker.php @@ -11,7 +11,7 @@ class CleanupDocker public string $jobQueue = 'high'; - public function handle(Server $server) + public function handle(Server $server, bool $deleteUnusedVolumes = false, bool $deleteUnusedNetworks = false) { $settings = instanceSettings(); $realtimeImage = config('constants.coolify.realtime_image'); @@ -36,11 +36,11 @@ class CleanupDocker "docker images --filter before=$realtimeImageWithoutPrefixVersion --filter reference=$realtimeImageWithoutPrefix | grep $realtimeImageWithoutPrefix | awk '{print $3}' | xargs -r docker rmi -f", ]; - if ($server->settings->delete_unused_volumes) { + if ($deleteUnusedVolumes) { $commands[] = 'docker volume prune -af'; } - if ($server->settings->delete_unused_networks) { + if ($deleteUnusedNetworks) { $commands[] = 'docker network prune -f'; } diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index 1ecf882dc..dd1a7ed53 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -2,6 +2,7 @@ namespace App\Actions\Server; +use App\Events\SentinelRestarted; use App\Models\Server; use Lorisleiva\Actions\Concerns\AsAction; @@ -61,5 +62,8 @@ class StartSentinel $server->settings->is_sentinel_enabled = true; $server->settings->save(); $server->sentinelHeartbeat(); + + // Dispatch event to notify UI components + SentinelRestarted::dispatch($server, $version); } } diff --git a/app/Actions/Server/UpdateCoolify.php b/app/Actions/Server/UpdateCoolify.php index 9a6cc140b..2a06428e2 100644 --- a/app/Actions/Server/UpdateCoolify.php +++ b/app/Actions/Server/UpdateCoolify.php @@ -29,7 +29,7 @@ class UpdateCoolify if (! $this->server) { return; } - CleanupDocker::dispatch($this->server); + CleanupDocker::dispatch($this->server, false, false); $this->latestVersion = get_latest_version_of_coolify(); $this->currentVersion = config('constants.coolify.version'); if (! $manual_update) { diff --git a/app/Actions/Service/DeleteService.php b/app/Actions/Service/DeleteService.php index 404e11559..8790901cd 100644 --- a/app/Actions/Service/DeleteService.php +++ b/app/Actions/Service/DeleteService.php @@ -11,7 +11,7 @@ class DeleteService { use AsAction; - public function handle(Service $service, bool $deleteConfigurations, bool $deleteVolumes, bool $dockerCleanup, bool $deleteConnectedNetworks) + public function handle(Service $service, bool $deleteVolumes, bool $deleteConnectedNetworks, bool $deleteConfigurations, bool $dockerCleanup) { try { $server = data_get($service, 'server'); @@ -71,7 +71,7 @@ class DeleteService $service->forceDelete(); if ($dockerCleanup) { - CleanupDocker::dispatch($server, true); + CleanupDocker::dispatch($server, false, false); } } } diff --git a/app/Actions/Service/StopService.php b/app/Actions/Service/StopService.php index a7fa4b8b2..3f4e96479 100644 --- a/app/Actions/Service/StopService.php +++ b/app/Actions/Service/StopService.php @@ -14,7 +14,7 @@ class StopService public string $jobQueue = 'high'; - public function handle(Service $service, bool $isDeleteOperation = false, bool $dockerCleanup = true) + public function handle(Service $service, bool $deleteConnectedNetworks = false, bool $dockerCleanup = true) { try { $server = $service->destination->server; @@ -36,11 +36,11 @@ class StopService $this->stopContainersInParallel($containersToStop, $server); } - if ($isDeleteOperation) { + if ($deleteConnectedNetworks) { $service->deleteConnectedNetworks(); } if ($dockerCleanup) { - CleanupDocker::dispatch($server, true); + CleanupDocker::dispatch($server, false, false); } } catch (\Exception $e) { return $e->getMessage(); diff --git a/app/Console/Commands/CleanupNames.php b/app/Console/Commands/CleanupNames.php new file mode 100644 index 000000000..2992e32b9 --- /dev/null +++ b/app/Console/Commands/CleanupNames.php @@ -0,0 +1,248 @@ +<?php + +namespace App\Console\Commands; + +use App\Models\Application; +use App\Models\Environment; +use App\Models\PrivateKey; +use App\Models\Project; +use App\Models\S3Storage; +use App\Models\ScheduledTask; +use App\Models\Server; +use App\Models\Service; +use App\Models\StandaloneClickhouse; +use App\Models\StandaloneDragonfly; +use App\Models\StandaloneKeydb; +use App\Models\StandaloneMariadb; +use App\Models\StandaloneMongodb; +use App\Models\StandaloneMysql; +use App\Models\StandalonePostgresql; +use App\Models\StandaloneRedis; +use App\Models\Tag; +use App\Models\Team; +use App\Support\ValidationPatterns; +use Illuminate\Console\Command; +use Illuminate\Support\Facades\Log; + +class CleanupNames extends Command +{ + protected $signature = 'cleanup:names + {--dry-run : Preview changes without applying them} + {--model= : Clean specific model (e.g., Project, Server)} + {--backup : Create database backup before changes} + {--force : Skip confirmation prompt}'; + + protected $description = 'Sanitize name fields by removing invalid characters (keeping only letters, numbers, spaces, dashes, underscores, dots, slashes, colons, parentheses)'; + + protected array $modelsToClean = [ + 'Project' => Project::class, + 'Environment' => Environment::class, + 'Application' => Application::class, + 'Service' => Service::class, + 'Server' => Server::class, + 'Team' => Team::class, + 'StandalonePostgresql' => StandalonePostgresql::class, + 'StandaloneMysql' => StandaloneMysql::class, + 'StandaloneRedis' => StandaloneRedis::class, + 'StandaloneMongodb' => StandaloneMongodb::class, + 'StandaloneMariadb' => StandaloneMariadb::class, + 'StandaloneKeydb' => StandaloneKeydb::class, + 'StandaloneDragonfly' => StandaloneDragonfly::class, + 'StandaloneClickhouse' => StandaloneClickhouse::class, + 'S3Storage' => S3Storage::class, + 'Tag' => Tag::class, + 'PrivateKey' => PrivateKey::class, + 'ScheduledTask' => ScheduledTask::class, + ]; + + protected array $changes = []; + + protected int $totalProcessed = 0; + + protected int $totalCleaned = 0; + + public function handle(): int + { + $this->info('🔍 Scanning for invalid characters in name fields...'); + + if ($this->option('backup') && ! $this->option('dry-run')) { + $this->createBackup(); + } + + $modelFilter = $this->option('model'); + $modelsToProcess = $modelFilter + ? [$modelFilter => $this->modelsToClean[$modelFilter] ?? null] + : $this->modelsToClean; + + if ($modelFilter && ! isset($this->modelsToClean[$modelFilter])) { + $this->error("❌ Unknown model: {$modelFilter}"); + $this->info('Available models: '.implode(', ', array_keys($this->modelsToClean))); + + return self::FAILURE; + } + + foreach ($modelsToProcess as $modelName => $modelClass) { + if (! $modelClass) { + continue; + } + $this->processModel($modelName, $modelClass); + } + + $this->displaySummary(); + + if (! $this->option('dry-run') && $this->totalCleaned > 0) { + $this->logChanges(); + } + + return self::SUCCESS; + } + + protected function processModel(string $modelName, string $modelClass): void + { + $this->info("\n📋 Processing {$modelName}..."); + + try { + $records = $modelClass::all(['id', 'name']); + $cleaned = 0; + + foreach ($records as $record) { + $this->totalProcessed++; + + $originalName = $record->name; + $sanitizedName = $this->sanitizeName($originalName); + + if ($sanitizedName !== $originalName) { + $this->changes[] = [ + 'model' => $modelName, + 'id' => $record->id, + 'original' => $originalName, + 'sanitized' => $sanitizedName, + 'timestamp' => now(), + ]; + + if (! $this->option('dry-run')) { + // Update without triggering events/mutators to avoid conflicts + $modelClass::where('id', $record->id)->update(['name' => $sanitizedName]); + } + + $cleaned++; + $this->totalCleaned++; + + $this->warn(" 🧹 {$modelName} #{$record->id}:"); + $this->line(' From: '.$this->truncate($originalName, 80)); + $this->line(' To: '.$this->truncate($sanitizedName, 80)); + } + } + + if ($cleaned > 0) { + $action = $this->option('dry-run') ? 'would be sanitized' : 'sanitized'; + $this->info(" ✅ {$cleaned}/{$records->count()} records {$action}"); + } else { + $this->info(' ✨ No invalid characters found'); + } + + } catch (\Exception $e) { + $this->error(" ❌ Error processing {$modelName}: ".$e->getMessage()); + } + } + + protected function sanitizeName(string $name): string + { + // Remove all characters that don't match the allowed pattern + // Use the shared ValidationPatterns to ensure consistency + $allowedPattern = str_replace(['/', '^', '$'], '', ValidationPatterns::NAME_PATTERN); + $sanitized = preg_replace('/[^'.$allowedPattern.']+/', '', $name); + + // Clean up excessive whitespace but preserve other allowed characters + $sanitized = preg_replace('/\s+/', ' ', $sanitized); + $sanitized = trim($sanitized); + + // If result is empty, provide a default name + if (empty($sanitized)) { + $sanitized = 'sanitized-item'; + } + + return $sanitized; + } + + protected function displaySummary(): void + { + $this->info("\n".str_repeat('=', 60)); + $this->info('📊 CLEANUP SUMMARY'); + $this->info(str_repeat('=', 60)); + + $this->line("Records processed: {$this->totalProcessed}"); + $this->line("Records with invalid characters: {$this->totalCleaned}"); + + if ($this->option('dry-run')) { + $this->warn("\n🔍 DRY RUN - No changes were made to the database"); + $this->info('Run without --dry-run to apply these changes'); + } else { + if ($this->totalCleaned > 0) { + $this->info("\n✅ Database successfully sanitized!"); + $this->info('Changes logged to storage/logs/name-cleanup.log'); + } else { + $this->info("\n✨ No cleanup needed - all names are valid!"); + } + } + } + + protected function logChanges(): void + { + $logFile = storage_path('logs/name-cleanup.log'); + $logData = [ + 'timestamp' => now()->toISOString(), + 'total_processed' => $this->totalProcessed, + 'total_cleaned' => $this->totalCleaned, + 'changes' => $this->changes, + ]; + + file_put_contents($logFile, json_encode($logData, JSON_PRETTY_PRINT)."\n", FILE_APPEND); + + Log::info('Name Sanitization completed', [ + 'total_processed' => $this->totalProcessed, + 'total_sanitized' => $this->totalCleaned, + 'changes_count' => count($this->changes), + ]); + } + + protected function createBackup(): void + { + $this->info('💾 Creating database backup...'); + + try { + $backupFile = storage_path('backups/name-cleanup-backup-'.now()->format('Y-m-d-H-i-s').'.sql'); + + // Ensure backup directory exists + if (! file_exists(dirname($backupFile))) { + mkdir(dirname($backupFile), 0755, true); + } + + $dbConfig = config('database.connections.'.config('database.default')); + $command = sprintf( + 'pg_dump -h %s -p %s -U %s -d %s > %s', + $dbConfig['host'], + $dbConfig['port'], + $dbConfig['username'], + $dbConfig['database'], + $backupFile + ); + + exec($command, $output, $returnCode); + + if ($returnCode === 0) { + $this->info("✅ Backup created: {$backupFile}"); + } else { + $this->warn('⚠️ Backup creation may have failed. Proceeding anyway...'); + } + } catch (\Exception $e) { + $this->warn('⚠️ Could not create backup: '.$e->getMessage()); + $this->warn('Proceeding without backup...'); + } + } + + protected function truncate(string $text, int $length): string + { + return strlen($text) > $length ? substr($text, 0, $length).'...' : $text; + } +} diff --git a/app/Console/Commands/Generate/Services.php b/app/Console/Commands/Generate/Services.php index 577e94ac8..42f9360bb 100644 --- a/app/Console/Commands/Generate/Services.php +++ b/app/Console/Commands/Generate/Services.php @@ -16,7 +16,7 @@ class Services extends Command /** * {@inheritdoc} */ - protected $description = 'Generate service-templates.yaml based on /templates/compose directory'; + protected $description = 'Generates service-templates json file based on /templates/compose directory'; public function handle(): int { @@ -33,7 +33,10 @@ class Services extends Command ]; })->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - file_put_contents(base_path('templates/service-templates.json'), $serviceTemplatesJson.PHP_EOL); + file_put_contents(base_path('templates/'.config('constants.services.file_name')), $serviceTemplatesJson.PHP_EOL); + + // Generate service-templates.json with SERVICE_URL changed to SERVICE_FQDN + $this->generateServiceTemplatesWithFqdn(); return self::SUCCESS; } @@ -71,6 +74,7 @@ class Services extends Command 'slogan' => $data->get('slogan', str($file)->headline()), 'compose' => $compose, 'tags' => $tags, + 'category' => $data->get('category'), 'logo' => $data->get('logo', 'svgs/default.webp'), 'minversion' => $data->get('minversion', '0.0.0'), ]; @@ -86,4 +90,145 @@ class Services extends Command return $payload; } + + private function generateServiceTemplatesWithFqdn(): void + { + $serviceTemplatesWithFqdn = collect(array_merge( + glob(base_path('templates/compose/*.yaml')), + glob(base_path('templates/compose/*.yml')) + )) + ->mapWithKeys(function ($file): array { + $file = basename($file); + $parsed = $this->processFileWithFqdn($file); + + return $parsed === false ? [] : [ + Arr::pull($parsed, 'name') => $parsed, + ]; + })->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + + file_put_contents(base_path('templates/service-templates.json'), $serviceTemplatesWithFqdn.PHP_EOL); + + // Generate service-templates-raw.json with non-base64 encoded compose content + // $this->generateServiceTemplatesRaw(); + } + + private function processFileWithFqdn(string $file): false|array + { + $content = file_get_contents(base_path("templates/compose/$file")); + + $data = collect(explode(PHP_EOL, $content))->mapWithKeys(function ($line): array { + preg_match('/^#(?<key>.*):(?<value>.*)$/U', $line, $m); + + return $m ? [trim($m['key']) => trim($m['value'])] : []; + }); + + if (str($data->get('ignore'))->toBoolean()) { + return false; + } + + $documentation = $data->get('documentation'); + $documentation = $documentation ? $documentation.'?utm_source=coolify.io' : 'https://coolify.io/docs'; + + // Replace SERVICE_URL with SERVICE_FQDN in the content + $modifiedContent = str_replace('SERVICE_URL', 'SERVICE_FQDN', $content); + + $json = Yaml::parse($modifiedContent); + $compose = base64_encode(Yaml::dump($json, 10, 2)); + + $tags = str($data->get('tags'))->lower()->explode(',')->map(fn ($tag) => trim($tag))->filter(); + $tags = $tags->isEmpty() ? null : $tags->all(); + + $payload = [ + 'name' => pathinfo($file, PATHINFO_FILENAME), + 'documentation' => $documentation, + 'slogan' => $data->get('slogan', str($file)->headline()), + 'compose' => $compose, + 'tags' => $tags, + 'category' => $data->get('category'), + 'logo' => $data->get('logo', 'svgs/default.webp'), + 'minversion' => $data->get('minversion', '0.0.0'), + ]; + + if ($port = $data->get('port')) { + $payload['port'] = $port; + } + + if ($envFile = $data->get('env_file')) { + $envFileContent = file_get_contents(base_path("templates/compose/$envFile")); + // Also replace SERVICE_URL with SERVICE_FQDN in env file content + $modifiedEnvContent = str_replace('SERVICE_URL', 'SERVICE_FQDN', $envFileContent); + $payload['envs'] = base64_encode($modifiedEnvContent); + } + + return $payload; + } + + private function generateServiceTemplatesRaw(): void + { + $serviceTemplatesRaw = collect(array_merge( + glob(base_path('templates/compose/*.yaml')), + glob(base_path('templates/compose/*.yml')) + )) + ->mapWithKeys(function ($file): array { + $file = basename($file); + $parsed = $this->processFileWithFqdnRaw($file); + + return $parsed === false ? [] : [ + Arr::pull($parsed, 'name') => $parsed, + ]; + })->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + + file_put_contents(base_path('templates/service-templates-raw.json'), $serviceTemplatesRaw.PHP_EOL); + } + + private function processFileWithFqdnRaw(string $file): false|array + { + $content = file_get_contents(base_path("templates/compose/$file")); + + $data = collect(explode(PHP_EOL, $content))->mapWithKeys(function ($line): array { + preg_match('/^#(?<key>.*):(?<value>.*)$/U', $line, $m); + + return $m ? [trim($m['key']) => trim($m['value'])] : []; + }); + + if (str($data->get('ignore'))->toBoolean()) { + return false; + } + + $documentation = $data->get('documentation'); + $documentation = $documentation ? $documentation.'?utm_source=coolify.io' : 'https://coolify.io/docs'; + + // Replace SERVICE_URL with SERVICE_FQDN in the content + $modifiedContent = str_replace('SERVICE_URL', 'SERVICE_FQDN', $content); + + $json = Yaml::parse($modifiedContent); + $compose = Yaml::dump($json, 10, 2); // Not base64 encoded + + $tags = str($data->get('tags'))->lower()->explode(',')->map(fn ($tag) => trim($tag))->filter(); + $tags = $tags->isEmpty() ? null : $tags->all(); + + $payload = [ + 'name' => pathinfo($file, PATHINFO_FILENAME), + 'documentation' => $documentation, + 'slogan' => $data->get('slogan', str($file)->headline()), + 'compose' => $compose, + 'tags' => $tags, + 'category' => $data->get('category'), + 'logo' => $data->get('logo', 'svgs/default.webp'), + 'minversion' => $data->get('minversion', '0.0.0'), + ]; + + if ($port = $data->get('port')) { + $payload['port'] = $port; + } + + if ($envFile = $data->get('env_file')) { + $envFileContent = file_get_contents(base_path("templates/compose/$envFile")); + // Also replace SERVICE_URL with SERVICE_FQDN in env file content (not base64 encoded) + $modifiedEnvContent = str_replace('SERVICE_URL', 'SERVICE_FQDN', $envFileContent); + $payload['envs'] = $modifiedEnvContent; + } + + return $payload; + } } diff --git a/app/Console/Commands/Init.php b/app/Console/Commands/Init.php index 1a7c0911f..b85829256 100644 --- a/app/Console/Commands/Init.php +++ b/app/Console/Commands/Init.php @@ -5,6 +5,7 @@ namespace App\Console\Commands; use App\Enums\ActivityTypes; use App\Enums\ApplicationDeploymentStatus; use App\Jobs\CheckHelperImageJob; +use App\Jobs\PullChangelogFromGitHub; use App\Models\ApplicationDeploymentQueue; use App\Models\Environment; use App\Models\ScheduledDatabaseBackup; @@ -52,6 +53,11 @@ class Init extends Command $this->call('cleanup:redis'); + try { + $this->call('cleanup:names'); + } catch (\Throwable $e) { + echo "Error in cleanup:names command: {$e->getMessage()}\n"; + } $this->call('cleanup:stucked-resources'); try { @@ -62,21 +68,43 @@ class Init extends Command if (isCloud()) { try { - $this->cleanupUnnecessaryDynamicProxyConfiguration(); + $this->cleanupInProgressApplicationDeployments(); + } catch (\Throwable $e) { + echo "Could not cleanup inprogress deployments: {$e->getMessage()}\n"; + } + + try { $this->pullTemplatesFromCDN(); } catch (\Throwable $e) { echo "Could not pull templates from CDN: {$e->getMessage()}\n"; } + try { + $this->pullChangelogFromGitHub(); + } catch (\Throwable $e) { + echo "Could not changelogs from github: {$e->getMessage()}\n"; + } + return; } try { $this->cleanupInProgressApplicationDeployments(); + } catch (\Throwable $e) { + echo "Could not cleanup inprogress deployments: {$e->getMessage()}\n"; + } + + try { $this->pullTemplatesFromCDN(); } catch (\Throwable $e) { echo "Could not pull templates from CDN: {$e->getMessage()}\n"; } + + try { + $this->pullChangelogFromGitHub(); + } catch (\Throwable $e) { + echo "Could not changelogs from github: {$e->getMessage()}\n"; + } try { $localhost = $this->servers->where('id', 0)->first(); $localhost->setupDynamicProxyConfiguration(); @@ -105,7 +133,17 @@ class Init extends Command $response = Http::retry(3, 1000)->get(config('constants.services.official')); if ($response->successful()) { $services = $response->json(); - File::put(base_path('templates/service-templates.json'), json_encode($services)); + File::put(base_path('templates/'.config('constants.services.file_name')), json_encode($services)); + } + } + + private function pullChangelogFromGitHub() + { + try { + PullChangelogFromGitHub::dispatch(); + echo "Changelog fetch initiated\n"; + } catch (\Throwable $e) { + echo "Could not fetch changelog from GitHub: {$e->getMessage()}\n"; } } diff --git a/app/Console/Commands/InitChangelog.php b/app/Console/Commands/InitChangelog.php new file mode 100644 index 000000000..f9eb12f04 --- /dev/null +++ b/app/Console/Commands/InitChangelog.php @@ -0,0 +1,98 @@ +<?php + +namespace App\Console\Commands; + +use Carbon\Carbon; +use Illuminate\Console\Command; + +class InitChangelog extends Command +{ + /** + * The name and signature of the console command. + * + * @var string + */ + protected $signature = 'changelog:init {month? : Month in YYYY-MM format (defaults to current month)}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Initialize a new monthly changelog file with example structure'; + + /** + * Execute the console command. + */ + public function handle() + { + $month = $this->argument('month') ?: Carbon::now()->format('Y-m'); + + // Validate month format + if (! preg_match('/^\d{4}-(0[1-9]|1[0-2])$/', $month)) { + $this->error('Invalid month format. Use YYYY-MM format with valid months 01-12 (e.g., 2025-08)'); + + return self::FAILURE; + } + + $changelogsDir = base_path('changelogs'); + $filePath = $changelogsDir."/{$month}.json"; + + // Create changelogs directory if it doesn't exist + if (! is_dir($changelogsDir)) { + mkdir($changelogsDir, 0755, true); + $this->info("Created changelogs directory: {$changelogsDir}"); + } + + // Check if file already exists + if (file_exists($filePath)) { + if (! $this->confirm("File {$month}.json already exists. Overwrite?")) { + $this->info('Operation cancelled'); + + return self::SUCCESS; + } + } + + // Parse the month for example data + $carbonMonth = Carbon::createFromFormat('Y-m', $month); + $monthName = $carbonMonth->format('F Y'); + $sampleDate = $carbonMonth->addDays(14)->toISOString(); // Mid-month + + // Get version from config + $version = 'v'.config('constants.coolify.version'); + + // Create example changelog structure + $exampleData = [ + 'entries' => [ + [ + 'version' => $version, + 'title' => 'Example Feature Release', + 'content' => "This is an example changelog entry for {$monthName}. Replace this with your actual release notes. Include details about new features, improvements, bug fixes, and any breaking changes.", + 'published_at' => $sampleDate, + ], + ], + ]; + + // Write the file + $jsonContent = json_encode($exampleData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + + if (file_put_contents($filePath, $jsonContent) === false) { + $this->error("Failed to create changelog file: {$filePath}"); + + return self::FAILURE; + } + + $this->info("✅ Created changelog file: changelogs/{$month}.json"); + $this->line(" Example entry created for {$monthName}"); + $this->line(' Edit the file to add your actual changelog entries'); + + // Show the file contents + if ($this->option('verbose')) { + $this->newLine(); + $this->line('File contents:'); + $this->line($jsonContent); + } + + return self::SUCCESS; + } +} diff --git a/app/Console/Commands/RunScheduledJobsManually.php b/app/Console/Commands/RunScheduledJobsManually.php index 1685d47cc..238bcbce3 100644 --- a/app/Console/Commands/RunScheduledJobsManually.php +++ b/app/Console/Commands/RunScheduledJobsManually.php @@ -13,6 +13,7 @@ class RunScheduledJobsManually extends Command { protected $signature = 'schedule:run-manual {--type=all : Type of jobs to run (all, backups, tasks)} + {--frequency= : Filter by frequency (daily, hourly, weekly, monthly, yearly, or cron expression)} {--chunk=5 : Number of jobs to process in each batch} {--delay=30 : Delay in seconds between batches} {--max= : Maximum number of jobs to process (useful for testing)} @@ -23,37 +24,52 @@ class RunScheduledJobsManually extends Command public function handle() { $type = $this->option('type'); + $frequency = $this->option('frequency'); $chunkSize = (int) $this->option('chunk'); $delay = (int) $this->option('delay'); $maxJobs = $this->option('max') ? (int) $this->option('max') : null; $dryRun = $this->option('dry-run'); $this->info('Starting manual execution of scheduled jobs...'.($dryRun ? ' (DRY RUN)' : '')); - $this->info("Type: {$type}, Chunk size: {$chunkSize}, Delay: {$delay}s".($maxJobs ? ", Max jobs: {$maxJobs}" : '').($dryRun ? ', Dry run: enabled' : '')); + $this->info("Type: {$type}".($frequency ? ", Frequency: {$frequency}" : '').", Chunk size: {$chunkSize}, Delay: {$delay}s".($maxJobs ? ", Max jobs: {$maxJobs}" : '').($dryRun ? ', Dry run: enabled' : '')); if ($dryRun) { $this->warn('DRY RUN MODE: No jobs will actually be dispatched'); } if ($type === 'all' || $type === 'backups') { - $this->runScheduledBackups($chunkSize, $delay, $maxJobs, $dryRun); + $this->runScheduledBackups($chunkSize, $delay, $maxJobs, $dryRun, $frequency); } if ($type === 'all' || $type === 'tasks') { - $this->runScheduledTasks($chunkSize, $delay, $maxJobs, $dryRun); + $this->runScheduledTasks($chunkSize, $delay, $maxJobs, $dryRun, $frequency); } $this->info('Completed manual execution of scheduled jobs.'.($dryRun ? ' (DRY RUN)' : '')); } - private function runScheduledBackups(int $chunkSize, int $delay, ?int $maxJobs = null, bool $dryRun = false): void + private function runScheduledBackups(int $chunkSize, int $delay, ?int $maxJobs = null, bool $dryRun = false, ?string $frequency = null): void { $this->info('Processing scheduled database backups...'); - $scheduled_backups = ScheduledDatabaseBackup::where('enabled', true)->get(); + $query = ScheduledDatabaseBackup::where('enabled', true); + + if ($frequency) { + $query->where(function ($q) use ($frequency) { + // Handle human-readable frequency strings + if (in_array($frequency, ['daily', 'hourly', 'weekly', 'monthly', 'yearly', 'every_minute'])) { + $q->where('frequency', $frequency); + } else { + // Handle cron expressions + $q->where('frequency', $frequency); + } + }); + } + + $scheduled_backups = $query->get(); if ($scheduled_backups->isEmpty()) { - $this->info('No enabled scheduled backups found.'); + $this->info('No enabled scheduled backups found'.($frequency ? " with frequency '{$frequency}'" : '').'.'); return; } @@ -96,7 +112,7 @@ class RunScheduledJobsManually extends Command $this->info("Limited to {$maxJobs} scheduled backups for testing"); } - $this->info("Found {$finalScheduledBackups->count()} valid scheduled backups to process"); + $this->info("Found {$finalScheduledBackups->count()} valid scheduled backups to process".($frequency ? " with frequency '{$frequency}'" : '')); $chunks = $finalScheduledBackups->chunk($chunkSize); foreach ($chunks as $index => $chunk) { @@ -105,10 +121,10 @@ class RunScheduledJobsManually extends Command foreach ($chunk as $scheduled_backup) { try { if ($dryRun) { - $this->info("🔍 Would dispatch backup job for: {$scheduled_backup->name} (ID: {$scheduled_backup->id})"); + $this->info("🔍 Would dispatch backup job for: {$scheduled_backup->name} (ID: {$scheduled_backup->id}, Frequency: {$scheduled_backup->frequency})"); } else { DatabaseBackupJob::dispatch($scheduled_backup); - $this->info("✓ Dispatched backup job for: {$scheduled_backup->name} (ID: {$scheduled_backup->id})"); + $this->info("✓ Dispatched backup job for: {$scheduled_backup->name} (ID: {$scheduled_backup->id}, Frequency: {$scheduled_backup->frequency})"); } } catch (\Exception $e) { $this->error("✗ Failed to dispatch backup job for {$scheduled_backup->id}: ".$e->getMessage()); @@ -123,14 +139,28 @@ class RunScheduledJobsManually extends Command } } - private function runScheduledTasks(int $chunkSize, int $delay, ?int $maxJobs = null, bool $dryRun = false): void + private function runScheduledTasks(int $chunkSize, int $delay, ?int $maxJobs = null, bool $dryRun = false, ?string $frequency = null): void { $this->info('Processing scheduled tasks...'); - $scheduled_tasks = ScheduledTask::where('enabled', true)->get(); + $query = ScheduledTask::where('enabled', true); + + if ($frequency) { + $query->where(function ($q) use ($frequency) { + // Handle human-readable frequency strings + if (in_array($frequency, ['daily', 'hourly', 'weekly', 'monthly', 'yearly', 'every_minute'])) { + $q->where('frequency', $frequency); + } else { + // Handle cron expressions + $q->where('frequency', $frequency); + } + }); + } + + $scheduled_tasks = $query->get(); if ($scheduled_tasks->isEmpty()) { - $this->info('No enabled scheduled tasks found.'); + $this->info('No enabled scheduled tasks found'.($frequency ? " with frequency '{$frequency}'" : '').'.'); return; } @@ -188,7 +218,7 @@ class RunScheduledJobsManually extends Command $this->info("Limited to {$maxJobs} scheduled tasks for testing"); } - $this->info("Found {$finalScheduledTasks->count()} valid scheduled tasks to process"); + $this->info("Found {$finalScheduledTasks->count()} valid scheduled tasks to process".($frequency ? " with frequency '{$frequency}'" : '')); $chunks = $finalScheduledTasks->chunk($chunkSize); foreach ($chunks as $index => $chunk) { @@ -197,10 +227,10 @@ class RunScheduledJobsManually extends Command foreach ($chunk as $scheduled_task) { try { if ($dryRun) { - $this->info("🔍 Would dispatch task job for: {$scheduled_task->name} (ID: {$scheduled_task->id})"); + $this->info("🔍 Would dispatch task job for: {$scheduled_task->name} (ID: {$scheduled_task->id}, Frequency: {$scheduled_task->frequency})"); } else { ScheduledTaskJob::dispatch($scheduled_task); - $this->info("✓ Dispatched task job for: {$scheduled_task->name} (ID: {$scheduled_task->id})"); + $this->info("✓ Dispatched task job for: {$scheduled_task->name} (ID: {$scheduled_task->id}, Frequency: {$scheduled_task->frequency})"); } } catch (\Exception $e) { $this->error("✗ Failed to dispatch task job for {$scheduled_task->id}: ".$e->getMessage()); diff --git a/app/Console/Commands/SyncBunny.php b/app/Console/Commands/SyncBunny.php index df1903828..6581bb587 100644 --- a/app/Console/Commands/SyncBunny.php +++ b/app/Console/Commands/SyncBunny.php @@ -45,7 +45,7 @@ class SyncBunny extends Command $install_script = 'install.sh'; $upgrade_script = 'upgrade.sh'; $production_env = '.env.production'; - $service_template = 'service-templates.json'; + $service_template = config('constants.services.file_name'); $versions = 'versions.json'; $compose_file_location = "$parent_dir/$compose_file"; @@ -102,7 +102,7 @@ class SyncBunny extends Command } } if ($only_template) { - $this->info('About to sync service-templates.json to BunnyCDN.'); + $this->info('About to sync '.config('constants.services.file_name').' to BunnyCDN.'); $confirmed = confirm('Are you sure you want to sync?'); if (! $confirmed) { return; diff --git a/app/Console/Commands/ViewScheduledLogs.php b/app/Console/Commands/ViewScheduledLogs.php new file mode 100644 index 000000000..9ecf90716 --- /dev/null +++ b/app/Console/Commands/ViewScheduledLogs.php @@ -0,0 +1,278 @@ +<?php + +namespace App\Console\Commands; + +use Illuminate\Console\Command; +use Illuminate\Support\Facades\File; + +class ViewScheduledLogs extends Command +{ + protected $signature = 'logs:scheduled + {--lines=50 : Number of lines to display} + {--follow : Follow the log file (tail -f)} + {--date= : Specific date (Y-m-d format, defaults to today)} + {--task-name= : Filter by task name (partial match)} + {--task-id= : Filter by task ID} + {--backup-name= : Filter by backup name (partial match)} + {--backup-id= : Filter by backup ID} + {--errors : View error logs only} + {--all : View both normal and error logs} + {--hourly : Filter hourly jobs} + {--daily : Filter daily jobs} + {--weekly : Filter weekly jobs} + {--monthly : Filter monthly jobs} + {--frequency= : Filter by specific cron expression}'; + + protected $description = 'View scheduled backups and tasks logs with optional filtering'; + + public function handle() + { + $date = $this->option('date') ?: now()->format('Y-m-d'); + $logPaths = $this->getLogPaths($date); + + if (empty($logPaths)) { + $this->showAvailableLogFiles($date); + + return; + } + + $lines = $this->option('lines'); + $follow = $this->option('follow'); + + // Build grep filters + $filters = $this->buildFilters(); + $filterDescription = $this->getFilterDescription(); + $logTypeDescription = $this->getLogTypeDescription(); + + if ($follow) { + $this->info("Following {$logTypeDescription} logs for {$date}{$filterDescription} (Press Ctrl+C to stop)..."); + $this->line(''); + + if (count($logPaths) === 1) { + $logPath = $logPaths[0]; + if ($filters) { + passthru("tail -f {$logPath} | grep -E '{$filters}'"); + } else { + passthru("tail -f {$logPath}"); + } + } else { + // Multiple files - use multitail or tail with process substitution + $logPathsStr = implode(' ', $logPaths); + if ($filters) { + passthru("tail -f {$logPathsStr} | grep -E '{$filters}'"); + } else { + passthru("tail -f {$logPathsStr}"); + } + } + } else { + $this->info("Showing last {$lines} lines of {$logTypeDescription} logs for {$date}{$filterDescription}:"); + $this->line(''); + + if (count($logPaths) === 1) { + $logPath = $logPaths[0]; + if ($filters) { + passthru("tail -n {$lines} {$logPath} | grep -E '{$filters}'"); + } else { + passthru("tail -n {$lines} {$logPath}"); + } + } else { + // Multiple files - concatenate and sort by timestamp + $logPathsStr = implode(' ', $logPaths); + if ($filters) { + passthru("tail -n {$lines} {$logPathsStr} | sort | grep -E '{$filters}'"); + } else { + passthru("tail -n {$lines} {$logPathsStr} | sort"); + } + } + } + } + + private function getLogPaths(string $date): array + { + $paths = []; + + if ($this->option('errors')) { + // Error logs only + $errorPath = storage_path("logs/scheduled-errors-{$date}.log"); + if (File::exists($errorPath)) { + $paths[] = $errorPath; + } + } elseif ($this->option('all')) { + // Both normal and error logs + $normalPath = storage_path("logs/scheduled-{$date}.log"); + $errorPath = storage_path("logs/scheduled-errors-{$date}.log"); + + if (File::exists($normalPath)) { + $paths[] = $normalPath; + } + if (File::exists($errorPath)) { + $paths[] = $errorPath; + } + } else { + // Normal logs only (default) + $normalPath = storage_path("logs/scheduled-{$date}.log"); + if (File::exists($normalPath)) { + $paths[] = $normalPath; + } + } + + return $paths; + } + + private function showAvailableLogFiles(string $date): void + { + $logType = $this->getLogTypeDescription(); + $this->warn("No {$logType} logs found for date {$date}"); + + // Show available log files + $normalFiles = File::glob(storage_path('logs/scheduled-*.log')); + $errorFiles = File::glob(storage_path('logs/scheduled-errors-*.log')); + + if (! empty($normalFiles) || ! empty($errorFiles)) { + $this->info('Available scheduled log files:'); + + if (! empty($normalFiles)) { + $this->line(' Normal logs:'); + foreach ($normalFiles as $file) { + $basename = basename($file); + $this->line(" - {$basename}"); + } + } + + if (! empty($errorFiles)) { + $this->line(' Error logs:'); + foreach ($errorFiles as $file) { + $basename = basename($file); + $this->line(" - {$basename}"); + } + } + } + } + + private function getLogTypeDescription(): string + { + if ($this->option('errors')) { + return 'error'; + } elseif ($this->option('all')) { + return 'all'; + } else { + return 'normal'; + } + } + + private function buildFilters(): ?string + { + $filters = []; + + if ($taskName = $this->option('task-name')) { + $filters[] = '"task_name":"[^"]*'.preg_quote($taskName, '/').'[^"]*"'; + } + + if ($taskId = $this->option('task-id')) { + $filters[] = '"task_id":'.preg_quote($taskId, '/'); + } + + if ($backupName = $this->option('backup-name')) { + $filters[] = '"backup_name":"[^"]*'.preg_quote($backupName, '/').'[^"]*"'; + } + + if ($backupId = $this->option('backup-id')) { + $filters[] = '"backup_id":'.preg_quote($backupId, '/'); + } + + // Frequency filters + if ($this->option('hourly')) { + $filters[] = $this->getFrequencyPattern('hourly'); + } + + if ($this->option('daily')) { + $filters[] = $this->getFrequencyPattern('daily'); + } + + if ($this->option('weekly')) { + $filters[] = $this->getFrequencyPattern('weekly'); + } + + if ($this->option('monthly')) { + $filters[] = $this->getFrequencyPattern('monthly'); + } + + if ($frequency = $this->option('frequency')) { + $filters[] = '"frequency":"'.preg_quote($frequency, '/').'"'; + } + + return empty($filters) ? null : implode('|', $filters); + } + + private function getFrequencyPattern(string $type): string + { + $patterns = [ + 'hourly' => [ + '0 \* \* \* \*', // 0 * * * * + '@hourly', // @hourly + ], + 'daily' => [ + '0 0 \* \* \*', // 0 0 * * * + '@daily', // @daily + '@midnight', // @midnight + ], + 'weekly' => [ + '0 0 \* \* [0-6]', // 0 0 * * 0-6 (any day of week) + '@weekly', // @weekly + ], + 'monthly' => [ + '0 0 1 \* \*', // 0 0 1 * * (first of month) + '@monthly', // @monthly + ], + ]; + + $typePatterns = $patterns[$type] ?? []; + + // For grep, we need to match the frequency field in JSON + return '"frequency":"('.implode('|', $typePatterns).')"'; + } + + private function getFilterDescription(): string + { + $descriptions = []; + + if ($taskName = $this->option('task-name')) { + $descriptions[] = "task name: {$taskName}"; + } + + if ($taskId = $this->option('task-id')) { + $descriptions[] = "task ID: {$taskId}"; + } + + if ($backupName = $this->option('backup-name')) { + $descriptions[] = "backup name: {$backupName}"; + } + + if ($backupId = $this->option('backup-id')) { + $descriptions[] = "backup ID: {$backupId}"; + } + + // Frequency filters + if ($this->option('hourly')) { + $descriptions[] = 'hourly jobs'; + } + + if ($this->option('daily')) { + $descriptions[] = 'daily jobs'; + } + + if ($this->option('weekly')) { + $descriptions[] = 'weekly jobs'; + } + + if ($this->option('monthly')) { + $descriptions[] = 'monthly jobs'; + } + + if ($frequency = $this->option('frequency')) { + $descriptions[] = "frequency: {$frequency}"; + } + + return empty($descriptions) ? '' : ' (filtered by '.implode(', ', $descriptions).')'; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 395c58dee..c5c4d7e7f 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -6,23 +6,17 @@ use App\Jobs\CheckAndStartSentinelJob; use App\Jobs\CheckForUpdatesJob; use App\Jobs\CheckHelperImageJob; use App\Jobs\CleanupInstanceStuffsJob; -use App\Jobs\DatabaseBackupJob; -use App\Jobs\DockerCleanupJob; +use App\Jobs\PullChangelogFromGitHub; use App\Jobs\PullTemplatesFromCDN; use App\Jobs\RegenerateSslCertJob; -use App\Jobs\ScheduledTaskJob; -use App\Jobs\ServerCheckJob; -use App\Jobs\ServerPatchCheckJob; -use App\Jobs\ServerStorageCheckJob; +use App\Jobs\ScheduledJobManager; +use App\Jobs\ServerManagerJob; use App\Jobs\UpdateCoolifyJob; use App\Models\InstanceSettings; -use App\Models\ScheduledDatabaseBackup; -use App\Models\ScheduledTask; use App\Models\Server; use App\Models\Team; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; -use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Log; class Kernel extends ConsoleKernel @@ -61,10 +55,10 @@ class Kernel extends ConsoleKernel $this->scheduleInstance->job(new CheckHelperImageJob)->everyTenMinutes()->onOneServer(); // Server Jobs - $this->checkResources(); + $this->scheduleInstance->job(new ServerManagerJob)->everyMinute()->onOneServer(); - $this->checkScheduledBackups(); - $this->checkScheduledTasks(); + // Scheduled Jobs (Backups & Tasks) + $this->scheduleInstance->job(new ScheduledJobManager)->everyMinute()->onOneServer(); $this->scheduleInstance->command('uploads:clear')->everyTwoMinutes(); @@ -74,17 +68,18 @@ class Kernel extends ConsoleKernel $this->scheduleInstance->command('cleanup:unreachable-servers')->daily()->onOneServer(); $this->scheduleInstance->job(new PullTemplatesFromCDN)->cron($this->updateCheckFrequency)->timezone($this->instanceTimezone)->onOneServer(); + $this->scheduleInstance->job(new PullChangelogFromGitHub)->cron($this->updateCheckFrequency)->timezone($this->instanceTimezone)->onOneServer(); $this->scheduleInstance->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer(); $this->scheduleUpdates(); // Server Jobs - $this->checkResources(); + $this->scheduleInstance->job(new ServerManagerJob)->everyMinute()->onOneServer(); $this->pullImages(); - $this->checkScheduledBackups(); - $this->checkScheduledTasks(); + // Scheduled Jobs (Backups & Tasks) + $this->scheduleInstance->job(new ScheduledJobManager)->everyMinute()->onOneServer(); $this->scheduleInstance->job(new RegenerateSslCertJob)->twiceDaily(); @@ -135,182 +130,6 @@ class Kernel extends ConsoleKernel } } - private function checkResources(): void - { - if (isCloud()) { - $servers = $this->allServers->whereRelation('team.subscription', 'stripe_invoice_paid', true)->get(); - $own = Team::find(0)->servers; - $servers = $servers->merge($own); - } else { - $servers = $this->allServers->get(); - } - - foreach ($servers as $server) { - try { - $serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone); - if (validate_timezone($serverTimezone) === false) { - $serverTimezone = config('app.timezone'); - } - - // Sentinel check - $lastSentinelUpdate = $server->sentinel_updated_at; - if (Carbon::parse($lastSentinelUpdate)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) { - // Check container status every minute if Sentinel does not activated - if (isCloud()) { - $this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyFiveMinutes()->onOneServer(); - } else { - $this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyMinute()->onOneServer(); - } - // $this->scheduleInstance->job(new \App\Jobs\ServerCheckNewJob($server))->everyFiveMinutes()->onOneServer(); - - $serverDiskUsageCheckFrequency = data_get($server->settings, 'server_disk_usage_check_frequency', '0 * * * *'); - if (isset(VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency])) { - $serverDiskUsageCheckFrequency = VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency]; - } - $this->scheduleInstance->job(new ServerStorageCheckJob($server))->cron($serverDiskUsageCheckFrequency)->timezone($serverTimezone)->onOneServer(); - } - - $dockerCleanupFrequency = data_get($server->settings, 'docker_cleanup_frequency', '0 * * * *'); - if (isset(VALID_CRON_STRINGS[$dockerCleanupFrequency])) { - $dockerCleanupFrequency = VALID_CRON_STRINGS[$dockerCleanupFrequency]; - } - $this->scheduleInstance->job(new DockerCleanupJob($server))->cron($dockerCleanupFrequency)->timezone($serverTimezone)->onOneServer(); - - // Server patch check - weekly - $this->scheduleInstance->job(new ServerPatchCheckJob($server))->weekly()->timezone($serverTimezone)->onOneServer(); - - // Cleanup multiplexed connections every hour - // $this->scheduleInstance->job(new ServerCleanupMux($server))->hourly()->onOneServer(); - - // Temporary solution until we have better memory management for Sentinel - if ($server->isSentinelEnabled()) { - $this->scheduleInstance->job(function () use ($server) { - $server->restartContainer('coolify-sentinel'); - })->daily()->onOneServer(); - } - } catch (\Exception $e) { - Log::error('Error checking resources: '.$e->getMessage()); - } - } - } - - private function checkScheduledBackups(): void - { - $scheduled_backups = ScheduledDatabaseBackup::where('enabled', true)->get(); - if ($scheduled_backups->isEmpty()) { - return; - } - $finalScheduledBackups = collect(); - foreach ($scheduled_backups as $scheduled_backup) { - if (blank(data_get($scheduled_backup, 'database'))) { - $scheduled_backup->delete(); - - continue; - } - $server = $scheduled_backup->server(); - if (blank($server)) { - $scheduled_backup->delete(); - - continue; - } - if ($server->isFunctional() === false) { - continue; - } - if (isCloud() && data_get($server->team->subscription, 'stripe_invoice_paid', false) === false && $server->team->id !== 0) { - continue; - } - $finalScheduledBackups->push($scheduled_backup); - } - - foreach ($finalScheduledBackups as $scheduled_backup) { - try { - if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) { - $scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency]; - } - $server = $scheduled_backup->server(); - $serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone); - - if (validate_timezone($serverTimezone) === false) { - $serverTimezone = config('app.timezone'); - } - - if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) { - $scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency]; - } - $serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone); - $this->scheduleInstance->job(new DatabaseBackupJob( - backup: $scheduled_backup - ))->cron($scheduled_backup->frequency)->timezone($serverTimezone)->onOneServer(); - } catch (\Exception $e) { - Log::error('Error scheduling backup: '.$e->getMessage()); - Log::error($e->getTraceAsString()); - } - } - } - - private function checkScheduledTasks(): void - { - $scheduled_tasks = ScheduledTask::where('enabled', true)->get(); - if ($scheduled_tasks->isEmpty()) { - return; - } - $finalScheduledTasks = collect(); - foreach ($scheduled_tasks as $scheduled_task) { - $service = $scheduled_task->service; - $application = $scheduled_task->application; - - $server = $scheduled_task->server(); - if (blank($server)) { - $scheduled_task->delete(); - - continue; - } - - if ($server->isFunctional() === false) { - continue; - } - - if (isCloud() && data_get($server->team->subscription, 'stripe_invoice_paid', false) === false && $server->team->id !== 0) { - continue; - } - - if (! $service && ! $application) { - $scheduled_task->delete(); - - continue; - } - - if ($application && str($application->status)->contains('running') === false) { - continue; - } - if ($service && str($service->status)->contains('running') === false) { - continue; - } - - $finalScheduledTasks->push($scheduled_task); - } - - foreach ($finalScheduledTasks as $scheduled_task) { - try { - $server = $scheduled_task->server(); - if (isset(VALID_CRON_STRINGS[$scheduled_task->frequency])) { - $scheduled_task->frequency = VALID_CRON_STRINGS[$scheduled_task->frequency]; - } - $serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone); - - if (validate_timezone($serverTimezone) === false) { - $serverTimezone = config('app.timezone'); - } - $this->scheduleInstance->job(new ScheduledTaskJob( - task: $scheduled_task - ))->cron($scheduled_task->frequency)->timezone($serverTimezone)->onOneServer(); - } catch (\Exception $e) { - Log::error('Error scheduling task: '.$e->getMessage()); - Log::error($e->getTraceAsString()); - } - } - } - protected function commands(): void { $this->load(__DIR__.'/Commands'); diff --git a/app/Events/BackupCreated.php b/app/Events/BackupCreated.php index bc1ecee0d..9670f5c3c 100644 --- a/app/Events/BackupCreated.php +++ b/app/Events/BackupCreated.php @@ -7,8 +7,9 @@ use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; +use Laravel\Horizon\Contracts\Silenced; -class BackupCreated implements ShouldBroadcast +class BackupCreated implements ShouldBroadcast, Silenced { use Dispatchable, InteractsWithSockets, SerializesModels; diff --git a/app/Events/SentinelRestarted.php b/app/Events/SentinelRestarted.php new file mode 100644 index 000000000..9ddc3a07f --- /dev/null +++ b/app/Events/SentinelRestarted.php @@ -0,0 +1,39 @@ +<?php + +namespace App\Events; + +use App\Models\Server; +use Illuminate\Broadcasting\InteractsWithSockets; +use Illuminate\Broadcasting\PrivateChannel; +use Illuminate\Contracts\Broadcasting\ShouldBroadcast; +use Illuminate\Foundation\Events\Dispatchable; +use Illuminate\Queue\SerializesModels; + +class SentinelRestarted implements ShouldBroadcast +{ + use Dispatchable, InteractsWithSockets, SerializesModels; + + public ?int $teamId = null; + + public ?string $version = null; + + public string $serverUuid; + + public function __construct(Server $server, ?string $version = null) + { + $this->teamId = $server->team_id; + $this->serverUuid = $server->uuid; + $this->version = $version; + } + + public function broadcastOn(): array + { + if (is_null($this->teamId)) { + return []; + } + + return [ + new PrivateChannel("team.{$this->teamId}"), + ]; + } +} diff --git a/app/Events/ServiceChecked.php b/app/Events/ServiceChecked.php index 3f130a0fb..86a27a892 100644 --- a/app/Events/ServiceChecked.php +++ b/app/Events/ServiceChecked.php @@ -7,8 +7,9 @@ use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; +use Laravel\Horizon\Contracts\Silenced; -class ServiceChecked implements ShouldBroadcast +class ServiceChecked implements ShouldBroadcast, Silenced { use Dispatchable, InteractsWithSockets, SerializesModels; diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 8c89bb07f..275de57c0 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -53,6 +53,35 @@ class Handler extends ExceptionHandler return redirect()->guest($exception->redirectTo($request) ?? route('login')); } + /** + * Render an exception into an HTTP response. + */ + public function render($request, Throwable $e) + { + // Handle authorization exceptions for API routes + if ($e instanceof \Illuminate\Auth\Access\AuthorizationException) { + if ($request->is('api/*') || $request->expectsJson()) { + // Get the custom message from the policy if available + $message = $e->getMessage(); + + // Clean up the message for API responses (remove HTML tags if present) + $message = strip_tags(str_replace('<br/>', ' ', $message)); + + // If no custom message, use a default one + if (empty($message) || $message === 'This action is unauthorized.') { + $message = 'You are not authorized to perform this action.'; + } + + return response()->json([ + 'message' => $message, + 'error' => 'Unauthorized', + ], 403); + } + } + + return parent::render($request, $e); + } + /** * Register the exception handling callbacks for the application. */ diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index 0860c7133..c07ac354d 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -15,6 +15,8 @@ use App\Models\PrivateKey; use App\Models\Project; use App\Models\Server; use App\Models\Service; +use App\Rules\ValidGitBranch; +use App\Rules\ValidGitRepositoryUrl; use Illuminate\Http\Request; use Illuminate\Validation\Rule; use OpenApi\Attributes as OA; @@ -738,6 +740,8 @@ class ApplicationsController extends Controller return invalidTokenResponse(); } + $this->authorize('create', Application::class); + $return = validateIncomingRequest($request); if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; @@ -831,8 +835,8 @@ class ApplicationsController extends Controller $destination = $destinations->first(); if ($type === 'public') { $validationRules = [ - 'git_repository' => 'string|required', - 'git_branch' => 'string|required', + 'git_repository' => ['string', 'required', new ValidGitRepositoryUrl], + 'git_branch' => ['string', 'required', new ValidGitBranch], 'build_pack' => ['required', Rule::enum(BuildPackTypes::class)], 'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required', 'docker_compose_location' => 'string', @@ -883,7 +887,7 @@ class ApplicationsController extends Controller $application->source_type = GithubApp::class; $application->source_id = GithubApp::find(0)->id; } - $application->git_repository = $repository_url_parsed->getSegment(1).'/'.$repository_url_parsed->getSegment(2); + $application->git_repository = str($repository_url_parsed->getSegment(1).'/'.$repository_url_parsed->getSegment(2))->trim()->toString(); $application->fqdn = $fqdn; $application->destination_id = $destination->id; $application->destination_type = $destination->getMorphClass(); @@ -935,7 +939,7 @@ class ApplicationsController extends Controller } elseif ($type === 'private-gh-app') { $validationRules = [ 'git_repository' => 'string|required', - 'git_branch' => 'string|required', + 'git_branch' => ['string', 'required', new ValidGitBranch], 'build_pack' => ['required', Rule::enum(BuildPackTypes::class)], 'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required', 'github_app_uuid' => 'string|required', @@ -1043,7 +1047,7 @@ class ApplicationsController extends Controller $application->docker_compose_domains = $dockerComposeDomainsJson; } $application->fqdn = $fqdn; - $application->git_repository = $gitRepository; + $application->git_repository = str($gitRepository)->trim()->toString(); $application->destination_id = $destination->id; $application->destination_type = $destination->getMorphClass(); $application->environment_id = $environment->id; @@ -1090,8 +1094,8 @@ class ApplicationsController extends Controller } elseif ($type === 'private-deploy-key') { $validationRules = [ - 'git_repository' => 'string|required', - 'git_branch' => 'string|required', + 'git_repository' => ['string', 'required', new ValidGitRepositoryUrl], + 'git_branch' => ['string', 'required', new ValidGitBranch], 'build_pack' => ['required', Rule::enum(BuildPackTypes::class)], 'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required', 'private_key_uuid' => 'string|required', @@ -1519,6 +1523,8 @@ class ApplicationsController extends Controller return response()->json(['message' => 'Application not found.'], 404); } + $this->authorize('view', $application); + return response()->json($this->removeSensitiveData($application)); } @@ -1697,12 +1703,14 @@ class ApplicationsController extends Controller ], 404); } + $this->authorize('delete', $application); + DeleteResourceJob::dispatch( resource: $application, - deleteConfigurations: $request->query->get('delete_configurations', true), deleteVolumes: $request->query->get('delete_volumes', true), - dockerCleanup: $request->query->get('docker_cleanup', true), - deleteConnectedNetworks: $request->query->get('delete_connected_networks', true) + deleteConnectedNetworks: $request->query->get('delete_connected_networks', true), + deleteConfigurations: $request->query->get('delete_configurations', true), + dockerCleanup: $request->query->get('docker_cleanup', true) ); return response()->json([ @@ -1854,6 +1862,9 @@ class ApplicationsController extends Controller 'message' => 'Application not found', ], 404); } + + $this->authorize('update', $application); + $server = $application->destination->server; $allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network']; @@ -2138,6 +2149,9 @@ class ApplicationsController extends Controller 'message' => 'Application not found', ], 404); } + + $this->authorize('view', $application); + $envs = $application->environment_variables->sortBy('id')->merge($application->environment_variables_preview->sortBy('id')); $envs = $envs->map(function ($env) { @@ -2252,6 +2266,9 @@ class ApplicationsController extends Controller 'message' => 'Application not found', ], 404); } + + $this->authorize('manageEnvironment', $application); + $validator = customApiValidator($request->all(), [ 'key' => 'string|required', 'value' => 'string|nullable', @@ -2442,6 +2459,8 @@ class ApplicationsController extends Controller ], 404); } + $this->authorize('manageEnvironment', $application); + $bulk_data = $request->get('data'); if (! $bulk_data) { return response()->json([ @@ -2626,6 +2645,9 @@ class ApplicationsController extends Controller 'message' => 'Application not found', ], 404); } + + $this->authorize('manageEnvironment', $application); + $validator = customApiValidator($request->all(), [ 'key' => 'string|required', 'value' => 'string|nullable', @@ -2776,6 +2798,9 @@ class ApplicationsController extends Controller 'message' => 'Application not found.', ], 404); } + + $this->authorize('manageEnvironment', $application); + $found_env = EnvironmentVariable::where('uuid', $request->env_uuid) ->where('resourceable_type', Application::class) ->where('resourceable_id', $application->id) @@ -2879,6 +2904,8 @@ class ApplicationsController extends Controller return response()->json(['message' => 'Application not found.'], 404); } + $this->authorize('deploy', $application); + $deployment_uuid = new Cuid2; $result = queue_application_deployment( @@ -2971,6 +2998,9 @@ class ApplicationsController extends Controller if (! $application) { return response()->json(['message' => 'Application not found.'], 404); } + + $this->authorize('deploy', $application); + StopApplication::dispatch($application); return response()->json( @@ -3048,6 +3078,8 @@ class ApplicationsController extends Controller return response()->json(['message' => 'Application not found.'], 404); } + $this->authorize('deploy', $application); + $deployment_uuid = new Cuid2; $result = queue_application_deployment( diff --git a/app/Http/Controllers/Api/DatabasesController.php b/app/Http/Controllers/Api/DatabasesController.php index 504665f6a..389d119bd 100644 --- a/app/Http/Controllers/Api/DatabasesController.php +++ b/app/Http/Controllers/Api/DatabasesController.php @@ -12,6 +12,7 @@ use App\Http\Controllers\Controller; use App\Jobs\DeleteResourceJob; use App\Models\Project; use App\Models\Server; +use App\Models\StandalonePostgresql; use Illuminate\Http\Request; use OpenApi\Attributes as OA; @@ -143,6 +144,8 @@ class DatabasesController extends Controller return response()->json(['message' => 'Database not found.'], 404); } + $this->authorize('view', $database); + return response()->json($this->removeSensitiveData($database)); } @@ -276,6 +279,9 @@ class DatabasesController extends Controller if (! $database) { return response()->json(['message' => 'Database not found.'], 404); } + + $this->authorize('update', $database); + if ($request->is_public && $request->public_port) { if (isPublicPortAlreadyUsed($database->destination->server, $request->public_port, $database->id)) { return response()->json(['message' => 'Public port already used by another database.'], 400); @@ -1028,6 +1034,9 @@ class DatabasesController extends Controller return invalidTokenResponse(); } + // Use a generic authorization for database creation - using PostgreSQL as representative model + $this->authorize('create', StandalonePostgresql::class); + $return = validateIncomingRequest($request); if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; @@ -1606,12 +1615,14 @@ class DatabasesController extends Controller return response()->json(['message' => 'Database not found.'], 404); } + $this->authorize('delete', $database); + DeleteResourceJob::dispatch( resource: $database, - deleteConfigurations: $request->query->get('delete_configurations', true), deleteVolumes: $request->query->get('delete_volumes', true), - dockerCleanup: $request->query->get('docker_cleanup', true), - deleteConnectedNetworks: $request->query->get('delete_connected_networks', true) + deleteConnectedNetworks: $request->query->get('delete_connected_networks', true), + deleteConfigurations: $request->query->get('delete_configurations', true), + dockerCleanup: $request->query->get('docker_cleanup', true) ); return response()->json([ @@ -1684,6 +1695,9 @@ class DatabasesController extends Controller if (! $database) { return response()->json(['message' => 'Database not found.'], 404); } + + $this->authorize('manage', $database); + if (str($database->status)->contains('running')) { return response()->json(['message' => 'Database is already running.'], 400); } @@ -1762,6 +1776,9 @@ class DatabasesController extends Controller if (! $database) { return response()->json(['message' => 'Database not found.'], 404); } + + $this->authorize('manage', $database); + if (str($database->status)->contains('stopped') || str($database->status)->contains('exited')) { return response()->json(['message' => 'Database is already stopped.'], 400); } @@ -1840,6 +1857,9 @@ class DatabasesController extends Controller if (! $database) { return response()->json(['message' => 'Database not found.'], 404); } + + $this->authorize('manage', $database); + RestartDatabase::dispatch($database); return response()->json( diff --git a/app/Http/Controllers/Api/DeployController.php b/app/Http/Controllers/Api/DeployController.php index 5c7f20902..b87420f72 100644 --- a/app/Http/Controllers/Api/DeployController.php +++ b/app/Http/Controllers/Api/DeployController.php @@ -299,6 +299,12 @@ class DeployController extends Controller } switch ($resource?->getMorphClass()) { case Application::class: + // Check authorization for application deployment + try { + $this->authorize('deploy', $resource); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + return ['message' => 'Unauthorized to deploy this application.', 'deployment_uuid' => null]; + } $deployment_uuid = new Cuid2; $result = queue_application_deployment( application: $resource, @@ -313,11 +319,22 @@ class DeployController extends Controller } break; case Service::class: + // Check authorization for service deployment + try { + $this->authorize('deploy', $resource); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + return ['message' => 'Unauthorized to deploy this service.', 'deployment_uuid' => null]; + } StartService::run($resource); $message = "Service {$resource->name} started. It could take a while, be patient."; break; default: - // Database resource + // Database resource - check authorization + try { + $this->authorize('manage', $resource); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + return ['message' => 'Unauthorized to start this database.', 'deployment_uuid' => null]; + } StartDatabase::dispatch($resource); $resource->started_at ??= now(); @@ -423,6 +440,10 @@ class DeployController extends Controller if (is_null($application)) { return response()->json(['message' => 'Application not found'], 404); } + + // Check authorization to view application deployments + $this->authorize('view', $application); + $deployments = $application->deployments($skip, $take); return response()->json($deployments); diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 98637c3e8..e688b8980 100644 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -4,7 +4,9 @@ namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use App\Models\Project; +use App\Support\ValidationPatterns; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Validator; use OpenApi\Attributes as OA; class ProjectController extends Controller @@ -227,10 +229,10 @@ class ProjectController extends Controller if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; } - $validator = customApiValidator($request->all(), [ - 'name' => 'string|max:255|required', - 'description' => 'string|nullable', - ]); + $validator = Validator::make($request->all(), [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + ], ValidationPatterns::combinedMessages()); $extraFields = array_diff(array_keys($request->all()), $allowedFields); if ($validator->fails() || ! empty($extraFields)) { @@ -337,10 +339,10 @@ class ProjectController extends Controller if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; } - $validator = customApiValidator($request->all(), [ - 'name' => 'string|max:255|nullable', - 'description' => 'string|nullable', - ]); + $validator = Validator::make($request->all(), [ + 'name' => ValidationPatterns::nameRules(required: false), + 'description' => ValidationPatterns::descriptionRules(), + ], ValidationPatterns::combinedMessages()); $extraFields = array_diff(array_keys($request->all()), $allowedFields); if ($validator->fails() || ! empty($extraFields)) { @@ -447,4 +449,255 @@ class ProjectController extends Controller return response()->json(['message' => 'Project deleted.']); } + + #[OA\Get( + summary: 'List Environments', + description: 'List all environments in a project.', + path: '/projects/{uuid}/environments', + operationId: 'get-environments', + security: [ + ['bearerAuth' => []], + ], + tags: ['Projects'], + parameters: [ + new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')), + ], + responses: [ + new OA\Response( + response: 200, + description: 'List of environments', + content: [ + new OA\MediaType( + mediaType: 'application/json', + schema: new OA\Schema( + type: 'array', + items: new OA\Items(ref: '#/components/schemas/Environment') + ) + ), + ]), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + ref: '#/components/responses/400', + ), + new OA\Response( + response: 404, + description: 'Project not found.', + ), + ] + )] + public function get_environments(Request $request) + { + $teamId = getTeamIdFromToken(); + if (is_null($teamId)) { + return invalidTokenResponse(); + } + + if (! $request->uuid) { + return response()->json(['message' => 'Project UUID is required.'], 422); + } + + $project = Project::whereTeamId($teamId)->whereUuid($request->uuid)->first(); + if (! $project) { + return response()->json(['message' => 'Project not found.'], 404); + } + + $environments = $project->environments()->select('id', 'name', 'uuid')->get(); + + return response()->json(serializeApiResponse($environments)); + } + + #[OA\Post( + summary: 'Create Environment', + description: 'Create environment in project.', + path: '/projects/{uuid}/environments', + operationId: 'create-environment', + security: [ + ['bearerAuth' => []], + ], + tags: ['Projects'], + parameters: [ + new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')), + ], + requestBody: new OA\RequestBody( + required: true, + description: 'Environment created.', + content: new OA\MediaType( + mediaType: 'application/json', + schema: new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The name of the environment.'], + ], + ), + ), + ), + responses: [ + new OA\Response( + response: 201, + description: 'Environment created.', + content: [ + new OA\MediaType( + mediaType: 'application/json', + schema: new OA\Schema( + type: 'object', + properties: [ + 'uuid' => ['type' => 'string', 'example' => 'env123', 'description' => 'The UUID of the environment.'], + ] + ) + ), + ]), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + ref: '#/components/responses/400', + ), + new OA\Response( + response: 404, + description: 'Project not found.', + ), + new OA\Response( + response: 409, + description: 'Environment with this name already exists.', + ), + ] + )] + public function create_environment(Request $request) + { + $allowedFields = ['name']; + + $teamId = getTeamIdFromToken(); + if (is_null($teamId)) { + return invalidTokenResponse(); + } + + $return = validateIncomingRequest($request); + if ($return instanceof \Illuminate\Http\JsonResponse) { + return $return; + } + $validator = Validator::make($request->all(), [ + 'name' => ValidationPatterns::nameRules(), + ], ValidationPatterns::nameMessages()); + + $extraFields = array_diff(array_keys($request->all()), $allowedFields); + if ($validator->fails() || ! empty($extraFields)) { + $errors = $validator->errors(); + if (! empty($extraFields)) { + foreach ($extraFields as $field) { + $errors->add($field, 'This field is not allowed.'); + } + } + + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => $errors, + ], 422); + } + + if (! $request->uuid) { + return response()->json(['message' => 'Project UUID is required.'], 422); + } + + $project = Project::whereTeamId($teamId)->whereUuid($request->uuid)->first(); + if (! $project) { + return response()->json(['message' => 'Project not found.'], 404); + } + + $existingEnvironment = $project->environments()->where('name', $request->name)->first(); + if ($existingEnvironment) { + return response()->json(['message' => 'Environment with this name already exists.'], 409); + } + + $environment = $project->environments()->create([ + 'name' => $request->name, + ]); + + return response()->json([ + 'uuid' => $environment->uuid, + ])->setStatusCode(201); + } + + #[OA\Delete( + summary: 'Delete Environment', + description: 'Delete environment by name or UUID. Environment must be empty.', + path: '/projects/{uuid}/environments/{environment_name_or_uuid}', + operationId: 'delete-environment', + security: [ + ['bearerAuth' => []], + ], + tags: ['Projects'], + parameters: [ + new OA\Parameter(name: 'uuid', in: 'path', required: true, description: 'Project UUID', schema: new OA\Schema(type: 'string')), + new OA\Parameter(name: 'environment_name_or_uuid', in: 'path', required: true, description: 'Environment name or UUID', schema: new OA\Schema(type: 'string')), + ], + responses: [ + new OA\Response( + response: 200, + description: 'Environment deleted.', + content: [ + new OA\MediaType( + mediaType: 'application/json', + schema: new OA\Schema( + type: 'object', + properties: [ + 'message' => ['type' => 'string', 'example' => 'Environment deleted.'], + ] + ) + ), + ]), + new OA\Response( + response: 401, + ref: '#/components/responses/401', + ), + new OA\Response( + response: 400, + description: 'Environment has resources, so it cannot be deleted.', + ), + new OA\Response( + response: 404, + description: 'Project or environment not found.', + ), + ] + )] + public function delete_environment(Request $request) + { + $teamId = getTeamIdFromToken(); + if (is_null($teamId)) { + return invalidTokenResponse(); + } + + if (! $request->uuid) { + return response()->json(['message' => 'Project UUID is required.'], 422); + } + if (! $request->environment_name_or_uuid) { + return response()->json(['message' => 'Environment name or UUID is required.'], 422); + } + + $project = Project::whereTeamId($teamId)->whereUuid($request->uuid)->first(); + if (! $project) { + return response()->json(['message' => 'Project not found.'], 404); + } + + $environment = $project->environments()->whereName($request->environment_name_or_uuid)->first(); + if (! $environment) { + $environment = $project->environments()->whereUuid($request->environment_name_or_uuid)->first(); + } + if (! $environment) { + return response()->json(['message' => 'Environment not found.'], 404); + } + + if (! $environment->isEmpty()) { + return response()->json(['message' => 'Environment has resources, so it cannot be deleted.'], 400); + } + + $environment->delete(); + + return response()->json(['message' => 'Environment deleted.']); + } } diff --git a/app/Http/Controllers/Api/ResourcesController.php b/app/Http/Controllers/Api/ResourcesController.php index ad12c83ab..d5dc4a046 100644 --- a/app/Http/Controllers/Api/ResourcesController.php +++ b/app/Http/Controllers/Api/ResourcesController.php @@ -43,6 +43,10 @@ class ResourcesController extends Controller if (is_null($teamId)) { return invalidTokenResponse(); } + + // General authorization check for viewing resources - using Project as base resource type + $this->authorize('viewAny', Project::class); + $projects = Project::where('team_id', $teamId)->get(); $resources = collect(); $resources->push($projects->pluck('applications')->flatten()); diff --git a/app/Http/Controllers/Api/ServicesController.php b/app/Http/Controllers/Api/ServicesController.php index 542be83de..162f637c5 100644 --- a/app/Http/Controllers/Api/ServicesController.php +++ b/app/Http/Controllers/Api/ServicesController.php @@ -246,6 +246,8 @@ class ServicesController extends Controller return invalidTokenResponse(); } + $this->authorize('create', Service::class); + $return = validateIncomingRequest($request); if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; @@ -377,14 +379,118 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.', 'valid_service_types' => $serviceKeys], 404); } elseif (filled($request->docker_compose_raw)) { + $allowedFields = ['name', 'description', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'docker_compose_raw', 'connect_to_docker_network']; - $service = new Service; - $result = $this->upsert_service($request, $service, $teamId); - if ($result instanceof \Illuminate\Http\JsonResponse) { - return $result; + $validator = customApiValidator($request->all(), [ + 'project_uuid' => 'string|required', + 'environment_name' => 'string|nullable', + 'environment_uuid' => 'string|nullable', + 'server_uuid' => 'string|required', + 'destination_uuid' => 'string', + 'name' => 'string|max:255', + 'description' => 'string|nullable', + 'instant_deploy' => 'boolean', + 'connect_to_docker_network' => 'boolean', + 'docker_compose_raw' => 'string|required', + ]); + + $extraFields = array_diff(array_keys($request->all()), $allowedFields); + if ($validator->fails() || ! empty($extraFields)) { + $errors = $validator->errors(); + if (! empty($extraFields)) { + foreach ($extraFields as $field) { + $errors->add($field, 'This field is not allowed.'); + } + } + + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => $errors, + ], 422); } - return response()->json(serializeApiResponse($result))->setStatusCode(201); + $environmentUuid = $request->environment_uuid; + $environmentName = $request->environment_name; + if (blank($environmentUuid) && blank($environmentName)) { + return response()->json(['message' => 'You need to provide at least one of environment_name or environment_uuid.'], 422); + } + $serverUuid = $request->server_uuid; + $projectUuid = $request->project_uuid; + $project = Project::whereTeamId($teamId)->whereUuid($projectUuid)->first(); + if (! $project) { + return response()->json(['message' => 'Project not found.'], 404); + } + $environment = $project->environments()->where('name', $environmentName)->first(); + if (! $environment) { + $environment = $project->environments()->where('uuid', $environmentUuid)->first(); + } + if (! $environment) { + return response()->json(['message' => 'Environment not found.'], 404); + } + $server = Server::whereTeamId($teamId)->whereUuid($serverUuid)->first(); + if (! $server) { + return response()->json(['message' => 'Server not found.'], 404); + } + $destinations = $server->destinations(); + if ($destinations->count() == 0) { + return response()->json(['message' => 'Server has no destinations.'], 400); + } + if ($destinations->count() > 1 && ! $request->has('destination_uuid')) { + return response()->json(['message' => 'Server has multiple destinations and you do not set destination_uuid.'], 400); + } + $destination = $destinations->first(); + if (! isBase64Encoded($request->docker_compose_raw)) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', + ], + ], 422); + } + $dockerComposeRaw = base64_decode($request->docker_compose_raw); + if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', + ], + ], 422); + } + $dockerCompose = base64_decode($request->docker_compose_raw); + $dockerComposeRaw = Yaml::dump(Yaml::parse($dockerCompose), 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); + + $connectToDockerNetwork = $request->connect_to_docker_network ?? false; + $instantDeploy = $request->instant_deploy ?? false; + + $service = new Service; + $service->name = $request->name ?? 'service-'.str()->random(10); + $service->description = $request->description; + $service->docker_compose_raw = $dockerComposeRaw; + $service->environment_id = $environment->id; + $service->server_id = $server->id; + $service->destination_id = $destination->id; + $service->destination_type = $destination->getMorphClass(); + $service->connect_to_docker_network = $connectToDockerNetwork; + $service->save(); + + $service->parse(isNew: true); + if ($instantDeploy) { + StartService::dispatch($service); + } + + $domains = $service->applications()->get()->pluck('fqdn')->sort(); + $domains = $domains->map(function ($domain) { + if (count(explode(':', $domain)) > 2) { + return str($domain)->beforeLast(':')->value(); + } + + return $domain; + })->values(); + + return response()->json([ + 'uuid' => $service->uuid, + 'domains' => $domains, + ])->setStatusCode(201); } else { return response()->json(['message' => 'No service type or docker_compose_raw provided.'], 400); } @@ -443,6 +549,8 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.'], 404); } + $this->authorize('view', $service); + $service = $service->load(['applications', 'databases']); return response()->json($this->removeSensitiveData($service)); @@ -508,12 +616,14 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.'], 404); } + $this->authorize('delete', $service); + DeleteResourceJob::dispatch( resource: $service, - deleteConfigurations: $request->query->get('delete_configurations', true), deleteVolumes: $request->query->get('delete_volumes', true), - dockerCleanup: $request->query->get('docker_cleanup', true), - deleteConnectedNetworks: $request->query->get('delete_connected_networks', true) + deleteConnectedNetworks: $request->query->get('delete_connected_networks', true), + deleteConfigurations: $request->query->get('delete_configurations', true), + dockerCleanup: $request->query->get('docker_cleanup', true) ); return response()->json([ @@ -550,7 +660,6 @@ class ServicesController extends Controller mediaType: 'application/json', schema: new OA\Schema( type: 'object', - required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid', 'docker_compose_raw'], properties: [ 'name' => ['type' => 'string', 'description' => 'The service name.'], 'description' => ['type' => 'string', 'description' => 'The service description.'], @@ -615,28 +724,16 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.'], 404); } - $result = $this->upsert_service($request, $service, $teamId); - if ($result instanceof \Illuminate\Http\JsonResponse) { - return $result; - } + $this->authorize('update', $service); - return response()->json(serializeApiResponse($result))->setStatusCode(200); - } + $allowedFields = ['name', 'description', 'instant_deploy', 'docker_compose_raw', 'connect_to_docker_network']; - private function upsert_service(Request $request, Service $service, string $teamId) - { - $allowedFields = ['name', 'description', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'docker_compose_raw', 'connect_to_docker_network']; $validator = customApiValidator($request->all(), [ - 'project_uuid' => 'string|required', - 'environment_name' => 'string|nullable', - 'environment_uuid' => 'string|nullable', - 'server_uuid' => 'string|required', - 'destination_uuid' => 'string', 'name' => 'string|max:255', 'description' => 'string|nullable', 'instant_deploy' => 'boolean', 'connect_to_docker_network' => 'boolean', - 'docker_compose_raw' => 'string|required', + 'docker_compose_raw' => 'string|nullable', ]); $extraFields = array_diff(array_keys($request->all()), $allowedFields); @@ -653,70 +750,42 @@ class ServicesController extends Controller 'errors' => $errors, ], 422); } + if ($request->has('docker_compose_raw')) { + if (! isBase64Encoded($request->docker_compose_raw)) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', + ], + ], 422); + } + $dockerComposeRaw = base64_decode($request->docker_compose_raw); + if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', + ], + ], 422); + } + $dockerCompose = base64_decode($request->docker_compose_raw); + $dockerComposeRaw = Yaml::dump(Yaml::parse($dockerCompose), 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); + $service->docker_compose_raw = $dockerComposeRaw; + } - $environmentUuid = $request->environment_uuid; - $environmentName = $request->environment_name; - if (blank($environmentUuid) && blank($environmentName)) { - return response()->json(['message' => 'You need to provide at least one of environment_name or environment_uuid.'], 422); + if ($request->has('name')) { + $service->name = $request->name; } - $serverUuid = $request->server_uuid; - $instantDeploy = $request->instant_deploy ?? false; - $project = Project::whereTeamId($teamId)->whereUuid($request->project_uuid)->first(); - if (! $project) { - return response()->json(['message' => 'Project not found.'], 404); + if ($request->has('description')) { + $service->description = $request->description; } - $environment = $project->environments()->where('name', $environmentName)->first(); - if (! $environment) { - $environment = $project->environments()->where('uuid', $environmentUuid)->first(); + if ($request->has('connect_to_docker_network')) { + $service->connect_to_docker_network = $request->connect_to_docker_network; } - if (! $environment) { - return response()->json(['message' => 'Environment not found.'], 404); - } - $server = Server::whereTeamId($teamId)->whereUuid($serverUuid)->first(); - if (! $server) { - return response()->json(['message' => 'Server not found.'], 404); - } - $destinations = $server->destinations(); - if ($destinations->count() == 0) { - return response()->json(['message' => 'Server has no destinations.'], 400); - } - if ($destinations->count() > 1 && ! $request->has('destination_uuid')) { - return response()->json(['message' => 'Server has multiple destinations and you do not set destination_uuid.'], 400); - } - $destination = $destinations->first(); - if (! isBase64Encoded($request->docker_compose_raw)) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerCompose = base64_decode($request->docker_compose_raw); - $dockerComposeRaw = Yaml::dump(Yaml::parse($dockerCompose), 10, 2, Yaml::DUMP_MULTI_LINE_LITERAL_BLOCK); - $connectToDockerNetwork = $request->connect_to_docker_network ?? false; - - $service->name = $request->name ?? null; - $service->description = $request->description ?? null; - $service->docker_compose_raw = $dockerComposeRaw; - $service->environment_id = $environment->id; - $service->server_id = $server->id; - $service->destination_id = $destination->id; - $service->destination_type = $destination->getMorphClass(); - $service->connect_to_docker_network = $connectToDockerNetwork; $service->save(); $service->parse(); - if ($instantDeploy) { + if ($request->instant_deploy) { StartService::dispatch($service); } @@ -729,10 +798,10 @@ class ServicesController extends Controller return $domain; })->values(); - return [ + return response()->json([ 'uuid' => $service->uuid, 'domains' => $domains, - ]; + ])->setStatusCode(200); } #[OA\Get( @@ -795,6 +864,8 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.'], 404); } + $this->authorize('manageEnvironment', $service); + $envs = $service->environment_variables->map(function ($env) { $env->makeHidden([ 'application_id', @@ -899,6 +970,8 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.'], 404); } + $this->authorize('manageEnvironment', $service); + $validator = customApiValidator($request->all(), [ 'key' => 'string|required', 'value' => 'string|nullable', @@ -1020,6 +1093,8 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.'], 404); } + $this->authorize('manageEnvironment', $service); + $bulk_data = $request->get('data'); if (! $bulk_data) { return response()->json(['message' => 'Bulk data is required.'], 400); @@ -1136,6 +1211,8 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.'], 404); } + $this->authorize('manageEnvironment', $service); + $validator = customApiValidator($request->all(), [ 'key' => 'string|required', 'value' => 'string|nullable', @@ -1238,6 +1315,8 @@ class ServicesController extends Controller return response()->json(['message' => 'Service not found.'], 404); } + $this->authorize('manageEnvironment', $service); + $env = EnvironmentVariable::where('uuid', $request->env_uuid) ->where('resourceable_type', Service::class) ->where('resourceable_id', $service->id) @@ -1317,6 +1396,9 @@ class ServicesController extends Controller if (! $service) { return response()->json(['message' => 'Service not found.'], 404); } + + $this->authorize('deploy', $service); + if (str($service->status)->contains('running')) { return response()->json(['message' => 'Service is already running.'], 400); } @@ -1395,6 +1477,9 @@ class ServicesController extends Controller if (! $service) { return response()->json(['message' => 'Service not found.'], 404); } + + $this->authorize('stop', $service); + if (str($service->status)->contains('stopped') || str($service->status)->contains('exited')) { return response()->json(['message' => 'Service is already stopped.'], 400); } @@ -1482,6 +1567,9 @@ class ServicesController extends Controller if (! $service) { return response()->json(['message' => 'Service not found.'], 404); } + + $this->authorize('deploy', $service); + $pullLatest = $request->boolean('latest'); RestartService::dispatch($service, $pullLatest); diff --git a/app/Http/Controllers/Webhook/Bitbucket.php b/app/Http/Controllers/Webhook/Bitbucket.php index 490b66e58..078494f82 100644 --- a/app/Http/Controllers/Webhook/Bitbucket.php +++ b/app/Http/Controllers/Webhook/Bitbucket.php @@ -143,12 +143,13 @@ class Bitbucket extends Controller ]); $pr_app->generate_preview_fqdn_compose(); } else { - ApplicationPreview::create([ + $pr_app = ApplicationPreview::create([ 'git_type' => 'bitbucket', 'application_id' => $application->id, 'pull_request_id' => $pull_request_id, 'pull_request_html_url' => $pull_request_html_url, ]); + $pr_app->generate_preview_fqdn(); } } $result = queue_application_deployment( diff --git a/app/Http/Controllers/Webhook/Gitea.php b/app/Http/Controllers/Webhook/Gitea.php index 3c3d6e0b6..3e0c5a0b6 100644 --- a/app/Http/Controllers/Webhook/Gitea.php +++ b/app/Http/Controllers/Webhook/Gitea.php @@ -175,12 +175,13 @@ class Gitea extends Controller ]); $pr_app->generate_preview_fqdn_compose(); } else { - ApplicationPreview::create([ + $pr_app = ApplicationPreview::create([ 'git_type' => 'gitea', 'application_id' => $application->id, 'pull_request_id' => $pull_request_id, 'pull_request_html_url' => $pull_request_html_url, ]); + $pr_app->generate_preview_fqdn(); } } $result = queue_application_deployment( diff --git a/app/Http/Controllers/Webhook/Github.php b/app/Http/Controllers/Webhook/Github.php index 597ec023f..8872754e5 100644 --- a/app/Http/Controllers/Webhook/Github.php +++ b/app/Http/Controllers/Webhook/Github.php @@ -183,12 +183,13 @@ class Github extends Controller ]); $pr_app->generate_preview_fqdn_compose(); } else { - ApplicationPreview::create([ + $pr_app = ApplicationPreview::create([ 'git_type' => 'github', 'application_id' => $application->id, 'pull_request_id' => $pull_request_id, 'pull_request_html_url' => $pull_request_html_url, ]); + $pr_app->generate_preview_fqdn(); } } diff --git a/app/Http/Controllers/Webhook/Gitlab.php b/app/Http/Controllers/Webhook/Gitlab.php index d6d12a05f..3187663d4 100644 --- a/app/Http/Controllers/Webhook/Gitlab.php +++ b/app/Http/Controllers/Webhook/Gitlab.php @@ -202,12 +202,13 @@ class Gitlab extends Controller ]); $pr_app->generate_preview_fqdn_compose(); } else { - ApplicationPreview::create([ + $pr_app = ApplicationPreview::create([ 'git_type' => 'gitlab', 'application_id' => $application->id, 'pull_request_id' => $pull_request_id, 'pull_request_html_url' => $pull_request_html_url, ]); + $pr_app->generate_preview_fqdn(); } } $result = queue_application_deployment( diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index a1ce20295..e9d7b82b2 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -71,5 +71,8 @@ class Kernel extends HttpKernel 'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class, 'api.ability' => \App\Http\Middleware\ApiAbility::class, 'api.sensitive' => \App\Http\Middleware\ApiSensitiveData::class, + 'can.create.resources' => \App\Http\Middleware\CanCreateResources::class, + 'can.update.resource' => \App\Http\Middleware\CanUpdateResource::class, + 'can.access.terminal' => \App\Http\Middleware\CanAccessTerminal::class, ]; } diff --git a/app/Http/Middleware/ApiAllowed.php b/app/Http/Middleware/ApiAllowed.php index dc6be5da3..dd85c3521 100644 --- a/app/Http/Middleware/ApiAllowed.php +++ b/app/Http/Middleware/ApiAllowed.php @@ -18,12 +18,18 @@ class ApiAllowed return response()->json(['success' => true, 'message' => 'API is disabled.'], 403); } - if (! isDev()) { - if ($settings->allowed_ips) { - $allowedIps = explode(',', $settings->allowed_ips); - if (! in_array($request->ip(), $allowedIps)) { - return response()->json(['success' => true, 'message' => 'You are not allowed to access the API.'], 403); - } + if ($settings->allowed_ips) { + // Check for special case: 0.0.0.0 means allow all + if (trim($settings->allowed_ips) === '0.0.0.0') { + return $next($request); + } + + $allowedIps = explode(',', $settings->allowed_ips); + $allowedIps = array_map('trim', $allowedIps); + $allowedIps = array_filter($allowedIps); // Remove empty entries + + if (! empty($allowedIps) && ! check_ip_against_allowlist($request->ip(), $allowedIps)) { + return response()->json(['success' => true, 'message' => 'You are not allowed to access the API.'], 403); } } diff --git a/app/Http/Middleware/CanAccessTerminal.php b/app/Http/Middleware/CanAccessTerminal.php new file mode 100644 index 000000000..dcccd819b --- /dev/null +++ b/app/Http/Middleware/CanAccessTerminal.php @@ -0,0 +1,31 @@ +<?php + +namespace App\Http\Middleware; + +use Closure; +use Illuminate\Http\Request; +use Symfony\Component\HttpFoundation\Response; + +class CanAccessTerminal +{ + /** + * Handle an incoming request. + * + * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next + */ + public function handle(Request $request, Closure $next): Response + { + return $next($request); + + // if (! auth()->check()) { + // abort(401, 'Authentication required'); + // } + + // // Only admins/owners can access terminal functionality + // if (! auth()->user()->can('canAccessTerminal')) { + // abort(403, 'Access to terminal functionality is restricted to team administrators'); + // } + + // return $next($request); + } +} diff --git a/app/Http/Middleware/CanCreateResources.php b/app/Http/Middleware/CanCreateResources.php new file mode 100644 index 000000000..ba0ab67c1 --- /dev/null +++ b/app/Http/Middleware/CanCreateResources.php @@ -0,0 +1,26 @@ +<?php + +namespace App\Http\Middleware; + +use Closure; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Gate; +use Symfony\Component\HttpFoundation\Response; + +class CanCreateResources +{ + /** + * Handle an incoming request. + * + * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next + */ + public function handle(Request $request, Closure $next): Response + { + return $next($request); + // if (! Gate::allows('createAnyResource')) { + // abort(403, 'You do not have permission to create resources.'); + // } + + // return $next($request); + } +} diff --git a/app/Http/Middleware/CanUpdateResource.php b/app/Http/Middleware/CanUpdateResource.php new file mode 100644 index 000000000..372af4498 --- /dev/null +++ b/app/Http/Middleware/CanUpdateResource.php @@ -0,0 +1,75 @@ +<?php + +namespace App\Http\Middleware; + +use App\Models\Application; +use App\Models\Environment; +use App\Models\Project; +use App\Models\Service; +use App\Models\ServiceApplication; +use App\Models\ServiceDatabase; +use App\Models\StandaloneClickhouse; +use App\Models\StandaloneDragonfly; +use App\Models\StandaloneKeydb; +use App\Models\StandaloneMariadb; +use App\Models\StandaloneMongodb; +use App\Models\StandaloneMysql; +use App\Models\StandalonePostgresql; +use App\Models\StandaloneRedis; +use Closure; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Gate; +use Symfony\Component\HttpFoundation\Response; + +class CanUpdateResource +{ + public function handle(Request $request, Closure $next): Response + { + return $next($request); + + // Get resource from route parameters + // $resource = null; + // if ($request->route('application_uuid')) { + // $resource = Application::where('uuid', $request->route('application_uuid'))->first(); + // } elseif ($request->route('service_uuid')) { + // $resource = Service::where('uuid', $request->route('service_uuid'))->first(); + // } elseif ($request->route('stack_service_uuid')) { + // // Handle ServiceApplication or ServiceDatabase + // $stack_service_uuid = $request->route('stack_service_uuid'); + // $resource = ServiceApplication::where('uuid', $stack_service_uuid)->first() ?? + // ServiceDatabase::where('uuid', $stack_service_uuid)->first(); + // } elseif ($request->route('database_uuid')) { + // // Try different database types + // $database_uuid = $request->route('database_uuid'); + // $resource = StandalonePostgresql::where('uuid', $database_uuid)->first() ?? + // StandaloneMysql::where('uuid', $database_uuid)->first() ?? + // StandaloneMariadb::where('uuid', $database_uuid)->first() ?? + // StandaloneRedis::where('uuid', $database_uuid)->first() ?? + // StandaloneKeydb::where('uuid', $database_uuid)->first() ?? + // StandaloneDragonfly::where('uuid', $database_uuid)->first() ?? + // StandaloneClickhouse::where('uuid', $database_uuid)->first() ?? + // StandaloneMongodb::where('uuid', $database_uuid)->first(); + // } elseif ($request->route('server_uuid')) { + // // For server routes, check if user can manage servers + // if (! auth()->user()->isAdmin()) { + // abort(403, 'You do not have permission to access this resource.'); + // } + + // return $next($request); + // } elseif ($request->route('environment_uuid')) { + // $resource = Environment::where('uuid', $request->route('environment_uuid'))->first(); + // } elseif ($request->route('project_uuid')) { + // $resource = Project::ownedByCurrentTeam()->where('uuid', $request->route('project_uuid'))->first(); + // } + + // if (! $resource) { + // abort(404, 'Resource not found.'); + // } + + // if (! Gate::allows('update', $resource)) { + // abort(403, 'You do not have permission to update this resource.'); + // } + + // return $next($request); + } +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 9e8652172..f07050d5e 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,6 +12,6 @@ class VerifyCsrfToken extends Middleware * @var array<int, string> */ protected $except = [ - // + 'webhooks/*', ]; } diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index bc5fab30c..9037fa3e5 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -229,7 +229,14 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue // Set preview fqdn if ($this->pull_request_id !== 0) { - $this->preview = $this->application->generate_preview_fqdn($this->pull_request_id); + $this->preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id); + if ($this->preview) { + if ($this->application->build_pack === 'dockercompose') { + $this->preview->generate_preview_fqdn_compose(); + } else { + $this->preview->generate_preview_fqdn(); + } + } if ($this->application->is_github_based()) { ApplicationPullRequestUpdateJob::dispatch(application: $this->application, preview: $this->preview, deployment_uuid: $this->deployment_uuid, status: ProcessStatus::IN_PROGRESS); } @@ -1421,6 +1428,19 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue if ($this->pull_request_id !== 0) { $local_branch = "pull/{$this->pull_request_id}/head"; } + // Build an exact refspec for ls-remote so we don't match similarly named branches (e.g., changeset-release/main) + if ($this->pull_request_id === 0) { + $lsRemoteRef = "refs/heads/{$local_branch}"; + } else { + if ($this->git_type === 'github' || $this->git_type === 'gitea') { + $lsRemoteRef = "refs/pull/{$this->pull_request_id}/head"; + } elseif ($this->git_type === 'gitlab') { + $lsRemoteRef = "refs/merge-requests/{$this->pull_request_id}/head"; + } else { + // Fallback to the original value if provider-specific ref is unknown + $lsRemoteRef = $local_branch; + } + } $private_key = data_get($this->application, 'private_key.private_key'); if ($private_key) { $private_key = base64_encode($private_key); @@ -1435,7 +1455,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue executeInDocker($this->deployment_uuid, 'chmod 600 /root/.ssh/id_rsa'), ], [ - executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git ls-remote {$this->fullRepoUrl} {$local_branch}"), + executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git ls-remote {$this->fullRepoUrl} {$lsRemoteRef}"), 'hidden' => true, 'save' => 'git_commit_sha', ] @@ -1443,7 +1463,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue } else { $this->execute_remote_command( [ - executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git ls-remote {$this->fullRepoUrl} {$local_branch}"), + executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git ls-remote {$this->fullRepoUrl} {$lsRemoteRef}"), 'hidden' => true, 'save' => 'git_commit_sha', ], diff --git a/app/Jobs/CleanupInstanceStuffsJob.php b/app/Jobs/CleanupInstanceStuffsJob.php index 60ae58489..011c58639 100644 --- a/app/Jobs/CleanupInstanceStuffsJob.php +++ b/app/Jobs/CleanupInstanceStuffsJob.php @@ -3,6 +3,7 @@ namespace App\Jobs; use App\Models\TeamInvitation; +use App\Models\User; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldBeUnique; @@ -30,6 +31,7 @@ class CleanupInstanceStuffsJob implements ShouldBeEncrypted, ShouldBeUnique, Sho { try { $this->cleanupInvitationLink(); + $this->cleanupExpiredEmailChangeRequests(); } catch (\Throwable $e) { Log::error('CleanupInstanceStuffsJob failed with error: '.$e->getMessage()); } @@ -42,4 +44,15 @@ class CleanupInstanceStuffsJob implements ShouldBeEncrypted, ShouldBeUnique, Sho $item->isValid(); } } + + private function cleanupExpiredEmailChangeRequests() + { + User::whereNotNull('email_change_code_expires_at') + ->where('email_change_code_expires_at', '<', now()) + ->update([ + 'pending_email' => null, + 'email_change_code' => null, + 'email_change_code_expires_at' => null, + ]); + } } diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/DEPRECATEDContainerStatusJob.php similarity index 89% rename from app/Jobs/ContainerStatusJob.php rename to app/Jobs/DEPRECATEDContainerStatusJob.php index 22ae06ebd..df6dec7fe 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/DEPRECATEDContainerStatusJob.php @@ -11,7 +11,7 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class ContainerStatusJob implements ShouldBeEncrypted, ShouldQueue +class DEPRECATEDContainerStatusJob implements ShouldBeEncrypted, ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/ServerCheckNewJob.php b/app/Jobs/DEPRECATEDServerCheckNewJob.php similarity index 91% rename from app/Jobs/ServerCheckNewJob.php rename to app/Jobs/DEPRECATEDServerCheckNewJob.php index 3e8e60a31..1118366fe 100644 --- a/app/Jobs/ServerCheckNewJob.php +++ b/app/Jobs/DEPRECATEDServerCheckNewJob.php @@ -12,7 +12,7 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -class ServerCheckNewJob implements ShouldBeEncrypted, ShouldQueue +class DEPRECATEDServerCheckNewJob implements ShouldBeEncrypted, ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/DEPRECATEDServerResourceManager.php b/app/Jobs/DEPRECATEDServerResourceManager.php new file mode 100644 index 000000000..c50567a01 --- /dev/null +++ b/app/Jobs/DEPRECATEDServerResourceManager.php @@ -0,0 +1,162 @@ +<?php + +namespace App\Jobs; + +use App\Models\InstanceSettings; +use App\Models\Server; +use App\Models\Team; +use Cron\CronExpression; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\Middleware\WithoutOverlapping; +use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Carbon; +use Illuminate\Support\Facades\Log; + +class DEPRECATEDServerResourceManager implements ShouldQueue +{ + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + + /** + * The time when this job execution started. + */ + private ?Carbon $executionTime = null; + + private InstanceSettings $settings; + + private string $instanceTimezone; + + /** + * Create a new job instance. + */ + public function __construct() + { + $this->onQueue('high'); + } + + /** + * Get the middleware the job should pass through. + */ + public function middleware(): array + { + return [ + (new WithoutOverlapping('server-resource-manager')) + ->releaseAfter(60), + ]; + } + + public function handle(): void + { + // Freeze the execution time at the start of the job + $this->executionTime = Carbon::now(); + + $this->settings = instanceSettings(); + $this->instanceTimezone = $this->settings->instance_timezone ?: config('app.timezone'); + + if (validate_timezone($this->instanceTimezone) === false) { + $this->instanceTimezone = config('app.timezone'); + } + + // Process server checks - don't let failures stop the job + try { + $this->processServerChecks(); + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Failed to process server checks', [ + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), + ]); + } + } + + private function processServerChecks(): void + { + $servers = $this->getServers(); + + foreach ($servers as $server) { + try { + $this->processServer($server); + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Error processing server', [ + 'server_id' => $server->id, + 'server_name' => $server->name, + 'error' => $e->getMessage(), + ]); + } + } + } + + private function getServers() + { + $allServers = Server::where('ip', '!=', '1.2.3.4'); + + if (isCloud()) { + $servers = $allServers->whereRelation('team.subscription', 'stripe_invoice_paid', true)->get(); + $own = Team::find(0)->servers; + + return $servers->merge($own); + } else { + return $allServers->get(); + } + } + + private function processServer(Server $server): void + { + $serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone); + if (validate_timezone($serverTimezone) === false) { + $serverTimezone = config('app.timezone'); + } + + // Sentinel check + $lastSentinelUpdate = $server->sentinel_updated_at; + if (Carbon::parse($lastSentinelUpdate)->isBefore($this->executionTime->subSeconds($server->waitBeforeDoingSshCheck()))) { + // Dispatch ServerCheckJob if due + $checkFrequency = isCloud() ? '*/5 * * * *' : '* * * * *'; // Every 5 min for cloud, every minute for self-hosted + if ($this->shouldRunNow($checkFrequency, $serverTimezone)) { + ServerCheckJob::dispatch($server); + } + + // Dispatch ServerStorageCheckJob if due + $serverDiskUsageCheckFrequency = data_get($server->settings, 'server_disk_usage_check_frequency', '0 * * * *'); + if (isset(VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency])) { + $serverDiskUsageCheckFrequency = VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency]; + } + if ($this->shouldRunNow($serverDiskUsageCheckFrequency, $serverTimezone)) { + ServerStorageCheckJob::dispatch($server); + } + } + + // Dispatch DockerCleanupJob if due + $dockerCleanupFrequency = data_get($server->settings, 'docker_cleanup_frequency', '0 * * * *'); + if (isset(VALID_CRON_STRINGS[$dockerCleanupFrequency])) { + $dockerCleanupFrequency = VALID_CRON_STRINGS[$dockerCleanupFrequency]; + } + if ($this->shouldRunNow($dockerCleanupFrequency, $serverTimezone)) { + DockerCleanupJob::dispatch($server, false, $server->settings->delete_unused_volumes, $server->settings->delete_unused_networks); + } + + // Dispatch ServerPatchCheckJob if due (weekly) + if ($this->shouldRunNow('0 0 * * 0', $serverTimezone)) { // Weekly on Sunday at midnight + ServerPatchCheckJob::dispatch($server); + } + + // Dispatch Sentinel restart if due (daily for Sentinel-enabled servers) + if ($server->isSentinelEnabled() && $this->shouldRunNow('0 0 * * *', $serverTimezone)) { + dispatch(function () use ($server) { + $server->restartContainer('coolify-sentinel'); + }); + } + } + + private function shouldRunNow(string $frequency, string $timezone): bool + { + $cron = new CronExpression($frequency); + + // Use the frozen execution time, not the current time + $baseTime = $this->executionTime ?? Carbon::now(); + $executionTime = $baseTime->copy()->setTimezone($timezone); + + return $cron->isDue($executionTime); + } +} diff --git a/app/Jobs/DatabaseBackupJob.php b/app/Jobs/DatabaseBackupJob.php index a6c423cac..7ec5656da 100644 --- a/app/Jobs/DatabaseBackupJob.php +++ b/app/Jobs/DatabaseBackupJob.php @@ -23,6 +23,8 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Str; +use Throwable; +use Visus\Cuid2\Cuid2; class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue { @@ -60,9 +62,16 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue public ?S3Storage $s3 = null; + public $timeout = 3600; + + public string $backup_log_uuid; + public function __construct(public ScheduledDatabaseBackup $backup) { $this->onQueue('high'); + $this->timeout = $backup->timeout; + + $this->backup_log_uuid = (string) new Cuid2; } public function handle(): void @@ -219,12 +228,8 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue $this->mongo_root_username = str($rootUsername)->after('MONGO_INITDB_ROOT_USERNAME=')->value(); } } - \Log::info('MongoDB credentials extracted from environment', [ - 'has_username' => filled($this->mongo_root_username), - 'has_password' => filled($this->mongo_root_password), - ]); + } catch (\Throwable $e) { - \Log::warning('Failed to extract MongoDB environment variables', ['error' => $e->getMessage()]); // Continue without env vars - will be handled in backup_standalone_mongodb method } } @@ -288,6 +293,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue } $this->backup_location = $this->backup_dir.$this->backup_file; $this->backup_log = ScheduledDatabaseBackupExecution::create([ + 'uuid' => $this->backup_log_uuid, 'database_name' => $database, 'filename' => $this->backup_location, 'scheduled_database_backup_id' => $this->backup->id, @@ -307,6 +313,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue $this->backup_file = "/mongo-dump-$databaseName-".Carbon::now()->timestamp.'.tar.gz'; $this->backup_location = $this->backup_dir.$this->backup_file; $this->backup_log = ScheduledDatabaseBackupExecution::create([ + 'uuid' => $this->backup_log_uuid, 'database_name' => $databaseName, 'filename' => $this->backup_location, 'scheduled_database_backup_id' => $this->backup->id, @@ -319,6 +326,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue } $this->backup_location = $this->backup_dir.$this->backup_file; $this->backup_log = ScheduledDatabaseBackupExecution::create([ + 'uuid' => $this->backup_log_uuid, 'database_name' => $database, 'filename' => $this->backup_location, 'scheduled_database_backup_id' => $this->backup->id, @@ -331,6 +339,7 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue } $this->backup_location = $this->backup_dir.$this->backup_file; $this->backup_log = ScheduledDatabaseBackupExecution::create([ + 'uuid' => $this->backup_log_uuid, 'database_name' => $database, 'filename' => $this->backup_location, 'scheduled_database_backup_id' => $this->backup->id, @@ -342,6 +351,12 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue $size = $this->calculate_size(); if ($this->backup->save_s3) { $this->upload_to_s3(); + + // If local backup is disabled, delete the local file immediately after S3 upload + if ($this->backup->disable_local_backup) { + deleteBackupsLocally($this->backup_location, $this->server); + $this->add_to_backup_output('Local backup file deleted after S3 upload (disable_local_backup enabled).'); + } } $this->team->notify(new BackupSuccess($this->backup, $this->database, $database)); @@ -574,4 +589,18 @@ class DatabaseBackupJob implements ShouldBeEncrypted, ShouldQueue return "{$helperImage}:{$latestVersion}"; } + + public function failed(?Throwable $exception): void + { + $log = ScheduledDatabaseBackupExecution::where('uuid', $this->backup_log_uuid)->first(); + + if ($log) { + $log->update([ + 'status' => 'failed', + 'message' => 'Job failed: '.($exception?->getMessage() ?? 'Unknown error'), + 'size' => 0, + 'filename' => null, + ]); + } + } } diff --git a/app/Jobs/DeleteResourceJob.php b/app/Jobs/DeleteResourceJob.php index 408bb2a7a..b9fbebcc9 100644 --- a/app/Jobs/DeleteResourceJob.php +++ b/app/Jobs/DeleteResourceJob.php @@ -8,6 +8,7 @@ use App\Actions\Server\CleanupDocker; use App\Actions\Service\DeleteService; use App\Actions\Service\StopService; use App\Models\Application; +use App\Models\ApplicationPreview; use App\Models\Service; use App\Models\StandaloneClickhouse; use App\Models\StandaloneDragonfly; @@ -30,11 +31,11 @@ class DeleteResourceJob implements ShouldBeEncrypted, ShouldQueue use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; public function __construct( - public Application|Service|StandalonePostgresql|StandaloneRedis|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $resource, - public bool $deleteConfigurations = true, + public Application|ApplicationPreview|Service|StandalonePostgresql|StandaloneRedis|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $resource, public bool $deleteVolumes = true, - public bool $dockerCleanup = true, - public bool $deleteConnectedNetworks = true + public bool $deleteConnectedNetworks = true, + public bool $deleteConfigurations = true, + public bool $dockerCleanup = true ) { $this->onQueue('high'); } @@ -42,9 +43,16 @@ class DeleteResourceJob implements ShouldBeEncrypted, ShouldQueue public function handle() { try { + // Handle ApplicationPreview instances separately + if ($this->resource instanceof ApplicationPreview) { + $this->deleteApplicationPreview(); + + return; + } + switch ($this->resource->type()) { case 'application': - StopApplication::run($this->resource, previewDeployments: true); + StopApplication::run($this->resource, previewDeployments: true, dockerCleanup: $this->dockerCleanup); break; case 'standalone-postgresql': case 'standalone-redis': @@ -54,11 +62,11 @@ class DeleteResourceJob implements ShouldBeEncrypted, ShouldQueue case 'standalone-keydb': case 'standalone-dragonfly': case 'standalone-clickhouse': - StopDatabase::run($this->resource, true); + StopDatabase::run($this->resource, dockerCleanup: $this->dockerCleanup); break; case 'service': - StopService::run($this->resource, true); - DeleteService::run($this->resource, $this->deleteConfigurations, $this->deleteVolumes, $this->dockerCleanup, $this->deleteConnectedNetworks); + StopService::run($this->resource, $this->deleteConnectedNetworks, $this->dockerCleanup); + DeleteService::run($this->resource, $this->deleteVolumes, $this->deleteConnectedNetworks, $this->deleteConfigurations, $this->dockerCleanup); return; } @@ -70,7 +78,7 @@ class DeleteResourceJob implements ShouldBeEncrypted, ShouldQueue $this->resource->deleteVolumes(); $this->resource->persistentStorages()->delete(); } - $this->resource->fileStorages()->delete(); + $this->resource->fileStorages()->delete(); // these are file mounts which should probably have their own flag $isDatabase = $this->resource instanceof StandalonePostgresql || $this->resource instanceof StandaloneRedis @@ -98,10 +106,61 @@ class DeleteResourceJob implements ShouldBeEncrypted, ShouldQueue if ($this->dockerCleanup) { $server = data_get($this->resource, 'server') ?? data_get($this->resource, 'destination.server'); if ($server) { - CleanupDocker::dispatch($server, true); + CleanupDocker::dispatch($server, false, false); } } Artisan::queue('cleanup:stucked-resources'); } } + + private function deleteApplicationPreview() + { + $application = $this->resource->application; + $server = $application->destination->server; + $pull_request_id = $this->resource->pull_request_id; + + // Ensure the preview is soft deleted (may already be done in Livewire component) + if (! $this->resource->trashed()) { + $this->resource->delete(); + } + + try { + if ($server->isSwarm()) { + instant_remote_process(["docker stack rm {$application->uuid}-{$pull_request_id}"], $server); + } else { + $containers = getCurrentApplicationContainerStatus($server, $application->id, $pull_request_id)->toArray(); + $this->stopPreviewContainers($containers, $server); + } + } catch (\Throwable $e) { + // Log the error but don't fail the job + ray('Error stopping preview containers: '.$e->getMessage()); + } + + // Finally, force delete to trigger resource cleanup + $this->resource->forceDelete(); + } + + private function stopPreviewContainers(array $containers, $server, int $timeout = 30) + { + if (empty($containers)) { + return; + } + + $containerNames = []; + foreach ($containers as $container) { + $containerNames[] = str_replace('/', '', $container['Names']); + } + + $containerList = implode(' ', array_map('escapeshellarg', $containerNames)); + $commands = [ + "docker stop --time=$timeout $containerList", + "docker rm -f $containerList", + ]; + + instant_remote_process( + command: $commands, + server: $server, + throwError: false + ); + } } diff --git a/app/Jobs/DockerCleanupJob.php b/app/Jobs/DockerCleanupJob.php index 519728ab0..f3f3a2ae4 100644 --- a/app/Jobs/DockerCleanupJob.php +++ b/app/Jobs/DockerCleanupJob.php @@ -34,7 +34,12 @@ class DockerCleanupJob implements ShouldBeEncrypted, ShouldQueue return [(new WithoutOverlapping('docker-cleanup-'.$this->server->uuid))->expireAfter(600)->dontRelease()]; } - public function __construct(public Server $server, public bool $manualCleanup = false) {} + public function __construct( + public Server $server, + public bool $manualCleanup = false, + public bool $deleteUnusedVolumes = false, + public bool $deleteUnusedNetworks = false + ) {} public function handle(): void { @@ -50,7 +55,11 @@ class DockerCleanupJob implements ShouldBeEncrypted, ShouldQueue $this->usageBefore = $this->server->getDiskUsage(); if ($this->manualCleanup || $this->server->settings->force_docker_cleanup) { - $cleanup_log = CleanupDocker::run(server: $this->server); + $cleanup_log = CleanupDocker::run( + server: $this->server, + deleteUnusedVolumes: $this->deleteUnusedVolumes, + deleteUnusedNetworks: $this->deleteUnusedNetworks + ); $usageAfter = $this->server->getDiskUsage(); $message = ($this->manualCleanup ? 'Manual' : 'Forced').' Docker cleanup job executed successfully. Disk usage before: '.$this->usageBefore.'%, Disk usage after: '.$usageAfter.'%.'; @@ -67,7 +76,11 @@ class DockerCleanupJob implements ShouldBeEncrypted, ShouldQueue } if (str($this->usageBefore)->isEmpty() || $this->usageBefore === null || $this->usageBefore === 0) { - $cleanup_log = CleanupDocker::run(server: $this->server); + $cleanup_log = CleanupDocker::run( + server: $this->server, + deleteUnusedVolumes: $this->deleteUnusedVolumes, + deleteUnusedNetworks: $this->deleteUnusedNetworks + ); $message = 'Docker cleanup job executed successfully, but no disk usage could be determined.'; $this->execution_log->update([ @@ -81,7 +94,11 @@ class DockerCleanupJob implements ShouldBeEncrypted, ShouldQueue } if ($this->usageBefore >= $this->server->settings->docker_cleanup_threshold) { - $cleanup_log = CleanupDocker::run(server: $this->server); + $cleanup_log = CleanupDocker::run( + server: $this->server, + deleteUnusedVolumes: $this->deleteUnusedVolumes, + deleteUnusedNetworks: $this->deleteUnusedNetworks + ); $usageAfter = $this->server->getDiskUsage(); $diskSaved = $this->usageBefore - $usageAfter; diff --git a/app/Jobs/PullChangelogFromGitHub.php b/app/Jobs/PullChangelogFromGitHub.php new file mode 100644 index 000000000..e84766f7f --- /dev/null +++ b/app/Jobs/PullChangelogFromGitHub.php @@ -0,0 +1,110 @@ +<?php + +namespace App\Jobs; + +use Carbon\Carbon; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\File; +use Illuminate\Support\Facades\Http; + +class PullChangelogFromGitHub implements ShouldBeEncrypted, ShouldQueue +{ + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + + public $timeout = 30; + + public function __construct() + { + $this->onQueue('high'); + } + + public function handle(): void + { + try { + $response = Http::retry(3, 1000) + ->timeout(30) + ->get('https://api.github.com/repos/coollabsio/coolify/releases?per_page=10'); + + if ($response->successful()) { + $releases = $response->json(); + $changelog = $this->transformReleasesToChangelog($releases); + + // Group entries by month and save them + $this->saveChangelogEntries($changelog); + } else { + send_internal_notification('PullChangelogFromGitHub failed with: '.$response->status().' '.$response->body()); + } + } catch (\Throwable $e) { + send_internal_notification('PullChangelogFromGitHub failed with: '.$e->getMessage()); + } + } + + private function transformReleasesToChangelog(array $releases): array + { + $entries = []; + + foreach ($releases as $release) { + // Skip drafts and pre-releases if desired + if ($release['draft']) { + continue; + } + + $publishedAt = Carbon::parse($release['published_at']); + + $entry = [ + 'tag_name' => $release['tag_name'], + 'title' => $release['name'] ?: $release['tag_name'], + 'content' => $release['body'] ?: 'No release notes available.', + 'published_at' => $publishedAt->toISOString(), + ]; + + $entries[] = $entry; + } + + return $entries; + } + + private function saveChangelogEntries(array $entries): void + { + // Create changelogs directory if it doesn't exist + $changelogsDir = base_path('changelogs'); + if (! File::exists($changelogsDir)) { + File::makeDirectory($changelogsDir, 0755, true); + } + + // Group entries by year-month + $groupedEntries = []; + foreach ($entries as $entry) { + $date = Carbon::parse($entry['published_at']); + $monthKey = $date->format('Y-m'); + + if (! isset($groupedEntries[$monthKey])) { + $groupedEntries[$monthKey] = []; + } + + $groupedEntries[$monthKey][] = $entry; + } + + // Save each month's entries to separate files + foreach ($groupedEntries as $month => $monthEntries) { + // Sort entries by published date (newest first) + usort($monthEntries, function ($a, $b) { + return Carbon::parse($b['published_at'])->timestamp - Carbon::parse($a['published_at'])->timestamp; + }); + + $monthData = [ + 'entries' => $monthEntries, + 'last_updated' => now()->toISOString(), + ]; + + $filePath = base_path("changelogs/{$month}.json"); + File::put($filePath, json_encode($monthData, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + } + + } +} diff --git a/app/Jobs/PullTemplatesFromCDN.php b/app/Jobs/PullTemplatesFromCDN.php index 9a4c991bc..7e6b2e21a 100644 --- a/app/Jobs/PullTemplatesFromCDN.php +++ b/app/Jobs/PullTemplatesFromCDN.php @@ -31,7 +31,7 @@ class PullTemplatesFromCDN implements ShouldBeEncrypted, ShouldQueue $response = Http::retry(3, 1000)->get(config('constants.services.official')); if ($response->successful()) { $services = $response->json(); - File::put(base_path('templates/service-templates.json'), json_encode($services)); + File::put(base_path('templates/'.config('constants.services.file_name')), json_encode($services)); } else { send_internal_notification('PullTemplatesAndVersions failed with: '.$response->status().' '.$response->body()); } diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index 61206da6f..3e3aa1eb7 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -21,8 +21,9 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Middleware\WithoutOverlapping; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Collection; +use Laravel\Horizon\Contracts\Silenced; -class PushServerUpdateJob implements ShouldBeEncrypted, ShouldQueue +class PushServerUpdateJob implements ShouldBeEncrypted, ShouldQueue, Silenced { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/ScheduledJobManager.php b/app/Jobs/ScheduledJobManager.php new file mode 100644 index 000000000..18ca0008c --- /dev/null +++ b/app/Jobs/ScheduledJobManager.php @@ -0,0 +1,313 @@ +<?php + +namespace App\Jobs; + +use App\Models\ScheduledDatabaseBackup; +use App\Models\ScheduledTask; +use App\Models\Server; +use App\Models\Team; +use Cron\CronExpression; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\Middleware\WithoutOverlapping; +use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Carbon; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Log; + +class ScheduledJobManager implements ShouldQueue +{ + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + + /** + * The time when this job execution started. + * Used to ensure all scheduled items are evaluated against the same point in time. + */ + private ?Carbon $executionTime = null; + + /** + * Create a new job instance. + */ + public function __construct() + { + $this->onQueue($this->determineQueue()); + } + + private function determineQueue(): string + { + $preferredQueue = 'crons'; + $fallbackQueue = 'high'; + + $configuredQueues = explode(',', env('HORIZON_QUEUES', 'high,default')); + + return in_array($preferredQueue, $configuredQueues) ? $preferredQueue : $fallbackQueue; + } + + /** + * Get the middleware the job should pass through. + */ + public function middleware(): array + { + return [ + (new WithoutOverlapping('scheduled-job-manager')) + ->releaseAfter(60), // Release the lock after 60 seconds if job fails + ]; + } + + public function handle(): void + { + // Freeze the execution time at the start of the job + $this->executionTime = Carbon::now(); + + // Process backups - don't let failures stop task processing + try { + $this->processScheduledBackups(); + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Failed to process scheduled backups', [ + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), + ]); + } + + // Process tasks - don't let failures stop the job manager + try { + $this->processScheduledTasks(); + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Failed to process scheduled tasks', [ + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), + ]); + } + + // Process Docker cleanups - don't let failures stop the job manager + try { + $this->processDockerCleanups(); + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Failed to process docker cleanups', [ + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), + ]); + } + } + + private function processScheduledBackups(): void + { + $backups = ScheduledDatabaseBackup::with(['database']) + ->where('enabled', true) + ->get(); + + foreach ($backups as $backup) { + try { + // Apply the same filtering logic as the original + if (! $this->shouldProcessBackup($backup)) { + continue; + } + + $server = $backup->server(); + $serverTimezone = data_get($server->settings, 'server_timezone', config('app.timezone')); + + if (validate_timezone($serverTimezone) === false) { + $serverTimezone = config('app.timezone'); + } + + $frequency = $backup->frequency; + if (isset(VALID_CRON_STRINGS[$frequency])) { + $frequency = VALID_CRON_STRINGS[$frequency]; + } + + if ($this->shouldRunNow($frequency, $serverTimezone)) { + DatabaseBackupJob::dispatch($backup); + } + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Error processing backup', [ + 'backup_id' => $backup->id, + 'error' => $e->getMessage(), + ]); + } + } + } + + private function processScheduledTasks(): void + { + $tasks = ScheduledTask::with(['service', 'application']) + ->where('enabled', true) + ->get(); + + foreach ($tasks as $task) { + try { + if (! $this->shouldProcessTask($task)) { + continue; + } + + $server = $task->server(); + $serverTimezone = data_get($server->settings, 'server_timezone', config('app.timezone')); + + if (validate_timezone($serverTimezone) === false) { + $serverTimezone = config('app.timezone'); + } + + $frequency = $task->frequency; + if (isset(VALID_CRON_STRINGS[$frequency])) { + $frequency = VALID_CRON_STRINGS[$frequency]; + } + + if ($this->shouldRunNow($frequency, $serverTimezone)) { + ScheduledTaskJob::dispatch($task); + } + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Error processing task', [ + 'task_id' => $task->id, + 'error' => $e->getMessage(), + ]); + } + } + } + + private function shouldProcessBackup(ScheduledDatabaseBackup $backup): bool + { + if (blank(data_get($backup, 'database'))) { + $backup->delete(); + + return false; + } + + $server = $backup->server(); + if (blank($server)) { + $backup->delete(); + + return false; + } + + if ($server->isFunctional() === false) { + return false; + } + + if (isCloud() && data_get($server->team->subscription, 'stripe_invoice_paid', false) === false && $server->team->id !== 0) { + return false; + } + + return true; + } + + private function shouldProcessTask(ScheduledTask $task): bool + { + $service = $task->service; + $application = $task->application; + + $server = $task->server(); + if (blank($server)) { + $task->delete(); + + return false; + } + + if ($server->isFunctional() === false) { + return false; + } + + if (isCloud() && data_get($server->team->subscription, 'stripe_invoice_paid', false) === false && $server->team->id !== 0) { + return false; + } + + if (! $service && ! $application) { + $task->delete(); + + return false; + } + + if ($application && str($application->status)->contains('running') === false) { + return false; + } + + if ($service && str($service->status)->contains('running') === false) { + return false; + } + + return true; + } + + private function shouldRunNow(string $frequency, string $timezone): bool + { + $cron = new CronExpression($frequency); + + // Use the frozen execution time, not the current time + // Fallback to current time if execution time is not set (shouldn't happen) + $baseTime = $this->executionTime ?? Carbon::now(); + $executionTime = $baseTime->copy()->setTimezone($timezone); + + return $cron->isDue($executionTime); + } + + private function processDockerCleanups(): void + { + // Get all servers that need cleanup checks + $servers = $this->getServersForCleanup(); + + foreach ($servers as $server) { + try { + if (! $this->shouldProcessDockerCleanup($server)) { + continue; + } + + $serverTimezone = data_get($server->settings, 'server_timezone', config('app.timezone')); + if (validate_timezone($serverTimezone) === false) { + $serverTimezone = config('app.timezone'); + } + + $frequency = data_get($server->settings, 'docker_cleanup_frequency', '0 * * * *'); + if (isset(VALID_CRON_STRINGS[$frequency])) { + $frequency = VALID_CRON_STRINGS[$frequency]; + } + + // Use the frozen execution time for consistent evaluation + if ($this->shouldRunNow($frequency, $serverTimezone)) { + DockerCleanupJob::dispatch( + $server, + false, + $server->settings->delete_unused_volumes, + $server->settings->delete_unused_networks + ); + } + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Error processing docker cleanup', [ + 'server_id' => $server->id, + 'server_name' => $server->name, + 'error' => $e->getMessage(), + ]); + } + } + } + + private function getServersForCleanup(): Collection + { + $query = Server::with('settings') + ->where('ip', '!=', '1.2.3.4'); + + if (isCloud()) { + $servers = $query->whereRelation('team.subscription', 'stripe_invoice_paid', true)->get(); + $own = Team::find(0)->servers()->with('settings')->get(); + + return $servers->merge($own); + } + + return $query->get(); + } + + private function shouldProcessDockerCleanup(Server $server): bool + { + if (! $server->isFunctional()) { + return false; + } + + // In cloud, check subscription status (except team 0) + if (isCloud() && $server->team_id !== 0) { + if (data_get($server->team->subscription, 'stripe_invoice_paid', false) === false) { + return false; + } + } + + return true; + } +} diff --git a/app/Jobs/ServerConnectionCheckJob.php b/app/Jobs/ServerConnectionCheckJob.php new file mode 100644 index 000000000..167bcea38 --- /dev/null +++ b/app/Jobs/ServerConnectionCheckJob.php @@ -0,0 +1,153 @@ +<?php + +namespace App\Jobs; + +use App\Models\Server; +use App\Services\ConfigurationRepository; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\Middleware\WithoutOverlapping; +use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Log; + +class ServerConnectionCheckJob implements ShouldBeEncrypted, ShouldQueue +{ + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + + public $tries = 1; + + public $timeout = 30; + + public function __construct( + public Server $server, + public bool $disableMux = true + ) {} + + public function middleware(): array + { + return [(new WithoutOverlapping('server-connection-check-'.$this->server->uuid))->expireAfter(45)->dontRelease()]; + } + + private function disableSshMux(): void + { + $configRepository = app(ConfigurationRepository::class); + $configRepository->disableSshMux(); + } + + public function handle() + { + try { + // Check if server is disabled + if ($this->server->settings->force_disabled) { + $this->server->settings->update([ + 'is_reachable' => false, + 'is_usable' => false, + ]); + Log::debug('ServerConnectionCheck: Server is disabled', [ + 'server_id' => $this->server->id, + 'server_name' => $this->server->name, + ]); + + return; + } + + // Temporarily disable mux if requested + if ($this->disableMux) { + $this->disableSshMux(); + } + + // Check basic connectivity first + $isReachable = $this->checkConnection(); + + if (! $isReachable) { + $this->server->settings->update([ + 'is_reachable' => false, + 'is_usable' => false, + ]); + + Log::warning('ServerConnectionCheck: Server not reachable', [ + 'server_id' => $this->server->id, + 'server_name' => $this->server->name, + 'server_ip' => $this->server->ip, + ]); + + return; + } + + // Server is reachable, check if Docker is available + // $isUsable = $this->checkDockerAvailability(); + + $this->server->settings->update([ + 'is_reachable' => true, + 'is_usable' => true, + ]); + + } catch (\Throwable $e) { + $this->server->settings->update([ + 'is_reachable' => false, + 'is_usable' => false, + ]); + + throw $e; + } + } + + private function checkConnection(): bool + { + try { + // Use instant_remote_process with a simple command + // This will automatically handle mux, sudo, IPv6, Cloudflare tunnel, etc. + $output = instant_remote_process_with_timeout( + ['ls -la /'], + $this->server, + false // don't throw error + ); + + return $output !== null; + } catch (\Throwable $e) { + Log::debug('ServerConnectionCheck: Connection check failed', [ + 'server_id' => $this->server->id, + 'error' => $e->getMessage(), + ]); + + return false; + } + } + + private function checkDockerAvailability(): bool + { + try { + // Use instant_remote_process to check Docker + // The function will automatically handle sudo for non-root users + $output = instant_remote_process_with_timeout( + ['docker version --format json'], + $this->server, + false // don't throw error + ); + + if ($output === null) { + return false; + } + + // Try to parse the JSON output to ensure Docker is really working + $output = trim($output); + if (! empty($output)) { + $dockerInfo = json_decode($output, true); + + return isset($dockerInfo['Server']['Version']); + } + + return false; + } catch (\Throwable $e) { + Log::debug('ServerConnectionCheck: Docker check failed', [ + 'server_id' => $this->server->id, + 'error' => $e->getMessage(), + ]); + + return false; + } + } +} diff --git a/app/Jobs/ServerManagerJob.php b/app/Jobs/ServerManagerJob.php new file mode 100644 index 000000000..043845c00 --- /dev/null +++ b/app/Jobs/ServerManagerJob.php @@ -0,0 +1,170 @@ +<?php + +namespace App\Jobs; + +use App\Models\InstanceSettings; +use App\Models\Server; +use App\Models\Team; +use Cron\CronExpression; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Carbon; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Log; + +class ServerManagerJob implements ShouldQueue +{ + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + + /** + * The time when this job execution started. + */ + private ?Carbon $executionTime = null; + + private InstanceSettings $settings; + + private string $instanceTimezone; + + private string $checkFrequency = '* * * * *'; + + /** + * Create a new job instance. + */ + public function __construct() + { + $this->onQueue('high'); + } + + public function handle(): void + { + // Freeze the execution time at the start of the job + $this->executionTime = Carbon::now(); + if (isCloud()) { + $this->checkFrequency = '*/5 * * * *'; + } + $this->settings = instanceSettings(); + $this->instanceTimezone = $this->settings->instance_timezone ?: config('app.timezone'); + + if (validate_timezone($this->instanceTimezone) === false) { + $this->instanceTimezone = config('app.timezone'); + } + + // Get all servers to process + $servers = $this->getServers(); + + // Dispatch ServerConnectionCheck for all servers efficiently + $this->dispatchConnectionChecks($servers); + + // Process server-specific scheduled tasks + $this->processScheduledTasks($servers); + } + + private function getServers(): Collection + { + $allServers = Server::where('ip', '!=', '1.2.3.4'); + + if (isCloud()) { + $servers = $allServers->whereRelation('team.subscription', 'stripe_invoice_paid', true)->get(); + $own = Team::find(0)->servers; + + return $servers->merge($own); + } else { + return $allServers->get(); + } + } + + private function dispatchConnectionChecks(Collection $servers): void + { + + if ($this->shouldRunNow($this->checkFrequency)) { + $servers->each(function (Server $server) { + try { + ServerConnectionCheckJob::dispatch($server); + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Failed to dispatch ServerConnectionCheck', [ + 'server_id' => $server->id, + 'server_name' => $server->name, + 'error' => $e->getMessage(), + ]); + } + }); + } + } + + private function processScheduledTasks(Collection $servers): void + { + foreach ($servers as $server) { + try { + $this->processServerTasks($server); + } catch (\Exception $e) { + Log::channel('scheduled-errors')->error('Error processing server tasks', [ + 'server_id' => $server->id, + 'server_name' => $server->name, + 'error' => $e->getMessage(), + ]); + } + } + } + + private function processServerTasks(Server $server): void + { + // Check if we should run sentinel-based checks + $lastSentinelUpdate = $server->sentinel_updated_at; + $waitTime = $server->waitBeforeDoingSshCheck(); + $sentinelOutOfSync = Carbon::parse($lastSentinelUpdate)->isBefore($this->executionTime->subSeconds($waitTime)); + + if ($sentinelOutOfSync) { + // Dispatch jobs if Sentinel is out of sync + if ($this->shouldRunNow($this->checkFrequency)) { + ServerCheckJob::dispatch($server); + } + + // Dispatch ServerStorageCheckJob if due + $serverDiskUsageCheckFrequency = data_get($server->settings, 'server_disk_usage_check_frequency', '0 * * * *'); + if (isset(VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency])) { + $serverDiskUsageCheckFrequency = VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency]; + } + $shouldRunStorageCheck = $this->shouldRunNow($serverDiskUsageCheckFrequency); + + if ($shouldRunStorageCheck) { + ServerStorageCheckJob::dispatch($server); + } + } + + $serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone); + if (validate_timezone($serverTimezone) === false) { + $serverTimezone = config('app.timezone'); + } + + // Dispatch ServerPatchCheckJob if due (weekly) + $shouldRunPatchCheck = $this->shouldRunNow('0 0 * * 0', $serverTimezone); + + if ($shouldRunPatchCheck) { // Weekly on Sunday at midnight + ServerPatchCheckJob::dispatch($server); + } + + // Dispatch Sentinel restart if due (daily for Sentinel-enabled servers) + $isSentinelEnabled = $server->isSentinelEnabled(); + $shouldRestartSentinel = $isSentinelEnabled && $this->shouldRunNow('0 0 * * *', $serverTimezone); + + if ($shouldRestartSentinel) { + dispatch(function () use ($server) { + $server->restartContainer('coolify-sentinel'); + }); + } + } + + private function shouldRunNow(string $frequency, ?string $timezone = null): bool + { + $cron = new CronExpression($frequency); + + // Use the frozen execution time, not the current time + $baseTime = $this->executionTime ?? Carbon::now(); + $executionTime = $baseTime->copy()->setTimezone($timezone ?? config('app.timezone')); + + return $cron->isDue($executionTime); + } +} diff --git a/app/Jobs/ServerStorageCheckJob.php b/app/Jobs/ServerStorageCheckJob.php index 9a8d86be1..9d45491c6 100644 --- a/app/Jobs/ServerStorageCheckJob.php +++ b/app/Jobs/ServerStorageCheckJob.php @@ -11,8 +11,9 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\RateLimiter; +use Laravel\Horizon\Contracts\Silenced; -class ServerStorageCheckJob implements ShouldBeEncrypted, ShouldQueue +class ServerStorageCheckJob implements ShouldBeEncrypted, ShouldQueue, Silenced { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; diff --git a/app/Jobs/UpdateStripeCustomerEmailJob.php b/app/Jobs/UpdateStripeCustomerEmailJob.php new file mode 100644 index 000000000..2e86c14a0 --- /dev/null +++ b/app/Jobs/UpdateStripeCustomerEmailJob.php @@ -0,0 +1,133 @@ +<?php + +namespace App\Jobs; + +use App\Models\Team; +use Illuminate\Bus\Queueable; +use Illuminate\Contracts\Queue\ShouldBeEncrypted; +use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Foundation\Bus\Dispatchable; +use Illuminate\Queue\InteractsWithQueue; +use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Facades\Log; +use Stripe\Stripe; + +class UpdateStripeCustomerEmailJob implements ShouldBeEncrypted, ShouldQueue +{ + use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; + + public $tries = 3; + + public $backoff = [10, 30, 60]; + + public function __construct( + private Team $team, + private int $userId, + private string $newEmail, + private string $oldEmail + ) { + $this->onQueue('high'); + } + + public function handle(): void + { + try { + if (! isCloud() || ! $this->team->subscription) { + Log::info('Skipping Stripe email update - not cloud or no subscription', [ + 'team_id' => $this->team->id, + 'user_id' => $this->userId, + ]); + + return; + } + + // Check if the user changing email is a team owner + $isOwner = $this->team->members() + ->wherePivot('role', 'owner') + ->where('users.id', $this->userId) + ->exists(); + + if (! $isOwner) { + Log::info('Skipping Stripe email update - user is not team owner', [ + 'team_id' => $this->team->id, + 'user_id' => $this->userId, + ]); + + return; + } + + // Get current Stripe customer email to verify it matches the user's old email + $stripe_customer_id = data_get($this->team, 'subscription.stripe_customer_id'); + if (! $stripe_customer_id) { + Log::info('Skipping Stripe email update - no Stripe customer ID', [ + 'team_id' => $this->team->id, + 'user_id' => $this->userId, + ]); + + return; + } + + Stripe::setApiKey(config('subscription.stripe_api_key')); + + try { + $stripeCustomer = \Stripe\Customer::retrieve($stripe_customer_id); + $currentStripeEmail = $stripeCustomer->email; + + // Only update if the current Stripe email matches the user's old email + if (strtolower($currentStripeEmail) !== strtolower($this->oldEmail)) { + Log::info('Skipping Stripe email update - Stripe customer email does not match user old email', [ + 'team_id' => $this->team->id, + 'user_id' => $this->userId, + 'stripe_email' => $currentStripeEmail, + 'user_old_email' => $this->oldEmail, + ]); + + return; + } + + // Update Stripe customer email + \Stripe\Customer::update($stripe_customer_id, ['email' => $this->newEmail]); + + } catch (\Exception $e) { + Log::error('Failed to retrieve or update Stripe customer', [ + 'team_id' => $this->team->id, + 'user_id' => $this->userId, + 'stripe_customer_id' => $stripe_customer_id, + 'error' => $e->getMessage(), + ]); + + throw $e; + } + + Log::info('Successfully updated Stripe customer email', [ + 'team_id' => $this->team->id, + 'user_id' => $this->userId, + 'old_email' => $this->oldEmail, + 'new_email' => $this->newEmail, + ]); + } catch (\Exception $e) { + Log::error('Failed to update Stripe customer email', [ + 'team_id' => $this->team->id, + 'user_id' => $this->userId, + 'old_email' => $this->oldEmail, + 'new_email' => $this->newEmail, + 'error' => $e->getMessage(), + 'attempt' => $this->attempts(), + ]); + + // Re-throw to trigger retry + throw $e; + } + } + + public function failed(\Throwable $exception): void + { + Log::error('Permanently failed to update Stripe customer email after all retries', [ + 'team_id' => $this->team->id, + 'user_id' => $this->userId, + 'old_email' => $this->oldEmail, + 'new_email' => $this->newEmail, + 'error' => $exception->getMessage(), + ]); + } +} diff --git a/app/Livewire/Dashboard.php b/app/Livewire/Dashboard.php index edbdd25fe..18dbde0d3 100644 --- a/app/Livewire/Dashboard.php +++ b/app/Livewire/Dashboard.php @@ -2,6 +2,7 @@ namespace App\Livewire; +use App\Models\Application; use App\Models\ApplicationDeploymentQueue; use App\Models\PrivateKey; use App\Models\Project; @@ -30,6 +31,12 @@ class Dashboard extends Component public function cleanupQueue() { + try { + $this->authorize('cleanupDeploymentQueue', Application::class); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + return handleError($e, $this); + } + Artisan::queue('cleanup:deployment-queue', [ '--team-id' => currentTeam()->id, ]); diff --git a/app/Livewire/Destination/New/Docker.php b/app/Livewire/Destination/New/Docker.php index eb768d191..819ac3ecd 100644 --- a/app/Livewire/Destination/New/Docker.php +++ b/app/Livewire/Destination/New/Docker.php @@ -5,6 +5,7 @@ namespace App\Livewire\Destination\New; use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; use Livewire\Component; @@ -12,6 +13,8 @@ use Visus\Cuid2\Cuid2; class Docker extends Component { + use AuthorizesRequests; + #[Locked] public $servers; @@ -67,6 +70,7 @@ class Docker extends Component public function submit() { try { + $this->authorize('create', StandaloneDocker::class); $this->validate(); if ($this->isSwarm) { $found = $this->selectedServer->swarmDockers()->where('network', $this->network)->first(); diff --git a/app/Livewire/Destination/Show.php b/app/Livewire/Destination/Show.php index 5c4d6c170..98cf72376 100644 --- a/app/Livewire/Destination/Show.php +++ b/app/Livewire/Destination/Show.php @@ -5,12 +5,15 @@ namespace App\Livewire\Destination; use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + #[Locked] public $destination; @@ -63,6 +66,8 @@ class Show extends Component public function submit() { try { + $this->authorize('update', $this->destination); + $this->syncData(true); $this->dispatch('success', 'Destination saved.'); } catch (\Throwable $e) { @@ -73,6 +78,8 @@ class Show extends Component public function delete() { try { + $this->authorize('delete', $this->destination); + if ($this->destination->getMorphClass() === \App\Models\StandaloneDocker::class) { if ($this->destination->attachedTo()) { return $this->dispatch('error', 'You must delete all resources before deleting this destination.'); diff --git a/app/Livewire/Notifications/Discord.php b/app/Livewire/Notifications/Discord.php index e0425fa17..28d1cb866 100644 --- a/app/Livewire/Notifications/Discord.php +++ b/app/Livewire/Notifications/Discord.php @@ -5,11 +5,14 @@ namespace App\Livewire\Notifications; use App\Models\DiscordNotificationSettings; use App\Models\Team; use App\Notifications\Test; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Validate; use Livewire\Component; class Discord extends Component { + use AuthorizesRequests; + public Team $team; public DiscordNotificationSettings $settings; @@ -67,6 +70,7 @@ class Discord extends Component try { $this->team = auth()->user()->currentTeam(); $this->settings = $this->team->discordNotificationSettings; + $this->authorize('view', $this->settings); $this->syncData(); } catch (\Throwable $e) { return handleError($e, $this); @@ -77,6 +81,7 @@ class Discord extends Component { if ($toModel) { $this->validate(); + $this->authorize('update', $this->settings); $this->settings->discord_enabled = $this->discordEnabled; $this->settings->discord_webhook_url = $this->discordWebhookUrl; @@ -182,6 +187,7 @@ class Discord extends Component public function sendTestNotification() { try { + $this->authorize('sendTest', $this->settings); $this->team->notify(new Test(channel: 'discord')); $this->dispatch('success', 'Test notification sent.'); } catch (\Throwable $e) { diff --git a/app/Livewire/Notifications/Email.php b/app/Livewire/Notifications/Email.php index 128321ed2..d62a08417 100644 --- a/app/Livewire/Notifications/Email.php +++ b/app/Livewire/Notifications/Email.php @@ -5,6 +5,7 @@ namespace App\Livewire\Notifications; use App\Models\EmailNotificationSettings; use App\Models\Team; use App\Notifications\Test; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\RateLimiter; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; @@ -12,6 +13,8 @@ use Livewire\Component; class Email extends Component { + use AuthorizesRequests; + protected $listeners = ['refresh' => '$refresh']; #[Locked] @@ -110,6 +113,7 @@ class Email extends Component $this->team = auth()->user()->currentTeam(); $this->emails = auth()->user()->email; $this->settings = $this->team->emailNotificationSettings; + $this->authorize('view', $this->settings); $this->syncData(); $this->testEmailAddress = auth()->user()->email; } catch (\Throwable $e) { @@ -121,6 +125,7 @@ class Email extends Component { if ($toModel) { $this->validate(); + $this->authorize('update', $this->settings); $this->settings->smtp_enabled = $this->smtpEnabled; $this->settings->smtp_from_address = $this->smtpFromAddress; $this->settings->smtp_from_name = $this->smtpFromName; @@ -311,6 +316,7 @@ class Email extends Component public function sendTestEmail() { try { + $this->authorize('sendTest', $this->settings); $this->validate([ 'testEmailAddress' => 'required|email', ], [ @@ -338,6 +344,7 @@ class Email extends Component public function copyFromInstanceSettings() { + $this->authorize('update', $this->settings); $settings = instanceSettings(); $this->smtpFromAddress = $settings->smtp_from_address; $this->smtpFromName = $settings->smtp_from_name; diff --git a/app/Livewire/Notifications/Pushover.php b/app/Livewire/Notifications/Pushover.php index bd5ab79c8..9c7ff64ad 100644 --- a/app/Livewire/Notifications/Pushover.php +++ b/app/Livewire/Notifications/Pushover.php @@ -5,12 +5,15 @@ namespace App\Livewire\Notifications; use App\Models\PushoverNotificationSettings; use App\Models\Team; use App\Notifications\Test; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; use Livewire\Component; class Pushover extends Component { + use AuthorizesRequests; + protected $listeners = ['refresh' => '$refresh']; #[Locked] @@ -72,6 +75,7 @@ class Pushover extends Component try { $this->team = auth()->user()->currentTeam(); $this->settings = $this->team->pushoverNotificationSettings; + $this->authorize('view', $this->settings); $this->syncData(); } catch (\Throwable $e) { return handleError($e, $this); @@ -82,6 +86,7 @@ class Pushover extends Component { if ($toModel) { $this->validate(); + $this->authorize('update', $this->settings); $this->settings->pushover_enabled = $this->pushoverEnabled; $this->settings->pushover_user_key = $this->pushoverUserKey; $this->settings->pushover_api_token = $this->pushoverApiToken; @@ -175,6 +180,7 @@ class Pushover extends Component public function sendTestNotification() { try { + $this->authorize('sendTest', $this->settings); $this->team->notify(new Test(channel: 'pushover')); $this->dispatch('success', 'Test notification sent.'); } catch (\Throwable $e) { diff --git a/app/Livewire/Notifications/Slack.php b/app/Livewire/Notifications/Slack.php index 9c847ce57..d21399c42 100644 --- a/app/Livewire/Notifications/Slack.php +++ b/app/Livewire/Notifications/Slack.php @@ -5,12 +5,15 @@ namespace App\Livewire\Notifications; use App\Models\SlackNotificationSettings; use App\Models\Team; use App\Notifications\Test; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; use Livewire\Component; class Slack extends Component { + use AuthorizesRequests; + protected $listeners = ['refresh' => '$refresh']; #[Locked] @@ -69,6 +72,7 @@ class Slack extends Component try { $this->team = auth()->user()->currentTeam(); $this->settings = $this->team->slackNotificationSettings; + $this->authorize('view', $this->settings); $this->syncData(); } catch (\Throwable $e) { return handleError($e, $this); @@ -79,6 +83,7 @@ class Slack extends Component { if ($toModel) { $this->validate(); + $this->authorize('update', $this->settings); $this->settings->slack_enabled = $this->slackEnabled; $this->settings->slack_webhook_url = $this->slackWebhookUrl; @@ -168,6 +173,7 @@ class Slack extends Component public function sendTestNotification() { try { + $this->authorize('sendTest', $this->settings); $this->team->notify(new Test(channel: 'slack')); $this->dispatch('success', 'Test notification sent.'); } catch (\Throwable $e) { diff --git a/app/Livewire/Notifications/Telegram.php b/app/Livewire/Notifications/Telegram.php index 07393d4ea..ca9df47c1 100644 --- a/app/Livewire/Notifications/Telegram.php +++ b/app/Livewire/Notifications/Telegram.php @@ -5,12 +5,15 @@ namespace App\Livewire\Notifications; use App\Models\Team; use App\Models\TelegramNotificationSettings; use App\Notifications\Test; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; use Livewire\Component; class Telegram extends Component { + use AuthorizesRequests; + protected $listeners = ['refresh' => '$refresh']; #[Locked] @@ -111,6 +114,7 @@ class Telegram extends Component try { $this->team = auth()->user()->currentTeam(); $this->settings = $this->team->telegramNotificationSettings; + $this->authorize('view', $this->settings); $this->syncData(); } catch (\Throwable $e) { return handleError($e, $this); @@ -121,6 +125,7 @@ class Telegram extends Component { if ($toModel) { $this->validate(); + $this->authorize('update', $this->settings); $this->settings->telegram_enabled = $this->telegramEnabled; $this->settings->telegram_token = $this->telegramToken; $this->settings->telegram_chat_id = $this->telegramChatId; @@ -241,6 +246,7 @@ class Telegram extends Component public function sendTestNotification() { try { + $this->authorize('sendTest', $this->settings); $this->team->notify(new Test(channel: 'telegram')); $this->dispatch('success', 'Test notification sent.'); } catch (\Throwable $e) { diff --git a/app/Livewire/Profile/Index.php b/app/Livewire/Profile/Index.php index 788802353..a6b4dbe9e 100644 --- a/app/Livewire/Profile/Index.php +++ b/app/Livewire/Profile/Index.php @@ -4,6 +4,7 @@ namespace App\Livewire\Profile; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\RateLimiter; use Illuminate\Validation\Rules\Password; use Livewire\Attributes\Validate; use Livewire\Component; @@ -23,11 +24,25 @@ class Index extends Component #[Validate('required')] public string $name; + public string $new_email = ''; + + public string $email_verification_code = ''; + + public bool $show_email_change = false; + + public bool $show_verification = false; + public function mount() { $this->userId = Auth::id(); $this->name = Auth::user()->name; $this->email = Auth::user()->email; + + // Check if there's a pending email change + if (Auth::user()->hasEmailChangeRequest()) { + $this->new_email = Auth::user()->pending_email; + $this->show_verification = true; + } } public function submit() @@ -46,6 +61,180 @@ class Index extends Component } } + public function requestEmailChange() + { + try { + // For self-hosted, check if email is enabled + if (! isCloud()) { + $settings = instanceSettings(); + if (! $settings->smtp_enabled && ! $settings->resend_enabled) { + $this->dispatch('error', 'Email functionality is not configured. Please contact your administrator.'); + + return; + } + } + + $this->validate([ + 'new_email' => ['required', 'email', 'unique:users,email'], + ]); + + // Skip rate limiting in development mode + if (! isDev()) { + // Rate limit by current user's email (1 request per 2 minutes) + $userEmailKey = 'email-change:user:'.Auth::id(); + if (! RateLimiter::attempt($userEmailKey, 1, function () {}, 120)) { + $seconds = RateLimiter::availableIn($userEmailKey); + $this->dispatch('error', 'Too many requests. Please wait '.$seconds.' seconds before trying again.'); + + return; + } + + // Rate limit by new email address (3 requests per hour per email) + $newEmailKey = 'email-change:email:'.md5(strtolower($this->new_email)); + if (! RateLimiter::attempt($newEmailKey, 3, function () {}, 3600)) { + $this->dispatch('error', 'This email address has received too many verification requests. Please try again later.'); + + return; + } + + // Additional rate limit by IP address (5 requests per hour) + $ipKey = 'email-change:ip:'.request()->ip(); + if (! RateLimiter::attempt($ipKey, 5, function () {}, 3600)) { + $this->dispatch('error', 'Too many requests from your IP address. Please try again later.'); + + return; + } + } + + Auth::user()->requestEmailChange($this->new_email); + + $this->show_email_change = false; + $this->show_verification = true; + + $this->dispatch('success', 'Verification code sent to '.$this->new_email); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + + public function verifyEmailChange() + { + try { + $this->validate([ + 'email_verification_code' => ['required', 'string', 'size:6'], + ]); + + // Skip rate limiting in development mode + if (! isDev()) { + // Rate limit verification attempts (5 attempts per 10 minutes) + $verifyKey = 'email-verify:user:'.Auth::id(); + if (! RateLimiter::attempt($verifyKey, 5, function () {}, 600)) { + $seconds = RateLimiter::availableIn($verifyKey); + $minutes = ceil($seconds / 60); + $this->dispatch('error', 'Too many verification attempts. Please wait '.$minutes.' minutes before trying again.'); + + // If too many failed attempts, clear the email change request for security + if (RateLimiter::attempts($verifyKey) >= 10) { + Auth::user()->clearEmailChangeRequest(); + $this->new_email = ''; + $this->email_verification_code = ''; + $this->show_verification = false; + $this->dispatch('error', 'Email change request cancelled due to too many failed attempts. Please start over.'); + } + + return; + } + } + + if (! Auth::user()->isEmailChangeCodeValid($this->email_verification_code)) { + $this->dispatch('error', 'Invalid or expired verification code.'); + + return; + } + + if (Auth::user()->confirmEmailChange($this->email_verification_code)) { + // Clear rate limiters on successful verification (only in production) + if (! isDev()) { + $verifyKey = 'email-verify:user:'.Auth::id(); + RateLimiter::clear($verifyKey); + } + + $this->email = Auth::user()->email; + $this->new_email = ''; + $this->email_verification_code = ''; + $this->show_verification = false; + + $this->dispatch('success', 'Email address updated successfully.'); + } else { + $this->dispatch('error', 'Failed to update email address.'); + } + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + + public function resendVerificationCode() + { + try { + // Check if there's a pending request + if (! Auth::user()->hasEmailChangeRequest()) { + $this->dispatch('error', 'No pending email change request.'); + + return; + } + + // Check if enough time has passed (at least half of the expiry time) + $expiryMinutes = config('constants.email_change.verification_code_expiry_minutes', 10); + $halfExpiryMinutes = $expiryMinutes / 2; + $codeExpiry = Auth::user()->email_change_code_expires_at; + $timeSinceCreated = $codeExpiry->subMinutes($expiryMinutes)->diffInMinutes(now()); + + if ($timeSinceCreated < $halfExpiryMinutes) { + $minutesToWait = ceil($halfExpiryMinutes - $timeSinceCreated); + $this->dispatch('error', 'Please wait '.$minutesToWait.' more minutes before requesting a new code.'); + + return; + } + + $pendingEmail = Auth::user()->pending_email; + + // Skip rate limiting in development mode + if (! isDev()) { + // Rate limit by email address + $newEmailKey = 'email-change:email:'.md5(strtolower($pendingEmail)); + if (! RateLimiter::attempt($newEmailKey, 3, function () {}, 3600)) { + $this->dispatch('error', 'This email address has received too many verification requests. Please try again later.'); + + return; + } + } + + // Generate and send new code + Auth::user()->requestEmailChange($pendingEmail); + + $this->dispatch('success', 'New verification code sent to '.$pendingEmail); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + + public function cancelEmailChange() + { + Auth::user()->clearEmailChangeRequest(); + $this->new_email = ''; + $this->email_verification_code = ''; + $this->show_email_change = false; + $this->show_verification = false; + + $this->dispatch('success', 'Email change request cancelled.'); + } + + public function showEmailChangeForm() + { + $this->show_email_change = true; + $this->new_email = ''; + } + public function resetPassword() { try { diff --git a/app/Livewire/Project/AddEmpty.php b/app/Livewire/Project/AddEmpty.php index 07873c059..751b4945b 100644 --- a/app/Livewire/Project/AddEmpty.php +++ b/app/Livewire/Project/AddEmpty.php @@ -3,18 +3,29 @@ namespace App\Livewire\Project; use App\Models\Project; -use Livewire\Attributes\Validate; +use App\Support\ValidationPatterns; use Livewire\Component; use Visus\Cuid2\Cuid2; class AddEmpty extends Component { - #[Validate(['required', 'string', 'min:3'])] public string $name; - #[Validate(['nullable', 'string'])] public string $description = ''; + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + ]; + } + + protected function messages(): array + { + return ValidationPatterns::combinedMessages(); + } + public function submit() { try { diff --git a/app/Livewire/Project/Application/Advanced.php b/app/Livewire/Project/Application/Advanced.php index bd1388806..862dc20d8 100644 --- a/app/Livewire/Project/Application/Advanced.php +++ b/app/Livewire/Project/Application/Advanced.php @@ -3,11 +3,14 @@ namespace App\Livewire\Project\Application; use App\Models\Application; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Validate; use Livewire\Component; class Advanced extends Component { + use AuthorizesRequests; + public Application $application; #[Validate(['boolean'])] @@ -19,6 +22,9 @@ class Advanced extends Component #[Validate(['boolean'])] public bool $isGitLfsEnabled = false; + #[Validate(['boolean'])] + public bool $isGitShallowCloneEnabled = false; + #[Validate(['boolean'])] public bool $isPreviewDeploymentsEnabled = false; @@ -83,6 +89,7 @@ class Advanced extends Component $this->application->settings->is_force_https_enabled = $this->isForceHttpsEnabled; $this->application->settings->is_git_submodules_enabled = $this->isGitSubmodulesEnabled; $this->application->settings->is_git_lfs_enabled = $this->isGitLfsEnabled; + $this->application->settings->is_git_shallow_clone_enabled = $this->isGitShallowCloneEnabled; $this->application->settings->is_preview_deployments_enabled = $this->isPreviewDeploymentsEnabled; $this->application->settings->is_auto_deploy_enabled = $this->isAutoDeployEnabled; $this->application->settings->is_log_drain_enabled = $this->isLogDrainEnabled; @@ -108,6 +115,7 @@ class Advanced extends Component $this->isGitSubmodulesEnabled = $this->application->settings->is_git_submodules_enabled; $this->isGitLfsEnabled = $this->application->settings->is_git_lfs_enabled; + $this->isGitShallowCloneEnabled = $this->application->settings->is_git_shallow_clone_enabled ?? false; $this->isPreviewDeploymentsEnabled = $this->application->settings->is_preview_deployments_enabled; $this->isAutoDeployEnabled = $this->application->settings->is_auto_deploy_enabled; $this->isGpuEnabled = $this->application->settings->is_gpu_enabled; @@ -137,6 +145,7 @@ class Advanced extends Component public function instantSave() { try { + $this->authorize('update', $this->application); $reset = false; if ($this->isLogDrainEnabled) { if (! $this->application->destination->server->isLogDrainEnabled()) { @@ -175,6 +184,7 @@ class Advanced extends Component public function submit() { try { + $this->authorize('update', $this->application); if ($this->gpuCount && $this->gpuDeviceIds) { $this->dispatch('error', 'You cannot set both GPU count and GPU device IDs.'); $this->gpuCount = null; @@ -192,33 +202,39 @@ class Advanced extends Component public function saveCustomName() { - if (str($this->customInternalName)->isNotEmpty()) { - $this->customInternalName = str($this->customInternalName)->slug()->value(); - } else { - $this->customInternalName = null; - } - if (is_null($this->customInternalName)) { + try { + $this->authorize('update', $this->application); + + if (str($this->customInternalName)->isNotEmpty()) { + $this->customInternalName = str($this->customInternalName)->slug()->value(); + } else { + $this->customInternalName = null; + } + if (is_null($this->customInternalName)) { + $this->syncData(true); + $this->dispatch('success', 'Custom name saved.'); + + return; + } + $customInternalName = $this->customInternalName; + $server = $this->application->destination->server; + $allApplications = $server->applications(); + + $foundSameInternalName = $allApplications->filter(function ($application) { + return $application->id !== $this->application->id && $application->settings->custom_internal_name === $this->customInternalName; + }); + if ($foundSameInternalName->isNotEmpty()) { + $this->dispatch('error', 'This custom container name is already in use by another application on this server.'); + $this->customInternalName = $customInternalName; + $this->syncData(true); + + return; + } $this->syncData(true); $this->dispatch('success', 'Custom name saved.'); - - return; + } catch (\Throwable $e) { + return handleError($e, $this); } - $customInternalName = $this->customInternalName; - $server = $this->application->destination->server; - $allApplications = $server->applications(); - - $foundSameInternalName = $allApplications->filter(function ($application) { - return $application->id !== $this->application->id && $application->settings->custom_internal_name === $this->customInternalName; - }); - if ($foundSameInternalName->isNotEmpty()) { - $this->dispatch('error', 'This custom container name is already in use by another application on this server.'); - $this->customInternalName = $customInternalName; - $this->syncData(true); - - return; - } - $this->syncData(true); - $this->dispatch('success', 'Custom name saved.'); } public function render() diff --git a/app/Livewire/Project/Application/Deployment/Index.php b/app/Livewire/Project/Application/Deployment/Index.php index c957615ac..5b621cb95 100644 --- a/app/Livewire/Project/Application/Deployment/Index.php +++ b/app/Livewire/Project/Application/Deployment/Index.php @@ -18,11 +18,13 @@ class Index extends Component public int $skip = 0; - public int $default_take = 10; + public int $defaultTake = 10; - public bool $show_next = false; + public bool $showNext = false; - public bool $show_prev = false; + public bool $showPrev = false; + + public int $currentPage = 1; public ?string $pull_request_id = null; @@ -51,68 +53,111 @@ class Index extends Component if (! $application) { return redirect()->route('dashboard'); } - ['deployments' => $deployments, 'count' => $count] = $application->deployments(0, $this->default_take); + // Validate pull request ID from URL parameters + if ($this->pull_request_id !== null && $this->pull_request_id !== '') { + if (! is_numeric($this->pull_request_id) || (float) $this->pull_request_id <= 0 || (float) $this->pull_request_id != (int) $this->pull_request_id) { + $this->pull_request_id = null; + $this->dispatch('error', 'Invalid Pull Request ID in URL. Filter cleared.'); + } else { + // Ensure it's stored as a string representation of a positive integer + $this->pull_request_id = (string) (int) $this->pull_request_id; + } + } + + ['deployments' => $deployments, 'count' => $count] = $application->deployments(0, $this->defaultTake, $this->pull_request_id); $this->application = $application; $this->deployments = $deployments; $this->deployments_count = $count; $this->current_url = url()->current(); - $this->show_pull_request_only(); - $this->show_more(); + $this->updateCurrentPage(); + $this->showMore(); } - private function show_pull_request_only() - { - if ($this->pull_request_id) { - $this->deployments = $this->deployments->where('pull_request_id', $this->pull_request_id); - } - } - - private function show_more() + private function showMore() { if ($this->deployments->count() !== 0) { - $this->show_next = true; - if ($this->deployments->count() < $this->default_take) { - $this->show_next = false; + $this->showNext = true; + if ($this->deployments->count() < $this->defaultTake) { + $this->showNext = false; } return; } } - public function reload_deployments() + public function reloadDeployments() { - $this->load_deployments(); + $this->loadDeployments(); } - public function previous_page(?int $take = null) + public function previousPage(?int $take = null) { if ($take) { $this->skip = $this->skip - $take; } - $this->skip = $this->skip - $this->default_take; + $this->skip = $this->skip - $this->defaultTake; if ($this->skip < 0) { - $this->show_prev = false; + $this->showPrev = false; $this->skip = 0; } - $this->load_deployments(); + $this->updateCurrentPage(); + $this->loadDeployments(); } - public function next_page(?int $take = null) + public function nextPage(?int $take = null) { if ($take) { $this->skip = $this->skip + $take; } - $this->show_prev = true; - $this->load_deployments(); + $this->showPrev = true; + $this->updateCurrentPage(); + $this->loadDeployments(); } - public function load_deployments() + public function loadDeployments() { - ['deployments' => $deployments, 'count' => $count] = $this->application->deployments($this->skip, $this->default_take); + ['deployments' => $deployments, 'count' => $count] = $this->application->deployments($this->skip, $this->defaultTake, $this->pull_request_id); $this->deployments = $deployments; $this->deployments_count = $count; - $this->show_pull_request_only(); - $this->show_more(); + $this->showMore(); + } + + public function updatedPullRequestId($value) + { + // Sanitize and validate the pull request ID + if ($value !== null && $value !== '') { + // Check if it's numeric and positive + if (! is_numeric($value) || (float) $value <= 0 || (float) $value != (int) $value) { + $this->pull_request_id = null; + $this->dispatch('error', 'Invalid Pull Request ID. Please enter a valid positive number.'); + + return; + } + // Ensure it's stored as a string representation of a positive integer + $this->pull_request_id = (string) (int) $value; + } else { + $this->pull_request_id = null; + } + + // Reset pagination when filter changes + $this->skip = 0; + $this->showPrev = false; + $this->updateCurrentPage(); + $this->loadDeployments(); + } + + public function clearFilter() + { + $this->pull_request_id = null; + $this->skip = 0; + $this->showPrev = false; + $this->updateCurrentPage(); + $this->loadDeployments(); + } + + private function updateCurrentPage() + { + $this->currentPage = intval($this->skip / $this->defaultTake) + 1; } public function render() diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index 74f47232c..3107ef4cb 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -4,6 +4,8 @@ namespace App\Livewire\Project\Application; use App\Actions\Application\GenerateConfig; use App\Models\Application; +use App\Support\ValidationPatterns; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Component; use Spatie\Url\Url; @@ -11,6 +13,8 @@ use Visus\Cuid2\Cuid2; class General extends Component { + use AuthorizesRequests; + public string $applicationId; public Application $application; @@ -52,52 +56,89 @@ class General extends Component 'configurationChanged' => '$refresh', ]; - protected $rules = [ - 'application.name' => 'required', - 'application.description' => 'nullable', - 'application.fqdn' => 'nullable', - 'application.git_repository' => 'required', - 'application.git_branch' => 'required', - 'application.git_commit_sha' => 'nullable', - 'application.install_command' => 'nullable', - 'application.build_command' => 'nullable', - 'application.start_command' => 'nullable', - 'application.build_pack' => 'required', - 'application.static_image' => 'required', - 'application.base_directory' => 'required', - 'application.publish_directory' => 'nullable', - 'application.ports_exposes' => 'required', - 'application.ports_mappings' => 'nullable', - 'application.custom_network_aliases' => 'nullable', - 'application.dockerfile' => 'nullable', - 'application.docker_registry_image_name' => 'nullable', - 'application.docker_registry_image_tag' => 'nullable', - 'application.dockerfile_location' => 'nullable', - 'application.docker_compose_location' => 'nullable', - 'application.docker_compose' => 'nullable', - 'application.docker_compose_raw' => 'nullable', - 'application.dockerfile_target_build' => 'nullable', - 'application.docker_compose_custom_start_command' => 'nullable', - 'application.docker_compose_custom_build_command' => 'nullable', - 'application.custom_labels' => 'nullable', - 'application.custom_docker_run_options' => 'nullable', - 'application.pre_deployment_command' => 'nullable', - 'application.pre_deployment_command_container' => 'nullable', - 'application.post_deployment_command' => 'nullable', - 'application.post_deployment_command_container' => 'nullable', - 'application.custom_nginx_configuration' => 'nullable', - 'application.settings.is_static' => 'boolean|required', - 'application.settings.is_spa' => 'boolean|required', - 'application.settings.is_build_server_enabled' => 'boolean|required', - 'application.settings.is_container_label_escape_enabled' => 'boolean|required', - 'application.settings.is_container_label_readonly_enabled' => 'boolean|required', - 'application.settings.is_preserve_repository_enabled' => 'boolean|required', - 'application.is_http_basic_auth_enabled' => 'boolean|required', - 'application.http_basic_auth_username' => 'string|nullable', - 'application.http_basic_auth_password' => 'string|nullable', - 'application.watch_paths' => 'nullable', - 'application.redirect' => 'string|required', - ]; + protected function rules(): array + { + return [ + 'application.name' => ValidationPatterns::nameRules(), + 'application.description' => ValidationPatterns::descriptionRules(), + 'application.fqdn' => 'nullable', + 'application.git_repository' => 'required', + 'application.git_branch' => 'required', + 'application.git_commit_sha' => 'nullable', + 'application.install_command' => 'nullable', + 'application.build_command' => 'nullable', + 'application.start_command' => 'nullable', + 'application.build_pack' => 'required', + 'application.static_image' => 'required', + 'application.base_directory' => 'required', + 'application.publish_directory' => 'nullable', + 'application.ports_exposes' => 'required', + 'application.ports_mappings' => 'nullable', + 'application.custom_network_aliases' => 'nullable', + 'application.dockerfile' => 'nullable', + 'application.docker_registry_image_name' => 'nullable', + 'application.docker_registry_image_tag' => 'nullable', + 'application.dockerfile_location' => 'nullable', + 'application.docker_compose_location' => 'nullable', + 'application.docker_compose' => 'nullable', + 'application.docker_compose_raw' => 'nullable', + 'application.dockerfile_target_build' => 'nullable', + 'application.docker_compose_custom_start_command' => 'nullable', + 'application.docker_compose_custom_build_command' => 'nullable', + 'application.custom_labels' => 'nullable', + 'application.custom_docker_run_options' => 'nullable', + 'application.pre_deployment_command' => 'nullable', + 'application.pre_deployment_command_container' => 'nullable', + 'application.post_deployment_command' => 'nullable', + 'application.post_deployment_command_container' => 'nullable', + 'application.custom_nginx_configuration' => 'nullable', + 'application.settings.is_static' => 'boolean|required', + 'application.settings.is_spa' => 'boolean|required', + 'application.settings.is_build_server_enabled' => 'boolean|required', + 'application.settings.is_container_label_escape_enabled' => 'boolean|required', + 'application.settings.is_container_label_readonly_enabled' => 'boolean|required', + 'application.settings.is_preserve_repository_enabled' => 'boolean|required', + 'application.is_http_basic_auth_enabled' => 'boolean|required', + 'application.http_basic_auth_username' => 'string|nullable', + 'application.http_basic_auth_password' => 'string|nullable', + 'application.watch_paths' => 'nullable', + 'application.redirect' => 'string|required', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'application.name.required' => 'The Name field is required.', + 'application.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'application.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'application.git_repository.required' => 'The Git Repository field is required.', + 'application.git_branch.required' => 'The Git Branch field is required.', + 'application.build_pack.required' => 'The Build Pack field is required.', + 'application.static_image.required' => 'The Static Image field is required.', + 'application.base_directory.required' => 'The Base Directory field is required.', + 'application.ports_exposes.required' => 'The Exposed Ports field is required.', + 'application.settings.is_static.required' => 'The Static setting is required.', + 'application.settings.is_static.boolean' => 'The Static setting must be true or false.', + 'application.settings.is_spa.required' => 'The SPA setting is required.', + 'application.settings.is_spa.boolean' => 'The SPA setting must be true or false.', + 'application.settings.is_build_server_enabled.required' => 'The Build Server setting is required.', + 'application.settings.is_build_server_enabled.boolean' => 'The Build Server setting must be true or false.', + 'application.settings.is_container_label_escape_enabled.required' => 'The Container Label Escape setting is required.', + 'application.settings.is_container_label_escape_enabled.boolean' => 'The Container Label Escape setting must be true or false.', + 'application.settings.is_container_label_readonly_enabled.required' => 'The Container Label Readonly setting is required.', + 'application.settings.is_container_label_readonly_enabled.boolean' => 'The Container Label Readonly setting must be true or false.', + 'application.settings.is_preserve_repository_enabled.required' => 'The Preserve Repository setting is required.', + 'application.settings.is_preserve_repository_enabled.boolean' => 'The Preserve Repository setting must be true or false.', + 'application.is_http_basic_auth_enabled.required' => 'The HTTP Basic Auth setting is required.', + 'application.is_http_basic_auth_enabled.boolean' => 'The HTTP Basic Auth setting must be true or false.', + 'application.redirect.required' => 'The Redirect setting is required.', + 'application.redirect.string' => 'The Redirect setting must be a string.', + ] + ); + } protected $validationAttributes = [ 'application.name' => 'name', @@ -152,23 +193,50 @@ class General extends Component $this->dispatch('error', $e->getMessage()); } if ($this->application->build_pack === 'dockercompose') { - $this->application->fqdn = null; - $this->application->settings->save(); + // Only update if user has permission + try { + $this->authorize('update', $this->application); + $this->application->fqdn = null; + $this->application->settings->save(); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + // User doesn't have update permission, just continue without saving + } } $this->parsedServiceDomains = $this->application->docker_compose_domains ? json_decode($this->application->docker_compose_domains, true) : []; + // Convert service names with dots to use underscores for HTML form binding + $sanitizedDomains = []; + foreach ($this->parsedServiceDomains as $serviceName => $domain) { + $sanitizedKey = str($serviceName)->slug('_')->toString(); + $sanitizedDomains[$sanitizedKey] = $domain; + } + $this->parsedServiceDomains = $sanitizedDomains; + $this->ports_exposes = $this->application->ports_exposes; $this->is_preserve_repository_enabled = $this->application->settings->is_preserve_repository_enabled; $this->is_container_label_escape_enabled = $this->application->settings->is_container_label_escape_enabled; $this->customLabels = $this->application->parseContainerLabels(); if (! $this->customLabels && $this->application->destination->server->proxyType() !== 'NONE' && $this->application->settings->is_container_label_readonly_enabled === true) { - $this->customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n"); - $this->application->custom_labels = base64_encode($this->customLabels); - $this->application->save(); + // Only update custom labels if user has permission + try { + $this->authorize('update', $this->application); + $this->customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n"); + $this->application->custom_labels = base64_encode($this->customLabels); + $this->application->save(); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + // User doesn't have update permission, just use existing labels + // $this->customLabels = str(implode('|coolify|', generateLabelsApplication($this->application)))->replace('|coolify|', "\n"); + } } $this->initialDockerComposeLocation = $this->application->docker_compose_location; if ($this->application->build_pack === 'dockercompose' && ! $this->application->docker_compose_raw) { - $this->initLoadingCompose = true; - $this->dispatch('info', 'Loading docker compose file.'); + // Only load compose file if user has update permission + try { + $this->authorize('update', $this->application); + $this->initLoadingCompose = true; + $this->dispatch('info', 'Loading docker compose file.'); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + // User doesn't have update permission, skip loading compose file + } } if (str($this->application->status)->startsWith('running') && is_null($this->application->config_hash)) { @@ -178,53 +246,67 @@ class General extends Component public function instantSave() { - if ($this->application->settings->isDirty('is_spa')) { - $this->generateNginxConfiguration($this->application->settings->is_spa ? 'spa' : 'static'); - } - if ($this->application->isDirty('is_http_basic_auth_enabled')) { - $this->application->save(); - } - $this->application->settings->save(); - $this->dispatch('success', 'Settings saved.'); - $this->application->refresh(); + try { + $this->authorize('update', $this->application); - // If port_exposes changed, reset default labels - if ($this->ports_exposes !== $this->application->ports_exposes || $this->is_container_label_escape_enabled !== $this->application->settings->is_container_label_escape_enabled) { - $this->resetDefaultLabels(false); - } - if ($this->is_preserve_repository_enabled !== $this->application->settings->is_preserve_repository_enabled) { - if ($this->application->settings->is_preserve_repository_enabled === false) { - $this->application->fileStorages->each(function ($storage) { - $storage->is_based_on_git = $this->application->settings->is_preserve_repository_enabled; - $storage->save(); - }); + if ($this->application->settings->isDirty('is_spa')) { + $this->generateNginxConfiguration($this->application->settings->is_spa ? 'spa' : 'static'); } - } - if ($this->application->settings->is_container_label_readonly_enabled) { - $this->resetDefaultLabels(false); - } + if ($this->application->isDirty('is_http_basic_auth_enabled')) { + $this->application->save(); + } + $this->application->settings->save(); + $this->dispatch('success', 'Settings saved.'); + $this->application->refresh(); + // If port_exposes changed, reset default labels + if ($this->ports_exposes !== $this->application->ports_exposes || $this->is_container_label_escape_enabled !== $this->application->settings->is_container_label_escape_enabled) { + $this->resetDefaultLabels(false); + } + if ($this->is_preserve_repository_enabled !== $this->application->settings->is_preserve_repository_enabled) { + if ($this->application->settings->is_preserve_repository_enabled === false) { + $this->application->fileStorages->each(function ($storage) { + $storage->is_based_on_git = $this->application->settings->is_preserve_repository_enabled; + $storage->save(); + }); + } + } + if ($this->application->settings->is_container_label_readonly_enabled) { + $this->resetDefaultLabels(false); + } + } catch (\Throwable $e) { + return handleError($e, $this); + } } - public function loadComposeFile($isInit = false) + public function loadComposeFile($isInit = false, $showToast = true) { try { + $this->authorize('update', $this->application); + if ($isInit && $this->application->docker_compose_raw) { return; } - // Must reload the application to get the latest database changes - // Why? Not sure, but it works. - // $this->application->refresh(); - ['parsedServices' => $this->parsedServices, 'initialDockerComposeLocation' => $this->initialDockerComposeLocation] = $this->application->loadComposeFile($isInit); if (is_null($this->parsedServices)) { - $this->dispatch('error', 'Failed to parse your docker-compose file. Please check the syntax and try again.'); + $showToast && $this->dispatch('error', 'Failed to parse your docker-compose file. Please check the syntax and try again.'); return; } - $this->application->parse(); - $this->dispatch('success', 'Docker compose file loaded.'); + + // Refresh parsedServiceDomains to reflect any changes in docker_compose_domains + $this->application->refresh(); + $this->parsedServiceDomains = $this->application->docker_compose_domains ? json_decode($this->application->docker_compose_domains, true) : []; + // Convert service names with dots to use underscores for HTML form binding + $sanitizedDomains = []; + foreach ($this->parsedServiceDomains as $serviceName => $domain) { + $sanitizedKey = str($serviceName)->slug('_')->toString(); + $sanitizedDomains[$sanitizedKey] = $domain; + } + $this->parsedServiceDomains = $sanitizedDomains; + + $showToast && $this->dispatch('success', 'Docker compose file loaded.'); $this->dispatch('compose_loaded'); $this->dispatch('refreshStorages'); $this->dispatch('refreshEnvs'); @@ -240,17 +322,41 @@ class General extends Component public function generateDomain(string $serviceName) { - $uuid = new Cuid2; - $domain = generateFqdn($this->application->destination->server, $uuid); - $this->parsedServiceDomains[$serviceName]['domain'] = $domain; - $this->application->docker_compose_domains = json_encode($this->parsedServiceDomains); - $this->application->save(); - $this->dispatch('success', 'Domain generated.'); - if ($this->application->build_pack === 'dockercompose') { - $this->loadComposeFile(); - } + try { + $this->authorize('update', $this->application); - return $domain; + $uuid = new Cuid2; + $domain = generateUrl(server: $this->application->destination->server, random: $uuid); + $sanitizedKey = str($serviceName)->slug('_')->toString(); + $this->parsedServiceDomains[$sanitizedKey]['domain'] = $domain; + + // Convert back to original service names for storage + $originalDomains = []; + foreach ($this->parsedServiceDomains as $key => $value) { + // Find the original service name by checking parsed services + $originalServiceName = $key; + if (isset($this->parsedServices['services'])) { + foreach ($this->parsedServices['services'] as $originalName => $service) { + if (str($originalName)->slug('_')->toString() === $key) { + $originalServiceName = $originalName; + break; + } + } + } + $originalDomains[$originalServiceName] = $value; + } + + $this->application->docker_compose_domains = json_encode($originalDomains); + $this->application->save(); + $this->dispatch('success', 'Domain generated.'); + if ($this->application->build_pack === 'dockercompose') { + $this->loadComposeFile(showToast: false); + } + + return $domain; + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function updatedApplicationBaseDirectory() @@ -269,6 +375,16 @@ class General extends Component public function updatedApplicationBuildPack() { + // Check if user has permission to update + try { + $this->authorize('update', $this->application); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + // User doesn't have permission, revert the change and return + $this->application->refresh(); + + return; + } + if ($this->application->build_pack !== 'nixpacks') { $this->application->settings->is_static = false; $this->application->settings->save(); @@ -277,8 +393,26 @@ class General extends Component $this->resetDefaultLabels(false); } if ($this->application->build_pack === 'dockercompose') { - $this->application->fqdn = null; - $this->application->settings->save(); + // Only update if user has permission + try { + $this->authorize('update', $this->application); + $this->application->fqdn = null; + $this->application->settings->save(); + } catch (\Illuminate\Auth\Access\AuthorizationException $e) { + // User doesn't have update permission, just continue without saving + } + } else { + // Clear Docker Compose specific data when switching away from dockercompose + if ($this->application->getOriginal('build_pack') === 'dockercompose') { + $this->application->docker_compose_domains = null; + $this->application->docker_compose_raw = null; + + // Remove SERVICE_FQDN_* and SERVICE_URL_* environment variables + $this->application->environment_variables()->where('key', 'LIKE', 'SERVICE_FQDN_%')->delete(); + $this->application->environment_variables()->where('key', 'LIKE', 'SERVICE_URL_%')->delete(); + $this->application->environment_variables_preview()->where('key', 'LIKE', 'SERVICE_FQDN_%')->delete(); + $this->application->environment_variables_preview()->where('key', 'LIKE', 'SERVICE_URL_%')->delete(); + } } if ($this->application->build_pack === 'static') { $this->application->ports_exposes = $this->ports_exposes = 80; @@ -291,21 +425,33 @@ class General extends Component public function getWildcardDomain() { - $server = data_get($this->application, 'destination.server'); - if ($server) { - $fqdn = generateFqdn($server, $this->application->uuid); - $this->application->fqdn = $fqdn; - $this->application->save(); - $this->resetDefaultLabels(); - $this->dispatch('success', 'Wildcard domain generated.'); + try { + $this->authorize('update', $this->application); + + $server = data_get($this->application, 'destination.server'); + if ($server) { + $fqdn = generateFqdn(server: $server, random: $this->application->uuid, parserVersion: $this->application->compose_parsing_version); + $this->application->fqdn = $fqdn; + $this->application->save(); + $this->resetDefaultLabels(); + $this->dispatch('success', 'Wildcard domain generated.'); + } + } catch (\Throwable $e) { + return handleError($e, $this); } } public function generateNginxConfiguration($type = 'static') { - $this->application->custom_nginx_configuration = defaultNginxConfiguration($type); - $this->application->save(); - $this->dispatch('success', 'Nginx configuration generated.'); + try { + $this->authorize('update', $this->application); + + $this->application->custom_nginx_configuration = defaultNginxConfiguration($type); + $this->application->save(); + $this->dispatch('success', 'Nginx configuration generated.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function resetDefaultLabels($manualReset = false) @@ -320,7 +466,7 @@ class General extends Component $this->application->custom_labels = base64_encode($this->customLabels); $this->application->save(); if ($this->application->build_pack === 'dockercompose') { - $this->loadComposeFile(); + $this->loadComposeFile(showToast: false); } $this->dispatch('configurationChanged'); } catch (\Throwable $e) { @@ -347,6 +493,8 @@ class General extends Component public function setRedirect() { + $this->authorize('update', $this->application); + try { $has_www = collect($this->application->fqdns)->filter(fn ($fqdn) => str($fqdn)->contains('www.'))->count(); if ($has_www === 0 && $this->application->redirect === 'www') { @@ -365,6 +513,7 @@ class General extends Component public function submit($showToaster = true) { try { + $this->authorize('update', $this->application); $this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim(); $this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim(); $this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) { @@ -397,7 +546,7 @@ class General extends Component } if ($this->application->build_pack === 'dockercompose' && $this->initialDockerComposeLocation !== $this->application->docker_compose_location) { - $compose_return = $this->loadComposeFile(); + $compose_return = $this->loadComposeFile(showToast: false); if ($compose_return instanceof \Livewire\Features\SupportEvents\Event) { return; } @@ -430,17 +579,17 @@ class General extends Component } if ($this->application->build_pack === 'dockercompose') { $this->application->docker_compose_domains = json_encode($this->parsedServiceDomains); - - foreach ($this->parsedServiceDomains as $serviceName => $service) { - $domain = data_get($service, 'domain'); - if ($domain) { - if (! validate_dns_entry($domain, $this->application->destination->server)) { - $showToaster && $this->dispatch('error', 'Validating DNS failed.', "Make sure you have added the DNS records correctly.<br><br>$domain->{$this->application->destination->server->ip}<br><br>Check this <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/dns-configuration'>documentation</a> for further help."); - } - check_domain_usage(resource: $this->application); - } - } if ($this->application->isDirty('docker_compose_domains')) { + foreach ($this->parsedServiceDomains as $service) { + $domain = data_get($service, 'domain'); + if ($domain) { + if (! validate_dns_entry($domain, $this->application->destination->server)) { + $showToaster && $this->dispatch('error', 'Validating DNS failed.', "Make sure you have added the DNS records correctly.<br><br>$domain->{$this->application->destination->server->ip}<br><br>Check this <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/dns-configuration'>documentation</a> for further help."); + } + } + } + check_domain_usage(resource: $this->application); + $this->application->save(); $this->resetDefaultLabels(); } } @@ -471,4 +620,75 @@ class General extends Component 'Content-Disposition' => 'attachment; filename='.$fileName, ]); } + + private function updateServiceEnvironmentVariables() + { + $domains = collect(json_decode($this->application->docker_compose_domains, true)) ?? collect([]); + + foreach ($domains as $serviceName => $service) { + $serviceNameFormatted = str($serviceName)->upper()->replace('-', '_'); + $domain = data_get($service, 'domain'); + // Delete SERVICE_FQDN_ and SERVICE_URL_ variables if domain is removed + $this->application->environment_variables()->where('resourceable_type', Application::class) + ->where('resourceable_id', $this->application->id) + ->where('key', 'LIKE', "SERVICE_FQDN_{$serviceNameFormatted}%") + ->delete(); + + $this->application->environment_variables()->where('resourceable_type', Application::class) + ->where('resourceable_id', $this->application->id) + ->where('key', 'LIKE', "SERVICE_URL_{$serviceNameFormatted}%") + ->delete(); + + if ($domain) { + // Create or update SERVICE_FQDN_ and SERVICE_URL_ variables + $fqdn = Url::fromString($domain); + $port = $fqdn->getPort(); + $path = $fqdn->getPath(); + $urlValue = $fqdn->getScheme().'://'.$fqdn->getHost(); + if ($path !== '/') { + $urlValue = $urlValue.$path; + } + $fqdnValue = str($domain)->after('://'); + if ($path !== '/') { + $fqdnValue = $fqdnValue.$path; + } + + // Create/update SERVICE_FQDN_ + $this->application->environment_variables()->updateOrCreate([ + 'key' => "SERVICE_FQDN_{$serviceNameFormatted}", + ], [ + 'value' => $fqdnValue, + 'is_build_time' => false, + 'is_preview' => false, + ]); + + // Create/update SERVICE_URL_ + $this->application->environment_variables()->updateOrCreate([ + 'key' => "SERVICE_URL_{$serviceNameFormatted}", + ], [ + 'value' => $urlValue, + 'is_build_time' => false, + 'is_preview' => false, + ]); + // Create/update port-specific variables if port exists + if (filled($port)) { + $this->application->environment_variables()->updateOrCreate([ + 'key' => "SERVICE_FQDN_{$serviceNameFormatted}_{$port}", + ], [ + 'value' => $fqdnValue, + 'is_build_time' => false, + 'is_preview' => false, + ]); + + $this->application->environment_variables()->updateOrCreate([ + 'key' => "SERVICE_URL_{$serviceNameFormatted}_{$port}", + ], [ + 'value' => $urlValue, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } + } + } + } } diff --git a/app/Livewire/Project/Application/Heading.php b/app/Livewire/Project/Application/Heading.php index 9fd4da68a..62c93611e 100644 --- a/app/Livewire/Project/Application/Heading.php +++ b/app/Livewire/Project/Application/Heading.php @@ -5,11 +5,14 @@ namespace App\Livewire\Project\Application; use App\Actions\Application\StopApplication; use App\Actions\Docker\GetContainersStatus; use App\Models\Application; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; use Visus\Cuid2\Cuid2; class Heading extends Component { + use AuthorizesRequests; + public Application $application; public ?string $lastDeploymentInfo = null; @@ -57,11 +60,15 @@ class Heading extends Component public function force_deploy_without_cache() { + $this->authorize('deploy', $this->application); + $this->deploy(force_rebuild: true); } public function deploy(bool $force_rebuild = false) { + $this->authorize('deploy', $this->application); + if ($this->application->build_pack === 'dockercompose' && is_null($this->application->docker_compose_raw)) { $this->dispatch('error', 'Failed to deploy', 'Please load a Compose file first.'); @@ -110,12 +117,16 @@ class Heading extends Component public function stop() { + $this->authorize('deploy', $this->application); + $this->dispatch('info', 'Gracefully stopping application.<br/>It could take a while depending on the application.'); StopApplication::dispatch($this->application, false, $this->docker_cleanup); } public function restart() { + $this->authorize('deploy', $this->application); + if ($this->application->additional_servers->count() > 0 && str($this->application->docker_registry_image_name)->isEmpty()) { $this->dispatch('error', 'Failed to deploy', 'Before deploying to multiple servers, you must first set a Docker image in the General tab.<br>More information here: <a target="_blank" class="underline" href="https://coolify.io/docs/knowledge-base/server/multiple-servers">documentation</a>'); diff --git a/app/Livewire/Project/Application/Preview/Form.php b/app/Livewire/Project/Application/Preview/Form.php index edcab44c8..ff951ec54 100644 --- a/app/Livewire/Project/Application/Preview/Form.php +++ b/app/Livewire/Project/Application/Preview/Form.php @@ -3,12 +3,15 @@ namespace App\Livewire\Project\Application\Preview; use App\Models\Application; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Validate; use Livewire\Component; use Spatie\Url\Url; class Form extends Component { + use AuthorizesRequests; + public Application $application; #[Validate('required')] @@ -27,6 +30,7 @@ class Form extends Component public function submit() { try { + $this->authorize('update', $this->application); $this->resetErrorBag(); $this->validate(); $this->application->preview_url_template = str_replace(' ', '', $this->previewUrlTemplate); @@ -41,6 +45,7 @@ class Form extends Component public function resetToDefault() { try { + $this->authorize('update', $this->application); $this->application->preview_url_template = '{{pr_id}}.{{domain}}'; $this->previewUrlTemplate = $this->application->preview_url_template; $this->application->save(); diff --git a/app/Livewire/Project/Application/Previews.php b/app/Livewire/Project/Application/Previews.php index c781c9d8a..9164c1475 100644 --- a/app/Livewire/Project/Application/Previews.php +++ b/app/Livewire/Project/Application/Previews.php @@ -3,14 +3,18 @@ namespace App\Livewire\Project\Application; use App\Actions\Docker\GetContainersStatus; +use App\Jobs\DeleteResourceJob; use App\Models\Application; use App\Models\ApplicationPreview; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Component; use Visus\Cuid2\Cuid2; class Previews extends Component { + use AuthorizesRequests; + public Application $application; public string $deployment_uuid; @@ -34,6 +38,7 @@ class Previews extends Component public function load_prs() { try { + $this->authorize('update', $this->application); ['rate_limit_remaining' => $rate_limit_remaining, 'data' => $data] = githubApi(source: $this->application->source, endpoint: "/repos/{$this->application->git_repository}/pulls"); $this->rate_limit_remaining = $rate_limit_remaining; $this->pull_requests = $data->sortBy('number')->values(); @@ -47,6 +52,7 @@ class Previews extends Component public function save_preview($preview_id) { try { + $this->authorize('update', $this->application); $success = true; $preview = $this->application->previews->find($preview_id); if (data_get_str($preview, 'fqdn')->isNotEmpty()) { @@ -72,29 +78,36 @@ class Previews extends Component public function generate_preview($preview_id) { - $preview = $this->application->previews->find($preview_id); - if (! $preview) { - $this->dispatch('error', 'Preview not found.'); + try { + $this->authorize('update', $this->application); - return; - } - if ($this->application->build_pack === 'dockercompose') { - $preview->generate_preview_fqdn_compose(); + $preview = $this->application->previews->find($preview_id); + if (! $preview) { + $this->dispatch('error', 'Preview not found.'); + + return; + } + if ($this->application->build_pack === 'dockercompose') { + $preview->generate_preview_fqdn_compose(); + $this->application->refresh(); + $this->dispatch('success', 'Domain generated.'); + + return; + } + + $preview->generate_preview_fqdn(); $this->application->refresh(); + $this->dispatch('update_links'); $this->dispatch('success', 'Domain generated.'); - - return; + } catch (\Throwable $e) { + return handleError($e, $this); } - - $this->application->generate_preview_fqdn($preview->pull_request_id); - $this->application->refresh(); - $this->dispatch('update_links'); - $this->dispatch('success', 'Domain generated.'); } public function add(int $pull_request_id, ?string $pull_request_html_url = null) { try { + $this->authorize('update', $this->application); if ($this->application->build_pack === 'dockercompose') { $this->setDeploymentUuid(); $found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first(); @@ -118,7 +131,7 @@ class Previews extends Component 'pull_request_html_url' => $pull_request_html_url, ]); } - $this->application->generate_preview_fqdn($pull_request_id); + $found->generate_preview_fqdn(); $this->application->refresh(); $this->dispatch('update_links'); $this->dispatch('success', 'Preview added.'); @@ -130,17 +143,23 @@ class Previews extends Component public function force_deploy_without_cache(int $pull_request_id, ?string $pull_request_html_url = null) { + $this->authorize('deploy', $this->application); + $this->deploy($pull_request_id, $pull_request_html_url, force_rebuild: true); } public function add_and_deploy(int $pull_request_id, ?string $pull_request_html_url = null) { + $this->authorize('deploy', $this->application); + $this->add($pull_request_id, $pull_request_html_url); $this->deploy($pull_request_id, $pull_request_html_url); } public function deploy(int $pull_request_id, ?string $pull_request_html_url = null, bool $force_rebuild = false) { + $this->authorize('deploy', $this->application); + try { $this->setDeploymentUuid(); $found = ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first(); @@ -183,6 +202,8 @@ class Previews extends Component public function stop(int $pull_request_id) { + $this->authorize('deploy', $this->application); + try { $server = $this->application->destination->server; @@ -205,48 +226,29 @@ class Previews extends Component public function delete(int $pull_request_id) { try { - $server = $this->application->destination->server; + $this->authorize('delete', $this->application); + $preview = ApplicationPreview::where('application_id', $this->application->id) + ->where('pull_request_id', $pull_request_id) + ->first(); - if ($this->application->destination->server->isSwarm()) { - instant_remote_process(["docker stack rm {$this->application->uuid}-{$pull_request_id}"], $server); - } else { - $containers = getCurrentApplicationContainerStatus($server, $this->application->id, $pull_request_id)->toArray(); - $this->stopContainers($containers, $server); + if (! $preview) { + $this->dispatch('error', 'Preview not found.'); + + return; } - ApplicationPreview::where('application_id', $this->application->id) - ->where('pull_request_id', $pull_request_id) - ->first() - ->delete(); + // Soft delete immediately for instant UI feedback + $preview->delete(); - $this->application->refresh(); + // Dispatch the job for async cleanup (container stopping + force delete) + DeleteResourceJob::dispatch($preview); + + // Refresh the application and its previews relationship to reflect the soft delete + $this->application->load('previews'); $this->dispatch('update_links'); - $this->dispatch('success', 'Preview deleted.'); + $this->dispatch('success', 'Preview deletion started. It may take a few moments to complete.'); } catch (\Throwable $e) { return handleError($e, $this); } } - - private function stopContainers(array $containers, $server, int $timeout = 30) - { - if (empty($containers)) { - return; - } - $containerNames = []; - foreach ($containers as $container) { - $containerNames[] = str_replace('/', '', $container['Names']); - } - - $containerList = implode(' ', array_map('escapeshellarg', $containerNames)); - $commands = [ - "docker stop --time=$timeout $containerList", - "docker rm -f $containerList", - ]; - - instant_remote_process( - command: $commands, - server: $server, - throwError: false - ); - } } diff --git a/app/Livewire/Project/Application/PreviewsCompose.php b/app/Livewire/Project/Application/PreviewsCompose.php index b3e838bb3..0317ba7e7 100644 --- a/app/Livewire/Project/Application/PreviewsCompose.php +++ b/app/Livewire/Project/Application/PreviewsCompose.php @@ -3,12 +3,15 @@ namespace App\Livewire\Project\Application; use App\Models\ApplicationPreview; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; use Spatie\Url\Url; use Visus\Cuid2\Cuid2; class PreviewsCompose extends Component { + use AuthorizesRequests; + public $service; public $serviceName; @@ -22,40 +25,71 @@ class PreviewsCompose extends Component public function save() { - $domain = data_get($this->service, 'domain'); - $docker_compose_domains = data_get($this->preview, 'docker_compose_domains'); - $docker_compose_domains = json_decode($docker_compose_domains, true); - $docker_compose_domains[$this->serviceName]['domain'] = $domain; - $this->preview->docker_compose_domains = json_encode($docker_compose_domains); - $this->preview->save(); - $this->dispatch('update_links'); - $this->dispatch('success', 'Domain saved.'); + try { + $this->authorize('update', $this->preview->application); + + $domain = data_get($this->service, 'domain'); + $docker_compose_domains = data_get($this->preview, 'docker_compose_domains'); + $docker_compose_domains = json_decode($docker_compose_domains, true); + $docker_compose_domains[$this->serviceName]['domain'] = $domain; + $this->preview->docker_compose_domains = json_encode($docker_compose_domains); + $this->preview->save(); + $this->dispatch('update_links'); + $this->dispatch('success', 'Domain saved.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function generate() { - $domains = collect(json_decode($this->preview->application->docker_compose_domains)) ?? collect(); - $domain = $domains->first(function ($_, $key) { - return $key === $this->serviceName; - }); - if ($domain) { - $domain = data_get($domain, 'domain'); - $url = Url::fromString($domain); - $template = $this->preview->application->preview_url_template; - $host = $url->getHost(); - $schema = $url->getScheme(); - $random = new Cuid2; - $preview_fqdn = str_replace('{{random}}', $random, $template); - $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn); - $preview_fqdn = str_replace('{{pr_id}}', $this->preview->pull_request_id, $preview_fqdn); - $preview_fqdn = "$schema://$preview_fqdn"; + try { + $this->authorize('update', $this->preview->application); + + $domains = collect(json_decode($this->preview->application->docker_compose_domains)) ?? collect(); + $domain = $domains->first(function ($_, $key) { + return $key === $this->serviceName; + }); + + $domain_string = data_get($domain, 'domain'); + + // If no domain is set in the main application, generate a default domain + if (empty($domain_string)) { + $server = $this->preview->application->destination->server; + $template = $this->preview->application->preview_url_template; + $random = new Cuid2; + + // Generate a unique domain like main app services do + $generated_fqdn = generateFqdn(server: $server, random: $random, parserVersion: $this->preview->application->compose_parsing_version); + + $preview_fqdn = str_replace('{{random}}', $random, $template); + $preview_fqdn = str_replace('{{domain}}', str($generated_fqdn)->after('://'), $preview_fqdn); + $preview_fqdn = str_replace('{{pr_id}}', $this->preview->pull_request_id, $preview_fqdn); + $preview_fqdn = str($generated_fqdn)->before('://').'://'.$preview_fqdn; + } else { + // Use the existing domain from the main application + $url = Url::fromString($domain_string); + $template = $this->preview->application->preview_url_template; + $host = $url->getHost(); + $schema = $url->getScheme(); + $random = new Cuid2; + $preview_fqdn = str_replace('{{random}}', $random, $template); + $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn); + $preview_fqdn = str_replace('{{pr_id}}', $this->preview->pull_request_id, $preview_fqdn); + $preview_fqdn = "$schema://$preview_fqdn"; + } + + // Save the generated domain $docker_compose_domains = data_get($this->preview, 'docker_compose_domains'); $docker_compose_domains = json_decode($docker_compose_domains, true); $docker_compose_domains[$this->serviceName]['domain'] = $this->service->domain = $preview_fqdn; $this->preview->docker_compose_domains = json_encode($docker_compose_domains); $this->preview->save(); + + $this->dispatch('update_links'); + $this->dispatch('success', 'Domain generated.'); + } catch (\Throwable $e) { + return handleError($e, $this); } - $this->dispatch('update_links'); - $this->dispatch('success', 'Domain generated.'); } } diff --git a/app/Livewire/Project/Application/Rollback.php b/app/Livewire/Project/Application/Rollback.php index ff5db1e08..da67a5707 100644 --- a/app/Livewire/Project/Application/Rollback.php +++ b/app/Livewire/Project/Application/Rollback.php @@ -3,11 +3,14 @@ namespace App\Livewire\Project\Application; use App\Models\Application; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; use Visus\Cuid2\Cuid2; class Rollback extends Component { + use AuthorizesRequests; + public Application $application; public $images = []; @@ -23,6 +26,8 @@ class Rollback extends Component public function rollbackImage($commit) { + $this->authorize('deploy', $this->application); + $deployment_uuid = new Cuid2; queue_application_deployment( @@ -43,6 +48,8 @@ class Rollback extends Component public function loadImages($showToast = false) { + $this->authorize('view', $this->application); + try { $image = $this->application->docker_registry_image_name ?? $this->application->uuid; if ($this->application->destination->server->isFunctional()) { diff --git a/app/Livewire/Project/Application/Source.php b/app/Livewire/Project/Application/Source.php index 932a302ad..29be68b6c 100644 --- a/app/Livewire/Project/Application/Source.php +++ b/app/Livewire/Project/Application/Source.php @@ -4,12 +4,15 @@ namespace App\Livewire\Project\Application; use App\Models\Application; use App\Models\PrivateKey; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; use Livewire\Component; class Source extends Component { + use AuthorizesRequests; + public Application $application; #[Locked] @@ -81,6 +84,7 @@ class Source extends Component public function setPrivateKey(int $privateKeyId) { try { + $this->authorize('update', $this->application); $this->privateKeyId = $privateKeyId; $this->syncData(true); $this->getPrivateKeys(); @@ -94,7 +98,9 @@ class Source extends Component public function submit() { + try { + $this->authorize('update', $this->application); if (str($this->gitCommitSha)->isEmpty()) { $this->gitCommitSha = 'HEAD'; } @@ -107,7 +113,9 @@ class Source extends Component public function changeSource($sourceId, $sourceType) { + try { + $this->authorize('update', $this->application); $this->application->update([ 'source_id' => $sourceId, 'source_type' => $sourceType, diff --git a/app/Livewire/Project/CloneMe.php b/app/Livewire/Project/CloneMe.php index a7c44577c..3c8c9843d 100644 --- a/app/Livewire/Project/CloneMe.php +++ b/app/Livewire/Project/CloneMe.php @@ -11,6 +11,7 @@ use App\Jobs\VolumeCloneJob; use App\Models\Environment; use App\Models\Project; use App\Models\Server; +use App\Support\ValidationPatterns; use Livewire\Component; use Visus\Cuid2\Cuid2; @@ -42,11 +43,14 @@ class CloneMe extends Component public bool $cloneVolumeData = false; - protected $messages = [ - 'selectedServer' => 'Please select a server.', - 'selectedDestination' => 'Please select a server & destination.', - 'newName' => 'Please enter a name for the new project or environment.', - ]; + protected function messages(): array + { + return array_merge([ + 'selectedServer' => 'Please select a server.', + 'selectedDestination' => 'Please select a server & destination.', + 'newName.required' => 'Please enter a name for the new project or environment.', + ], ValidationPatterns::nameMessages()); + } public function mount($project_uuid) { @@ -90,7 +94,7 @@ class CloneMe extends Component try { $this->validate([ 'selectedDestination' => 'required', - 'newName' => 'required', + 'newName' => ValidationPatterns::nameRules(), ]); if ($type === 'project') { $foundProject = Project::where('name', $this->newName)->first(); @@ -129,7 +133,7 @@ class CloneMe extends Component $uuid = (string) new Cuid2; $url = $application->fqdn; if ($this->server->proxyType() !== 'NONE' && $applicationSettings->is_container_label_readonly_enabled === true) { - $url = generateFqdn($this->server, $uuid); + $url = generateFqdn(server: $this->server, random: $uuid, parserVersion: $application->compose_parsing_version); } $newApplication = $application->replicate([ @@ -454,7 +458,7 @@ class CloneMe extends Component if ($this->cloneVolumeData) { try { - StopService::dispatch($application, false, false); + StopService::dispatch($application); $sourceVolume = $volume->name; $targetVolume = $newPersistentVolume->name; $sourceServer = $application->service->destination->server; @@ -508,7 +512,7 @@ class CloneMe extends Component if ($this->cloneVolumeData) { try { - StopService::dispatch($database->service, false, false); + StopService::dispatch($database->service); $sourceVolume = $volume->name; $targetVolume = $newPersistentVolume->name; $sourceServer = $database->service->destination->server; diff --git a/app/Livewire/Project/Database/BackupEdit.php b/app/Livewire/Project/Database/BackupEdit.php index 0d363e983..98d076ac0 100644 --- a/app/Livewire/Project/Database/BackupEdit.php +++ b/app/Livewire/Project/Database/BackupEdit.php @@ -5,6 +5,7 @@ namespace App\Livewire\Project\Database; use App\Models\InstanceSettings; use App\Models\ScheduledDatabaseBackup; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Livewire\Attributes\Locked; @@ -14,6 +15,8 @@ use Spatie\Url\Url; class BackupEdit extends Component { + use AuthorizesRequests; + public ScheduledDatabaseBackup $backup; #[Locked] @@ -64,6 +67,9 @@ class BackupEdit extends Component #[Validate(['required', 'boolean'])] public bool $saveS3 = false; + #[Validate(['required', 'boolean'])] + public bool $disableLocalBackup = false; + #[Validate(['nullable', 'integer'])] public ?int $s3StorageId = 1; @@ -73,6 +79,9 @@ class BackupEdit extends Component #[Validate(['required', 'boolean'])] public bool $dumpAll = false; + #[Validate(['required', 'int', 'min:1', 'max:36000'])] + public int $timeout = 3600; + public function mount() { try { @@ -95,9 +104,11 @@ class BackupEdit extends Component $this->backup->database_backup_retention_days_s3 = $this->databaseBackupRetentionDaysS3; $this->backup->database_backup_retention_max_storage_s3 = $this->databaseBackupRetentionMaxStorageS3; $this->backup->save_s3 = $this->saveS3; + $this->backup->disable_local_backup = $this->disableLocalBackup; $this->backup->s3_storage_id = $this->s3StorageId; $this->backup->databases_to_backup = $this->databasesToBackup; $this->backup->dump_all = $this->dumpAll; + $this->backup->timeout = $this->timeout; $this->customValidate(); $this->backup->save(); } else { @@ -111,14 +122,18 @@ class BackupEdit extends Component $this->databaseBackupRetentionDaysS3 = $this->backup->database_backup_retention_days_s3; $this->databaseBackupRetentionMaxStorageS3 = $this->backup->database_backup_retention_max_storage_s3; $this->saveS3 = $this->backup->save_s3; + $this->disableLocalBackup = $this->backup->disable_local_backup ?? false; $this->s3StorageId = $this->backup->s3_storage_id; $this->databasesToBackup = $this->backup->databases_to_backup; $this->dumpAll = $this->backup->dump_all; + $this->timeout = $this->backup->timeout; } } public function delete($password) { + $this->authorize('manageBackups', $this->backup->database); + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); @@ -176,6 +191,8 @@ class BackupEdit extends Component public function instantSave() { try { + $this->authorize('manageBackups', $this->backup->database); + $this->syncData(true); $this->dispatch('success', 'Backup updated successfully.'); } catch (\Throwable $e) { @@ -188,6 +205,12 @@ class BackupEdit extends Component if (! is_numeric($this->backup->s3_storage_id)) { $this->backup->s3_storage_id = null; } + + // Validate that disable_local_backup can only be true when S3 backup is enabled + if ($this->backup->disable_local_backup && ! $this->backup->save_s3) { + throw new \Exception('Local backup can only be disabled when S3 backup is enabled.'); + } + $isValid = validate_cron_expression($this->backup->frequency); if (! $isValid) { throw new \Exception('Invalid Cron / Human expression'); @@ -198,6 +221,8 @@ class BackupEdit extends Component public function submit() { try { + $this->authorize('manageBackups', $this->backup->database); + $this->syncData(true); $this->dispatch('success', 'Backup updated successfully.'); } catch (\Throwable $e) { diff --git a/app/Livewire/Project/Database/BackupExecutions.php b/app/Livewire/Project/Database/BackupExecutions.php index f96ca9a6a..2f3aae8cf 100644 --- a/app/Livewire/Project/Database/BackupExecutions.php +++ b/app/Livewire/Project/Database/BackupExecutions.php @@ -4,6 +4,7 @@ namespace App\Livewire\Project\Database; use App\Models\InstanceSettings; use App\Models\ScheduledDatabaseBackup; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Livewire\Component; @@ -14,7 +15,19 @@ class BackupExecutions extends Component public $database; - public $executions = []; + public ?Collection $executions; + + public int $executions_count = 0; + + public int $skip = 0; + + public int $defaultTake = 10; + + public bool $showNext = false; + + public bool $showPrev = false; + + public int $currentPage = 1; public $setDeletableBackup; @@ -40,6 +53,20 @@ class BackupExecutions extends Component } } + public function cleanupDeleted() + { + if ($this->backup) { + $deletedCount = $this->backup->executions()->where('local_storage_deleted', true)->count(); + if ($deletedCount > 0) { + $this->backup->executions()->where('local_storage_deleted', true)->delete(); + $this->refreshBackupExecutions(); + $this->dispatch('success', "Cleaned up {$deletedCount} backup entries deleted from local storage."); + } else { + $this->dispatch('info', 'No backup entries found that are deleted from local storage.'); + } + } + } + public function deleteBackup($executionId, $password) { if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { @@ -85,18 +112,74 @@ class BackupExecutions extends Component public function refreshBackupExecutions(): void { - if ($this->backup && $this->backup->exists) { - $this->executions = $this->backup->executions()->get()->toArray(); - } else { - $this->executions = []; + $this->loadExecutions(); + } + + public function reloadExecutions() + { + $this->loadExecutions(); + } + + public function previousPage(?int $take = null) + { + if ($take) { + $this->skip = $this->skip - $take; } + $this->skip = $this->skip - $this->defaultTake; + if ($this->skip < 0) { + $this->showPrev = false; + $this->skip = 0; + } + $this->updateCurrentPage(); + $this->loadExecutions(); + } + + public function nextPage(?int $take = null) + { + if ($take) { + $this->skip = $this->skip + $take; + } + $this->showPrev = true; + $this->updateCurrentPage(); + $this->loadExecutions(); + } + + private function loadExecutions() + { + if ($this->backup && $this->backup->exists) { + ['executions' => $executions, 'count' => $count] = $this->backup->executionsPaginated($this->skip, $this->defaultTake); + $this->executions = $executions; + $this->executions_count = $count; + } else { + $this->executions = collect([]); + $this->executions_count = 0; + } + $this->showMore(); + } + + private function showMore() + { + if ($this->executions->count() !== 0) { + $this->showNext = true; + if ($this->executions->count() < $this->defaultTake) { + $this->showNext = false; + } + + return; + } + } + + private function updateCurrentPage() + { + $this->currentPage = intval($this->skip / $this->defaultTake) + 1; } public function mount(ScheduledDatabaseBackup $backup) { $this->backup = $backup; $this->database = $backup->database; - $this->refreshBackupExecutions(); + $this->updateCurrentPage(); + $this->loadExecutions(); } public function server() diff --git a/app/Livewire/Project/Database/BackupNow.php b/app/Livewire/Project/Database/BackupNow.php index 3cd360562..decd59a4c 100644 --- a/app/Livewire/Project/Database/BackupNow.php +++ b/app/Livewire/Project/Database/BackupNow.php @@ -3,14 +3,19 @@ namespace App\Livewire\Project\Database; use App\Jobs\DatabaseBackupJob; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class BackupNow extends Component { + use AuthorizesRequests; + public $backup; public function backupNow() { + $this->authorize('manageBackups', $this->backup->database); + DatabaseBackupJob::dispatch($this->backup); $this->dispatch('success', 'Backup queued. It will be available in a few minutes.'); } diff --git a/app/Livewire/Project/Database/Clickhouse/General.php b/app/Livewire/Project/Database/Clickhouse/General.php index 2d39c5151..b80775853 100644 --- a/app/Livewire/Project/Database/Clickhouse/General.php +++ b/app/Livewire/Project/Database/Clickhouse/General.php @@ -6,51 +6,42 @@ use App\Actions\Database\StartDatabaseProxy; use App\Actions\Database\StopDatabaseProxy; use App\Models\Server; use App\Models\StandaloneClickhouse; +use App\Support\ValidationPatterns; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; -use Livewire\Attributes\Validate; use Livewire\Component; class General extends Component { + use AuthorizesRequests; + public Server $server; public StandaloneClickhouse $database; - #[Validate(['required', 'string'])] public string $name; - #[Validate(['nullable', 'string'])] public ?string $description = null; - #[Validate(['required', 'string'])] public string $clickhouseAdminUser; - #[Validate(['required', 'string'])] public string $clickhouseAdminPassword; - #[Validate(['required', 'string'])] public string $image; - #[Validate(['nullable', 'string'])] public ?string $portsMappings = null; - #[Validate(['nullable', 'boolean'])] public ?bool $isPublic = null; - #[Validate(['nullable', 'integer'])] public ?int $publicPort = null; - #[Validate(['nullable', 'string'])] public ?string $customDockerRunOptions = null; - #[Validate(['nullable', 'string'])] public ?string $dbUrl = null; - #[Validate(['nullable', 'string'])] public ?string $dbUrlPublic = null; - #[Validate(['nullable', 'boolean'])] public bool $isLogDrainEnabled = false; public function getListeners() @@ -72,6 +63,40 @@ class General extends Component } } + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + 'clickhouseAdminUser' => 'required|string', + 'clickhouseAdminPassword' => 'required|string', + 'image' => 'required|string', + 'portsMappings' => 'nullable|string', + 'isPublic' => 'nullable|boolean', + 'publicPort' => 'nullable|integer', + 'customDockerRunOptions' => 'nullable|string', + 'dbUrl' => 'nullable|string', + 'dbUrlPublic' => 'nullable|string', + 'isLogDrainEnabled' => 'nullable|boolean', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'clickhouseAdminUser.required' => 'The Admin User field is required.', + 'clickhouseAdminUser.string' => 'The Admin User must be a string.', + 'clickhouseAdminPassword.required' => 'The Admin Password field is required.', + 'clickhouseAdminPassword.string' => 'The Admin Password must be a string.', + 'image.required' => 'The Docker Image field is required.', + 'image.string' => 'The Docker Image must be a string.', + 'publicPort.integer' => 'The Public Port must be an integer.', + ] + ); + } + public function syncData(bool $toModel = false) { if ($toModel) { @@ -109,6 +134,8 @@ class General extends Component public function instantSaveAdvanced() { try { + $this->authorize('update', $this->database); + if (! $this->server->isLogDrainEnabled()) { $this->isLogDrainEnabled = false; $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); @@ -127,6 +154,8 @@ class General extends Component public function instantSave() { try { + $this->authorize('update', $this->database); + if ($this->isPublic && ! $this->publicPort) { $this->dispatch('error', 'Public port is required.'); $this->isPublic = false; @@ -164,6 +193,8 @@ class General extends Component public function submit() { try { + $this->authorize('update', $this->database); + if (str($this->publicPort)->isEmpty()) { $this->publicPort = null; } diff --git a/app/Livewire/Project/Database/Configuration.php b/app/Livewire/Project/Database/Configuration.php index 6c4d0867e..88ecccf99 100644 --- a/app/Livewire/Project/Database/Configuration.php +++ b/app/Livewire/Project/Database/Configuration.php @@ -26,27 +26,38 @@ class Configuration extends Component public function mount() { - $this->currentRoute = request()->route()->getName(); + try { + $this->currentRoute = request()->route()->getName(); - $project = currentTeam() - ->projects() - ->select('id', 'uuid', 'team_id') - ->where('uuid', request()->route('project_uuid')) - ->firstOrFail(); - $environment = $project->environments() - ->select('id', 'name', 'project_id', 'uuid') - ->where('uuid', request()->route('environment_uuid')) - ->firstOrFail(); - $database = $environment->databases() - ->where('uuid', request()->route('database_uuid')) - ->firstOrFail(); + $project = currentTeam() + ->projects() + ->select('id', 'uuid', 'team_id') + ->where('uuid', request()->route('project_uuid')) + ->firstOrFail(); + $environment = $project->environments() + ->select('id', 'name', 'project_id', 'uuid') + ->where('uuid', request()->route('environment_uuid')) + ->firstOrFail(); + $database = $environment->databases() + ->where('uuid', request()->route('database_uuid')) + ->firstOrFail(); - $this->database = $database; - $this->project = $project; - $this->environment = $environment; - if (str($this->database->status)->startsWith('running') && is_null($this->database->config_hash)) { - $this->database->isConfigurationChanged(true); - $this->dispatch('configurationChanged'); + $this->database = $database; + $this->project = $project; + $this->environment = $environment; + if (str($this->database->status)->startsWith('running') && is_null($this->database->config_hash)) { + $this->database->isConfigurationChanged(true); + $this->dispatch('configurationChanged'); + } + } catch (\Throwable $e) { + if ($e instanceof \Illuminate\Auth\Access\AuthorizationException) { + return redirect()->route('dashboard'); + } + if ($e instanceof \Illuminate\Support\ItemNotFoundException) { + return redirect()->route('dashboard'); + } + + return handleError($e, $this); } } diff --git a/app/Livewire/Project/Database/CreateScheduledBackup.php b/app/Livewire/Project/Database/CreateScheduledBackup.php index 01108c290..7f807afe2 100644 --- a/app/Livewire/Project/Database/CreateScheduledBackup.php +++ b/app/Livewire/Project/Database/CreateScheduledBackup.php @@ -3,6 +3,7 @@ namespace App\Livewire\Project\Database; use App\Models\ScheduledDatabaseBackup; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; @@ -10,6 +11,8 @@ use Livewire\Component; class CreateScheduledBackup extends Component { + use AuthorizesRequests; + #[Validate(['required', 'string'])] public $frequency; @@ -41,6 +44,8 @@ class CreateScheduledBackup extends Component public function submit() { try { + $this->authorize('manageBackups', $this->database); + $this->validate(); $isValid = validate_cron_expression($this->frequency); diff --git a/app/Livewire/Project/Database/Dragonfly/General.php b/app/Livewire/Project/Database/Dragonfly/General.php index 0fffbef31..fabbc7cb4 100644 --- a/app/Livewire/Project/Database/Dragonfly/General.php +++ b/app/Livewire/Project/Database/Dragonfly/General.php @@ -8,54 +8,45 @@ use App\Helpers\SslHelper; use App\Models\Server; use App\Models\SslCertificate; use App\Models\StandaloneDragonfly; +use App\Support\ValidationPatterns; use Carbon\Carbon; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; -use Livewire\Attributes\Validate; use Livewire\Component; class General extends Component { + use AuthorizesRequests; + public Server $server; public StandaloneDragonfly $database; - #[Validate(['required', 'string'])] public string $name; - #[Validate(['nullable', 'string'])] public ?string $description = null; - #[Validate(['required', 'string'])] public string $dragonflyPassword; - #[Validate(['required', 'string'])] public string $image; - #[Validate(['nullable', 'string'])] public ?string $portsMappings = null; - #[Validate(['nullable', 'boolean'])] public ?bool $isPublic = null; - #[Validate(['nullable', 'integer'])] public ?int $publicPort = null; - #[Validate(['nullable', 'string'])] public ?string $customDockerRunOptions = null; - #[Validate(['nullable', 'string'])] public ?string $dbUrl = null; - #[Validate(['nullable', 'string'])] public ?string $dbUrlPublic = null; - #[Validate(['nullable', 'boolean'])] public bool $isLogDrainEnabled = false; public ?Carbon $certificateValidUntil = null; - #[Validate(['nullable', 'boolean'])] public bool $enable_ssl = false; public function getListeners() @@ -85,6 +76,38 @@ class General extends Component } } + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + 'dragonflyPassword' => 'required|string', + 'image' => 'required|string', + 'portsMappings' => 'nullable|string', + 'isPublic' => 'nullable|boolean', + 'publicPort' => 'nullable|integer', + 'customDockerRunOptions' => 'nullable|string', + 'dbUrl' => 'nullable|string', + 'dbUrlPublic' => 'nullable|string', + 'isLogDrainEnabled' => 'nullable|boolean', + 'enable_ssl' => 'nullable|boolean', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'dragonflyPassword.required' => 'The Dragonfly Password field is required.', + 'dragonflyPassword.string' => 'The Dragonfly Password must be a string.', + 'image.required' => 'The Docker Image field is required.', + 'image.string' => 'The Docker Image must be a string.', + 'publicPort.integer' => 'The Public Port must be an integer.', + ] + ); + } + public function syncData(bool $toModel = false) { if ($toModel) { @@ -122,6 +145,8 @@ class General extends Component public function instantSaveAdvanced() { try { + $this->authorize('update', $this->database); + if (! $this->server->isLogDrainEnabled()) { $this->isLogDrainEnabled = false; $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); @@ -140,6 +165,8 @@ class General extends Component public function instantSave() { try { + $this->authorize('update', $this->database); + if ($this->isPublic && ! $this->publicPort) { $this->dispatch('error', 'Public port is required.'); $this->isPublic = false; @@ -177,6 +204,8 @@ class General extends Component public function submit() { try { + $this->authorize('update', $this->database); + if (str($this->publicPort)->isEmpty()) { $this->publicPort = null; } @@ -196,6 +225,8 @@ class General extends Component public function instantSaveSSL() { try { + $this->authorize('update', $this->database); + $this->syncData(true); $this->dispatch('success', 'SSL configuration updated.'); } catch (Exception $e) { @@ -206,6 +237,8 @@ class General extends Component public function regenerateSslCertificate() { try { + $this->authorize('update', $this->database); + $existingCert = $this->database->sslCertificates()->first(); if (! $existingCert) { diff --git a/app/Livewire/Project/Database/Heading.php b/app/Livewire/Project/Database/Heading.php index a9783d911..6a287f8cc 100644 --- a/app/Livewire/Project/Database/Heading.php +++ b/app/Livewire/Project/Database/Heading.php @@ -7,10 +7,13 @@ use App\Actions\Database\StartDatabase; use App\Actions\Database\StopDatabase; use App\Actions\Docker\GetContainersStatus; use App\Events\ServiceStatusChanged; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Heading extends Component { + use AuthorizesRequests; + public $database; public array $parameters; @@ -33,7 +36,10 @@ class Heading extends Component public function activityFinished() { try { - $this->database->started_at ??= now(); + // Only set started_at if database is actually running + if ($this->database->isRunning()) { + $this->database->started_at ??= now(); + } $this->database->save(); if (is_null($this->database->config_hash) || $this->database->isConfigurationChanged()) { @@ -64,6 +70,8 @@ class Heading extends Component public function stop() { try { + $this->authorize('manage', $this->database); + $this->dispatch('info', 'Gracefully stopping database.'); StopDatabase::dispatch($this->database, false, $this->docker_cleanup); } catch (\Exception $e) { @@ -73,12 +81,16 @@ class Heading extends Component public function restart() { + $this->authorize('manage', $this->database); + $activity = RestartDatabase::run($this->database); $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } public function start() { + $this->authorize('manage', $this->database); + $activity = StartDatabase::run($this->database); $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } diff --git a/app/Livewire/Project/Database/Import.php b/app/Livewire/Project/Database/Import.php index eb80ca6f6..3f974f63d 100644 --- a/app/Livewire/Project/Database/Import.php +++ b/app/Livewire/Project/Database/Import.php @@ -3,12 +3,15 @@ namespace App\Livewire\Project\Database; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Storage; use Livewire\Component; class Import extends Component { + use AuthorizesRequests; + public bool $unsupported = false; public $resource; @@ -165,12 +168,15 @@ EOD; public function runImport() { + $this->authorize('update', $this->resource); + if ($this->filename === '') { $this->dispatch('error', 'Please select a file to import.'); return; } try { + $this->importRunning = true; $this->importCommands = []; if (filled($this->customLocation)) { $backupFileName = '/tmp/restore_'.$this->resource->uuid; diff --git a/app/Livewire/Project/Database/Keydb/General.php b/app/Livewire/Project/Database/Keydb/General.php index cfc22aedc..7502d001d 100644 --- a/app/Livewire/Project/Database/Keydb/General.php +++ b/app/Livewire/Project/Database/Keydb/General.php @@ -8,57 +8,47 @@ use App\Helpers\SslHelper; use App\Models\Server; use App\Models\SslCertificate; use App\Models\StandaloneKeydb; +use App\Support\ValidationPatterns; use Carbon\Carbon; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; -use Livewire\Attributes\Validate; use Livewire\Component; class General extends Component { + use AuthorizesRequests; + public Server $server; public StandaloneKeydb $database; - #[Validate(['required', 'string'])] public string $name; - #[Validate(['nullable', 'string'])] public ?string $description = null; - #[Validate(['nullable', 'string'])] public ?string $keydbConf = null; - #[Validate(['required', 'string'])] public string $keydbPassword; - #[Validate(['required', 'string'])] public string $image; - #[Validate(['nullable', 'string'])] public ?string $portsMappings = null; - #[Validate(['nullable', 'boolean'])] public ?bool $isPublic = null; - #[Validate(['nullable', 'integer'])] public ?int $publicPort = null; - #[Validate(['nullable', 'string'])] public ?string $customDockerRunOptions = null; - #[Validate(['nullable', 'string'])] public ?string $dbUrl = null; - #[Validate(['nullable', 'string'])] public ?string $dbUrlPublic = null; - #[Validate(['nullable', 'boolean'])] public bool $isLogDrainEnabled = false; public ?Carbon $certificateValidUntil = null; - #[Validate(['boolean'])] public bool $enable_ssl = false; public function getListeners() @@ -89,6 +79,41 @@ class General extends Component } } + protected function rules(): array + { + $baseRules = [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + 'keydbConf' => 'nullable|string', + 'keydbPassword' => 'required|string', + 'image' => 'required|string', + 'portsMappings' => 'nullable|string', + 'isPublic' => 'nullable|boolean', + 'publicPort' => 'nullable|integer', + 'customDockerRunOptions' => 'nullable|string', + 'dbUrl' => 'nullable|string', + 'dbUrlPublic' => 'nullable|string', + 'isLogDrainEnabled' => 'nullable|boolean', + 'enable_ssl' => 'boolean', + ]; + + return $baseRules; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'keydbPassword.required' => 'The KeyDB Password field is required.', + 'keydbPassword.string' => 'The KeyDB Password must be a string.', + 'image.required' => 'The Docker Image field is required.', + 'image.string' => 'The Docker Image must be a string.', + 'publicPort.integer' => 'The Public Port must be an integer.', + ] + ); + } + public function syncData(bool $toModel = false) { if ($toModel) { @@ -128,6 +153,8 @@ class General extends Component public function instantSaveAdvanced() { try { + $this->authorize('update', $this->database); + if (! $this->server->isLogDrainEnabled()) { $this->isLogDrainEnabled = false; $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); @@ -146,6 +173,8 @@ class General extends Component public function instantSave() { try { + $this->authorize('update', $this->database); + if ($this->isPublic && ! $this->publicPort) { $this->dispatch('error', 'Public port is required.'); $this->isPublic = false; @@ -183,6 +212,8 @@ class General extends Component public function submit() { try { + $this->authorize('manageEnvironment', $this->database); + if (str($this->publicPort)->isEmpty()) { $this->publicPort = null; } @@ -202,6 +233,8 @@ class General extends Component public function instantSaveSSL() { try { + $this->authorize('update', $this->database); + $this->syncData(true); $this->dispatch('success', 'SSL configuration updated.'); } catch (Exception $e) { @@ -212,6 +245,8 @@ class General extends Component public function regenerateSslCertificate() { try { + $this->authorize('update', $this->database); + $existingCert = $this->database->sslCertificates()->first(); if (! $existingCert) { diff --git a/app/Livewire/Project/Database/Mariadb/General.php b/app/Livewire/Project/Database/Mariadb/General.php index 174f907c8..c82c4538f 100644 --- a/app/Livewire/Project/Database/Mariadb/General.php +++ b/app/Livewire/Project/Database/Mariadb/General.php @@ -8,13 +8,17 @@ use App\Helpers\SslHelper; use App\Models\Server; use App\Models\SslCertificate; use App\Models\StandaloneMariadb; +use App\Support\ValidationPatterns; use Carbon\Carbon; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Livewire\Component; class General extends Component { + use AuthorizesRequests; + protected $listeners = ['refresh']; public Server $server; @@ -37,22 +41,43 @@ class General extends Component ]; } - protected $rules = [ - 'database.name' => 'required', - 'database.description' => 'nullable', - 'database.mariadb_root_password' => 'required', - 'database.mariadb_user' => 'required', - 'database.mariadb_password' => 'required', - 'database.mariadb_database' => 'required', - 'database.mariadb_conf' => 'nullable', - 'database.image' => 'required', - 'database.ports_mappings' => 'nullable', - 'database.is_public' => 'nullable|boolean', - 'database.public_port' => 'nullable|integer', - 'database.is_log_drain_enabled' => 'nullable|boolean', - 'database.custom_docker_run_options' => 'nullable', - 'database.enable_ssl' => 'boolean', - ]; + protected function rules(): array + { + return [ + 'database.name' => ValidationPatterns::nameRules(), + 'database.description' => ValidationPatterns::descriptionRules(), + 'database.mariadb_root_password' => 'required', + 'database.mariadb_user' => 'required', + 'database.mariadb_password' => 'required', + 'database.mariadb_database' => 'required', + 'database.mariadb_conf' => 'nullable', + 'database.image' => 'required', + 'database.ports_mappings' => 'nullable', + 'database.is_public' => 'nullable|boolean', + 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', + 'database.custom_docker_run_options' => 'nullable', + 'database.enable_ssl' => 'boolean', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'database.name.required' => 'The Name field is required.', + 'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'database.mariadb_root_password.required' => 'The Root Password field is required.', + 'database.mariadb_user.required' => 'The MariaDB User field is required.', + 'database.mariadb_password.required' => 'The MariaDB Password field is required.', + 'database.mariadb_database.required' => 'The MariaDB Database field is required.', + 'database.image.required' => 'The Docker Image field is required.', + 'database.public_port.integer' => 'The Public Port must be an integer.', + ] + ); + } protected $validationAttributes = [ 'database.name' => 'Name', @@ -86,6 +111,8 @@ class General extends Component public function instantSaveAdvanced() { try { + $this->authorize('update', $this->database); + if (! $this->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); @@ -103,6 +130,8 @@ class General extends Component public function submit() { try { + $this->authorize('update', $this->database); + if (str($this->database->public_port)->isEmpty()) { $this->database->public_port = null; } @@ -123,6 +152,8 @@ class General extends Component public function instantSave() { try { + $this->authorize('update', $this->database); + if ($this->database->is_public && ! $this->database->public_port) { $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; @@ -154,6 +185,8 @@ class General extends Component public function instantSaveSSL() { try { + $this->authorize('update', $this->database); + $this->database->save(); $this->dispatch('success', 'SSL configuration updated.'); } catch (Exception $e) { @@ -164,6 +197,8 @@ class General extends Component public function regenerateSslCertificate() { try { + $this->authorize('update', $this->database); + $existingCert = $this->database->sslCertificates()->first(); if (! $existingCert) { diff --git a/app/Livewire/Project/Database/Mongodb/General.php b/app/Livewire/Project/Database/Mongodb/General.php index 2ac6e43b7..4fbc45437 100644 --- a/app/Livewire/Project/Database/Mongodb/General.php +++ b/app/Livewire/Project/Database/Mongodb/General.php @@ -8,13 +8,17 @@ use App\Helpers\SslHelper; use App\Models\Server; use App\Models\SslCertificate; use App\Models\StandaloneMongodb; +use App\Support\ValidationPatterns; use Carbon\Carbon; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Livewire\Component; class General extends Component { + use AuthorizesRequests; + protected $listeners = ['refresh']; public Server $server; @@ -37,22 +41,43 @@ class General extends Component ]; } - protected $rules = [ - 'database.name' => 'required', - 'database.description' => 'nullable', - 'database.mongo_conf' => 'nullable', - 'database.mongo_initdb_root_username' => 'required', - 'database.mongo_initdb_root_password' => 'required', - 'database.mongo_initdb_database' => 'required', - 'database.image' => 'required', - 'database.ports_mappings' => 'nullable', - 'database.is_public' => 'nullable|boolean', - 'database.public_port' => 'nullable|integer', - 'database.is_log_drain_enabled' => 'nullable|boolean', - 'database.custom_docker_run_options' => 'nullable', - 'database.enable_ssl' => 'boolean', - 'database.ssl_mode' => 'nullable|string|in:allow,prefer,require,verify-full', - ]; + protected function rules(): array + { + return [ + 'database.name' => ValidationPatterns::nameRules(), + 'database.description' => ValidationPatterns::descriptionRules(), + 'database.mongo_conf' => 'nullable', + 'database.mongo_initdb_root_username' => 'required', + 'database.mongo_initdb_root_password' => 'required', + 'database.mongo_initdb_database' => 'required', + 'database.image' => 'required', + 'database.ports_mappings' => 'nullable', + 'database.is_public' => 'nullable|boolean', + 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', + 'database.custom_docker_run_options' => 'nullable', + 'database.enable_ssl' => 'boolean', + 'database.ssl_mode' => 'nullable|string|in:allow,prefer,require,verify-full', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'database.name.required' => 'The Name field is required.', + 'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'database.mongo_initdb_root_username.required' => 'The Root Username field is required.', + 'database.mongo_initdb_root_password.required' => 'The Root Password field is required.', + 'database.mongo_initdb_database.required' => 'The MongoDB Database field is required.', + 'database.image.required' => 'The Docker Image field is required.', + 'database.public_port.integer' => 'The Public Port must be an integer.', + 'database.ssl_mode.in' => 'The SSL Mode must be one of: allow, prefer, require, verify-full.', + ] + ); + } protected $validationAttributes = [ 'database.name' => 'Name', @@ -86,6 +111,8 @@ class General extends Component public function instantSaveAdvanced() { try { + $this->authorize('update', $this->database); + if (! $this->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); @@ -103,6 +130,8 @@ class General extends Component public function submit() { try { + $this->authorize('update', $this->database); + if (str($this->database->public_port)->isEmpty()) { $this->database->public_port = null; } @@ -126,6 +155,8 @@ class General extends Component public function instantSave() { try { + $this->authorize('update', $this->database); + if ($this->database->is_public && ! $this->database->public_port) { $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; @@ -162,6 +193,8 @@ class General extends Component public function instantSaveSSL() { try { + $this->authorize('update', $this->database); + $this->database->save(); $this->dispatch('success', 'SSL configuration updated.'); } catch (Exception $e) { @@ -172,6 +205,8 @@ class General extends Component public function regenerateSslCertificate() { try { + $this->authorize('update', $this->database); + $existingCert = $this->database->sslCertificates()->first(); if (! $existingCert) { diff --git a/app/Livewire/Project/Database/Mysql/General.php b/app/Livewire/Project/Database/Mysql/General.php index ea0ea4691..ada1b3a2c 100644 --- a/app/Livewire/Project/Database/Mysql/General.php +++ b/app/Livewire/Project/Database/Mysql/General.php @@ -8,13 +8,17 @@ use App\Helpers\SslHelper; use App\Models\Server; use App\Models\SslCertificate; use App\Models\StandaloneMysql; +use App\Support\ValidationPatterns; use Carbon\Carbon; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Livewire\Component; class General extends Component { + use AuthorizesRequests; + protected $listeners = ['refresh']; public StandaloneMysql $database; @@ -37,23 +41,45 @@ class General extends Component ]; } - protected $rules = [ - 'database.name' => 'required', - 'database.description' => 'nullable', - 'database.mysql_root_password' => 'required', - 'database.mysql_user' => 'required', - 'database.mysql_password' => 'required', - 'database.mysql_database' => 'required', - 'database.mysql_conf' => 'nullable', - 'database.image' => 'required', - 'database.ports_mappings' => 'nullable', - 'database.is_public' => 'nullable|boolean', - 'database.public_port' => 'nullable|integer', - 'database.is_log_drain_enabled' => 'nullable|boolean', - 'database.custom_docker_run_options' => 'nullable', - 'database.enable_ssl' => 'boolean', - 'database.ssl_mode' => 'nullable|string|in:PREFERRED,REQUIRED,VERIFY_CA,VERIFY_IDENTITY', - ]; + protected function rules(): array + { + return [ + 'database.name' => ValidationPatterns::nameRules(), + 'database.description' => ValidationPatterns::descriptionRules(), + 'database.mysql_root_password' => 'required', + 'database.mysql_user' => 'required', + 'database.mysql_password' => 'required', + 'database.mysql_database' => 'required', + 'database.mysql_conf' => 'nullable', + 'database.image' => 'required', + 'database.ports_mappings' => 'nullable', + 'database.is_public' => 'nullable|boolean', + 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', + 'database.custom_docker_run_options' => 'nullable', + 'database.enable_ssl' => 'boolean', + 'database.ssl_mode' => 'nullable|string|in:PREFERRED,REQUIRED,VERIFY_CA,VERIFY_IDENTITY', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'database.name.required' => 'The Name field is required.', + 'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'database.mysql_root_password.required' => 'The Root Password field is required.', + 'database.mysql_user.required' => 'The MySQL User field is required.', + 'database.mysql_password.required' => 'The MySQL Password field is required.', + 'database.mysql_database.required' => 'The MySQL Database field is required.', + 'database.image.required' => 'The Docker Image field is required.', + 'database.public_port.integer' => 'The Public Port must be an integer.', + 'database.ssl_mode.in' => 'The SSL Mode must be one of: PREFERRED, REQUIRED, VERIFY_CA, VERIFY_IDENTITY.', + ] + ); + } protected $validationAttributes = [ 'database.name' => 'Name', @@ -88,6 +114,8 @@ class General extends Component public function instantSaveAdvanced() { try { + $this->authorize('update', $this->database); + if (! $this->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); @@ -105,6 +133,8 @@ class General extends Component public function submit() { try { + $this->authorize('update', $this->database); + if (str($this->database->public_port)->isEmpty()) { $this->database->public_port = null; } @@ -125,6 +155,8 @@ class General extends Component public function instantSave() { try { + $this->authorize('update', $this->database); + if ($this->database->is_public && ! $this->database->public_port) { $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; @@ -161,6 +193,8 @@ class General extends Component public function instantSaveSSL() { try { + $this->authorize('update', $this->database); + $this->database->save(); $this->dispatch('success', 'SSL configuration updated.'); } catch (Exception $e) { @@ -171,6 +205,8 @@ class General extends Component public function regenerateSslCertificate() { try { + $this->authorize('update', $this->database); + $existingCert = $this->database->sslCertificates()->first(); if (! $existingCert) { diff --git a/app/Livewire/Project/Database/Postgresql/General.php b/app/Livewire/Project/Database/Postgresql/General.php index d512445b7..2d37620b9 100644 --- a/app/Livewire/Project/Database/Postgresql/General.php +++ b/app/Livewire/Project/Database/Postgresql/General.php @@ -8,13 +8,17 @@ use App\Helpers\SslHelper; use App\Models\Server; use App\Models\SslCertificate; use App\Models\StandalonePostgresql; +use App\Support\ValidationPatterns; use Carbon\Carbon; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Livewire\Component; class General extends Component { + use AuthorizesRequests; + public StandalonePostgresql $database; public Server $server; @@ -41,25 +45,46 @@ class General extends Component ]; } - protected $rules = [ - 'database.name' => 'required', - 'database.description' => 'nullable', - 'database.postgres_user' => 'required', - 'database.postgres_password' => 'required', - 'database.postgres_db' => 'required', - 'database.postgres_initdb_args' => 'nullable', - 'database.postgres_host_auth_method' => 'nullable', - 'database.postgres_conf' => 'nullable', - 'database.init_scripts' => 'nullable', - 'database.image' => 'required', - 'database.ports_mappings' => 'nullable', - 'database.is_public' => 'nullable|boolean', - 'database.public_port' => 'nullable|integer', - 'database.is_log_drain_enabled' => 'nullable|boolean', - 'database.custom_docker_run_options' => 'nullable', - 'database.enable_ssl' => 'boolean', - 'database.ssl_mode' => 'nullable|string|in:allow,prefer,require,verify-ca,verify-full', - ]; + protected function rules(): array + { + return [ + 'database.name' => ValidationPatterns::nameRules(), + 'database.description' => ValidationPatterns::descriptionRules(), + 'database.postgres_user' => 'required', + 'database.postgres_password' => 'required', + 'database.postgres_db' => 'required', + 'database.postgres_initdb_args' => 'nullable', + 'database.postgres_host_auth_method' => 'nullable', + 'database.postgres_conf' => 'nullable', + 'database.init_scripts' => 'nullable', + 'database.image' => 'required', + 'database.ports_mappings' => 'nullable', + 'database.is_public' => 'nullable|boolean', + 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', + 'database.custom_docker_run_options' => 'nullable', + 'database.enable_ssl' => 'boolean', + 'database.ssl_mode' => 'nullable|string|in:allow,prefer,require,verify-ca,verify-full', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'database.name.required' => 'The Name field is required.', + 'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'database.postgres_user.required' => 'The Postgres User field is required.', + 'database.postgres_password.required' => 'The Postgres Password field is required.', + 'database.postgres_db.required' => 'The Postgres Database field is required.', + 'database.image.required' => 'The Docker Image field is required.', + 'database.public_port.integer' => 'The Public Port must be an integer.', + 'database.ssl_mode.in' => 'The SSL Mode must be one of: allow, prefer, require, verify-ca, verify-full.', + ] + ); + } protected $validationAttributes = [ 'database.name' => 'Name', @@ -96,6 +121,8 @@ class General extends Component public function instantSaveAdvanced() { try { + $this->authorize('update', $this->database); + if (! $this->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); @@ -118,6 +145,8 @@ class General extends Component public function instantSaveSSL() { try { + $this->authorize('update', $this->database); + $this->database->save(); $this->dispatch('success', 'SSL configuration updated.'); $this->db_url = $this->database->internal_db_url; @@ -130,6 +159,8 @@ class General extends Component public function regenerateSslCertificate() { try { + $this->authorize('update', $this->database); + $existingCert = $this->database->sslCertificates()->first(); if (! $existingCert) { @@ -162,6 +193,8 @@ class General extends Component public function instantSave() { try { + $this->authorize('update', $this->database); + if ($this->database->is_public && ! $this->database->public_port) { $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; @@ -192,6 +225,8 @@ class General extends Component public function save_init_script($script) { + $this->authorize('update', $this->database); + $initScripts = collect($this->database->init_scripts ?? []); $existingScript = $initScripts->firstWhere('filename', $script['filename']); @@ -242,6 +277,8 @@ class General extends Component public function delete_init_script($script) { + $this->authorize('update', $this->database); + $collection = collect($this->database->init_scripts); $found = $collection->firstWhere('filename', $script['filename']); if ($found) { @@ -276,6 +313,8 @@ class General extends Component public function save_new_init_script() { + $this->authorize('update', $this->database); + $this->validate([ 'new_filename' => 'required|string', 'new_content' => 'required|string', @@ -305,6 +344,8 @@ class General extends Component public function submit() { try { + $this->authorize('update', $this->database); + if (str($this->database->public_port)->isEmpty()) { $this->database->public_port = null; } diff --git a/app/Livewire/Project/Database/Redis/General.php b/app/Livewire/Project/Database/Redis/General.php index f03f1256d..1eb4f5c8d 100644 --- a/app/Livewire/Project/Database/Redis/General.php +++ b/app/Livewire/Project/Database/Redis/General.php @@ -8,13 +8,17 @@ use App\Helpers\SslHelper; use App\Models\Server; use App\Models\SslCertificate; use App\Models\StandaloneRedis; +use App\Support\ValidationPatterns; use Carbon\Carbon; use Exception; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Livewire\Component; class General extends Component { + use AuthorizesRequests; + public Server $server; public StandaloneRedis $database; @@ -42,20 +46,39 @@ class General extends Component ]; } - protected $rules = [ - 'database.name' => 'required', - 'database.description' => 'nullable', - 'database.redis_conf' => 'nullable', - 'database.image' => 'required', - 'database.ports_mappings' => 'nullable', - 'database.is_public' => 'nullable|boolean', - 'database.public_port' => 'nullable|integer', - 'database.is_log_drain_enabled' => 'nullable|boolean', - 'database.custom_docker_run_options' => 'nullable', - 'redis_username' => 'required', - 'redis_password' => 'required', - 'database.enable_ssl' => 'boolean', - ]; + protected function rules(): array + { + return [ + 'database.name' => ValidationPatterns::nameRules(), + 'database.description' => ValidationPatterns::descriptionRules(), + 'database.redis_conf' => 'nullable', + 'database.image' => 'required', + 'database.ports_mappings' => 'nullable', + 'database.is_public' => 'nullable|boolean', + 'database.public_port' => 'nullable|integer', + 'database.is_log_drain_enabled' => 'nullable|boolean', + 'database.custom_docker_run_options' => 'nullable', + 'redis_username' => 'required', + 'redis_password' => 'required', + 'database.enable_ssl' => 'boolean', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'database.name.required' => 'The Name field is required.', + 'database.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'database.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'database.image.required' => 'The Docker Image field is required.', + 'database.public_port.integer' => 'The Public Port must be an integer.', + 'redis_username.required' => 'The Redis Username field is required.', + 'redis_password.required' => 'The Redis Password field is required.', + ] + ); + } protected $validationAttributes = [ 'database.name' => 'Name', @@ -85,6 +108,8 @@ class General extends Component public function instantSaveAdvanced() { try { + $this->authorize('update', $this->database); + if (! $this->server->isLogDrainEnabled()) { $this->database->is_log_drain_enabled = false; $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); @@ -102,6 +127,8 @@ class General extends Component public function submit() { try { + $this->authorize('manageEnvironment', $this->database); + $this->validate(); if (version_compare($this->redis_version, '6.0', '>=')) { @@ -127,6 +154,8 @@ class General extends Component public function instantSave() { try { + $this->authorize('update', $this->database); + if ($this->database->is_public && ! $this->database->public_port) { $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; @@ -158,6 +187,8 @@ class General extends Component public function instantSaveSSL() { try { + $this->authorize('update', $this->database); + $this->database->save(); $this->dispatch('success', 'SSL configuration updated.'); } catch (Exception $e) { @@ -168,6 +199,8 @@ class General extends Component public function regenerateSslCertificate() { try { + $this->authorize('update', $this->database); + $existingCert = $this->database->sslCertificates()->first(); if (! $existingCert) { diff --git a/app/Livewire/Project/Database/ScheduledBackups.php b/app/Livewire/Project/Database/ScheduledBackups.php index 51d8cb33e..1cf5e53f6 100644 --- a/app/Livewire/Project/Database/ScheduledBackups.php +++ b/app/Livewire/Project/Database/ScheduledBackups.php @@ -3,10 +3,13 @@ namespace App\Livewire\Project\Database; use App\Models\ScheduledDatabaseBackup; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class ScheduledBackups extends Component { + use AuthorizesRequests; + public $database; public $parameters; @@ -53,6 +56,8 @@ class ScheduledBackups extends Component public function setCustomType() { + $this->authorize('update', $this->database); + $this->database->custom_type = $this->custom_type; $this->database->save(); $this->dispatch('success', 'Database type set.'); @@ -61,7 +66,10 @@ class ScheduledBackups extends Component public function delete($scheduled_backup_id): void { - $this->database->scheduledBackups->find($scheduled_backup_id)->delete(); + $backup = $this->database->scheduledBackups->find($scheduled_backup_id); + $this->authorize('manageBackups', $this->database); + + $backup->delete(); $this->dispatch('success', 'Scheduled backup deleted.'); $this->refreshScheduledBackups(); } diff --git a/app/Livewire/Project/DeleteEnvironment.php b/app/Livewire/Project/DeleteEnvironment.php index 1ee5de269..e97206081 100644 --- a/app/Livewire/Project/DeleteEnvironment.php +++ b/app/Livewire/Project/DeleteEnvironment.php @@ -3,10 +3,13 @@ namespace App\Livewire\Project; use App\Models\Environment; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class DeleteEnvironment extends Component { + use AuthorizesRequests; + public int $environment_id; public bool $disabled = false; @@ -31,6 +34,8 @@ class DeleteEnvironment extends Component 'environment_id' => 'required|int', ]); $environment = Environment::findOrFail($this->environment_id); + $this->authorize('delete', $environment); + if ($environment->isEmpty()) { $environment->delete(); diff --git a/app/Livewire/Project/DeleteProject.php b/app/Livewire/Project/DeleteProject.php index f320a19b0..26b35b2e7 100644 --- a/app/Livewire/Project/DeleteProject.php +++ b/app/Livewire/Project/DeleteProject.php @@ -3,10 +3,13 @@ namespace App\Livewire\Project; use App\Models\Project; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class DeleteProject extends Component { + use AuthorizesRequests; + public array $parameters; public int $project_id; @@ -27,6 +30,8 @@ class DeleteProject extends Component 'project_id' => 'required|int', ]); $project = Project::findOrFail($this->project_id); + $this->authorize('delete', $project); + if ($project->isEmpty()) { $project->delete(); diff --git a/app/Livewire/Project/Edit.php b/app/Livewire/Project/Edit.php index 463febb10..a2d73eb5f 100644 --- a/app/Livewire/Project/Edit.php +++ b/app/Livewire/Project/Edit.php @@ -3,19 +3,30 @@ namespace App\Livewire\Project; use App\Models\Project; -use Livewire\Attributes\Validate; +use App\Support\ValidationPatterns; use Livewire\Component; class Edit extends Component { public Project $project; - #[Validate(['required', 'string', 'min:3', 'max:255'])] public string $name; - #[Validate(['nullable', 'string', 'max:255'])] public ?string $description = null; + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + ]; + } + + protected function messages(): array + { + return ValidationPatterns::combinedMessages(); + } + public function mount(string $project_uuid) { try { diff --git a/app/Livewire/Project/EnvironmentEdit.php b/app/Livewire/Project/EnvironmentEdit.php index e98b088ec..d57be2cc8 100644 --- a/app/Livewire/Project/EnvironmentEdit.php +++ b/app/Livewire/Project/EnvironmentEdit.php @@ -4,8 +4,8 @@ namespace App\Livewire\Project; use App\Models\Application; use App\Models\Project; +use App\Support\ValidationPatterns; use Livewire\Attributes\Locked; -use Livewire\Attributes\Validate; use Livewire\Component; class EnvironmentEdit extends Component @@ -17,12 +17,23 @@ class EnvironmentEdit extends Component #[Locked] public $environment; - #[Validate(['required', 'string', 'min:3', 'max:255'])] public string $name; - #[Validate(['nullable', 'string', 'max:255'])] public ?string $description = null; + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + ]; + } + + protected function messages(): array + { + return ValidationPatterns::combinedMessages(); + } + public function mount(string $project_uuid, string $environment_uuid) { try { diff --git a/app/Livewire/Project/Index.php b/app/Livewire/Project/Index.php index 5347d74f0..5381fa78d 100644 --- a/app/Livewire/Project/Index.php +++ b/app/Livewire/Project/Index.php @@ -20,6 +20,7 @@ class Index extends Component $this->private_keys = PrivateKey::ownedByCurrentTeam()->get(); $this->projects = Project::ownedByCurrentTeam()->get()->map(function ($project) { $project->settingsRoute = route('project.edit', ['project_uuid' => $project->uuid]); + $project->canUpdate = auth()->user()->can('update', $project); return $project; }); diff --git a/app/Livewire/Project/New/GithubPrivateRepository.php b/app/Livewire/Project/New/GithubPrivateRepository.php index b1b0aef15..a7aaa94a4 100644 --- a/app/Livewire/Project/New/GithubPrivateRepository.php +++ b/app/Livewire/Project/New/GithubPrivateRepository.php @@ -7,6 +7,7 @@ use App\Models\GithubApp; use App\Models\Project; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; +use App\Rules\ValidGitBranch; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Route; use Livewire\Component; @@ -155,6 +156,21 @@ class GithubPrivateRepository extends Component public function submit() { try { + // Validate git repository parts and branch + $validator = validator([ + 'selected_repository_owner' => $this->selected_repository_owner, + 'selected_repository_repo' => $this->selected_repository_repo, + 'selected_branch_name' => $this->selected_branch_name, + ], [ + 'selected_repository_owner' => 'required|string|regex:/^[a-zA-Z0-9\-_]+$/', + 'selected_repository_repo' => 'required|string|regex:/^[a-zA-Z0-9\-_\.]+$/', + 'selected_branch_name' => ['required', 'string', new ValidGitBranch], + ]); + + if ($validator->fails()) { + throw new \RuntimeException('Invalid repository data: '.$validator->errors()->first()); + } + $destination_uuid = $this->query['destination']; $destination = StandaloneDocker::where('uuid', $destination_uuid)->first(); if (! $destination) { @@ -171,8 +187,8 @@ class GithubPrivateRepository extends Component $application = Application::create([ 'name' => generate_application_name($this->selected_repository_owner.'/'.$this->selected_repository_repo, $this->selected_branch_name), 'repository_project_id' => $this->selected_repository_id, - 'git_repository' => "{$this->selected_repository_owner}/{$this->selected_repository_repo}", - 'git_branch' => $this->selected_branch_name, + 'git_repository' => str($this->selected_repository_owner)->trim()->toString().'/'.str($this->selected_repository_repo)->trim()->toString(), + 'git_branch' => str($this->selected_branch_name)->trim()->toString(), 'build_pack' => $this->build_pack, 'ports_exposes' => $this->port, 'publish_directory' => $this->publish_directory, diff --git a/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php b/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php index 01b0c9ae8..d76f7baaa 100644 --- a/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php +++ b/app/Livewire/Project/New/GithubPrivateRepositoryDeployKey.php @@ -9,6 +9,8 @@ use App\Models\PrivateKey; use App\Models\Project; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; +use App\Rules\ValidGitBranch; +use App\Rules\ValidGitRepositoryUrl; use Illuminate\Support\Str; use Livewire\Component; use Spatie\Url\Url; @@ -53,17 +55,29 @@ class GithubPrivateRepositoryDeployKey extends Component private ?string $git_host = null; - private string $git_repository; + private ?string $git_repository = null; protected $rules = [ - 'repository_url' => 'required', - 'branch' => 'required|string', + 'repository_url' => ['required', 'string'], + 'branch' => ['required', 'string'], 'port' => 'required|numeric', 'is_static' => 'required|boolean', 'publish_directory' => 'nullable|string', 'build_pack' => 'required|string', ]; + protected function rules() + { + return [ + 'repository_url' => ['required', 'string', new ValidGitRepositoryUrl], + 'branch' => ['required', 'string', new ValidGitBranch], + 'port' => 'required|numeric', + 'is_static' => 'required|boolean', + 'publish_directory' => 'nullable|string', + 'build_pack' => 'required|string', + ]; + } + protected $validationAttributes = [ 'repository_url' => 'Repository', 'branch' => 'Branch', @@ -135,6 +149,9 @@ class GithubPrivateRepositoryDeployKey extends Component $this->get_git_source(); + // Note: git_repository has already been validated and transformed in get_git_source() + // It may now be in SSH format (git@host:repo.git) which is valid for deploy keys + $project = Project::where('uuid', $this->parameters['project_uuid'])->first(); $environment = $project->load(['environments'])->environments->where('uuid', $this->parameters['environment_uuid'])->first(); if ($this->git_source === 'other') { @@ -194,6 +211,15 @@ class GithubPrivateRepositoryDeployKey extends Component private function get_git_source() { + // Validate repository URL before parsing + $validator = validator(['repository_url' => $this->repository_url], [ + 'repository_url' => ['required', 'string', new ValidGitRepositoryUrl], + ]); + + if ($validator->fails()) { + throw new \RuntimeException('Invalid repository URL: '.$validator->errors()->first('repository_url')); + } + $this->repository_url_parsed = Url::fromString($this->repository_url); $this->git_host = $this->repository_url_parsed->getHost(); $this->git_repository = $this->repository_url_parsed->getSegment(1).'/'.$this->repository_url_parsed->getSegment(2); @@ -206,8 +232,10 @@ class GithubPrivateRepositoryDeployKey extends Component if (str($this->repository_url)->startsWith('http')) { $this->git_host = $this->repository_url_parsed->getHost(); $this->git_repository = $this->repository_url_parsed->getSegment(1).'/'.$this->repository_url_parsed->getSegment(2); + // Convert to SSH format for deploy key usage $this->git_repository = Str::finish("git@$this->git_host:$this->git_repository", '.git'); } else { + // If it's already in SSH format, just use it as-is $this->git_repository = $this->repository_url; } $this->git_source = 'other'; diff --git a/app/Livewire/Project/New/PublicGitRepository.php b/app/Livewire/Project/New/PublicGitRepository.php index 45b3b5726..8de998a96 100644 --- a/app/Livewire/Project/New/PublicGitRepository.php +++ b/app/Livewire/Project/New/PublicGitRepository.php @@ -9,6 +9,8 @@ use App\Models\Project; use App\Models\Service; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; +use App\Rules\ValidGitBranch; +use App\Rules\ValidGitRepositoryUrl; use Carbon\Carbon; use Livewire\Component; use Spatie\Url\Url; @@ -62,7 +64,7 @@ class PublicGitRepository extends Component public bool $new_compose_services = false; protected $rules = [ - 'repository_url' => 'required|url', + 'repository_url' => ['required', 'string'], 'port' => 'required|numeric', 'isStatic' => 'required|boolean', 'publish_directory' => 'nullable|string', @@ -71,6 +73,20 @@ class PublicGitRepository extends Component 'docker_compose_location' => 'nullable|string', ]; + protected function rules() + { + return [ + 'repository_url' => ['required', 'string', new ValidGitRepositoryUrl], + 'port' => 'required|numeric', + 'isStatic' => 'required|boolean', + 'publish_directory' => 'nullable|string', + 'build_pack' => 'required|string', + 'base_directory' => 'nullable|string', + 'docker_compose_location' => 'nullable|string', + 'git_branch' => ['required', 'string', new ValidGitBranch], + ]; + } + protected $validationAttributes = [ 'repository_url' => 'repository', 'port' => 'port', @@ -141,6 +157,15 @@ class PublicGitRepository extends Component public function loadBranch() { try { + // Validate repository URL + $validator = validator(['repository_url' => $this->repository_url], [ + 'repository_url' => ['required', 'string', new ValidGitRepositoryUrl], + ]); + + if ($validator->fails()) { + throw new \RuntimeException('Invalid repository URL: '.$validator->errors()->first('repository_url')); + } + if (str($this->repository_url)->startsWith('git@')) { $github_instance = str($this->repository_url)->after('git@')->before(':'); $repository = str($this->repository_url)->after(':')->before('.git'); @@ -191,6 +216,15 @@ class PublicGitRepository extends Component $this->git_branch = 'main'; $this->base_directory = '/'; + // Validate repository URL before parsing + $validator = validator(['repository_url' => $this->repository_url], [ + 'repository_url' => ['required', 'string', new ValidGitRepositoryUrl], + ]); + + if ($validator->fails()) { + throw new \RuntimeException('Invalid repository URL: '.$validator->errors()->first('repository_url')); + } + $this->repository_url_parsed = Url::fromString($this->repository_url); $this->git_host = $this->repository_url_parsed->getHost(); $this->git_repository = $this->repository_url_parsed->getSegment(1).'/'.$this->repository_url_parsed->getSegment(2); @@ -234,6 +268,27 @@ class PublicGitRepository extends Component { try { $this->validate(); + + // Additional validation for git repository and branch + if ($this->git_source === 'other') { + // For 'other' sources, git_repository contains the full URL + $validator = validator(['git_repository' => $this->git_repository], [ + 'git_repository' => ['required', 'string', new ValidGitRepositoryUrl], + ]); + + if ($validator->fails()) { + throw new \RuntimeException('Invalid repository URL: '.$validator->errors()->first('git_repository')); + } + } + + $branchValidator = validator(['git_branch' => $this->git_branch], [ + 'git_branch' => ['required', 'string', new ValidGitBranch], + ]); + + if ($branchValidator->fails()) { + throw new \RuntimeException('Invalid branch: '.$branchValidator->errors()->first('git_branch')); + } + $destination_uuid = $this->query['destination']; $project_uuid = $this->parameters['project_uuid']; $environment_uuid = $this->parameters['environment_uuid']; diff --git a/app/Livewire/Project/Resource/Create.php b/app/Livewire/Project/Resource/Create.php index e7cff4f29..3dbe4230c 100644 --- a/app/Livewire/Project/Resource/Create.php +++ b/app/Livewire/Project/Resource/Create.php @@ -15,6 +15,7 @@ class Create extends Component public function mount() { + $type = str(request()->query('type')); $destination_uuid = request()->query('destination'); $server_id = request()->query('server_id'); diff --git a/app/Livewire/Project/Service/Configuration.php b/app/Livewire/Project/Service/Configuration.php index 8ac74e7de..559851e3a 100644 --- a/app/Livewire/Project/Service/Configuration.php +++ b/app/Livewire/Project/Service/Configuration.php @@ -3,11 +3,14 @@ namespace App\Livewire\Project\Service; use App\Models\Service; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Livewire\Component; class Configuration extends Component { + use AuthorizesRequests; + public $currentRoute; public $project; @@ -40,24 +43,30 @@ class Configuration extends Component public function mount() { - $this->parameters = get_route_parameters(); - $this->currentRoute = request()->route()->getName(); - $this->query = request()->query(); - $project = currentTeam() - ->projects() - ->select('id', 'uuid', 'team_id') - ->where('uuid', request()->route('project_uuid')) - ->firstOrFail(); - $environment = $project->environments() - ->select('id', 'uuid', 'name', 'project_id') - ->where('uuid', request()->route('environment_uuid')) - ->firstOrFail(); - $this->service = $environment->services()->whereUuid(request()->route('service_uuid'))->firstOrFail(); + try { + $this->parameters = get_route_parameters(); + $this->currentRoute = request()->route()->getName(); + $this->query = request()->query(); + $project = currentTeam() + ->projects() + ->select('id', 'uuid', 'team_id') + ->where('uuid', request()->route('project_uuid')) + ->firstOrFail(); + $environment = $project->environments() + ->select('id', 'uuid', 'name', 'project_id') + ->where('uuid', request()->route('environment_uuid')) + ->firstOrFail(); + $this->service = $environment->services()->whereUuid(request()->route('service_uuid'))->firstOrFail(); - $this->project = $project; - $this->environment = $environment; - $this->applications = $this->service->applications->sort(); - $this->databases = $this->service->databases->sort(); + $this->authorize('view', $this->service); + + $this->project = $project; + $this->environment = $environment; + $this->applications = $this->service->applications->sort(); + $this->databases = $this->service->databases->sort(); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function refreshServices() @@ -70,6 +79,7 @@ class Configuration extends Component public function restartApplication($id) { try { + $this->authorize('update', $this->service); $application = $this->service->applications->find($id); if ($application) { $application->restart(); @@ -83,6 +93,7 @@ class Configuration extends Component public function restartDatabase($id) { try { + $this->authorize('update', $this->service); $database = $this->service->databases->find($id); if ($database) { $database->restart(); diff --git a/app/Livewire/Project/Service/Database.php b/app/Livewire/Project/Service/Database.php index 0af757c8c..abf4c45a7 100644 --- a/app/Livewire/Project/Service/Database.php +++ b/app/Livewire/Project/Service/Database.php @@ -6,6 +6,7 @@ use App\Actions\Database\StartDatabaseProxy; use App\Actions\Database\StopDatabaseProxy; use App\Models\InstanceSettings; use App\Models\ServiceDatabase; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; @@ -13,6 +14,8 @@ use Livewire\Component; class Database extends Component { + use AuthorizesRequests; + public ServiceDatabase $database; public ?string $db_url_public = null; @@ -40,24 +43,31 @@ class Database extends Component public function mount() { - $this->parameters = get_route_parameters(); - if ($this->database->is_public) { - $this->db_url_public = $this->database->getServiceDatabaseUrl(); + try { + $this->parameters = get_route_parameters(); + $this->authorize('view', $this->database); + if ($this->database->is_public) { + $this->db_url_public = $this->database->getServiceDatabaseUrl(); + } + $this->refreshFileStorages(); + } catch (\Throwable $e) { + return handleError($e, $this); } - $this->refreshFileStorages(); } public function delete($password) { - if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { - if (! Hash::check($password, Auth::user()->password)) { - $this->addError('password', 'The provided password is incorrect.'); - - return; - } - } - try { + $this->authorize('delete', $this->database); + + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { + if (! Hash::check($password, Auth::user()->password)) { + $this->addError('password', 'The provided password is incorrect.'); + + return; + } + } + $this->database->delete(); $this->dispatch('success', 'Database deleted.'); @@ -69,24 +79,35 @@ class Database extends Component public function instantSaveExclude() { - $this->submit(); + try { + $this->authorize('update', $this->database); + $this->submit(); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function instantSaveLogDrain() { - if (! $this->database->service->destination->server->isLogDrainEnabled()) { - $this->database->is_log_drain_enabled = false; - $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); + try { + $this->authorize('update', $this->database); + if (! $this->database->service->destination->server->isLogDrainEnabled()) { + $this->database->is_log_drain_enabled = false; + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); - return; + return; + } + $this->submit(); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); + } catch (\Throwable $e) { + return handleError($e, $this); } - $this->submit(); - $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } public function convertToApplication() { try { + $this->authorize('update', $this->database); $service = $this->database->service; $serviceDatabase = $this->database; @@ -122,28 +143,33 @@ class Database extends Component public function instantSave() { - if ($this->database->is_public && ! $this->database->public_port) { - $this->dispatch('error', 'Public port is required.'); - $this->database->is_public = false; - - return; - } - if ($this->database->is_public) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); + try { + $this->authorize('update', $this->database); + if ($this->database->is_public && ! $this->database->public_port) { + $this->dispatch('error', 'Public port is required.'); $this->database->is_public = false; return; } - StartDatabaseProxy::run($this->database); - $this->db_url_public = $this->database->getServiceDatabaseUrl(); - $this->dispatch('success', 'Database is now publicly accessible.'); - } else { - StopDatabaseProxy::run($this->database); - $this->db_url_public = null; - $this->dispatch('success', 'Database is no longer publicly accessible.'); + if ($this->database->is_public) { + if (! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->database->is_public = false; + + return; + } + StartDatabaseProxy::run($this->database); + $this->db_url_public = $this->database->getServiceDatabaseUrl(); + $this->dispatch('success', 'Database is now publicly accessible.'); + } else { + StopDatabaseProxy::run($this->database); + $this->db_url_public = null; + $this->dispatch('success', 'Database is no longer publicly accessible.'); + } + $this->submit(); + } catch (\Throwable $e) { + return handleError($e, $this); } - $this->submit(); } public function refreshFileStorages() @@ -154,11 +180,13 @@ class Database extends Component public function submit() { try { + $this->authorize('update', $this->database); $this->validate(); $this->database->save(); updateCompose($this->database); $this->dispatch('success', 'Database saved.'); - } catch (\Throwable) { + } catch (\Throwable $e) { + return handleError($e, $this); } finally { $this->dispatch('generateDockerCompose'); } diff --git a/app/Livewire/Project/Service/FileStorage.php b/app/Livewire/Project/Service/FileStorage.php index 5b88c15eb..2933a8cca 100644 --- a/app/Livewire/Project/Service/FileStorage.php +++ b/app/Livewire/Project/Service/FileStorage.php @@ -15,12 +15,15 @@ use App\Models\StandaloneMongodb; use App\Models\StandaloneMysql; use App\Models\StandalonePostgresql; use App\Models\StandaloneRedis; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Livewire\Component; class FileStorage extends Component { + use AuthorizesRequests; + public LocalFileVolume $fileStorage; public ServiceApplication|StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|ServiceDatabase|Application $resource; @@ -54,6 +57,8 @@ class FileStorage extends Component public function convertToDirectory() { try { + $this->authorize('update', $this->resource); + $this->fileStorage->deleteStorageOnServer(); $this->fileStorage->is_directory = true; $this->fileStorage->content = null; @@ -70,6 +75,8 @@ class FileStorage extends Component public function loadStorageOnServer() { try { + $this->authorize('update', $this->resource); + $this->fileStorage->loadStorageOnServer(); $this->dispatch('success', 'File storage loaded from server.'); } catch (\Throwable $e) { @@ -82,6 +89,8 @@ class FileStorage extends Component public function convertToFile() { try { + $this->authorize('update', $this->resource); + $this->fileStorage->deleteStorageOnServer(); $this->fileStorage->is_directory = false; $this->fileStorage->content = null; @@ -99,6 +108,8 @@ class FileStorage extends Component public function delete($password) { + $this->authorize('update', $this->resource); + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); @@ -127,6 +138,8 @@ class FileStorage extends Component public function submit() { + $this->authorize('update', $this->resource); + $original = $this->fileStorage->getOriginal(); try { $this->validate(); diff --git a/app/Livewire/Project/Service/Index.php b/app/Livewire/Project/Service/Index.php index 39f4e106d..8d37d3e31 100644 --- a/app/Livewire/Project/Service/Index.php +++ b/app/Livewire/Project/Service/Index.php @@ -5,11 +5,14 @@ namespace App\Livewire\Project\Service; use App\Models\Service; use App\Models\ServiceApplication; use App\Models\ServiceDatabase; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Component; class Index extends Component { + use AuthorizesRequests; + public ?Service $service = null; public ?ServiceApplication $serviceApplication = null; @@ -36,6 +39,7 @@ class Index extends Component if (! $this->service) { return redirect()->route('dashboard'); } + $this->authorize('view', $this->service); $service = $this->service->applications()->whereUuid($this->parameters['stack_service_uuid'])->first(); if ($service) { $this->serviceApplication = $service; @@ -52,7 +56,12 @@ class Index extends Component public function generateDockerCompose() { - $this->service->parse(); + try { + $this->authorize('update', $this->service); + $this->service->parse(); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function render() diff --git a/app/Livewire/Project/Service/ServiceApplicationView.php b/app/Livewire/Project/Service/ServiceApplicationView.php index 64f7ab95c..5e178374b 100644 --- a/app/Livewire/Project/Service/ServiceApplicationView.php +++ b/app/Livewire/Project/Service/ServiceApplicationView.php @@ -4,6 +4,7 @@ namespace App\Livewire\Project\Service; use App\Models\InstanceSettings; use App\Models\ServiceApplication; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; @@ -12,6 +13,8 @@ use Spatie\Url\Url; class ServiceApplicationView extends Component { + use AuthorizesRequests; + public ServiceApplication $application; public $parameters; @@ -34,32 +37,44 @@ class ServiceApplicationView extends Component public function instantSave() { - $this->submit(); + try { + $this->authorize('update', $this->application); + $this->submit(); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function instantSaveAdvanced() { - if (! $this->application->service->destination->server->isLogDrainEnabled()) { - $this->application->is_log_drain_enabled = false; - $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); + try { + $this->authorize('update', $this->application); + if (! $this->application->service->destination->server->isLogDrainEnabled()) { + $this->application->is_log_drain_enabled = false; + $this->dispatch('error', 'Log drain is not enabled on the server. Please enable it first.'); - return; + return; + } + $this->application->save(); + $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); + } catch (\Throwable $e) { + return handleError($e, $this); } - $this->application->save(); - $this->dispatch('success', 'You need to restart the service for the changes to take effect.'); } public function delete($password) { - if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { - if (! Hash::check($password, Auth::user()->password)) { - $this->addError('password', 'The provided password is incorrect.'); - - return; - } - } - try { + $this->authorize('delete', $this->application); + + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { + if (! Hash::check($password, Auth::user()->password)) { + $this->addError('password', 'The provided password is incorrect.'); + + return; + } + } + $this->application->delete(); $this->dispatch('success', 'Application deleted.'); @@ -71,12 +86,18 @@ class ServiceApplicationView extends Component public function mount() { - $this->parameters = get_route_parameters(); + try { + $this->parameters = get_route_parameters(); + $this->authorize('view', $this->application); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function convertToDatabase() { try { + $this->authorize('update', $this->application); $service = $this->application->service; $serviceApplication = $this->application; @@ -111,6 +132,7 @@ class ServiceApplicationView extends Component public function submit() { try { + $this->authorize('update', $this->application); $this->application->fqdn = str($this->application->fqdn)->replaceEnd(',', '')->trim(); $this->application->fqdn = str($this->application->fqdn)->replaceStart(',', '')->trim(); $this->application->fqdn = str($this->application->fqdn)->trim()->explode(',')->map(function ($domain) { diff --git a/app/Livewire/Project/Service/StackForm.php b/app/Livewire/Project/Service/StackForm.php index a67bd9210..1961a7985 100644 --- a/app/Livewire/Project/Service/StackForm.php +++ b/app/Livewire/Project/Service/StackForm.php @@ -3,6 +3,7 @@ namespace App\Livewire\Project\Service; use App\Models\Service; +use App\Support\ValidationPatterns; use Illuminate\Support\Collection; use Livewire\Component; @@ -14,13 +15,38 @@ class StackForm extends Component protected $listeners = ['saveCompose']; - public $rules = [ - 'service.docker_compose_raw' => 'required', - 'service.docker_compose' => 'required', - 'service.name' => 'required', - 'service.description' => 'nullable', - 'service.connect_to_docker_network' => 'nullable', - ]; + protected function rules(): array + { + $baseRules = [ + 'service.docker_compose_raw' => 'required', + 'service.docker_compose' => 'required', + 'service.name' => ValidationPatterns::nameRules(), + 'service.description' => ValidationPatterns::descriptionRules(), + 'service.connect_to_docker_network' => 'nullable', + ]; + + // Add dynamic field rules + foreach ($this->fields ?? collect() as $key => $field) { + $rules = data_get($field, 'rules', 'nullable'); + $baseRules["fields.$key.value"] = $rules; + } + + return $baseRules; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'service.name.required' => 'The Name field is required.', + 'service.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'service.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'service.docker_compose_raw.required' => 'The Docker Compose Raw field is required.', + 'service.docker_compose.required' => 'The Docker Compose field is required.', + ] + ); + } public $validationAttributes = []; @@ -45,7 +71,6 @@ class StackForm extends Component 'customHelper' => $customHelper, ]); - $this->rules["fields.$key.value"] = $rules; $this->validationAttributes["fields.$key.value"] = $fieldKey; } } diff --git a/app/Livewire/Project/Service/Storage.php b/app/Livewire/Project/Service/Storage.php index 4b64a8b5e..26cd54425 100644 --- a/app/Livewire/Project/Service/Storage.php +++ b/app/Livewire/Project/Service/Storage.php @@ -3,10 +3,13 @@ namespace App\Livewire\Project\Service; use App\Models\LocalPersistentVolume; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Storage extends Component { + use AuthorizesRequests; + public $resource; public $fileStorage; @@ -42,6 +45,8 @@ class Storage extends Component public function addNewVolume($data) { try { + $this->authorize('update', $this->resource); + LocalPersistentVolume::create([ 'name' => $data['name'], 'mount_path' => $data['mount_path'], diff --git a/app/Livewire/Project/Shared/Danger.php b/app/Livewire/Project/Shared/Danger.php index 7da48f9fb..0ed1347f8 100644 --- a/app/Livewire/Project/Shared/Danger.php +++ b/app/Livewire/Project/Shared/Danger.php @@ -7,6 +7,7 @@ use App\Models\InstanceSettings; use App\Models\Service; use App\Models\ServiceApplication; use App\Models\ServiceDatabase; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Livewire\Component; @@ -14,6 +15,8 @@ use Visus\Cuid2\Cuid2; class Danger extends Component { + use AuthorizesRequests; + public $resource; public $resourceName; @@ -34,6 +37,8 @@ class Danger extends Component public string $resourceDomain = ''; + public bool $canDelete = false; + public function mount() { $parameters = get_route_parameters(); @@ -77,6 +82,13 @@ class Danger extends Component 'service-database' => $this->resource->name ?? 'Service Database', default => 'Unknown Resource', }; + + // Check if user can delete this resource + try { + $this->canDelete = auth()->user()->can('delete', $this->resource); + } catch (\Exception $e) { + $this->canDelete = false; + } } public function delete($password) @@ -96,13 +108,14 @@ class Danger extends Component } try { + $this->authorize('delete', $this->resource); $this->resource->delete(); DeleteResourceJob::dispatch( $this->resource, - $this->delete_configurations, $this->delete_volumes, - $this->docker_cleanup, - $this->delete_connected_networks + $this->delete_connected_networks, + $this->delete_configurations, + $this->docker_cleanup ); return redirect()->route('project.resource.index', [ diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/Add.php b/app/Livewire/Project/Shared/EnvironmentVariable/Add.php index 0dbf0f957..cf7843f84 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/Add.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/Add.php @@ -2,10 +2,13 @@ namespace App\Livewire\Project\Shared\EnvironmentVariable; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Add extends Component { + use AuthorizesRequests; + public $parameters; public bool $shared = false; diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/All.php b/app/Livewire/Project/Shared/EnvironmentVariable/All.php index 3b6d8b937..3631a43c8 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/All.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/All.php @@ -4,11 +4,12 @@ namespace App\Livewire\Project\Shared\EnvironmentVariable; use App\Models\EnvironmentVariable; use App\Traits\EnvironmentVariableProtection; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class All extends Component { - use EnvironmentVariableProtection; + use AuthorizesRequests, EnvironmentVariableProtection; public $resource; @@ -44,10 +45,16 @@ class All extends Component public function instantSave() { - $this->resource->settings->is_env_sorting_enabled = $this->is_env_sorting_enabled; - $this->resource->settings->save(); - $this->sortEnvironmentVariables(); - $this->dispatch('success', 'Environment variable settings updated.'); + try { + $this->authorize('manageEnvironment', $this->resource); + + $this->resource->settings->is_env_sorting_enabled = $this->is_env_sorting_enabled; + $this->resource->settings->save(); + $this->sortEnvironmentVariables(); + $this->dispatch('success', 'Environment variable settings updated.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function sortEnvironmentVariables() @@ -96,6 +103,7 @@ class All extends Component public function submit($data = null) { try { + $this->authorize('manageEnvironment', $this->resource); if ($data === null) { $this->handleBulkSubmit(); } else { diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php index 966d626b1..1a9daf77b 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php @@ -5,11 +5,12 @@ namespace App\Livewire\Project\Shared\EnvironmentVariable; use App\Models\EnvironmentVariable as ModelsEnvironmentVariable; use App\Models\SharedEnvironmentVariable; use App\Traits\EnvironmentVariableProtection; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Show extends Component { - use EnvironmentVariableProtection; + use AuthorizesRequests, EnvironmentVariableProtection; public $parameters; @@ -75,6 +76,11 @@ class Show extends Component } } + public function getResourceProperty() + { + return $this->env->resourceable ?? $this->env; + } + public function refresh() { $this->syncData(); @@ -140,6 +146,8 @@ class Show extends Component public function lock() { + $this->authorize('update', $this->env); + $this->env->is_shown_once = true; if ($this->isSharedVariable) { unset($this->env->is_required); @@ -158,6 +166,8 @@ class Show extends Component public function submit() { try { + $this->authorize('update', $this->env); + if (! $this->isSharedVariable && $this->is_required && str($this->value)->isEmpty()) { $oldValue = $this->env->getOriginal('value'); $this->value = $oldValue; @@ -179,9 +189,11 @@ class Show extends Component public function delete() { try { + $this->authorize('delete', $this->env); + // Check if the variable is used in Docker Compose - if ($this->type === 'service' || $this->type === 'application' && $this->env->resource()?->docker_compose) { - [$isUsed, $reason] = $this->isEnvironmentVariableUsedInDockerCompose($this->env->key, $this->env->resource()?->docker_compose); + if ($this->type === 'service' || $this->type === 'application' && $this->env->resourceable?->docker_compose) { + [$isUsed, $reason] = $this->isEnvironmentVariableUsedInDockerCompose($this->env->key, $this->env->resourceable?->docker_compose); if ($isUsed) { $this->dispatch('error', "Cannot delete environment variable '{$this->env->key}' <br><br>Please remove it from the Docker Compose file first."); diff --git a/app/Livewire/Project/Shared/ExecuteContainerCommand.php b/app/Livewire/Project/Shared/ExecuteContainerCommand.php index ca1597d4f..6833492a6 100644 --- a/app/Livewire/Project/Shared/ExecuteContainerCommand.php +++ b/app/Livewire/Project/Shared/ExecuteContainerCommand.php @@ -132,11 +132,24 @@ class ExecuteContainerCommand extends Component }); } } + + // Sort containers alphabetically by name + $this->containers = $this->containers->sortBy(function ($container) { + return data_get($container, 'container.Names'); + }); + if ($this->containers->count() === 1) { $this->selected_container = data_get($this->containers->first(), 'container.Names'); } } + public function updatedSelectedContainer() + { + if ($this->selected_container !== 'default') { + $this->connectToContainer(); + } + } + #[On('connectToServer')] public function connectToServer() { @@ -151,6 +164,9 @@ class ExecuteContainerCommand extends Component data_get($server, 'name'), data_get($server, 'uuid') ); + + // Dispatch a frontend event to ensure terminal gets focus after connection + $this->dispatch('terminal-should-focus'); } catch (\Throwable $e) { return handleError($e, $this); } finally { @@ -206,6 +222,9 @@ class ExecuteContainerCommand extends Component data_get($container, 'container.Names'), data_get($container, 'server.uuid') ); + + // Dispatch a frontend event to ensure terminal gets focus after connection + $this->dispatch('terminal-should-focus'); } catch (\Throwable $e) { return handleError($e, $this); } finally { diff --git a/app/Livewire/Project/Shared/HealthChecks.php b/app/Livewire/Project/Shared/HealthChecks.php index 83162e36a..ae94f7cf2 100644 --- a/app/Livewire/Project/Shared/HealthChecks.php +++ b/app/Livewire/Project/Shared/HealthChecks.php @@ -2,10 +2,13 @@ namespace App\Livewire\Project\Shared; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class HealthChecks extends Component { + use AuthorizesRequests; + public $resource; protected $rules = [ @@ -27,6 +30,7 @@ class HealthChecks extends Component public function instantSave() { + $this->authorize('update', $this->resource); $this->resource->save(); $this->dispatch('success', 'Health check updated.'); } @@ -34,6 +38,7 @@ class HealthChecks extends Component public function submit() { try { + $this->authorize('update', $this->resource); $this->validate(); $this->resource->save(); $this->dispatch('success', 'Health check updated.'); diff --git a/app/Livewire/Project/Shared/ResourceLimits.php b/app/Livewire/Project/Shared/ResourceLimits.php index 608dfbf02..196badec8 100644 --- a/app/Livewire/Project/Shared/ResourceLimits.php +++ b/app/Livewire/Project/Shared/ResourceLimits.php @@ -2,10 +2,13 @@ namespace App\Livewire\Project\Shared; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class ResourceLimits extends Component { + use AuthorizesRequests; + public $resource; protected $rules = [ @@ -31,6 +34,7 @@ class ResourceLimits extends Component public function submit() { try { + $this->authorize('update', $this->resource); if (! $this->resource->limits_memory) { $this->resource->limits_memory = '0'; } diff --git a/app/Livewire/Project/Shared/ResourceOperations.php b/app/Livewire/Project/Shared/ResourceOperations.php index fb19acb55..c9b341eed 100644 --- a/app/Livewire/Project/Shared/ResourceOperations.php +++ b/app/Livewire/Project/Shared/ResourceOperations.php @@ -12,11 +12,14 @@ use App\Models\Environment; use App\Models\Project; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; use Visus\Cuid2\Cuid2; class ResourceOperations extends Component { + use AuthorizesRequests; + public $resource; public $projectUuid; @@ -45,6 +48,8 @@ class ResourceOperations extends Component public function cloneTo($destination_id) { + $this->authorize('update', $this->resource); + $new_destination = StandaloneDocker::find($destination_id); if (! $new_destination) { $new_destination = SwarmDocker::find($destination_id); @@ -61,7 +66,7 @@ class ResourceOperations extends Component $url = $this->resource->fqdn; if ($server->proxyType() !== 'NONE' && $applicationSettings->is_container_label_readonly_enabled === true) { - $url = generateFqdn($server, $uuid); + $url = generateFqdn(server: $server, random: $uuid, parserVersion: $this->resource->compose_parsing_version); } $new_resource = $this->resource->replicate([ @@ -412,7 +417,7 @@ class ResourceOperations extends Component if ($this->cloneVolumeData) { try { - StopService::dispatch($application, false, false); + StopService::dispatch($application); $sourceVolume = $volume->name; $targetVolume = $newPersistentVolume->name; $sourceServer = $application->service->destination->server; @@ -454,7 +459,7 @@ class ResourceOperations extends Component if ($this->cloneVolumeData) { try { - StopService::dispatch($database->service, false, false); + StopService::dispatch($database->service); $sourceVolume = $volume->name; $targetVolume = $newPersistentVolume->name; $sourceServer = $database->service->destination->server; @@ -485,6 +490,7 @@ class ResourceOperations extends Component public function moveTo($environment_id) { try { + $this->authorize('update', $this->resource); $new_environment = Environment::findOrFail($environment_id); $this->resource->update([ 'environment_id' => $environment_id, diff --git a/app/Livewire/Project/Shared/ScheduledTask/Add.php b/app/Livewire/Project/Shared/ScheduledTask/Add.php index c286fee5a..e4b666532 100644 --- a/app/Livewire/Project/Shared/ScheduledTask/Add.php +++ b/app/Livewire/Project/Shared/ScheduledTask/Add.php @@ -3,12 +3,15 @@ namespace App\Livewire\Project\Shared\ScheduledTask; use App\Models\ScheduledTask; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Attributes\Locked; use Livewire\Component; class Add extends Component { + use AuthorizesRequests; + public $parameters; #[Locked] @@ -20,6 +23,9 @@ class Add extends Component #[Locked] public Collection $containerNames; + #[Locked] + public $resource; + public string $name; public string $command; @@ -45,6 +51,22 @@ class Add extends Component public function mount() { $this->parameters = get_route_parameters(); + + // Get the resource based on type and id + switch ($this->type) { + case 'application': + $this->resource = \App\Models\Application::findOrFail($this->id); + break; + case 'service': + $this->resource = \App\Models\Service::findOrFail($this->id); + break; + case 'standalone-postgresql': + $this->resource = \App\Models\StandalonePostgresql::findOrFail($this->id); + break; + default: + throw new \Exception('Invalid resource type'); + } + if ($this->containerNames->count() > 0) { $this->container = $this->containerNames->first(); } @@ -53,6 +75,7 @@ class Add extends Component public function submit() { try { + $this->authorize('update', $this->resource); $this->validate(); $isValid = validate_cron_expression($this->frequency); if (! $isValid) { diff --git a/app/Livewire/Project/Shared/ScheduledTask/Show.php b/app/Livewire/Project/Shared/ScheduledTask/Show.php index fe6e36d5c..c8d07ae36 100644 --- a/app/Livewire/Project/Shared/ScheduledTask/Show.php +++ b/app/Livewire/Project/Shared/ScheduledTask/Show.php @@ -6,12 +6,15 @@ use App\Jobs\ScheduledTaskJob; use App\Models\Application; use App\Models\ScheduledTask; use App\Models\Service; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Locked; use Livewire\Attributes\Validate; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + public Application|Service $resource; public ScheduledTask $task; @@ -109,6 +112,7 @@ class Show extends Component public function instantSave() { try { + $this->authorize('update', $this->resource); $this->syncData(true); $this->dispatch('success', 'Scheduled task updated.'); $this->refreshTasks(); @@ -120,6 +124,7 @@ class Show extends Component public function submit() { try { + $this->authorize('update', $this->resource); $this->syncData(true); $this->dispatch('success', 'Scheduled task updated.'); } catch (\Exception $e) { @@ -139,6 +144,7 @@ class Show extends Component public function delete() { try { + $this->authorize('update', $this->resource); $this->task->delete(); if ($this->type === 'application') { @@ -154,6 +160,7 @@ class Show extends Component public function executeNow() { try { + $this->authorize('update', $this->resource); ScheduledTaskJob::dispatch($this->task); $this->dispatch('success', 'Scheduled task executed.'); } catch (\Exception $e) { diff --git a/app/Livewire/Project/Shared/Storages/Add.php b/app/Livewire/Project/Shared/Storages/Add.php index dc015386c..006d41c14 100644 --- a/app/Livewire/Project/Shared/Storages/Add.php +++ b/app/Livewire/Project/Shared/Storages/Add.php @@ -4,10 +4,13 @@ namespace App\Livewire\Project\Shared\Storages; use App\Models\Application; use App\Models\LocalFileVolume; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Add extends Component { + use AuthorizesRequests; + public $resource; public $uuid; @@ -77,6 +80,8 @@ class Add extends Component public function submitFileStorage() { try { + $this->authorize('update', $this->resource); + $this->validate([ 'file_storage_path' => 'string', 'file_storage_content' => 'nullable|string', @@ -112,6 +117,8 @@ class Add extends Component public function submitFileStorageDirectory() { try { + $this->authorize('update', $this->resource); + $this->validate([ 'file_storage_directory_source' => 'string', 'file_storage_directory_destination' => 'string', @@ -140,6 +147,8 @@ class Add extends Component public function submitPersistentVolume() { try { + $this->authorize('update', $this->resource); + $this->validate([ 'name' => 'required|string', 'mount_path' => 'required|string', diff --git a/app/Livewire/Project/Shared/Storages/Show.php b/app/Livewire/Project/Shared/Storages/Show.php index 54b1be3af..3928ee1d4 100644 --- a/app/Livewire/Project/Shared/Storages/Show.php +++ b/app/Livewire/Project/Shared/Storages/Show.php @@ -4,14 +4,19 @@ namespace App\Livewire\Project\Shared\Storages; use App\Models\InstanceSettings; use App\Models\LocalPersistentVolume; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + public LocalPersistentVolume $storage; + public $resource; + public bool $isReadOnly = false; public bool $isFirst = true; @@ -34,6 +39,8 @@ class Show extends Component public function submit() { + $this->authorize('update', $this->resource); + $this->validate(); $this->storage->save(); $this->dispatch('success', 'Storage updated successfully'); @@ -41,6 +48,8 @@ class Show extends Component public function delete($password) { + $this->authorize('update', $this->resource); + if (! data_get(InstanceSettings::get(), 'disable_two_step_confirmation')) { if (! Hash::check($password, Auth::user()->password)) { $this->addError('password', 'The provided password is incorrect.'); diff --git a/app/Livewire/Project/Shared/Tags.php b/app/Livewire/Project/Shared/Tags.php index 811859cb8..37b8b277a 100644 --- a/app/Livewire/Project/Shared/Tags.php +++ b/app/Livewire/Project/Shared/Tags.php @@ -3,12 +3,15 @@ namespace App\Livewire\Project\Shared; use App\Models\Tag; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Validate; use Livewire\Component; // Refactored ✅ class Tags extends Component { + use AuthorizesRequests; + public $resource = null; #[Validate('required|string|min:2')] @@ -34,6 +37,7 @@ class Tags extends Component public function submit() { try { + $this->authorize('update', $this->resource); $this->validate(); $tags = str($this->newTags)->trim()->explode(' '); foreach ($tags as $tag) { @@ -66,6 +70,7 @@ class Tags extends Component public function addTag(string $id, string $name) { try { + $this->authorize('update', $this->resource); $name = strip_tags($name); if ($this->resource->tags()->where('id', $id)->exists()) { $this->dispatch('error', 'Duplicate tags.', "Tag <span class='dark:text-warning'>$name</span> already added."); @@ -83,6 +88,7 @@ class Tags extends Component public function deleteTag(string $id) { try { + $this->authorize('update', $this->resource); $this->resource->tags()->detach($id); $found_more_tags = Tag::ownedByCurrentTeam()->find($id); if ($found_more_tags && $found_more_tags->applications()->count() == 0 && $found_more_tags->services()->count() == 0) { diff --git a/app/Livewire/Project/Shared/Webhooks.php b/app/Livewire/Project/Shared/Webhooks.php index 57c65c4dd..eafc653d5 100644 --- a/app/Livewire/Project/Shared/Webhooks.php +++ b/app/Livewire/Project/Shared/Webhooks.php @@ -2,11 +2,14 @@ namespace App\Livewire\Project\Shared; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; // Refactored ✅ class Webhooks extends Component { + use AuthorizesRequests; + public $resource; public ?string $deploywebhook; diff --git a/app/Livewire/Project/Show.php b/app/Livewire/Project/Show.php index 886a20218..7e828d14c 100644 --- a/app/Livewire/Project/Show.php +++ b/app/Livewire/Project/Show.php @@ -4,7 +4,7 @@ namespace App\Livewire\Project; use App\Models\Environment; use App\Models\Project; -use Livewire\Attributes\Validate; +use App\Support\ValidationPatterns; use Livewire\Component; use Visus\Cuid2\Cuid2; @@ -12,12 +12,23 @@ class Show extends Component { public Project $project; - #[Validate(['required', 'string', 'min:3'])] public string $name; - #[Validate(['nullable', 'string'])] public ?string $description = null; + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + ]; + } + + protected function messages(): array + { + return ValidationPatterns::combinedMessages(); + } + public function mount(string $project_uuid) { try { diff --git a/app/Livewire/Security/ApiTokens.php b/app/Livewire/Security/ApiTokens.php index 72684bdc6..a263acedf 100644 --- a/app/Livewire/Security/ApiTokens.php +++ b/app/Livewire/Security/ApiTokens.php @@ -3,10 +3,14 @@ namespace App\Livewire\Security; use App\Models\InstanceSettings; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; +use Laravel\Sanctum\PersonalAccessToken; use Livewire\Component; class ApiTokens extends Component { + use AuthorizesRequests; + public ?string $description = null; public $tokens = []; @@ -15,6 +19,10 @@ class ApiTokens extends Component public $isApiEnabled; + public bool $canUseRootPermissions = false; + + public bool $canUseWritePermissions = false; + public function render() { return view('livewire.security.api-tokens'); @@ -23,6 +31,8 @@ class ApiTokens extends Component public function mount() { $this->isApiEnabled = InstanceSettings::get()->is_api_enabled; + $this->canUseRootPermissions = auth()->user()->can('useRootPermissions', PersonalAccessToken::class); + $this->canUseWritePermissions = auth()->user()->can('useWritePermissions', PersonalAccessToken::class); $this->getTokens(); } @@ -33,6 +43,23 @@ class ApiTokens extends Component public function updatedPermissions($permissionToUpdate) { + // Check if user is trying to use restricted permissions + if ($permissionToUpdate == 'root' && ! $this->canUseRootPermissions) { + $this->dispatch('error', 'You do not have permission to use root permissions.'); + // Remove root from permissions if it was somehow added + $this->permissions = array_diff($this->permissions, ['root']); + + return; + } + + if (in_array($permissionToUpdate, ['write', 'write:sensitive']) && ! $this->canUseWritePermissions) { + $this->dispatch('error', 'You do not have permission to use write permissions.'); + // Remove write permissions if they were somehow added + $this->permissions = array_diff($this->permissions, ['write', 'write:sensitive']); + + return; + } + if ($permissionToUpdate == 'root') { $this->permissions = ['root']; } elseif ($permissionToUpdate == 'read:sensitive' && ! in_array('read', $this->permissions)) { @@ -50,6 +77,17 @@ class ApiTokens extends Component public function addNewToken() { try { + $this->authorize('create', PersonalAccessToken::class); + + // Validate permissions based on user role + if (in_array('root', $this->permissions) && ! $this->canUseRootPermissions) { + throw new \Exception('You do not have permission to create tokens with root permissions.'); + } + + if (array_intersect(['write', 'write:sensitive'], $this->permissions) && ! $this->canUseWritePermissions) { + throw new \Exception('You do not have permission to create tokens with write permissions.'); + } + $this->validate([ 'description' => 'required|min:3|max:255', ]); @@ -65,6 +103,7 @@ class ApiTokens extends Component { try { $token = auth()->user()->tokens()->where('id', $id)->firstOrFail(); + $this->authorize('delete', $token); $token->delete(); $this->getTokens(); } catch (\Exception $e) { diff --git a/app/Livewire/Security/PrivateKey/Create.php b/app/Livewire/Security/PrivateKey/Create.php index 319cec192..0f36037ff 100644 --- a/app/Livewire/Security/PrivateKey/Create.php +++ b/app/Livewire/Security/PrivateKey/Create.php @@ -3,10 +3,14 @@ namespace App\Livewire\Security\PrivateKey; use App\Models\PrivateKey; +use App\Support\ValidationPatterns; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Create extends Component { + use AuthorizesRequests; + public string $name = ''; public string $value = ''; @@ -17,10 +21,25 @@ class Create extends Component public ?string $publicKey = null; - protected $rules = [ - 'name' => 'required|string', - 'value' => 'required|string', - ]; + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + 'value' => 'required|string', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'value.required' => 'The Private Key field is required.', + 'value.string' => 'The Private Key must be a valid string.', + ] + ); + } public function generateNewRSAKey() { @@ -50,6 +69,7 @@ class Create extends Component $this->validate(); try { + $this->authorize('create', PrivateKey::class); $privateKey = PrivateKey::createAndStore([ 'name' => $this->name, 'description' => $this->description, diff --git a/app/Livewire/Security/PrivateKey/Index.php b/app/Livewire/Security/PrivateKey/Index.php index 76441a67e..950ec152d 100644 --- a/app/Livewire/Security/PrivateKey/Index.php +++ b/app/Livewire/Security/PrivateKey/Index.php @@ -3,10 +3,13 @@ namespace App\Livewire\Security\PrivateKey; use App\Models\PrivateKey; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Index extends Component { + use AuthorizesRequests; + public function render() { $privateKeys = PrivateKey::ownedByCurrentTeam(['name', 'uuid', 'is_git_related', 'description'])->get(); @@ -18,6 +21,7 @@ class Index extends Component public function cleanupUnusedKeys() { + $this->authorize('create', PrivateKey::class); PrivateKey::cleanupUnusedKeys(); $this->dispatch('success', 'Unused keys have been cleaned up.'); } diff --git a/app/Livewire/Security/PrivateKey/Show.php b/app/Livewire/Security/PrivateKey/Show.php index b9195b543..2ff06c349 100644 --- a/app/Livewire/Security/PrivateKey/Show.php +++ b/app/Livewire/Security/PrivateKey/Show.php @@ -3,20 +3,41 @@ namespace App\Livewire\Security\PrivateKey; use App\Models\PrivateKey; +use App\Support\ValidationPatterns; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + public PrivateKey $private_key; public $public_key = 'Loading...'; - protected $rules = [ - 'private_key.name' => 'required|string', - 'private_key.description' => 'nullable|string', - 'private_key.private_key' => 'required|string', - 'private_key.is_git_related' => 'nullable|boolean', - ]; + protected function rules(): array + { + return [ + 'private_key.name' => ValidationPatterns::nameRules(), + 'private_key.description' => ValidationPatterns::descriptionRules(), + 'private_key.private_key' => 'required|string', + 'private_key.is_git_related' => 'nullable|boolean', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'private_key.name.required' => 'The Name field is required.', + 'private_key.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'private_key.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'private_key.private_key.required' => 'The Private Key field is required.', + 'private_key.private_key.string' => 'The Private Key must be a valid string.', + ] + ); + } protected $validationAttributes = [ 'private_key.name' => 'name', @@ -44,6 +65,7 @@ class Show extends Component public function delete() { try { + $this->authorize('delete', $this->private_key); $this->private_key->safeDelete(); currentTeam()->privateKeys = PrivateKey::where('team_id', currentTeam()->id)->get(); @@ -58,6 +80,7 @@ class Show extends Component public function changePrivateKey() { try { + $this->authorize('update', $this->private_key); $this->private_key->updatePrivateKey([ 'private_key' => formatPrivateKey($this->private_key->private_key), ]); diff --git a/app/Livewire/Server/Advanced.php b/app/Livewire/Server/Advanced.php index 1bf8cf4c9..760c4df0d 100644 --- a/app/Livewire/Server/Advanced.php +++ b/app/Livewire/Server/Advanced.php @@ -76,6 +76,7 @@ class Advanced extends Component public function syncData(bool $toModel = false) { if ($toModel) { + $this->authorize('update', $this->server); $this->validate(); $this->server->settings->concurrent_builds = $this->concurrentBuilds; $this->server->settings->dynamic_timeout = $this->dynamicTimeout; diff --git a/app/Livewire/Server/CaCertificate/Show.php b/app/Livewire/Server/CaCertificate/Show.php index 750ed9f81..039b5f71d 100644 --- a/app/Livewire/Server/CaCertificate/Show.php +++ b/app/Livewire/Server/CaCertificate/Show.php @@ -6,12 +6,15 @@ use App\Helpers\SslHelper; use App\Jobs\RegenerateSslCertJob; use App\Models\Server; use App\Models\SslCertificate; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Carbon; use Livewire\Attributes\Locked; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + #[Locked] public Server $server; @@ -52,6 +55,7 @@ class Show extends Component public function saveCaCertificate() { try { + $this->authorize('manageCaCertificate', $this->server); if (! $this->certificateContent) { throw new \Exception('Certificate content cannot be empty.'); } @@ -82,6 +86,7 @@ class Show extends Component public function regenerateCaCertificate() { try { + $this->authorize('manageCaCertificate', $this->server); SslHelper::generateSslCertificate( commonName: 'Coolify CA Certificate', serverId: $this->server->id, diff --git a/app/Livewire/Server/CloudflareTunnel.php b/app/Livewire/Server/CloudflareTunnel.php index b2ffa003f..24f8e022e 100644 --- a/app/Livewire/Server/CloudflareTunnel.php +++ b/app/Livewire/Server/CloudflareTunnel.php @@ -4,11 +4,14 @@ namespace App\Livewire\Server; use App\Actions\Server\ConfigureCloudflared; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Validate; use Livewire\Component; class CloudflareTunnel extends Component { + use AuthorizesRequests; + public Server $server; #[Validate(['required', 'string'])] @@ -51,6 +54,7 @@ class CloudflareTunnel extends Component public function toggleCloudflareTunnels() { try { + $this->authorize('update', $this->server); remote_process(['docker rm -f coolify-cloudflared'], $this->server, false, 10); $this->isCloudflareTunnelsEnabled = false; $this->server->settings->is_cloudflare_tunnel = false; @@ -68,6 +72,7 @@ class CloudflareTunnel extends Component public function manualCloudflareConfig() { + $this->authorize('update', $this->server); $this->isCloudflareTunnelsEnabled = true; $this->server->settings->is_cloudflare_tunnel = true; $this->server->settings->save(); @@ -78,6 +83,7 @@ class CloudflareTunnel extends Component public function automatedCloudflareConfig() { try { + $this->authorize('update', $this->server); if (str($this->ssh_domain)->contains('https://')) { $this->ssh_domain = str($this->ssh_domain)->replace('https://', '')->replace('http://', '')->trim(); $this->ssh_domain = str($this->ssh_domain)->replace('/', ''); diff --git a/app/Livewire/Server/Destinations.php b/app/Livewire/Server/Destinations.php index dbab6e03f..3dbb3fcf8 100644 --- a/app/Livewire/Server/Destinations.php +++ b/app/Livewire/Server/Destinations.php @@ -5,11 +5,14 @@ namespace App\Livewire\Server; use App\Models\Server; use App\Models\StandaloneDocker; use App\Models\SwarmDocker; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Component; class Destinations extends Component { + use AuthorizesRequests; + public Server $server; public Collection $networks; @@ -33,6 +36,7 @@ class Destinations extends Component public function add($name) { if ($this->server->isSwarm()) { + $this->authorize('create', SwarmDocker::class); $found = $this->server->swarmDockers()->where('network', $name)->first(); if ($found) { $this->dispatch('error', 'Network already added to this server.'); @@ -46,6 +50,7 @@ class Destinations extends Component ]); } } else { + $this->authorize('create', StandaloneDocker::class); $found = $this->server->standaloneDockers()->where('network', $name)->first(); if ($found) { $this->dispatch('error', 'Network already added to this server.'); diff --git a/app/Livewire/Server/DockerCleanup.php b/app/Livewire/Server/DockerCleanup.php index d3378d63f..764e583cd 100644 --- a/app/Livewire/Server/DockerCleanup.php +++ b/app/Livewire/Server/DockerCleanup.php @@ -4,11 +4,14 @@ namespace App\Livewire\Server; use App\Jobs\DockerCleanupJob; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Validate; use Livewire\Component; class DockerCleanup extends Component { + use AuthorizesRequests; + public Server $server; public array $parameters = []; @@ -42,6 +45,7 @@ class DockerCleanup extends Component public function syncData(bool $toModel = false) { if ($toModel) { + $this->authorize('update', $this->server); $this->validate(); $this->server->settings->force_docker_cleanup = $this->forceDockerCleanup; $this->server->settings->docker_cleanup_frequency = $this->dockerCleanupFrequency; @@ -71,7 +75,8 @@ class DockerCleanup extends Component public function manualCleanup() { try { - DockerCleanupJob::dispatch($this->server, true); + $this->authorize('update', $this->server); + DockerCleanupJob::dispatch($this->server, true, $this->deleteUnusedVolumes, $this->deleteUnusedNetworks); $this->dispatch('success', 'Manual cleanup job started. Depending on the amount of data, this might take a while.'); } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Livewire/Server/LogDrains.php b/app/Livewire/Server/LogDrains.php index edddfc755..d4a65af81 100644 --- a/app/Livewire/Server/LogDrains.php +++ b/app/Livewire/Server/LogDrains.php @@ -5,11 +5,14 @@ namespace App\Livewire\Server; use App\Actions\Server\StartLogDrain; use App\Actions\Server\StopLogDrain; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Validate; use Livewire\Component; class LogDrains extends Component { + use AuthorizesRequests; + public Server $server; #[Validate(['boolean'])] @@ -160,6 +163,7 @@ class LogDrains extends Component public function instantSave() { try { + $this->authorize('update', $this->server); $this->syncData(true); if ($this->server->isLogDrainEnabled()) { StartLogDrain::run($this->server); @@ -176,6 +180,7 @@ class LogDrains extends Component public function submit(string $type) { try { + $this->authorize('update', $this->server); $this->syncData(true, $type); $this->dispatch('success', 'Settings saved.'); } catch (\Throwable $e) { diff --git a/app/Livewire/Server/Navbar.php b/app/Livewire/Server/Navbar.php index 5381d1e19..055290580 100644 --- a/app/Livewire/Server/Navbar.php +++ b/app/Livewire/Server/Navbar.php @@ -8,10 +8,13 @@ use App\Actions\Proxy\StopProxy; use App\Jobs\RestartProxyJob; use App\Models\Server; use App\Services\ProxyDashboardCacheService; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Navbar extends Component { + use AuthorizesRequests; + public Server $server; public bool $isChecking = false; @@ -57,6 +60,7 @@ class Navbar extends Component public function restart() { try { + $this->authorize('manageProxy', $this->server); RestartProxyJob::dispatch($this->server); } catch (\Throwable $e) { return handleError($e, $this); @@ -66,6 +70,7 @@ class Navbar extends Component public function checkProxy() { try { + $this->authorize('manageProxy', $this->server); CheckProxy::run($this->server, true); $this->dispatch('startProxy')->self(); } catch (\Throwable $e) { @@ -76,6 +81,7 @@ class Navbar extends Component public function startProxy() { try { + $this->authorize('manageProxy', $this->server); $activity = StartProxy::run($this->server, force: true); $this->dispatch('activityMonitor', $activity->id); } catch (\Throwable $e) { @@ -86,6 +92,7 @@ class Navbar extends Component public function stop(bool $forceStop = true) { try { + $this->authorize('manageProxy', $this->server); StopProxy::dispatch($this->server, $forceStop); } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Livewire/Server/New/ByIp.php b/app/Livewire/Server/New/ByIp.php index 5f60c5db5..116775a6f 100644 --- a/app/Livewire/Server/New/ByIp.php +++ b/app/Livewire/Server/New/ByIp.php @@ -5,56 +5,46 @@ namespace App\Livewire\Server\New; use App\Enums\ProxyTypes; use App\Models\Server; use App\Models\Team; +use App\Support\ValidationPatterns; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Collection; use Livewire\Attributes\Locked; -use Livewire\Attributes\Validate; use Livewire\Component; class ByIp extends Component { + use AuthorizesRequests; + #[Locked] public $private_keys; #[Locked] public $limit_reached; - #[Validate('nullable|integer', as: 'Private Key')] public ?int $private_key_id = null; - #[Validate('nullable|string', as: 'Private Key Name')] public $new_private_key_name; - #[Validate('nullable|string', as: 'Private Key Description')] public $new_private_key_description; - #[Validate('nullable|string', as: 'Private Key Value')] public $new_private_key_value; - #[Validate('required|string', as: 'Name')] public string $name; - #[Validate('nullable|string', as: 'Description')] public ?string $description = null; - #[Validate('required|string', as: 'IP Address/Domain')] public string $ip; - #[Validate('required|string', as: 'User')] public string $user = 'root'; - #[Validate('required|integer|between:1,65535', as: 'Port')] public int $port = 22; - #[Validate('required|boolean', as: 'Swarm Manager')] public bool $is_swarm_manager = false; - #[Validate('required|boolean', as: 'Swarm Worker')] public bool $is_swarm_worker = false; - #[Validate('nullable|integer', as: 'Swarm Cluster')] public $selected_swarm_cluster = null; - #[Validate('required|boolean', as: 'Build Server')] public bool $is_build_server = false; #[Locked] @@ -70,6 +60,50 @@ class ByIp extends Component } } + protected function rules(): array + { + return [ + 'private_key_id' => 'nullable|integer', + 'new_private_key_name' => 'nullable|string', + 'new_private_key_description' => 'nullable|string', + 'new_private_key_value' => 'nullable|string', + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + 'ip' => 'required|string', + 'user' => 'required|string', + 'port' => 'required|integer|between:1,65535', + 'is_swarm_manager' => 'required|boolean', + 'is_swarm_worker' => 'required|boolean', + 'selected_swarm_cluster' => 'nullable|integer', + 'is_build_server' => 'required|boolean', + ]; + } + + protected function messages(): array + { + return array_merge(ValidationPatterns::combinedMessages(), [ + 'private_key_id.integer' => 'The Private Key field must be an integer.', + 'private_key_id.nullable' => 'The Private Key field is optional.', + 'new_private_key_name.string' => 'The Private Key Name must be a string.', + 'new_private_key_description.string' => 'The Private Key Description must be a string.', + 'new_private_key_value.string' => 'The Private Key Value must be a string.', + 'ip.required' => 'The IP Address/Domain is required.', + 'ip.string' => 'The IP Address/Domain must be a string.', + 'user.required' => 'The User field is required.', + 'user.string' => 'The User field must be a string.', + 'port.required' => 'The Port field is required.', + 'port.integer' => 'The Port field must be an integer.', + 'port.between' => 'The Port field must be between 1 and 65535.', + 'is_swarm_manager.required' => 'The Swarm Manager field is required.', + 'is_swarm_manager.boolean' => 'The Swarm Manager field must be true or false.', + 'is_swarm_worker.required' => 'The Swarm Worker field is required.', + 'is_swarm_worker.boolean' => 'The Swarm Worker field must be true or false.', + 'selected_swarm_cluster.integer' => 'The Swarm Cluster field must be an integer.', + 'is_build_server.required' => 'The Build Server field is required.', + 'is_build_server.boolean' => 'The Build Server field must be true or false.', + ]); + } + public function setPrivateKey(string $private_key_id) { $this->private_key_id = $private_key_id; @@ -84,6 +118,7 @@ class ByIp extends Component { $this->validate(); try { + $this->authorize('create', Server::class); if (Server::where('team_id', currentTeam()->id) ->where('ip', $this->ip) ->exists()) { diff --git a/app/Livewire/Server/PrivateKey/Show.php b/app/Livewire/Server/PrivateKey/Show.php index 64aa1884b..845d568ce 100644 --- a/app/Livewire/Server/PrivateKey/Show.php +++ b/app/Livewire/Server/PrivateKey/Show.php @@ -4,10 +4,13 @@ namespace App\Livewire\Server\PrivateKey; use App\Models\PrivateKey; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + public Server $server; public $privateKeys = []; @@ -35,6 +38,7 @@ class Show extends Component $originalPrivateKeyId = $this->server->getOriginal('private_key_id'); try { + $this->authorize('update', $this->server); $this->server->update(['private_key_id' => $privateKeyId]); ['uptime' => $uptime, 'error' => $error] = $this->server->validateConnection(justCheckingNewKey: true); if ($uptime) { diff --git a/app/Livewire/Server/Proxy.php b/app/Livewire/Server/Proxy.php index 1cf8c839e..49adf7fe6 100644 --- a/app/Livewire/Server/Proxy.php +++ b/app/Livewire/Server/Proxy.php @@ -5,10 +5,13 @@ namespace App\Livewire\Server; use App\Actions\Proxy\CheckConfiguration; use App\Actions\Proxy\SaveConfiguration; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Proxy extends Component { + use AuthorizesRequests; + public Server $server; public ?string $selectedProxy = null; @@ -47,6 +50,7 @@ class Proxy extends Component public function changeProxy() { + $this->authorize('update', $this->server); $this->server->proxy = null; $this->server->save(); @@ -56,6 +60,7 @@ class Proxy extends Component public function selectProxy($proxy_type) { try { + $this->authorize('update', $this->server); $this->server->changeProxy($proxy_type, async: false); $this->selectedProxy = $this->server->proxy->type; @@ -68,6 +73,7 @@ class Proxy extends Component public function instantSave() { try { + $this->authorize('update', $this->server); $this->validate(); $this->server->settings->save(); $this->dispatch('success', 'Settings saved.'); @@ -79,6 +85,7 @@ class Proxy extends Component public function instantSaveRedirect() { try { + $this->authorize('update', $this->server); $this->server->proxy->redirect_enabled = $this->redirect_enabled; $this->server->save(); $this->server->setupDefaultRedirect(); @@ -91,6 +98,7 @@ class Proxy extends Component public function submit() { try { + $this->authorize('update', $this->server); SaveConfiguration::run($this->server, $this->proxy_settings); $this->server->proxy->redirect_url = $this->redirect_url; $this->server->save(); @@ -104,6 +112,7 @@ class Proxy extends Component public function reset_proxy_configuration() { try { + $this->authorize('update', $this->server); $this->proxy_settings = CheckConfiguration::run($this->server, true); SaveConfiguration::run($this->server, $this->proxy_settings); $this->server->save(); diff --git a/app/Livewire/Server/Proxy/DynamicConfigurationNavbar.php b/app/Livewire/Server/Proxy/DynamicConfigurationNavbar.php index 392ad38fa..f377bbeb9 100644 --- a/app/Livewire/Server/Proxy/DynamicConfigurationNavbar.php +++ b/app/Livewire/Server/Proxy/DynamicConfigurationNavbar.php @@ -3,12 +3,17 @@ namespace App\Livewire\Server\Proxy; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class DynamicConfigurationNavbar extends Component { + use AuthorizesRequests; + public $server_id; + public Server $server; + public $fileName = ''; public $value = ''; @@ -17,18 +22,18 @@ class DynamicConfigurationNavbar extends Component public function delete(string $fileName) { - $server = Server::ownedByCurrentTeam()->whereId($this->server_id)->first(); - $proxy_path = $server->proxyPath(); - $proxy_type = $server->proxyType(); + $this->authorize('update', $this->server); + $proxy_path = $this->server->proxyPath(); + $proxy_type = $this->server->proxyType(); $file = str_replace('|', '.', $fileName); if ($proxy_type === 'CADDY' && $file === 'Caddyfile') { $this->dispatch('error', 'Cannot delete Caddyfile.'); return; } - instant_remote_process(["rm -f {$proxy_path}/dynamic/{$file}"], $server); + instant_remote_process(["rm -f {$proxy_path}/dynamic/{$file}"], $this->server); if ($proxy_type === 'CADDY') { - $server->reloadCaddy(); + $this->server->reloadCaddy(); } $this->dispatch('success', 'File deleted.'); $this->dispatch('loadDynamicConfigurations'); diff --git a/app/Livewire/Server/Proxy/NewDynamicConfiguration.php b/app/Livewire/Server/Proxy/NewDynamicConfiguration.php index 2155f1e82..eb2db1cbb 100644 --- a/app/Livewire/Server/Proxy/NewDynamicConfiguration.php +++ b/app/Livewire/Server/Proxy/NewDynamicConfiguration.php @@ -4,11 +4,14 @@ namespace App\Livewire\Server\Proxy; use App\Enums\ProxyTypes; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; use Symfony\Component\Yaml\Yaml; class NewDynamicConfiguration extends Component { + use AuthorizesRequests; + public string $fileName = ''; public string $value = ''; @@ -23,6 +26,7 @@ class NewDynamicConfiguration extends Component public function mount() { + $this->server = Server::ownedByCurrentTeam()->whereId($this->server_id)->first(); $this->parameters = get_route_parameters(); if ($this->fileName !== '') { $this->fileName = str_replace('|', '.', $this->fileName); @@ -32,6 +36,7 @@ class NewDynamicConfiguration extends Component public function addDynamicConfiguration() { try { + $this->authorize('update', $this->server); $this->validate([ 'fileName' => 'required', 'value' => 'required', @@ -39,9 +44,7 @@ class NewDynamicConfiguration extends Component if (data_get($this->parameters, 'server_uuid')) { $this->server = Server::ownedByCurrentTeam()->whereUuid(data_get($this->parameters, 'server_uuid'))->first(); } - if (! is_null($this->server_id)) { - $this->server = Server::ownedByCurrentTeam()->whereId($this->server_id)->first(); - } + if (is_null($this->server)) { return redirect()->route('server.index'); } diff --git a/app/Livewire/Server/Security/Patches.php b/app/Livewire/Server/Security/Patches.php index b7d17a61d..b4d151424 100644 --- a/app/Livewire/Server/Security/Patches.php +++ b/app/Livewire/Server/Security/Patches.php @@ -6,10 +6,14 @@ use App\Actions\Server\CheckUpdates; use App\Actions\Server\UpdatePackage; use App\Events\ServerPackageUpdated; use App\Models\Server; +use App\Notifications\Server\ServerPatchCheck; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Patches extends Component { + use AuthorizesRequests; + public array $parameters; public Server $server; @@ -35,11 +39,9 @@ class Patches extends Component public function mount() { - if (! auth()->user()->isAdmin()) { - abort(403); - } $this->parameters = get_route_parameters(); $this->server = Server::ownedByCurrentTeam()->whereUuid($this->parameters['server_uuid'])->firstOrFail(); + $this->authorize('viewSecurity', $this->server); } public function checkForUpdatesDispatch() @@ -67,8 +69,9 @@ class Patches extends Component public function updateAllPackages() { + $this->authorize('update', $this->server); if (! $this->packageManager || ! $this->osId) { - $this->dispatch('error', message: 'Run “Check for updates” first.'); + $this->dispatch('error', message: 'Run "Check for updates" first.'); return; } @@ -89,6 +92,7 @@ class Patches extends Component public function updatePackage($package) { try { + $this->authorize('update', $this->server); $activity = UpdatePackage::run(server: $this->server, packageManager: $this->packageManager, osId: $this->osId, package: $package); $this->dispatch('activityMonitor', $activity->id, ServerPackageUpdated::class); } catch (\Exception $e) { @@ -96,6 +100,89 @@ class Patches extends Component } } + public function sendTestEmail() + { + if (! isDev()) { + $this->dispatch('error', message: 'Test email functionality is only available in development mode.'); + + return; + } + + try { + // Get current patch data or create test data if none exists + $testPatchData = $this->createTestPatchData(); + + // Send test notification + $this->server->team->notify(new ServerPatchCheck($this->server, $testPatchData)); + + $this->dispatch('success', 'Test email sent successfully! Check your email inbox.'); + } catch (\Exception $e) { + $this->dispatch('error', message: 'Failed to send test email: '.$e->getMessage()); + } + } + + private function createTestPatchData(): array + { + // If we have real patch data, use it + if (isset($this->updates) && is_array($this->updates) && count($this->updates) > 0) { + return [ + 'total_updates' => $this->totalUpdates, + 'updates' => $this->updates, + 'osId' => $this->osId, + 'package_manager' => $this->packageManager, + ]; + } + + // Otherwise create realistic test data + return [ + 'total_updates' => 8, + 'updates' => [ + [ + 'package' => 'docker-ce', + 'current_version' => '24.0.7-1', + 'new_version' => '25.0.1-1', + ], + [ + 'package' => 'nginx', + 'current_version' => '1.20.2-1', + 'new_version' => '1.22.1-1', + ], + [ + 'package' => 'kernel-generic', + 'current_version' => '5.15.0-89', + 'new_version' => '5.15.0-91', + ], + [ + 'package' => 'openssh-server', + 'current_version' => '8.9p1-3', + 'new_version' => '9.0p1-1', + ], + [ + 'package' => 'curl', + 'current_version' => '7.81.0-1', + 'new_version' => '7.85.0-1', + ], + [ + 'package' => 'git', + 'current_version' => '2.34.1-1', + 'new_version' => '2.39.1-1', + ], + [ + 'package' => 'python3', + 'current_version' => '3.10.6-1', + 'new_version' => '3.11.0-1', + ], + [ + 'package' => 'htop', + 'current_version' => '3.2.1-1', + 'new_version' => '3.2.2-1', + ], + ], + 'osId' => $this->osId ?? 'ubuntu', + 'package_manager' => $this->packageManager ?? 'apt', + ]; + } + public function render() { return view('livewire.server.security.patches'); diff --git a/app/Livewire/Server/Show.php b/app/Livewire/Server/Show.php index d53f10d74..f4ae6dd7e 100644 --- a/app/Livewire/Server/Show.php +++ b/app/Livewire/Server/Show.php @@ -6,91 +6,128 @@ use App\Actions\Server\StartSentinel; use App\Actions\Server\StopSentinel; use App\Events\ServerReachabilityChanged; use App\Models\Server; +use App\Support\ValidationPatterns; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Attributes\Computed; use Livewire\Attributes\Locked; -use Livewire\Attributes\Validate; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + public Server $server; - #[Validate(['required'])] public string $name; - #[Validate(['nullable'])] public ?string $description = null; - #[Validate(['required'])] public string $ip; - #[Validate(['required'])] public string $user; - #[Validate(['required'])] public string $port; - #[Validate(['nullable'])] public ?string $validationLogs = null; - #[Validate(['nullable', 'url'])] public ?string $wildcardDomain = null; - #[Validate(['required'])] public bool $isReachable; - #[Validate(['required'])] public bool $isUsable; - #[Validate(['required'])] public bool $isSwarmManager; - #[Validate(['required'])] public bool $isSwarmWorker; - #[Validate(['required'])] public bool $isBuildServer; #[Locked] public bool $isBuildServerLocked = false; - #[Validate(['required'])] public bool $isMetricsEnabled; - #[Validate(['required'])] public string $sentinelToken; - #[Validate(['nullable'])] public ?string $sentinelUpdatedAt = null; - #[Validate(['required', 'integer', 'min:1'])] public int $sentinelMetricsRefreshRateSeconds; - #[Validate(['required', 'integer', 'min:1'])] public int $sentinelMetricsHistoryDays; - #[Validate(['required', 'integer', 'min:10'])] public int $sentinelPushIntervalSeconds; - #[Validate(['nullable', 'url'])] public ?string $sentinelCustomUrl = null; - #[Validate(['required'])] public bool $isSentinelEnabled; - #[Validate(['required'])] public bool $isSentinelDebugEnabled; - #[Validate(['required'])] public string $serverTimezone; public function getListeners() { + $teamId = $this->server->team_id ?? auth()->user()->currentTeam()->id; + return [ 'refreshServerShow' => 'refresh', + "echo-private:team.{$teamId},SentinelRestarted" => 'handleSentinelRestarted', ]; } + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + 'ip' => 'required', + 'user' => 'required', + 'port' => 'required', + 'validationLogs' => 'nullable', + 'wildcardDomain' => 'nullable|url', + 'isReachable' => 'required', + 'isUsable' => 'required', + 'isSwarmManager' => 'required', + 'isSwarmWorker' => 'required', + 'isBuildServer' => 'required', + 'isMetricsEnabled' => 'required', + 'sentinelToken' => 'required', + 'sentinelUpdatedAt' => 'nullable', + 'sentinelMetricsRefreshRateSeconds' => 'required|integer|min:1', + 'sentinelMetricsHistoryDays' => 'required|integer|min:1', + 'sentinelPushIntervalSeconds' => 'required|integer|min:10', + 'sentinelCustomUrl' => 'nullable|url', + 'isSentinelEnabled' => 'required', + 'isSentinelDebugEnabled' => 'required', + 'serverTimezone' => 'required', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'ip.required' => 'The IP Address field is required.', + 'user.required' => 'The User field is required.', + 'port.required' => 'The Port field is required.', + 'wildcardDomain.url' => 'The Wildcard Domain must be a valid URL.', + 'sentinelToken.required' => 'The Sentinel Token field is required.', + 'sentinelMetricsRefreshRateSeconds.required' => 'The Metrics Refresh Rate field is required.', + 'sentinelMetricsRefreshRateSeconds.integer' => 'The Metrics Refresh Rate must be an integer.', + 'sentinelMetricsRefreshRateSeconds.min' => 'The Metrics Refresh Rate must be at least 1 second.', + 'sentinelMetricsHistoryDays.required' => 'The Metrics History Days field is required.', + 'sentinelMetricsHistoryDays.integer' => 'The Metrics History Days must be an integer.', + 'sentinelMetricsHistoryDays.min' => 'The Metrics History Days must be at least 1 day.', + 'sentinelPushIntervalSeconds.required' => 'The Push Interval field is required.', + 'sentinelPushIntervalSeconds.integer' => 'The Push Interval must be an integer.', + 'sentinelPushIntervalSeconds.min' => 'The Push Interval must be at least 10 seconds.', + 'sentinelCustomUrl.url' => 'The Custom Sentinel URL must be a valid URL.', + 'serverTimezone.required' => 'The Server Timezone field is required.', + ] + ); + } + public function mount(string $server_uuid) { try { @@ -118,6 +155,7 @@ class Show extends Component if ($toModel) { $this->validate(); + $this->authorize('update', $this->server); if (Server::where('team_id', currentTeam()->id) ->where('ip', $this->ip) ->where('id', '!=', $this->server->id) @@ -186,9 +224,20 @@ class Show extends Component $this->syncData(); } + public function handleSentinelRestarted($event) + { + // Only refresh if the event is for this server + if (isset($event['serverUuid']) && $event['serverUuid'] === $this->server->uuid) { + $this->server->refresh(); + $this->syncData(); + $this->dispatch('success', 'Sentinel has been restarted successfully.'); + } + } + public function validateServer($install = true) { try { + $this->authorize('update', $this->server); $this->validationLogs = $this->server->validation_logs = null; $this->server->save(); $this->dispatch('init', $install); @@ -216,40 +265,59 @@ class Show extends Component public function restartSentinel() { - $this->server->restartSentinel(); - $this->dispatch('success', 'Sentinel restarted.'); + try { + $this->authorize('manageSentinel', $this->server); + $this->server->restartSentinel(); + $this->dispatch('success', 'Restarting Sentinel.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } public function updatedIsSentinelDebugEnabled($value) { - $this->submit(); - $this->restartSentinel(); + try { + $this->submit(); + $this->restartSentinel(); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function updatedIsMetricsEnabled($value) { - $this->submit(); - $this->restartSentinel(); + try { + $this->submit(); + $this->restartSentinel(); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function updatedIsSentinelEnabled($value) { - if ($value === true) { - StartSentinel::run($this->server, true); - } else { - $this->isMetricsEnabled = false; - $this->isSentinelDebugEnabled = false; - StopSentinel::dispatch($this->server); + try { + $this->authorize('manageSentinel', $this->server); + if ($value === true) { + StartSentinel::run($this->server, true); + } else { + $this->isMetricsEnabled = false; + $this->isSentinelDebugEnabled = false; + StopSentinel::dispatch($this->server); + } + $this->submit(); + } catch (\Throwable $e) { + return handleError($e, $this); } - $this->submit(); - } public function regenerateSentinelToken() { try { + $this->authorize('manageSentinel', $this->server); $this->server->settings->generateSentinelToken(); - $this->dispatch('success', 'Token regenerated & Sentinel restarted.'); + $this->dispatch('success', 'Token regenerated. Restarting Sentinel.'); } catch (\Throwable $e) { return handleError($e, $this); } @@ -257,7 +325,11 @@ class Show extends Component public function instantSave() { - $this->submit(); + try { + $this->submit(); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function submit() diff --git a/app/Livewire/Server/ValidateAndInstall.php b/app/Livewire/Server/ValidateAndInstall.php index 479fdef22..c75474e44 100644 --- a/app/Livewire/Server/ValidateAndInstall.php +++ b/app/Livewire/Server/ValidateAndInstall.php @@ -5,10 +5,13 @@ namespace App\Livewire\Server; use App\Actions\Proxy\CheckProxy; use App\Actions\Proxy\StartProxy; use App\Models\Server; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class ValidateAndInstall extends Component { + use AuthorizesRequests; + public Server $server; public int $number_of_tries = 0; @@ -62,6 +65,7 @@ class ValidateAndInstall extends Component public function validateConnection() { + $this->authorize('update', $this->server); ['uptime' => $this->uptime, 'error' => $error] = $this->server->validateConnection(); if (! $this->uptime) { $this->error = 'Server is not reachable. Please validate your configuration and connection.<br>Check this <a target="_blank" class="text-black underline dark:text-white" href="https://coolify.io/docs/knowledge-base/server/openssh">documentation</a> for further help. <br><br><div class="text-error">Error: '.$error.'</div>'; diff --git a/app/Livewire/Settings/Advanced.php b/app/Livewire/Settings/Advanced.php index 4425b414d..832123d5a 100644 --- a/app/Livewire/Settings/Advanced.php +++ b/app/Livewire/Settings/Advanced.php @@ -4,6 +4,7 @@ namespace App\Livewire\Settings; use App\Models\InstanceSettings; use App\Models\Server; +use App\Rules\ValidIpOrCidr; use Auth; use Hash; use Livewire\Attributes\Validate; @@ -31,7 +32,6 @@ class Advanced extends Component #[Validate('boolean')] public bool $is_api_enabled; - #[Validate('nullable|string')] public ?string $allowed_ips = null; #[Validate('boolean')] @@ -40,6 +40,21 @@ class Advanced extends Component #[Validate('boolean')] public bool $disable_two_step_confirmation; + public function rules() + { + return [ + 'server' => 'required', + 'is_registration_enabled' => 'boolean', + 'do_not_track' => 'boolean', + 'is_dns_validation_enabled' => 'boolean', + 'custom_dns_servers' => 'nullable|string', + 'is_api_enabled' => 'boolean', + 'allowed_ips' => ['nullable', 'string', new ValidIpOrCidr], + 'is_sponsorship_popup_enabled' => 'boolean', + 'disable_two_step_confirmation' => 'boolean', + ]; + } + public function mount() { if (! isInstanceAdmin()) { @@ -67,12 +82,76 @@ class Advanced extends Component return str($dns)->trim()->lower(); })->unique()->implode(','); + // Handle allowed IPs with subnet support and 0.0.0.0 special case $this->allowed_ips = str($this->allowed_ips)->replaceEnd(',', '')->trim(); - $this->allowed_ips = str($this->allowed_ips)->trim()->explode(',')->map(function ($ip) { - return str($ip)->trim(); - })->unique()->implode(','); + + // Check if user entered 0.0.0.0 or left field empty (both allow access from anywhere) + $allowsFromAnywhere = false; + if (empty($this->allowed_ips)) { + $allowsFromAnywhere = true; + } elseif ($this->allowed_ips === '0.0.0.0' || str_contains($this->allowed_ips, '0.0.0.0')) { + $allowsFromAnywhere = true; + } + + // Check if it's 0.0.0.0 (allow all) or empty + if ($this->allowed_ips === '0.0.0.0' || empty($this->allowed_ips)) { + // Keep as is - empty means no restriction, 0.0.0.0 means allow all + } else { + // Validate and clean up the entries + $invalidEntries = []; + $validEntries = str($this->allowed_ips)->trim()->explode(',')->map(function ($entry) use (&$invalidEntries) { + $entry = str($entry)->trim()->toString(); + + if (empty($entry)) { + return null; + } + + // Check if it's valid CIDR notation + if (str_contains($entry, '/')) { + [$ip, $mask] = explode('/', $entry); + if (filter_var($ip, FILTER_VALIDATE_IP) && is_numeric($mask) && $mask >= 0 && $mask <= 32) { + return $entry; + } + $invalidEntries[] = $entry; + + return null; + } + + // Check if it's a valid IP address + if (filter_var($entry, FILTER_VALIDATE_IP)) { + return $entry; + } + + $invalidEntries[] = $entry; + + return null; + })->filter()->unique(); + + if (! empty($invalidEntries)) { + $this->dispatch('error', 'Invalid IP addresses or subnets: '.implode(', ', $invalidEntries)); + + return; + } + + // Also check if we have no valid entries after filtering + if ($validEntries->isEmpty()) { + $this->dispatch('error', 'No valid IP addresses or subnets provided'); + + return; + } + + $this->allowed_ips = $validEntries->implode(','); + } $this->instantSave(); + + // Show security warning if allowing access from anywhere + if ($allowsFromAnywhere) { + $message = empty($this->allowed_ips) + ? 'Empty IP allowlist allows API access from anywhere.<br><br>This is not recommended for production environments!' + : 'Using 0.0.0.0 allows API access from anywhere.<br><br>This is not recommended for production environments!'; + $this->dispatch('warning', $message); + } } catch (\Exception $e) { return handleError($e, $this); } diff --git a/app/Livewire/SettingsDropdown.php b/app/Livewire/SettingsDropdown.php new file mode 100644 index 000000000..314957462 --- /dev/null +++ b/app/Livewire/SettingsDropdown.php @@ -0,0 +1,67 @@ +<?php + +namespace App\Livewire; + +use App\Jobs\PullChangelogFromGitHub; +use App\Services\ChangelogService; +use Illuminate\Support\Facades\Auth; +use Livewire\Component; + +class SettingsDropdown extends Component +{ + public $showWhatsNewModal = false; + + public function getUnreadCountProperty() + { + return Auth::user()->getUnreadChangelogCount(); + } + + public function getEntriesProperty() + { + $user = Auth::user(); + + return app(ChangelogService::class)->getEntriesForUser($user); + } + + public function openWhatsNewModal() + { + $this->showWhatsNewModal = true; + } + + public function closeWhatsNewModal() + { + $this->showWhatsNewModal = false; + } + + public function markAsRead($identifier) + { + app(ChangelogService::class)->markAsReadForUser($identifier, Auth::user()); + } + + public function markAllAsRead() + { + app(ChangelogService::class)->markAllAsReadForUser(Auth::user()); + } + + public function manualFetchChangelog() + { + if (! isDev()) { + return; + } + + try { + PullChangelogFromGitHub::dispatch(); + $this->dispatch('success', 'Changelog fetch initiated! Check back in a few moments.'); + } catch (\Throwable $e) { + $this->dispatch('error', 'Failed to fetch changelog: '.$e->getMessage()); + } + } + + public function render() + { + return view('livewire.settings-dropdown', [ + 'entries' => $this->entries, + 'unreadCount' => $this->unreadCount, + ]); + } +} diff --git a/app/Livewire/SharedVariables/Environment/Show.php b/app/Livewire/SharedVariables/Environment/Show.php index e88ac5f13..bee757a64 100644 --- a/app/Livewire/SharedVariables/Environment/Show.php +++ b/app/Livewire/SharedVariables/Environment/Show.php @@ -4,10 +4,13 @@ namespace App\Livewire\SharedVariables\Environment; use App\Models\Application; use App\Models\Project; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + public Project $project; public Application $application; @@ -21,6 +24,8 @@ class Show extends Component public function saveKey($data) { try { + $this->authorize('update', $this->environment); + $found = $this->environment->environment_variables()->where('key', $data['key'])->first(); if ($found) { throw new \Exception('Variable already exists.'); diff --git a/app/Livewire/SharedVariables/Project/Show.php b/app/Livewire/SharedVariables/Project/Show.php index 0171283c4..712a9960b 100644 --- a/app/Livewire/SharedVariables/Project/Show.php +++ b/app/Livewire/SharedVariables/Project/Show.php @@ -3,10 +3,13 @@ namespace App\Livewire\SharedVariables\Project; use App\Models\Project; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Show extends Component { + use AuthorizesRequests; + public Project $project; protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey' => 'saveKey', 'environmentVariableDeleted' => '$refresh']; @@ -14,6 +17,8 @@ class Show extends Component public function saveKey($data) { try { + $this->authorize('update', $this->project); + $found = $this->project->environment_variables()->where('key', $data['key'])->first(); if ($found) { throw new \Exception('Variable already exists.'); diff --git a/app/Livewire/SharedVariables/Team/Index.php b/app/Livewire/SharedVariables/Team/Index.php index a76ccf58a..82473528c 100644 --- a/app/Livewire/SharedVariables/Team/Index.php +++ b/app/Livewire/SharedVariables/Team/Index.php @@ -3,10 +3,13 @@ namespace App\Livewire\SharedVariables\Team; use App\Models\Team; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Index extends Component { + use AuthorizesRequests; + public Team $team; protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey' => 'saveKey', 'environmentVariableDeleted' => '$refresh']; @@ -14,6 +17,8 @@ class Index extends Component public function saveKey($data) { try { + $this->authorize('update', $this->team); + $found = $this->team->environment_variables()->where('key', $data['key'])->first(); if ($found) { throw new \Exception('Variable already exists.'); diff --git a/app/Livewire/Source/Github/Change.php b/app/Livewire/Source/Github/Change.php index e73c9dc73..9ad5444b9 100644 --- a/app/Livewire/Source/Github/Change.php +++ b/app/Livewire/Source/Github/Change.php @@ -5,6 +5,7 @@ namespace App\Livewire\Source\Github; use App\Jobs\GithubAppPermissionJob; use App\Models\GithubApp; use App\Models\PrivateKey; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Http; use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer\Key\InMemory; @@ -13,7 +14,9 @@ use Livewire\Component; class Change extends Component { - public string $webhook_endpoint; + use AuthorizesRequests; + + public string $webhook_endpoint = ''; public ?string $ipv4 = null; @@ -69,6 +72,8 @@ class Change extends Component public function checkPermissions() { try { + $this->authorize('view', $this->github_app); + GithubAppPermissionJob::dispatchSync($this->github_app); $this->github_app->refresh()->makeVisible('client_secret')->makeVisible('webhook_secret'); $this->dispatch('success', 'Github App permissions updated.'); @@ -155,7 +160,7 @@ class Change extends Component if (isCloud() && ! isDev()) { $this->webhook_endpoint = config('app.url'); } else { - $this->webhook_endpoint = $this->ipv4; + $this->webhook_endpoint = $this->ipv4 ?? ''; $this->is_system_wide = $this->github_app->is_system_wide; } } catch (\Throwable $e) { @@ -195,6 +200,8 @@ class Change extends Component public function updateGithubAppName() { try { + $this->authorize('update', $this->github_app); + $privateKey = PrivateKey::ownedByCurrentTeam()->find($this->github_app->private_key_id); if (! $privateKey) { @@ -237,6 +244,8 @@ class Change extends Component public function submit() { try { + $this->authorize('update', $this->github_app); + $this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret'); $this->validate([ 'github_app.name' => 'required|string', @@ -262,6 +271,8 @@ class Change extends Component public function createGithubAppManually() { + $this->authorize('update', $this->github_app); + $this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret'); $this->github_app->app_id = '1234567890'; $this->github_app->installation_id = '1234567890'; @@ -272,6 +283,8 @@ class Change extends Component public function instantSave() { try { + $this->authorize('update', $this->github_app); + $this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret'); $this->github_app->save(); $this->dispatch('success', 'Github App updated.'); @@ -283,6 +296,8 @@ class Change extends Component public function delete() { try { + $this->authorize('delete', $this->github_app); + if ($this->github_app->applications->isNotEmpty()) { $this->dispatch('error', 'This source is being used by an application. Please delete all applications first.'); $this->github_app->makeVisible('client_secret')->makeVisible('webhook_secret'); diff --git a/app/Livewire/Source/Github/Create.php b/app/Livewire/Source/Github/Create.php index 136d3525e..f5d851b64 100644 --- a/app/Livewire/Source/Github/Create.php +++ b/app/Livewire/Source/Github/Create.php @@ -3,10 +3,13 @@ namespace App\Livewire\Source\Github; use App\Models\GithubApp; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Create extends Component { + use AuthorizesRequests; + public string $name; public ?string $organization = null; @@ -29,6 +32,8 @@ class Create extends Component public function createGitHubApp() { try { + $this->authorize('createAnyResource'); + $this->validate([ 'name' => 'required|string', 'organization' => 'nullable|string', diff --git a/app/Livewire/Source/Gitlab/Change.php b/app/Livewire/Source/Gitlab/Change.php deleted file mode 100644 index 34600bb7d..000000000 --- a/app/Livewire/Source/Gitlab/Change.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php - -namespace App\Livewire\Source\Gitlab; - -use Livewire\Component; - -class Change extends Component -{ - public function render() - { - return view('livewire.source.gitlab.change'); - } -} diff --git a/app/Livewire/Storage/Create.php b/app/Livewire/Storage/Create.php index 1d60d6ac5..9efeb948c 100644 --- a/app/Livewire/Storage/Create.php +++ b/app/Livewire/Storage/Create.php @@ -3,11 +3,15 @@ namespace App\Livewire\Storage; use App\Models\S3Storage; +use App\Support\ValidationPatterns; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Uri; use Livewire\Component; class Create extends Component { + use AuthorizesRequests; + public string $name; public string $description; @@ -24,15 +28,38 @@ class Create extends Component public S3Storage $storage; - protected $rules = [ - 'name' => 'required|min:3|max:255', - 'description' => 'nullable|min:3|max:255', - 'region' => 'required|max:255', - 'key' => 'required|max:255', - 'secret' => 'required|max:255', - 'bucket' => 'required|max:255', - 'endpoint' => 'required|url|max:255', - ]; + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + 'region' => 'required|max:255', + 'key' => 'required|max:255', + 'secret' => 'required|max:255', + 'bucket' => 'required|max:255', + 'endpoint' => 'required|url|max:255', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'region.required' => 'The Region field is required.', + 'region.max' => 'The Region may not be greater than 255 characters.', + 'key.required' => 'The Access Key field is required.', + 'key.max' => 'The Access Key may not be greater than 255 characters.', + 'secret.required' => 'The Secret Key field is required.', + 'secret.max' => 'The Secret Key may not be greater than 255 characters.', + 'bucket.required' => 'The Bucket field is required.', + 'bucket.max' => 'The Bucket may not be greater than 255 characters.', + 'endpoint.required' => 'The Endpoint field is required.', + 'endpoint.url' => 'The Endpoint must be a valid URL.', + 'endpoint.max' => 'The Endpoint may not be greater than 255 characters.', + ] + ); + } protected $validationAttributes = [ 'name' => 'Name', @@ -70,6 +97,8 @@ class Create extends Component public function submit() { try { + $this->authorize('create', S3Storage::class); + $this->validate(); $this->storage = new S3Storage; $this->storage->name = $this->name; diff --git a/app/Livewire/Storage/Form.php b/app/Livewire/Storage/Form.php index ad1627863..41541f6b9 100644 --- a/app/Livewire/Storage/Form.php +++ b/app/Livewire/Storage/Form.php @@ -3,22 +3,51 @@ namespace App\Livewire\Storage; use App\Models\S3Storage; +use App\Support\ValidationPatterns; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Form extends Component { + use AuthorizesRequests; + public S3Storage $storage; - protected $rules = [ - 'storage.is_usable' => 'nullable|boolean', - 'storage.name' => 'nullable|min:3|max:255', - 'storage.description' => 'nullable|min:3|max:255', - 'storage.region' => 'required|max:255', - 'storage.key' => 'required|max:255', - 'storage.secret' => 'required|max:255', - 'storage.bucket' => 'required|max:255', - 'storage.endpoint' => 'required|url|max:255', - ]; + protected function rules(): array + { + return [ + 'storage.is_usable' => 'nullable|boolean', + 'storage.name' => ValidationPatterns::nameRules(required: false), + 'storage.description' => ValidationPatterns::descriptionRules(), + 'storage.region' => 'required|max:255', + 'storage.key' => 'required|max:255', + 'storage.secret' => 'required|max:255', + 'storage.bucket' => 'required|max:255', + 'storage.endpoint' => 'required|url|max:255', + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'storage.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'storage.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'storage.region.required' => 'The Region field is required.', + 'storage.region.max' => 'The Region may not be greater than 255 characters.', + 'storage.key.required' => 'The Access Key field is required.', + 'storage.key.max' => 'The Access Key may not be greater than 255 characters.', + 'storage.secret.required' => 'The Secret Key field is required.', + 'storage.secret.max' => 'The Secret Key may not be greater than 255 characters.', + 'storage.bucket.required' => 'The Bucket field is required.', + 'storage.bucket.max' => 'The Bucket may not be greater than 255 characters.', + 'storage.endpoint.required' => 'The Endpoint field is required.', + 'storage.endpoint.url' => 'The Endpoint must be a valid URL.', + 'storage.endpoint.max' => 'The Endpoint may not be greater than 255 characters.', + ] + ); + } protected $validationAttributes = [ 'storage.is_usable' => 'Is Usable', @@ -34,6 +63,8 @@ class Form extends Component public function testConnection() { try { + $this->authorize('validateConnection', $this->storage); + $this->storage->testConnection(shouldSave: true); return $this->dispatch('success', 'Connection is working.', 'Tested with "ListObjectsV2" action.'); @@ -57,8 +88,10 @@ class Form extends Component public function submit() { - $this->validate(); try { + $this->authorize('update', $this->storage); + + $this->validate(); $this->testConnection(); } catch (\Throwable $e) { return handleError($e, $this); diff --git a/app/Livewire/Subscription/Index.php b/app/Livewire/Subscription/Index.php index 8a9cc456f..ac37cca05 100644 --- a/app/Livewire/Subscription/Index.php +++ b/app/Livewire/Subscription/Index.php @@ -75,7 +75,7 @@ class Index extends Component } } catch (\Exception $e) { // Log the error - logger()->error('Stripe API error: ' . $e->getMessage()); + logger()->error('Stripe API error: '.$e->getMessage()); // Set a flag to show an error message to the user $this->addError('stripe', 'Could not retrieve subscription information. Please try again later.'); } finally { diff --git a/app/Livewire/Team/Create.php b/app/Livewire/Team/Create.php index f805d6122..d3d27556c 100644 --- a/app/Livewire/Team/Create.php +++ b/app/Livewire/Team/Create.php @@ -3,17 +3,28 @@ namespace App\Livewire\Team; use App\Models\Team; -use Livewire\Attributes\Validate; +use App\Support\ValidationPatterns; use Livewire\Component; class Create extends Component { - #[Validate(['required', 'min:3', 'max:255'])] public string $name = ''; - #[Validate(['nullable', 'min:3', 'max:255'])] public ?string $description = null; + protected function rules(): array + { + return [ + 'name' => ValidationPatterns::nameRules(), + 'description' => ValidationPatterns::descriptionRules(), + ]; + } + + protected function messages(): array + { + return ValidationPatterns::combinedMessages(); + } + public function submit() { try { diff --git a/app/Livewire/Team/Index.php b/app/Livewire/Team/Index.php index 0972e7364..8b9b70e14 100644 --- a/app/Livewire/Team/Index.php +++ b/app/Livewire/Team/Index.php @@ -4,20 +4,39 @@ namespace App\Livewire\Team; use App\Models\Team; use App\Models\TeamInvitation; +use App\Support\ValidationPatterns; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; use Livewire\Component; class Index extends Component { + use AuthorizesRequests; + public $invitations = []; public Team $team; - protected $rules = [ - 'team.name' => 'required|min:3|max:255', - 'team.description' => 'nullable|min:3|max:255', - ]; + protected function rules(): array + { + return [ + 'team.name' => ValidationPatterns::nameRules(), + 'team.description' => ValidationPatterns::descriptionRules(), + ]; + } + + protected function messages(): array + { + return array_merge( + ValidationPatterns::combinedMessages(), + [ + 'team.name.required' => 'The Name field is required.', + 'team.name.regex' => 'The Name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'team.description.regex' => 'The Description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + ] + ); + } protected $validationAttributes = [ 'team.name' => 'name', @@ -42,6 +61,7 @@ class Index extends Component { $this->validate(); try { + $this->authorize('update', $this->team); $this->team->save(); refreshSession(); $this->dispatch('success', 'Team updated.'); @@ -53,6 +73,7 @@ class Index extends Component public function delete() { $currentTeam = currentTeam(); + $this->authorize('delete', $currentTeam); $currentTeam->delete(); $currentTeam->members->each(function ($user) use ($currentTeam) { diff --git a/app/Livewire/Team/Invitations.php b/app/Livewire/Team/Invitations.php index 3af0e0e92..523f640b9 100644 --- a/app/Livewire/Team/Invitations.php +++ b/app/Livewire/Team/Invitations.php @@ -4,10 +4,13 @@ namespace App\Livewire\Team; use App\Models\TeamInvitation; use App\Models\User; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Invitations extends Component { + use AuthorizesRequests; + public $invitations; protected $listeners = ['refreshInvitations']; @@ -15,6 +18,8 @@ class Invitations extends Component public function deleteInvitation(int $invitation_id) { try { + $this->authorize('manageInvitations', currentTeam()); + $invitation = TeamInvitation::ownedByCurrentTeam()->findOrFail($invitation_id); $user = User::whereEmail($invitation->email)->first(); if (filled($user)) { diff --git a/app/Livewire/Team/InviteLink.php b/app/Livewire/Team/InviteLink.php index fb0c51e54..0bac39db8 100644 --- a/app/Livewire/Team/InviteLink.php +++ b/app/Livewire/Team/InviteLink.php @@ -4,6 +4,7 @@ namespace App\Livewire\Team; use App\Models\TeamInvitation; use App\Models\User; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Hash; @@ -13,6 +14,8 @@ use Visus\Cuid2\Cuid2; class InviteLink extends Component { + use AuthorizesRequests; + public string $email; public string $role = 'member'; @@ -40,6 +43,7 @@ class InviteLink extends Component private function generateInviteLink(bool $sendEmail = false) { try { + $this->authorize('manageInvitations', currentTeam()); $this->validate(); if (auth()->user()->role() === 'admin' && $this->role === 'owner') { throw new \Exception('Admins cannot invite owners.'); diff --git a/app/Livewire/Team/Member.php b/app/Livewire/Team/Member.php index 890d640a0..96c98c637 100644 --- a/app/Livewire/Team/Member.php +++ b/app/Livewire/Team/Member.php @@ -4,16 +4,21 @@ namespace App\Livewire\Team; use App\Enums\Role; use App\Models\User; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\Cache; use Livewire\Component; class Member extends Component { + use AuthorizesRequests; + public User $member; public function makeAdmin() { try { + $this->authorize('manageMembers', currentTeam()); + if (Role::from(auth()->user()->role())->lt(Role::ADMIN) || Role::from($this->getMemberRole())->gt(auth()->user()->role())) { throw new \Exception('You are not authorized to perform this action.'); @@ -28,6 +33,8 @@ class Member extends Component public function makeOwner() { try { + $this->authorize('manageMembers', currentTeam()); + if (Role::from(auth()->user()->role())->lt(Role::OWNER) || Role::from($this->getMemberRole())->gt(auth()->user()->role())) { throw new \Exception('You are not authorized to perform this action.'); @@ -42,6 +49,8 @@ class Member extends Component public function makeReadonly() { try { + $this->authorize('manageMembers', currentTeam()); + if (Role::from(auth()->user()->role())->lt(Role::ADMIN) || Role::from($this->getMemberRole())->gt(auth()->user()->role())) { throw new \Exception('You are not authorized to perform this action.'); @@ -56,6 +65,8 @@ class Member extends Component public function remove() { try { + $this->authorize('manageMembers', currentTeam()); + if (Role::from(auth()->user()->role())->lt(Role::ADMIN) || Role::from($this->getMemberRole())->gt(auth()->user()->role())) { throw new \Exception('You are not authorized to perform this action.'); diff --git a/app/Livewire/Team/Member/Index.php b/app/Livewire/Team/Member/Index.php index 00b745fe4..e057ba3f6 100644 --- a/app/Livewire/Team/Member/Index.php +++ b/app/Livewire/Team/Member/Index.php @@ -3,15 +3,19 @@ namespace App\Livewire\Team\Member; use App\Models\TeamInvitation; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Livewire\Component; class Index extends Component { + use AuthorizesRequests; + public $invitations = []; public function mount() { - if (auth()->user()->isAdminFromSession()) { + // Only load invitations for users who can manage them + if (auth()->user()->can('manageInvitations', currentTeam())) { $this->invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get(); } } diff --git a/app/Livewire/Terminal/Index.php b/app/Livewire/Terminal/Index.php index 10084a991..03dbc1d91 100644 --- a/app/Livewire/Terminal/Index.php +++ b/app/Livewire/Terminal/Index.php @@ -18,9 +18,6 @@ class Index extends Component public function mount() { - if (! auth()->user()->isAdmin()) { - abort(403); - } $this->servers = Server::isReachable()->get()->filter(function ($server) { return $server->isTerminalEnabled(); }); @@ -59,7 +56,7 @@ class Index extends Component return null; })->filter(); - }); + })->sortBy('name'); } public function updatedSelectedUuid() diff --git a/app/Models/Application.php b/app/Models/Application.php index f3f063d19..f8f86d1f9 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -5,6 +5,7 @@ namespace App\Models; use App\Enums\ApplicationDeploymentStatus; use App\Services\ConfigurationGenerator; use App\Traits\HasConfiguration; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -109,9 +110,9 @@ use Visus\Cuid2\Cuid2; class Application extends BaseModel { - use HasConfiguration, HasFactory, SoftDeletes; + use HasConfiguration, HasFactory, HasSafeStringAttribute, SoftDeletes; - private static $parserVersion = '4'; + private static $parserVersion = '5'; protected $guarded = []; @@ -798,7 +799,7 @@ class Application extends BaseModel public function previews() { - return $this->hasMany(ApplicationPreview::class); + return $this->hasMany(ApplicationPreview::class)->orderBy('pull_request_id', 'desc'); } public function deployment_queue() @@ -836,9 +837,14 @@ class Application extends BaseModel return ApplicationDeploymentQueue::where('application_id', $this->id)->where('created_at', '>=', now()->subDays(7))->orderBy('created_at', 'desc')->get(); } - public function deployments(int $skip = 0, int $take = 10) + public function deployments(int $skip = 0, int $take = 10, ?string $pullRequestId = null) { $deployments = ApplicationDeploymentQueue::where('application_id', $this->id)->orderBy('created_at', 'desc'); + + if ($pullRequestId) { + $deployments = $deployments->where('pull_request_id', $pullRequestId); + } + $count = $deployments->count(); $deployments = $deployments->skip($skip)->take($take)->get(); @@ -974,15 +980,26 @@ class Application extends BaseModel public function setGitImportSettings(string $deployment_uuid, string $git_clone_command, bool $public = false) { $baseDir = $this->generateBaseDir($deployment_uuid); + $isShallowCloneEnabled = $this->settings?->is_git_shallow_clone_enabled ?? false; if ($this->git_commit_sha !== 'HEAD') { - $git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git -c advice.detachedHead=false checkout {$this->git_commit_sha} >/dev/null 2>&1"; + // If shallow clone is enabled and we need a specific commit, + // we need to fetch that specific commit with depth=1 + if ($isShallowCloneEnabled) { + $git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git fetch --depth=1 origin {$this->git_commit_sha} && git -c advice.detachedHead=false checkout {$this->git_commit_sha} >/dev/null 2>&1"; + } else { + $git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git -c advice.detachedHead=false checkout {$this->git_commit_sha} >/dev/null 2>&1"; + } } if ($this->settings->is_git_submodules_enabled) { + // Check if .gitmodules file exists before running submodule commands + $git_clone_command = "{$git_clone_command} && cd {$baseDir} && if [ -f .gitmodules ]; then"; if ($public) { - $git_clone_command = "{$git_clone_command} && cd {$baseDir} && sed -i \"s#git@\(.*\):#https://\\1/#g\" {$baseDir}/.gitmodules || true"; + $git_clone_command = "{$git_clone_command} sed -i \"s#git@\(.*\):#https://\\1/#g\" {$baseDir}/.gitmodules || true &&"; } - $git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git submodule update --init --recursive"; + // Add shallow submodules flag if shallow clone is enabled + $submoduleFlags = $isShallowCloneEnabled ? '--shallow-submodules' : ''; + $git_clone_command = "{$git_clone_command} GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git submodule update --init --recursive {$submoduleFlags}; fi"; } if ($this->settings->is_git_lfs_enabled) { $git_clone_command = "{$git_clone_command} && cd {$baseDir} && GIT_SSH_COMMAND=\"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git lfs pull"; @@ -1111,10 +1128,20 @@ class Application extends BaseModel $branch = $this->git_branch; ['repository' => $customRepository, 'port' => $customPort] = $this->customRepository(); $baseDir = $custom_base_dir ?? $this->generateBaseDir($deployment_uuid); + + // Escape shell arguments for safety to prevent command injection + $escapedBranch = escapeshellarg($branch); + $escapedBaseDir = escapeshellarg($baseDir); + $commands = collect([]); - $git_clone_command = "git clone -b \"{$this->git_branch}\""; + + // Check if shallow clone is enabled + $isShallowCloneEnabled = $this->settings?->is_git_shallow_clone_enabled ?? false; + $depthFlag = $isShallowCloneEnabled ? ' --depth=1' : ''; + + $git_clone_command = "git clone{$depthFlag} -b {$escapedBranch}"; if ($only_checkout) { - $git_clone_command = "git clone --no-checkout -b \"{$this->git_branch}\""; + $git_clone_command = "git clone{$depthFlag} --no-checkout -b {$escapedBranch}"; } if ($pull_request_id !== 0) { $pr_branch_name = "pr-{$pull_request_id}-coolify"; @@ -1128,7 +1155,8 @@ class Application extends BaseModel if ($this->source->getMorphClass() === \App\Models\GithubApp::class) { if ($this->source->is_public) { $fullRepoUrl = "{$this->source->html_url}/{$customRepository}"; - $git_clone_command = "{$git_clone_command} {$this->source->html_url}/{$customRepository} {$baseDir}"; + $escapedRepoUrl = escapeshellarg("{$this->source->html_url}/{$customRepository}"); + $git_clone_command = "{$git_clone_command} {$escapedRepoUrl} {$escapedBaseDir}"; if (! $only_checkout) { $git_clone_command = $this->setGitImportSettings($deployment_uuid, $git_clone_command, public: true); } @@ -1140,11 +1168,15 @@ class Application extends BaseModel } else { $github_access_token = generateGithubInstallationToken($this->source); if ($exec_in_docker) { - $git_clone_command = "{$git_clone_command} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}.git {$baseDir}"; - $fullRepoUrl = "$source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}.git"; + $repoUrl = "$source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}.git"; + $escapedRepoUrl = escapeshellarg($repoUrl); + $git_clone_command = "{$git_clone_command} {$escapedRepoUrl} {$escapedBaseDir}"; + $fullRepoUrl = $repoUrl; } else { - $git_clone_command = "{$git_clone_command} $source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository} {$baseDir}"; - $fullRepoUrl = "$source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}"; + $repoUrl = "$source_html_url_scheme://x-access-token:$github_access_token@$source_html_url_host/{$customRepository}"; + $escapedRepoUrl = escapeshellarg($repoUrl); + $git_clone_command = "{$git_clone_command} {$escapedRepoUrl} {$escapedBaseDir}"; + $fullRepoUrl = $repoUrl; } if (! $only_checkout) { $git_clone_command = $this->setGitImportSettings($deployment_uuid, $git_clone_command, public: false); @@ -1159,10 +1191,11 @@ class Application extends BaseModel $branch = "pull/{$pull_request_id}/head:$pr_branch_name"; $git_checkout_command = $this->buildGitCheckoutCommand($pr_branch_name); + $escapedPrBranch = escapeshellarg($branch); if ($exec_in_docker) { - $commands->push(executeInDocker($deployment_uuid, "cd {$baseDir} && git fetch origin {$branch} && $git_checkout_command")); + $commands->push(executeInDocker($deployment_uuid, "cd {$escapedBaseDir} && git fetch origin {$escapedPrBranch} && $git_checkout_command")); } else { - $commands->push("cd {$baseDir} && git fetch origin {$branch} && $git_checkout_command"); + $commands->push("cd {$escapedBaseDir} && git fetch origin {$escapedPrBranch} && $git_checkout_command"); } } @@ -1180,7 +1213,8 @@ class Application extends BaseModel throw new RuntimeException('Private key not found. Please add a private key to the application and try again.'); } $private_key = base64_encode($private_key); - $git_clone_command_base = "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$customRepository} {$baseDir}"; + $escapedCustomRepository = escapeshellarg($customRepository); + $git_clone_command_base = "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$customPort} -o Port={$customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" {$git_clone_command} {$escapedCustomRepository} {$escapedBaseDir}"; if ($only_checkout) { $git_clone_command = $git_clone_command_base; } else { @@ -1348,7 +1382,7 @@ class Application extends BaseModel public function parse(int $pull_request_id = 0, ?int $preview_id = null) { if ((int) $this->compose_parsing_version >= 3) { - return newParser($this, $pull_request_id, $preview_id); + return applicationParser($this, $pull_request_id, $preview_id); } elseif ($this->docker_compose_raw) { return parseDockerComposeFile(resource: $this, isNew: false, pull_request_id: $pull_request_id, preview_id: $preview_id); } else { @@ -1437,7 +1471,21 @@ class Application extends BaseModel $parsedServices = $this->parse(); if ($this->docker_compose_domains) { $json = collect(json_decode($this->docker_compose_domains)); - $names = collect(data_get($parsedServices, 'services'))->keys()->toArray(); + foreach ($json as $key => $value) { + if (str($key)->contains('-')) { + $key = str($key)->replace('-', '_'); + } + $json->put((string) $key, $value); + } + $services = collect(data_get($parsedServices, 'services', [])); + foreach ($services as $name => $service) { + if (str($name)->contains('-')) { + $replacedName = str($name)->replace('-', '_'); + $services->put((string) $replacedName, $service); + $services->forget((string) $name); + } + } + $names = collect($services)->keys()->toArray(); $jsonNames = $json->keys()->toArray(); $diff = array_diff($jsonNames, $names); $json = $json->filter(function ($value, $key) use ($diff) { @@ -1578,34 +1626,6 @@ class Application extends BaseModel } } - public function generate_preview_fqdn(int $pull_request_id) - { - $preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->id, $pull_request_id); - if (is_null(data_get($preview, 'fqdn')) && $this->fqdn) { - if (str($this->fqdn)->contains(',')) { - $url = Url::fromString(str($this->fqdn)->explode(',')[0]); - $preview_fqdn = getFqdnWithoutPort(str($this->fqdn)->explode(',')[0]); - } else { - $url = Url::fromString($this->fqdn); - if (data_get($preview, 'fqdn')) { - $preview_fqdn = getFqdnWithoutPort(data_get($preview, 'fqdn')); - } - } - $template = $this->preview_url_template; - $host = $url->getHost(); - $schema = $url->getScheme(); - $random = new Cuid2; - $preview_fqdn = str_replace('{{random}}', $random, $template); - $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn); - $preview_fqdn = str_replace('{{pr_id}}', $pull_request_id, $preview_fqdn); - $preview_fqdn = "$schema://$preview_fqdn"; - $preview->fqdn = $preview_fqdn; - $preview->save(); - } - - return $preview; - } - public static function getDomainsByUuid(string $uuid): array { $application = self::where('uuid', $uuid)->first(); diff --git a/app/Models/ApplicationPreview.php b/app/Models/ApplicationPreview.php index c635f146a..aa31268f1 100644 --- a/app/Models/ApplicationPreview.php +++ b/app/Models/ApplicationPreview.php @@ -2,19 +2,25 @@ namespace App\Models; +use Illuminate\Database\Eloquent\SoftDeletes; use Spatie\Url\Url; use Visus\Cuid2\Cuid2; class ApplicationPreview extends BaseModel { + use SoftDeletes; + protected $guarded = []; protected static function booted() { - static::deleting(function ($preview) { + static::forceDeleting(function ($preview) { + $server = $preview->application->destination->server; + $application = $preview->application; + if (data_get($preview, 'application.build_pack') === 'dockercompose') { - $server = $preview->application->destination->server; - $composeFile = $preview->application->parse(pull_request_id: $preview->pull_request_id); + // Docker Compose volume and network cleanup + $composeFile = $application->parse(pull_request_id: $preview->pull_request_id); $volumes = data_get($composeFile, 'volumes'); $networks = data_get($composeFile, 'networks'); $networkKeys = collect($networks)->keys(); @@ -26,7 +32,18 @@ class ApplicationPreview extends BaseModel instant_remote_process(["docker network disconnect $key coolify-proxy"], $server, false); instant_remote_process(["docker network rm $key"], $server, false); }); + } else { + // Regular application volume cleanup + $persistentStorages = $preview->persistentStorages()->get() ?? collect(); + if ($persistentStorages->count() > 0) { + foreach ($persistentStorages as $storage) { + instant_remote_process(["docker volume rm -f $storage->name"], $server, false); + } + } } + + // Clean up persistent storage records + $preview->persistentStorages()->delete(); }); static::saving(function ($preview) { if ($preview->isDirty('status')) { @@ -50,14 +67,72 @@ class ApplicationPreview extends BaseModel return $this->belongsTo(Application::class); } + public function persistentStorages() + { + return $this->morphMany(\App\Models\LocalPersistentVolume::class, 'resource'); + } + + public function generate_preview_fqdn() + { + if (empty($this->fqdn) && $this->application->fqdn) { + if (str($this->application->fqdn)->contains(',')) { + $url = Url::fromString(str($this->application->fqdn)->explode(',')[0]); + $preview_fqdn = getFqdnWithoutPort(str($this->application->fqdn)->explode(',')[0]); + } else { + $url = Url::fromString($this->application->fqdn); + if ($this->fqdn) { + $preview_fqdn = getFqdnWithoutPort($this->fqdn); + } + } + $template = $this->application->preview_url_template; + $host = $url->getHost(); + $schema = $url->getScheme(); + $random = new Cuid2; + $preview_fqdn = str_replace('{{random}}', $random, $template); + $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn); + $preview_fqdn = str_replace('{{pr_id}}', $this->pull_request_id, $preview_fqdn); + $preview_fqdn = "$schema://$preview_fqdn"; + $this->fqdn = $preview_fqdn; + $this->save(); + } + + return $this; + } + public function generate_preview_fqdn_compose() { $services = collect(json_decode($this->application->docker_compose_domains)) ?? collect(); $docker_compose_domains = data_get($this, 'docker_compose_domains'); $docker_compose_domains = json_decode($docker_compose_domains, true) ?? []; + // Get all services from the parsed compose file to ensure all services have entries + $parsedServices = $this->application->parse(pull_request_id: $this->pull_request_id); + if (isset($parsedServices['services'])) { + foreach ($parsedServices['services'] as $serviceName => $service) { + if (! isDatabaseImage(data_get($service, 'image'))) { + // Remove PR suffix from service name to get original service name + $originalServiceName = str($serviceName)->replaceLast('-pr-'.$this->pull_request_id, '')->toString(); + + // Ensure all services have an entry, even if empty + if (! $services->has($originalServiceName)) { + $services->put($originalServiceName, ['domain' => '']); + } + } + } + } + foreach ($services as $service_name => $service_config) { $domain_string = data_get($service_config, 'domain'); + + // If domain string is empty or null, don't auto-generate domain + // Only generate domains when main app already has domains set + if (empty($domain_string)) { + // Ensure service has an empty domain entry for form binding + $docker_compose_domains[$service_name]['domain'] = ''; + + continue; + } + $service_domains = str($domain_string)->explode(',')->map(fn ($d) => trim($d)); $preview_domains = []; @@ -80,6 +155,9 @@ class ApplicationPreview extends BaseModel if (! empty($preview_domains)) { $docker_compose_domains[$service_name]['domain'] = implode(',', $preview_domains); + } else { + // Ensure service has an empty domain entry for form binding + $docker_compose_domains[$service_name]['domain'] = ''; } } diff --git a/app/Models/ApplicationSetting.php b/app/Models/ApplicationSetting.php index c7624fdaa..d05081d21 100644 --- a/app/Models/ApplicationSetting.php +++ b/app/Models/ApplicationSetting.php @@ -15,6 +15,7 @@ class ApplicationSetting extends Model 'is_preview_deployments_enabled' => 'boolean', 'is_git_submodules_enabled' => 'boolean', 'is_git_lfs_enabled' => 'boolean', + 'is_git_shallow_clone_enabled' => 'boolean', ]; protected $guarded = []; diff --git a/app/Models/Environment.php b/app/Models/Environment.php index b8f1090d8..437be7d87 100644 --- a/app/Models/Environment.php +++ b/app/Models/Environment.php @@ -2,7 +2,7 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Casts\Attribute; +use App\Traits\HasSafeStringAttribute; use OpenApi\Attributes as OA; #[OA\Schema( @@ -19,6 +19,8 @@ use OpenApi\Attributes as OA; )] class Environment extends BaseModel { + use HasSafeStringAttribute; + protected $guarded = []; protected static function booted() @@ -119,10 +121,8 @@ class Environment extends BaseModel return $this->hasMany(Service::class); } - protected function name(): Attribute + protected function customizeName($value) { - return Attribute::make( - set: fn (string $value) => str($value)->lower()->trim()->replace('/', '-')->toString(), - ); + return str($value)->lower()->trim()->replace('/', '-')->toString(); } } diff --git a/app/Models/LocalPersistentVolume.php b/app/Models/LocalPersistentVolume.php index b5dfd9663..00dc15fea 100644 --- a/app/Models/LocalPersistentVolume.php +++ b/app/Models/LocalPersistentVolume.php @@ -24,11 +24,9 @@ class LocalPersistentVolume extends Model return $this->morphTo('resource'); } - protected function name(): Attribute + protected function customizeName($value) { - return Attribute::make( - set: fn (string $value) => str($value)->trim()->value, - ); + return str($value)->trim()->value; } protected function mountPath(): Attribute diff --git a/app/Models/PrivateKey.php b/app/Models/PrivateKey.php index dbed7b439..f70f32bc4 100644 --- a/app/Models/PrivateKey.php +++ b/app/Models/PrivateKey.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use DanHarrin\LivewireRateLimiting\WithRateLimiting; use Illuminate\Support\Facades\Storage; use Illuminate\Validation\ValidationException; @@ -27,7 +28,7 @@ use phpseclib3\Crypt\PublicKeyLoader; )] class PrivateKey extends BaseModel { - use WithRateLimiting; + use HasSafeStringAttribute, WithRateLimiting; protected $fillable = [ 'name', diff --git a/app/Models/Project.php b/app/Models/Project.php index 2e4d45859..1c46042e3 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use OpenApi\Attributes as OA; use Visus\Cuid2\Cuid2; @@ -23,6 +24,8 @@ use Visus\Cuid2\Cuid2; )] class Project extends BaseModel { + use HasSafeStringAttribute; + protected $guarded = []; public static function ownedByCurrentTeam() diff --git a/app/Models/S3Storage.php b/app/Models/S3Storage.php index e9d674650..de27bbca6 100644 --- a/app/Models/S3Storage.php +++ b/app/Models/S3Storage.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Support\Facades\Storage; class S3Storage extends BaseModel { - use HasFactory; + use HasFactory, HasSafeStringAttribute; protected $guarded = []; diff --git a/app/Models/ScheduledDatabaseBackup.php b/app/Models/ScheduledDatabaseBackup.php index 473fc7b4b..90204d8df 100644 --- a/app/Models/ScheduledDatabaseBackup.php +++ b/app/Models/ScheduledDatabaseBackup.php @@ -36,6 +36,18 @@ class ScheduledDatabaseBackup extends BaseModel return $this->hasMany(ScheduledDatabaseBackupExecution::class)->where('created_at', '>=', now()->subDays($days))->get(); } + public function executionsPaginated(int $skip = 0, int $take = 10) + { + $executions = $this->hasMany(ScheduledDatabaseBackupExecution::class)->orderBy('created_at', 'desc'); + $count = $executions->count(); + $executions = $executions->skip($skip)->take($take)->get(); + + return [ + 'count' => $count, + 'executions' => $executions, + ]; + } + public function server() { if ($this->database) { diff --git a/app/Models/ScheduledTask.php b/app/Models/ScheduledTask.php index 264a04d1f..06903ffb6 100644 --- a/app/Models/ScheduledTask.php +++ b/app/Models/ScheduledTask.php @@ -2,11 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\Relations\HasOne; class ScheduledTask extends BaseModel { + use HasSafeStringAttribute; + protected $guarded = []; public function service() diff --git a/app/Models/Server.php b/app/Models/Server.php index 41ecdafb8..0f92bd390 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -13,6 +13,7 @@ use App\Jobs\RegenerateSslCertJob; use App\Notifications\Server\Reachable; use App\Notifications\Server\Unreachable; use App\Services\ConfigurationRepository; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -164,6 +165,8 @@ class Server extends BaseModel protected $guarded = []; + use HasSafeStringAttribute; + public function type() { return 'server'; diff --git a/app/Models/Service.php b/app/Models/Service.php index da6c34fbb..43cb32d85 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Enums\ProcessStatus; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -40,9 +41,9 @@ use Visus\Cuid2\Cuid2; )] class Service extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; - private static $parserVersion = '4'; + private static $parserVersion = '5'; protected $guarded = []; @@ -255,6 +256,19 @@ class Service extends BaseModel continue; } switch ($image) { + case $image->contains('drizzle-team/gateway'): + $data = collect([]); + $masterpass = $this->environment_variables()->where('key', 'SERVICE_PASSWORD_DRIZZLE')->first(); + $data = $data->merge([ + 'Master Password' => [ + 'key' => data_get($masterpass, 'key'), + 'value' => data_get($masterpass, 'value'), + 'rules' => 'required', + 'isPassword' => true, + ], + ]); + $fields->put('Drizzle', $data->toArray()); + break; case $image->contains('castopod'): $data = collect([]); $disable_https = $this->environment_variables()->where('key', 'CP_DISABLE_HTTPS')->first(); @@ -1277,7 +1291,7 @@ class Service extends BaseModel public function parse(bool $isNew = false): Collection { if ((int) $this->compose_parsing_version >= 3) { - return newParser($this); + return serviceParser($this); } elseif ($this->docker_compose_raw) { return parseDockerComposeFile($this, $isNew); } else { diff --git a/app/Models/SharedEnvironmentVariable.php b/app/Models/SharedEnvironmentVariable.php index aab8b8735..7956f006a 100644 --- a/app/Models/SharedEnvironmentVariable.php +++ b/app/Models/SharedEnvironmentVariable.php @@ -12,4 +12,19 @@ class SharedEnvironmentVariable extends Model 'key' => 'string', 'value' => 'encrypted', ]; + + public function team() + { + return $this->belongsTo(Team::class); + } + + public function project() + { + return $this->belongsTo(Project::class); + } + + public function environment() + { + return $this->belongsTo(Environment::class); + } } diff --git a/app/Models/StandaloneClickhouse.php b/app/Models/StandaloneClickhouse.php index fcd81cdc9..60a750a99 100644 --- a/app/Models/StandaloneClickhouse.php +++ b/app/Models/StandaloneClickhouse.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; class StandaloneClickhouse extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; protected $guarded = []; diff --git a/app/Models/StandaloneDocker.php b/app/Models/StandaloneDocker.php index 9db6a2d29..aeb99d34a 100644 --- a/app/Models/StandaloneDocker.php +++ b/app/Models/StandaloneDocker.php @@ -2,8 +2,12 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; + class StandaloneDocker extends BaseModel { + use HasSafeStringAttribute; + protected $guarded = []; protected static function boot() diff --git a/app/Models/StandaloneDragonfly.php b/app/Models/StandaloneDragonfly.php index fdf69b834..673851713 100644 --- a/app/Models/StandaloneDragonfly.php +++ b/app/Models/StandaloneDragonfly.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; class StandaloneDragonfly extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; protected $guarded = []; diff --git a/app/Models/StandaloneKeydb.php b/app/Models/StandaloneKeydb.php index d52023920..e6562193b 100644 --- a/app/Models/StandaloneKeydb.php +++ b/app/Models/StandaloneKeydb.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; class StandaloneKeydb extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; protected $guarded = []; diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index 5a8869b41..1aa9d63c1 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\MorphTo; @@ -9,7 +10,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; class StandaloneMariadb extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; protected $guarded = []; diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index 88833eebe..299ea75b2 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; class StandaloneMongodb extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; protected $guarded = []; diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index dedc35f91..f376c7644 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; class StandaloneMysql extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; protected $guarded = []; diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index 689134a32..0bca2f4a7 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; class StandalonePostgresql extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; protected $guarded = []; @@ -320,7 +321,10 @@ class StandalonePostgresql extends BaseModel } $metrics = json_decode($metrics, true); $parsedCollection = collect($metrics)->map(function ($metric) { - return [(int) $metric['time'], (float) $metric['percent']]; + return [ + (int) $metric['time'], + (float) ($metric['percent'] ?? 0.0), + ]; }); return $parsedCollection->toArray(); diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 7f6f2ad72..6a44ee714 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -2,13 +2,14 @@ namespace App\Models; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\SoftDeletes; class StandaloneRedis extends BaseModel { - use HasFactory, SoftDeletes; + use HasFactory, HasSafeStringAttribute, SoftDeletes; protected $guarded = []; diff --git a/app/Models/Tag.php b/app/Models/Tag.php index a64c994a3..3594d1072 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -2,18 +2,17 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Casts\Attribute; +use App\Traits\HasSafeStringAttribute; class Tag extends BaseModel { + use HasSafeStringAttribute; + protected $guarded = []; - public function name(): Attribute + protected function customizeName($value) { - return Attribute::make( - get: fn ($value) => strtolower($value), - set: fn ($value) => strtolower($value) - ); + return strtolower($value); } public static function ownedByCurrentTeam() diff --git a/app/Models/Team.php b/app/Models/Team.php index 42b88f9e7..81638e31c 100644 --- a/app/Models/Team.php +++ b/app/Models/Team.php @@ -8,6 +8,7 @@ use App\Notifications\Channels\SendsEmail; use App\Notifications\Channels\SendsPushover; use App\Notifications\Channels\SendsSlack; use App\Traits\HasNotificationSettings; +use App\Traits\HasSafeStringAttribute; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Notifications\Notifiable; @@ -36,7 +37,7 @@ use OpenApi\Attributes as OA; class Team extends Model implements SendsDiscord, SendsEmail, SendsPushover, SendsSlack { - use HasNotificationSettings, Notifiable; + use HasNotificationSettings, HasSafeStringAttribute, Notifiable; protected $guarded = []; diff --git a/app/Models/User.php b/app/Models/User.php index 6cd1b66db..48651d292 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -53,6 +53,7 @@ class User extends Authenticatable implements SendsEmail 'email_verified_at' => 'datetime', 'force_password_reset' => 'boolean', 'show_boarding' => 'boolean', + 'email_change_code_expires_at' => 'datetime', ]; protected static function boot() @@ -203,6 +204,16 @@ class User extends Authenticatable implements SendsEmail return $this->belongsToMany(Team::class)->withPivot('role'); } + public function changelogReads() + { + return $this->hasMany(UserChangelogRead::class); + } + + public function getUnreadChangelogCount(): int + { + return app(\App\Services\ChangelogService::class)->getUnreadCountForUser($this); + } + public function getRecipients(): array { return [$this->email]; @@ -310,4 +321,77 @@ class User extends Authenticatable implements SendsEmail return data_get($user, 'pivot.role'); } + + public function requestEmailChange(string $newEmail): void + { + // Generate 6-digit code + $code = sprintf('%06d', mt_rand(0, 999999)); + + // Set expiration using config value + $expiryMinutes = config('constants.email_change.verification_code_expiry_minutes', 10); + $expiresAt = Carbon::now()->addMinutes($expiryMinutes); + + $this->update([ + 'pending_email' => $newEmail, + 'email_change_code' => $code, + 'email_change_code_expires_at' => $expiresAt, + ]); + + // Send verification email to new address + $this->notify(new \App\Notifications\TransactionalEmails\EmailChangeVerification($this, $code, $newEmail, $expiresAt)); + } + + public function isEmailChangeCodeValid(string $code): bool + { + return $this->email_change_code === $code + && $this->email_change_code_expires_at + && Carbon::now()->lessThan($this->email_change_code_expires_at); + } + + public function confirmEmailChange(string $code): bool + { + if (! $this->isEmailChangeCodeValid($code)) { + return false; + } + + $oldEmail = $this->email; + $newEmail = $this->pending_email; + + // Update email and clear change request fields + $this->update([ + 'email' => $newEmail, + 'pending_email' => null, + 'email_change_code' => null, + 'email_change_code_expires_at' => null, + ]); + + // For cloud users, dispatch job to update Stripe customer email asynchronously + if (isCloud() && $this->currentTeam()->subscription) { + dispatch(new \App\Jobs\UpdateStripeCustomerEmailJob( + $this->currentTeam(), + $this->id, + $newEmail, + $oldEmail + )); + } + + return true; + } + + public function clearEmailChangeRequest(): void + { + $this->update([ + 'pending_email' => null, + 'email_change_code' => null, + 'email_change_code_expires_at' => null, + ]); + } + + public function hasEmailChangeRequest(): bool + { + return ! is_null($this->pending_email) + && ! is_null($this->email_change_code) + && $this->email_change_code_expires_at + && Carbon::now()->lessThan($this->email_change_code_expires_at); + } } diff --git a/app/Models/UserChangelogRead.php b/app/Models/UserChangelogRead.php new file mode 100644 index 000000000..8c29ece14 --- /dev/null +++ b/app/Models/UserChangelogRead.php @@ -0,0 +1,48 @@ +<?php + +namespace App\Models; + +use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; + +class UserChangelogRead extends Model +{ + protected $fillable = [ + 'user_id', + 'release_tag', + 'read_at', + ]; + + protected $casts = [ + 'read_at' => 'datetime', + ]; + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public static function markAsRead(int $userId, string $identifier): void + { + self::firstOrCreate([ + 'user_id' => $userId, + 'release_tag' => $identifier, + ], [ + 'read_at' => now(), + ]); + } + + public static function isReadByUser(int $userId, string $identifier): bool + { + return self::where('user_id', $userId) + ->where('release_tag', $identifier) + ->exists(); + } + + public static function getReadIdentifiersForUser(int $userId): array + { + return self::where('user_id', $userId) + ->pluck('release_tag') + ->toArray(); + } +} diff --git a/app/Notifications/Channels/EmailChannel.php b/app/Notifications/Channels/EmailChannel.php index 8a9a95107..47994c690 100644 --- a/app/Notifications/Channels/EmailChannel.php +++ b/app/Notifications/Channels/EmailChannel.php @@ -2,6 +2,8 @@ namespace App\Notifications\Channels; +use App\Models\Team; +use Exception; use Illuminate\Notifications\Notification; use Resend; @@ -11,60 +13,102 @@ class EmailChannel public function send(SendsEmail $notifiable, Notification $notification): void { - $useInstanceEmailSettings = $notifiable->emailNotificationSettings->use_instance_email_settings; - $isTransactionalEmail = data_get($notification, 'isTransactionalEmail', false); - $customEmails = data_get($notification, 'emails', null); - if ($useInstanceEmailSettings || $isTransactionalEmail) { - $settings = instanceSettings(); - } else { - $settings = $notifiable->emailNotificationSettings; - } - $isResendEnabled = $settings->resend_enabled; - $isSmtpEnabled = $settings->smtp_enabled; - if ($customEmails) { - $recipients = [$customEmails]; - } else { - $recipients = $notifiable->getRecipients(); - } - $mailMessage = $notification->toMail($notifiable); + try { + // Get team and validate membership before proceeding + $team = data_get($notifiable, 'id'); + $members = Team::find($team)->members; - if ($isResendEnabled) { - $resend = Resend::client($settings->resend_api_key); - $from = "{$settings->smtp_from_name} <{$settings->smtp_from_address}>"; - $resend->emails->send([ - 'from' => $from, - 'to' => $recipients, - 'subject' => $mailMessage->subject, - 'html' => (string) $mailMessage->render(), + $useInstanceEmailSettings = $notifiable->emailNotificationSettings->use_instance_email_settings; + $isTransactionalEmail = data_get($notification, 'isTransactionalEmail', false); + $customEmails = data_get($notification, 'emails', null); + + if ($useInstanceEmailSettings || $isTransactionalEmail) { + $settings = instanceSettings(); + } else { + $settings = $notifiable->emailNotificationSettings; + } + + $isResendEnabled = $settings->resend_enabled; + $isSmtpEnabled = $settings->smtp_enabled; + + if ($customEmails) { + $recipients = [$customEmails]; + } else { + $recipients = $notifiable->getRecipients(); + } + + // Validate team membership for all recipients + if (count($recipients) === 0) { + throw new Exception('No email recipients found'); + } + + foreach ($recipients as $recipient) { + // Check if the recipient is part of the team + if (! $members->contains('email', $recipient)) { + $emailSettings = $notifiable->emailNotificationSettings; + data_set($emailSettings, 'smtp_password', '********'); + data_set($emailSettings, 'resend_api_key', '********'); + send_internal_notification(sprintf( + "Recipient is not part of the team: %s\nTeam: %s\nNotification: %s\nNotifiable: %s\nEmail Settings:\n%s", + $recipient, + $team, + get_class($notification), + get_class($notifiable), + json_encode($emailSettings, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) + )); + throw new Exception('Recipient is not part of the team'); + } + } + + $mailMessage = $notification->toMail($notifiable); + + if ($isResendEnabled) { + $resend = Resend::client($settings->resend_api_key); + $from = "{$settings->smtp_from_name} <{$settings->smtp_from_address}>"; + $resend->emails->send([ + 'from' => $from, + 'to' => $recipients, + 'subject' => $mailMessage->subject, + 'html' => (string) $mailMessage->render(), + ]); + } elseif ($isSmtpEnabled) { + $encryption = match (strtolower($settings->smtp_encryption)) { + 'starttls' => null, + 'tls' => 'tls', + 'none' => null, + default => null, + }; + + $transport = new \Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport( + $settings->smtp_host, + $settings->smtp_port, + $encryption + ); + $transport->setUsername($settings->smtp_username ?? ''); + $transport->setPassword($settings->smtp_password ?? ''); + + $mailer = new \Symfony\Component\Mailer\Mailer($transport); + + $fromEmail = $settings->smtp_from_address ?? 'noreply@localhost'; + $fromName = $settings->smtp_from_name ?? 'System'; + $from = new \Symfony\Component\Mime\Address($fromEmail, $fromName); + $email = (new \Symfony\Component\Mime\Email) + ->from($from) + ->to(...$recipients) + ->subject($mailMessage->subject) + ->html((string) $mailMessage->render()); + + $mailer->send($email); + } + } catch (\Throwable $e) { + \Illuminate\Support\Facades\Log::error('EmailChannel failed: '.$e->getMessage(), [ + 'notification' => get_class($notification), + 'notifiable' => get_class($notifiable), + 'team_id' => data_get($notifiable, 'id'), + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString(), ]); - } elseif ($isSmtpEnabled) { - $encryption = match (strtolower($settings->smtp_encryption)) { - 'starttls' => null, - 'tls' => 'tls', - 'none' => null, - default => null, - }; - - $transport = new \Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport( - $settings->smtp_host, - $settings->smtp_port, - $encryption - ); - $transport->setUsername($settings->smtp_username ?? ''); - $transport->setPassword($settings->smtp_password ?? ''); - - $mailer = new \Symfony\Component\Mailer\Mailer($transport); - - $fromEmail = $settings->smtp_from_address ?? 'noreply@localhost'; - $fromName = $settings->smtp_from_name ?? 'System'; - $from = new \Symfony\Component\Mime\Address($fromEmail, $fromName); - $email = (new \Symfony\Component\Mime\Email) - ->from($from) - ->to(...$recipients) - ->subject($mailMessage->subject) - ->html((string) $mailMessage->render()); - - $mailer->send($email); + throw $e; } } } diff --git a/app/Notifications/Channels/TransactionalEmailChannel.php b/app/Notifications/Channels/TransactionalEmailChannel.php index 114d1f6ed..8ab74a60b 100644 --- a/app/Notifications/Channels/TransactionalEmailChannel.php +++ b/app/Notifications/Channels/TransactionalEmailChannel.php @@ -16,7 +16,12 @@ class TransactionalEmailChannel if (! data_get($settings, 'smtp_enabled') && ! data_get($settings, 'resend_enabled')) { return; } - $email = $notifiable->email; + + // Check if notification has a custom recipient (for email changes) + $email = property_exists($notification, 'newEmail') && $notification->newEmail + ? $notification->newEmail + : $notifiable->email; + if (! $email) { return; } diff --git a/app/Notifications/TransactionalEmails/EmailChangeVerification.php b/app/Notifications/TransactionalEmails/EmailChangeVerification.php new file mode 100644 index 000000000..ea8462366 --- /dev/null +++ b/app/Notifications/TransactionalEmails/EmailChangeVerification.php @@ -0,0 +1,43 @@ +<?php + +namespace App\Notifications\TransactionalEmails; + +use App\Models\User; +use App\Notifications\Channels\TransactionalEmailChannel; +use App\Notifications\CustomEmailNotification; +use Illuminate\Notifications\Messages\MailMessage; +use Illuminate\Support\Carbon; + +class EmailChangeVerification extends CustomEmailNotification +{ + public function via(): array + { + return [TransactionalEmailChannel::class]; + } + + public function __construct( + public User $user, + public string $verificationCode, + public string $newEmail, + public Carbon $expiresAt, + public bool $isTransactionalEmail = true + ) { + $this->onQueue('high'); + } + + public function toMail(): MailMessage + { + // Use the configured expiry minutes value + $expiryMinutes = config('constants.email_change.verification_code_expiry_minutes', 10); + + $mail = new MailMessage; + $mail->subject('Coolify: Verify Your New Email Address'); + $mail->view('emails.email-change-verification', [ + 'newEmail' => $this->newEmail, + 'verificationCode' => $this->verificationCode, + 'expiryMinutes' => $expiryMinutes, + ]); + + return $mail; + } +} diff --git a/app/Policies/ApiTokenPolicy.php b/app/Policies/ApiTokenPolicy.php new file mode 100644 index 000000000..761227118 --- /dev/null +++ b/app/Policies/ApiTokenPolicy.php @@ -0,0 +1,109 @@ +<?php + +namespace App\Policies; + +use App\Models\User; +use Laravel\Sanctum\PersonalAccessToken; + +class ApiTokenPolicy +{ + /** + * Determine whether the user can view any API tokens. + */ + public function viewAny(User $user): bool + { + // Authorization temporarily disabled + /* + // Users can view their own API tokens + return true; + */ + return true; + } + + /** + * Determine whether the user can view the API token. + */ + public function view(User $user, PersonalAccessToken $token): bool + { + // Authorization temporarily disabled + /* + // Users can only view their own tokens + return $user->id === $token->tokenable_id && $token->tokenable_type === User::class; + */ + return true; + } + + /** + * Determine whether the user can create API tokens. + */ + public function create(User $user): bool + { + // Authorization temporarily disabled + /* + // All authenticated users can create their own API tokens + return true; + */ + return true; + } + + /** + * Determine whether the user can update the API token. + */ + public function update(User $user, PersonalAccessToken $token): bool + { + // Authorization temporarily disabled + /* + // Users can only update their own tokens + return $user->id === $token->tokenable_id && $token->tokenable_type === User::class; + */ + return true; + } + + /** + * Determine whether the user can delete the API token. + */ + public function delete(User $user, PersonalAccessToken $token): bool + { + // Authorization temporarily disabled + /* + // Users can only delete their own tokens + return $user->id === $token->tokenable_id && $token->tokenable_type === User::class; + */ + return true; + } + + /** + * Determine whether the user can manage their own API tokens. + */ + public function manage(User $user): bool + { + // Authorization temporarily disabled + /* + // All authenticated users can manage their own API tokens + return true; + */ + return true; + } + + /** + * Determine whether the user can use root permissions for API tokens. + */ + public function useRootPermissions(User $user): bool + { + // Only admins and owners can use root permissions + return $user->isAdmin() || $user->isOwner(); + } + + /** + * Determine whether the user can use write permissions for API tokens. + */ + public function useWritePermissions(User $user): bool + { + // Authorization temporarily disabled + /* + // Only admins and owners can use write permissions + return $user->isAdmin() || $user->isOwner(); + */ + return true; + } +} diff --git a/app/Policies/ApplicationPolicy.php b/app/Policies/ApplicationPolicy.php index 05fc289b8..d64a436ad 100644 --- a/app/Policies/ApplicationPolicy.php +++ b/app/Policies/ApplicationPolicy.php @@ -4,6 +4,7 @@ namespace App\Policies; use App\Models\Application; use App\Models\User; +use Illuminate\Auth\Access\Response; class ApplicationPolicy { @@ -12,6 +13,10 @@ class ApplicationPolicy */ public function viewAny(User $user): bool { + // Authorization temporarily disabled + /* + return true; + */ return true; } @@ -20,6 +25,10 @@ class ApplicationPolicy */ public function view(User $user, Application $application): bool { + // Authorization temporarily disabled + /* + return true; + */ return true; } @@ -28,15 +37,31 @@ class ApplicationPolicy */ public function create(User $user): bool { + // Authorization temporarily disabled + /* + if ($user->isAdmin()) { + return true; + } + + return false; + */ return true; } /** * Determine whether the user can update the model. */ - public function update(User $user, Application $application): bool + public function update(User $user, Application $application): Response { - return true; + // Authorization temporarily disabled + /* + if ($user->isAdmin()) { + return Response::allow(); + } + + return Response::deny('As a member, you cannot update this application.<br/><br/>You need at least admin or owner permissions.'); + */ + return Response::allow(); } /** @@ -44,11 +69,15 @@ class ApplicationPolicy */ public function delete(User $user, Application $application): bool { + // Authorization temporarily disabled + /* if ($user->isAdmin()) { return true; } return false; + */ + return true; } /** @@ -56,6 +85,10 @@ class ApplicationPolicy */ public function restore(User $user, Application $application): bool { + // Authorization temporarily disabled + /* + return true; + */ return true; } @@ -64,6 +97,58 @@ class ApplicationPolicy */ public function forceDelete(User $user, Application $application): bool { + // Authorization temporarily disabled + /* + return $user->isAdmin() && $user->teams->contains('id', $application->team()->first()->id); + */ + return true; + } + + /** + * Determine whether the user can deploy the application. + */ + public function deploy(User $user, Application $application): bool + { + // Authorization temporarily disabled + /* + return $user->teams->contains('id', $application->team()->first()->id); + */ + return true; + } + + /** + * Determine whether the user can manage deployments. + */ + public function manageDeployments(User $user, Application $application): bool + { + // Authorization temporarily disabled + /* + return $user->isAdmin() && $user->teams->contains('id', $application->team()->first()->id); + */ + return true; + } + + /** + * Determine whether the user can manage environment variables. + */ + public function manageEnvironment(User $user, Application $application): bool + { + // Authorization temporarily disabled + /* + return $user->isAdmin() && $user->teams->contains('id', $application->team()->first()->id); + */ + return true; + } + + /** + * Determine whether the user can cleanup deployment queue. + */ + public function cleanupDeploymentQueue(User $user): bool + { + // Authorization temporarily disabled + /* + return $user->isAdmin(); + */ return true; } } diff --git a/app/Policies/ApplicationPreviewPolicy.php b/app/Policies/ApplicationPreviewPolicy.php new file mode 100644 index 000000000..14efbdef9 --- /dev/null +++ b/app/Policies/ApplicationPreviewPolicy.php @@ -0,0 +1,94 @@ +<?php + +namespace App\Policies; + +use App\Models\ApplicationPreview; +use App\Models\User; +use Illuminate\Auth\Access\Response; + +class ApplicationPreviewPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, ApplicationPreview $applicationPreview): bool + { + // return $user->teams->contains('id', $applicationPreview->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, ApplicationPreview $applicationPreview): Response + { + // if ($user->isAdmin()) { + // return Response::allow(); + // } + + // return Response::deny('As a member, you cannot update this preview.<br/><br/>You need at least admin or owner permissions.'); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, ApplicationPreview $applicationPreview): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $applicationPreview->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, ApplicationPreview $applicationPreview): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $applicationPreview->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, ApplicationPreview $applicationPreview): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $applicationPreview->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can deploy the preview. + */ + public function deploy(User $user, ApplicationPreview $applicationPreview): bool + { + // return $user->teams->contains('id', $applicationPreview->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can manage preview deployments. + */ + public function manageDeployments(User $user, ApplicationPreview $applicationPreview): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $applicationPreview->application->team()->first()->id); + return true; + } +} diff --git a/app/Policies/ApplicationSettingPolicy.php b/app/Policies/ApplicationSettingPolicy.php new file mode 100644 index 000000000..848dc9aee --- /dev/null +++ b/app/Policies/ApplicationSettingPolicy.php @@ -0,0 +1,71 @@ +<?php + +namespace App\Policies; + +use App\Models\ApplicationSetting; +use App\Models\User; + +class ApplicationSettingPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, ApplicationSetting $applicationSetting): bool + { + // return $user->teams->contains('id', $applicationSetting->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, ApplicationSetting $applicationSetting): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $applicationSetting->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, ApplicationSetting $applicationSetting): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $applicationSetting->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, ApplicationSetting $applicationSetting): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $applicationSetting->application->team()->first()->id); + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, ApplicationSetting $applicationSetting): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $applicationSetting->application->team()->first()->id); + return true; + } +} diff --git a/app/Policies/DatabasePolicy.php b/app/Policies/DatabasePolicy.php new file mode 100644 index 000000000..520c0006e --- /dev/null +++ b/app/Policies/DatabasePolicy.php @@ -0,0 +1,102 @@ +<?php + +namespace App\Policies; + +use App\Models\User; +use Illuminate\Auth\Access\Response; + +class DatabasePolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, $database): bool + { + // return $user->teams->contains('id', $database->team()->first()->id); + return true; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, $database): Response + { + // if ($user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id)) { + // return Response::allow(); + // } + + // return Response::deny('As a member, you cannot update this database.<br/><br/>You need at least admin or owner permissions.'); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, $database): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, $database): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id); + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, $database): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id); + return true; + } + + /** + * Determine whether the user can start/stop the database. + */ + public function manage(User $user, $database): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id); + return true; + } + + /** + * Determine whether the user can manage database backups. + */ + public function manageBackups(User $user, $database): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id); + return true; + } + + /** + * Determine whether the user can manage environment variables. + */ + public function manageEnvironment(User $user, $database): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $database->team()->first()->id); + return true; + } +} diff --git a/app/Policies/EnvironmentPolicy.php b/app/Policies/EnvironmentPolicy.php new file mode 100644 index 000000000..7199abb25 --- /dev/null +++ b/app/Policies/EnvironmentPolicy.php @@ -0,0 +1,71 @@ +<?php + +namespace App\Policies; + +use App\Models\Environment; +use App\Models\User; + +class EnvironmentPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, Environment $environment): bool + { + // return $user->teams->contains('id', $environment->project->team_id); + return true; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, Environment $environment): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $environment->project->team_id); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, Environment $environment): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $environment->project->team_id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, Environment $environment): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $environment->project->team_id); + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, Environment $environment): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $environment->project->team_id); + return true; + } +} diff --git a/app/Policies/GithubAppPolicy.php b/app/Policies/GithubAppPolicy.php new file mode 100644 index 000000000..56bec7032 --- /dev/null +++ b/app/Policies/GithubAppPolicy.php @@ -0,0 +1,79 @@ +<?php + +namespace App\Policies; + +use App\Models\GithubApp; +use App\Models\User; + +class GithubAppPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, GithubApp $githubApp): bool + { + // return $user->teams->contains('id', $githubApp->team_id) || $githubApp->is_system_wide; + return true; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, GithubApp $githubApp): bool + { + if ($githubApp->is_system_wide) { + // return $user->isAdmin(); + return true; + } + + // return $user->isAdmin() && $user->teams->contains('id', $githubApp->team_id); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, GithubApp $githubApp): bool + { + if ($githubApp->is_system_wide) { + // return $user->isAdmin(); + return true; + } + + // return $user->isAdmin() && $user->teams->contains('id', $githubApp->team_id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, GithubApp $githubApp): bool + { + return false; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, GithubApp $githubApp): bool + { + return false; + } +} diff --git a/app/Policies/NotificationPolicy.php b/app/Policies/NotificationPolicy.php new file mode 100644 index 000000000..4f3be431d --- /dev/null +++ b/app/Policies/NotificationPolicy.php @@ -0,0 +1,56 @@ +<?php + +namespace App\Policies; + +use App\Models\User; +use Illuminate\Database\Eloquent\Model; + +class NotificationPolicy +{ + /** + * Determine whether the user can view the notification settings. + */ + public function view(User $user, Model $notificationSettings): bool + { + // Check if the notification settings belong to the user's current team + if (! $notificationSettings->team) { + return false; + } + + // return $user->teams()->where('teams.id', $notificationSettings->team->id)->exists(); + return true; + } + + /** + * Determine whether the user can update the notification settings. + */ + public function update(User $user, Model $notificationSettings): bool + { + // Check if the notification settings belong to the user's current team + if (! $notificationSettings->team) { + return false; + } + + // Only owners and admins can update notification settings + // return $user->isAdmin() || $user->isOwner(); + return true; + } + + /** + * Determine whether the user can manage (create, update, delete) notification settings. + */ + public function manage(User $user, Model $notificationSettings): bool + { + // return $this->update($user, $notificationSettings); + return true; + } + + /** + * Determine whether the user can send test notifications. + */ + public function sendTest(User $user, Model $notificationSettings): bool + { + // return $this->update($user, $notificationSettings); + return true; + } +} diff --git a/app/Policies/PrivateKeyPolicy.php b/app/Policies/PrivateKeyPolicy.php new file mode 100644 index 000000000..996054c95 --- /dev/null +++ b/app/Policies/PrivateKeyPolicy.php @@ -0,0 +1,69 @@ +<?php + +namespace App\Policies; + +use App\Models\PrivateKey; +use App\Models\User; + +class PrivateKeyPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, PrivateKey $privateKey): bool + { + // return $user->teams->contains('id', $privateKey->team_id); + return true; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, PrivateKey $privateKey): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $privateKey->team_id); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, PrivateKey $privateKey): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $privateKey->team_id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, PrivateKey $privateKey): bool + { + return false; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, PrivateKey $privateKey): bool + { + return false; + } +} diff --git a/app/Policies/ProjectPolicy.php b/app/Policies/ProjectPolicy.php new file mode 100644 index 000000000..e188c293f --- /dev/null +++ b/app/Policies/ProjectPolicy.php @@ -0,0 +1,71 @@ +<?php + +namespace App\Policies; + +use App\Models\Project; +use App\Models\User; + +class ProjectPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, Project $project): bool + { + // return $user->teams->contains('id', $project->team_id); + return true; + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, Project $project): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $project->team_id); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, Project $project): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $project->team_id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, Project $project): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $project->team_id); + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, Project $project): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $project->team_id); + return true; + } +} diff --git a/app/Policies/ResourceCreatePolicy.php b/app/Policies/ResourceCreatePolicy.php new file mode 100644 index 000000000..9ed2b66ab --- /dev/null +++ b/app/Policies/ResourceCreatePolicy.php @@ -0,0 +1,65 @@ +<?php + +namespace App\Policies; + +use App\Models\Application; +use App\Models\Service; +use App\Models\StandaloneClickhouse; +use App\Models\StandaloneDragonfly; +use App\Models\StandaloneKeydb; +use App\Models\StandaloneMariadb; +use App\Models\StandaloneMongodb; +use App\Models\StandaloneMysql; +use App\Models\StandalonePostgresql; +use App\Models\StandaloneRedis; +use App\Models\User; + +class ResourceCreatePolicy +{ + /** + * List of resource classes that can be created + */ + public const CREATABLE_RESOURCES = [ + StandalonePostgresql::class, + StandaloneRedis::class, + StandaloneMongodb::class, + StandaloneMysql::class, + StandaloneMariadb::class, + StandaloneKeydb::class, + StandaloneDragonfly::class, + StandaloneClickhouse::class, + Service::class, + Application::class, + GithubApp::class, + ]; + + /** + * Determine whether the user can create any resource. + */ + public function createAny(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can create a specific resource type. + */ + public function create(User $user, string $resourceClass): bool + { + if (! in_array($resourceClass, self::CREATABLE_RESOURCES)) { + return false; + } + + // return $user->isAdmin(); + return true; + } + + /** + * Authorize creation of all supported resource types. + */ + public function authorizeAllResourceCreation(User $user): bool + { + return $this->createAny($user); + } +} diff --git a/app/Policies/S3StoragePolicy.php b/app/Policies/S3StoragePolicy.php index 28f5f8426..982c7c523 100644 --- a/app/Policies/S3StoragePolicy.php +++ b/app/Policies/S3StoragePolicy.php @@ -3,7 +3,6 @@ namespace App\Policies; use App\Models\S3Storage; -use App\Models\Server; use App\Models\User; class S3StoragePolicy @@ -21,7 +20,7 @@ class S3StoragePolicy */ public function view(User $user, S3Storage $storage): bool { - return $user->teams()->where('id', $storage->team_id)->exists(); + return $user->teams->contains('id', $storage->team_id); } /** @@ -29,15 +28,16 @@ class S3StoragePolicy */ public function create(User $user): bool { - return true; + return $user->isAdmin(); } /** * Determine whether the user can update the model. */ - public function update(User $user, Server $server): bool + public function update(User $user, S3Storage $storage): bool { - return $user->teams()->get()->firstWhere('id', $server->team_id) !== null; + // return $user->teams->contains('id', $storage->team_id) && $user->isAdmin(); + return $user->teams->contains('id', $storage->team_id); } /** @@ -45,7 +45,8 @@ class S3StoragePolicy */ public function delete(User $user, S3Storage $storage): bool { - return $user->teams()->where('id', $storage->team_id)->exists(); + // return $user->teams->contains('id', $storage->team_id) && $user->isAdmin(); + return $user->teams->contains('id', $storage->team_id); } /** @@ -63,4 +64,12 @@ class S3StoragePolicy { return false; } + + /** + * Determine whether the user can validate the connection of the model. + */ + public function validateConnection(User $user, S3Storage $storage): bool + { + return $user->teams->contains('id', $storage->team_id); + } } diff --git a/app/Policies/ServerPolicy.php b/app/Policies/ServerPolicy.php index ad59b7140..5cc6b739f 100644 --- a/app/Policies/ServerPolicy.php +++ b/app/Policies/ServerPolicy.php @@ -20,7 +20,7 @@ class ServerPolicy */ public function view(User $user, Server $server): bool { - return $user->teams()->get()->firstWhere('id', $server->team_id) !== null; + return $user->teams->contains('id', $server->team_id); } /** @@ -28,7 +28,7 @@ class ServerPolicy */ public function create(User $user): bool { - return true; + return $user->isAdmin(); } /** @@ -36,7 +36,7 @@ class ServerPolicy */ public function update(User $user, Server $server): bool { - return $user->teams()->get()->firstWhere('id', $server->team_id) !== null; + return $user->isAdmin() && $user->teams->contains('id', $server->team_id); } /** @@ -44,7 +44,7 @@ class ServerPolicy */ public function delete(User $user, Server $server): bool { - return $user->teams()->get()->firstWhere('id', $server->team_id) !== null; + return $user->isAdmin() && $user->teams->contains('id', $server->team_id); } /** @@ -62,4 +62,44 @@ class ServerPolicy { return false; } + + /** + * Determine whether the user can manage proxy (start/stop/restart). + */ + public function manageProxy(User $user, Server $server): bool + { + return $user->isAdmin() && $user->teams->contains('id', $server->team_id); + } + + /** + * Determine whether the user can manage sentinel (start/stop). + */ + public function manageSentinel(User $user, Server $server): bool + { + return $user->isAdmin() && $user->teams->contains('id', $server->team_id); + } + + /** + * Determine whether the user can manage CA certificates. + */ + public function manageCaCertificate(User $user, Server $server): bool + { + return $user->isAdmin() && $user->teams->contains('id', $server->team_id); + } + + /** + * Determine whether the user can view terminal. + */ + public function viewTerminal(User $user, Server $server): bool + { + return $user->isAdmin() && $user->teams->contains('id', $server->team_id); + } + + /** + * Determine whether the user can view security views. + */ + public function viewSecurity(User $user, Server $server): bool + { + return $user->isAdmin() && $user->teams->contains('id', $server->team_id); + } } diff --git a/app/Policies/ServiceApplicationPolicy.php b/app/Policies/ServiceApplicationPolicy.php new file mode 100644 index 000000000..af380a90f --- /dev/null +++ b/app/Policies/ServiceApplicationPolicy.php @@ -0,0 +1,63 @@ +<?php + +namespace App\Policies; + +use App\Models\ServiceApplication; +use App\Models\User; +use Illuminate\Support\Facades\Gate; + +class ServiceApplicationPolicy +{ + /** + * Determine whether the user can view the model. + */ + public function view(User $user, ServiceApplication $serviceApplication): bool + { + return Gate::allows('view', $serviceApplication->service); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, ServiceApplication $serviceApplication): bool + { + // return Gate::allows('update', $serviceApplication->service); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, ServiceApplication $serviceApplication): bool + { + // return Gate::allows('delete', $serviceApplication->service); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, ServiceApplication $serviceApplication): bool + { + // return Gate::allows('update', $serviceApplication->service); + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, ServiceApplication $serviceApplication): bool + { + // return Gate::allows('delete', $serviceApplication->service); + return true; + } +} diff --git a/app/Policies/ServiceDatabasePolicy.php b/app/Policies/ServiceDatabasePolicy.php new file mode 100644 index 000000000..023434a24 --- /dev/null +++ b/app/Policies/ServiceDatabasePolicy.php @@ -0,0 +1,63 @@ +<?php + +namespace App\Policies; + +use App\Models\ServiceDatabase; +use App\Models\User; +use Illuminate\Support\Facades\Gate; + +class ServiceDatabasePolicy +{ + /** + * Determine whether the user can view the model. + */ + public function view(User $user, ServiceDatabase $serviceDatabase): bool + { + return Gate::allows('view', $serviceDatabase->service); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, ServiceDatabase $serviceDatabase): bool + { + // return Gate::allows('update', $serviceDatabase->service); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, ServiceDatabase $serviceDatabase): bool + { + // return Gate::allows('delete', $serviceDatabase->service); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, ServiceDatabase $serviceDatabase): bool + { + // return Gate::allows('update', $serviceDatabase->service); + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, ServiceDatabase $serviceDatabase): bool + { + // return Gate::allows('delete', $serviceDatabase->service); + return true; + } +} diff --git a/app/Policies/ServicePolicy.php b/app/Policies/ServicePolicy.php index 51a6d8116..7ab0fe7d0 100644 --- a/app/Policies/ServicePolicy.php +++ b/app/Policies/ServicePolicy.php @@ -28,6 +28,7 @@ class ServicePolicy */ public function create(User $user): bool { + // return $user->isAdmin(); return true; } @@ -36,6 +37,12 @@ class ServicePolicy */ public function update(User $user, Service $service): bool { + $team = $service->team(); + if (! $team) { + return false; + } + + // return $user->isAdmin() && $user->teams->contains('id', $team->id); return true; } @@ -44,11 +51,12 @@ class ServicePolicy */ public function delete(User $user, Service $service): bool { - if ($user->isAdmin()) { - return true; - } + // if ($user->isAdmin()) { + // return true; + // } - return false; + // return false; + return true; } /** @@ -56,6 +64,7 @@ class ServicePolicy */ public function restore(User $user, Service $service): bool { + // return true; return true; } @@ -64,19 +73,56 @@ class ServicePolicy */ public function forceDelete(User $user, Service $service): bool { - if ($user->isAdmin()) { - return true; - } + // if ($user->isAdmin()) { + // return true; + // } - return false; + // return false; + return true; } public function stop(User $user, Service $service): bool { - if ($user->isAdmin()) { - return true; + $team = $service->team(); + if (! $team) { + return false; } - return false; + // return $user->teams->contains('id', $team->id); + return true; + } + + /** + * Determine whether the user can manage environment variables. + */ + public function manageEnvironment(User $user, Service $service): bool + { + $team = $service->team(); + if (! $team) { + return false; + } + + // return $user->isAdmin() && $user->teams->contains('id', $team->id); + return true; + } + + /** + * Determine whether the user can deploy the service. + */ + public function deploy(User $user, Service $service): bool + { + $team = $service->team(); + if (! $team) { + return false; + } + + // return $user->teams->contains('id', $team->id); + return true; + } + + public function accessTerminal(User $user, Service $service): bool + { + // return $user->isAdmin() || $user->teams->contains('id', $service->team()->id); + return true; } } diff --git a/app/Policies/SharedEnvironmentVariablePolicy.php b/app/Policies/SharedEnvironmentVariablePolicy.php new file mode 100644 index 000000000..b465d8a0c --- /dev/null +++ b/app/Policies/SharedEnvironmentVariablePolicy.php @@ -0,0 +1,79 @@ +<?php + +namespace App\Policies; + +use App\Models\SharedEnvironmentVariable; +use App\Models\User; + +class SharedEnvironmentVariablePolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool + { + return $user->teams->contains('id', $sharedEnvironmentVariable->team_id); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id); + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id); + return true; + } + + /** + * Determine whether the user can manage environment variables. + */ + public function manageEnvironment(User $user, SharedEnvironmentVariable $sharedEnvironmentVariable): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $sharedEnvironmentVariable->team_id); + return true; + } +} diff --git a/app/Policies/StandaloneDockerPolicy.php b/app/Policies/StandaloneDockerPolicy.php new file mode 100644 index 000000000..154648599 --- /dev/null +++ b/app/Policies/StandaloneDockerPolicy.php @@ -0,0 +1,70 @@ +<?php + +namespace App\Policies; + +use App\Models\StandaloneDocker; +use App\Models\User; + +class StandaloneDockerPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, StandaloneDocker $standaloneDocker): bool + { + return $user->teams->contains('id', $standaloneDocker->server->team_id); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, StandaloneDocker $standaloneDocker): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $standaloneDocker->server->team_id); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, StandaloneDocker $standaloneDocker): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $standaloneDocker->server->team_id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, StandaloneDocker $standaloneDocker): bool + { + // return false; + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, StandaloneDocker $standaloneDocker): bool + { + // return false; + return true; + } +} diff --git a/app/Policies/SwarmDockerPolicy.php b/app/Policies/SwarmDockerPolicy.php new file mode 100644 index 000000000..979bb5889 --- /dev/null +++ b/app/Policies/SwarmDockerPolicy.php @@ -0,0 +1,70 @@ +<?php + +namespace App\Policies; + +use App\Models\SwarmDocker; +use App\Models\User; + +class SwarmDockerPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, SwarmDocker $swarmDocker): bool + { + return $user->teams->contains('id', $swarmDocker->server->team_id); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // return $user->isAdmin(); + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, SwarmDocker $swarmDocker): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $swarmDocker->server->team_id); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, SwarmDocker $swarmDocker): bool + { + // return $user->isAdmin() && $user->teams->contains('id', $swarmDocker->server->team_id); + return true; + } + + /** + * Determine whether the user can restore the model. + */ + public function restore(User $user, SwarmDocker $swarmDocker): bool + { + // return false; + return true; + } + + /** + * Determine whether the user can permanently delete the model. + */ + public function forceDelete(User $user, SwarmDocker $swarmDocker): bool + { + // return false; + return true; + } +} diff --git a/app/Policies/TeamPolicy.php b/app/Policies/TeamPolicy.php new file mode 100644 index 000000000..b7ef48943 --- /dev/null +++ b/app/Policies/TeamPolicy.php @@ -0,0 +1,104 @@ +<?php + +namespace App\Policies; + +use App\Models\Team; +use App\Models\User; + +class TeamPolicy +{ + /** + * Determine whether the user can view any models. + */ + public function viewAny(User $user): bool + { + return true; + } + + /** + * Determine whether the user can view the model. + */ + public function view(User $user, Team $team): bool + { + return $user->teams->contains('id', $team->id); + } + + /** + * Determine whether the user can create models. + */ + public function create(User $user): bool + { + // All authenticated users can create teams + return true; + } + + /** + * Determine whether the user can update the model. + */ + public function update(User $user, Team $team): bool + { + // Only admins and owners can update team settings + if (! $user->teams->contains('id', $team->id)) { + return false; + } + + // return $user->isAdmin() || $user->isOwner(); + return true; + } + + /** + * Determine whether the user can delete the model. + */ + public function delete(User $user, Team $team): bool + { + // Only admins and owners can delete teams + if (! $user->teams->contains('id', $team->id)) { + return false; + } + + // return $user->isAdmin() || $user->isOwner(); + return true; + } + + /** + * Determine whether the user can manage team members. + */ + public function manageMembers(User $user, Team $team): bool + { + // Only admins and owners can manage team members + if (! $user->teams->contains('id', $team->id)) { + return false; + } + + // return $user->isAdmin() || $user->isOwner(); + return true; + } + + /** + * Determine whether the user can view admin panel. + */ + public function viewAdmin(User $user, Team $team): bool + { + // Only admins and owners can view admin panel + if (! $user->teams->contains('id', $team->id)) { + return false; + } + + // return $user->isAdmin() || $user->isOwner(); + return true; + } + + /** + * Determine whether the user can manage invitations. + */ + public function manageInvitations(User $user, Team $team): bool + { + // Only admins and owners can manage invitations + if (! $user->teams->contains('id', $team->id)) { + return false; + } + + // return $user->isAdmin() || $user->isOwner(); + return true; + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index dafcbee79..a17d9ec5e 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -3,7 +3,9 @@ namespace App\Providers; // use Illuminate\Support\Facades\Gate; +use App\Policies\ResourceCreatePolicy; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; +use Illuminate\Support\Facades\Gate; class AuthServiceProvider extends ServiceProvider { @@ -13,7 +15,45 @@ class AuthServiceProvider extends ServiceProvider * @var array<class-string, class-string> */ protected $policies = [ - // 'App\Models\Model' => 'App\Policies\ModelPolicy', + \App\Models\Server::class => \App\Policies\ServerPolicy::class, + \App\Models\PrivateKey::class => \App\Policies\PrivateKeyPolicy::class, + \App\Models\StandaloneDocker::class => \App\Policies\StandaloneDockerPolicy::class, + \App\Models\SwarmDocker::class => \App\Policies\SwarmDockerPolicy::class, + \App\Models\Application::class => \App\Policies\ApplicationPolicy::class, + \App\Models\ApplicationPreview::class => \App\Policies\ApplicationPreviewPolicy::class, + \App\Models\ApplicationSetting::class => \App\Policies\ApplicationSettingPolicy::class, + \App\Models\Service::class => \App\Policies\ServicePolicy::class, + \App\Models\ServiceApplication::class => \App\Policies\ServiceApplicationPolicy::class, + \App\Models\ServiceDatabase::class => \App\Policies\ServiceDatabasePolicy::class, + \App\Models\Project::class => \App\Policies\ProjectPolicy::class, + \App\Models\Environment::class => \App\Policies\EnvironmentPolicy::class, + \App\Models\SharedEnvironmentVariable::class => \App\Policies\SharedEnvironmentVariablePolicy::class, + // Database policies - all use the shared DatabasePolicy + \App\Models\StandalonePostgresql::class => \App\Policies\DatabasePolicy::class, + \App\Models\StandaloneMysql::class => \App\Policies\DatabasePolicy::class, + \App\Models\StandaloneMariadb::class => \App\Policies\DatabasePolicy::class, + \App\Models\StandaloneMongodb::class => \App\Policies\DatabasePolicy::class, + \App\Models\StandaloneRedis::class => \App\Policies\DatabasePolicy::class, + \App\Models\StandaloneKeydb::class => \App\Policies\DatabasePolicy::class, + \App\Models\StandaloneDragonfly::class => \App\Policies\DatabasePolicy::class, + \App\Models\StandaloneClickhouse::class => \App\Policies\DatabasePolicy::class, + + // Notification policies - all use the shared NotificationPolicy + \App\Models\EmailNotificationSettings::class => \App\Policies\NotificationPolicy::class, + \App\Models\DiscordNotificationSettings::class => \App\Policies\NotificationPolicy::class, + \App\Models\TelegramNotificationSettings::class => \App\Policies\NotificationPolicy::class, + \App\Models\SlackNotificationSettings::class => \App\Policies\NotificationPolicy::class, + \App\Models\PushoverNotificationSettings::class => \App\Policies\NotificationPolicy::class, + + // API Token policy + \Laravel\Sanctum\PersonalAccessToken::class => \App\Policies\ApiTokenPolicy::class, + + // Team policy + \App\Models\Team::class => \App\Policies\TeamPolicy::class, + + // Git source policies + \App\Models\GithubApp::class => \App\Policies\GithubAppPolicy::class, + ]; /** @@ -21,6 +61,13 @@ class AuthServiceProvider extends ServiceProvider */ public function boot(): void { - // + // Register gates for resource creation policy + Gate::define('createAnyResource', [ResourceCreatePolicy::class, 'createAny']); + + // Register gate for terminal access + Gate::define('canAccessTerminal', function ($user) { + // return $user->isAdmin() || $user->isOwner(); + return true; + }); } } diff --git a/app/Rules/ValidGitBranch.php b/app/Rules/ValidGitBranch.php new file mode 100644 index 000000000..a3069f08e --- /dev/null +++ b/app/Rules/ValidGitBranch.php @@ -0,0 +1,96 @@ +<?php + +namespace App\Rules; + +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; +use Illuminate\Support\Facades\Log; + +class ValidGitBranch implements ValidationRule +{ + /** + * Run the validation rule. + */ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + if (empty($value)) { + return; + } + + $branch = trim($value); + + // Check for dangerous shell metacharacters + $dangerousChars = [ + ';', '|', '&', '$', '`', '(', ')', '{', '}', + '<', '>', '\n', '\r', '\0', '"', "'", '\\', + '!', '*', '?', '[', ']', '~', '^', ':', ' ', + '#', + ]; + + foreach ($dangerousChars as $char) { + if (str_contains($branch, $char)) { + Log::warning('Git branch validation failed - dangerous character', [ + 'branch' => $branch, + 'character' => $char, + 'ip' => request()->ip(), + 'user_id' => auth()->id(), + ]); + $fail('The :attribute contains invalid characters.'); + + return; + } + } + + // Git branch name rules: + // - Cannot contain: .., //, @{ + // - Cannot start or end with: / or . + // - Cannot be empty after trimming + + if (str_contains($branch, '..') || + str_contains($branch, '//') || + str_contains($branch, '@{')) { + $fail('The :attribute contains invalid patterns.'); + + return; + } + + if (str_starts_with($branch, '/') || + str_ends_with($branch, '/') || + str_starts_with($branch, '.') || + str_ends_with($branch, '.')) { + $fail('The :attribute cannot start or end with / or .'); + + return; + } + + // Allow only safe characters for branch names + // Letters, numbers, hyphens, underscores, forward slashes, and dots + if (! preg_match('/^[a-zA-Z0-9\-_\/\.]+$/', $branch)) { + $fail('The :attribute contains invalid characters. Only letters, numbers, hyphens, underscores, forward slashes, and dots are allowed.'); + + return; + } + + // Additional Git-specific validations + // Branch name cannot be 'HEAD' + if ($branch === 'HEAD') { + $fail('The :attribute cannot be HEAD.'); + + return; + } + + // Check for consecutive dots (not allowed in Git) + if (str_contains($branch, '..')) { + $fail('The :attribute cannot contain consecutive dots.'); + + return; + } + + // Check for .lock suffix (reserved by Git) + if (str_ends_with($branch, '.lock')) { + $fail('The :attribute cannot end with .lock.'); + + return; + } + } +} diff --git a/app/Rules/ValidGitRepositoryUrl.php b/app/Rules/ValidGitRepositoryUrl.php new file mode 100644 index 000000000..3cbe9246e --- /dev/null +++ b/app/Rules/ValidGitRepositoryUrl.php @@ -0,0 +1,157 @@ +<?php + +namespace App\Rules; + +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; +use Illuminate\Support\Facades\Log; + +class ValidGitRepositoryUrl implements ValidationRule +{ + protected bool $allowSSH; + + protected bool $allowIP; + + public function __construct(bool $allowSSH = true, bool $allowIP = false) + { + $this->allowSSH = $allowSSH; + $this->allowIP = $allowIP; + } + + /** + * Run the validation rule. + */ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + if (empty($value)) { + return; + } + + // Check for dangerous shell metacharacters that could be used for command injection + $dangerousChars = [ + ';', '|', '&', '$', '`', '(', ')', '{', '}', + '[', ']', '<', '>', '\n', '\r', '\0', '"', "'", + '\\', '!', '?', '*', '~', '^', '%', '=', '+', + '#', // Comment character that could hide commands + ]; + + foreach ($dangerousChars as $char) { + if (str_contains($value, $char)) { + Log::warning('Git repository URL validation failed - dangerous character', [ + 'url' => $value, + 'character' => $char, + 'ip' => request()->ip(), + 'user_id' => auth()->id(), + ]); + $fail('The :attribute contains invalid characters.'); + + return; + } + } + + // Check for command substitution patterns + $dangerousPatterns = [ + '/\$\(.*\)/', // Command substitution $(...) + '/\${.*}/', // Variable expansion ${...} + '/;;/', // Double semicolon + '/&&/', // Command chaining + '/\|\|/', // Command chaining + '/>>/', // Redirect append + '/<</', // Here document + '/\\\n/', // Line continuation + '/\.\.[\/\\\\]/', // Directory traversal + ]; + + foreach ($dangerousPatterns as $pattern) { + if (preg_match($pattern, $value)) { + Log::warning('Git repository URL validation failed - dangerous pattern', [ + 'url' => $value, + 'pattern' => $pattern, + 'ip' => request()->ip(), + 'user_id' => auth()->id(), + ]); + $fail('The :attribute contains invalid patterns.'); + + return; + } + } + + // Validate based on URL type + if (str_starts_with($value, 'git@')) { + if (! $this->allowSSH) { + $fail('SSH URLs are not allowed.'); + + return; + } + + // Validate SSH URL format (git@host:user/repo.git) + if (! preg_match('/^git@[a-zA-Z0-9\.\-]+:[a-zA-Z0-9\-_\/\.]+$/', $value)) { + $fail('The :attribute is not a valid SSH repository URL.'); + + return; + } + } elseif (str_starts_with($value, 'http://') || str_starts_with($value, 'https://')) { + // Validate HTTP(S) URL + if (! filter_var($value, FILTER_VALIDATE_URL)) { + $fail('The :attribute is not a valid URL.'); + + return; + } + + $parsed = parse_url($value); + + // Check for IP addresses if not allowed + if (! $this->allowIP && filter_var($parsed['host'] ?? '', FILTER_VALIDATE_IP)) { + Log::warning('Git repository URL contains IP address', [ + 'url' => $value, + 'ip' => request()->ip(), + 'user_id' => auth()->id(), + ]); + $fail('The :attribute cannot use IP addresses.'); + + return; + } + + // Check for localhost/internal addresses + $host = strtolower($parsed['host'] ?? ''); + $internalHosts = ['localhost', '127.0.0.1', '0.0.0.0', '::1']; + if (in_array($host, $internalHosts) || str_ends_with($host, '.local')) { + Log::warning('Git repository URL points to internal host', [ + 'url' => $value, + 'host' => $host, + 'ip' => request()->ip(), + 'user_id' => auth()->id(), + ]); + $fail('The :attribute cannot point to internal hosts.'); + + return; + } + + // Ensure no query parameters or fragments + if (! empty($parsed['query']) || ! empty($parsed['fragment'])) { + $fail('The :attribute should not contain query parameters or fragments.'); + + return; + } + + // Validate path contains only safe characters + $path = $parsed['path'] ?? ''; + if (! empty($path) && ! preg_match('/^[a-zA-Z0-9\-_\/\.]+$/', $path)) { + $fail('The :attribute path contains invalid characters.'); + + return; + } + } elseif (str_starts_with($value, 'git://')) { + // Validate git:// protocol URL + if (! preg_match('/^git:\/\/[a-zA-Z0-9\.\-]+\/[a-zA-Z0-9\-_\/\.]+$/', $value)) { + $fail('The :attribute is not a valid git:// URL.'); + + return; + } + } else { + $fail('The :attribute must start with https://, http://, git://, or git@.'); + + return; + } + } +} diff --git a/app/Rules/ValidIpOrCidr.php b/app/Rules/ValidIpOrCidr.php new file mode 100644 index 000000000..e172ffd1a --- /dev/null +++ b/app/Rules/ValidIpOrCidr.php @@ -0,0 +1,63 @@ +<?php + +namespace App\Rules; + +use Closure; +use Illuminate\Contracts\Validation\ValidationRule; + +class ValidIpOrCidr implements ValidationRule +{ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + if (empty($value)) { + // Empty is allowed (means allow from anywhere) + return; + } + + // Special case: 0.0.0.0 is allowed + if ($value === '0.0.0.0') { + return; + } + + $entries = explode(',', $value); + $invalidEntries = []; + + foreach ($entries as $entry) { + $entry = trim($entry); + + if (empty($entry)) { + continue; + } + + // Special case: 0.0.0.0 with or without subnet + if (str_starts_with($entry, '0.0.0.0')) { + continue; + } + + // Check if it's CIDR notation + if (str_contains($entry, '/')) { + $parts = explode('/', $entry); + if (count($parts) !== 2) { + $invalidEntries[] = $entry; + + continue; + } + + [$ip, $mask] = $parts; + + if (! filter_var($ip, FILTER_VALIDATE_IP) || ! is_numeric($mask) || $mask < 0 || $mask > 32) { + $invalidEntries[] = $entry; + } + } else { + // Check if it's a valid IP + if (! filter_var($entry, FILTER_VALIDATE_IP)) { + $invalidEntries[] = $entry; + } + } + } + + if (! empty($invalidEntries)) { + $fail('The following entries are not valid IP addresses or CIDR notations: '.implode(', ', $invalidEntries)); + } + } +} diff --git a/app/Services/ChangelogService.php b/app/Services/ChangelogService.php new file mode 100644 index 000000000..f0887c11c --- /dev/null +++ b/app/Services/ChangelogService.php @@ -0,0 +1,300 @@ +<?php + +namespace App\Services; + +use App\Models\User; +use App\Models\UserChangelogRead; +use Carbon\Carbon; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Log; +use Spatie\LaravelMarkdown\MarkdownRenderer; + +class ChangelogService +{ + public function getEntries(int $recentMonths = 3): Collection + { + // For backward compatibility, check if old changelog.json exists + if (file_exists(base_path('changelog.json'))) { + $data = $this->fetchChangelogData(); + + if (! $data || ! isset($data['entries'])) { + return collect(); + } + + return collect($data['entries']) + ->filter(fn ($entry) => $this->validateEntryData($entry)) + ->map(function ($entry) { + $entry['published_at'] = Carbon::parse($entry['published_at']); + $entry['content_html'] = $this->parseMarkdown($entry['content']); + + return (object) $entry; + }) + ->filter(fn ($entry) => $entry->published_at <= now()) + ->sortBy('published_at') + ->reverse() + ->values(); + } + + // Load entries from recent months for performance + $availableMonths = $this->getAvailableMonths(); + $monthsToLoad = $availableMonths->take($recentMonths); + + return $monthsToLoad + ->flatMap(fn ($month) => $this->getEntriesForMonth($month)) + ->sortBy('published_at') + ->reverse() + ->values(); + } + + public function getAllEntries(): Collection + { + $availableMonths = $this->getAvailableMonths(); + + return $availableMonths + ->flatMap(fn ($month) => $this->getEntriesForMonth($month)) + ->sortBy('published_at') + ->reverse() + ->values(); + } + + public function getEntriesForUser(User $user): Collection + { + $entries = $this->getEntries(); + $readIdentifiers = UserChangelogRead::getReadIdentifiersForUser($user->id); + + return $entries->map(function ($entry) use ($readIdentifiers) { + $entry->is_read = in_array($entry->tag_name, $readIdentifiers); + + return $entry; + })->sortBy([ + ['is_read', 'asc'], // unread first + ['published_at', 'desc'], // then by date + ])->values(); + } + + public function getUnreadCountForUser(User $user): int + { + if (isDev()) { + $entries = $this->getEntries(); + $readIdentifiers = UserChangelogRead::getReadIdentifiersForUser($user->id); + + return $entries->reject(fn ($entry) => in_array($entry->tag_name, $readIdentifiers))->count(); + } else { + return Cache::remember( + 'user_unread_changelog_count_'.$user->id, + now()->addHour(), + function () use ($user) { + $entries = $this->getEntries(); + $readIdentifiers = UserChangelogRead::getReadIdentifiersForUser($user->id); + + return $entries->reject(fn ($entry) => in_array($entry->tag_name, $readIdentifiers))->count(); + } + ); + } + } + + public function getAvailableMonths(): Collection + { + $pattern = base_path('changelogs/*.json'); + $files = glob($pattern); + + if ($files === false) { + return collect(); + } + + return collect($files) + ->map(fn ($file) => basename($file, '.json')) + ->filter(fn ($name) => preg_match('/^\d{4}-\d{2}$/', $name)) + ->sort() + ->reverse() + ->values(); + } + + public function getEntriesForMonth(string $month): Collection + { + $path = base_path("changelogs/{$month}.json"); + + if (! file_exists($path)) { + return collect(); + } + + $content = file_get_contents($path); + + if ($content === false) { + Log::error("Failed to read changelog file: {$month}.json"); + + return collect(); + } + + $data = json_decode($content, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + Log::error("Invalid JSON in {$month}.json: ".json_last_error_msg()); + + return collect(); + } + + if (! isset($data['entries']) || ! is_array($data['entries'])) { + return collect(); + } + + return collect($data['entries']) + ->filter(fn ($entry) => $this->validateEntryData($entry)) + ->map(function ($entry) { + $entry['published_at'] = Carbon::parse($entry['published_at']); + $entry['content_html'] = $this->parseMarkdown($entry['content']); + + return (object) $entry; + }) + ->filter(fn ($entry) => $entry->published_at <= now()) + ->sortBy('published_at') + ->reverse() + ->values(); + } + + private function fetchChangelogData(): ?array + { + // Legacy support for old changelog.json + $path = base_path('changelog.json'); + + if (file_exists($path)) { + $content = file_get_contents($path); + + if ($content === false) { + Log::error('Failed to read changelog.json file'); + + return null; + } + + $data = json_decode($content, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + Log::error('Invalid JSON in changelog.json: '.json_last_error_msg()); + + return null; + } + + return $data; + } + + // New monthly structure - combine all months + $allEntries = []; + foreach ($this->getAvailableMonths() as $month) { + $monthEntries = $this->getEntriesForMonth($month); + foreach ($monthEntries as $entry) { + $allEntries[] = (array) $entry; + } + } + + return ['entries' => $allEntries]; + } + + public function markAsReadForUser(string $version, User $user): void + { + UserChangelogRead::markAsRead($user->id, $version); + Cache::forget('user_unread_changelog_count_'.$user->id); + } + + public function markAllAsReadForUser(User $user): void + { + $entries = $this->getEntries(); + + foreach ($entries as $entry) { + UserChangelogRead::markAsRead($user->id, $entry->tag_name); + } + + Cache::forget('user_unread_changelog_count_'.$user->id); + } + + private function validateEntryData(array $data): bool + { + $required = ['tag_name', 'title', 'content', 'published_at']; + + foreach ($required as $field) { + if (! isset($data[$field]) || empty($data[$field])) { + return false; + } + } + + return true; + } + + public function clearAllReadStatus(): array + { + try { + $count = UserChangelogRead::count(); + UserChangelogRead::truncate(); + + // Clear all user caches + $this->clearAllUserCaches(); + + return [ + 'success' => true, + 'message' => "Successfully cleared {$count} read status records", + ]; + } catch (\Exception $e) { + Log::error('Failed to clear read status: '.$e->getMessage()); + + return [ + 'success' => false, + 'message' => 'Failed to clear read status: '.$e->getMessage(), + ]; + } + } + + private function clearAllUserCaches(): void + { + $users = User::select('id')->get(); + + foreach ($users as $user) { + Cache::forget('user_unread_changelog_count_'.$user->id); + } + } + + private function parseMarkdown(string $content): string + { + $renderer = app(MarkdownRenderer::class); + + $html = $renderer->toHtml($content); + + // Apply custom Tailwind CSS classes for dark mode compatibility + $html = $this->applyCustomStyling($html); + + return $html; + } + + private function applyCustomStyling(string $html): string + { + // Headers + $html = preg_replace('/<h1[^>]*>/', '<h1 class="text-xl font-bold dark:text-white mb-2">', $html); + $html = preg_replace('/<h2[^>]*>/', '<h2 class="text-lg font-semibold dark:text-white mb-2">', $html); + $html = preg_replace('/<h3[^>]*>/', '<h3 class="text-md font-semibold dark:text-white mb-1">', $html); + + // Paragraphs + $html = preg_replace('/<p[^>]*>/', '<p class="mb-2 dark:text-neutral-300">', $html); + + // Lists + $html = preg_replace('/<ul[^>]*>/', '<ul class="mb-2 ml-4 list-disc">', $html); + $html = preg_replace('/<ol[^>]*>/', '<ol class="mb-2 ml-4 list-decimal">', $html); + $html = preg_replace('/<li[^>]*>/', '<li class="dark:text-neutral-300">', $html); + + // Code blocks and inline code + $html = preg_replace('/<pre[^>]*>/', '<pre class="bg-gray-100 dark:bg-coolgray-300 p-2 rounded text-sm overflow-x-auto my-2">', $html); + $html = preg_replace('/<code[^>]*>/', '<code class="bg-gray-100 dark:bg-coolgray-300 px-1 py-0.5 rounded text-sm">', $html); + + // Links - Apply styling to existing markdown links + $html = preg_replace('/<a([^>]*)>/', '<a$1 class="text-blue-500 hover:text-blue-600 underline" target="_blank" rel="noopener">', $html); + + // Convert plain URLs to clickable links (that aren't already in <a> tags) + $html = preg_replace('/(?<!href="|href=\')(?<!>)(?<!\/)(https?:\/\/[^\s<>"]+)(?![^<]*<\/a>)/', '<a href="$1" class="text-blue-500 hover:text-blue-600 underline" target="_blank" rel="noopener">$1</a>', $html); + + // Strong/bold text + $html = preg_replace('/<strong[^>]*>/', '<strong class="font-semibold dark:text-white">', $html); + + // Emphasis/italic text + $html = preg_replace('/<em[^>]*>/', '<em class="italic dark:text-neutral-300">', $html); + + return $html; + } +} diff --git a/app/Support/ValidationPatterns.php b/app/Support/ValidationPatterns.php new file mode 100644 index 000000000..965142558 --- /dev/null +++ b/app/Support/ValidationPatterns.php @@ -0,0 +1,93 @@ +<?php + +namespace App\Support; + +/** + * Shared validation patterns for consistent use across the application + */ +class ValidationPatterns +{ + /** + * Pattern for names (allows letters, numbers, spaces, dashes, underscores, dots, slashes, colons, parentheses) + * Matches CleanupNames::sanitizeName() allowed characters + */ + public const NAME_PATTERN = '/^[a-zA-Z0-9\s\-_.:\/()]+$/'; + + /** + * Pattern for descriptions (allows more characters including quotes, commas, etc.) + * More permissive than names but still restricts dangerous characters + */ + public const DESCRIPTION_PATTERN = '/^[a-zA-Z0-9\s\-_.:\/()\'\",.!?@#%&+=\[\]{}|~`*]+$/'; + + /** + * Get validation rules for name fields + */ + public static function nameRules(bool $required = true, int $minLength = 3, int $maxLength = 255): array + { + $rules = []; + + if ($required) { + $rules[] = 'required'; + } else { + $rules[] = 'nullable'; + } + + $rules[] = 'string'; + $rules[] = "min:$minLength"; + $rules[] = "max:$maxLength"; + $rules[] = 'regex:'.self::NAME_PATTERN; + + return $rules; + } + + /** + * Get validation rules for description fields + */ + public static function descriptionRules(bool $required = false, int $maxLength = 255): array + { + $rules = []; + + if ($required) { + $rules[] = 'required'; + } else { + $rules[] = 'nullable'; + } + + $rules[] = 'string'; + $rules[] = "max:$maxLength"; + $rules[] = 'regex:'.self::DESCRIPTION_PATTERN; + + return $rules; + } + + /** + * Get validation messages for name fields + */ + public static function nameMessages(): array + { + return [ + 'name.regex' => 'The name may only contain letters, numbers, spaces, dashes (-), underscores (_), dots (.), slashes (/), colons (:), and parentheses ().', + 'name.min' => 'The name must be at least :min characters.', + 'name.max' => 'The name may not be greater than :max characters.', + ]; + } + + /** + * Get validation messages for description fields + */ + public static function descriptionMessages(): array + { + return [ + 'description.regex' => 'The description contains invalid characters. Only letters, numbers, spaces, and common punctuation (- _ . : / () \' " , ! ? @ # % & + = [] {} | ~ ` *) are allowed.', + 'description.max' => 'The description may not be greater than :max characters.', + ]; + } + + /** + * Get combined validation messages for both name and description fields + */ + public static function combinedMessages(): array + { + return array_merge(self::nameMessages(), self::descriptionMessages()); + } +} diff --git a/app/Traits/AuthorizesResourceCreation.php b/app/Traits/AuthorizesResourceCreation.php new file mode 100644 index 000000000..01ae7c8d9 --- /dev/null +++ b/app/Traits/AuthorizesResourceCreation.php @@ -0,0 +1,20 @@ +<?php + +namespace App\Traits; + +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; + +trait AuthorizesResourceCreation +{ + use AuthorizesRequests; + + /** + * Authorize creation of all supported resources. + * + * @throws \Illuminate\Auth\Access\AuthorizationException + */ + protected function authorizeResourceCreation(): void + { + $this->authorize('createAnyResource'); + } +} diff --git a/app/Traits/HasSafeStringAttribute.php b/app/Traits/HasSafeStringAttribute.php new file mode 100644 index 000000000..8a5d2ce77 --- /dev/null +++ b/app/Traits/HasSafeStringAttribute.php @@ -0,0 +1,25 @@ +<?php + +namespace App\Traits; + +trait HasSafeStringAttribute +{ + /** + * Set the name attribute - strip any HTML tags for safety + */ + public function setNameAttribute($value) + { + $sanitized = strip_tags($value); + $this->attributes['name'] = $this->customizeName($sanitized); + } + + protected function customizeName($value) + { + return $value; // Default: no customization + } + + public function setDescriptionAttribute($value) + { + $this->attributes['description'] = strip_tags($value); + } +} diff --git a/app/View/Components/Forms/Button.php b/app/View/Components/Forms/Button.php index bf88d3f88..b54444261 100644 --- a/app/View/Components/Forms/Button.php +++ b/app/View/Components/Forms/Button.php @@ -4,6 +4,7 @@ namespace App\View\Components\Forms; use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Facades\Gate; use Illuminate\View\Component; class Button extends Component @@ -17,7 +18,19 @@ class Button extends Component public ?string $modalId = null, public string $defaultClass = 'button', public bool $showLoadingIndicator = true, + public ?string $canGate = null, + public mixed $canResource = null, + public bool $autoDisable = true, ) { + // Handle authorization-based disabling + if ($this->canGate && $this->canResource && $this->autoDisable) { + $hasPermission = Gate::allows($this->canGate, $this->canResource); + + if (! $hasPermission) { + $this->disabled = true; + } + } + if ($this->noStyle) { $this->defaultClass = ''; } diff --git a/app/View/Components/Forms/Checkbox.php b/app/View/Components/Forms/Checkbox.php index 8db739642..ece7f0e35 100644 --- a/app/View/Components/Forms/Checkbox.php +++ b/app/View/Components/Forms/Checkbox.php @@ -4,6 +4,7 @@ namespace App\View\Components\Forms; use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Facades\Gate; use Illuminate\View\Component; class Checkbox extends Component @@ -22,7 +23,20 @@ class Checkbox extends Component public string|bool $instantSave = false, public bool $disabled = false, public string $defaultClass = 'dark:border-neutral-700 text-coolgray-400 focus:ring-warning dark:bg-coolgray-100 rounded-sm cursor-pointer dark:disabled:bg-base dark:disabled:cursor-not-allowed', + public ?string $canGate = null, + public mixed $canResource = null, + public bool $autoDisable = true, ) { + // Handle authorization-based disabling + if ($this->canGate && $this->canResource && $this->autoDisable) { + $hasPermission = Gate::allows($this->canGate, $this->canResource); + + if (! $hasPermission) { + $this->disabled = true; + $this->instantSave = false; // Disable instant save for unauthorized users + } + } + if ($this->disabled) { $this->defaultClass .= ' opacity-40'; } diff --git a/app/View/Components/Forms/Input.php b/app/View/Components/Forms/Input.php index 7283ef20f..83c98c0df 100644 --- a/app/View/Components/Forms/Input.php +++ b/app/View/Components/Forms/Input.php @@ -4,6 +4,7 @@ namespace App\View\Components\Forms; use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Facades\Gate; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; @@ -25,7 +26,20 @@ class Input extends Component public string $autocomplete = 'off', public ?int $minlength = null, public ?int $maxlength = null, - ) {} + public bool $autofocus = false, + public ?string $canGate = null, + public mixed $canResource = null, + public bool $autoDisable = true, + ) { + // Handle authorization-based disabling + if ($this->canGate && $this->canResource && $this->autoDisable) { + $hasPermission = Gate::allows($this->canGate, $this->canResource); + + if (! $hasPermission) { + $this->disabled = true; + } + } + } public function render(): View|Closure|string { diff --git a/app/View/Components/Forms/Select.php b/app/View/Components/Forms/Select.php index feb4bf343..49b69136b 100644 --- a/app/View/Components/Forms/Select.php +++ b/app/View/Components/Forms/Select.php @@ -4,6 +4,7 @@ namespace App\View\Components\Forms; use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Facades\Gate; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; @@ -19,9 +20,19 @@ class Select extends Component public ?string $helper = null, public bool $required = false, public bool $disabled = false, - public string $defaultClass = 'select w-full' + public string $defaultClass = 'select w-full', + public ?string $canGate = null, + public mixed $canResource = null, + public bool $autoDisable = true, ) { - // + // Handle authorization-based disabling + if ($this->canGate && $this->canResource && $this->autoDisable) { + $hasPermission = Gate::allows($this->canGate, $this->canResource); + + if (! $hasPermission) { + $this->disabled = true; + } + } } /** diff --git a/app/View/Components/Forms/Textarea.php b/app/View/Components/Forms/Textarea.php index 6081c2a8a..3148d2566 100644 --- a/app/View/Components/Forms/Textarea.php +++ b/app/View/Components/Forms/Textarea.php @@ -4,6 +4,7 @@ namespace App\View\Components\Forms; use Closure; use Illuminate\Contracts\View\View; +use Illuminate\Support\Facades\Gate; use Illuminate\View\Component; use Visus\Cuid2\Cuid2; @@ -33,8 +34,18 @@ class Textarea extends Component public string $defaultClassInput = 'input', public ?int $minlength = null, public ?int $maxlength = null, + public ?string $canGate = null, + public mixed $canResource = null, + public bool $autoDisable = true, ) { - // + // Handle authorization-based disabling + if ($this->canGate && $this->canResource && $this->autoDisable) { + $hasPermission = Gate::allows($this->canGate, $this->canResource); + + if (! $hasPermission) { + $this->disabled = true; + } + } } /** diff --git a/backlog/config.yml b/backlog/config.yml new file mode 100644 index 000000000..42af39aa7 --- /dev/null +++ b/backlog/config.yml @@ -0,0 +1,16 @@ +project_name: "Coolify" +default_status: "To Do" +statuses: ["To Do", "In Progress", "Done"] +labels: [] +milestones: [] +date_format: yyyy-mm-dd +max_column_width: 20 +default_editor: "vim" +auto_open_browser: true +default_port: 6420 +remote_operations: true +auto_commit: false +zero_padded_ids: 5 +bypass_git_hooks: true +check_active_branches: true +active_branch_days: 30 diff --git a/backlog/tasks/task-00001 - Implement-Docker-build-caching-for-Coolify-staging-builds.md b/backlog/tasks/task-00001 - Implement-Docker-build-caching-for-Coolify-staging-builds.md new file mode 100644 index 000000000..13a0a9c94 --- /dev/null +++ b/backlog/tasks/task-00001 - Implement-Docker-build-caching-for-Coolify-staging-builds.md @@ -0,0 +1,58 @@ +--- +id: task-00001 +title: Implement Docker build caching for Coolify staging builds +status: To Do +assignee: [] +created_date: '2025-08-26 12:15' +updated_date: '2025-08-26 12:16' +labels: + - heyandras + - performance + - docker + - ci-cd + - build-optimization +dependencies: [] +priority: high +--- + +## Description + +Implement comprehensive Docker build caching to reduce staging build times by 50-70% through BuildKit cache mounts for dependencies and GitHub Actions registry caching. This optimization will significantly reduce build times from ~10-15 minutes to ~3-5 minutes, decrease network usage, and lower GitHub Actions costs. + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 Docker BuildKit cache mounts are added to Composer dependency installation in production Dockerfile +- [ ] #2 Docker BuildKit cache mounts are added to NPM dependency installation in production Dockerfile +- [ ] #3 GitHub Actions BuildX setup is configured for both AMD64 and AARCH64 jobs +- [ ] #4 Registry cache-from and cache-to configurations are implemented for both architecture builds +- [ ] #5 Build time reduction of at least 40% is achieved in staging builds +- [ ] #6 GitHub Actions minutes consumption is reduced compared to baseline +- [ ] #7 All existing build functionality remains intact with no regressions +<!-- AC:END --> + +## Implementation Plan + +1. Modify docker/production/Dockerfile to add BuildKit cache mounts: + - Add cache mount for Composer dependencies at line 30: --mount=type=cache,target=/var/www/.composer/cache + - Add cache mount for NPM dependencies at line 41: --mount=type=cache,target=/root/.npm + +2. Update .github/workflows/coolify-staging-build.yml for AMD64 job: + - Add docker/setup-buildx-action@v3 step after checkout + - Configure cache-from and cache-to parameters in build-push-action + - Use registry caching with buildcache-amd64 tags + +3. Update .github/workflows/coolify-staging-build.yml for AARCH64 job: + - Add docker/setup-buildx-action@v3 step after checkout + - Configure cache-from and cache-to parameters in build-push-action + - Use registry caching with buildcache-aarch64 tags + +4. Test implementation: + - Measure baseline build times before changes + - Deploy changes and monitor initial build (will be slower due to cache population) + - Measure subsequent build times to verify 40%+ improvement + - Validate all build outputs and functionality remain unchanged + +5. Monitor and validate: + - Track GitHub Actions minutes consumption reduction + - Ensure Docker registry storage usage is reasonable + - Verify no build failures or regressions introduced diff --git a/backlog/tasks/task-00001.01 - Add-BuildKit-cache-mounts-to-Dockerfile.md b/backlog/tasks/task-00001.01 - Add-BuildKit-cache-mounts-to-Dockerfile.md new file mode 100644 index 000000000..93fa3e431 --- /dev/null +++ b/backlog/tasks/task-00001.01 - Add-BuildKit-cache-mounts-to-Dockerfile.md @@ -0,0 +1,24 @@ +--- +id: task-00001.01 +title: Add BuildKit cache mounts to Dockerfile +status: To Do +assignee: [] +created_date: '2025-08-26 12:19' +labels: + - docker + - buildkit + - performance + - dockerfile +dependencies: [] +parent_task_id: task-00001 +priority: high +--- + +## Description + +Modify the production Dockerfile to include BuildKit cache mounts for Composer and NPM dependencies to speed up subsequent builds by reusing cached dependency installations + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 Cache mount for Composer dependencies is added at line 30 with --mount=type=cache target=/var/www/.composer/cache,Cache mount for NPM dependencies is added at line 41 with --mount=type=cache target=/root/.npm,Dockerfile syntax remains valid and builds successfully,All existing functionality is preserved with no regressions +<!-- AC:END --> diff --git a/backlog/tasks/task-00001.02 - Configure-BuildX-and-registry-caching-for-AMD64-staging-builds.md b/backlog/tasks/task-00001.02 - Configure-BuildX-and-registry-caching-for-AMD64-staging-builds.md new file mode 100644 index 000000000..60ac514f6 --- /dev/null +++ b/backlog/tasks/task-00001.02 - Configure-BuildX-and-registry-caching-for-AMD64-staging-builds.md @@ -0,0 +1,24 @@ +--- +id: task-00001.02 +title: Configure BuildX and registry caching for AMD64 staging builds +status: To Do +assignee: [] +created_date: '2025-08-26 12:19' +labels: + - github-actions + - buildx + - caching + - amd64 +dependencies: [] +parent_task_id: task-00001 +priority: high +--- + +## Description + +Update the GitHub Actions workflow to add BuildX setup and configure registry-based caching for the AMD64 build job to leverage Docker layer caching across builds + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 docker/setup-buildx-action@v3 step is added after checkout in AMD64 job,Registry cache configuration is added to build-push-action with cache-from and cache-to parameters,Cache tags use buildcache-amd64 naming convention for architecture-specific caching,Build job runs successfully with caching enabled,No impact on existing build outputs or functionality +<!-- AC:END --> diff --git a/backlog/tasks/task-00001.03 - Configure-BuildX-and-registry-caching-for-AARCH64-staging-builds.md b/backlog/tasks/task-00001.03 - Configure-BuildX-and-registry-caching-for-AARCH64-staging-builds.md new file mode 100644 index 000000000..3dd730d34 --- /dev/null +++ b/backlog/tasks/task-00001.03 - Configure-BuildX-and-registry-caching-for-AARCH64-staging-builds.md @@ -0,0 +1,25 @@ +--- +id: task-00001.03 +title: Configure BuildX and registry caching for AARCH64 staging builds +status: To Do +assignee: [] +created_date: '2025-08-26 12:19' +labels: + - github-actions + - buildx + - caching + - aarch64 + - self-hosted +dependencies: [] +parent_task_id: task-00001 +priority: high +--- + +## Description + +Update the GitHub Actions workflow to add BuildX setup and configure registry-based caching for the AARCH64 build job running on self-hosted ARM64 runners + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 docker/setup-buildx-action@v3 step is added after checkout in AARCH64 job,Registry cache configuration is added to build-push-action with cache-from and cache-to parameters,Cache tags use buildcache-aarch64 naming convention for architecture-specific caching,Build job runs successfully on self-hosted ARM64 runner with caching enabled,No impact on existing build outputs or functionality +<!-- AC:END --> diff --git a/backlog/tasks/task-00001.04 - Establish-build-time-baseline-measurements.md b/backlog/tasks/task-00001.04 - Establish-build-time-baseline-measurements.md new file mode 100644 index 000000000..6fa997663 --- /dev/null +++ b/backlog/tasks/task-00001.04 - Establish-build-time-baseline-measurements.md @@ -0,0 +1,24 @@ +--- +id: task-00001.04 +title: Establish build time baseline measurements +status: To Do +assignee: [] +created_date: '2025-08-26 12:19' +labels: + - performance + - testing + - baseline + - measurement +dependencies: [] +parent_task_id: task-00001 +priority: medium +--- + +## Description + +Measure and document current staging build times for both AMD64 and AARCH64 architectures before implementing caching optimizations to establish a performance baseline for comparison + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 Baseline build times are measured for at least 3 consecutive AMD64 builds,Baseline build times are measured for at least 3 consecutive AARCH64 builds,Average build time and GitHub Actions minutes consumption are documented,Baseline measurements include both cold builds and any existing warm builds,Results are documented in a format suitable for comparing against post-optimization builds +<!-- AC:END --> diff --git a/backlog/tasks/task-00001.05 - Validate-caching-implementation-and-measure-performance-improvements.md b/backlog/tasks/task-00001.05 - Validate-caching-implementation-and-measure-performance-improvements.md new file mode 100644 index 000000000..6a11168da --- /dev/null +++ b/backlog/tasks/task-00001.05 - Validate-caching-implementation-and-measure-performance-improvements.md @@ -0,0 +1,28 @@ +--- +id: task-00001.05 +title: Validate caching implementation and measure performance improvements +status: To Do +assignee: [] +created_date: '2025-08-26 12:19' +labels: + - testing + - performance + - validation + - measurement +dependencies: + - task-00001.01 + - task-00001.02 + - task-00001.03 + - task-00001.04 +parent_task_id: task-00001 +priority: high +--- + +## Description + +Test the complete Docker build caching implementation by running multiple staging builds and measuring performance improvements to ensure the 40% build time reduction target is achieved + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 First build after cache implementation runs successfully (expected slower due to cache population),Second and subsequent builds show significant time reduction compared to baseline,Build time reduction of at least 40% is achieved and documented,GitHub Actions minutes consumption is reduced compared to baseline measurements,All Docker images function identically to pre-optimization builds,No build failures or regressions are introduced by caching changes +<!-- AC:END --> diff --git a/backlog/tasks/task-00001.06 - Document-cache-optimization-results-and-create-production-workflow-plan.md b/backlog/tasks/task-00001.06 - Document-cache-optimization-results-and-create-production-workflow-plan.md new file mode 100644 index 000000000..3749e58f3 --- /dev/null +++ b/backlog/tasks/task-00001.06 - Document-cache-optimization-results-and-create-production-workflow-plan.md @@ -0,0 +1,25 @@ +--- +id: task-00001.06 +title: Document cache optimization results and create production workflow plan +status: To Do +assignee: [] +created_date: '2025-08-26 12:19' +labels: + - documentation + - planning + - production + - analysis +dependencies: + - task-00001.05 +parent_task_id: task-00001 +priority: low +--- + +## Description + +Document the staging build caching results and create a detailed plan for applying the same optimizations to the production build workflow if staging results meet performance targets + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 Performance improvement results are documented with before/after metrics,Cost savings in GitHub Actions minutes are calculated and documented,Analysis of Docker registry storage impact is provided,Detailed plan for production workflow optimization is created,Recommendations for cache retention policies and cleanup strategies are provided,Documentation includes rollback procedures if issues arise +<!-- AC:END --> diff --git a/backlog/tasks/task-00002 - Fix-Docker-cleanup-irregular-scheduling-in-cloud-environment.md b/backlog/tasks/task-00002 - Fix-Docker-cleanup-irregular-scheduling-in-cloud-environment.md new file mode 100644 index 000000000..d0e63456b --- /dev/null +++ b/backlog/tasks/task-00002 - Fix-Docker-cleanup-irregular-scheduling-in-cloud-environment.md @@ -0,0 +1,82 @@ +--- +id: task-00002 +title: Fix Docker cleanup irregular scheduling in cloud environment +status: Done +assignee: + - '@claude' +created_date: '2025-08-26 12:17' +updated_date: '2025-08-26 12:26' +labels: + - backend + - performance + - cloud +dependencies: [] +priority: high +--- + +## Description + +Docker cleanup jobs are running at irregular intervals instead of hourly as configured (0 * * * *) in the cloud environment with 2 Horizon workers and thousands of servers. The issue stems from the ServerManagerJob processing servers sequentially with a frozen execution time, causing timing mismatches when evaluating cron expressions for large server counts. + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [x] #1 Docker cleanup runs consistently at the configured hourly intervals +- [x] #2 All eligible servers receive cleanup jobs when due +- [x] #3 Solution handles thousands of servers efficiently +- [x] #4 Maintains backwards compatibility with existing settings +- [x] #5 Cloud subscription checks are properly enforced +<!-- AC:END --> + +## Implementation Plan + +1. Add processDockerCleanups() method to ScheduledJobManager + - Implement method to fetch all eligible servers + - Apply frozen execution time for consistent cron evaluation + - Check server functionality and cloud subscription status + - Dispatch DockerCleanupJob for servers where cleanup is due + +2. Implement helper methods in ScheduledJobManager + - getServersForCleanup(): Fetch servers with proper cloud/self-hosted filtering + - shouldProcessDockerCleanup(): Validate server eligibility + - Reuse existing shouldRunNow() method with frozen execution time + +3. Remove Docker cleanup logic from ServerManagerJob + - Delete lines 136-150 that handle Docker cleanup scheduling + - Keep other server management tasks intact + +4. Test the implementation + - Verify hourly execution with test servers + - Check timezone handling + - Validate cloud subscription filtering + - Monitor for duplicate job prevention via WithoutOverlapping middleware + +5. Deploy strategy + - First deploy updated ScheduledJobManager + - Monitor logs for successful hourly executions + - Once confirmed, remove cleanup from ServerManagerJob + - No database migrations required + +## Implementation Notes + +Successfully migrated Docker cleanup scheduling from ServerManagerJob to ScheduledJobManager. + +**Changes Made:** +1. Added processDockerCleanups() method to ScheduledJobManager that processes all servers with a single frozen execution time +2. Implemented getServersForCleanup() to fetch servers with proper cloud/self-hosted filtering +3. Implemented shouldProcessDockerCleanup() for server eligibility validation +4. Removed Docker cleanup logic from ServerManagerJob (lines 136-150) + +**Key Improvements:** +- All servers now evaluated against the same timestamp, ensuring consistent hourly execution +- Proper cloud subscription checks maintained +- Backwards compatible - no database migrations or settings changes required +- Follows the same proven pattern used for database backups + +**Files Modified:** +- app/Jobs/ScheduledJobManager.php: Added Docker cleanup processing +- app/Jobs/ServerManagerJob.php: Removed Docker cleanup logic + +**Testing:** +- Syntax validation passed +- Code formatting verified with Laravel Pint +- PHPStan analysis completed (existing warnings unrelated to changes) diff --git a/backlog/tasks/task-00003 - Simplify-resource-operations-UI-replace-boxes-with-dropdown-selections.md b/backlog/tasks/task-00003 - Simplify-resource-operations-UI-replace-boxes-with-dropdown-selections.md new file mode 100644 index 000000000..38aa18209 --- /dev/null +++ b/backlog/tasks/task-00003 - Simplify-resource-operations-UI-replace-boxes-with-dropdown-selections.md @@ -0,0 +1,30 @@ +--- +id: task-00003 +title: Simplify resource operations UI - replace boxes with dropdown selections +status: To Do +assignee: [] +created_date: '2025-08-26 13:22' +updated_date: '2025-08-26 13:22' +labels: + - ui + - frontend + - livewire +dependencies: [] +priority: medium +--- + +## Description + +Replace the current box-based layout in resource-operations.blade.php with clean dropdown selections to improve UX when there are many servers, projects, or environments. The current interface becomes overwhelming and cluttered with multiple modal confirmation boxes for each option. + +## Acceptance Criteria +<!-- AC:BEGIN --> +- [ ] #1 Clone section shows a dropdown to select server/destination instead of multiple boxes +- [ ] #2 Move section shows a dropdown to select project/environment instead of multiple boxes +- [ ] #3 Single "Clone Resource" button that triggers modal after dropdown selection +- [ ] #4 Single "Move Resource" button that triggers modal after dropdown selection +- [ ] #5 Authorization warnings remain in place for users without permissions +- [ ] #6 All existing functionality preserved (cloning, moving, success messages) +- [ ] #7 Clean, simple interface that scales well with many options +- [ ] #8 Mobile-friendly dropdown interface +<!-- AC:END --> diff --git a/bootstrap/helpers/databases.php b/bootstrap/helpers/databases.php index 48962f89c..5dbd46b5e 100644 --- a/bootstrap/helpers/databases.php +++ b/bootstrap/helpers/databases.php @@ -237,11 +237,18 @@ function removeOldBackups($backup): void { try { if ($backup->executions) { - $localBackupsToDelete = deleteOldBackupsLocally($backup); - if ($localBackupsToDelete->isNotEmpty()) { + // If local backup is disabled, mark all executions as having local storage deleted + if ($backup->disable_local_backup && $backup->save_s3) { $backup->executions() - ->whereIn('id', $localBackupsToDelete->pluck('id')) + ->where('local_storage_deleted', false) ->update(['local_storage_deleted' => true]); + } else { + $localBackupsToDelete = deleteOldBackupsLocally($backup); + if ($localBackupsToDelete->isNotEmpty()) { + $backup->executions() + ->whereIn('id', $localBackupsToDelete->pluck('id')) + ->update(['local_storage_deleted' => true]); + } } } @@ -254,10 +261,18 @@ function removeOldBackups($backup): void } } - $backup->executions() - ->where('local_storage_deleted', true) - ->where('s3_storage_deleted', true) - ->delete(); + // Delete executions where both local and S3 storage are marked as deleted + // or where only S3 is enabled and S3 storage is deleted + if ($backup->disable_local_backup && $backup->save_s3) { + $backup->executions() + ->where('s3_storage_deleted', true) + ->delete(); + } else { + $backup->executions() + ->where('local_storage_deleted', true) + ->where('s3_storage_deleted', true) + ->delete(); + } } catch (\Exception $e) { throw $e; diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index 944c51e3c..1737ca714 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -256,12 +256,12 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource) if (str($MINIO_BROWSER_REDIRECT_URL->value ?? '')->isEmpty()) { $MINIO_BROWSER_REDIRECT_URL->update([ - 'value' => generateFqdn($server, 'console-'.$uuid, true), + 'value' => generateFqdn(server: $server, random: 'console-'.$uuid, parserVersion: $resource->compose_parsing_version, forceHttps: true), ]); } if (str($MINIO_SERVER_URL->value ?? '')->isEmpty()) { $MINIO_SERVER_URL->update([ - 'value' => generateFqdn($server, 'minio-'.$uuid, true), + 'value' => generateFqdn(server: $server, random: 'minio-'.$uuid, parserVersion: $resource->compose_parsing_version, forceHttps: true), ]); } $payload = collect([ @@ -279,12 +279,12 @@ function generateServiceSpecificFqdns(ServiceApplication|Application $resource) if (str($LOGTO_ENDPOINT->value ?? '')->isEmpty()) { $LOGTO_ENDPOINT->update([ - 'value' => generateFqdn($server, 'logto-'.$uuid), + 'value' => generateFqdn(server: $server, random: 'logto-'.$uuid, parserVersion: $resource->compose_parsing_version), ]); } if (str($LOGTO_ADMIN_ENDPOINT->value ?? '')->isEmpty()) { $LOGTO_ADMIN_ENDPOINT->update([ - 'value' => generateFqdn($server, 'logto-admin-'.$uuid), + 'value' => generateFqdn(server: $server, random: 'logto-admin-'.$uuid, parserVersion: $resource->compose_parsing_version), ]); } $payload = collect([ @@ -1101,7 +1101,7 @@ function getContainerLogs(Server $server, string $container_id, int $lines = 100 ], $server); } - $output .= removeAnsiColors($output); + $output = removeAnsiColors($output); return $output; } diff --git a/bootstrap/helpers/parsers.php b/bootstrap/helpers/parsers.php new file mode 100644 index 000000000..f35e73390 --- /dev/null +++ b/bootstrap/helpers/parsers.php @@ -0,0 +1,1772 @@ +<?php + +use App\Enums\ProxyTypes; +use App\Jobs\ServerFilesFromServerJob; +use App\Models\Application; +use App\Models\ApplicationPreview; +use App\Models\LocalFileVolume; +use App\Models\LocalPersistentVolume; +use App\Models\Service; +use App\Models\ServiceApplication; +use App\Models\ServiceDatabase; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\File; +use Illuminate\Support\Str; +use Spatie\Url\Url; +use Symfony\Component\Yaml\Yaml; +use Visus\Cuid2\Cuid2; + +function applicationParser(Application $resource, int $pull_request_id = 0, ?int $preview_id = null): Collection +{ + $uuid = data_get($resource, 'uuid'); + $compose = data_get($resource, 'docker_compose_raw'); + if (! $compose) { + return collect([]); + } + + $pullRequestId = $pull_request_id; + $isPullRequest = $pullRequestId == 0 ? false : true; + $server = data_get($resource, 'destination.server'); + $fileStorages = $resource->fileStorages(); + + try { + $yaml = Yaml::parse($compose); + } catch (\Exception) { + return collect([]); + } + $services = data_get($yaml, 'services', collect([])); + $topLevel = collect([ + 'volumes' => collect(data_get($yaml, 'volumes', [])), + 'networks' => collect(data_get($yaml, 'networks', [])), + 'configs' => collect(data_get($yaml, 'configs', [])), + 'secrets' => collect(data_get($yaml, 'secrets', [])), + ]); + // If there are predefined volumes, make sure they are not null + if ($topLevel->get('volumes')->count() > 0) { + $temp = collect([]); + foreach ($topLevel['volumes'] as $volumeName => $volume) { + if (is_null($volume)) { + continue; + } + $temp->put($volumeName, $volume); + } + $topLevel['volumes'] = $temp; + } + // Get the base docker network + $baseNetwork = collect([$uuid]); + if ($isPullRequest) { + $baseNetwork = collect(["{$uuid}-{$pullRequestId}"]); + } + + $parsedServices = collect([]); + + $allMagicEnvironments = collect([]); + foreach ($services as $serviceName => $service) { + $magicEnvironments = collect([]); + $image = data_get_str($service, 'image'); + $environment = collect(data_get($service, 'environment', [])); + $buildArgs = collect(data_get($service, 'build.args', [])); + $environment = $environment->merge($buildArgs); + + $environment = collect(data_get($service, 'environment', [])); + $buildArgs = collect(data_get($service, 'build.args', [])); + $environment = $environment->merge($buildArgs); + + // convert environment variables to one format + $environment = convertToKeyValueCollection($environment); + + // Add Coolify defined environments + $allEnvironments = $resource->environment_variables()->get(['key', 'value']); + + $allEnvironments = $allEnvironments->mapWithKeys(function ($item) { + return [$item['key'] => $item['value']]; + }); + // filter and add magic environments + foreach ($environment as $key => $value) { + // Get all SERVICE_ variables from keys and values + $key = str($key); + $value = str($value); + $regex = '/\$(\{?([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\}?)/'; + preg_match_all($regex, $value, $valueMatches); + if (count($valueMatches[1]) > 0) { + foreach ($valueMatches[1] as $match) { + $match = replaceVariables($match); + if ($match->startsWith('SERVICE_')) { + if ($magicEnvironments->has($match->value())) { + continue; + } + $magicEnvironments->put($match->value(), ''); + } + } + } + // Get magic environments where we need to preset the FQDN + // for example SERVICE_FQDN_APP_3000 (without a value) + if ($key->startsWith('SERVICE_FQDN_')) { + // SERVICE_FQDN_APP or SERVICE_FQDN_APP_3000 + if (substr_count(str($key)->value(), '_') === 3) { + $fqdnFor = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower()->value(); + $port = $key->afterLast('_')->value(); + } else { + $fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value(); + $port = null; + } + $fqdn = $resource->fqdn; + if (blank($resource->fqdn)) { + $fqdn = generateFqdn(server: $server, random: "$uuid", parserVersion: $resource->compose_parsing_version); + } + + if ($value && get_class($value) === \Illuminate\Support\Stringable::class && $value->startsWith('/')) { + $path = $value->value(); + if ($path !== '/') { + $fqdn = "$fqdn$path"; + } + } + $fqdnWithPort = $fqdn; + if ($port) { + $fqdnWithPort = "$fqdn:$port"; + } + if (is_null($resource->fqdn)) { + data_forget($resource, 'environment_variables'); + data_forget($resource, 'environment_variables_preview'); + $resource->fqdn = $fqdnWithPort; + $resource->save(); + } + + if (substr_count(str($key)->value(), '_') === 2) { + $resource->environment_variables()->updateOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $fqdn, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } + if (substr_count(str($key)->value(), '_') === 3) { + + $newKey = str($key)->beforeLast('_'); + $resource->environment_variables()->updateOrCreate([ + 'key' => $newKey->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $fqdn, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } + } + } + + $allMagicEnvironments = $allMagicEnvironments->merge($magicEnvironments); + if ($magicEnvironments->count() > 0) { + // Generate Coolify environment variables + foreach ($magicEnvironments as $key => $value) { + $key = str($key); + $value = replaceVariables($value); + $command = parseCommandFromMagicEnvVariable($key); + if ($command->value() === 'FQDN') { + $fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value(); + $originalFqdnFor = str($fqdnFor)->replace('_', '-'); + if (str($fqdnFor)->contains('-')) { + $fqdnFor = str($fqdnFor)->replace('-', '_'); + } + // Generated FQDN & URL + $fqdn = generateFqdn(server: $server, random: "$originalFqdnFor-$uuid", parserVersion: $resource->compose_parsing_version); + $url = generateUrl(server: $server, random: "$originalFqdnFor-$uuid"); + $resource->environment_variables()->firstOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $fqdn, + 'is_build_time' => false, + 'is_preview' => false, + ]); + if ($resource->build_pack === 'dockercompose') { + $domains = collect(json_decode(data_get($resource, 'docker_compose_domains'))) ?? collect([]); + $domainExists = data_get($domains->get($fqdnFor), 'domain'); + $envExists = $resource->environment_variables()->where('key', $key->value())->first(); + if (str($domainExists)->replace('http://', '')->replace('https://', '')->value() !== $envExists->value) { + $envExists->update([ + 'value' => $url, + ]); + } + if (is_null($domainExists)) { + // Put URL in the domains array instead of FQDN + $domains->put((string) $fqdnFor, [ + 'domain' => $url, + ]); + $resource->docker_compose_domains = $domains->toJson(); + $resource->save(); + } + } + } elseif ($command->value() === 'URL') { + $urlFor = $key->after('SERVICE_URL_')->lower()->value(); + $originalUrlFor = str($urlFor)->replace('_', '-'); + if (str($urlFor)->contains('-')) { + $urlFor = str($urlFor)->replace('-', '_'); + } + $url = generateUrl(server: $server, random: "$originalUrlFor-$uuid"); + $resource->environment_variables()->firstOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $url, + 'is_build_time' => false, + 'is_preview' => false, + ]); + if ($resource->build_pack === 'dockercompose') { + $domains = collect(json_decode(data_get($resource, 'docker_compose_domains'))) ?? collect([]); + $domainExists = data_get($domains->get($urlFor), 'domain'); + $envExists = $resource->environment_variables()->where('key', $key->value())->first(); + if ($domainExists !== $envExists->value) { + $envExists->update([ + 'value' => $url, + ]); + } + if (is_null($domainExists)) { + $domains->put((string) $urlFor, [ + 'domain' => $url, + ]); + $resource->docker_compose_domains = $domains->toJson(); + $resource->save(); + } + } + } else { + $value = generateEnvValue($command, $resource); + $resource->environment_variables()->firstOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $value, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } + } + } + } + + // Parse the rest of the services + foreach ($services as $serviceName => $service) { + $image = data_get_str($service, 'image'); + $restart = data_get_str($service, 'restart', RESTART_MODE); + $logging = data_get($service, 'logging'); + + if ($server->isLogDrainEnabled()) { + if ($resource->isLogDrainEnabled()) { + $logging = generate_fluentd_configuration(); + } + } + $volumes = collect(data_get($service, 'volumes', [])); + $networks = collect(data_get($service, 'networks', [])); + $use_network_mode = data_get($service, 'network_mode') !== null; + $depends_on = collect(data_get($service, 'depends_on', [])); + $labels = collect(data_get($service, 'labels', [])); + if ($labels->count() > 0) { + if (isAssociativeArray($labels)) { + $newLabels = collect([]); + $labels->each(function ($value, $key) use ($newLabels) { + $newLabels->push("$key=$value"); + }); + $labels = $newLabels; + } + } + $environment = collect(data_get($service, 'environment', [])); + $ports = collect(data_get($service, 'ports', [])); + $buildArgs = collect(data_get($service, 'build.args', [])); + $environment = $environment->merge($buildArgs); + + $environment = convertToKeyValueCollection($environment); + $coolifyEnvironments = collect([]); + + $isDatabase = isDatabaseImage($image, $service); + $volumesParsed = collect([]); + + $baseName = generateApplicationContainerName( + application: $resource, + pull_request_id: $pullRequestId + ); + $containerName = "$serviceName-$baseName"; + $predefinedPort = null; + + $originalResource = $resource; + + if ($volumes->count() > 0) { + foreach ($volumes as $index => $volume) { + $type = null; + $source = null; + $target = null; + $content = null; + $isDirectory = false; + if (is_string($volume)) { + $source = str($volume)->beforeLast(':'); + $target = str($volume)->afterLast(':'); + $foundConfig = $fileStorages->whereMountPath($target)->first(); + if (sourceIsLocal($source)) { + $type = str('bind'); + if ($foundConfig) { + $contentNotNull_temp = data_get($foundConfig, 'content'); + if ($contentNotNull_temp) { + $content = $contentNotNull_temp; + } + $isDirectory = data_get($foundConfig, 'is_directory'); + } else { + // By default, we cannot determine if the bind is a directory or not, so we set it to directory + $isDirectory = true; + } + } else { + $type = str('volume'); + } + } elseif (is_array($volume)) { + $type = data_get_str($volume, 'type'); + $source = data_get_str($volume, 'source'); + $target = data_get_str($volume, 'target'); + $content = data_get($volume, 'content'); + $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); + + $foundConfig = $fileStorages->whereMountPath($target)->first(); + if ($foundConfig) { + $contentNotNull_temp = data_get($foundConfig, 'content'); + if ($contentNotNull_temp) { + $content = $contentNotNull_temp; + } + $isDirectory = data_get($foundConfig, 'is_directory'); + } else { + // if isDirectory is not set (or false) & content is also not set, we assume it is a directory + if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) { + $isDirectory = true; + } + } + } + if ($type->value() === 'bind') { + if ($source->value() === '/var/run/docker.sock') { + $volume = $source->value().':'.$target->value(); + } elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') { + $volume = $source->value().':'.$target->value(); + } else { + if ((int) $resource->compose_parsing_version >= 4) { + $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid); + } else { + $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid); + } + $source = replaceLocalSource($source, $mainDirectory); + if ($isPullRequest) { + $source = $source."-pr-$pullRequestId"; + } + LocalFileVolume::updateOrCreate( + [ + 'mount_path' => $target, + 'resource_id' => $originalResource->id, + 'resource_type' => get_class($originalResource), + ], + [ + 'fs_path' => $source, + 'mount_path' => $target, + 'content' => $content, + 'is_directory' => $isDirectory, + 'resource_id' => $originalResource->id, + 'resource_type' => get_class($originalResource), + ] + ); + if (isDev()) { + if ((int) $resource->compose_parsing_version >= 4) { + $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/'.$uuid); + } else { + $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/'.$uuid); + } + } + $volume = "$source:$target"; + } + } elseif ($type->value() === 'volume') { + if ($topLevel->get('volumes')->has($source->value())) { + $temp = $topLevel->get('volumes')->get($source->value()); + if (data_get($temp, 'driver_opts.type') === 'cifs') { + continue; + } + if (data_get($temp, 'driver_opts.type') === 'nfs') { + continue; + } + } + $slugWithoutUuid = Str::slug($source, '-'); + $name = "{$uuid}_{$slugWithoutUuid}"; + + if ($isPullRequest) { + $name = "{$name}-pr-$pullRequestId"; + } + if (is_string($volume)) { + $source = str($volume)->beforeLast(':'); + $target = str($volume)->afterLast(':'); + $source = $name; + $volume = "$source:$target"; + } elseif (is_array($volume)) { + data_set($volume, 'source', $name); + } + $topLevel->get('volumes')->put($name, [ + 'name' => $name, + ]); + LocalPersistentVolume::updateOrCreate( + [ + 'name' => $name, + 'resource_id' => $originalResource->id, + 'resource_type' => get_class($originalResource), + ], + [ + 'name' => $name, + 'mount_path' => $target, + 'resource_id' => $originalResource->id, + 'resource_type' => get_class($originalResource), + ] + ); + } + dispatch(new ServerFilesFromServerJob($originalResource)); + $volumesParsed->put($index, $volume); + } + } + + if ($depends_on?->count() > 0) { + if ($isPullRequest) { + $newDependsOn = collect([]); + $depends_on->each(function ($dependency, $condition) use ($pullRequestId, $newDependsOn) { + if (is_numeric($condition)) { + $dependency = "$dependency-pr-$pullRequestId"; + + $newDependsOn->put($condition, $dependency); + } else { + $condition = "$condition-pr-$pullRequestId"; + $newDependsOn->put($condition, $dependency); + } + }); + $depends_on = $newDependsOn; + } + } + if (! $use_network_mode) { + if ($topLevel->get('networks')?->count() > 0) { + foreach ($topLevel->get('networks') as $networkName => $network) { + if ($networkName === 'default') { + continue; + } + // ignore aliases + if ($network['aliases'] ?? false) { + continue; + } + $networkExists = $networks->contains(function ($value, $key) use ($networkName) { + return $value == $networkName || $key == $networkName; + }); + if (! $networkExists) { + $networks->put($networkName, null); + } + } + } + $baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) { + return $value == $baseNetwork; + }); + if (! $baseNetworkExists) { + foreach ($baseNetwork as $network) { + $topLevel->get('networks')->put($network, [ + 'name' => $network, + 'external' => true, + ]); + } + } + } + + // Collect/create/update ports + $collectedPorts = collect([]); + if ($ports->count() > 0) { + foreach ($ports as $sport) { + if (is_string($sport) || is_numeric($sport)) { + $collectedPorts->push($sport); + } + if (is_array($sport)) { + $target = data_get($sport, 'target'); + $published = data_get($sport, 'published'); + $protocol = data_get($sport, 'protocol'); + $collectedPorts->push("$target:$published/$protocol"); + } + } + } + + $networks_temp = collect(); + + if (! $use_network_mode) { + foreach ($networks as $key => $network) { + if (gettype($network) === 'string') { + // networks: + // - appwrite + $networks_temp->put($network, null); + } elseif (gettype($network) === 'array') { + // networks: + // default: + // ipv4_address: 192.168.203.254 + $networks_temp->put($key, $network); + } + } + foreach ($baseNetwork as $key => $network) { + $networks_temp->put($network, null); + } + + if (data_get($resource, 'settings.connect_to_docker_network')) { + $network = $resource->destination->network; + $networks_temp->put($network, null); + $topLevel->get('networks')->put($network, [ + 'name' => $network, + 'external' => true, + ]); + } + } + + $normalEnvironments = $environment->diffKeys($allMagicEnvironments); + $normalEnvironments = $normalEnvironments->filter(function ($value, $key) { + return ! str($value)->startsWith('SERVICE_'); + }); + foreach ($normalEnvironments as $key => $value) { + $key = str($key); + $value = str($value); + $originalValue = $value; + $parsedValue = replaceVariables($value); + if ($value->startsWith('$SERVICE_')) { + $resource->environment_variables()->firstOrCreate([ + 'key' => $key, + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $value, + 'is_build_time' => false, + 'is_preview' => false, + ]); + + continue; + } + if (! $value->startsWith('$')) { + continue; + } + if ($key->value() === $parsedValue->value()) { + $value = null; + $resource->environment_variables()->firstOrCreate([ + 'key' => $key, + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $value, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } else { + if ($value->startsWith('$')) { + $isRequired = false; + if ($value->contains(':-')) { + $value = replaceVariables($value); + $key = $value->before(':'); + $value = $value->after(':-'); + } elseif ($value->contains('-')) { + $value = replaceVariables($value); + + $key = $value->before('-'); + $value = $value->after('-'); + } elseif ($value->contains(':?')) { + $value = replaceVariables($value); + + $key = $value->before(':'); + $value = $value->after(':?'); + $isRequired = true; + } elseif ($value->contains('?')) { + $value = replaceVariables($value); + + $key = $value->before('?'); + $value = $value->after('?'); + $isRequired = true; + } + if ($originalValue->value() === $value->value()) { + // This means the variable does not have a default value, so it needs to be created in Coolify + $parsedKeyValue = replaceVariables($value); + $resource->environment_variables()->firstOrCreate([ + 'key' => $parsedKeyValue, + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'is_build_time' => false, + 'is_preview' => false, + 'is_required' => $isRequired, + ]); + // Add the variable to the environment so it will be shown in the deployable compose file + $environment[$parsedKeyValue->value()] = $value; + + continue; + } + $resource->environment_variables()->firstOrCreate([ + 'key' => $key, + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $value, + 'is_build_time' => false, + 'is_preview' => false, + 'is_required' => $isRequired, + ]); + } + } + } + $branch = $originalResource->git_branch; + if ($pullRequestId !== 0) { + $branch = "pull/{$pullRequestId}/head"; + } + if ($originalResource->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) { + $coolifyEnvironments->put('COOLIFY_BRANCH', "\"{$branch}\""); + } + + // Add COOLIFY_RESOURCE_UUID to environment + if ($resource->environment_variables->where('key', 'COOLIFY_RESOURCE_UUID')->isEmpty()) { + $coolifyEnvironments->put('COOLIFY_RESOURCE_UUID', "{$resource->uuid}"); + } + + // Add COOLIFY_CONTAINER_NAME to environment + if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) { + $coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', "{$containerName}"); + } + + if ($isPullRequest) { + $preview = $resource->previews()->find($preview_id); + $domains = collect(json_decode(data_get($preview, 'docker_compose_domains'))) ?? collect([]); + } else { + $domains = collect(json_decode(data_get($resource, 'docker_compose_domains'))) ?? collect([]); + } + + // Only process domains for dockercompose applications to prevent SERVICE variable recreation + if ($resource->build_pack !== 'dockercompose') { + $domains = collect([]); + } + $fqdns = data_get($domains, "$serviceName.domain"); + // Generate SERVICE_FQDN & SERVICE_URL for dockercompose + if ($resource->build_pack === 'dockercompose') { + foreach ($domains as $forServiceName => $domain) { + $parsedDomain = data_get($domain, 'domain'); + $serviceNameFormatted = str($serviceName)->upper()->replace('-', '_'); + + if (filled($parsedDomain)) { + $parsedDomain = str($parsedDomain)->explode(',')->first(); + $coolifyUrl = Url::fromString($parsedDomain); + $coolifyScheme = $coolifyUrl->getScheme(); + $coolifyFqdn = $coolifyUrl->getHost(); + $coolifyUrl = $coolifyUrl->withScheme($coolifyScheme)->withHost($coolifyFqdn)->withPort(null); + $coolifyEnvironments->put('SERVICE_URL_'.str($forServiceName)->upper()->replace('-', '_'), $coolifyUrl->__toString()); + $coolifyEnvironments->put('SERVICE_FQDN_'.str($forServiceName)->upper()->replace('-', '_'), $coolifyFqdn); + $resource->environment_variables()->updateOrCreate([ + 'resourceable_type' => Application::class, + 'resourceable_id' => $resource->id, + 'key' => 'SERVICE_URL_'.str($forServiceName)->upper()->replace('-', '_'), + ], [ + 'value' => $coolifyUrl->__toString(), + 'is_build_time' => false, + 'is_preview' => false, + ]); + $resource->environment_variables()->updateOrCreate([ + 'resourceable_type' => Application::class, + 'resourceable_id' => $resource->id, + 'key' => 'SERVICE_FQDN_'.str($forServiceName)->upper()->replace('-', '_'), + ], [ + 'value' => $coolifyFqdn, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } else { + $resource->environment_variables()->where('resourceable_type', Application::class) + ->where('resourceable_id', $resource->id) + ->where('key', 'LIKE', "SERVICE_FQDN_{$serviceNameFormatted}%") + ->update([ + 'value' => null, + ]); + $resource->environment_variables()->where('resourceable_type', Application::class) + ->where('resourceable_id', $resource->id) + ->where('key', 'LIKE', "SERVICE_URL_{$serviceNameFormatted}%") + ->update([ + 'value' => null, + ]); + } + } + } + // If the domain is set, we need to generate the FQDNs for the preview + if (filled($fqdns)) { + $fqdns = str($fqdns)->explode(','); + if ($isPullRequest) { + $preview = $resource->previews()->find($preview_id); + $docker_compose_domains = collect(json_decode(data_get($preview, 'docker_compose_domains'))); + if ($docker_compose_domains->count() > 0) { + $found_fqdn = data_get($docker_compose_domains, "$serviceName.domain"); + if ($found_fqdn) { + $fqdns = collect($found_fqdn); + } else { + $fqdns = collect([]); + } + } else { + $fqdns = $fqdns->map(function ($fqdn) use ($pullRequestId, $resource) { + $preview = ApplicationPreview::findPreviewByApplicationAndPullId($resource->id, $pullRequestId); + $url = Url::fromString($fqdn); + $template = $resource->preview_url_template; + $host = $url->getHost(); + $schema = $url->getScheme(); + $random = new Cuid2; + $preview_fqdn = str_replace('{{random}}', $random, $template); + $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn); + $preview_fqdn = str_replace('{{pr_id}}', $pullRequestId, $preview_fqdn); + $preview_fqdn = "$schema://$preview_fqdn"; + $preview->fqdn = $preview_fqdn; + $preview->save(); + + return $preview_fqdn; + }); + } + } + } + $defaultLabels = defaultLabels( + id: $resource->id, + name: $containerName, + projectName: $resource->project()->name, + resourceName: $resource->name, + pull_request_id: $pullRequestId, + type: 'application', + environment: $resource->environment->name, + ); + + $isDatabase = isDatabaseImage($image, $service); + // Add COOLIFY_FQDN & COOLIFY_URL to environment + if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { + $fqdnsWithoutPort = $fqdns->map(function ($fqdn) { + return str($fqdn)->after('://')->before(':')->prepend(str($fqdn)->before('://')->append('://')); + }); + $coolifyEnvironments->put('COOLIFY_URL', $fqdnsWithoutPort->implode(',')); + + $urls = $fqdns->map(function ($fqdn) { + return str($fqdn)->replace('http://', '')->replace('https://', '')->before(':'); + }); + $coolifyEnvironments->put('COOLIFY_FQDN', $urls->implode(',')); + } + add_coolify_default_environment_variables($resource, $coolifyEnvironments, $resource->environment_variables); + if ($environment->count() > 0) { + $environment = $environment->filter(function ($value, $key) { + return ! str($key)->startsWith('SERVICE_FQDN_'); + })->map(function ($value, $key) use ($resource) { + // if value is empty, set it to null so if you set the environment variable in the .env file (Coolify's UI), it will used + if (str($value)->isEmpty()) { + if ($resource->environment_variables()->where('key', $key)->exists()) { + $value = $resource->environment_variables()->where('key', $key)->first()->value; + } else { + $value = null; + } + } + + return $value; + }); + } + $serviceLabels = $labels->merge($defaultLabels); + if ($serviceLabels->count() > 0) { + $isContainerLabelEscapeEnabled = data_get($resource, 'settings.is_container_label_escape_enabled'); + if ($isContainerLabelEscapeEnabled) { + $serviceLabels = $serviceLabels->map(function ($value, $key) { + return escapeDollarSign($value); + }); + } + } + if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { + $shouldGenerateLabelsExactly = $resource->destination->server->settings->generate_exact_labels; + $uuid = $resource->uuid; + $network = data_get($resource, 'destination.network'); + if ($isPullRequest) { + $uuid = "{$resource->uuid}-{$pullRequestId}"; + } + if ($isPullRequest) { + $network = "{$resource->destination->network}-{$pullRequestId}"; + } + if ($shouldGenerateLabelsExactly) { + switch ($server->proxyType()) { + case ProxyTypes::TRAEFIK->value: + $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( + uuid: $uuid, + domains: $fqdns, + is_force_https_enabled: true, + serviceLabels: $serviceLabels, + is_gzip_enabled: $originalResource->isGzipEnabled(), + is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), + service_name: $serviceName, + image: $image + )); + break; + case ProxyTypes::CADDY->value: + $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( + network: $network, + uuid: $uuid, + domains: $fqdns, + is_force_https_enabled: true, + serviceLabels: $serviceLabels, + is_gzip_enabled: $originalResource->isGzipEnabled(), + is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), + service_name: $serviceName, + image: $image, + predefinedPort: $predefinedPort + )); + break; + } + } else { + $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( + uuid: $uuid, + domains: $fqdns, + is_force_https_enabled: true, + serviceLabels: $serviceLabels, + is_gzip_enabled: $originalResource->isGzipEnabled(), + is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), + service_name: $serviceName, + image: $image + )); + $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( + network: $network, + uuid: $uuid, + domains: $fqdns, + is_force_https_enabled: true, + serviceLabels: $serviceLabels, + is_gzip_enabled: $originalResource->isGzipEnabled(), + is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), + service_name: $serviceName, + image: $image, + predefinedPort: $predefinedPort + )); + } + } + data_forget($service, 'volumes.*.content'); + data_forget($service, 'volumes.*.isDirectory'); + data_forget($service, 'volumes.*.is_directory'); + data_forget($service, 'exclude_from_hc'); + + $volumesParsed = $volumesParsed->map(function ($volume) { + data_forget($volume, 'content'); + data_forget($volume, 'is_directory'); + data_forget($volume, 'isDirectory'); + + return $volume; + }); + + $payload = collect($service)->merge([ + 'container_name' => $containerName, + 'restart' => $restart->value(), + 'labels' => $serviceLabels, + ]); + if (! $use_network_mode) { + $payload['networks'] = $networks_temp; + } + if ($ports->count() > 0) { + $payload['ports'] = $ports; + } + if ($volumesParsed->count() > 0) { + $payload['volumes'] = $volumesParsed; + } + if ($environment->count() > 0 || $coolifyEnvironments->count() > 0) { + $payload['environment'] = $environment->merge($coolifyEnvironments); + } + if ($logging) { + $payload['logging'] = $logging; + } + if ($depends_on->count() > 0) { + $payload['depends_on'] = $depends_on; + } + if ($isPullRequest) { + $serviceName = "{$serviceName}-pr-{$pullRequestId}"; + } + + $parsedServices->put($serviceName, $payload); + } + $topLevel->put('services', $parsedServices); + + $customOrder = ['services', 'volumes', 'networks', 'configs', 'secrets']; + + $topLevel = $topLevel->sortBy(function ($value, $key) use ($customOrder) { + return array_search($key, $customOrder); + }); + + $resource->docker_compose = Yaml::dump(convertToArray($topLevel), 10, 2); + data_forget($resource, 'environment_variables'); + data_forget($resource, 'environment_variables_preview'); + $resource->save(); + + return $topLevel; +} + +function serviceParser(Service $resource): Collection +{ + $uuid = data_get($resource, 'uuid'); + $compose = data_get($resource, 'docker_compose_raw'); + if (! $compose) { + return collect([]); + } + + $server = data_get($resource, 'server'); + $allServices = get_service_templates(); + + try { + $yaml = Yaml::parse($compose); + } catch (\Exception) { + return collect([]); + } + $services = data_get($yaml, 'services', collect([])); + $topLevel = collect([ + 'volumes' => collect(data_get($yaml, 'volumes', [])), + 'networks' => collect(data_get($yaml, 'networks', [])), + 'configs' => collect(data_get($yaml, 'configs', [])), + 'secrets' => collect(data_get($yaml, 'secrets', [])), + ]); + // If there are predefined volumes, make sure they are not null + if ($topLevel->get('volumes')->count() > 0) { + $temp = collect([]); + foreach ($topLevel['volumes'] as $volumeName => $volume) { + if (is_null($volume)) { + continue; + } + $temp->put($volumeName, $volume); + } + $topLevel['volumes'] = $temp; + } + // Get the base docker network + $baseNetwork = collect([$uuid]); + + $parsedServices = collect([]); + + $allMagicEnvironments = collect([]); + // Presave services + foreach ($services as $serviceName => $service) { + $image = data_get_str($service, 'image'); + $isDatabase = isDatabaseImage($image, $service); + if ($isDatabase) { + $applicationFound = ServiceApplication::where('name', $serviceName)->where('image', $image)->where('service_id', $resource->id)->first(); + if ($applicationFound) { + $savedService = $applicationFound; + } else { + $savedService = ServiceDatabase::firstOrCreate([ + 'name' => $serviceName, + 'image' => $image, + 'service_id' => $resource->id, + ]); + } + } else { + $savedService = ServiceApplication::firstOrCreate([ + 'name' => $serviceName, + 'image' => $image, + 'service_id' => $resource->id, + ]); + } + } + foreach ($services as $serviceName => $service) { + $predefinedPort = null; + $magicEnvironments = collect([]); + $image = data_get_str($service, 'image'); + $environment = collect(data_get($service, 'environment', [])); + $buildArgs = collect(data_get($service, 'build.args', [])); + $environment = $environment->merge($buildArgs); + $isDatabase = isDatabaseImage($image, $service); + + $containerName = "$serviceName-{$resource->uuid}"; + + if ($serviceName === 'registry') { + $tempServiceName = 'docker-registry'; + } else { + $tempServiceName = $serviceName; + } + if (str(data_get($service, 'image'))->contains('glitchtip')) { + $tempServiceName = 'glitchtip'; + } + if ($serviceName === 'supabase-kong') { + $tempServiceName = 'supabase'; + } + $serviceDefinition = data_get($allServices, $tempServiceName); + $predefinedPort = data_get($serviceDefinition, 'port'); + if ($serviceName === 'plausible') { + $predefinedPort = '8000'; + } + if ($isDatabase) { + $applicationFound = ServiceApplication::where('name', $serviceName)->where('service_id', $resource->id)->first(); + if ($applicationFound) { + $savedService = $applicationFound; + } else { + $savedService = ServiceDatabase::firstOrCreate([ + 'name' => $serviceName, + 'service_id' => $resource->id, + ]); + } + } else { + $savedService = ServiceApplication::firstOrCreate([ + 'name' => $serviceName, + 'service_id' => $resource->id, + ], [ + 'is_gzip_enabled' => true, + ]); + } + // Check if image changed + if ($savedService->image !== $image) { + $savedService->image = $image; + $savedService->save(); + } + // Pocketbase does not need gzip for SSE. + if (str($savedService->image)->contains('pocketbase') && $savedService->is_gzip_enabled) { + $savedService->is_gzip_enabled = false; + $savedService->save(); + } + + $environment = collect(data_get($service, 'environment', [])); + $buildArgs = collect(data_get($service, 'build.args', [])); + $environment = $environment->merge($buildArgs); + + // convert environment variables to one format + $environment = convertToKeyValueCollection($environment); + + // Add Coolify defined environments + $allEnvironments = $resource->environment_variables()->get(['key', 'value']); + + $allEnvironments = $allEnvironments->mapWithKeys(function ($item) { + return [$item['key'] => $item['value']]; + }); + // filter and add magic environments + foreach ($environment as $key => $value) { + // Get all SERVICE_ variables from keys and values + $key = str($key); + $value = str($value); + $regex = '/\$(\{?([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\}?)/'; + preg_match_all($regex, $value, $valueMatches); + if (count($valueMatches[1]) > 0) { + foreach ($valueMatches[1] as $match) { + $match = replaceVariables($match); + if ($match->startsWith('SERVICE_')) { + if ($magicEnvironments->has($match->value())) { + continue; + } + $magicEnvironments->put($match->value(), ''); + } + } + } + // Get magic environments where we need to preset the FQDN / URL + if ($key->startsWith('SERVICE_FQDN_') || $key->startsWith('SERVICE_URL_')) { + // SERVICE_FQDN_APP or SERVICE_FQDN_APP_3000 + if (substr_count(str($key)->value(), '_') === 3) { + if ($key->startsWith('SERVICE_FQDN_')) { + $urlFor = null; + $fqdnFor = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower()->value(); + } + if ($key->startsWith('SERVICE_URL_')) { + $fqdnFor = null; + $urlFor = $key->after('SERVICE_URL_')->beforeLast('_')->lower()->value(); + } + $port = $key->afterLast('_')->value(); + } else { + if ($key->startsWith('SERVICE_FQDN_')) { + $urlFor = null; + $fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value(); + } + if ($key->startsWith('SERVICE_URL_')) { + $fqdnFor = null; + $urlFor = $key->after('SERVICE_URL_')->lower()->value(); + } + $port = null; + } + if (blank($savedService->fqdn)) { + if ($fqdnFor) { + $fqdn = generateFqdn(server: $server, random: "$fqdnFor-$uuid", parserVersion: $resource->compose_parsing_version); + } else { + $fqdn = generateFqdn(server: $server, random: "{$savedService->name}-$uuid", parserVersion: $resource->compose_parsing_version); + } + if ($urlFor) { + $url = generateUrl($server, "$urlFor-$uuid"); + } else { + $url = generateUrl($server, "{$savedService->name}-$uuid"); + } + } else { + $fqdn = str($savedService->fqdn)->after('://')->before(':')->prepend(str($savedService->fqdn)->before('://')->append('://'))->value(); + $url = str($savedService->fqdn)->after('://')->before(':')->prepend(str($savedService->fqdn)->before('://')->append('://'))->value(); + } + + if ($value && get_class($value) === \Illuminate\Support\Stringable::class && $value->startsWith('/')) { + $path = $value->value(); + if ($path !== '/') { + $fqdn = "$fqdn$path"; + $url = "$url$path"; + } + } + $fqdnWithPort = $fqdn; + $urlWithPort = $url; + if ($fqdn && $port) { + $fqdnWithPort = "$fqdn:$port"; + } + if ($url && $port) { + $urlWithPort = "$url:$port"; + } + if (is_null($savedService->fqdn)) { + if ((int) $resource->compose_parsing_version >= 5 && version_compare(config('constants.coolify.version'), '4.0.0-beta.420.7', '>=')) { + if ($fqdnFor) { + $savedService->fqdn = $fqdnWithPort; + } + if ($urlFor) { + $savedService->fqdn = $urlWithPort; + } + } else { + $savedService->fqdn = $fqdnWithPort; + } + $savedService->save(); + } + if (substr_count(str($key)->value(), '_') === 2) { + $resource->environment_variables()->updateOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $fqdn, + 'is_build_time' => false, + 'is_preview' => false, + ]); + $resource->environment_variables()->updateOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $url, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } + if (substr_count(str($key)->value(), '_') === 3) { + $newKey = str($key)->beforeLast('_'); + $resource->environment_variables()->updateOrCreate([ + 'key' => $newKey->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $fqdn, + 'is_build_time' => false, + 'is_preview' => false, + ]); + $resource->environment_variables()->updateOrCreate([ + 'key' => $newKey->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $url, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } + } + } + $allMagicEnvironments = $allMagicEnvironments->merge($magicEnvironments); + if ($magicEnvironments->count() > 0) { + foreach ($magicEnvironments as $key => $value) { + $key = str($key); + $value = replaceVariables($value); + $command = parseCommandFromMagicEnvVariable($key); + if ($command->value() === 'FQDN') { + $fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value(); + $fqdn = generateFqdn(server: $server, random: str($fqdnFor)->replace('_', '-')->value()."-$uuid", parserVersion: $resource->compose_parsing_version); + $url = generateUrl(server: $server, random: str($fqdnFor)->replace('_', '-')->value()."-$uuid"); + + $envExists = $resource->environment_variables()->where('key', $key->value())->first(); + $serviceExists = ServiceApplication::where('name', str($fqdnFor)->replace('_', '-')->value())->where('service_id', $resource->id)->first(); + if (! $envExists && (data_get($serviceExists, 'name') === str($fqdnFor)->replace('_', '-')->value())) { + // Save URL otherwise it won't work. + $serviceExists->fqdn = $url; + $serviceExists->save(); + } + $resource->environment_variables()->firstOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $fqdn, + 'is_build_time' => false, + 'is_preview' => false, + ]); + + } elseif ($command->value() === 'URL') { + $urlFor = $key->after('SERVICE_URL_')->lower()->value(); + $url = generateUrl(server: $server, random: str($urlFor)->replace('_', '-')->value()."-$uuid"); + + $envExists = $resource->environment_variables()->where('key', $key->value())->first(); + $serviceExists = ServiceApplication::where('name', str($urlFor)->replace('_', '-')->value())->where('service_id', $resource->id)->first(); + if (! $envExists && (data_get($serviceExists, 'name') === str($urlFor)->replace('_', '-')->value())) { + $serviceExists->fqdn = $url; + $serviceExists->save(); + } + $resource->environment_variables()->firstOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $url, + 'is_build_time' => false, + 'is_preview' => false, + ]); + + } else { + $value = generateEnvValue($command, $resource); + $resource->environment_variables()->firstOrCreate([ + 'key' => $key->value(), + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $value, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } + } + } + } + + $serviceAppsLogDrainEnabledMap = $resource->applications()->get()->keyBy('name')->map(function ($app) { + return $app->isLogDrainEnabled(); + }); + + // Parse the rest of the services + foreach ($services as $serviceName => $service) { + $image = data_get_str($service, 'image'); + $restart = data_get_str($service, 'restart', RESTART_MODE); + $logging = data_get($service, 'logging'); + + if ($server->isLogDrainEnabled()) { + if ($serviceAppsLogDrainEnabledMap->get($serviceName)) { + $logging = generate_fluentd_configuration(); + } + } + $volumes = collect(data_get($service, 'volumes', [])); + $networks = collect(data_get($service, 'networks', [])); + $use_network_mode = data_get($service, 'network_mode') !== null; + $depends_on = collect(data_get($service, 'depends_on', [])); + $labels = collect(data_get($service, 'labels', [])); + if ($labels->count() > 0) { + if (isAssociativeArray($labels)) { + $newLabels = collect([]); + $labels->each(function ($value, $key) use ($newLabels) { + $newLabels->push("$key=$value"); + }); + $labels = $newLabels; + } + } + $environment = collect(data_get($service, 'environment', [])); + $ports = collect(data_get($service, 'ports', [])); + $buildArgs = collect(data_get($service, 'build.args', [])); + $environment = $environment->merge($buildArgs); + + $environment = convertToKeyValueCollection($environment); + $coolifyEnvironments = collect([]); + + $isDatabase = isDatabaseImage($image, $service); + $volumesParsed = collect([]); + + $containerName = "$serviceName-{$resource->uuid}"; + + if ($serviceName === 'registry') { + $tempServiceName = 'docker-registry'; + } else { + $tempServiceName = $serviceName; + } + if (str(data_get($service, 'image'))->contains('glitchtip')) { + $tempServiceName = 'glitchtip'; + } + if ($serviceName === 'supabase-kong') { + $tempServiceName = 'supabase'; + } + $serviceDefinition = data_get($allServices, $tempServiceName); + $predefinedPort = data_get($serviceDefinition, 'port'); + if ($serviceName === 'plausible') { + $predefinedPort = '8000'; + } + + if ($isDatabase) { + $applicationFound = ServiceApplication::where('name', $serviceName)->where('image', $image)->where('service_id', $resource->id)->first(); + if ($applicationFound) { + $savedService = $applicationFound; + } else { + $savedService = ServiceDatabase::firstOrCreate([ + 'name' => $serviceName, + 'image' => $image, + 'service_id' => $resource->id, + ]); + } + } else { + $savedService = ServiceApplication::firstOrCreate([ + 'name' => $serviceName, + 'image' => $image, + 'service_id' => $resource->id, + ]); + } + $fileStorages = $savedService->fileStorages(); + if ($savedService->image !== $image) { + $savedService->image = $image; + $savedService->save(); + } + + $originalResource = $savedService; + + if ($volumes->count() > 0) { + foreach ($volumes as $index => $volume) { + $type = null; + $source = null; + $target = null; + $content = null; + $isDirectory = false; + if (is_string($volume)) { + $source = str($volume)->beforeLast(':'); + $target = str($volume)->afterLast(':'); + $foundConfig = $fileStorages->whereMountPath($target)->first(); + if (sourceIsLocal($source)) { + $type = str('bind'); + if ($foundConfig) { + $contentNotNull_temp = data_get($foundConfig, 'content'); + if ($contentNotNull_temp) { + $content = $contentNotNull_temp; + } + $isDirectory = data_get($foundConfig, 'is_directory'); + } else { + // By default, we cannot determine if the bind is a directory or not, so we set it to directory + $isDirectory = true; + } + } else { + $type = str('volume'); + } + } elseif (is_array($volume)) { + $type = data_get_str($volume, 'type'); + $source = data_get_str($volume, 'source'); + $target = data_get_str($volume, 'target'); + $content = data_get($volume, 'content'); + $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); + + $foundConfig = $fileStorages->whereMountPath($target)->first(); + if ($foundConfig) { + $contentNotNull_temp = data_get($foundConfig, 'content'); + if ($contentNotNull_temp) { + $content = $contentNotNull_temp; + } + $isDirectory = data_get($foundConfig, 'is_directory'); + } else { + // if isDirectory is not set (or false) & content is also not set, we assume it is a directory + if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) { + $isDirectory = true; + } + } + } + if ($type->value() === 'bind') { + if ($source->value() === '/var/run/docker.sock') { + $volume = $source->value().':'.$target->value(); + } elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') { + $volume = $source->value().':'.$target->value(); + } else { + if ((int) $resource->compose_parsing_version >= 4) { + $mainDirectory = str(base_configuration_dir().'/services/'.$uuid); + } else { + $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid); + } + $source = replaceLocalSource($source, $mainDirectory); + LocalFileVolume::updateOrCreate( + [ + 'mount_path' => $target, + 'resource_id' => $originalResource->id, + 'resource_type' => get_class($originalResource), + ], + [ + 'fs_path' => $source, + 'mount_path' => $target, + 'content' => $content, + 'is_directory' => $isDirectory, + 'resource_id' => $originalResource->id, + 'resource_type' => get_class($originalResource), + ] + ); + if (isDev()) { + if ((int) $resource->compose_parsing_version >= 4) { + $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/services/'.$uuid); + } else { + $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/'.$uuid); + } + } + $volume = "$source:$target"; + } + } elseif ($type->value() === 'volume') { + if ($topLevel->get('volumes')->has($source->value())) { + $temp = $topLevel->get('volumes')->get($source->value()); + if (data_get($temp, 'driver_opts.type') === 'cifs') { + continue; + } + if (data_get($temp, 'driver_opts.type') === 'nfs') { + continue; + } + } + $slugWithoutUuid = Str::slug($source, '-'); + $name = "{$uuid}_{$slugWithoutUuid}"; + + if (is_string($volume)) { + $source = str($volume)->beforeLast(':'); + $target = str($volume)->afterLast(':'); + $source = $name; + $volume = "$source:$target"; + } elseif (is_array($volume)) { + data_set($volume, 'source', $name); + } + $topLevel->get('volumes')->put($name, [ + 'name' => $name, + ]); + LocalPersistentVolume::updateOrCreate( + [ + 'name' => $name, + 'resource_id' => $originalResource->id, + 'resource_type' => get_class($originalResource), + ], + [ + 'name' => $name, + 'mount_path' => $target, + 'resource_id' => $originalResource->id, + 'resource_type' => get_class($originalResource), + ] + ); + } + dispatch(new ServerFilesFromServerJob($originalResource)); + $volumesParsed->put($index, $volume); + } + } + + if (! $use_network_mode) { + if ($topLevel->get('networks')?->count() > 0) { + foreach ($topLevel->get('networks') as $networkName => $network) { + if ($networkName === 'default') { + continue; + } + // ignore aliases + if ($network['aliases'] ?? false) { + continue; + } + $networkExists = $networks->contains(function ($value, $key) use ($networkName) { + return $value == $networkName || $key == $networkName; + }); + if (! $networkExists) { + $networks->put($networkName, null); + } + } + } + $baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) { + return $value == $baseNetwork; + }); + if (! $baseNetworkExists) { + foreach ($baseNetwork as $network) { + $topLevel->get('networks')->put($network, [ + 'name' => $network, + 'external' => true, + ]); + } + } + } + + // Collect/create/update ports + $collectedPorts = collect([]); + if ($ports->count() > 0) { + foreach ($ports as $sport) { + if (is_string($sport) || is_numeric($sport)) { + $collectedPorts->push($sport); + } + if (is_array($sport)) { + $target = data_get($sport, 'target'); + $published = data_get($sport, 'published'); + $protocol = data_get($sport, 'protocol'); + $collectedPorts->push("$target:$published/$protocol"); + } + } + } + $originalResource->ports = $collectedPorts->implode(','); + $originalResource->save(); + + $networks_temp = collect(); + + if (! $use_network_mode) { + foreach ($networks as $key => $network) { + if (gettype($network) === 'string') { + // networks: + // - appwrite + $networks_temp->put($network, null); + } elseif (gettype($network) === 'array') { + // networks: + // default: + // ipv4_address: 192.168.203.254 + $networks_temp->put($key, $network); + } + } + foreach ($baseNetwork as $key => $network) { + $networks_temp->put($network, null); + } + } + + $normalEnvironments = $environment->diffKeys($allMagicEnvironments); + $normalEnvironments = $normalEnvironments->filter(function ($value, $key) { + return ! str($value)->startsWith('SERVICE_'); + }); + foreach ($normalEnvironments as $key => $value) { + $key = str($key); + $value = str($value); + $originalValue = $value; + $parsedValue = replaceVariables($value); + if ($parsedValue->startsWith('SERVICE_')) { + $resource->environment_variables()->firstOrCreate([ + 'key' => $key, + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $value, + 'is_build_time' => false, + 'is_preview' => false, + ]); + + continue; + } + if (! $value->startsWith('$')) { + continue; + } + if ($key->value() === $parsedValue->value()) { + $value = null; + $resource->environment_variables()->firstOrCreate([ + 'key' => $key, + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $value, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } else { + if ($value->startsWith('$')) { + $isRequired = false; + if ($value->contains(':-')) { + $value = replaceVariables($value); + $key = $value->before(':'); + $value = $value->after(':-'); + } elseif ($value->contains('-')) { + $value = replaceVariables($value); + + $key = $value->before('-'); + $value = $value->after('-'); + } elseif ($value->contains(':?')) { + $value = replaceVariables($value); + + $key = $value->before(':'); + $value = $value->after(':?'); + $isRequired = true; + } elseif ($value->contains('?')) { + $value = replaceVariables($value); + + $key = $value->before('?'); + $value = $value->after('?'); + $isRequired = true; + } + if ($originalValue->value() === $value->value()) { + // This means the variable does not have a default value, so it needs to be created in Coolify + $parsedKeyValue = replaceVariables($value); + $resource->environment_variables()->firstOrCreate([ + 'key' => $parsedKeyValue, + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'is_build_time' => false, + 'is_preview' => false, + 'is_required' => $isRequired, + ]); + // Add the variable to the environment so it will be shown in the deployable compose file + $environment[$parsedKeyValue->value()] = $value; + + continue; + } + $resource->environment_variables()->firstOrCreate([ + 'key' => $key, + 'resourceable_type' => get_class($resource), + 'resourceable_id' => $resource->id, + ], [ + 'value' => $value, + 'is_build_time' => false, + 'is_preview' => false, + 'is_required' => $isRequired, + ]); + } + } + } + + // Add COOLIFY_RESOURCE_UUID to environment + if ($resource->environment_variables->where('key', 'COOLIFY_RESOURCE_UUID')->isEmpty()) { + $coolifyEnvironments->put('COOLIFY_RESOURCE_UUID', "{$resource->uuid}"); + } + + // Add COOLIFY_CONTAINER_NAME to environment + if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) { + $coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', "{$containerName}"); + } + + if ($savedService->serviceType()) { + $fqdns = generateServiceSpecificFqdns($savedService); + } else { + $fqdns = collect(data_get($savedService, 'fqdns'))->filter(); + } + + $defaultLabels = defaultLabels( + id: $resource->id, + name: $containerName, + projectName: $resource->project()->name, + resourceName: $resource->name, + type: 'service', + subType: $isDatabase ? 'database' : 'application', + subId: $savedService->id, + subName: $savedService->human_name ?? $savedService->name, + environment: $resource->environment->name, + ); + + // Add COOLIFY_FQDN & COOLIFY_URL to environment + if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { + $fqdnsWithoutPort = $fqdns->map(function ($fqdn) { + return str($fqdn)->replace('http://', '')->replace('https://', '')->before(':'); + }); + $coolifyEnvironments->put('COOLIFY_FQDN', $fqdnsWithoutPort->implode(',')); + $urls = $fqdns->map(function ($fqdn): Stringable { + return str($fqdn)->after('://')->before(':')->prepend(str($fqdn)->before('://')->append('://')); + }); + $coolifyEnvironments->put('COOLIFY_URL', $urls->implode(',')); + } + add_coolify_default_environment_variables($resource, $coolifyEnvironments, $resource->environment_variables); + if ($environment->count() > 0) { + $environment = $environment->filter(function ($value, $key) { + return ! str($key)->startsWith('SERVICE_FQDN_'); + })->map(function ($value, $key) use ($resource) { + // if value is empty, set it to null so if you set the environment variable in the .env file (Coolify's UI), it will used + if (str($value)->isEmpty()) { + if ($resource->environment_variables()->where('key', $key)->exists()) { + $value = $resource->environment_variables()->where('key', $key)->first()->value; + } else { + $value = null; + } + } + + return $value; + }); + } + $serviceLabels = $labels->merge($defaultLabels); + if ($serviceLabels->count() > 0) { + $isContainerLabelEscapeEnabled = data_get($resource, 'is_container_label_escape_enabled'); + if ($isContainerLabelEscapeEnabled) { + $serviceLabels = $serviceLabels->map(function ($value, $key) { + return escapeDollarSign($value); + }); + } + } + if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { + $shouldGenerateLabelsExactly = $resource->server->settings->generate_exact_labels; + $uuid = $resource->uuid; + $network = data_get($resource, 'destination.network'); + if ($shouldGenerateLabelsExactly) { + switch ($server->proxyType()) { + case ProxyTypes::TRAEFIK->value: + $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( + uuid: $uuid, + domains: $fqdns, + is_force_https_enabled: true, + serviceLabels: $serviceLabels, + is_gzip_enabled: $originalResource->isGzipEnabled(), + is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), + service_name: $serviceName, + image: $image + )); + break; + case ProxyTypes::CADDY->value: + $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( + network: $network, + uuid: $uuid, + domains: $fqdns, + is_force_https_enabled: true, + serviceLabels: $serviceLabels, + is_gzip_enabled: $originalResource->isGzipEnabled(), + is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), + service_name: $serviceName, + image: $image, + predefinedPort: $predefinedPort + )); + break; + } + } else { + $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( + uuid: $uuid, + domains: $fqdns, + is_force_https_enabled: true, + serviceLabels: $serviceLabels, + is_gzip_enabled: $originalResource->isGzipEnabled(), + is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), + service_name: $serviceName, + image: $image + )); + $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( + network: $network, + uuid: $uuid, + domains: $fqdns, + is_force_https_enabled: true, + serviceLabels: $serviceLabels, + is_gzip_enabled: $originalResource->isGzipEnabled(), + is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), + service_name: $serviceName, + image: $image, + predefinedPort: $predefinedPort + )); + } + } + if (data_get($service, 'restart') === 'no' || data_get($service, 'exclude_from_hc')) { + $savedService->update(['exclude_from_status' => true]); + } + data_forget($service, 'volumes.*.content'); + data_forget($service, 'volumes.*.isDirectory'); + data_forget($service, 'volumes.*.is_directory'); + data_forget($service, 'exclude_from_hc'); + + $volumesParsed = $volumesParsed->map(function ($volume) { + data_forget($volume, 'content'); + data_forget($volume, 'is_directory'); + data_forget($volume, 'isDirectory'); + + return $volume; + }); + + $payload = collect($service)->merge([ + 'container_name' => $containerName, + 'restart' => $restart->value(), + 'labels' => $serviceLabels, + ]); + if (! $use_network_mode) { + $payload['networks'] = $networks_temp; + } + if ($ports->count() > 0) { + $payload['ports'] = $ports; + } + if ($volumesParsed->count() > 0) { + $payload['volumes'] = $volumesParsed; + } + if ($environment->count() > 0 || $coolifyEnvironments->count() > 0) { + $payload['environment'] = $environment->merge($coolifyEnvironments); + } + if ($logging) { + $payload['logging'] = $logging; + } + if ($depends_on->count() > 0) { + $payload['depends_on'] = $depends_on; + } + + $parsedServices->put($serviceName, $payload); + } + $topLevel->put('services', $parsedServices); + + $customOrder = ['services', 'volumes', 'networks', 'configs', 'secrets']; + + $topLevel = $topLevel->sortBy(function ($value, $key) use ($customOrder) { + return array_search($key, $customOrder); + }); + + $resource->docker_compose = Yaml::dump(convertToArray($topLevel), 10, 2); + data_forget($resource, 'environment_variables'); + data_forget($resource, 'environment_variables_preview'); + $resource->save(); + + return $topLevel; +} diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index cabdabaa7..2d479a193 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -130,10 +130,16 @@ function generate_default_proxy_configuration(Server $server) } $array_of_networks = collect([]); - $networks->map(function ($network) use ($array_of_networks) { + $filtered_networks = collect([]); + $networks->map(function ($network) use ($array_of_networks, $filtered_networks) { + if ($network === 'host') { + return; // network-scoped alias is supported only for containers in user defined networks + } + $array_of_networks[$network] = [ 'external' => true, ]; + $filtered_networks->push($network); }); if ($proxy_type === ProxyTypes::TRAEFIK->value) { $labels = [ @@ -155,7 +161,7 @@ function generate_default_proxy_configuration(Server $server) 'extra_hosts' => [ 'host.docker.internal:host-gateway', ], - 'networks' => $networks->toArray(), + 'networks' => $filtered_networks->toArray(), 'ports' => [ '80:80', '443:443', @@ -237,7 +243,7 @@ function generate_default_proxy_configuration(Server $server) 'CADDY_DOCKER_POLLING_INTERVAL=5s', 'CADDY_DOCKER_CADDYFILE_PATH=/dynamic/Caddyfile', ], - 'networks' => $networks->toArray(), + 'networks' => $filtered_networks->toArray(), 'ports' => [ '80:80', '443:443', diff --git a/bootstrap/helpers/services.php b/bootstrap/helpers/services.php index cd99713a2..cf12a28a5 100644 --- a/bootstrap/helpers/services.php +++ b/bootstrap/helpers/services.php @@ -1,7 +1,6 @@ <?php use App\Models\Application; -use App\Models\EnvironmentVariable; use App\Models\Service; use App\Models\ServiceApplication; use App\Models\ServiceDatabase; @@ -115,159 +114,70 @@ function updateCompose(ServiceApplication|ServiceDatabase $resource) $resource->image = $updatedImage; $resource->save(); } + + $serviceName = str($resource->name)->upper()->replace('-', '_'); + $resource->service->environment_variables()->where('key', 'LIKE', "SERVICE_FQDN_{$serviceName}%")->delete(); + $resource->service->environment_variables()->where('key', 'LIKE', "SERVICE_URL_{$serviceName}%")->delete(); + if ($resource->fqdn) { $resourceFqdns = str($resource->fqdn)->explode(','); - if ($resourceFqdns->count() === 1) { - $resourceFqdns = $resourceFqdns->first(); - $variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', ''); - $generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', $variableName) - ->first(); - $fqdn = Url::fromString($resourceFqdns); - $port = $fqdn->getPort(); - $path = $fqdn->getPath(); - $fqdn = $fqdn->getScheme().'://'.$fqdn->getHost(); - if ($generatedEnv) { - if ($path === '/') { - $generatedEnv->value = $fqdn; - } else { - $generatedEnv->value = $fqdn.$path; - } - $generatedEnv->save(); - } - if ($port) { - $variableName = $variableName."_$port"; - $generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', $variableName) - ->first(); - if ($generatedEnv) { - if ($path === '/') { - $generatedEnv->value = $fqdn; - } else { - $generatedEnv->value = $fqdn.$path; - } - $generatedEnv->save(); - } - } - $variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', ''); - $generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', $variableName) - ->first(); - $url = Url::fromString($fqdn); - $port = $url->getPort(); - $path = $url->getPath(); - $url = $url->getHost(); - if ($generatedEnv) { - $url = str($fqdn)->after('://'); - if ($path === '/') { - $generatedEnv->value = $url; - } else { - $generatedEnv->value = $url.$path; - } - $generatedEnv->save(); - } - if ($port) { - $variableName = $variableName."_$port"; - $generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', $variableName) - ->first(); - if ($generatedEnv) { - if ($path === '/') { - $generatedEnv->value = $url; - } else { - $generatedEnv->value = $url.$path; - } - $generatedEnv->save(); - } - } - } elseif ($resourceFqdns->count() > 1) { - foreach ($resourceFqdns as $fqdn) { - $host = Url::fromString($fqdn); - $port = $host->getPort(); - $url = $host->getHost(); - $path = $host->getPath(); - $host = $host->getScheme().'://'.$host->getHost(); - if ($port) { - $port_envs = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', 'like', "SERVICE_FQDN_%_$port") - ->get(); - foreach ($port_envs as $port_env) { - $service_fqdn = str($port_env->key)->beforeLast('_')->after('SERVICE_FQDN_'); - $env = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', 'SERVICE_FQDN_'.$service_fqdn) - ->first(); - if ($env) { - if ($path === '/') { - $env->value = $host; - } else { - $env->value = $host.$path; - } - $env->save(); - } - if ($path === '/') { - $port_env->value = $host; - } else { - $port_env->value = $host.$path; - } - $port_env->save(); - } - $port_envs_url = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', 'like', "SERVICE_URL_%_$port") - ->get(); - foreach ($port_envs_url as $port_env_url) { - $service_url = str($port_env_url->key)->beforeLast('_')->after('SERVICE_URL_'); - $env = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', 'SERVICE_URL_'.$service_url) - ->first(); - if ($env) { - if ($path === '/') { - $env->value = $url; - } else { - $env->value = $url.$path; - } - $env->save(); - } - if ($path === '/') { - $port_env_url->value = $url; - } else { - $port_env_url->value = $url.$path; - } - $port_env_url->save(); - } - } else { - $variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', ''); - $generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', $variableName) - ->first(); - $fqdn = Url::fromString($fqdn); - $fqdn = $fqdn->getScheme().'://'.$fqdn->getHost().$fqdn->getPath(); - if ($generatedEnv) { - $generatedEnv->value = $fqdn; - $generatedEnv->save(); - } - $variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', ''); - $generatedEnv = EnvironmentVariable::where('resourceable_type', Service::class) - ->where('resourceable_id', $resource->service_id) - ->where('key', $variableName) - ->first(); - $url = Url::fromString($fqdn); - $url = $url->getHost().$url->getPath(); - if ($generatedEnv) { - $url = str($fqdn)->after('://'); - $generatedEnv->value = $url; - $generatedEnv->save(); - } - } - } + $resourceFqdns = $resourceFqdns->first(); + $variableName = 'SERVICE_URL_'.str($resource->name)->upper()->replace('-', '_'); + $url = Url::fromString($resourceFqdns); + $port = $url->getPort(); + $path = $url->getPath(); + $urlValue = $url->getScheme().'://'.$url->getHost(); + $urlValue = ($path === '/') ? $urlValue : $urlValue.$path; + $resource->service->environment_variables()->updateOrCreate([ + 'resourceable_type' => Service::class, + 'resourceable_id' => $resource->service_id, + 'key' => $variableName, + ], [ + 'value' => $urlValue, + 'is_build_time' => false, + 'is_preview' => false, + ]); + if ($port) { + $variableName = $variableName."_$port"; + $resource->service->environment_variables()->updateOrCreate([ + 'resourceable_type' => Service::class, + 'resourceable_id' => $resource->service_id, + 'key' => $variableName, + ], [ + 'value' => $urlValue, + 'is_build_time' => false, + 'is_preview' => false, + ]); + } + $variableName = 'SERVICE_FQDN_'.str($resource->name)->upper()->replace('-', '_'); + $fqdn = Url::fromString($resourceFqdns); + $port = $fqdn->getPort(); + $path = $fqdn->getPath(); + $fqdn = $fqdn->getHost(); + $fqdnValue = str($fqdn)->after('://'); + if ($path !== '/') { + $fqdnValue = $fqdnValue.$path; + } + $resource->service->environment_variables()->updateOrCreate([ + 'resourceable_type' => Service::class, + 'resourceable_id' => $resource->service_id, + 'key' => $variableName, + ], [ + 'value' => $fqdnValue, + 'is_build_time' => false, + 'is_preview' => false, + ]); + if ($port) { + $variableName = $variableName."_$port"; + $resource->service->environment_variables()->updateOrCreate([ + 'resourceable_type' => Service::class, + 'resourceable_id' => $resource->service_id, + 'key' => $variableName, + ], [ + 'value' => $fqdnValue, + 'is_build_time' => false, + 'is_preview' => false, + ]); } } } catch (\Throwable $e) { diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 00a674eeb..88bcd5538 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -402,7 +402,7 @@ function data_get_str($data, $key, $default = null): Stringable return str($str); } -function generateFqdn(Server $server, string $random, bool $forceHttps = false): string +function generateUrl(Server $server, string $random, bool $forceHttps = false): string { $wildcard = data_get($server, 'settings.wildcard_domain'); if (is_null($wildcard) || $wildcard === '') { @@ -418,6 +418,26 @@ function generateFqdn(Server $server, string $random, bool $forceHttps = false): return "$scheme://{$random}.$host$path"; } +function generateFqdn(Server $server, string $random, bool $forceHttps = false, int $parserVersion = 4): string +{ + $wildcard = data_get($server, 'settings.wildcard_domain'); + if (is_null($wildcard) || $wildcard === '') { + $wildcard = sslip($server); + } + $url = Url::fromString($wildcard); + $host = $url->getHost(); + $path = $url->getPath() === '/' ? '' : $url->getPath(); + $scheme = $url->getScheme(); + if ($forceHttps) { + $scheme = 'https'; + } + + if ($parserVersion >= 5 && version_compare(config('constants.coolify.version'), '4.0.0-beta.420.7', '>=')) { + return "{$random}.$host$path"; + } + + return "$scheme://{$random}.$host$path"; +} function sslip(Server $server) { if (isDev() && $server->id === 0) { @@ -451,12 +471,12 @@ function get_service_templates(bool $force = false): Collection return collect($services); } catch (\Throwable) { - $services = File::get(base_path('templates/service-templates.json')); + $services = File::get(base_path('templates/'.config('constants.services.file_name'))); return collect(json_decode($services))->sortKeys(); } } else { - $services = File::get(base_path('templates/service-templates.json')); + $services = File::get(base_path('templates/'.config('constants.services.file_name'))); return collect(json_decode($services))->sortKeys(); } @@ -1005,6 +1025,64 @@ function ip_match($ip, $cidrs, &$match = null) return false; } + +function check_ip_against_allowlist($ip, $allowlist) +{ + if (empty($allowlist)) { + return false; + } + + foreach ((array) $allowlist as $allowed) { + $allowed = trim($allowed); + + if (empty($allowed)) { + continue; + } + + // Check if it's a CIDR notation + if (str_contains($allowed, '/')) { + [$subnet, $mask] = explode('/', $allowed); + + // Special case: 0.0.0.0 with any subnet means allow all + if ($subnet === '0.0.0.0') { + return true; + } + + $mask = (int) $mask; + + // Validate mask + if ($mask < 0 || $mask > 32) { + continue; + } + + // Calculate network addresses + $ip_long = ip2long($ip); + $subnet_long = ip2long($subnet); + + if ($ip_long === false || $subnet_long === false) { + continue; + } + + $mask_long = ~((1 << (32 - $mask)) - 1); + + if (($ip_long & $mask_long) == ($subnet_long & $mask_long)) { + return true; + } + } else { + // Special case: 0.0.0.0 means allow all + if ($allowed === '0.0.0.0') { + return true; + } + + // Direct IP comparison + if ($ip === $allowed) { + return true; + } + } + } + + return false; +} function checkIfDomainIsAlreadyUsed(Collection|array $domains, ?string $teamId = null, ?string $uuid = null) { if (is_null($teamId)) { @@ -1306,143 +1384,6 @@ function customApiValidator(Collection|array $item, array $rules) 'required' => 'This field is required.', ]); } - -function parseServiceVolumes($serviceVolumes, $resource, $topLevelVolumes, $pull_request_id = 0) -{ - $serviceVolumes = $serviceVolumes->map(function ($volume) use ($resource, $topLevelVolumes, $pull_request_id) { - $type = null; - $source = null; - $target = null; - $content = null; - $isDirectory = false; - if (is_string($volume)) { - $source = str($volume)->before(':'); - $target = str($volume)->after(':')->beforeLast(':'); - $foundConfig = $resource->fileStorages()->whereMountPath($target)->first(); - if ($source->startsWith('./') || $source->startsWith('/') || $source->startsWith('~')) { - $type = str('bind'); - if ($foundConfig) { - $contentNotNull = data_get($foundConfig, 'content'); - if ($contentNotNull) { - $content = $contentNotNull; - } - $isDirectory = data_get($foundConfig, 'is_directory'); - } else { - // By default, we cannot determine if the bind is a directory or not, so we set it to directory - $isDirectory = true; - } - } else { - $type = str('volume'); - } - } elseif (is_array($volume)) { - $type = data_get_str($volume, 'type'); - $source = data_get_str($volume, 'source'); - $target = data_get_str($volume, 'target'); - $content = data_get($volume, 'content'); - $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); - $foundConfig = $resource->fileStorages()->whereMountPath($target)->first(); - if ($foundConfig) { - $contentNotNull = data_get($foundConfig, 'content'); - if ($contentNotNull) { - $content = $contentNotNull; - } - $isDirectory = data_get($foundConfig, 'is_directory'); - } else { - $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); - if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) { - // if isDirectory is not set (or false) & content is also not set, we assume it is a directory - $isDirectory = true; - } - } - } - if ($type?->value() === 'bind') { - if ($source->value() === '/var/run/docker.sock') { - return $volume; - } - if ($source->value() === '/tmp' || $source->value() === '/tmp/') { - return $volume; - } - if (get_class($resource) === \App\Models\Application::class) { - $dir = base_configuration_dir().'/applications/'.$resource->uuid; - } else { - $dir = base_configuration_dir().'/services/'.$resource->service->uuid; - } - - if ($source->startsWith('.')) { - $source = $source->replaceFirst('.', $dir); - } - if ($source->startsWith('~')) { - $source = $source->replaceFirst('~', $dir); - } - if ($pull_request_id !== 0) { - $source = $source."-pr-$pull_request_id"; - } - if (! $resource?->settings?->is_preserve_repository_enabled || $foundConfig?->is_based_on_git) { - LocalFileVolume::updateOrCreate( - [ - 'mount_path' => $target, - 'resource_id' => $resource->id, - 'resource_type' => get_class($resource), - ], - [ - 'fs_path' => $source, - 'mount_path' => $target, - 'content' => $content, - 'is_directory' => $isDirectory, - 'resource_id' => $resource->id, - 'resource_type' => get_class($resource), - ] - ); - } - } elseif ($type->value() === 'volume') { - if ($topLevelVolumes->has($source->value())) { - $v = $topLevelVolumes->get($source->value()); - if (data_get($v, 'driver_opts.type') === 'cifs') { - return $volume; - } - } - $slugWithoutUuid = Str::slug($source, '-'); - if (get_class($resource) === \App\Models\Application::class) { - $name = "{$resource->uuid}_{$slugWithoutUuid}"; - } else { - $name = "{$resource->service->uuid}_{$slugWithoutUuid}"; - } - if (is_string($volume)) { - $source = str($volume)->before(':'); - $target = str($volume)->after(':')->beforeLast(':'); - $source = $name; - $volume = "$source:$target"; - } elseif (is_array($volume)) { - data_set($volume, 'source', $name); - } - $topLevelVolumes->put($name, [ - 'name' => $name, - ]); - LocalPersistentVolume::updateOrCreate( - [ - 'mount_path' => $target, - 'resource_id' => $resource->id, - 'resource_type' => get_class($resource), - ], - [ - 'name' => $name, - 'mount_path' => $target, - 'resource_id' => $resource->id, - 'resource_type' => get_class($resource), - ] - ); - } - dispatch(new ServerFilesFromServerJob($resource)); - - return $volume; - }); - - return [ - 'serviceVolumes' => $serviceVolumes, - 'topLevelVolumes' => $topLevelVolumes, - ]; -} - function parseDockerComposeFile(Service|Application $resource, bool $isNew = false, int $pull_request_id = 0, ?int $preview_id = null) { if ($resource->getMorphClass() === \App\Models\Service::class) { @@ -2918,1005 +2859,6 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal } } -function newParser(Application|Service $resource, int $pull_request_id = 0, ?int $preview_id = null): Collection -{ - $isApplication = $resource instanceof Application; - $isService = $resource instanceof Service; - - $uuid = data_get($resource, 'uuid'); - $compose = data_get($resource, 'docker_compose_raw'); - if (! $compose) { - return collect([]); - } - - if ($isApplication) { - $pullRequestId = $pull_request_id; - $isPullRequest = $pullRequestId == 0 ? false : true; - $server = data_get($resource, 'destination.server'); - $fileStorages = $resource->fileStorages(); - } elseif ($isService) { - $server = data_get($resource, 'server'); - $allServices = get_service_templates(); - } else { - return collect([]); - } - - try { - $yaml = Yaml::parse($compose); - } catch (\Exception) { - return collect([]); - } - $services = data_get($yaml, 'services', collect([])); - $topLevel = collect([ - 'volumes' => collect(data_get($yaml, 'volumes', [])), - 'networks' => collect(data_get($yaml, 'networks', [])), - 'configs' => collect(data_get($yaml, 'configs', [])), - 'secrets' => collect(data_get($yaml, 'secrets', [])), - ]); - // If there are predefined volumes, make sure they are not null - if ($topLevel->get('volumes')->count() > 0) { - $temp = collect([]); - foreach ($topLevel['volumes'] as $volumeName => $volume) { - if (is_null($volume)) { - continue; - } - $temp->put($volumeName, $volume); - } - $topLevel['volumes'] = $temp; - } - // Get the base docker network - $baseNetwork = collect([$uuid]); - if ($isApplication && $isPullRequest) { - $baseNetwork = collect(["{$uuid}-{$pullRequestId}"]); - } - - $parsedServices = collect([]); - - $allMagicEnvironments = collect([]); - foreach ($services as $serviceName => $service) { - $predefinedPort = null; - $magicEnvironments = collect([]); - $image = data_get_str($service, 'image'); - $environment = collect(data_get($service, 'environment', [])); - $buildArgs = collect(data_get($service, 'build.args', [])); - $environment = $environment->merge($buildArgs); - $isDatabase = isDatabaseImage($image, $service); - - if ($isService) { - $containerName = "$serviceName-{$resource->uuid}"; - - if ($serviceName === 'registry') { - $tempServiceName = 'docker-registry'; - } else { - $tempServiceName = $serviceName; - } - if (str(data_get($service, 'image'))->contains('glitchtip')) { - $tempServiceName = 'glitchtip'; - } - if ($serviceName === 'supabase-kong') { - $tempServiceName = 'supabase'; - } - $serviceDefinition = data_get($allServices, $tempServiceName); - $predefinedPort = data_get($serviceDefinition, 'port'); - if ($serviceName === 'plausible') { - $predefinedPort = '8000'; - } - if ($isDatabase) { - $applicationFound = ServiceApplication::where('name', $serviceName)->where('service_id', $resource->id)->first(); - if ($applicationFound) { - $savedService = $applicationFound; - } else { - $savedService = ServiceDatabase::firstOrCreate([ - 'name' => $serviceName, - 'service_id' => $resource->id, - ]); - } - } else { - $savedService = ServiceApplication::firstOrCreate([ - 'name' => $serviceName, - 'service_id' => $resource->id, - ], [ - 'is_gzip_enabled' => true, - ]); - } - // Check if image changed - if ($savedService->image !== $image) { - $savedService->image = $image; - $savedService->save(); - } - // Pocketbase does not need gzip for SSE. - if (str($savedService->image)->contains('pocketbase') && $savedService->is_gzip_enabled) { - $savedService->is_gzip_enabled = false; - $savedService->save(); - } - } - - $environment = collect(data_get($service, 'environment', [])); - $buildArgs = collect(data_get($service, 'build.args', [])); - $environment = $environment->merge($buildArgs); - - // convert environment variables to one format - $environment = convertToKeyValueCollection($environment); - - // Add Coolify defined environments - $allEnvironments = $resource->environment_variables()->get(['key', 'value']); - - $allEnvironments = $allEnvironments->mapWithKeys(function ($item) { - return [$item['key'] => $item['value']]; - }); - // filter and add magic environments - foreach ($environment as $key => $value) { - // Get all SERVICE_ variables from keys and values - $key = str($key); - $value = str($value); - - $regex = '/\$(\{?([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\}?)/'; - preg_match_all($regex, $value, $valueMatches); - if (count($valueMatches[1]) > 0) { - foreach ($valueMatches[1] as $match) { - $match = replaceVariables($match); - if ($match->startsWith('SERVICE_')) { - if ($magicEnvironments->has($match->value())) { - continue; - } - $magicEnvironments->put($match->value(), ''); - } - } - } - // Get magic environments where we need to preset the FQDN - if ($key->startsWith('SERVICE_FQDN_')) { - // SERVICE_FQDN_APP or SERVICE_FQDN_APP_3000 - if (substr_count(str($key)->value(), '_') === 3) { - $fqdnFor = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower()->value(); - $port = $key->afterLast('_')->value(); - } else { - $fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value(); - $port = null; - } - if ($isApplication) { - $fqdn = $resource->fqdn; - if (blank($resource->fqdn)) { - $fqdn = generateFqdn($server, "$uuid"); - } - } elseif ($isService) { - if (blank($savedService->fqdn)) { - if ($fqdnFor) { - $fqdn = generateFqdn($server, "$fqdnFor-$uuid"); - } else { - $fqdn = generateFqdn($server, "{$savedService->name}-$uuid"); - } - } else { - $fqdn = str($savedService->fqdn)->after('://')->before(':')->prepend(str($savedService->fqdn)->before('://')->append('://'))->value(); - } - } - - if ($value && get_class($value) === \Illuminate\Support\Stringable::class && $value->startsWith('/')) { - $path = $value->value(); - if ($path !== '/') { - $fqdn = "$fqdn$path"; - } - } - $fqdnWithPort = $fqdn; - if ($port) { - $fqdnWithPort = "$fqdn:$port"; - } - if ($isApplication && is_null($resource->fqdn)) { - data_forget($resource, 'environment_variables'); - data_forget($resource, 'environment_variables_preview'); - $resource->fqdn = $fqdnWithPort; - $resource->save(); - } elseif ($isService && is_null($savedService->fqdn)) { - $savedService->fqdn = $fqdnWithPort; - $savedService->save(); - } - - if (substr_count(str($key)->value(), '_') === 2) { - $resource->environment_variables()->updateOrCreate([ - 'key' => $key->value(), - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'value' => $fqdn, - 'is_build_time' => false, - 'is_preview' => false, - ]); - } - if (substr_count(str($key)->value(), '_') === 3) { - $newKey = str($key)->beforeLast('_'); - $resource->environment_variables()->updateOrCreate([ - 'key' => $newKey->value(), - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'value' => $fqdn, - 'is_build_time' => false, - 'is_preview' => false, - ]); - } - } - } - - $allMagicEnvironments = $allMagicEnvironments->merge($magicEnvironments); - if ($magicEnvironments->count() > 0) { - foreach ($magicEnvironments as $key => $value) { - $key = str($key); - $value = replaceVariables($value); - $command = parseCommandFromMagicEnvVariable($key); - $found = $resource->environment_variables()->where('key', $key->value())->where('resourceable_type', get_class($resource))->where('resourceable_id', $resource->id)->first(); - if ($found) { - continue; - } - if ($command->value() === 'FQDN') { - if ($isApplication && $resource->build_pack === 'dockercompose') { - continue; - } - $fqdnFor = $key->after('SERVICE_FQDN_')->lower()->value(); - if (str($fqdnFor)->contains('_')) { - $fqdnFor = str($fqdnFor)->before('_'); - } - $fqdn = generateFqdn($server, "$fqdnFor-$uuid"); - $resource->environment_variables()->firstOrCreate([ - 'key' => $key->value(), - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'value' => $fqdn, - 'is_build_time' => false, - 'is_preview' => false, - ]); - } elseif ($command->value() === 'URL') { - if ($isApplication && $resource->build_pack === 'dockercompose') { - continue; - } - $fqdnFor = $key->after('SERVICE_URL_')->lower()->value(); - if (str($fqdnFor)->contains('_')) { - $fqdnFor = str($fqdnFor)->before('_'); - } - $fqdn = generateFqdn($server, "$fqdnFor-$uuid"); - $fqdn = str($fqdn)->replace('http://', '')->replace('https://', ''); - $resource->environment_variables()->firstOrCreate([ - 'key' => $key->value(), - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'value' => $fqdn, - 'is_build_time' => false, - 'is_preview' => false, - ]); - } else { - $value = generateEnvValue($command, $resource); - $resource->environment_variables()->firstOrCreate([ - 'key' => $key->value(), - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'value' => $value, - 'is_build_time' => false, - 'is_preview' => false, - ]); - } - } - } - } - - $serviceAppsLogDrainEnabledMap = collect([]); - if ($resource instanceof Service) { - $serviceAppsLogDrainEnabledMap = $resource->applications()->get()->keyBy('name')->map(function ($app) { - return $app->isLogDrainEnabled(); - }); - } - - // Parse the rest of the services - foreach ($services as $serviceName => $service) { - $image = data_get_str($service, 'image'); - $restart = data_get_str($service, 'restart', RESTART_MODE); - $logging = data_get($service, 'logging'); - - if ($server->isLogDrainEnabled()) { - if ($resource instanceof Application && $resource->isLogDrainEnabled()) { - $logging = generate_fluentd_configuration(); - } - if ($resource instanceof Service && $serviceAppsLogDrainEnabledMap->get($serviceName)) { - $logging = generate_fluentd_configuration(); - } - } - $volumes = collect(data_get($service, 'volumes', [])); - $networks = collect(data_get($service, 'networks', [])); - $use_network_mode = data_get($service, 'network_mode') !== null; - $depends_on = collect(data_get($service, 'depends_on', [])); - $labels = collect(data_get($service, 'labels', [])); - if ($labels->count() > 0) { - if (isAssociativeArray($labels)) { - $newLabels = collect([]); - $labels->each(function ($value, $key) use ($newLabels) { - $newLabels->push("$key=$value"); - }); - $labels = $newLabels; - } - } - $environment = collect(data_get($service, 'environment', [])); - $ports = collect(data_get($service, 'ports', [])); - $buildArgs = collect(data_get($service, 'build.args', [])); - $environment = $environment->merge($buildArgs); - - $environment = convertToKeyValueCollection($environment); - $coolifyEnvironments = collect([]); - - $isDatabase = isDatabaseImage($image, $service); - $volumesParsed = collect([]); - - if ($isApplication) { - $baseName = generateApplicationContainerName( - application: $resource, - pull_request_id: $pullRequestId - ); - $containerName = "$serviceName-$baseName"; - $predefinedPort = null; - } elseif ($isService) { - $containerName = "$serviceName-{$resource->uuid}"; - - if ($serviceName === 'registry') { - $tempServiceName = 'docker-registry'; - } else { - $tempServiceName = $serviceName; - } - if (str(data_get($service, 'image'))->contains('glitchtip')) { - $tempServiceName = 'glitchtip'; - } - if ($serviceName === 'supabase-kong') { - $tempServiceName = 'supabase'; - } - $serviceDefinition = data_get($allServices, $tempServiceName); - $predefinedPort = data_get($serviceDefinition, 'port'); - if ($serviceName === 'plausible') { - $predefinedPort = '8000'; - } - - if ($isDatabase) { - $applicationFound = ServiceApplication::where('name', $serviceName)->where('image', $image)->where('service_id', $resource->id)->first(); - if ($applicationFound) { - $savedService = $applicationFound; - // $savedService = ServiceDatabase::firstOrCreate([ - // 'name' => $applicationFound->name, - // 'image' => $applicationFound->image, - // 'service_id' => $applicationFound->service_id, - // ]); - // $applicationFound->delete(); - } else { - $savedService = ServiceDatabase::firstOrCreate([ - 'name' => $serviceName, - 'image' => $image, - 'service_id' => $resource->id, - ]); - } - } else { - $savedService = ServiceApplication::firstOrCreate([ - 'name' => $serviceName, - 'image' => $image, - 'service_id' => $resource->id, - ]); - } - $fileStorages = $savedService->fileStorages(); - if ($savedService->image !== $image) { - $savedService->image = $image; - $savedService->save(); - } - } - - $originalResource = $isApplication ? $resource : $savedService; - - if ($volumes->count() > 0) { - foreach ($volumes as $index => $volume) { - $type = null; - $source = null; - $target = null; - $content = null; - $isDirectory = false; - if (is_string($volume)) { - $source = str($volume)->before(':'); - $target = str($volume)->after(':')->beforeLast(':'); - $foundConfig = $fileStorages->whereMountPath($target)->first(); - if (sourceIsLocal($source)) { - $type = str('bind'); - if ($foundConfig) { - $contentNotNull_temp = data_get($foundConfig, 'content'); - if ($contentNotNull_temp) { - $content = $contentNotNull_temp; - } - $isDirectory = data_get($foundConfig, 'is_directory'); - } else { - // By default, we cannot determine if the bind is a directory or not, so we set it to directory - $isDirectory = true; - } - } else { - $type = str('volume'); - } - } elseif (is_array($volume)) { - $type = data_get_str($volume, 'type'); - $source = data_get_str($volume, 'source'); - $target = data_get_str($volume, 'target'); - $content = data_get($volume, 'content'); - $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); - - $foundConfig = $fileStorages->whereMountPath($target)->first(); - if ($foundConfig) { - $contentNotNull_temp = data_get($foundConfig, 'content'); - if ($contentNotNull_temp) { - $content = $contentNotNull_temp; - } - $isDirectory = data_get($foundConfig, 'is_directory'); - } else { - // if isDirectory is not set (or false) & content is also not set, we assume it is a directory - if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) { - $isDirectory = true; - } - } - } - if ($type->value() === 'bind') { - if ($source->value() === '/var/run/docker.sock') { - $volume = $source->value().':'.$target->value(); - } elseif ($source->value() === '/tmp' || $source->value() === '/tmp/') { - $volume = $source->value().':'.$target->value(); - } else { - if ((int) $resource->compose_parsing_version >= 4) { - if ($isApplication) { - $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid); - } elseif ($isService) { - $mainDirectory = str(base_configuration_dir().'/services/'.$uuid); - } - } else { - $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid); - } - $source = replaceLocalSource($source, $mainDirectory); - if ($isApplication && $isPullRequest) { - $source = $source."-pr-$pullRequestId"; - } - LocalFileVolume::updateOrCreate( - [ - 'mount_path' => $target, - 'resource_id' => $originalResource->id, - 'resource_type' => get_class($originalResource), - ], - [ - 'fs_path' => $source, - 'mount_path' => $target, - 'content' => $content, - 'is_directory' => $isDirectory, - 'resource_id' => $originalResource->id, - 'resource_type' => get_class($originalResource), - ] - ); - if (isDev()) { - if ((int) $resource->compose_parsing_version >= 4) { - if ($isApplication) { - $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/'.$uuid); - } elseif ($isService) { - $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/services/'.$uuid); - } - } else { - $source = $source->replace($mainDirectory, '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/applications/'.$uuid); - } - } - $volume = "$source:$target"; - } - } elseif ($type->value() === 'volume') { - if ($topLevel->get('volumes')->has($source->value())) { - $temp = $topLevel->get('volumes')->get($source->value()); - if (data_get($temp, 'driver_opts.type') === 'cifs') { - continue; - } - if (data_get($temp, 'driver_opts.type') === 'nfs') { - continue; - } - } - $slugWithoutUuid = Str::slug($source, '-'); - $name = "{$uuid}_{$slugWithoutUuid}"; - - if ($isApplication && $isPullRequest) { - $name = "{$name}-pr-$pullRequestId"; - } - if (is_string($volume)) { - $source = str($volume)->before(':'); - $target = str($volume)->after(':')->beforeLast(':'); - $source = $name; - $volume = "$source:$target"; - } elseif (is_array($volume)) { - data_set($volume, 'source', $name); - } - $topLevel->get('volumes')->put($name, [ - 'name' => $name, - ]); - LocalPersistentVolume::updateOrCreate( - [ - 'name' => $name, - 'resource_id' => $originalResource->id, - 'resource_type' => get_class($originalResource), - ], - [ - 'name' => $name, - 'mount_path' => $target, - 'resource_id' => $originalResource->id, - 'resource_type' => get_class($originalResource), - ] - ); - } - dispatch(new ServerFilesFromServerJob($originalResource)); - $volumesParsed->put($index, $volume); - } - } - - if ($depends_on?->count() > 0) { - if ($isApplication && $isPullRequest) { - $newDependsOn = collect([]); - $depends_on->each(function ($dependency, $condition) use ($pullRequestId, $newDependsOn) { - if (is_numeric($condition)) { - $dependency = "$dependency-pr-$pullRequestId"; - - $newDependsOn->put($condition, $dependency); - } else { - $condition = "$condition-pr-$pullRequestId"; - $newDependsOn->put($condition, $dependency); - } - }); - $depends_on = $newDependsOn; - } - } - if (! $use_network_mode) { - if ($topLevel->get('networks')?->count() > 0) { - foreach ($topLevel->get('networks') as $networkName => $network) { - if ($networkName === 'default') { - continue; - } - // ignore aliases - if ($network['aliases'] ?? false) { - continue; - } - $networkExists = $networks->contains(function ($value, $key) use ($networkName) { - return $value == $networkName || $key == $networkName; - }); - if (! $networkExists) { - $networks->put($networkName, null); - } - } - } - $baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) { - return $value == $baseNetwork; - }); - if (! $baseNetworkExists) { - foreach ($baseNetwork as $network) { - $topLevel->get('networks')->put($network, [ - 'name' => $network, - 'external' => true, - ]); - } - } - } - - // Collect/create/update ports - $collectedPorts = collect([]); - if ($ports->count() > 0) { - foreach ($ports as $sport) { - if (is_string($sport) || is_numeric($sport)) { - $collectedPorts->push($sport); - } - if (is_array($sport)) { - $target = data_get($sport, 'target'); - $published = data_get($sport, 'published'); - $protocol = data_get($sport, 'protocol'); - $collectedPorts->push("$target:$published/$protocol"); - } - } - } - if ($isService) { - $originalResource->ports = $collectedPorts->implode(','); - $originalResource->save(); - } - - $networks_temp = collect(); - - if (! $use_network_mode) { - foreach ($networks as $key => $network) { - if (gettype($network) === 'string') { - // networks: - // - appwrite - $networks_temp->put($network, null); - } elseif (gettype($network) === 'array') { - // networks: - // default: - // ipv4_address: 192.168.203.254 - $networks_temp->put($key, $network); - } - } - foreach ($baseNetwork as $key => $network) { - $networks_temp->put($network, null); - } - - if ($isApplication) { - if (data_get($resource, 'settings.connect_to_docker_network')) { - $network = $resource->destination->network; - $networks_temp->put($network, null); - $topLevel->get('networks')->put($network, [ - 'name' => $network, - 'external' => true, - ]); - } - } - } - - $normalEnvironments = $environment->diffKeys($allMagicEnvironments); - $normalEnvironments = $normalEnvironments->filter(function ($value, $key) { - return ! str($value)->startsWith('SERVICE_'); - }); - - foreach ($normalEnvironments as $key => $value) { - $key = str($key); - $value = str($value); - $originalValue = $value; - $parsedValue = replaceVariables($value); - if ($value->startsWith('$SERVICE_')) { - $resource->environment_variables()->firstOrCreate([ - 'key' => $key, - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'value' => $value, - 'is_build_time' => false, - 'is_preview' => false, - ]); - - continue; - } - if (! $value->startsWith('$')) { - continue; - } - if ($key->value() === $parsedValue->value()) { - $value = null; - $resource->environment_variables()->firstOrCreate([ - 'key' => $key, - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'value' => $value, - 'is_build_time' => false, - 'is_preview' => false, - ]); - } else { - if ($value->startsWith('$')) { - $isRequired = false; - if ($value->contains(':-')) { - $value = replaceVariables($value); - $key = $value->before(':'); - $value = $value->after(':-'); - } elseif ($value->contains('-')) { - $value = replaceVariables($value); - - $key = $value->before('-'); - $value = $value->after('-'); - } elseif ($value->contains(':?')) { - $value = replaceVariables($value); - - $key = $value->before(':'); - $value = $value->after(':?'); - $isRequired = true; - } elseif ($value->contains('?')) { - $value = replaceVariables($value); - - $key = $value->before('?'); - $value = $value->after('?'); - $isRequired = true; - } - if ($originalValue->value() === $value->value()) { - // This means the variable does not have a default value, so it needs to be created in Coolify - $parsedKeyValue = replaceVariables($value); - $resource->environment_variables()->firstOrCreate([ - 'key' => $parsedKeyValue, - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'is_build_time' => false, - 'is_preview' => false, - 'is_required' => $isRequired, - ]); - // Add the variable to the environment so it will be shown in the deployable compose file - // $environment[$parsedKeyValue->value()] = $resource->environment_variables()->where('key', $parsedKeyValue)->where('resourceable_type', get_class($resource))->where('resourceable_id', $resource->id)->first()->real_value; - $environment[$parsedKeyValue->value()] = $value; - - continue; - } - $resource->environment_variables()->firstOrCreate([ - 'key' => $key, - 'resourceable_type' => get_class($resource), - 'resourceable_id' => $resource->id, - ], [ - 'value' => $value, - 'is_build_time' => false, - 'is_preview' => false, - 'is_required' => $isRequired, - ]); - } - } - } - if ($isApplication) { - $branch = $originalResource->git_branch; - if ($pullRequestId !== 0) { - $branch = "pull/{$pullRequestId}/head"; - } - if ($originalResource->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) { - $coolifyEnvironments->put('COOLIFY_BRANCH', "\"{$branch}\""); - } - } - - // Add COOLIFY_RESOURCE_UUID to environment - if ($resource->environment_variables->where('key', 'COOLIFY_RESOURCE_UUID')->isEmpty()) { - $coolifyEnvironments->put('COOLIFY_RESOURCE_UUID', "{$resource->uuid}"); - } - - // Add COOLIFY_CONTAINER_NAME to environment - if ($resource->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) { - $coolifyEnvironments->put('COOLIFY_CONTAINER_NAME', "{$containerName}"); - } - - if ($isApplication) { - if ($isPullRequest) { - $preview = $resource->previews()->find($preview_id); - $domains = collect(json_decode(data_get($preview, 'docker_compose_domains'))) ?? collect([]); - } else { - $domains = collect(json_decode($resource->docker_compose_domains)) ?? collect([]); - } - $fqdns = data_get($domains, "$serviceName.domain"); - // Generate SERVICE_FQDN & SERVICE_URL for dockercompose - if ($resource->build_pack === 'dockercompose') { - foreach ($domains as $forServiceName => $domain) { - $parsedDomain = data_get($domain, 'domain'); - if (filled($parsedDomain)) { - $parsedDomain = str($parsedDomain)->explode(',')->first(); - $coolifyUrl = Url::fromString($parsedDomain); - $coolifyScheme = $coolifyUrl->getScheme(); - $coolifyFqdn = $coolifyUrl->getHost(); - $coolifyUrl = $coolifyUrl->withScheme($coolifyScheme)->withHost($coolifyFqdn)->withPort(null); - $coolifyEnvironments->put('SERVICE_URL_'.str($forServiceName)->upper(), $coolifyUrl->__toString()); - $coolifyEnvironments->put('SERVICE_FQDN_'.str($forServiceName)->upper(), $coolifyFqdn); - } - } - } - // If the domain is set, we need to generate the FQDNs for the preview - if (filled($fqdns)) { - $fqdns = str($fqdns)->explode(','); - if ($isPullRequest) { - $preview = $resource->previews()->find($preview_id); - $docker_compose_domains = collect(json_decode(data_get($preview, 'docker_compose_domains'))); - if ($docker_compose_domains->count() > 0) { - $found_fqdn = data_get($docker_compose_domains, "$serviceName.domain"); - if ($found_fqdn) { - $fqdns = collect($found_fqdn); - } else { - $fqdns = collect([]); - } - } else { - $fqdns = $fqdns->map(function ($fqdn) use ($pullRequestId, $resource) { - $preview = ApplicationPreview::findPreviewByApplicationAndPullId($resource->id, $pullRequestId); - $url = Url::fromString($fqdn); - $template = $resource->preview_url_template; - $host = $url->getHost(); - $schema = $url->getScheme(); - $random = new Cuid2; - $preview_fqdn = str_replace('{{random}}', $random, $template); - $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn); - $preview_fqdn = str_replace('{{pr_id}}', $pullRequestId, $preview_fqdn); - $preview_fqdn = "$schema://$preview_fqdn"; - $preview->fqdn = $preview_fqdn; - $preview->save(); - - return $preview_fqdn; - }); - } - } - } - $defaultLabels = defaultLabels( - id: $resource->id, - name: $containerName, - projectName: $resource->project()->name, - resourceName: $resource->name, - pull_request_id: $pullRequestId, - type: 'application', - environment: $resource->environment->name, - ); - - } elseif ($isService) { - if ($savedService->serviceType()) { - $fqdns = generateServiceSpecificFqdns($savedService); - } else { - $fqdns = collect(data_get($savedService, 'fqdns'))->filter(); - } - - $defaultLabels = defaultLabels( - id: $resource->id, - name: $containerName, - projectName: $resource->project()->name, - resourceName: $resource->name, - type: 'service', - subType: $isDatabase ? 'database' : 'application', - subId: $savedService->id, - subName: $savedService->human_name ?? $savedService->name, - environment: $resource->environment->name, - ); - } - // Add COOLIFY_FQDN & COOLIFY_URL to environment - if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { - $fqdnsWithoutPort = $fqdns->map(function ($fqdn) { - return str($fqdn)->after('://')->before(':')->prepend(str($fqdn)->before('://')->append('://')); - }); - $coolifyEnvironments->put('COOLIFY_URL', $fqdnsWithoutPort->implode(',')); - - $urls = $fqdns->map(function ($fqdn) { - return str($fqdn)->replace('http://', '')->replace('https://', '')->before(':'); - }); - $coolifyEnvironments->put('COOLIFY_FQDN', $urls->implode(',')); - } - add_coolify_default_environment_variables($resource, $coolifyEnvironments, $resource->environment_variables); - - if ($environment->count() > 0) { - $environment = $environment->filter(function ($value, $key) { - return ! str($key)->startsWith('SERVICE_FQDN_'); - })->map(function ($value, $key) use ($resource) { - // if value is empty, set it to null so if you set the environment variable in the .env file (Coolify's UI), it will used - if (str($value)->isEmpty()) { - if ($resource->environment_variables()->where('key', $key)->exists()) { - $value = $resource->environment_variables()->where('key', $key)->first()->value; - } else { - $value = null; - } - } - - return $value; - }); - } - $serviceLabels = $labels->merge($defaultLabels); - if ($serviceLabels->count() > 0) { - if ($isApplication) { - $isContainerLabelEscapeEnabled = data_get($resource, 'settings.is_container_label_escape_enabled'); - } else { - $isContainerLabelEscapeEnabled = data_get($resource, 'is_container_label_escape_enabled'); - } - if ($isContainerLabelEscapeEnabled) { - $serviceLabels = $serviceLabels->map(function ($value, $key) { - return escapeDollarSign($value); - }); - } - } - if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { - if ($isApplication) { - $shouldGenerateLabelsExactly = $resource->destination->server->settings->generate_exact_labels; - $uuid = $resource->uuid; - $network = data_get($resource, 'destination.network'); - if ($isPullRequest) { - $uuid = "{$resource->uuid}-{$pullRequestId}"; - } - if ($isPullRequest) { - $network = "{$resource->destination->network}-{$pullRequestId}"; - } - } else { - $shouldGenerateLabelsExactly = $resource->server->settings->generate_exact_labels; - $uuid = $resource->uuid; - $network = data_get($resource, 'destination.network'); - } - if ($shouldGenerateLabelsExactly) { - switch ($server->proxyType()) { - case ProxyTypes::TRAEFIK->value: - $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( - uuid: $uuid, - domains: $fqdns, - is_force_https_enabled: true, - serviceLabels: $serviceLabels, - is_gzip_enabled: $originalResource->isGzipEnabled(), - is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), - service_name: $serviceName, - image: $image - )); - break; - case ProxyTypes::CADDY->value: - $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( - network: $network, - uuid: $uuid, - domains: $fqdns, - is_force_https_enabled: true, - serviceLabels: $serviceLabels, - is_gzip_enabled: $originalResource->isGzipEnabled(), - is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), - service_name: $serviceName, - image: $image, - predefinedPort: $predefinedPort - )); - break; - } - } else { - $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( - uuid: $uuid, - domains: $fqdns, - is_force_https_enabled: true, - serviceLabels: $serviceLabels, - is_gzip_enabled: $originalResource->isGzipEnabled(), - is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), - service_name: $serviceName, - image: $image - )); - $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( - network: $network, - uuid: $uuid, - domains: $fqdns, - is_force_https_enabled: true, - serviceLabels: $serviceLabels, - is_gzip_enabled: $originalResource->isGzipEnabled(), - is_stripprefix_enabled: $originalResource->isStripprefixEnabled(), - service_name: $serviceName, - image: $image, - predefinedPort: $predefinedPort - )); - } - } - if ($isService) { - if (data_get($service, 'restart') === 'no' || data_get($service, 'exclude_from_hc')) { - $savedService->update(['exclude_from_status' => true]); - } - } - data_forget($service, 'volumes.*.content'); - data_forget($service, 'volumes.*.isDirectory'); - data_forget($service, 'volumes.*.is_directory'); - data_forget($service, 'exclude_from_hc'); - - $volumesParsed = $volumesParsed->map(function ($volume) { - data_forget($volume, 'content'); - data_forget($volume, 'is_directory'); - data_forget($volume, 'isDirectory'); - - return $volume; - }); - - $payload = collect($service)->merge([ - 'container_name' => $containerName, - 'restart' => $restart->value(), - 'labels' => $serviceLabels, - ]); - if (! $use_network_mode) { - $payload['networks'] = $networks_temp; - } - if ($ports->count() > 0) { - $payload['ports'] = $ports; - } - if ($volumesParsed->count() > 0) { - $payload['volumes'] = $volumesParsed; - } - if ($environment->count() > 0 || $coolifyEnvironments->count() > 0) { - $payload['environment'] = $environment->merge($coolifyEnvironments); - } - if ($logging) { - $payload['logging'] = $logging; - } - if ($depends_on->count() > 0) { - $payload['depends_on'] = $depends_on; - } - if ($isApplication && $isPullRequest) { - $serviceName = "{$serviceName}-pr-{$pullRequestId}"; - } - - $parsedServices->put($serviceName, $payload); - } - $topLevel->put('services', $parsedServices); - - $customOrder = ['services', 'volumes', 'networks', 'configs', 'secrets']; - - $topLevel = $topLevel->sortBy(function ($value, $key) use ($customOrder) { - return array_search($key, $customOrder); - }); - - $resource->docker_compose = Yaml::dump(convertToArray($topLevel), 10, 2); - data_forget($resource, 'environment_variables'); - data_forget($resource, 'environment_variables_preview'); - $resource->save(); - - return $topLevel; -} - function generate_fluentd_configuration(): array { return [ diff --git a/bootstrap/helpers/subscriptions.php b/bootstrap/helpers/subscriptions.php index 510516a2f..48c3a62c3 100644 --- a/bootstrap/helpers/subscriptions.php +++ b/bootstrap/helpers/subscriptions.php @@ -89,3 +89,22 @@ function allowedPathsForInvalidAccounts() 'livewire/update', ]; } + +function updateStripeCustomerEmail(Team $team, string $newEmail): void +{ + if (! isStripe()) { + return; + } + + $stripe_customer_id = data_get($team, 'subscription.stripe_customer_id'); + if (! $stripe_customer_id) { + return; + } + + Stripe::setApiKey(config('subscription.stripe_api_key')); + + \Stripe\Customer::update( + $stripe_customer_id, + ['email' => $newEmail] + ); +} diff --git a/changelogs/.gitignore b/changelogs/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/changelogs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/composer.json b/composer.json index 7e8e768c0..38756edf9 100644 --- a/composer.json +++ b/composer.json @@ -47,6 +47,7 @@ "socialiteproviders/zitadel": "^4.2", "spatie/laravel-activitylog": "^4.10.2", "spatie/laravel-data": "^4.17.0", + "spatie/laravel-markdown": "^2.7", "spatie/laravel-ray": "^1.40.2", "spatie/laravel-schemaless-attributes": "^2.5.1", "spatie/url": "^2.4", diff --git a/composer.lock b/composer.lock index 8d170cdc1..c7de9ad34 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "52a680a0eb446dcaa74bc35e158aca57", + "content-hash": "a78cf8fdfec25eac43de77c05640dc91", "packages": [ { "name": "amphp/amp", @@ -870,16 +870,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.351.1", + "version": "3.352.0", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "f3e20c8cdd2cc5827d77a0b3c0872fab89cdf805" + "reference": "7f3ad0da2545b24259273ea7ab892188bae7d91b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f3e20c8cdd2cc5827d77a0b3c0872fab89cdf805", - "reference": "f3e20c8cdd2cc5827d77a0b3c0872fab89cdf805", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/7f3ad0da2545b24259273ea7ab892188bae7d91b", + "reference": "7f3ad0da2545b24259273ea7ab892188bae7d91b", "shasum": "" }, "require": { @@ -961,9 +961,9 @@ "support": { "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.351.1" + "source": "https://github.com/aws/aws-sdk-php/tree/3.352.0" }, - "time": "2025-07-17T18:07:08+00:00" + "time": "2025-08-01T18:04:23+00:00" }, { "name": "bacon/bacon-qr-code", @@ -1373,16 +1373,16 @@ }, { "name": "doctrine/dbal", - "version": "4.3.0", + "version": "4.3.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "5fe09532be619202d59c70956c6fb20e97933ee3" + "reference": "ac336c95ea9e13433d56ca81c308b39db0e1a2a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/5fe09532be619202d59c70956c6fb20e97933ee3", - "reference": "5fe09532be619202d59c70956c6fb20e97933ee3", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/ac336c95ea9e13433d56ca81c308b39db0e1a2a7", + "reference": "ac336c95ea9e13433d56ca81c308b39db0e1a2a7", "shasum": "" }, "require": { @@ -1459,7 +1459,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/4.3.0" + "source": "https://github.com/doctrine/dbal/tree/4.3.1" }, "funding": [ { @@ -1475,7 +1475,7 @@ "type": "tidelift" } ], - "time": "2025-06-16T19:31:04+00:00" + "time": "2025-07-22T10:09:51+00:00" }, { "name": "doctrine/deprecations", @@ -2678,16 +2678,16 @@ }, { "name": "laravel/framework", - "version": "v12.20.0", + "version": "v12.21.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "1b9a00f8caf5503c92aa436279172beae1a484ff" + "reference": "ac8c4e73bf1b5387b709f7736d41427e6af1c93b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/1b9a00f8caf5503c92aa436279172beae1a484ff", - "reference": "1b9a00f8caf5503c92aa436279172beae1a484ff", + "url": "https://api.github.com/repos/laravel/framework/zipball/ac8c4e73bf1b5387b709f7736d41427e6af1c93b", + "reference": "ac8c4e73bf1b5387b709f7736d41427e6af1c93b", "shasum": "" }, "require": { @@ -2889,7 +2889,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-07-08T15:02:21+00:00" + "time": "2025-07-22T15:41:55+00:00" }, { "name": "laravel/horizon", @@ -3111,16 +3111,16 @@ }, { "name": "laravel/sanctum", - "version": "v4.1.2", + "version": "v4.2.0", "source": { "type": "git", "url": "https://github.com/laravel/sanctum.git", - "reference": "e4c09e69aecd5a383e0c1b85a6bb501c997d7491" + "reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sanctum/zipball/e4c09e69aecd5a383e0c1b85a6bb501c997d7491", - "reference": "e4c09e69aecd5a383e0c1b85a6bb501c997d7491", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/fd6df4f79f48a72992e8d29a9c0ee25422a0d677", + "reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677", "shasum": "" }, "require": { @@ -3171,7 +3171,7 @@ "issues": "https://github.com/laravel/sanctum/issues", "source": "https://github.com/laravel/sanctum" }, - "time": "2025-07-01T15:49:32+00:00" + "time": "2025-07-09T19:45:24+00:00" }, { "name": "laravel/serializable-closure", @@ -3236,16 +3236,16 @@ }, { "name": "laravel/socialite", - "version": "v5.21.0", + "version": "v5.23.0", "source": { "type": "git", "url": "https://github.com/laravel/socialite.git", - "reference": "d83639499ad14985c9a6a9713b70073300ce998d" + "reference": "e9e0fc83b9d8d71c8385a5da20e5b95ca6234cf5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/socialite/zipball/d83639499ad14985c9a6a9713b70073300ce998d", - "reference": "d83639499ad14985c9a6a9713b70073300ce998d", + "url": "https://api.github.com/repos/laravel/socialite/zipball/e9e0fc83b9d8d71c8385a5da20e5b95ca6234cf5", + "reference": "e9e0fc83b9d8d71c8385a5da20e5b95ca6234cf5", "shasum": "" }, "require": { @@ -3304,7 +3304,7 @@ "issues": "https://github.com/laravel/socialite/issues", "source": "https://github.com/laravel/socialite" }, - "time": "2025-05-19T12:56:37+00:00" + "time": "2025-07-23T14:16:08+00:00" }, { "name": "laravel/tinker", @@ -3510,16 +3510,16 @@ }, { "name": "league/commonmark", - "version": "2.7.0", + "version": "2.7.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405" + "reference": "10732241927d3971d28e7ea7b5712721fa2296ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", - "reference": "6fbb36d44824ed4091adbcf4c7d4a3923cdb3405", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/10732241927d3971d28e7ea7b5712721fa2296ca", + "reference": "10732241927d3971d28e7ea7b5712721fa2296ca", "shasum": "" }, "require": { @@ -3548,7 +3548,7 @@ "symfony/process": "^5.4 | ^6.0 | ^7.0", "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", "unleashedtech/php-coding-standard": "^3.1.1", - "vimeo/psalm": "^4.24.0 || ^5.0.0" + "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" }, "suggest": { "symfony/yaml": "v2.3+ required if using the Front Matter extension" @@ -3613,7 +3613,7 @@ "type": "tidelift" } ], - "time": "2025-05-05T12:20:28+00:00" + "time": "2025-07-20T12:47:49+00:00" }, { "name": "league/config", @@ -4696,16 +4696,16 @@ }, { "name": "nesbot/carbon", - "version": "3.10.1", + "version": "3.10.2", "source": { "type": "git", "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "1fd1935b2d90aef2f093c5e35f7ae1257c448d00" + "reference": "76b5c07b8a9d2025ed1610e14cef1f3fd6ad2c24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/1fd1935b2d90aef2f093c5e35f7ae1257c448d00", - "reference": "1fd1935b2d90aef2f093c5e35f7ae1257c448d00", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/76b5c07b8a9d2025ed1610e14cef1f3fd6ad2c24", + "reference": "76b5c07b8a9d2025ed1610e14cef1f3fd6ad2c24", "shasum": "" }, "require": { @@ -4797,7 +4797,7 @@ "type": "tidelift" } ], - "time": "2025-06-21T15:19:35+00:00" + "time": "2025-08-02T09:36:06+00:00" }, { "name": "nette/schema", @@ -4949,16 +4949,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.5.0", + "version": "v5.6.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "ae59794362fe85e051a58ad36b289443f57be7a9" + "reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9", - "reference": "ae59794362fe85e051a58ad36b289443f57be7a9", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/221b0d0fdf1369c71047ad1d18bb5880017bbc56", + "reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56", "shasum": "" }, "require": { @@ -5001,9 +5001,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.0" }, - "time": "2025-05-31T08:24:38+00:00" + "time": "2025-07-27T20:03:57+00:00" }, { "name": "nubs/random-name-generator", @@ -6663,16 +6663,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.9", + "version": "v0.12.10", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "1b801844becfe648985372cb4b12ad6840245ace" + "reference": "6e80abe6f2257121f1eb9a4c55bf29d921025b22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/1b801844becfe648985372cb4b12ad6840245ace", - "reference": "1b801844becfe648985372cb4b12ad6840245ace", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/6e80abe6f2257121f1eb9a4c55bf29d921025b22", + "reference": "6e80abe6f2257121f1eb9a4c55bf29d921025b22", "shasum": "" }, "require": { @@ -6722,12 +6722,11 @@ "authors": [ { "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" + "email": "justin@justinhileman.info" } ], "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", + "homepage": "https://psysh.org", "keywords": [ "REPL", "console", @@ -6736,9 +6735,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.9" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.10" }, - "time": "2025-06-23T02:35:06+00:00" + "time": "2025-08-04T12:39:37+00:00" }, { "name": "purplepixie/phpdns", @@ -7247,16 +7246,16 @@ }, { "name": "sentry/sentry", - "version": "4.14.1", + "version": "4.14.2", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "a28c4a6f5fda2bf730789a638501d7a737a64eda" + "reference": "bfeec74303d60d3f8bc33701ab3e86f8a8729f17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/a28c4a6f5fda2bf730789a638501d7a737a64eda", - "reference": "a28c4a6f5fda2bf730789a638501d7a737a64eda", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/bfeec74303d60d3f8bc33701ab3e86f8a8729f17", + "reference": "bfeec74303d60d3f8bc33701ab3e86f8a8729f17", "shasum": "" }, "require": { @@ -7320,7 +7319,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/4.14.1" + "source": "https://github.com/getsentry/sentry-php/tree/4.14.2" }, "funding": [ { @@ -7332,7 +7331,7 @@ "type": "custom" } ], - "time": "2025-06-23T15:25:52+00:00" + "time": "2025-07-21T08:28:29+00:00" }, { "name": "sentry/sentry-laravel", @@ -7903,6 +7902,66 @@ ], "time": "2025-05-08T15:41:09+00:00" }, + { + "name": "spatie/commonmark-shiki-highlighter", + "version": "2.5.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/commonmark-shiki-highlighter.git", + "reference": "595c7e0b45d4a63b17dfc1ccbd13532d431ec351" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/commonmark-shiki-highlighter/zipball/595c7e0b45d4a63b17dfc1ccbd13532d431ec351", + "reference": "595c7e0b45d4a63b17dfc1ccbd13532d431ec351", + "shasum": "" + }, + "require": { + "league/commonmark": "^2.4.2", + "php": "^8.0", + "spatie/shiki-php": "^2.2.2", + "symfony/process": "^5.4|^6.4|^7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.19|^v3.49.0", + "phpunit/phpunit": "^9.5", + "spatie/phpunit-snapshot-assertions": "^4.2.7", + "spatie/ray": "^1.28" + }, + "type": "commonmark-extension", + "autoload": { + "psr-4": { + "Spatie\\CommonMarkShikiHighlighter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Highlight code blocks with league/commonmark and Shiki", + "homepage": "https://github.com/spatie/commonmark-shiki-highlighter", + "keywords": [ + "commonmark-shiki-highlighter", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/commonmark-shiki-highlighter/tree/2.5.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-01-13T11:25:47+00:00" + }, { "name": "spatie/laravel-activitylog", "version": "4.10.2", @@ -8077,6 +8136,82 @@ ], "time": "2025-06-25T11:36:37+00:00" }, + { + "name": "spatie/laravel-markdown", + "version": "2.7.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-markdown.git", + "reference": "353e7f9fae62826e26cbadef58a12ecf39685280" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-markdown/zipball/353e7f9fae62826e26cbadef58a12ecf39685280", + "reference": "353e7f9fae62826e26cbadef58a12ecf39685280", + "shasum": "" + }, + "require": { + "illuminate/cache": "^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^9.0|^10.0|^11.0|^12.0", + "illuminate/view": "^9.0|^10.0|^11.0|^12.0", + "league/commonmark": "^2.6.0", + "php": "^8.1", + "spatie/commonmark-shiki-highlighter": "^2.5", + "spatie/laravel-package-tools": "^1.4.3" + }, + "require-dev": { + "brianium/paratest": "^6.2|^7.8", + "nunomaduro/collision": "^5.3|^6.0|^7.0|^8.0", + "orchestra/testbench": "^6.15|^7.0|^8.0|^10.0", + "pestphp/pest": "^1.22|^2.0|^3.7", + "phpunit/phpunit": "^9.3|^11.5.3", + "spatie/laravel-ray": "^1.23", + "spatie/pest-plugin-snapshots": "^1.1|^2.2|^3.0", + "vimeo/psalm": "^4.8|^6.7" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\LaravelMarkdown\\MarkdownServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\LaravelMarkdown\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "A highly configurable markdown renderer and Blade component for Laravel", + "homepage": "https://github.com/spatie/laravel-markdown", + "keywords": [ + "Laravel-Markdown", + "laravel", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/laravel-markdown/tree/2.7.1" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-02-21T13:43:18+00:00" + }, { "name": "spatie/laravel-package-tools", "version": "1.92.7", @@ -8516,6 +8651,71 @@ ], "time": "2025-04-18T08:17:40+00:00" }, + { + "name": "spatie/shiki-php", + "version": "2.3.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/shiki-php.git", + "reference": "a2e78a9ff8a1290b25d550be8fbf8285c13175c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/shiki-php/zipball/a2e78a9ff8a1290b25d550be8fbf8285c13175c5", + "reference": "a2e78a9ff8a1290b25d550be8fbf8285c13175c5", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.0", + "symfony/process": "^5.4|^6.4|^7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^v3.0", + "pestphp/pest": "^1.8", + "phpunit/phpunit": "^9.5", + "spatie/pest-plugin-snapshots": "^1.1", + "spatie/ray": "^1.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\ShikiPhp\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Rias Van der Veken", + "email": "rias@spatie.be", + "role": "Developer" + }, + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Highlight code using Shiki in PHP", + "homepage": "https://github.com/spatie/shiki-php", + "keywords": [ + "shiki", + "spatie" + ], + "support": { + "source": "https://github.com/spatie/shiki-php/tree/2.3.2" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-02-21T14:16:57+00:00" + }, { "name": "spatie/url", "version": "2.4.0", @@ -8779,16 +8979,16 @@ }, { "name": "symfony/console", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "9e27aecde8f506ba0fd1d9989620c04a87697101" + "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/9e27aecde8f506ba0fd1d9989620c04a87697101", - "reference": "9e27aecde8f506ba0fd1d9989620c04a87697101", + "url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1", + "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1", "shasum": "" }, "require": { @@ -8853,7 +9053,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.3.1" + "source": "https://github.com/symfony/console/tree/v7.3.2" }, "funding": [ { @@ -8864,12 +9064,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-27T19:55:54+00:00" + "time": "2025-07-30T17:13:41+00:00" }, { "name": "symfony/css-selector", @@ -9005,16 +9209,16 @@ }, { "name": "symfony/error-handler", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "35b55b166f6752d6aaf21aa042fc5ed280fce235" + "reference": "0b31a944fcd8759ae294da4d2808cbc53aebd0c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/35b55b166f6752d6aaf21aa042fc5ed280fce235", - "reference": "35b55b166f6752d6aaf21aa042fc5ed280fce235", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/0b31a944fcd8759ae294da4d2808cbc53aebd0c3", + "reference": "0b31a944fcd8759ae294da4d2808cbc53aebd0c3", "shasum": "" }, "require": { @@ -9062,7 +9266,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.3.1" + "source": "https://github.com/symfony/error-handler/tree/v7.3.2" }, "funding": [ { @@ -9073,12 +9277,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-13T07:48:40+00:00" + "time": "2025-07-07T08:17:57+00:00" }, { "name": "symfony/event-dispatcher", @@ -9238,16 +9446,16 @@ }, { "name": "symfony/finder", - "version": "v7.3.0", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d" + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d", - "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d", + "url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe", + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe", "shasum": "" }, "require": { @@ -9282,7 +9490,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.3.0" + "source": "https://github.com/symfony/finder/tree/v7.3.2" }, "funding": [ { @@ -9293,25 +9501,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-12-30T19:00:26+00:00" + "time": "2025-07-15T13:41:35+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "23dd60256610c86a3414575b70c596e5deff6ed9" + "reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/23dd60256610c86a3414575b70c596e5deff6ed9", - "reference": "23dd60256610c86a3414575b70c596e5deff6ed9", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6877c122b3a6cc3695849622720054f6e6fa5fa6", + "reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6", "shasum": "" }, "require": { @@ -9361,7 +9573,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.3.1" + "source": "https://github.com/symfony/http-foundation/tree/v7.3.2" }, "funding": [ { @@ -9372,25 +9584,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-23T15:07:14+00:00" + "time": "2025-07-10T08:47:49+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "1644879a66e4aa29c36fe33dfa6c54b450ce1831" + "reference": "6ecc895559ec0097e221ed2fd5eb44d5fede083c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1644879a66e4aa29c36fe33dfa6c54b450ce1831", - "reference": "1644879a66e4aa29c36fe33dfa6c54b450ce1831", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6ecc895559ec0097e221ed2fd5eb44d5fede083c", + "reference": "6ecc895559ec0097e221ed2fd5eb44d5fede083c", "shasum": "" }, "require": { @@ -9475,7 +9691,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.3.1" + "source": "https://github.com/symfony/http-kernel/tree/v7.3.2" }, "funding": [ { @@ -9486,25 +9702,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-28T08:24:55+00:00" + "time": "2025-07-31T10:45:04+00:00" }, { "name": "symfony/mailer", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "b5db5105b290bdbea5ab27b89c69effcf1cb3368" + "reference": "d43e84d9522345f96ad6283d5dfccc8c1cfc299b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/b5db5105b290bdbea5ab27b89c69effcf1cb3368", - "reference": "b5db5105b290bdbea5ab27b89c69effcf1cb3368", + "url": "https://api.github.com/repos/symfony/mailer/zipball/d43e84d9522345f96ad6283d5dfccc8c1cfc299b", + "reference": "d43e84d9522345f96ad6283d5dfccc8c1cfc299b", "shasum": "" }, "require": { @@ -9555,7 +9775,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.3.1" + "source": "https://github.com/symfony/mailer/tree/v7.3.2" }, "funding": [ { @@ -9566,25 +9786,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-27T19:55:54+00:00" + "time": "2025-07-15T11:36:08+00:00" }, { "name": "symfony/mime", - "version": "v7.3.0", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9" + "reference": "e0a0f859148daf1edf6c60b398eb40bfc96697d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9", - "reference": "0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9", + "url": "https://api.github.com/repos/symfony/mime/zipball/e0a0f859148daf1edf6c60b398eb40bfc96697d1", + "reference": "e0a0f859148daf1edf6c60b398eb40bfc96697d1", "shasum": "" }, "require": { @@ -9639,7 +9863,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.3.0" + "source": "https://github.com/symfony/mime/tree/v7.3.2" }, "funding": [ { @@ -9650,25 +9874,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-02-19T08:51:26+00:00" + "time": "2025-07-15T13:41:35+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.3.0", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca" + "reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca", - "reference": "afb9a8038025e5dbc657378bfab9198d75f10fca", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/119bcf13e67dbd188e5dbc74228b1686f66acd37", + "reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37", "shasum": "" }, "require": { @@ -9706,7 +9934,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.3.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.3.2" }, "funding": [ { @@ -9717,12 +9945,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-04T13:12:05+00:00" + "time": "2025-07-15T11:36:08+00:00" }, { "name": "symfony/polyfill-ctype", @@ -10587,16 +10819,16 @@ }, { "name": "symfony/routing", - "version": "v7.3.0", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "8e213820c5fea844ecea29203d2a308019007c15" + "reference": "7614b8ca5fa89b9cd233e21b627bfc5774f586e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/8e213820c5fea844ecea29203d2a308019007c15", - "reference": "8e213820c5fea844ecea29203d2a308019007c15", + "url": "https://api.github.com/repos/symfony/routing/zipball/7614b8ca5fa89b9cd233e21b627bfc5774f586e4", + "reference": "7614b8ca5fa89b9cd233e21b627bfc5774f586e4", "shasum": "" }, "require": { @@ -10648,7 +10880,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.3.0" + "source": "https://github.com/symfony/routing/tree/v7.3.2" }, "funding": [ { @@ -10659,12 +10891,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-05-24T20:43:28+00:00" + "time": "2025-07-15T11:36:08+00:00" }, { "name": "symfony/service-contracts", @@ -10813,16 +11049,16 @@ }, { "name": "symfony/string", - "version": "v7.3.0", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125" + "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125", - "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125", + "url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca", + "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca", "shasum": "" }, "require": { @@ -10880,7 +11116,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.3.0" + "source": "https://github.com/symfony/string/tree/v7.3.2" }, "funding": [ { @@ -10891,25 +11127,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-20T20:19:01+00:00" + "time": "2025-07-10T08:47:49+00:00" }, { "name": "symfony/translation", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "241d5ac4910d256660238a7ecf250deba4c73063" + "reference": "81b48f4daa96272efcce9c7a6c4b58e629df3c90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/241d5ac4910d256660238a7ecf250deba4c73063", - "reference": "241d5ac4910d256660238a7ecf250deba4c73063", + "url": "https://api.github.com/repos/symfony/translation/zipball/81b48f4daa96272efcce9c7a6c4b58e629df3c90", + "reference": "81b48f4daa96272efcce9c7a6c4b58e629df3c90", "shasum": "" }, "require": { @@ -10976,7 +11216,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.3.1" + "source": "https://github.com/symfony/translation/tree/v7.3.2" }, "funding": [ { @@ -10987,12 +11227,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-27T19:55:54+00:00" + "time": "2025-07-30T17:31:46+00:00" }, { "name": "symfony/translation-contracts", @@ -11148,16 +11392,16 @@ }, { "name": "symfony/var-dumper", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "6e209fbe5f5a7b6043baba46fe5735a4b85d0d42" + "reference": "53205bea27450dc5c65377518b3275e126d45e75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/6e209fbe5f5a7b6043baba46fe5735a4b85d0d42", - "reference": "6e209fbe5f5a7b6043baba46fe5735a4b85d0d42", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/53205bea27450dc5c65377518b3275e126d45e75", + "reference": "53205bea27450dc5c65377518b3275e126d45e75", "shasum": "" }, "require": { @@ -11169,7 +11413,6 @@ "symfony/console": "<6.4" }, "require-dev": { - "ext-iconv": "*", "symfony/console": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", "symfony/process": "^6.4|^7.0", @@ -11212,7 +11455,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.3.1" + "source": "https://github.com/symfony/var-dumper/tree/v7.3.2" }, "funding": [ { @@ -11223,25 +11466,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-27T19:55:54+00:00" + "time": "2025-07-29T20:02:46+00:00" }, { "name": "symfony/yaml", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "0c3555045a46ab3cd4cc5a69d161225195230edb" + "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/0c3555045a46ab3cd4cc5a69d161225195230edb", - "reference": "0c3555045a46ab3cd4cc5a69d161225195230edb", + "url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30", + "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30", "shasum": "" }, "require": { @@ -11284,7 +11531,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.3.1" + "source": "https://github.com/symfony/yaml/tree/v7.3.2" }, "funding": [ { @@ -11295,12 +11542,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-03T06:57:57+00:00" + "time": "2025-07-10T08:47:49+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -12039,16 +12290,16 @@ "packages-dev": [ { "name": "barryvdh/laravel-debugbar", - "version": "v3.15.4", + "version": "v3.16.0", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-debugbar.git", - "reference": "c0667ea91f7185f1e074402c5788195e96bf8106" + "reference": "f265cf5e38577d42311f1a90d619bcd3740bea23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/c0667ea91f7185f1e074402c5788195e96bf8106", - "reference": "c0667ea91f7185f1e074402c5788195e96bf8106", + "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/f265cf5e38577d42311f1a90d619bcd3740bea23", + "reference": "f265cf5e38577d42311f1a90d619bcd3740bea23", "shasum": "" }, "require": { @@ -12056,7 +12307,7 @@ "illuminate/session": "^9|^10|^11|^12", "illuminate/support": "^9|^10|^11|^12", "php": "^8.1", - "php-debugbar/php-debugbar": "~2.1.1", + "php-debugbar/php-debugbar": "~2.2.0", "symfony/finder": "^6|^7" }, "require-dev": { @@ -12076,7 +12327,7 @@ ] }, "branch-alias": { - "dev-master": "3.15-dev" + "dev-master": "3.16-dev" } }, "autoload": { @@ -12108,7 +12359,7 @@ ], "support": { "issues": "https://github.com/barryvdh/laravel-debugbar/issues", - "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.15.4" + "source": "https://github.com/barryvdh/laravel-debugbar/tree/v3.16.0" }, "funding": [ { @@ -12120,7 +12371,7 @@ "type": "github" } ], - "time": "2025-04-16T06:32:06+00:00" + "time": "2025-07-14T11:56:43+00:00" }, { "name": "brianium/paratest", @@ -12641,16 +12892,16 @@ }, { "name": "laravel/telescope", - "version": "v5.10.0", + "version": "v5.10.2", "source": { "type": "git", "url": "https://github.com/laravel/telescope.git", - "reference": "fc0a8662682c0375b534033873debb780c003486" + "reference": "6d249d93ab06dc147ac62ea02b4272c2e7a24b72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/telescope/zipball/fc0a8662682c0375b534033873debb780c003486", - "reference": "fc0a8662682c0375b534033873debb780c003486", + "url": "https://api.github.com/repos/laravel/telescope/zipball/6d249d93ab06dc147ac62ea02b4272c2e7a24b72", + "reference": "6d249d93ab06dc147ac62ea02b4272c2e7a24b72", "shasum": "" }, "require": { @@ -12704,9 +12955,9 @@ ], "support": { "issues": "https://github.com/laravel/telescope/issues", - "source": "https://github.com/laravel/telescope/tree/v5.10.0" + "source": "https://github.com/laravel/telescope/tree/v5.10.2" }, - "time": "2025-07-07T14:47:19+00:00" + "time": "2025-07-24T05:26:13+00:00" }, { "name": "mockery/mockery", @@ -12793,16 +13044,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.13.3", + "version": "1.13.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "faed855a7b5f4d4637717c2b3863e277116beb36" + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/faed855a7b5f4d4637717c2b3863e277116beb36", - "reference": "faed855a7b5f4d4637717c2b3863e277116beb36", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { @@ -12841,7 +13092,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.3" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" }, "funding": [ { @@ -12849,7 +13100,7 @@ "type": "tidelift" } ], - "time": "2025-07-05T12:25:42+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { "name": "nunomaduro/collision", @@ -13394,16 +13645,16 @@ }, { "name": "php-debugbar/php-debugbar", - "version": "v2.1.6", + "version": "v2.2.4", "source": { "type": "git", "url": "https://github.com/php-debugbar/php-debugbar.git", - "reference": "16fa68da5617220594aa5e33fa9de415f94784a0" + "reference": "3146d04671f51f69ffec2a4207ac3bdcf13a9f35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/16fa68da5617220594aa5e33fa9de415f94784a0", - "reference": "16fa68da5617220594aa5e33fa9de415f94784a0", + "url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/3146d04671f51f69ffec2a4207ac3bdcf13a9f35", + "reference": "3146d04671f51f69ffec2a4207ac3bdcf13a9f35", "shasum": "" }, "require": { @@ -13411,6 +13662,9 @@ "psr/log": "^1|^2|^3", "symfony/var-dumper": "^4|^5|^6|^7" }, + "replace": { + "maximebf/debugbar": "self.version" + }, "require-dev": { "dbrekelmans/bdi": "^1", "phpunit/phpunit": "^8|^9", @@ -13425,7 +13679,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -13458,9 +13712,9 @@ ], "support": { "issues": "https://github.com/php-debugbar/php-debugbar/issues", - "source": "https://github.com/php-debugbar/php-debugbar/tree/v2.1.6" + "source": "https://github.com/php-debugbar/php-debugbar/tree/v2.2.4" }, - "time": "2025-02-21T17:47:03+00:00" + "time": "2025-07-22T14:01:30+00:00" }, { "name": "php-webdriver/webdriver", @@ -13530,16 +13784,16 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.18", + "version": "2.1.21", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "ee1f390b7a70cdf74a2b737e554f68afea885db7" + "reference": "1ccf445757458c06a04eb3f803603cb118fe5fa6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ee1f390b7a70cdf74a2b737e554f68afea885db7", - "reference": "ee1f390b7a70cdf74a2b737e554f68afea885db7", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1ccf445757458c06a04eb3f803603cb118fe5fa6", + "reference": "1ccf445757458c06a04eb3f803603cb118fe5fa6", "shasum": "" }, "require": { @@ -13584,7 +13838,7 @@ "type": "github" } ], - "time": "2025-07-17T17:22:31+00:00" + "time": "2025-07-28T19:35:08+00:00" }, { "name": "phpunit/php-code-coverage", @@ -15436,16 +15690,16 @@ }, { "name": "symfony/http-client", - "version": "v7.3.1", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "4403d87a2c16f33345dca93407a8714ee8c05a64" + "reference": "1c064a0c67749923483216b081066642751cc2c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/4403d87a2c16f33345dca93407a8714ee8c05a64", - "reference": "4403d87a2c16f33345dca93407a8714ee8c05a64", + "url": "https://api.github.com/repos/symfony/http-client/zipball/1c064a0c67749923483216b081066642751cc2c7", + "reference": "1c064a0c67749923483216b081066642751cc2c7", "shasum": "" }, "require": { @@ -15511,7 +15765,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.3.1" + "source": "https://github.com/symfony/http-client/tree/v7.3.2" }, "funding": [ { @@ -15522,12 +15776,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-06-28T07:58:39+00:00" + "time": "2025-07-15T11:36:08+00:00" }, { "name": "symfony/http-client-contracts", diff --git a/config/constants.php b/config/constants.php index ae984aa18..bbd442654 100644 --- a/config/constants.php +++ b/config/constants.php @@ -2,9 +2,9 @@ return [ 'coolify' => [ - 'version' => '4.0.0-beta.420.6', - 'helper_version' => '1.0.8', - 'realtime_version' => '1.0.9', + 'version' => '4.0.0-beta.420.7', + 'helper_version' => '1.0.9', + 'realtime_version' => '1.0.10', 'self_hosted' => env('SELF_HOSTED', true), 'autoupdate' => env('AUTOUPDATE'), 'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'), @@ -22,7 +22,8 @@ return [ 'services' => [ // Temporary disabled until cache is implemented // 'official' => 'https://cdn.coollabs.io/coolify/service-templates.json', - 'official' => 'https://raw.githubusercontent.com/coollabsio/coolify/main/templates/service-templates.json', + 'official' => 'https://raw.githubusercontent.com/coollabsio/coolify/v4.x/templates/service-templates-latest.json', + 'file_name' => 'service-templates-latest.json', ], 'terminal' => [ @@ -69,6 +70,10 @@ return [ ], ], + 'email_change' => [ + 'verification_code_expiry_minutes' => 10, + ], + 'sentry' => [ 'sentry_dsn' => env('SENTRY_DSN'), ], diff --git a/config/horizon.php b/config/horizon.php index 6086b30da..cdabcb1e8 100644 --- a/config/horizon.php +++ b/config/horizon.php @@ -182,14 +182,15 @@ return [ 'defaults' => [ 's6' => [ 'connection' => 'redis', - 'queue' => ['high', 'default'], - 'balance' => env('HORIZON_BALANCE', 'auto'), - 'maxTime' => 0, - 'maxJobs' => 0, + 'balance' => env('HORIZON_BALANCE', 'false'), + 'queue' => env('HORIZON_QUEUES', 'high,default'), + 'maxTime' => 3600, + 'maxJobs' => 400, 'memory' => 128, 'tries' => 1, - 'timeout' => 3560, 'nice' => 0, + 'sleep' => 3, + 'timeout' => 3600, ], ], @@ -198,7 +199,7 @@ return [ 's6' => [ 'autoScalingStrategy' => 'size', 'minProcesses' => env('HORIZON_MIN_PROCESSES', 1), - 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 6), + 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 4), 'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1), 'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1), ], @@ -208,7 +209,7 @@ return [ 's6' => [ 'autoScalingStrategy' => 'size', 'minProcesses' => env('HORIZON_MIN_PROCESSES', 1), - 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 6), + 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 4), 'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1), 'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1), ], diff --git a/config/logging.php b/config/logging.php index 4c3df4ce1..488327414 100644 --- a/config/logging.php +++ b/config/logging.php @@ -118,6 +118,20 @@ return [ 'emergency' => [ 'path' => storage_path('logs/laravel.log'), ], + + 'scheduled' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/scheduled.log'), + 'level' => 'debug', + 'days' => 1, + ], + + 'scheduled-errors' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/scheduled-errors.log'), + 'level' => 'debug', + 'days' => 7, + ], ], ]; diff --git a/config/services.php b/config/services.php index 7add50a5c..6a21cda18 100644 --- a/config/services.php +++ b/config/services.php @@ -65,6 +65,6 @@ return [ 'client_secret' => env('ZITADEL_CLIENT_SECRET'), 'redirect' => env('ZITADEL_REDIRECT_URI'), 'base_url' => env('ZITADEL_BASE_URL'), - ] + ], ]; diff --git a/database/migrations/2025_07_14_191016_add_deleted_at_to_application_previews_table.php b/database/migrations/2025_07_14_191016_add_deleted_at_to_application_previews_table.php new file mode 100644 index 000000000..25aa0f5f0 --- /dev/null +++ b/database/migrations/2025_07_14_191016_add_deleted_at_to_application_previews_table.php @@ -0,0 +1,28 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + /** + * Run the migrations. + */ + public function up(): void + { + Schema::table('application_previews', function (Blueprint $table) { + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('application_previews', function (Blueprint $table) { + $table->dropSoftDeletes(); + }); + } +}; diff --git a/database/migrations/2025_07_16_202201_add_timeout_to_scheduled_database_backups_table.php b/database/migrations/2025_07_16_202201_add_timeout_to_scheduled_database_backups_table.php new file mode 100644 index 000000000..f8f8cb8ad --- /dev/null +++ b/database/migrations/2025_07_16_202201_add_timeout_to_scheduled_database_backups_table.php @@ -0,0 +1,18 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + /** + * Run the migrations. + */ + public function up(): void + { + Schema::table('scheduled_database_backups', function (Blueprint $table) { + $table->integer('timeout')->default(3600); + }); + } +}; diff --git a/database/migrations/2025_08_07_142403_create_user_changelog_reads_table.php b/database/migrations/2025_08_07_142403_create_user_changelog_reads_table.php new file mode 100644 index 000000000..db8a42fb7 --- /dev/null +++ b/database/migrations/2025_08_07_142403_create_user_changelog_reads_table.php @@ -0,0 +1,34 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + /** + * Run the migrations. + */ + public function up(): void + { + Schema::create('user_changelog_reads', function (Blueprint $table) { + $table->id(); + $table->foreignId('user_id')->constrained()->onDelete('cascade'); + $table->string('release_tag'); // GitHub tag_name (e.g., "v4.0.0-beta.420.6") + $table->timestamp('read_at'); + $table->timestamps(); + + $table->unique(['user_id', 'release_tag']); + $table->index('user_id'); + $table->index('release_tag'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('user_changelog_reads'); + } +}; diff --git a/database/migrations/2025_08_17_102422_add_disable_local_backup_to_scheduled_database_backups_table.php b/database/migrations/2025_08_17_102422_add_disable_local_backup_to_scheduled_database_backups_table.php new file mode 100644 index 000000000..e414472df --- /dev/null +++ b/database/migrations/2025_08_17_102422_add_disable_local_backup_to_scheduled_database_backups_table.php @@ -0,0 +1,28 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + /** + * Run the migrations. + */ + public function up(): void + { + Schema::table('scheduled_database_backups', function (Blueprint $table) { + $table->boolean('disable_local_backup')->default(false)->after('save_s3'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('scheduled_database_backups', function (Blueprint $table) { + $table->dropColumn('disable_local_backup'); + }); + } +}; diff --git a/database/migrations/2025_08_18_104146_add_email_change_fields_to_users_table.php b/database/migrations/2025_08_18_104146_add_email_change_fields_to_users_table.php new file mode 100644 index 000000000..9cefe2c09 --- /dev/null +++ b/database/migrations/2025_08_18_104146_add_email_change_fields_to_users_table.php @@ -0,0 +1,30 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + /** + * Run the migrations. + */ + public function up(): void + { + Schema::table('users', function (Blueprint $table) { + $table->string('pending_email')->nullable()->after('email'); + $table->string('email_change_code', 6)->nullable()->after('pending_email'); + $table->timestamp('email_change_code_expires_at')->nullable()->after('email_change_code'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn(['pending_email', 'email_change_code', 'email_change_code_expires_at']); + }); + } +}; diff --git a/database/migrations/2025_08_18_154244_change_env_sorting_default_to_false.php b/database/migrations/2025_08_18_154244_change_env_sorting_default_to_false.php new file mode 100644 index 000000000..32ed075ba --- /dev/null +++ b/database/migrations/2025_08_18_154244_change_env_sorting_default_to_false.php @@ -0,0 +1,18 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + /** + * Run the migrations. + */ + public function up(): void + { + Schema::table('application_settings', function (Blueprint $table) { + $table->boolean('is_env_sorting_enabled')->default(false)->change(); + }); + } +}; diff --git a/database/migrations/2025_08_21_080234_add_git_shallow_clone_to_application_settings_table.php b/database/migrations/2025_08_21_080234_add_git_shallow_clone_to_application_settings_table.php new file mode 100644 index 000000000..399c49c7f --- /dev/null +++ b/database/migrations/2025_08_21_080234_add_git_shallow_clone_to_application_settings_table.php @@ -0,0 +1,28 @@ +<?php + +use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; + +return new class extends Migration +{ + /** + * Run the migrations. + */ + public function up(): void + { + Schema::table('application_settings', function (Blueprint $table) { + $table->boolean('is_git_shallow_clone_enabled')->default(true)->after('is_git_lfs_enabled'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('is_git_shallow_clone_enabled'); + }); + } +}; diff --git a/docker/coolify-helper/Dockerfile b/docker/coolify-helper/Dockerfile index b62469cef..8c7073519 100644 --- a/docker/coolify-helper/Dockerfile +++ b/docker/coolify-helper/Dockerfile @@ -4,15 +4,15 @@ ARG BASE_IMAGE=alpine:3.21 # https://download.docker.com/linux/static/stable/ ARG DOCKER_VERSION=28.0.0 # https://github.com/docker/compose/releases -ARG DOCKER_COMPOSE_VERSION=2.34.0 +ARG DOCKER_COMPOSE_VERSION=2.38.2 # https://github.com/docker/buildx/releases -ARG DOCKER_BUILDX_VERSION=0.22.0 +ARG DOCKER_BUILDX_VERSION=0.25.0 # https://github.com/buildpacks/pack/releases -ARG PACK_VERSION=0.37.0 +ARG PACK_VERSION=0.38.2 # https://github.com/railwayapp/nixpacks/releases -ARG NIXPACKS_VERSION=1.34.1 +ARG NIXPACKS_VERSION=1.39.0 # https://github.com/minio/mc/releases -ARG MINIO_VERSION=RELEASE.2025-03-12T17-29-24Z +ARG MINIO_VERSION=RELEASE.2025-05-21T01-59-54Z FROM minio/mc:${MINIO_VERSION} AS minio-client diff --git a/docker/coolify-realtime/Dockerfile b/docker/coolify-realtime/Dockerfile index 7a24200d6..18c2f9301 100644 --- a/docker/coolify-realtime/Dockerfile +++ b/docker/coolify-realtime/Dockerfile @@ -2,7 +2,7 @@ # https://github.com/soketi/soketi/releases ARG SOKETI_VERSION=1.6-16-alpine # https://github.com/cloudflare/cloudflared/releases -ARG CLOUDFLARED_VERSION=2025.5.0 +ARG CLOUDFLARED_VERSION=2025.7.0 FROM quay.io/soketi/soketi:${SOKETI_VERSION} diff --git a/docker/coolify-realtime/package-lock.json b/docker/coolify-realtime/package-lock.json index 1c329e47f..49907cbd4 100644 --- a/docker/coolify-realtime/package-lock.json +++ b/docker/coolify-realtime/package-lock.json @@ -181,14 +181,15 @@ } }, "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -323,9 +324,9 @@ } }, "node_modules/nan": { - "version": "2.22.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.1.tgz", - "integrity": "sha512-pfRR4ZcNTSm2ZFHaztuvbICf+hyiG6ecA06SfAxoPmuHjvMu0KUIae7Y8GyVkbBqeEIidsmXeYooWIX9+qjfRQ==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz", + "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==", "license": "MIT" }, "node_modules/node-pty": { diff --git a/docker/development/Dockerfile b/docker/development/Dockerfile index 8c5beec07..85cce14d7 100644 --- a/docker/development/Dockerfile +++ b/docker/development/Dockerfile @@ -2,9 +2,9 @@ # https://hub.docker.com/r/serversideup/php/tags?name=8.4-fpm-nginx-alpine ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine # https://github.com/minio/mc/releases -ARG MINIO_VERSION=RELEASE.2025-03-12T17-29-24Z +ARG MINIO_VERSION=RELEASE.2025-05-21T01-59-54Z # https://github.com/cloudflare/cloudflared/releases -ARG CLOUDFLARED_VERSION=2025.2.0 +ARG CLOUDFLARED_VERSION=2025.7.0 # https://www.postgresql.org/support/versioning/ ARG POSTGRES_VERSION=15 diff --git a/docker/production/Dockerfile b/docker/production/Dockerfile index 5633170e3..6c9628a81 100644 --- a/docker/production/Dockerfile +++ b/docker/production/Dockerfile @@ -2,9 +2,9 @@ # https://hub.docker.com/r/serversideup/php/tags?name=8.4-fpm-nginx-alpine ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine # https://github.com/minio/mc/releases -ARG MINIO_VERSION=RELEASE.2025-03-12T17-29-24Z +ARG MINIO_VERSION=RELEASE.2025-05-21T01-59-54Z # https://github.com/cloudflare/cloudflared/releases -ARG CLOUDFLARED_VERSION=2025.2.0 +ARG CLOUDFLARED_VERSION=2025.7.0 # https://www.postgresql.org/support/versioning/ ARG POSTGRES_VERSION=15 @@ -120,6 +120,7 @@ COPY --chown=www-data:www-data templates ./templates COPY --chown=www-data:www-data resources/views ./resources/views COPY --chown=www-data:www-data artisan artisan COPY --chown=www-data:www-data openapi.yaml ./openapi.yaml +COPY --chown=www-data:www-data changelogs/ ./changelogs/ RUN composer dump-autoload diff --git a/docker/testing-host/Dockerfile b/docker/testing-host/Dockerfile index b19d0875c..fdad3cc41 100644 --- a/docker/testing-host/Dockerfile +++ b/docker/testing-host/Dockerfile @@ -2,9 +2,9 @@ # https://download.docker.com/linux/static/stable/ ARG DOCKER_VERSION=28.0.0 # https://github.com/docker/compose/releases -ARG DOCKER_COMPOSE_VERSION=2.34.0 +ARG DOCKER_COMPOSE_VERSION=2.38.2 # https://github.com/docker/buildx/releases -ARG DOCKER_BUILDX_VERSION=0.22.0 +ARG DOCKER_BUILDX_VERSION=0.25.0 FROM debian:12-slim diff --git a/lang/ar.json b/lang/ar.json index 263924c24..c966cc686 100644 --- a/lang/ar.json +++ b/lang/ar.json @@ -11,7 +11,8 @@ "auth.login.infomaniak": "تسجيل الدخول باستخدام Infomaniak", "auth.already_registered": "هل سبق لك التسجيل؟", "auth.confirm_password": "تأكيد كلمة المرور", - "auth.forgot_password": "نسيت كلمة المرور", + "auth.forgot_password_link": "هل نسيت كلمة المرور؟", + "auth.forgot_password_heading": "استعادة كلمة المرور", "auth.forgot_password_send_email": "إرسال بريد إلكتروني لإعادة تعيين كلمة المرور", "auth.register_now": "تسجيل", "auth.logout": "تسجيل الخروج", @@ -39,4 +40,4 @@ "resource.delete_configurations": "حذف جميع ملفات التعريف من الخادم بشكل دائم.", "database.delete_backups_locally": "حذف كافة النسخ الاحتياطية نهائيًا من التخزين المحلي.", "warning.sslipdomain": "تم حفظ ملفات التعريف الخاصة بك، ولكن استخدام نطاق sslip مع https <span class='dark:text-red-500 text-red-500 font-bold'>غير</span> مستحسن، لأن خوادم Let's Encrypt مع هذا النطاق العام محدودة المعدل (ستفشل عملية التحقق من شهادة SSL). <br><br>استخدم نطاقك الخاص بدلاً من ذلك." -} +} \ No newline at end of file diff --git a/lang/az.json b/lang/az.json index 92f56ddbc..85cee7589 100644 --- a/lang/az.json +++ b/lang/az.json @@ -11,7 +11,8 @@ "auth.login.infomaniak": "Infomaniak ilə daxil ol", "auth.already_registered": "Qeytiyatınız var?", "auth.confirm_password": "Şifrəni təsdiqləyin", - "auth.forgot_password": "Şifrəmi unutdum", + "auth.forgot_password_link": "Şifrəmi unutdum?", + "auth.forgot_password_heading": "Şifrəni bərpa et", "auth.forgot_password_send_email": "Şifrəni sıfırlamaq üçün e-poçt göndər", "auth.register_now": "Qeydiyyat", "auth.logout": "Çıxış", @@ -39,4 +40,4 @@ "resource.delete_configurations": "Serverdən bütün konfiqurasiya faylları tamamilə silinəcək.", "database.delete_backups_locally": "Bütün ehtiyat nüsxələr lokal yaddaşdan tamamilə silinəcək.", "warning.sslipdomain": "Konfiqurasiya yadda saxlanıldı, lakin sslip domeni ilə https <span class='dark:text-red-500 text-red-500 font-bold'>TÖVSİYƏ EDİLMİR</span>, çünki Let's Encrypt serverləri bu ümumi domenlə məhdudlaşdırılır (SSL sertifikatının təsdiqlənməsi uğursuz olacaq). <br><br>Əvəzində öz domeninizdən istifadə edin." -} +} \ No newline at end of file diff --git a/lang/cs.json b/lang/cs.json index 00455aa81..9e5d2c44e 100644 --- a/lang/cs.json +++ b/lang/cs.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "Přihlásit se pomocí Infomaniak", "auth.already_registered": "Již jste registrováni?", "auth.confirm_password": "Potvrďte heslo", - "auth.forgot_password": "Zapomněli jste heslo", + "auth.forgot_password_link": "Zapomněli jste heslo?", + "auth.forgot_password_heading": "Obnovení hesla", "auth.forgot_password_send_email": "Poslat e-mail pro resetování hesla", "auth.register_now": "Registrovat se", "auth.logout": "Odhlásit se", @@ -30,4 +31,4 @@ "input.recovery_code": "Obnovovací kód", "button.save": "Uložit", "repository.url": "<span class='text-helper'>Příklady</span><br>Pro veřejné repozitáře, použijte <span class='text-helper'>https://...</span>.<br>Pro soukromé repozitáře, použijte <span class='text-helper'>git@...</span>.<br><br>https://github.com/coollabsio/coolify-examples <span class='text-helper'>main</span> branch bude zvolena<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify <span class='text-helper'>nodejs-fastify</span> branch bude vybrána.<br>https://gitea.com/sedlav/expressjs.git <span class='text-helper'>main</span> branch vybrána.<br>https://gitlab.com/andrasbacsai/nodejs-example.git <span class='text-helper'>main</span> branch bude vybrána." -} +} \ No newline at end of file diff --git a/lang/de.json b/lang/de.json index f56b21710..fd587de22 100644 --- a/lang/de.json +++ b/lang/de.json @@ -11,7 +11,8 @@ "auth.login.zitadel": "Mit Zitadel anmelden", "auth.already_registered": "Bereits registriert?", "auth.confirm_password": "Passwort bestätigen", - "auth.forgot_password": "Passwort vergessen", + "auth.forgot_password_link": "Passwort vergessen?", + "auth.forgot_password_heading": "Passwort-Wiederherstellung", "auth.forgot_password_send_email": "Passwort zurücksetzen E-Mail senden", "auth.register_now": "Registrieren", "auth.logout": "Abmelden", @@ -31,4 +32,4 @@ "input.recovery_code": "Wiederherstellungscode", "button.save": "Speichern", "repository.url": "<span class='text-helper'>Beispiele</span><br>Für öffentliche Repositories benutze <span class='text-helper'>https://...</span>.<br>Für private Repositories benutze <span class='text-helper'>git@...</span>.<br><br>https://github.com/coollabsio/coolify-examples <span class='text-helper'>main</span> Branch wird ausgewählt<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify <span class='text-helper'>nodejs-fastify</span> Branch wird ausgewählt.<br>https://gitea.com/sedlav/expressjs.git <span class='text-helper'>main</span> Branch wird ausgewählt.<br>https://gitlab.com/andrasbacsai/nodejs-example.git <span class='text-helper'>main</span> Branch wird ausgewählt." -} +} \ No newline at end of file diff --git a/lang/en.json b/lang/en.json index 4a398a9f9..af7f2145d 100644 --- a/lang/en.json +++ b/lang/en.json @@ -12,7 +12,8 @@ "auth.login.zitadel": "Login with Zitadel", "auth.already_registered": "Already registered?", "auth.confirm_password": "Confirm password", - "auth.forgot_password": "Forgot password", + "auth.forgot_password_link": "Forgot password?", + "auth.forgot_password_heading": "Password recovery", "auth.forgot_password_send_email": "Send password reset email", "auth.register_now": "Register", "auth.logout": "Logout", @@ -40,4 +41,4 @@ "resource.delete_configurations": "Permanently delete all configuration files from the server.", "database.delete_backups_locally": "All backups will be permanently deleted from local storage.", "warning.sslipdomain": "Your configuration is saved, but sslip domain with https is <span class='dark:text-red-500 text-red-500 font-bold'>NOT</span> recommended, because Let's Encrypt servers with this public domain are rate limited (SSL certificate validation will fail). <br><br>Use your own domain instead." -} +} \ No newline at end of file diff --git a/lang/es.json b/lang/es.json index 73363a9bf..f56387f05 100644 --- a/lang/es.json +++ b/lang/es.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "Acceder con Infomaniak", "auth.already_registered": "¿Ya estás registrado?", "auth.confirm_password": "Confirmar contraseña", - "auth.forgot_password": "¿Olvidaste tu contraseña?", + "auth.forgot_password_link": "¿Olvidaste tu contraseña?", + "auth.forgot_password_heading": "Recuperación de contraseña", "auth.forgot_password_send_email": "Enviar correo de recuperación de contraseña", "auth.register_now": "Registrar", "auth.logout": "Cerrar sesión", @@ -30,4 +31,4 @@ "input.recovery_code": "Código de recuperación", "button.save": "Guardar", "repository.url": "<span class='text-helper'>Examples</span><br>Para repositorios públicos, usar <span class='text-helper'>https://...</span>.<br>Para repositorios privados, usar <span class='text-helper'>git@...</span>.<br><br>https://github.com/coollabsio/coolify-examples <span class='text-helper'>main</span> la rama 'main' será seleccionada.<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify <span class='text-helper'>nodejs-fastify</span> la rama 'nodejs-fastify' será seleccionada.<br>https://gitea.com/sedlav/expressjs.git <span class='text-helper'>main</span> la rama 'main' será seleccionada.<br>https://gitlab.com/andrasbacsai/nodejs-example.git <span class='text-helper'>main</span> la rama 'main' será seleccionada." -} +} \ No newline at end of file diff --git a/lang/fa.json b/lang/fa.json index d68049e77..ae22ee946 100644 --- a/lang/fa.json +++ b/lang/fa.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "ورود با Infomaniak", "auth.already_registered": "قبلاً ثبت نام کرده‌اید؟", "auth.confirm_password": "تایید رمز عبور", - "auth.forgot_password": "فراموشی رمز عبور", + "auth.forgot_password_link": "رمز عبور را فراموش کرده‌اید؟", + "auth.forgot_password_heading": "بازیابی رمز عبور", "auth.forgot_password_send_email": "ارسال ایمیل بازیابی رمز عبور", "auth.register_now": "ثبت نام", "auth.logout": "خروج", @@ -30,4 +31,4 @@ "input.recovery_code": "کد بازیابی", "button.save": "ذخیره", "repository.url": "<span class='text-helper'>مثال‌ها</span><br>برای مخازن عمومی، از <span class='text-helper'>https://...</span> استفاده کنید.<br>برای مخازن خصوصی، از <span class='text-helper'>git@...</span> استفاده کنید.<br><br>شاخه <span class='text-helper'>main</span> انتخاب خواهد شد.<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify شاخه <span class='text-helper'>nodejs-fastify</span> انتخاب خواهد شد.<br>https://gitea.com/sedlav/expressjs.git شاخه <span class='text-helper'>main</span> انتخاب خواهد شد.<br>https://gitlab.com/andrasbacsai/nodejs-example.git شاخه <span class='text-helper'>main</span> انتخاب خواهد شد." -} +} \ No newline at end of file diff --git a/lang/fr.json b/lang/fr.json index 2516d0f69..d98a1ebc8 100644 --- a/lang/fr.json +++ b/lang/fr.json @@ -11,7 +11,8 @@ "auth.login.infomaniak": "Connexion avec Infomaniak", "auth.already_registered": "Déjà enregistré ?", "auth.confirm_password": "Confirmer le mot de passe", - "auth.forgot_password": "Mot de passe oublié", + "auth.forgot_password_link": "Mot de passe oublié ?", + "auth.forgot_password_heading": "Récupération du mot de passe", "auth.forgot_password_send_email": "Envoyer l'email de réinitialisation de mot de passe", "auth.register_now": "S'enregistrer", "auth.logout": "Déconnexion", @@ -39,4 +40,4 @@ "resource.delete_configurations": "Supprimer définitivement tous les fichiers de configuration du serveur.", "database.delete_backups_locally": "Toutes les sauvegardes seront définitivement supprimées du stockage local.", "warning.sslipdomain": "Votre configuration est enregistrée, mais l'utilisation du domaine sslip avec https <span class='dark:text-red-500 text-red-500 font-bold'>N'EST PAS</span> recommandée, car les serveurs Let's Encrypt avec ce domaine public sont limités en taux (la validation du certificat SSL échouera). <br><br>Utilisez plutôt votre propre domaine." -} +} \ No newline at end of file diff --git a/lang/id.json b/lang/id.json index b0e38197a..d85176cda 100644 --- a/lang/id.json +++ b/lang/id.json @@ -11,7 +11,8 @@ "auth.login.infomaniak": "Masuk dengan Infomaniak", "auth.already_registered": "Sudah terdaftar?", "auth.confirm_password": "Konfirmasi kata sandi", - "auth.forgot_password": "Lupa kata sandi", + "auth.forgot_password_link": "Lupa kata sandi?", + "auth.forgot_password_heading": "Pemulihan Kata Sandi", "auth.forgot_password_send_email": "Kirim email reset kata sandi", "auth.register_now": "Daftar", "auth.logout": "Keluar", @@ -39,4 +40,4 @@ "resource.delete_configurations": "Hapus permanen semua file konfigurasi dari server.", "database.delete_backups_locally": "Semua backup akan dihapus permanen dari penyimpanan lokal.", "warning.sslipdomain": "Konfigurasi Anda disimpan, tetapi domain sslip dengan https <span class='font-bold text-red-500 dark:text-red-500'>TIDAK</span> direkomendasikan, karena server Let's Encrypt dengan domain publik ini dibatasi (validasi sertifikat SSL akan gagal). <br><br>Gunakan domain Anda sendiri sebagai gantinya." -} +} \ No newline at end of file diff --git a/lang/it.json b/lang/it.json index c0edc314b..e4c1a9c05 100644 --- a/lang/it.json +++ b/lang/it.json @@ -11,7 +11,8 @@ "auth.login.infomaniak": "Accedi con Infomaniak", "auth.already_registered": "Già registrato?", "auth.confirm_password": "Conferma password", - "auth.forgot_password": "Password dimenticata", + "auth.forgot_password_link": "Hai dimenticato la password?", + "auth.forgot_password_heading": "Recupero password", "auth.forgot_password_send_email": "Invia email per reimpostare la password", "auth.register_now": "Registrati", "auth.logout": "Esci", @@ -39,4 +40,4 @@ "resource.delete_configurations": "Elimina definitivamente tutti i file di configurazione dal server.", "database.delete_backups_locally": "Tutti i backup verranno eliminati definitivamente dall'archiviazione locale.", "warning.sslipdomain": "La tua configurazione è stata salvata, ma il dominio sslip con https <span class='dark:text-red-500 text-red-500 font-bold'>NON</span> è raccomandato, poiché i server di Let's Encrypt con questo dominio pubblico hanno limitazioni di frequenza (la convalida del certificato SSL fallirà). <br><br>Utilizza invece il tuo dominio personale." -} +} \ No newline at end of file diff --git a/lang/ja.json b/lang/ja.json index 87d87d99b..05987e7ce 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "Infomaniakでログイン", "auth.already_registered": "すでに登録済みですか?", "auth.confirm_password": "パスワードを確認", - "auth.forgot_password": "パスワードを忘れた", + "auth.forgot_password_link": "パスワードをお忘れですか?", + "auth.forgot_password_heading": "パスワードの再設定", "auth.forgot_password_send_email": "パスワードリセットメールを送信", "auth.register_now": "今すぐ登録", "auth.logout": "ログアウト", @@ -30,4 +31,4 @@ "input.recovery_code": "リカバリーコード", "button.save": "保存", "repository.url": "<span class='text-helper'>例</span><br>公開リポジトリの場合は<span class='text-helper'>https://...</span>を使用してください。<br>プライベートリポジトリの場合は<span class='text-helper'>git@...</span>を使用してください。<br><br>https://github.com/coollabsio/coolify-examples <span class='text-helper'>main</span>ブランチが選択されます<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify <span class='text-helper'>nodejs-fastify</span>ブランチが選択されます。<br>https://gitea.com/sedlav/expressjs.git <span class='text-helper'>main</span>ブランチが選択されます。<br>https://gitlab.com/andrasbacsai/nodejs-example.git <span class='text-helper'>main</span>ブランチが選択されます。" -} +} \ No newline at end of file diff --git a/lang/no.json b/lang/no.json index a84f6aa6c..967bdf606 100644 --- a/lang/no.json +++ b/lang/no.json @@ -11,7 +11,8 @@ "auth.login.infomaniak": "Logg inn med Infomaniak", "auth.already_registered": "Allerede registrert?", "auth.confirm_password": "Bekreft passord", - "auth.forgot_password": "Glemt passord", + "auth.forgot_password_link": "Glemt passord?", + "auth.forgot_password_heading": "Gjenoppretting av passord", "auth.forgot_password_send_email": "Send e-post for tilbakestilling av passord", "auth.register_now": "Registrer deg", "auth.logout": "Logg ut", @@ -39,4 +40,4 @@ "resource.delete_configurations": "Slett alle konfigurasjonsfiler fra serveren permanent.", "database.delete_backups_locally": "Alle sikkerhetskopier vil bli slettet permanent fra lokal lagring.", "warning.sslipdomain": "Konfigurasjonen din er lagret, men sslip-domene med https er <span class='dark:text-red-500 text-red-500 font-bold'>IKKE</span> anbefalt, fordi Let's Encrypt-servere med dette offentlige domenet er hastighetsbegrenset (SSL-sertifikatvalidering vil mislykkes). <br><br>Bruk ditt eget domene i stedet." -} +} \ No newline at end of file diff --git a/lang/pl.json b/lang/pl.json new file mode 100644 index 000000000..bcd8e2393 --- /dev/null +++ b/lang/pl.json @@ -0,0 +1,44 @@ +{ + "auth.login": "Zaloguj", + "auth.login.authentik": "Zaloguj się przez Authentik", + "auth.login.azure": "Zaloguj się przez Microsoft", + "auth.login.bitbucket": "Zaloguj się przez Bitbucket", + "auth.login.clerk": "Zaloguj się przez Clerk", + "auth.login.discord": "Zaloguj się przez Discord", + "auth.login.github": "Zaloguj się przez GitHub", + "auth.login.gitlab": "Zaloguj się przez Gitlab", + "auth.login.google": "Zaloguj się przez Google", + "auth.login.infomaniak": "Zaloguj się przez Infomaniak", + "auth.login.zitadel": "Zaloguj się przez Zitadel", + "auth.already_registered": "Już zarejestrowany?", + "auth.confirm_password": "Potwierdź hasło", + "auth.forgot_password_link": "Zapomniałeś hasło?", + "auth.forgot_password_heading": "Odzyskiwanie hasła", + "auth.forgot_password_send_email": "Wyślij email resetujący hasło", + "auth.register_now": "Zarejestruj", + "auth.logout": "Wyloguj", + "auth.register": "Zarejestruj", + "auth.registration_disabled": "Rejestracja jest wyłączona. Skontaktuj się z administratorem.", + "auth.reset_password": "Zresetuj hasło", + "auth.failed": "Podane dane nie zgadzają się z naszymi rekordami.", + "auth.failed.callback": "Nie udało się przeprocesować callbacku od dostawcy logowania.", + "auth.failed.password": "Podane hasło jest nieprawidłowe.", + "auth.failed.email": "Nie znaleziono użytkownika z takim adresem email.", + "auth.throttle": "Zbyt wiele prób logowania. Spróbuj ponownie za :seconds sekund.", + "input.name": "Nazwa", + "input.email": "Email", + "input.password": "Hasło", + "input.password.again": "Hasło ponownie", + "input.code": "Jednorazowy kod", + "input.recovery_code": "Kod odzyskiwania", + "button.save": "Zapisz", + "repository.url": "<span class='text-helper'>Przykłady</span><br>Dla publicznych repozytoriów użyj <span class='text-helper'>https://...</span>.<br>Dla prywatnych repozytoriów, użyj <span class='text-helper'>git@...</span>.<br><br>https://github.com/coollabsio/coolify-examples - zostanie wybrany branch <span class='text-helper'>main</span><br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify - zostanie wybrany branch <span class='text-helper'>nodejs-fastify</span><br>https://gitea.com/sedlav/expressjs.git - zostanie wybrany branch <span class='text-helper'>main</span><br>https://gitlab.com/andrasbacsai/nodejs-example.git - zostanie wybrany branch <span class='text-helper'>main</span>", + "service.stop": "Ten serwis zostanie zatrzymany.", + "resource.docker_cleanup": "Uruchom Docker Cleanup (usunie nieużywane obrazy i cache buildera).", + "resource.non_persistent": "Wszystkie nietrwałe dane zostaną usunięte.", + "resource.delete_volumes": "Trwale usuń wszystkie wolumeny powiązane z tym zasobem.", + "resource.delete_connected_networks": "Trwale usuń wszystkie niepredefiniowane sieci powiązane z tym zasobem.", + "resource.delete_configurations": "Trwale usuń wszystkie pliki konfiguracyjne z serwera.", + "database.delete_backups_locally": "Wszystkie backupy zostaną trwale usunięte z lokalnej pamięci.", + "warning.sslipdomain": "Twoja konfiguracja została zapisana, lecz domena sslip z https jest <span class='dark:text-red-500 text-red-500 font-bold'>NIEZALECANA</span>, ponieważ serwery Let's Encrypt z tą publiczną domeną są pod rate limitem (walidacja certyfikatu SSL certificate się nie powiedzie). <br><br>Lepiej użyj własnej domeny." +} \ No newline at end of file diff --git a/lang/pt-br.json b/lang/pt-br.json index c3a102995..f3ebb6c69 100644 --- a/lang/pt-br.json +++ b/lang/pt-br.json @@ -11,7 +11,8 @@ "auth.login.infomaniak": "Entrar com Infomaniak", "auth.already_registered": "Já tem uma conta?", "auth.confirm_password": "Confirmar senha", - "auth.forgot_password": "Esqueceu a senha", + "auth.forgot_password_link": "Esqueceu a senha?", + "auth.forgot_password_heading": "Recuperação de senha", "auth.forgot_password_send_email": "Enviar e-mail para redefinir senha", "auth.register_now": "Cadastre-se", "auth.logout": "Sair", @@ -39,4 +40,4 @@ "resource.delete_configurations": "Excluir permanentemente todos os arquivos de configuração do servidor.", "database.delete_backups_locally": "Todos os backups serão excluídos permanentemente do armazenamento local.", "warning.sslipdomain": "Sua configuração foi salva, mas o domínio sslip com https <span class='dark:text-red-500 text-red-500 font-bold'>NÃO</span> é recomendado, porque os servidores do Let's Encrypt com este domínio público têm limitação de taxa (a validação do certificado SSL falhará). <br><br>Use seu próprio domínio em vez disso." -} +} \ No newline at end of file diff --git a/lang/pt.json b/lang/pt.json index 80ff8c146..08ad19df3 100644 --- a/lang/pt.json +++ b/lang/pt.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "Entrar com Infomaniak", "auth.already_registered": "Já tem uma conta?", "auth.confirm_password": "Confirmar senha", - "auth.forgot_password": "Esqueceu a senha?", + "auth.forgot_password_link": "Esqueceu a senha?", + "auth.forgot_password_heading": "Recuperação de senha", "auth.forgot_password_send_email": "Enviar e-mail de redefinição de senha", "auth.register_now": "Cadastrar-se", "auth.logout": "Sair", @@ -30,4 +31,4 @@ "input.recovery_code": "Código de recuperação", "button.save": "Salvar", "repository.url": "<span class='text-helper'>Exemplos</span><br>Para repositórios públicos, use <span class='text-helper'>https://...</span>.<br>Para repositórios privados, use <span class='text-helper'>git@...</span>.<br><br>https://github.com/coollabsio/coolify-examples <span class='text-helper'>a branch main</span> será selecionada<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify <span class='text-helper'>a branch nodejs-fastify</span> será selecionada.<br>https://gitea.com/sedlav/expressjs.git <span class='text-helper'>a branch main</span> será selecionada.<br>https://gitlab.com/andrasbacsai/nodejs-example.git <span class='text-helper'>a branch main</span> será selecionada." -} +} \ No newline at end of file diff --git a/lang/ro.json b/lang/ro.json index 5588ea6f4..18028d087 100644 --- a/lang/ro.json +++ b/lang/ro.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "Autentificare prin Infomaniak", "auth.already_registered": "Sunteți deja înregistrat?", "auth.confirm_password": "Confirmați parola", - "auth.forgot_password": "Ați uitat parola", + "auth.forgot_password_link": "Ați uitat parola?", + "auth.forgot_password_heading": "Recuperare parolă", "auth.forgot_password_send_email": "Trimiteți e-mail-ul pentru resetarea parolei", "auth.register_now": "Înregistrare", "auth.logout": "Deconectare", @@ -37,4 +38,4 @@ "resource.delete_connected_networks": "Ștergeți definitiv toate rețelele non-predefinite asociate cu această resursă.", "resource.delete_configurations": "Ștergeți definitiv toate fișierele de configurare de pe server.", "database.delete_backups_locally": "Toate copiile de rezervă vor fi șterse definitiv din stocarea locală." -} +} \ No newline at end of file diff --git a/lang/tr.json b/lang/tr.json index 74f693dc9..e3f34aa14 100644 --- a/lang/tr.json +++ b/lang/tr.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "Infomaniak ile Giriş Yap", "auth.already_registered": "Zaten kayıtlı mısınız?", "auth.confirm_password": "Şifreyi Onayla", - "auth.forgot_password": "Şifremi Unuttum", + "auth.forgot_password_link": "Şifrenizi mi unuttunuz?", + "auth.forgot_password_heading": "Şifre Kurtarma", "auth.forgot_password_send_email": "Şifre sıfırlama e-postası gönder", "auth.register_now": "Kayıt Ol", "auth.logout": "Çıkış Yap", @@ -38,4 +39,4 @@ "resource.delete_configurations": "Sunucudaki tüm yapılandırma dosyaları kalıcı olarak silinecek.", "database.delete_backups_locally": "Tüm yedekler yerel depolamadan kalıcı olarak silinecek.", "warning.sslipdomain": "Yapılandırmanız kaydedildi, ancak sslip domain ile https <span class='dark:text-red-500 text-red-500 font-bold'>ÖNERİLMEZ</span>, çünkü Let's Encrypt sunucuları bu genel domain ile sınırlandırılmıştır (SSL sertifikası doğrulaması başarısız olur). <br><br>Bunun yerine kendi domaininizi kullanın." -} +} \ No newline at end of file diff --git a/lang/vi.json b/lang/vi.json index 46edac599..76e380477 100644 --- a/lang/vi.json +++ b/lang/vi.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "Đăng Nhập Bằng Infomaniak", "auth.already_registered": "Đã đăng ký?", "auth.confirm_password": "Nhập lại mật khẩu", - "auth.forgot_password": "Quên mật khẩu", + "auth.forgot_password_link": "Quên mật khẩu?", + "auth.forgot_password_heading": "Khôi phục mật khẩu", "auth.forgot_password_send_email": "Gửi email đặt lại mật khẩu", "auth.register_now": "Đăng ký ngay", "auth.logout": "Đăng xuất", @@ -30,4 +31,4 @@ "input.recovery_code": "Mã khôi phục", "button.save": "Lưu", "repository.url": "<span class='text-helper'>Ví dụ</span><br>Với repo công khai, sử dụng <span class='text-helper'>https://...</span>.<br>Với repo riêng tư, sử dụng <span class='text-helper'>git@...</span>.<br><br>https://github.com/coollabsio/coolify-examples <span class='text-helper'>nhánh chính</span> sẽ được chọn<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify <span class='text-helper'>nhánh nodejs-fastify</span> sẽ được chọn.<br>https://gitea.com/sedlav/expressjs.git <span class='text-helper'>nhánh chính</span> sẽ được chọn.<br>https://gitlab.com/andrasbacsai/nodejs-example.git <span class='text-helper'>nhánh chính</span> sẽ được chọn." -} +} \ No newline at end of file diff --git a/lang/zh-cn.json b/lang/zh-cn.json index d46c71e07..530621ee1 100644 --- a/lang/zh-cn.json +++ b/lang/zh-cn.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "使用 Infomaniak 登录", "auth.already_registered": "已经注册?", "auth.confirm_password": "确认密码", - "auth.forgot_password": "忘记密码", + "auth.forgot_password_link": "忘记密码?", + "auth.forgot_password_heading": "密码找回", "auth.forgot_password_send_email": "发送密码重置邮件", "auth.register_now": "注册", "auth.logout": "退出登录", @@ -30,4 +31,4 @@ "input.recovery_code": "恢复码", "button.save": "保存", "repository.url": "<span class='text-helper'>示例</span><br>对于公共代码仓库,请使用 <span class='text-helper'>https://...</span>。<br>对于私有代码仓库,请使用 <span class='text-helper'>git@...</span>。<br><br>https://github.com/coollabsio/coolify-examples <span class='text-helper'>main</span> 分支将被选择<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify <span class='text-helper'>nodejs-fastify</span> 分支将被选择。<br>https://gitea.com/sedlav/expressjs.git <span class='text-helper'>main</span> 分支将被选择。<br>https://gitlab.com/andrasbacsai/nodejs-example.git <span class='text-helper'>main</span> 分支将被选择" -} +} \ No newline at end of file diff --git a/lang/zh-tw.json b/lang/zh-tw.json index c0784c7b7..aa078104b 100644 --- a/lang/zh-tw.json +++ b/lang/zh-tw.json @@ -10,7 +10,8 @@ "auth.login.infomaniak": "使用 Infomaniak 登入", "auth.already_registered": "已經註冊?", "auth.confirm_password": "確認密碼", - "auth.forgot_password": "忘記密碼", + "auth.forgot_password_link": "忘記密碼?", + "auth.forgot_password_heading": "密碼找回", "auth.forgot_password_send_email": "發送重設密碼電郵", "auth.register_now": "註冊", "auth.logout": "登出", @@ -30,4 +31,4 @@ "input.recovery_code": "恢復碼", "button.save": "儲存", "repository.url": "<span class='text-helper'>例子</span><br>對於公共代碼倉庫,請使用 <span class='text-helper'>https://...</span>。<br>對於私有代碼倉庫,請使用 <span class='text-helper'>git@...</span>。<br><br>https://github.com/coollabsio/coolify-examples <span class='text-helper'>main</span> 分支將被選擇<br>https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify <span class='text-helper'>nodejs-fastify</span> 分支將被選擇。<br>https://gitea.com/sedlav/expressjs.git <span class='text-helper'>main</span> 分支將被選擇。<br>https://gitlab.com/andrasbacsai/nodejs-example.git <span class='text-helper'>main</span> 分支將被選擇。" -} +} \ No newline at end of file diff --git a/other/nightly/install.sh b/other/nightly/install.sh index e9f54952a..92ad12302 100755 --- a/other/nightly/install.sh +++ b/other/nightly/install.sh @@ -253,6 +253,11 @@ if [ "$OS_TYPE" = "endeavouros" ]; then OS_TYPE="arch" fi +# Check if the OS is Cachy OS, if so, change it to arch +if [ "$OS_TYPE" = "cachyos" ]; then + OS_TYPE="arch" +fi + # Check if the OS is Asahi Linux, if so, change it to fedora if [ "$OS_TYPE" = "fedora-asahi-remix" ]; then OS_TYPE="fedora" @@ -844,7 +849,7 @@ IPV6_PUBLIC_IP=$(curl -6s https://ifconfig.io || true) echo -e "\nYour instance is ready to use!\n" if [ -n "$IPV4_PUBLIC_IP" ]; then - echo -e "You can access Coolify through your Public IPV4: http://$(curl -4s https://ifconfig.io):8000" + echo -e "You can access Coolify through your Public IPV4: http://$IPV4_PUBLIC_IP:8000" fi if [ -n "$IPV6_PUBLIC_IP" ]; then echo -e "You can access Coolify through your Public IPv6: http://[$IPV6_PUBLIC_IP]:8000" diff --git a/package-lock.json b/package-lock.json index d86caea87..34b2c1dd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -74,13 +74,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz", - "integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.27.3" + "@babel/types": "^7.28.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -90,9 +90,9 @@ } }, "node_modules/@babel/types": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.6.tgz", - "integrity": "sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==", + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", "dev": true, "license": "MIT", "dependencies": { @@ -104,9 +104,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", + "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", "cpu": [ "ppc64" ], @@ -121,9 +121,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", + "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", "cpu": [ "arm" ], @@ -138,9 +138,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", + "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", "cpu": [ "arm64" ], @@ -155,9 +155,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", + "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", "cpu": [ "x64" ], @@ -172,9 +172,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", + "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", "cpu": [ "arm64" ], @@ -189,9 +189,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", + "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", "cpu": [ "x64" ], @@ -206,9 +206,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", + "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", "cpu": [ "arm64" ], @@ -223,9 +223,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", + "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", "cpu": [ "x64" ], @@ -240,9 +240,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", + "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", "cpu": [ "arm" ], @@ -257,9 +257,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", + "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", "cpu": [ "arm64" ], @@ -274,9 +274,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", + "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", "cpu": [ "ia32" ], @@ -291,9 +291,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", + "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", "cpu": [ "loong64" ], @@ -308,9 +308,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", + "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", "cpu": [ "mips64el" ], @@ -325,9 +325,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", + "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", "cpu": [ "ppc64" ], @@ -342,9 +342,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", + "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", "cpu": [ "riscv64" ], @@ -359,9 +359,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", + "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", "cpu": [ "s390x" ], @@ -376,9 +376,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", + "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", "cpu": [ "x64" ], @@ -393,9 +393,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", + "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", "cpu": [ "arm64" ], @@ -410,9 +410,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", + "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", "cpu": [ "x64" ], @@ -427,9 +427,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", + "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", "cpu": [ "arm64" ], @@ -444,9 +444,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", + "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", "cpu": [ "x64" ], @@ -460,10 +460,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", + "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", + "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", "cpu": [ "x64" ], @@ -478,9 +495,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", + "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", "cpu": [ "arm64" ], @@ -495,9 +512,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", + "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", "cpu": [ "ia32" ], @@ -512,9 +529,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", + "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", "cpu": [ "x64" ], @@ -529,9 +546,9 @@ } }, "node_modules/@ioredis/commands": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz", - "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.3.0.tgz", + "integrity": "sha512-M/T6Zewn7sDaBQEqIZ8Rb+i9y8qfGmq+5SDFSf9sA2lUZTmdDLVdOiQaeDp+Q4wElZ9HG1GAX5KhDaidp6LQsQ==", "license": "MIT" }, "node_modules/@isaacs/fs-minipass": { @@ -548,18 +565,14 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { @@ -572,27 +585,17 @@ "node": ">=6.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "dev": true, "license": "MIT", "dependencies": { @@ -601,9 +604,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", - "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", + "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", "cpu": [ "arm" ], @@ -615,9 +618,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.2.tgz", - "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", + "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", "cpu": [ "arm64" ], @@ -629,9 +632,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.2.tgz", - "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", + "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", "cpu": [ "arm64" ], @@ -643,9 +646,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.2.tgz", - "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", + "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", "cpu": [ "x64" ], @@ -657,9 +660,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.2.tgz", - "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", + "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", "cpu": [ "arm64" ], @@ -671,9 +674,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.2.tgz", - "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", + "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", "cpu": [ "x64" ], @@ -685,9 +688,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.2.tgz", - "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", + "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", "cpu": [ "arm" ], @@ -699,9 +702,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.2.tgz", - "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", + "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", "cpu": [ "arm" ], @@ -713,9 +716,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.2.tgz", - "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", + "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", "cpu": [ "arm64" ], @@ -727,9 +730,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.2.tgz", - "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", + "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", "cpu": [ "arm64" ], @@ -741,9 +744,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.2.tgz", - "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", + "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", "cpu": [ "loong64" ], @@ -754,10 +757,10 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.2.tgz", - "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", + "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", "cpu": [ "ppc64" ], @@ -769,9 +772,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.2.tgz", - "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", + "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", "cpu": [ "riscv64" ], @@ -783,9 +786,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.2.tgz", - "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", + "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", "cpu": [ "riscv64" ], @@ -797,9 +800,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.2.tgz", - "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", + "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", "cpu": [ "s390x" ], @@ -811,9 +814,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", - "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", + "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", "cpu": [ "x64" ], @@ -825,9 +828,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.2.tgz", - "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", + "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", "cpu": [ "x64" ], @@ -839,9 +842,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.2.tgz", - "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", + "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", "cpu": [ "arm64" ], @@ -853,9 +856,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.2.tgz", - "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", + "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", "cpu": [ "ia32" ], @@ -867,9 +870,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.2.tgz", - "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", + "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", "cpu": [ "x64" ], @@ -1192,9 +1195,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -1544,9 +1547,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1620,9 +1623,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "version": "0.25.8", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", + "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1633,31 +1636,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" + "@esbuild/aix-ppc64": "0.25.8", + "@esbuild/android-arm": "0.25.8", + "@esbuild/android-arm64": "0.25.8", + "@esbuild/android-x64": "0.25.8", + "@esbuild/darwin-arm64": "0.25.8", + "@esbuild/darwin-x64": "0.25.8", + "@esbuild/freebsd-arm64": "0.25.8", + "@esbuild/freebsd-x64": "0.25.8", + "@esbuild/linux-arm": "0.25.8", + "@esbuild/linux-arm64": "0.25.8", + "@esbuild/linux-ia32": "0.25.8", + "@esbuild/linux-loong64": "0.25.8", + "@esbuild/linux-mips64el": "0.25.8", + "@esbuild/linux-ppc64": "0.25.8", + "@esbuild/linux-riscv64": "0.25.8", + "@esbuild/linux-s390x": "0.25.8", + "@esbuild/linux-x64": "0.25.8", + "@esbuild/netbsd-arm64": "0.25.8", + "@esbuild/netbsd-x64": "0.25.8", + "@esbuild/openbsd-arm64": "0.25.8", + "@esbuild/openbsd-x64": "0.25.8", + "@esbuild/openharmony-arm64": "0.25.8", + "@esbuild/sunos-x64": "0.25.8", + "@esbuild/win32-arm64": "0.25.8", + "@esbuild/win32-ia32": "0.25.8", + "@esbuild/win32-x64": "0.25.8" } }, "node_modules/estree-walker": { @@ -1668,9 +1672,9 @@ "license": "MIT" }, "node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1683,9 +1687,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "dev": true, "funding": [ { @@ -1704,15 +1708,16 @@ } }, "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -1870,9 +1875,9 @@ } }, "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", "dev": true, "license": "MIT", "bin": { @@ -2306,9 +2311,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -2392,9 +2397,9 @@ } }, "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", + "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==", "dev": true, "license": "MIT", "peer": true, @@ -2424,13 +2429,13 @@ } }, "node_modules/rollup": { - "version": "4.40.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", - "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", + "version": "4.46.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", + "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.7" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -2440,26 +2445,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.40.2", - "@rollup/rollup-android-arm64": "4.40.2", - "@rollup/rollup-darwin-arm64": "4.40.2", - "@rollup/rollup-darwin-x64": "4.40.2", - "@rollup/rollup-freebsd-arm64": "4.40.2", - "@rollup/rollup-freebsd-x64": "4.40.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.40.2", - "@rollup/rollup-linux-arm-musleabihf": "4.40.2", - "@rollup/rollup-linux-arm64-gnu": "4.40.2", - "@rollup/rollup-linux-arm64-musl": "4.40.2", - "@rollup/rollup-linux-loongarch64-gnu": "4.40.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.40.2", - "@rollup/rollup-linux-riscv64-gnu": "4.40.2", - "@rollup/rollup-linux-riscv64-musl": "4.40.2", - "@rollup/rollup-linux-s390x-gnu": "4.40.2", - "@rollup/rollup-linux-x64-gnu": "4.40.2", - "@rollup/rollup-linux-x64-musl": "4.40.2", - "@rollup/rollup-win32-arm64-msvc": "4.40.2", - "@rollup/rollup-win32-ia32-msvc": "4.40.2", - "@rollup/rollup-win32-x64-msvc": "4.40.2", + "@rollup/rollup-android-arm-eabi": "4.46.2", + "@rollup/rollup-android-arm64": "4.46.2", + "@rollup/rollup-darwin-arm64": "4.46.2", + "@rollup/rollup-darwin-x64": "4.46.2", + "@rollup/rollup-freebsd-arm64": "4.46.2", + "@rollup/rollup-freebsd-x64": "4.46.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", + "@rollup/rollup-linux-arm-musleabihf": "4.46.2", + "@rollup/rollup-linux-arm64-gnu": "4.46.2", + "@rollup/rollup-linux-arm64-musl": "4.46.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", + "@rollup/rollup-linux-ppc64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-gnu": "4.46.2", + "@rollup/rollup-linux-riscv64-musl": "4.46.2", + "@rollup/rollup-linux-s390x-gnu": "4.46.2", + "@rollup/rollup-linux-x64-gnu": "4.46.2", + "@rollup/rollup-linux-x64-musl": "4.46.2", + "@rollup/rollup-win32-arm64-msvc": "4.46.2", + "@rollup/rollup-win32-ia32-msvc": "4.46.2", + "@rollup/rollup-win32-x64-msvc": "4.46.2", "fsevents": "~2.3.2" } }, @@ -2600,9 +2605,9 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", - "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/public/js/purify.min.js b/public/js/purify.min.js new file mode 100644 index 000000000..73df78d60 --- /dev/null +++ b/public/js/purify.min.js @@ -0,0 +1,3 @@ +/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).DOMPurify=t()}(this,(function(){"use strict";const{entries:e,setPrototypeOf:t,isFrozen:n,getPrototypeOf:o,getOwnPropertyDescriptor:r}=Object;let{freeze:i,seal:a,create:l}=Object,{apply:c,construct:s}="undefined"!=typeof Reflect&&Reflect;i||(i=function(e){return e}),a||(a=function(e){return e}),c||(c=function(e,t,n){return e.apply(t,n)}),s||(s=function(e,t){return new e(...t)});const u=R(Array.prototype.forEach),m=R(Array.prototype.lastIndexOf),p=R(Array.prototype.pop),f=R(Array.prototype.push),d=R(Array.prototype.splice),h=R(String.prototype.toLowerCase),g=R(String.prototype.toString),T=R(String.prototype.match),y=R(String.prototype.replace),E=R(String.prototype.indexOf),A=R(String.prototype.trim),_=R(Object.prototype.hasOwnProperty),S=R(RegExp.prototype.test),b=(N=TypeError,function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return s(N,t)});var N;function R(e){return function(t){t instanceof RegExp&&(t.lastIndex=0);for(var n=arguments.length,o=new Array(n>1?n-1:0),r=1;r<n;r++)o[r-1]=arguments[r];return c(e,t,o)}}function w(e,o){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:h;t&&t(e,null);let i=o.length;for(;i--;){let t=o[i];if("string"==typeof t){const e=r(t);e!==t&&(n(o)||(o[i]=e),t=e)}e[t]=!0}return e}function O(e){for(let t=0;t<e.length;t++){_(e,t)||(e[t]=null)}return e}function D(t){const n=l(null);for(const[o,r]of e(t)){_(t,o)&&(Array.isArray(r)?n[o]=O(r):r&&"object"==typeof r&&r.constructor===Object?n[o]=D(r):n[o]=r)}return n}function v(e,t){for(;null!==e;){const n=r(e,t);if(n){if(n.get)return R(n.get);if("function"==typeof n.value)return R(n.value)}e=o(e)}return function(){return null}}const L=i(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),C=i(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),x=i(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),I=i(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),M=i(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),k=i(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),U=i(["#text"]),z=i(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),P=i(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),H=i(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),F=i(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),B=a(/\{\{[\w\W]*|[\w\W]*\}\}/gm),W=a(/<%[\w\W]*|[\w\W]*%>/gm),G=a(/\$\{[\w\W]*/gm),Y=a(/^data-[\-\w.\u00B7-\uFFFF]+$/),j=a(/^aria-[\-\w]+$/),X=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),q=a(/^(?:\w+script|data):/i),$=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),K=a(/^html$/i),V=a(/^[a-z][.\w]*(-[.\w]+)+$/i);var Z=Object.freeze({__proto__:null,ARIA_ATTR:j,ATTR_WHITESPACE:$,CUSTOM_ELEMENT:V,DATA_ATTR:Y,DOCTYPE_NAME:K,ERB_EXPR:W,IS_ALLOWED_URI:X,IS_SCRIPT_OR_DATA:q,MUSTACHE_EXPR:B,TMPLIT_EXPR:G});const J=1,Q=3,ee=7,te=8,ne=9,oe=function(){return"undefined"==typeof window?null:window};var re=function t(){let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:oe();const o=e=>t(e);if(o.version="3.2.6",o.removed=[],!n||!n.document||n.document.nodeType!==ne||!n.Element)return o.isSupported=!1,o;let{document:r}=n;const a=r,c=a.currentScript,{DocumentFragment:s,HTMLTemplateElement:N,Node:R,Element:O,NodeFilter:B,NamedNodeMap:W=n.NamedNodeMap||n.MozNamedAttrMap,HTMLFormElement:G,DOMParser:Y,trustedTypes:j}=n,q=O.prototype,$=v(q,"cloneNode"),V=v(q,"remove"),re=v(q,"nextSibling"),ie=v(q,"childNodes"),ae=v(q,"parentNode");if("function"==typeof N){const e=r.createElement("template");e.content&&e.content.ownerDocument&&(r=e.content.ownerDocument)}let le,ce="";const{implementation:se,createNodeIterator:ue,createDocumentFragment:me,getElementsByTagName:pe}=r,{importNode:fe}=a;let de={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]};o.isSupported="function"==typeof e&&"function"==typeof ae&&se&&void 0!==se.createHTMLDocument;const{MUSTACHE_EXPR:he,ERB_EXPR:ge,TMPLIT_EXPR:Te,DATA_ATTR:ye,ARIA_ATTR:Ee,IS_SCRIPT_OR_DATA:Ae,ATTR_WHITESPACE:_e,CUSTOM_ELEMENT:Se}=Z;let{IS_ALLOWED_URI:be}=Z,Ne=null;const Re=w({},[...L,...C,...x,...M,...U]);let we=null;const Oe=w({},[...z,...P,...H,...F]);let De=Object.seal(l(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ve=null,Le=null,Ce=!0,xe=!0,Ie=!1,Me=!0,ke=!1,Ue=!0,ze=!1,Pe=!1,He=!1,Fe=!1,Be=!1,We=!1,Ge=!0,Ye=!1,je=!0,Xe=!1,qe={},$e=null;const Ke=w({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Ve=null;const Ze=w({},["audio","video","img","source","image","track"]);let Je=null;const Qe=w({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),et="http://www.w3.org/1998/Math/MathML",tt="http://www.w3.org/2000/svg",nt="http://www.w3.org/1999/xhtml";let ot=nt,rt=!1,it=null;const at=w({},[et,tt,nt],g);let lt=w({},["mi","mo","mn","ms","mtext"]),ct=w({},["annotation-xml"]);const st=w({},["title","style","font","a","script"]);let ut=null;const mt=["application/xhtml+xml","text/html"];let pt=null,ft=null;const dt=r.createElement("form"),ht=function(e){return e instanceof RegExp||e instanceof Function},gt=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!ft||ft!==e){if(e&&"object"==typeof e||(e={}),e=D(e),ut=-1===mt.indexOf(e.PARSER_MEDIA_TYPE)?"text/html":e.PARSER_MEDIA_TYPE,pt="application/xhtml+xml"===ut?g:h,Ne=_(e,"ALLOWED_TAGS")?w({},e.ALLOWED_TAGS,pt):Re,we=_(e,"ALLOWED_ATTR")?w({},e.ALLOWED_ATTR,pt):Oe,it=_(e,"ALLOWED_NAMESPACES")?w({},e.ALLOWED_NAMESPACES,g):at,Je=_(e,"ADD_URI_SAFE_ATTR")?w(D(Qe),e.ADD_URI_SAFE_ATTR,pt):Qe,Ve=_(e,"ADD_DATA_URI_TAGS")?w(D(Ze),e.ADD_DATA_URI_TAGS,pt):Ze,$e=_(e,"FORBID_CONTENTS")?w({},e.FORBID_CONTENTS,pt):Ke,ve=_(e,"FORBID_TAGS")?w({},e.FORBID_TAGS,pt):D({}),Le=_(e,"FORBID_ATTR")?w({},e.FORBID_ATTR,pt):D({}),qe=!!_(e,"USE_PROFILES")&&e.USE_PROFILES,Ce=!1!==e.ALLOW_ARIA_ATTR,xe=!1!==e.ALLOW_DATA_ATTR,Ie=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Me=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,ke=e.SAFE_FOR_TEMPLATES||!1,Ue=!1!==e.SAFE_FOR_XML,ze=e.WHOLE_DOCUMENT||!1,Fe=e.RETURN_DOM||!1,Be=e.RETURN_DOM_FRAGMENT||!1,We=e.RETURN_TRUSTED_TYPE||!1,He=e.FORCE_BODY||!1,Ge=!1!==e.SANITIZE_DOM,Ye=e.SANITIZE_NAMED_PROPS||!1,je=!1!==e.KEEP_CONTENT,Xe=e.IN_PLACE||!1,be=e.ALLOWED_URI_REGEXP||X,ot=e.NAMESPACE||nt,lt=e.MATHML_TEXT_INTEGRATION_POINTS||lt,ct=e.HTML_INTEGRATION_POINTS||ct,De=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&ht(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(De.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&ht(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(De.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(De.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),ke&&(xe=!1),Be&&(Fe=!0),qe&&(Ne=w({},U),we=[],!0===qe.html&&(w(Ne,L),w(we,z)),!0===qe.svg&&(w(Ne,C),w(we,P),w(we,F)),!0===qe.svgFilters&&(w(Ne,x),w(we,P),w(we,F)),!0===qe.mathMl&&(w(Ne,M),w(we,H),w(we,F))),e.ADD_TAGS&&(Ne===Re&&(Ne=D(Ne)),w(Ne,e.ADD_TAGS,pt)),e.ADD_ATTR&&(we===Oe&&(we=D(we)),w(we,e.ADD_ATTR,pt)),e.ADD_URI_SAFE_ATTR&&w(Je,e.ADD_URI_SAFE_ATTR,pt),e.FORBID_CONTENTS&&($e===Ke&&($e=D($e)),w($e,e.FORBID_CONTENTS,pt)),je&&(Ne["#text"]=!0),ze&&w(Ne,["html","head","body"]),Ne.table&&(w(Ne,["tbody"]),delete ve.tbody),e.TRUSTED_TYPES_POLICY){if("function"!=typeof e.TRUSTED_TYPES_POLICY.createHTML)throw b('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof e.TRUSTED_TYPES_POLICY.createScriptURL)throw b('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');le=e.TRUSTED_TYPES_POLICY,ce=le.createHTML("")}else void 0===le&&(le=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let n=null;const o="data-tt-policy-suffix";t&&t.hasAttribute(o)&&(n=t.getAttribute(o));const r="dompurify"+(n?"#"+n:"");try{return e.createPolicy(r,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+r+" could not be created."),null}}(j,c)),null!==le&&"string"==typeof ce&&(ce=le.createHTML(""));i&&i(e),ft=e}},Tt=w({},[...C,...x,...I]),yt=w({},[...M,...k]),Et=function(e){f(o.removed,{element:e});try{ae(e).removeChild(e)}catch(t){V(e)}},At=function(e,t){try{f(o.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){f(o.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e)if(Fe||Be)try{Et(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},_t=function(e){let t=null,n=null;if(He)e="<remove></remove>"+e;else{const t=T(e,/^[\r\n\t ]+/);n=t&&t[0]}"application/xhtml+xml"===ut&&ot===nt&&(e='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+e+"</body></html>");const o=le?le.createHTML(e):e;if(ot===nt)try{t=(new Y).parseFromString(o,ut)}catch(e){}if(!t||!t.documentElement){t=se.createDocument(ot,"template",null);try{t.documentElement.innerHTML=rt?ce:o}catch(e){}}const i=t.body||t.documentElement;return e&&n&&i.insertBefore(r.createTextNode(n),i.childNodes[0]||null),ot===nt?pe.call(t,ze?"html":"body")[0]:ze?t.documentElement:i},St=function(e){return ue.call(e.ownerDocument||e,e,B.SHOW_ELEMENT|B.SHOW_COMMENT|B.SHOW_TEXT|B.SHOW_PROCESSING_INSTRUCTION|B.SHOW_CDATA_SECTION,null)},bt=function(e){return e instanceof G&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof W)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},Nt=function(e){return"function"==typeof R&&e instanceof R};function Rt(e,t,n){u(e,(e=>{e.call(o,t,n,ft)}))}const wt=function(e){let t=null;if(Rt(de.beforeSanitizeElements,e,null),bt(e))return Et(e),!0;const n=pt(e.nodeName);if(Rt(de.uponSanitizeElement,e,{tagName:n,allowedTags:Ne}),Ue&&e.hasChildNodes()&&!Nt(e.firstElementChild)&&S(/<[/\w!]/g,e.innerHTML)&&S(/<[/\w!]/g,e.textContent))return Et(e),!0;if(e.nodeType===ee)return Et(e),!0;if(Ue&&e.nodeType===te&&S(/<[/\w]/g,e.data))return Et(e),!0;if(!Ne[n]||ve[n]){if(!ve[n]&&Dt(n)){if(De.tagNameCheck instanceof RegExp&&S(De.tagNameCheck,n))return!1;if(De.tagNameCheck instanceof Function&&De.tagNameCheck(n))return!1}if(je&&!$e[n]){const t=ae(e)||e.parentNode,n=ie(e)||e.childNodes;if(n&&t){for(let o=n.length-1;o>=0;--o){const r=$(n[o],!0);r.__removalCount=(e.__removalCount||0)+1,t.insertBefore(r,re(e))}}}return Et(e),!0}return e instanceof O&&!function(e){let t=ae(e);t&&t.tagName||(t={namespaceURI:ot,tagName:"template"});const n=h(e.tagName),o=h(t.tagName);return!!it[e.namespaceURI]&&(e.namespaceURI===tt?t.namespaceURI===nt?"svg"===n:t.namespaceURI===et?"svg"===n&&("annotation-xml"===o||lt[o]):Boolean(Tt[n]):e.namespaceURI===et?t.namespaceURI===nt?"math"===n:t.namespaceURI===tt?"math"===n&&ct[o]:Boolean(yt[n]):e.namespaceURI===nt?!(t.namespaceURI===tt&&!ct[o])&&!(t.namespaceURI===et&&!lt[o])&&!yt[n]&&(st[n]||!Tt[n]):!("application/xhtml+xml"!==ut||!it[e.namespaceURI]))}(e)?(Et(e),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!S(/<\/no(script|embed|frames)/i,e.innerHTML)?(ke&&e.nodeType===Q&&(t=e.textContent,u([he,ge,Te],(e=>{t=y(t,e," ")})),e.textContent!==t&&(f(o.removed,{element:e.cloneNode()}),e.textContent=t)),Rt(de.afterSanitizeElements,e,null),!1):(Et(e),!0)},Ot=function(e,t,n){if(Ge&&("id"===t||"name"===t)&&(n in r||n in dt))return!1;if(xe&&!Le[t]&&S(ye,t));else if(Ce&&S(Ee,t));else if(!we[t]||Le[t]){if(!(Dt(e)&&(De.tagNameCheck instanceof RegExp&&S(De.tagNameCheck,e)||De.tagNameCheck instanceof Function&&De.tagNameCheck(e))&&(De.attributeNameCheck instanceof RegExp&&S(De.attributeNameCheck,t)||De.attributeNameCheck instanceof Function&&De.attributeNameCheck(t))||"is"===t&&De.allowCustomizedBuiltInElements&&(De.tagNameCheck instanceof RegExp&&S(De.tagNameCheck,n)||De.tagNameCheck instanceof Function&&De.tagNameCheck(n))))return!1}else if(Je[t]);else if(S(be,y(n,_e,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==E(n,"data:")||!Ve[e]){if(Ie&&!S(Ae,y(n,_e,"")));else if(n)return!1}else;return!0},Dt=function(e){return"annotation-xml"!==e&&T(e,Se)},vt=function(e){Rt(de.beforeSanitizeAttributes,e,null);const{attributes:t}=e;if(!t||bt(e))return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:we,forceKeepAttr:void 0};let r=t.length;for(;r--;){const i=t[r],{name:a,namespaceURI:l,value:c}=i,s=pt(a),m=c;let f="value"===a?m:A(m);if(n.attrName=s,n.attrValue=f,n.keepAttr=!0,n.forceKeepAttr=void 0,Rt(de.uponSanitizeAttribute,e,n),f=n.attrValue,!Ye||"id"!==s&&"name"!==s||(At(a,e),f="user-content-"+f),Ue&&S(/((--!?|])>)|<\/(style|title)/i,f)){At(a,e);continue}if(n.forceKeepAttr)continue;if(!n.keepAttr){At(a,e);continue}if(!Me&&S(/\/>/i,f)){At(a,e);continue}ke&&u([he,ge,Te],(e=>{f=y(f,e," ")}));const d=pt(e.nodeName);if(Ot(d,s,f)){if(le&&"object"==typeof j&&"function"==typeof j.getAttributeType)if(l);else switch(j.getAttributeType(d,s)){case"TrustedHTML":f=le.createHTML(f);break;case"TrustedScriptURL":f=le.createScriptURL(f)}if(f!==m)try{l?e.setAttributeNS(l,a,f):e.setAttribute(a,f),bt(e)?Et(e):p(o.removed)}catch(t){At(a,e)}}else At(a,e)}Rt(de.afterSanitizeAttributes,e,null)},Lt=function e(t){let n=null;const o=St(t);for(Rt(de.beforeSanitizeShadowDOM,t,null);n=o.nextNode();)Rt(de.uponSanitizeShadowNode,n,null),wt(n),vt(n),n.content instanceof s&&e(n.content);Rt(de.afterSanitizeShadowDOM,t,null)};return o.sanitize=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,r=null,i=null,l=null;if(rt=!e,rt&&(e="\x3c!--\x3e"),"string"!=typeof e&&!Nt(e)){if("function"!=typeof e.toString)throw b("toString is not a function");if("string"!=typeof(e=e.toString()))throw b("dirty is not a string, aborting")}if(!o.isSupported)return e;if(Pe||gt(t),o.removed=[],"string"==typeof e&&(Xe=!1),Xe){if(e.nodeName){const t=pt(e.nodeName);if(!Ne[t]||ve[t])throw b("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof R)n=_t("\x3c!----\x3e"),r=n.ownerDocument.importNode(e,!0),r.nodeType===J&&"BODY"===r.nodeName||"HTML"===r.nodeName?n=r:n.appendChild(r);else{if(!Fe&&!ke&&!ze&&-1===e.indexOf("<"))return le&&We?le.createHTML(e):e;if(n=_t(e),!n)return Fe?null:We?ce:""}n&&He&&Et(n.firstChild);const c=St(Xe?e:n);for(;i=c.nextNode();)wt(i),vt(i),i.content instanceof s&&Lt(i.content);if(Xe)return e;if(Fe){if(Be)for(l=me.call(n.ownerDocument);n.firstChild;)l.appendChild(n.firstChild);else l=n;return(we.shadowroot||we.shadowrootmode)&&(l=fe.call(a,l,!0)),l}let m=ze?n.outerHTML:n.innerHTML;return ze&&Ne["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&S(K,n.ownerDocument.doctype.name)&&(m="<!DOCTYPE "+n.ownerDocument.doctype.name+">\n"+m),ke&&u([he,ge,Te],(e=>{m=y(m,e," ")})),le&&We?le.createHTML(m):m},o.setConfig=function(){gt(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Pe=!0},o.clearConfig=function(){ft=null,Pe=!1},o.isValidAttribute=function(e,t,n){ft||gt({});const o=pt(e),r=pt(t);return Ot(o,r,n)},o.addHook=function(e,t){"function"==typeof t&&f(de[e],t)},o.removeHook=function(e,t){if(void 0!==t){const n=m(de[e],t);return-1===n?void 0:d(de[e],n,1)[0]}return p(de[e])},o.removeHooks=function(e){de[e]=[]},o.removeAllHooks=function(){de={afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},o}();return re})); +//# sourceMappingURL=purify.min.js.map diff --git a/public/svgs/bluesky.svg b/public/svgs/bluesky.svg new file mode 100644 index 000000000..77ebea072 --- /dev/null +++ b/public/svgs/bluesky.svg @@ -0,0 +1,3 @@ +<svg width="600" height="530" xmlns="http://www.w3.org/2000/svg"> + <path d="M135.72 44.03C202.216 93.951 273.74 195.17 300 249.49c26.262-54.316 97.782-155.54 164.28-205.46C512.26 8.009 590-19.862 590 68.825c0 17.712-10.155 148.79-16.111 170.07-20.703 73.984-96.144 92.854-163.25 81.433 117.3 19.964 147.14 86.092 82.697 152.22-122.39 125.59-175.91-31.511-189.63-71.766-2.514-7.38-3.69-10.832-3.708-7.896-.017-2.936-1.193.516-3.707 7.896-13.714 40.255-67.233 197.36-189.63 71.766-64.444-66.128-34.605-132.26 82.697-152.22-67.108 11.421-142.55-7.45-163.25-81.433C20.15 217.613 9.997 86.535 9.997 68.825c0-88.687 77.742-60.816 125.72-24.795z" fill="#1185fe"/> +</svg> diff --git a/public/svgs/chroma.svg b/public/svgs/chroma.svg new file mode 100644 index 000000000..930288fbf --- /dev/null +++ b/public/svgs/chroma.svg @@ -0,0 +1,13 @@ +<svg width="36" height="25" fill="none" xmlns="http://www.w3.org/2000/svg"> + <mask id="prefix__a" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="36" height="25"> + <path d="M36 .934H0v24h36v-24z" fill="#fff" /> + </mask> + <g mask="url(#prefix__a)"> + <path d="M12 .934c-6.627 0-12 5.372-12 12 0 6.627 5.373 12 12 12s12-5.373 12-12c0-6.628-5.373-12-12-12z" + fill="#327EFF" /> + <path d="M24 .934c-6.627 0-12 5.372-12 12 0 6.627 5.373 12 12 12s12-5.373 12-12c0-6.628-5.373-12-12-12z" + fill="#FFDE2D" /> + <path d="M12 12.934c0-6.628 5.373-12 12-12v12H12z" fill="#FF6446" /> + <path d="M24 12.934c0 6.627-5.373 12-12 12v-12h12z" fill="#FF6446" /> + </g> +</svg> \ No newline at end of file diff --git a/public/svgs/drizzle.jpeg b/public/svgs/drizzle.jpeg new file mode 100644 index 000000000..d84ff854b Binary files /dev/null and b/public/svgs/drizzle.jpeg differ diff --git a/public/svgs/elasticsearch.svg b/public/svgs/elasticsearch.svg new file mode 100644 index 000000000..bfc5bfb6a --- /dev/null +++ b/public/svgs/elasticsearch.svg @@ -0,0 +1,16 @@ +<svg width="205" height="204" viewBox="0 0 205 204" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_1178_2)"> +<path d="M204.58 106.744C204.603 98.4365 202.056 90.3256 197.289 83.5226C192.521 76.7196 185.766 71.5575 177.95 68.7437C178.661 65.1202 179.02 61.4363 179.02 57.7437C179.015 45.5282 175.137 33.6288 167.945 23.7553C160.752 13.8817 150.615 6.54212 138.99 2.79108C127.365 -0.95996 114.849 -0.929399 103.242 2.87837C91.6356 6.68615 81.5344 14.0751 74.3903 23.9837C69.1179 19.9113 62.6636 17.6651 56.0021 17.5844C49.3406 17.5036 42.8337 19.5926 37.4641 23.536C32.0946 27.4793 28.1539 33.0628 26.2374 39.4431C24.3208 45.8235 24.5325 52.6542 26.8403 58.9037C19.0148 61.7531 12.2486 66.929 7.45072 73.7362C2.6528 80.5433 0.0529206 88.6558 0.000313645 96.9837C-0.0326102 105.33 2.52727 113.48 7.32627 120.309C12.1253 127.138 18.9265 132.307 26.7903 135.104C25.1677 143.453 25.4123 152.057 27.5064 160.301C29.6005 168.544 33.4924 176.222 38.903 182.784C44.3136 189.347 51.1089 194.631 58.8019 198.258C66.495 201.885 74.8951 203.765 83.4003 203.764C92.5559 203.772 101.581 201.59 109.722 197.402C117.863 193.213 124.884 187.138 130.2 179.684C135.455 183.802 141.912 186.091 148.588 186.201C155.264 186.312 161.793 184.238 167.181 180.295C172.569 176.353 176.522 170.758 178.437 164.362C180.352 157.965 180.125 151.119 177.79 144.864C185.623 142.013 192.394 136.832 197.193 130.016C201.992 123.201 204.587 115.079 204.63 106.744" fill="white"/> +<path d="M80.4304 87.7437L125.2 108.154L170.36 68.5837C172.647 57.1747 170.923 45.326 165.48 35.0418C160.036 24.7576 151.208 16.6692 140.487 12.1447C129.767 7.62016 117.813 6.9373 106.647 10.2116C95.4817 13.4859 85.7895 20.5163 79.2104 30.1137L71.6904 69.1137L80.4304 87.7437Z" fill="#FEC514"/> +<path d="M34.1005 135.154C31.7687 146.616 33.4787 158.533 38.9397 168.877C44.4007 179.221 53.2757 187.355 64.0559 191.896C74.836 196.436 86.856 197.103 98.0722 193.783C109.288 190.463 119.009 183.36 125.581 173.684L133.031 134.844L123.031 115.844L78.1405 95.3438L34.1005 135.154Z" fill="#02BCB7"/> +<path d="M33.7903 57.6838L64.4903 64.9238L71.2103 30.0437C67.0362 26.8839 61.9516 25.1598 56.7165 25.129C51.4814 25.0981 46.3769 26.7623 42.1659 29.8727C37.9549 32.9831 34.8636 37.3728 33.3539 42.3856C31.8442 47.3984 31.9973 52.7652 33.7903 57.6838Z" fill="#F04E98"/> +<path d="M31.1505 64.9837C24.5185 67.1748 18.727 71.3643 14.5705 76.9775C10.4141 82.5907 8.09631 89.3525 7.93527 96.3353C7.77423 103.318 9.7778 110.179 13.6711 115.978C17.5643 121.777 23.1566 126.229 29.6805 128.724L72.6805 89.8137L64.7905 72.9837L31.1505 64.9837Z" fill="#1BA9F5"/> +<path d="M133.44 173.684C137.012 176.435 141.284 178.128 145.77 178.572C150.256 179.016 154.777 178.191 158.818 176.193C162.859 174.195 166.259 171.103 168.63 167.269C171.001 163.434 172.248 159.012 172.23 154.504C172.243 151.636 171.749 148.789 170.77 146.094L140.12 138.924L133.44 173.684Z" fill="#9ADC30"/> +<path d="M139.68 130.894L173.43 138.784C180.166 136.513 186.025 132.197 190.191 126.437C194.357 120.678 196.622 113.762 196.67 106.654C196.664 99.8008 194.573 93.112 190.676 87.4751C186.779 81.8383 181.259 77.5201 174.85 75.0938L130.72 113.764L139.68 130.894Z" fill="#0B64DD"/> +</g> +<defs> +<clipPath id="clip0_1178_2"> +<rect width="205" height="204" fill="white"/> +</clipPath> +</defs> +</svg> diff --git a/public/svgs/github-runner.png b/public/svgs/github-runner.png new file mode 100644 index 000000000..fb5b5c1b7 Binary files /dev/null and b/public/svgs/github-runner.png differ diff --git a/public/svgs/gowa.svg b/public/svgs/gowa.svg new file mode 100644 index 000000000..1121b05bc --- /dev/null +++ b/public/svgs/gowa.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1024" height="1024" preserveAspectRatio="xMidYMid meet" version="1.2" viewBox="0 0 768 768" zoomAndPan="magnify"><g id="29fd9150bd"><g mask="url(#5de07e7afc)" transform="matrix(0.871582,0,0,0.871582,-62.175558,-42.190514)"><image width="1024" height="1024" preserveAspectRatio="xMidYMid meet" xlink:href="data:image/png;base64,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N1dqjbqrnTLG4bAqhI3YRl0T2DIbECNydZigqOrUNNYwbYyq3FcwaNLQEgCK1CbbVZ2MTWqCQCQWaoXq/ERvlCwEBVBqKIsYhfNFedtUDzFMd+JCOdFAumAQadAYwJQu1tVgVK/WWJP+qeFwzzvecdOF9d3JSHsoxpGl7dT0Th5f6/dfOnPGQ72cc+4K8g2Ac869Lr0igEjkf3nmmY7FrmhP9OnJrooq5LbByCzVtMrSwGxE9snthqOJbrh2/8yJE3K+OdgtRoWQTRlUpOgEA9AknSqoUepKE4kQ66aqk0hh0WIQS6r9Ud3EMpgxDNNa5/nbduaf5YaV9eWGCihIodFGKQ3qer1qLnbiemqayW5lNr1nzyvDlLx0xznnXgf8vdg5516Xvm4D8I3/9pssqY+QnY2NYzUn+6OO4e1V9cRkR4CoeltVPdEpVUQFd1S1UYySyEQkGiCqUEhDqylNnjRQc3OyszUxsT3Xbb/+N/++3+ATfAPgnHOvJx4D6pxzr0vffBDBt+PlS++L46/2jVJNL9OK3Nf9zjn3euJvys459+b1zRb9fkneOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPOOeecc84555xzzjnnnHPuDUiu9A/gnHPOudcTsv2D+CLBuTcnf227v6av+8Vw5AiPvh8Ajh7+Bp9++Gj7h6/5W5Gv+TqX/vy1X/mV3/HrffNfTkfI/J2PXvrQa/ebjARwGDgMHL30HV9xG9/0vvMb+62fBq/4Fl//rMif//U/xjd7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"/><mask id="5de07e7afc"><g transform="matrix(1,0,0,1,0,-0.000000000000007105)"><image width="1024" height="1024" preserveAspectRatio="xMidYMid meet" xlink:href="data:image/png;base64,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0Ewar4RABqpmHiX5a7nDGQrNBPBNk335eq9Fv/UdHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0d54f/AZ3d8PhLsHVUAAAAAElFTkSuQmCC"/></g></mask></g></g></svg> \ No newline at end of file diff --git a/public/svgs/homebox.svg b/public/svgs/homebox.svg new file mode 100644 index 000000000..08670bbb9 --- /dev/null +++ b/public/svgs/homebox.svg @@ -0,0 +1,11 @@ +<svg viewBox="0 0 10817 9730" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:5.42683"> + <path d="M9310.16 2560.9c245.302 249.894 419.711 539.916 565.373 845.231 47.039 98.872 36.229 215.514-28.2 304.05-64.391 88.536-172.099 134.676-280.631 120.28 0 .053-.039.053-.039.053" style="fill:gray;stroke:#000;stroke-width:206.41px"/> + <path d="M5401.56 487.044c-127.958 6.227-254.855 40.77-370.992 103.628-765.271 414.225-2397.45 1297.68-3193.03 1728.32-137.966 74.669-250.327 183.605-328.791 313.046l3963.09 2122.43s-249.048 416.428-470.593 786.926c-189.24 316.445-592.833 429.831-919.198 258.219l-2699.36-1419.32v2215.59c0 226.273 128.751 435.33 337.755 548.466 764.649 413.885 2620.97 1418.66 3385.59 1832.51 209.018 113.137 466.496 113.137 675.514 0 764.623-413.857 2620.94-1418.63 3385.59-1832.51 208.989-113.136 337.743-322.193 337.743-548.466v-3513.48c0-318.684-174.59-611.722-454.853-763.409-795.543-430.632-2427.75-1314.09-3193.02-1728.32-141.693-76.684-299.364-111.227-455.442-103.628" style="fill:#dadada;stroke:#000;stroke-width:206.42px"/> + <path d="M5471.83 4754.46V504.71c-127.958 6.226-325.127 23.1-441.264 85.958-765.271 414.225-2397.45 1297.68-3193.03 1728.32-137.966 74.669-250.327 183.605-328.791 313.046l3963.09 2122.43Z" style="fill:gray;stroke:#000;stroke-width:206.42px"/> + <path d="m1459.34 2725.96-373.791 715.667c-177.166 339.292-46.417 758 292.375 936.167l4.75 2.5m0 0 2699.37 1419.29c326.374 171.625 729.916 58.25 919.165-258.208 221.542-370.5 470.583-786.917 470.583-786.917l-3963.04-2122.42-2.167 3.458-47.25 90.458" style="fill:#dadada;stroke:#000;stroke-width:206.42px"/> + <path d="M5443.74 520.879v4149.79" style="fill:none;stroke:#000;stroke-width:153.5px"/> + <path d="M8951.41 4102.72c0-41.65-22.221-80.136-58.291-100.961-36.069-20.825-80.51-20.825-116.58 0l-2439.92 1408.69c-36.07 20.825-58.29 59.311-58.29 100.961V7058c0 41.65 22.22 80.136 58.29 100.961 36.07 20.825 80.51 20.825 116.58 0l2439.92-1408.69c36.07-20.825 58.291-59.312 58.291-100.962v-1546.59Z" style="fill:#567f67"/> + <path d="M8951.41 4102.72c0-41.65-22.221-80.136-58.291-100.961-36.069-20.825-80.51-20.825-116.58 0l-2439.92 1408.69c-36.07 20.825-58.29 59.311-58.29 100.961V7058c0 41.65 22.22 80.136 58.29 100.961 36.07 20.825 80.51 20.825 116.58 0l2439.92-1408.69c36.07-20.825 58.291-59.312 58.291-100.962v-1546.59ZM6463.98 5551.29v1387.06l2301.77-1328.92V4222.37L6463.98 5551.29Z"/> + <path d="M5443.76 9041.74v-4278.4" style="fill:none;stroke:#000;stroke-width:206.44px;stroke-linejoin:miter"/> + <path d="m5471.79 4773.86 3829.35-2188.22" style="fill:none;stroke:#000;stroke-width:206.43px;stroke-linejoin:miter"/> +</svg> diff --git a/public/svgs/langfuse.png b/public/svgs/langfuse.png deleted file mode 100644 index 8dec0fe4a..000000000 Binary files a/public/svgs/langfuse.png and /dev/null differ diff --git a/public/svgs/langfuse.svg b/public/svgs/langfuse.svg new file mode 100644 index 000000000..b04e07490 --- /dev/null +++ b/public/svgs/langfuse.svg @@ -0,0 +1,9 @@ +<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M409.105 333.507C391.926 356.747 365.618 372.254 335.933 374.517C335.009 374.582 334.084 374.646 333.147 374.698C298.339 376.431 272.046 360.55 254.61 345.807C223.757 329.472 199.617 325.359 185.493 321.803C175.221 319.216 166.234 314.043 162.382 311.456C158.967 309.426 152.098 304.718 146.975 295.937C141.235 286.095 140.902 276.693 140.991 272.697C143.983 272.296 147.848 271.856 152.367 271.571C156.065 271.339 159.647 271.248 163.666 271.235C194.84 271.196 219.017 272.722 236.607 280.534C246.121 284.75 254.942 290.363 262.8 297.204C272.904 306.024 293.563 319.966 319.024 315.207C322.259 314.599 325.366 313.797 328.358 312.814C337.525 311.495 353.202 310.435 371.666 315.336C389.191 319.992 401.8 328.036 409.105 333.507Z" fill="#0A60B5" stroke="black" stroke-width="8" stroke-miterlimit="10"/> +<path d="M406.82 173.454C399.075 163.42 389.662 153.934 378.544 147.462C366.696 140.568 351.578 134.631 333.292 133.023C288.618 129.091 258.074 153.87 252.509 158.556C245.584 165.054 217.887 188.046 184.547 200.812C178.739 202.881 167.557 207.77 157.62 218.685C149.759 227.316 145.912 236.15 144.027 241.64C148.002 242.188 152.106 242.584 156.337 242.827C188.664 244.627 216.438 244.806 234.608 235.907C246.61 230.035 257.138 221.673 266.216 211.881C282.578 194.225 306.441 186.348 328.163 191.748C338.139 193.14 355.514 194.199 375.608 188.046C389.482 183.795 399.819 178.446 406.82 173.454Z" fill="#0A60B5" stroke="black" stroke-width="8" stroke-miterlimit="10"/> +<path d="M103.656 180.905C91.263 174.535 81.5884 167.187 74.9897 161.435C71.3011 158.217 65.5703 160.856 65.5703 165.771V205.96C65.5703 207.711 66.3616 209.371 67.7146 210.452L84.1793 226.293C85.0472 219.923 86.9107 211.262 91.0971 201.688C95.041 192.654 99.7762 185.744 103.656 180.905Z" fill="#0A60B5" stroke="black" stroke-width="8" stroke-miterlimit="10"/> +<path d="M368.734 270.592C370.618 264.787 371.663 258.698 371.818 252.493C371.947 247.591 371.38 245.759 370.528 241.012C379.289 239.541 390.232 237.142 400.206 234.561C410.748 231.84 418.542 228.679 427.304 225.531C428.581 231.659 429.923 234.639 430.388 239.18C430.826 243.463 431.097 247.9 431.175 252.493C431.407 266.761 429.665 279.7 426.981 291.039C418.723 286.756 408.916 282.318 397.625 278.423C387.122 274.785 377.354 272.308 368.734 270.592Z" fill="#0A60B5" stroke="black" stroke-width="8" stroke-miterlimit="10"/> +<path d="M74.6068 355.448C70.8288 358.191 65.5703 355.487 65.5703 350.786V301.427C65.5703 299.933 66.1447 298.517 67.1402 297.461C67.638 296.933 68.0975 296.637 68.3017 296.521L84.6133 289.516C85.813 296.057 87.7914 303.887 91.0971 312.412C94.9644 322.379 99.5592 330.453 103.656 336.595C93.9688 342.88 84.2814 349.164 74.6068 355.448Z" fill="#0A60B5" stroke="black" stroke-width="8" stroke-miterlimit="10"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M179.649 139.803C212.273 138.184 236.669 151.849 249.244 160.981C239.725 169.389 213.966 189.679 183.499 201.397C181.444 202.132 178.717 203.221 175.61 204.807C153.564 215.666 140.455 237.306 139.87 260.424C139.772 264.315 139.97 268.192 140.485 272.001C140.429 272.009 140.374 272.016 140.318 272.024C140.229 275.989 140.562 285.318 146.298 295.083C151.418 303.796 158.283 308.467 161.697 310.481C163.391 311.61 166.078 313.237 169.431 314.922C173.371 317.021 177.74 318.781 182.559 320.143C183.296 320.357 184.042 320.559 184.794 320.747C186.548 321.185 188.458 321.639 190.52 322.128C205.056 325.578 227.082 330.805 254.088 345C256.815 347.289 259.755 349.596 262.906 351.852C261.949 352.709 261.143 353.458 260.491 354.073C254.922 358.782 224.356 383.689 179.649 379.737C161.351 378.12 146.209 372.153 134.365 365.224C114.411 353.559 99.3333 335.107 91.108 313.51C85.8083 299.588 81.1888 281.584 80.8551 260.398C80.56 242.305 83.46 226.368 87.4123 213.151C99.513 172.768 134.801 143.152 176.865 139.982L176.865 139.982L176.865 139.982C177.789 139.918 178.713 139.854 179.649 139.803ZM408.148 332.266C400.825 326.841 388.261 318.92 370.86 314.331C352.407 309.468 336.739 310.52 327.577 311.829C324.587 312.804 321.482 313.599 318.248 314.203C292.802 318.925 272.155 305.092 262.056 296.34C260.093 294.643 258.069 293.022 255.989 291.48C262.786 285.507 270.259 280.352 278.405 276.349C296.588 267.418 324.382 267.597 356.732 269.394C401.311 271.883 432.108 293.12 444.401 302.873C445.774 303.963 446.557 305.606 446.557 307.351V347.426C446.557 352.34 440.795 354.971 437.086 351.75C430.442 345.997 420.67 338.639 408.148 332.266ZM265.226 212.522C262.303 215.689 259.23 218.707 256.006 221.54C262.249 226.172 268.996 230.093 276.134 233.233C293.714 240.983 317.876 242.498 349.033 242.459C394.728 242.395 428.373 225.187 443.81 215.82C445.517 214.78 446.557 212.933 446.557 210.931V161.745C446.557 157.062 441.27 154.367 437.471 157.1C428.48 163.572 415.109 171.832 397.866 178.329C391.656 181.989 383.918 185.727 374.696 188.565C354.589 194.75 337.201 193.685 327.218 192.286C305.48 186.858 281.6 194.776 265.226 212.522Z" fill="#E11312"/> +<path d="M249.244 160.981L251.892 163.979L255.631 160.676L251.595 157.744L249.244 160.981ZM179.649 139.803L179.451 135.807L179.441 135.808L179.43 135.809L179.649 139.803ZM183.499 201.397L184.845 205.163L184.89 205.147L184.934 205.13L183.499 201.397ZM175.61 204.807L177.378 208.396L177.404 208.383L177.429 208.37L175.61 204.807ZM139.87 260.424L135.871 260.323L135.871 260.323L139.87 260.424ZM140.485 272.001L141.008 275.967L144.986 275.442L144.449 271.466L140.485 272.001ZM140.318 272.024L139.791 268.058L136.397 268.51L136.319 271.933L140.318 272.024ZM146.298 295.083L142.849 297.109L142.85 297.109L146.298 295.083ZM161.697 310.481L163.916 307.153L163.824 307.092L163.73 307.037L161.697 310.481ZM169.431 314.922L171.312 311.392L171.27 311.37L171.228 311.348L169.431 314.922ZM182.559 320.143L183.673 316.301L183.66 316.298L183.647 316.294L182.559 320.143ZM184.794 320.747L185.765 316.866L185.765 316.866L184.794 320.747ZM190.52 322.128L191.443 318.236L191.443 318.236L190.52 322.128ZM254.088 345L256.659 341.936L256.33 341.659L255.949 341.459L254.088 345ZM262.906 351.852L265.574 354.833L269.293 351.505L265.235 348.6L262.906 351.852ZM260.491 354.073L263.074 357.127L263.158 357.056L263.238 356.981L260.491 354.073ZM179.649 379.737L180.002 375.752L180.001 375.752L179.649 379.737ZM134.365 365.224L136.385 361.771L136.384 361.77L134.365 365.224ZM91.108 313.51L87.3696 314.933L87.3699 314.934L91.108 313.51ZM80.8551 260.398L84.8546 260.335L84.8546 260.333L80.8551 260.398ZM87.4123 213.151L83.5807 212.003L83.58 212.005L87.4123 213.151ZM176.865 139.982L176.593 135.991L176.578 135.992L176.564 135.993L176.865 139.982ZM176.865 139.982L176.666 135.987L176.629 135.989L176.593 135.991L176.865 139.982ZM176.865 139.982L177.065 143.977L177.104 143.975L177.142 143.973L176.865 139.982ZM370.86 314.331L371.88 310.463L371.879 310.463L370.86 314.331ZM408.148 332.266L405.766 335.48L406.035 335.68L406.333 335.831L408.148 332.266ZM327.577 311.829L327.011 307.869L326.667 307.918L326.337 308.026L327.577 311.829ZM318.248 314.203L318.978 318.135L318.981 318.135L318.248 314.203ZM262.056 296.34L264.676 293.317L264.672 293.314L262.056 296.34ZM255.989 291.48L253.349 288.475L249.63 291.744L253.607 294.693L255.989 291.48ZM278.405 276.349L276.642 272.758L276.641 272.759L278.405 276.349ZM356.732 269.394L356.955 265.4L356.954 265.4L356.732 269.394ZM444.401 302.873L446.889 299.741L446.887 299.739L444.401 302.873ZM437.086 351.75L439.709 348.73L439.705 348.726L437.086 351.75ZM256.006 221.54L253.365 218.536L249.647 221.803L253.623 224.753L256.006 221.54ZM265.226 212.522L268.165 215.236L268.166 215.235L265.226 212.522ZM276.134 233.233L277.747 229.573L277.745 229.572L276.134 233.233ZM349.033 242.459L349.038 246.459L349.038 246.459L349.033 242.459ZM443.81 215.82L445.886 219.239L445.891 219.236L443.81 215.82ZM437.471 157.1L435.135 153.853L435.135 153.854L437.471 157.1ZM397.866 178.329L396.455 174.586L396.132 174.707L395.835 174.883L397.866 178.329ZM374.696 188.565L375.872 192.388L375.873 192.388L374.696 188.565ZM327.218 192.286L326.249 196.167L326.454 196.218L326.663 196.248L327.218 192.286ZM251.595 157.744C238.61 148.315 213.322 134.127 179.451 135.807L179.847 143.798C211.224 142.241 234.729 155.383 246.893 164.217L251.595 157.744ZM184.934 205.13C216.028 193.171 242.198 172.541 251.892 163.979L246.596 157.983C237.251 166.237 211.904 186.186 182.063 197.664L184.934 205.13ZM177.429 208.37C180.352 206.877 182.916 205.853 184.845 205.163L182.152 197.631C179.971 198.41 177.081 199.565 173.791 201.245L177.429 208.37ZM143.869 260.525C144.417 238.86 156.696 218.582 177.378 208.396L173.843 201.219C150.433 212.749 136.493 235.752 135.871 260.323L143.869 260.525ZM144.449 271.466C143.964 267.878 143.775 264.214 143.869 260.525L135.871 260.323C135.768 264.416 135.976 268.507 136.521 272.537L144.449 271.466ZM140.846 275.989C140.9 275.981 140.954 275.974 141.008 275.967L139.961 268.036C139.904 268.043 139.847 268.051 139.791 268.058L140.846 275.989ZM149.747 293.057C144.542 284.195 144.236 275.715 144.317 272.114L136.319 271.933C136.221 276.262 136.583 286.44 142.849 297.109L149.747 293.057ZM163.73 307.037C160.625 305.204 154.391 300.959 149.747 293.056L142.85 297.109C148.446 306.632 155.941 311.729 159.664 313.926L163.73 307.037ZM171.228 311.348C168.021 309.737 165.475 308.193 163.916 307.153L159.478 313.809C161.306 315.028 164.135 316.737 167.635 318.496L171.228 311.348ZM183.647 316.294C179.088 315.006 174.987 313.35 171.312 311.392L167.551 318.452C171.756 320.693 176.392 322.557 181.471 323.992L183.647 316.294ZM185.765 316.866C185.062 316.691 184.364 316.502 183.673 316.301L181.445 323.985C182.228 324.212 183.022 324.427 183.824 324.627L185.765 316.866ZM191.443 318.236C189.376 317.745 187.49 317.298 185.765 316.866L183.824 324.627C185.605 325.073 187.54 325.532 189.596 326.02L191.443 318.236ZM255.949 341.459C228.482 327.023 206.055 321.704 191.443 318.236L189.596 326.02C204.058 329.452 225.682 334.588 252.227 348.54L255.949 341.459ZM265.235 348.6C262.175 346.41 259.317 344.167 256.659 341.936L251.516 348.063C254.314 350.412 257.335 352.783 260.578 355.105L265.235 348.6ZM263.238 356.981C263.869 356.385 264.648 355.661 265.574 354.833L260.239 348.871C259.25 349.757 258.417 350.53 257.745 351.164L263.238 356.981ZM179.297 383.721C225.654 387.819 257.29 362.018 263.074 357.127L257.909 351.018C252.555 355.546 223.059 379.559 180.002 375.752L179.297 383.721ZM132.345 368.676C144.61 375.852 160.316 382.044 179.297 383.721L180.001 375.752C162.385 374.196 147.807 368.454 136.385 361.771L132.345 368.676ZM87.3699 314.934C95.9012 337.334 111.56 356.526 132.346 368.677L136.384 361.77C117.262 350.593 102.765 332.88 94.846 312.087L87.3699 314.934ZM76.8556 260.461C77.1979 282.197 81.9376 300.663 87.3696 314.933L94.8463 312.087C89.679 298.512 85.1796 280.971 84.8546 260.335L76.8556 260.461ZM83.58 212.005C79.5286 225.553 76.5529 241.901 76.8557 260.464L84.8546 260.333C84.5671 242.709 87.3915 227.182 91.2447 214.297L83.58 212.005ZM176.564 135.993C132.774 139.293 96.1347 170.107 83.5807 212.003L91.244 214.299C102.891 175.429 136.829 147.01 177.165 143.971L176.564 135.993ZM176.593 135.991L176.593 135.991L177.137 143.973L177.137 143.973L176.593 135.991ZM176.666 135.987L176.666 135.987L177.065 143.977L177.065 143.977L176.666 135.987ZM179.43 135.809C178.46 135.862 177.507 135.928 176.588 135.992L177.142 143.973C178.071 143.908 178.966 143.846 179.868 143.797L179.43 135.809ZM369.84 318.199C386.602 322.619 398.707 330.25 405.766 335.48L410.529 329.053C402.943 323.432 389.921 315.221 371.88 310.463L369.84 318.199ZM328.143 315.788C336.97 314.527 352.065 313.514 369.84 318.199L371.879 310.463C352.749 305.421 336.508 306.512 327.011 307.869L328.143 315.788ZM318.981 318.135C322.385 317.5 325.66 316.661 328.817 315.631L326.337 308.026C323.514 308.946 320.578 309.699 317.515 310.27L318.981 318.135ZM259.437 299.363C269.82 308.361 291.7 323.198 318.978 318.135L317.518 310.27C293.904 314.652 274.49 301.823 264.676 293.317L259.437 299.363ZM253.607 294.693C255.607 296.176 257.552 297.734 259.441 299.366L264.672 293.314C262.633 291.552 260.532 289.868 258.372 288.267L253.607 294.693ZM276.641 272.759C268.143 276.935 260.379 282.296 253.349 288.475L258.63 294.484C265.192 288.717 272.374 283.769 280.169 279.939L276.641 272.759ZM356.954 265.4C340.756 264.5 325.519 263.993 312.001 264.856C298.515 265.718 286.417 267.957 276.642 272.758L280.168 279.939C288.576 275.809 299.467 273.673 312.511 272.84C325.523 272.009 340.358 272.491 356.51 273.388L356.954 265.4ZM446.887 299.739C434.284 289.741 402.704 267.955 356.955 265.4L356.509 273.387C399.917 275.812 429.931 296.5 441.915 306.006L446.887 299.739ZM450.557 307.351C450.557 304.399 449.227 301.598 446.889 299.741L441.913 306.005C442.321 306.329 442.557 306.813 442.557 307.351H450.557ZM450.557 347.426V307.351H442.557V347.426H450.557ZM434.464 354.77C440.766 360.244 450.557 355.763 450.557 347.426H442.557C442.557 348.917 440.823 349.698 439.709 348.73L434.464 354.77ZM406.333 335.831C418.504 342.024 428.008 349.181 434.468 354.774L439.705 348.726C432.876 342.813 422.837 335.253 409.962 328.701L406.333 335.831ZM258.647 224.545C261.982 221.614 265.154 218.498 268.165 215.236L262.287 209.809C259.452 212.88 256.479 215.8 253.365 218.536L258.647 224.545ZM277.745 229.572C270.88 226.552 264.392 222.781 258.389 218.328L253.623 224.753C260.106 229.562 267.112 233.634 274.523 236.894L277.745 229.572ZM349.028 238.459C317.781 238.498 294.446 236.935 277.747 229.573L274.52 236.893C292.982 245.032 317.972 246.498 349.038 246.459L349.028 238.459ZM441.735 212.4C426.633 221.564 393.715 238.396 349.027 238.459L349.038 246.459C395.74 246.394 430.114 228.81 445.886 219.239L441.735 212.4ZM442.557 210.931C442.557 211.537 442.245 212.09 441.73 212.403L445.891 219.236C448.789 217.471 450.557 214.329 450.557 210.931H442.557ZM442.557 161.745V210.931H450.557V161.745H442.557ZM439.808 160.347C440.973 159.509 442.557 160.337 442.557 161.745H450.557C450.557 153.786 441.567 149.225 435.135 153.853L439.808 160.347ZM399.276 182.072C416.924 175.422 430.604 166.971 439.808 160.347L435.135 153.854C426.355 160.172 413.295 168.241 396.455 174.586L399.276 182.072ZM375.873 192.388C385.437 189.444 393.461 185.568 399.897 181.775L395.835 174.883C389.85 178.41 382.398 182.01 373.52 184.742L375.873 192.388ZM326.663 196.248C336.999 197.696 355.02 198.802 375.872 192.388L373.52 184.742C354.157 190.698 337.403 189.674 327.773 188.325L326.663 196.248ZM268.166 215.235C283.661 198.44 306.085 191.132 326.249 196.167L328.187 188.405C304.876 182.584 279.538 191.111 262.286 209.81L268.166 215.235Z" fill="black"/> +</svg> diff --git a/public/svgs/librechat.svg b/public/svgs/librechat.svg new file mode 100644 index 000000000..36a536d65 --- /dev/null +++ b/public/svgs/librechat.svg @@ -0,0 +1,32 @@ +<svg width="512" height="512" version="1.1" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <linearGradient id="linearGradient22708"> + <stop stop-color="#21facf" offset="0"/> + <stop stop-color="#0970ef" offset="1"/> + </linearGradient> + <linearGradient id="linearGradient6949" x1="68.454" x2="198.59" y1="246.73" y2="96.35" gradientTransform="translate(-5.754,-56.594)" gradientUnits="userSpaceOnUse"> + <stop stop-color="#72004e" offset="0"/> + <stop stop-color="#0015b1" offset="1"/> + </linearGradient> + <linearGradient id="linearGradient22718" x1="56.735" x2="155.2" y1="246.96" y2="58.575" gradientUnits="userSpaceOnUse"> + <stop stop-color="#4f00da" offset="0"/> + <stop stop-color="#e5311b" offset="1"/> + </linearGradient> + <linearGradient id="linearGradient23463" x1="68.454" x2="198.59" y1="246.73" y2="96.35" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient22708"/> + <linearGradient id="linearGradient903" x1="54.478" x2="192.1" y1="247.56" y2="9.8095" gradientTransform="matrix(.87923 0 0 .87923 -9.551 48.787)" gradientUnits="userSpaceOnUse"> + <stop stop-color="#dc180d" offset="0"/> + <stop stop-color="#f96e20" offset=".5"/> + <stop stop-color="#f4ce41" offset="1"/> + </linearGradient> + <linearGradient id="linearGradient918" x1="39.468" x2="154.99" y1="204.22" y2="124.47" gradientUnits="userSpaceOnUse" xlink:href="#linearGradient22708"/> + </defs> + <g transform="matrix(2.473 0 0 2.473 -4.8978 -4.8812)"> + <path transform="translate(-5.5496,-57.412)" d="m148.16 59.393c-7.7098 9.3985-19.951 42.888-20.696 49.204-0.16994 4.6737 1.3731 14.231 0.67182 15.805-0.71909 1.6134-5.117-9.4461-7.2151-6.3266-12.219 18.168-10.7 17.731-15.582 31.378-1.8357 5.1315-0.42447 21.99-1.5666 23.773-1.273 1.9866-3.962-12.31-6.8063-9.236-11.603 12.54-16.279 20.379-22.336 30.607-3.3589 5.6725-2.1817 23.33-3.506 24.674-1.3023 1.3215-3.8566-18.326-7.6437-14.309-8.5193 9.038-14.054 13.441-18.946 19.252-5.1981 6.1739-0.78251 17.584-5.0672 35.383l0.1448 0.22073c77.447-50.308 101.52-127.16 107.61-181.19-0.68051 63.93-29.41 142.78-105.33 184.65l0.1127 0.17141c20.241-2.181 22.307 10.458 44.562-4.2837 55.792-48.277 81.856-124.29 61.593-199.78z" display="none" fill="url(#linearGradient903)"/> + <path transform="translate(-5.5498,-57.412)" d="m148.16 59.393c-7.7098 9.3985-19.951 42.888-20.696 49.204-0.16994 4.6737 1.3731 14.231 0.67182 15.805-0.71909 1.6134-5.117-9.4461-7.2151-6.3266-12.219 18.168-10.7 17.731-15.582 31.378-1.8357 5.1315-0.42447 21.99-1.5666 23.773-1.273 1.9866-3.962-12.31-6.8063-9.236-11.603 12.54-16.279 20.379-22.336 30.607-3.3589 5.6725-2.1817 23.33-3.506 24.674-1.3023 1.3215-3.8566-18.326-7.6437-14.309-8.5193 9.038-14.054 13.441-18.946 19.252-5.1981 6.1739-0.78251 17.584-5.0672 35.383l0.1448 0.22073c77.447-50.308 101.52-127.16 107.61-181.19-0.68051 63.93-29.41 142.78-105.33 184.65l0.1127 0.17141c20.241-2.181 22.307 10.458 44.562-4.2837 55.792-48.277 81.856-124.29 61.593-199.78z" fill="url(#linearGradient918)"/> + <g transform="translate(0 2.0218e-5)"> + <path transform="translate(-5.7543,-56.594)" d="m111.25 81.024c-48.394-1.5e-5 -87.625 39.231-87.625 87.625 0.0174 20.443 7.1818 40.236 20.253 55.954 0.2523-0.42224 0.53629-0.82423 0.85783-1.2061 4.892-5.8104 10.427-10.214 18.946-19.252 3.7871-4.0176 6.3412 15.63 7.6435 14.309 1.3243-1.3439 0.1473-19.001 3.5062-24.674 6.0563-10.228 10.733-18.067 22.336-30.607 2.8443-3.0741 5.5333 11.223 6.8063 9.2361 1.1421-1.7823-0.26941-18.641 1.5663-23.773 4.8819-13.647 3.3631-13.21 15.582-31.378 2.098-3.1195 6.496 7.9402 7.2151 6.3268 0.70126-1.5734-0.84173-11.131-0.67179-15.805 0.37161-3.1498 3.6036-13.059 7.7055-23.367-7.8432-2.2472-15.962-3.3881-24.12-3.3895zm43.142 11.356c5.5662 61.595-18.426 120.7-62.796 161.65 6.446 1.4857 13.04 2.2367 19.655 2.2386 48.394 1e-5 87.625-39.231 87.625-87.625-3.1e-4 -31.581-16.995-60.719-44.484-76.268z" display="none" fill="url(#linearGradient22718)"/> + <path transform="translate(-5.754,-56.594)" d="m111.25 81.024c-48.394-1.5e-5 -87.625 39.231-87.625 87.625 0.0174 20.443 7.1818 40.236 20.253 55.954 0.2523-0.42224 0.53629-0.82423 0.85783-1.2061 4.892-5.8104 10.427-10.214 18.946-19.252 3.7871-4.0176 6.3412 15.63 7.6435 14.309 1.3243-1.3439 0.1473-19.001 3.5062-24.674 6.0563-10.228 10.733-18.067 22.336-30.607 2.8443-3.0741 5.5333 11.223 6.8063 9.2361 1.1421-1.7823-0.26941-18.641 1.5663-23.773 4.8819-13.647 3.3631-13.21 15.582-31.378 2.098-3.1195 6.496 7.9402 7.2151 6.3268 0.70126-1.5734-0.84173-11.131-0.67179-15.805 0.37161-3.1498 3.6036-13.059 7.7055-23.367-7.8432-2.2472-15.962-3.3881-24.12-3.3895zm43.142 11.356c5.5662 61.595-18.426 120.7-62.796 161.65 6.446 1.4857 13.04 2.2367 19.655 2.2386 48.394 1e-5 87.625-39.231 87.625-87.625-3.1e-4 -31.581-16.995-60.719-44.484-76.268z" display="none" fill="url(#linearGradient23463)"/> + <path d="m105.5 24.43c-48.394-1.5e-5 -87.625 39.231-87.625 87.625 0.0174 20.443 7.1818 40.236 20.253 55.954 0.2523-0.42224 0.53629-0.82423 0.85783-1.2061 4.892-5.8104 10.427-10.214 18.946-19.252 3.7871-4.0176 6.3412 15.63 7.6435 14.309 1.3243-1.3439 0.1473-19.001 3.5062-24.674 6.0563-10.228 10.733-18.067 22.336-30.607 2.8443-3.0741 5.5333 11.223 6.8063 9.2361 1.1421-1.7823-0.26941-18.641 1.5663-23.773 4.8819-13.647 3.3631-13.21 15.582-31.378 2.098-3.1195 6.496 7.9402 7.2151 6.3268 0.70126-1.5734-0.84173-11.131-0.67179-15.805 0.37161-3.1498 3.6036-13.059 7.7055-23.367-7.8432-2.2472-15.962-3.3881-24.12-3.3895zm43.142 11.356c5.5662 61.595-18.426 120.7-62.796 161.65 6.446 1.4857 13.04 2.2367 19.655 2.2386 48.394 1e-5 87.625-39.231 87.625-87.625-3.1e-4 -31.581-16.995-60.719-44.484-76.268z" fill="url(#linearGradient6949)"/> + </g> + </g> +</svg> diff --git a/public/svgs/matrix.svg b/public/svgs/matrix.svg new file mode 100644 index 000000000..bc41720a2 --- /dev/null +++ b/public/svgs/matrix.svg @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 520 520" style="enable-background:new 0 0 520 520;" xml:space="preserve"> +<path d="M13.7,11.9v496.2h35.7V520H0V0h49.4v11.9H13.7z"/> +<path d="M166.3,169.2v25.1h0.7c6.7-9.6,14.8-17,24.2-22.2c9.4-5.3,20.3-7.9,32.5-7.9c11.7,0,22.4,2.3,32.1,6.8 c9.7,4.5,17,12.6,22.1,24c5.5-8.1,13-15.3,22.4-21.5c9.4-6.2,20.6-9.3,33.5-9.3c9.8,0,18.9,1.2,27.3,3.6c8.4,2.4,15.5,6.2,21.5,11.5 c6,5.3,10.6,12.1,14,20.6c3.3,8.5,5,18.7,5,30.7v124.1h-50.9V249.6c0-6.2-0.2-12.1-0.7-17.6c-0.5-5.5-1.8-10.3-3.9-14.3 c-2.2-4.1-5.3-7.3-9.5-9.7c-4.2-2.4-9.9-3.6-17-3.6c-7.2,0-13,1.4-17.4,4.1c-4.4,2.8-7.9,6.3-10.4,10.8c-2.5,4.4-4.2,9.4-5,15.1 c-0.8,5.6-1.3,11.3-1.3,17v103.3h-50.9v-104c0-5.5-0.1-10.9-0.4-16.3c-0.2-5.4-1.3-10.3-3.1-14.9c-1.8-4.5-4.8-8.2-9-10.9 c-4.2-2.7-10.3-4.1-18.5-4.1c-2.4,0-5.6,0.5-9.5,1.6c-3.9,1.1-7.8,3.1-11.5,6.1c-3.7,3-6.9,7.3-9.5,12.9c-2.6,5.6-3.9,13-3.9,22.1 v107.6h-50.9V169.2H166.3z"/> +<path d="M506.3,508.1V11.9h-35.7V0H520v520h-49.4v-11.9H506.3z"/> +</svg> \ No newline at end of file diff --git a/public/svgs/openpanel.svg b/public/svgs/openpanel.svg new file mode 100644 index 000000000..8508fc69e --- /dev/null +++ b/public/svgs/openpanel.svg @@ -0,0 +1 @@ +<svg viewBox="0 0 61 35" xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="text-black dark:text-white w-16 h-6"><rect x="34.0269" y="0.368164" width="10.3474" height="34.2258" rx="5.17372"></rect><rect x="49.9458" y="0.368164" width="10.3474" height="17.5109" rx="5.17372"></rect><path fill-rule="evenodd" clip-rule="evenodd" d="M14.212 0C6.36293 0 0 6.36293 0 14.212V20.02C0 27.8691 6.36293 34.232 14.212 34.232C22.0611 34.232 28.424 27.8691 28.424 20.02V14.212C28.424 6.36293 22.0611 0 14.212 0ZM14.2379 8.35999C11.3805 8.35999 9.06419 10.6763 9.06419 13.5337V20.6971C9.06419 23.5545 11.3805 25.8708 14.2379 25.8708C17.0953 25.8708 19.4116 23.5545 19.4116 20.6971V13.5337C19.4116 10.6763 17.0953 8.35999 14.2379 8.35999Z"></path></svg> diff --git a/public/svgs/pihole.svg b/public/svgs/pihole.svg new file mode 100644 index 000000000..a4efefcc8 --- /dev/null +++ b/public/svgs/pihole.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="-20.805 0 129.93 129.93"><defs><linearGradient id="New_Gradient_Swatch_1" x1="2.71" x2="69.77" y1="20.04" y2="20.04" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#12b212"/><stop offset="1" stop-color="#0f0"/></linearGradient><style>.cls-2{fill:#980200}.cls-3{fill:red}</style></defs><title>NewVortex + @endauth @section('body') @@ -61,6 +62,67 @@