Skip to content

feat(settings): add Files menu to configure org S3 buckets#3446

Open
viktormarinho wants to merge 1 commit into
mainfrom
viktormarinho/org-s3-bucket-settings
Open

feat(settings): add Files menu to configure org S3 buckets#3446
viktormarinho wants to merge 1 commit into
mainfrom
viktormarinho/org-s3-bucket-settings

Conversation

@viktormarinho
Copy link
Copy Markdown
Contributor

@viktormarinho viktormarinho commented May 22, 2026

What is this contribution about?

Adds an org-scoped Files settings page where members can register S3-compatible bucket configurations (AWS S3, Cloudflare R2, GCS with force-path-style, MinIO). Access keys are encrypted at rest via the existing CredentialVault and never returned over the API; bucket/region/endpoint are stored plaintext for listing.

Backend: migration 083-org-file-configs, OrgFileConfigStorage, and FILE_CONFIG_{CREATE,LIST,UPDATE,DELETE} tools wired into MeshContext with a file-configs:manage permission group. Frontend: new `/$org/settings/files` route, sidebar entry, create/delete dialogs, and TanStack Query hooks.

This sets up only the config + UI; consumers will come in a follow-up PR.

How to Test

  1. `bun run --cwd=apps/mesh migrate` to apply migration 083.
  2. `bun run dev` and open Settings → Files for an org.
  3. Add a bucket (e.g. an R2 endpoint with force-path-style off, or a GCS endpoint with it on); verify it appears in the list with name/bucket/region/endpoint.
  4. Delete a bucket via the row trash icon; confirm it's removed.
  5. Confirm no plaintext credentials appear in the `org_file_configs` table (only `encrypted_credentials`).

Migration Notes

Run `bun run --cwd=apps/mesh migrate` to apply `083-org-file-configs.ts` (creates the `org_file_configs` table with a case-insensitive unique `(organization_id, name)` index, cascades on org delete).

Review Checklist

  • PR title is clear and descriptive
  • Changes are tested and working (typecheck + touched test suites pass)
  • Documentation is updated (if needed)
  • No breaking changes

Summary by cubic

Adds an org-scoped Files settings page to register S3-compatible bucket configs (AWS S3, Cloudflare R2, GCS, MinIO). Access keys are encrypted at rest and never returned; this sets up config + UI for future consumers.

  • New Features

    • Migration 083-org-file-configs adds org_file_configs with case-insensitive unique (organization_id, name).
    • OrgFileConfigStorage and tools FILE_CONFIG_CREATE, FILE_CONFIG_LIST, FILE_CONFIG_UPDATE, FILE_CONFIG_DELETE behind file-configs:manage.
    • New route /$org/settings/files, sidebar entry, and create/delete dialogs with @tanstack/react-query hooks for list/create/update/delete.
    • Supports custom endpoint and forcePathStyle for non-AWS providers.
  • Migration

    • Run bun run --cwd=apps/mesh migrate to apply 083-org-file-configs.

Written for commit b6c182e. Summary will update on new commits. Review in cubic

Adds an org-scoped "Files" settings page where members can register
S3-compatible bucket configurations (AWS S3, Cloudflare R2, GCS, MinIO).
Access keys are encrypted at rest via the existing CredentialVault and
never returned over the API. Supports custom endpoints and the
force-path-style flag needed for GCS.

Backend: migration 083-org-file-configs, OrgFileConfigStorage, and
FILE_CONFIG_{CREATE,LIST,UPDATE,DELETE} tools wired into MeshContext
with a file-configs:manage permission group.

Frontend: new /\$org/settings/files route, sidebar entry, create/delete
dialogs and TanStack Query hooks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

🧪 Benchmark

Should we run the Virtual MCP strategy benchmark for this PR?

React with 👍 to run the benchmark.

Reaction Action
👍 Run quick benchmark (10 & 128 tools)

Benchmark will run on the next push after you react.

@github-actions
Copy link
Copy Markdown
Contributor

Release Options

Suggested: Minor (2.344.0) — based on feat: prefix

React with an emoji to override the release type:

Reaction Type Next Version
👍 Prerelease 2.343.1-alpha.1
🎉 Patch 2.343.1
❤️ Minor 2.344.0
🚀 Major 3.0.0

Current version: 2.343.0

Note: If multiple reactions exist, the smallest bump wins. If no reactions, the suggested bump is used (default: patch).

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 27 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/mesh/src/web/views/settings/files.tsx">

<violation number="1" location="apps/mesh/src/web/views/settings/files.tsx:369">
P2: `AlertDialogAction` auto-closes the dialog before the async delete finishes, so failed deletes dismiss confirmation and prevent immediate retry.</violation>
</file>

<file name="apps/mesh/src/tools/file-configs/create.ts">

<violation number="1" location="apps/mesh/src/tools/file-configs/create.ts:15">
P1: `endpoint` accepts full URLs with optional `user:password@...`, which can leak credentials in plaintext metadata. Reject endpoint values containing embedded auth info.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

description: z.string().max(500).optional(),
bucket: z.string().min(1).max(255),
region: z.string().min(1).max(64),
endpoint: z.string().url().optional(),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: endpoint accepts full URLs with optional user:password@..., which can leak credentials in plaintext metadata. Reject endpoint values containing embedded auth info.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/tools/file-configs/create.ts, line 15:

<comment>`endpoint` accepts full URLs with optional `user:password@...`, which can leak credentials in plaintext metadata. Reject endpoint values containing embedded auth info.</comment>

<file context>
@@ -0,0 +1,41 @@
+    description: z.string().max(500).optional(),
+    bucket: z.string().min(1).max(255),
+    region: z.string().min(1).max(64),
+    endpoint: z.string().url().optional(),
+    forcePathStyle: z.boolean().optional(),
+    accessKeyId: z.string().min(1),
</file context>

<AlertDialogCancel disabled={deleteConfig.isPending}>
Cancel
</AlertDialogCancel>
<AlertDialogAction
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: AlertDialogAction auto-closes the dialog before the async delete finishes, so failed deletes dismiss confirmation and prevent immediate retry.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/mesh/src/web/views/settings/files.tsx, line 369:

<comment>`AlertDialogAction` auto-closes the dialog before the async delete finishes, so failed deletes dismiss confirmation and prevent immediate retry.</comment>

<file context>
@@ -0,0 +1,452 @@
+          <AlertDialogCancel disabled={deleteConfig.isPending}>
+            Cancel
+          </AlertDialogCancel>
+          <AlertDialogAction
+            onClick={handleConfirm}
+            disabled={deleteConfig.isPending}
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant