High-Performance, Secure File Management System built with Next.js 16, MinIO (S3), Redis, and ZITADEL authentication.
Features
- 📁 S3-Compatible Storage - Multi-bucket architecture with MinIO
- 🔐 YAML-based RBAC - Enterprise-grade access control with role-based permissions
- ⚡ Redis Caching - Lightning-fast permission checks and file listings
- 🔑 ZITADEL Auth - OIDC authentication with Auth.js v5
- 📝 Audit Logging - Complete operation tracking
- 🎨 Modern UI - Built with Shadcn UI and Tailwind CSS v4
- 👁️ File Preview - In-browser preview for images and PDFs (no download required)
- 🐳 Docker Ready - Multi-stage production Dockerfile included
Tech Stack
| Category | Technology |
|---|---|
| Framework | Next.js 16.1.6 (App Router + Turbopack) |
| Runtime | Node.js 22+ |
| Auth | Auth.js v5 (next-auth@5.0.0-beta.30) + ZITADEL OIDC |
| Storage | MinIO (S3-compatible) |
| Cache | Redis (ioredis) |
| UI | Shadcn UI, Tailwind CSS v4, Lucide Icons |
| Language | TypeScript 5 |
Quick Start
Prerequisites
- Node.js 22+ (use
nvm usewith included.nvmrc) - Docker & Docker Compose
- ZITADEL instance (for authentication)
1. Clone and Install
git clone <repo-url> cd s3-browser npm install
2. Setup Environment
cp .env.local.example .env.local
# Edit .env.local with your configuration3. Start Services
# Start MinIO and Redis npm run docker:up # MinIO Console: http://localhost:9001 # Redis Commander: http://localhost:8081
4. Initialize
# Create S3 buckets npm run init-buckets # Sync permissions to Redis npm run sync-permissions
5. Run Development Server
npm run dev
# Open http://localhost:3000Project Structure
s3-browser/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── api/
│ │ │ ├── auth/ # Auth.js v5 handlers
│ │ │ ├── files/ # File operation endpoints
│ │ │ └── permissions/ # Permission sync endpoint
│ │ ├── auth/ # Auth pages (signin, error)
│ │ └── (dashboard)/ # Protected routes
│ │ └── explorer/ # File explorer
│ ├── components/
│ │ ├── explorer/ # File explorer components
│ │ │ ├── FileExplorer.tsx
│ │ │ ├── FileList.tsx
│ │ │ ├── FileItem.tsx
│ │ │ ├── FilePreview.tsx # Image/PDF preview modal
│ │ │ ├── Breadcrumb.tsx
│ │ │ ├── UploadZone.tsx
│ │ │ └── PermissionBadge.tsx
│ │ └── ui/ # Shadcn UI components
│ ├── lib/
│ │ ├── auth.ts # Auth.js v5 configuration
│ │ ├── redis.ts # Redis client
│ │ └── s3-client.ts # S3/MinIO client
│ ├── services/
│ │ ├── s3Service.ts # S3 operations
│ │ ├── permissionService.ts # RBAC engine
│ │ ├── cacheService.ts # Redis caching
│ │ ├── auditService.ts # Audit logging
│ │ └── syncService.ts # YAML sync
│ ├── types/ # TypeScript types
│ └── proxy.ts # Auth proxy (Next.js 16 pattern)
├── scripts/
│ ├── init-buckets.ts # Bucket initialization
│ └── sync-permissions.ts # Permission sync CLI
├── permissions.yaml # Permission configuration
├── Dockerfile # Multi-stage production build
├── docker-compose.yml # Development services
├── .nvmrc # Node.js version (22)
└── .vscode/ # VS Code debug configs
Permission System
Levels
- OWNER - Full control (read, write, delete)
- EDITOR - Read and write access
- VIEWER - Read-only access
Configuration (permissions.yaml)
roles: admin: priority: 100 permissions: - path: "*" level: OWNER engineering: priority: 50 permissions: - path: "shared/engineering/*" level: EDITOR users: john@company.com: priority: 80 permissions: - path: "projects/secret/*" level: OWNER defaults: authenticated: permissions: - path: "shared/public/*" level: VIEWER
Auto-granted Permissions
Every user automatically gets OWNER access to their home directory: home/${username}/*
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/files/list |
GET | List files in a path |
/api/files/upload-url |
POST | Get presigned upload URL |
/api/files/download-url |
POST | Get presigned download URL |
/api/files/preview-url |
POST | Get presigned preview URL (images/PDF) |
/api/files/create-folder |
POST | Create a new folder |
/api/files/rename |
POST | Rename file/folder |
/api/files/delete |
DELETE | Delete file/folder |
/api/permissions/sync |
POST | Sync permissions to Redis |
File Preview
The file explorer supports in-browser preview for:
| File Type | Features |
|---|---|
| Images (jpg, png, gif, webp, svg, bmp) | Zoom in/out, Rotate |
| Embedded iframe viewer |
Click the 👁️ (eye) icon on any previewable file to open the preview modal without downloading.
Environment Variables
# Auth.js v5 NEXTAUTH_URL=http://localhost:3000 NEXTAUTH_SECRET=your-secret-key AUTH_TRUST_HOST=true # ZITADEL ZITADEL_ISSUER=https://your-instance.zitadel.cloud ZITADEL_CLIENT_ID=your-client-id ZITADEL_CLIENT_SECRET=your-client-secret # MinIO S3_ENDPOINT=http://localhost:9000 S3_REGION=us-east-1 S3_ACCESS_KEY_ID=minioadmin S3_SECRET_ACCESS_KEY=minioadmin S3_BUCKET_USER_FILES=user-files S3_BUCKET_SHARED_FILES=shared-files S3_BUCKET_TEMP_UPLOADS=temp-uploads # Redis REDIS_URL=redis://localhost:6379 # App Config MAX_FILE_SIZE_MB=100 ALLOWED_FILE_TYPES=.pdf,.jpg,.png,.doc,.docx,.xls,.xlsx,.zip PRESIGNED_URL_EXPIRY_SECONDS=3600
Scripts
npm run dev # Start development server (Turbopack) npm run build # Build for production npm run start # Start production server npm run lint # Run ESLint npm run sync-permissions # Sync permissions.yaml to Redis npm run init-buckets # Create S3 buckets npm run docker:up # Start Docker services npm run docker:down # Stop Docker services
Docker
Development
# Start MinIO + Redis docker compose up -d # Access MinIO Console open http://localhost:9001
Production
# Build and run the app docker compose --profile app up -d # Or build manually docker build -t s3-browser . docker run -p 3000:3000 --env-file .env.local s3-browser
Security Checklist
- ✅ All S3 operations are server-side only
- ✅ Presigned URLs with expiration
- ✅ Permission checks before every operation
- ✅ Audit logging for all file access
- ✅ Path sanitization and validation
- ✅ File type and size restrictions
- ✅ CSRF protection with Auth.js v5
- ✅ Server Actions for authentication
Development
VS Code
The project includes VS Code launch configurations for debugging:
- Next.js: Debug Server - Debug the Next.js server
- Next.js: Full Stack - Debug both server and client
Use nvm use to switch to Node.js 22 before running.
Node.js Version
This project requires Node.js 22+. Use the included .nvmrc:
License
MIT