# CloudflareR2-Manager A self-contained PHP web application for managing a Cloudflare R2 bucket with a local SQLite mirror. ## Features - Simple password authentication with CSRF protection. - R2 object browser backed by SQLite, so normal navigation uses the local mirror instead of repeatedly listing the bucket. - Prefix/folder organization, including zero-byte marker objects for empty folders. - Upload one or more files directly to R2 with local tags, permission labels, and operator notes. - Download, delete, copy, move, rename, and refresh object metadata. - Generate presigned `GET`, `PUT`, `HEAD`, and `DELETE` URLs. - Manage bucket CORS from JSON. - Track local usage events for sync, upload, download, copy, move, delete, CORS, and signed URL generation. - Optional public URL display for public buckets or custom R2 domains. ## Cloudflare R2 Notes Cloudflare R2 uses the S3-compatible API at `https://.r2.cloudflarestorage.com` and the S3 region is `auto`. As of Cloudflare's R2 S3 compatibility docs updated June 8, 2026, S3 ACLs and object tagging APIs are not implemented by R2. This app therefore stores tags, permission labels, and notes locally in SQLite while keeping file bytes in R2. Bucket CORS, object list/get/put/delete/copy, and presigned URLs are handled through R2's S3-compatible API. ## Requirements - PHP 8.1 or newer. - PHP extensions: `pdo_sqlite`, `curl`, `simplexml`, `fileinfo`. - A Cloudflare R2 bucket. - R2 API credentials with access to that bucket. Composer is not required. ## Setup 1. Copy the environment example: ```sh cp .env.example .env ``` 2. Edit `.env`: ```dotenv APP_PASSWORD="choose-a-real-password" R2_ACCOUNT_ID="your-cloudflare-account-id" R2_ACCESS_KEY_ID="your-r2-access-key-id" R2_SECRET_ACCESS_KEY="your-r2-secret-access-key" R2_BUCKET="your-bucket-name" ``` 3. Start the PHP development server: ```sh php -S 127.0.0.1:8080 -t public ``` 4. Open `http://127.0.0.1:8080`, sign in, and run **Sync current prefix**. ## Password Hashes For a plain setup, use `APP_PASSWORD`. For a hashed password, generate a hash with PHP and set `APP_PASSWORD_HASH` instead: ```sh php -r 'echo password_hash("your-password", PASSWORD_DEFAULT), PHP_EOL;' ``` ## Public URLs If your bucket has public access or a custom domain, set: ```dotenv R2_PUBLIC_URL="https://static.example.com" ``` The app will display copyable public links. It does not make a bucket public; public access is controlled in Cloudflare. ## Usage Tracking The usage dashboard is a local operational ledger. It records actions performed through this app and current mirrored storage size. It is useful for estimating activity, but it is not a replacement for Cloudflare's official billing or analytics. ## CORS Format Enter CORS as an array of S3-style rules: ```json [ { "AllowedOrigins": ["https://example.com"], "AllowedMethods": ["GET", "PUT", "HEAD"], "AllowedHeaders": ["Content-Type"], "ExposeHeaders": ["ETag"], "MaxAgeSeconds": 3600 } ] ``` ## Security - Keep `.env` outside version control. - Serve the app behind HTTPS in production. - Use least-privilege R2 credentials. - Restrict access at your web server or VPN if this manages production buckets.