Skip to content

XyStorage is a fast, secure, and developer-first cloud storage solution designed to scale with your applications. Whether you're building a SaaS product, managing large datasets, or delivering content at scale, XyStorage gives you the tools you need to store, access, and manage files with ease.

Notifications You must be signed in to change notification settings

NextGenGk/XyStorage-Data-Reimagined

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

44 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

S3-UI: Modern AWS S3 File Management Interface

A production-ready, full-stack web application for managing AWS S3 files with a beautiful glass morphism UI, built with Next.js 15, TypeScript, React 19, and Clerk authentication.

S3-UI Demo

🎯 Current Status: Production Ready

βœ… All systems operational - File upload, download, and management working perfectly
βœ… Database connected - Supabase PostgreSQL with 4 files successfully stored
βœ… Authentication working - Clerk integration with user mapping
βœ… AWS S3 integrated - Files stored and accessible
βœ… API endpoints tested - All endpoints functional
βœ… Build ready - Production deployment prepared

πŸ“ Your Current Files (4 files found)

File Size Type Uploaded
favicon.svg 6.3KB image/svg+xml Today 14:58
ASSIGNMENT MCA.pdf 30.4KB application/pdf Today 14:43
codeeditor.png 507B image/png Today 14:42
Basic v2 (1).xlsx 9KB application/vnd.openxmlformats-officedocument.spreadsheetml.sheet Today 13:53

πŸš€ Quick Start (Production Ready)

Prerequisites

  • Node.js 18+
  • AWS S3 bucket
  • Supabase account
  • Clerk account

1. Environment Setup

# Clone repository
git clone <your-repo-url>
cd s3-ui

# Install dependencies
npm install

# Configure environment
cp .env.local.example .env.local

2. Environment Variables (.env.local)

# Application
NEXT_PUBLIC_APP_URL=http://localhost:3001
NODE_ENV=production

# Database (Supabase)
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key

# Authentication (Clerk)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up

# AWS S3
AWS_ACCESS_KEY_ID=your_aws_access_key
AWS_SECRET_ACCESS_KEY=your_aws_secret_key
AWS_REGION=your_aws_region
AWS_S3_BUCKET_NAME=your_bucket_name

3. Database Setup

-- Users table (auto-created by Clerk webhooks)
CREATE TABLE IF NOT EXISTS users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  clerk_id TEXT UNIQUE NOT NULL,
  email TEXT UNIQUE NOT NULL,
  first_name TEXT,
  last_name TEXT,
  bucket_prefix TEXT NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Files table
CREATE TABLE IF NOT EXISTS user_files (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id) ON DELETE CASCADE,
  s3_key TEXT NOT NULL,
  file_name TEXT NOT NULL,
  file_size INTEGER NOT NULL,
  content_type TEXT,
  uploaded_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  last_accessed TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  folder_id UUID REFERENCES folders(id) ON DELETE SET NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- Indexes for performance
CREATE INDEX idx_user_files_user_id ON user_files(user_id);
CREATE INDEX idx_user_files_uploaded_at ON user_files(uploaded_at DESC);
CREATE INDEX idx_users_clerk_id ON users(clerk_id);

4. Run Development

npm run dev
# Open http://localhost:3001

5. Production Build

npm run build
npm start

πŸ”Œ API Endpoints

Authentication

  • POST /api/webhooks/clerk - Clerk user sync webhook
  • GET /api/auth-test - Test authentication

File Operations

  • GET /api/objects - List user's files
  • POST /api/upload - Upload files
  • DELETE /api/objects/[id] - Delete file
  • PUT /api/objects/[id]/rename - Rename file
  • PUT /api/objects/[id]/move - Move file

User Management

  • GET /api/user-data - Get user info
  • GET /api/api-keys - Manage API keys
  • POST /api/api-keys - Create API key
  • DELETE /api/api-keys/[id] - Delete API key

Debug/Admin

  • GET /api/admin/all-files - All files (public)
  • GET /api/debug/user-files?clerkId=ID - User files (public)
  • GET /api/health - Health check

πŸ—οΈ Architecture

Frontend (Next.js 15)
β”œβ”€β”€ App Router (App Directory)
β”œβ”€β”€ React 19 (Server Components)
β”œβ”€β”€ TypeScript 5
β”œβ”€β”€ Tailwind CSS
β”œβ”€β”€ Framer Motion
β”œβ”€β”€ Radix UI Components
β”œβ”€β”€ Clerk Auth
└── React Hook Form

Backend (API Routes)
β”œβ”€β”€ Next.js API Routes
β”œβ”€β”€ AWS SDK v3 (S3)
β”œβ”€β”€ Supabase Client
β”œβ”€β”€ Zod Validation
β”œβ”€β”€ Rate Limiting
β”œβ”€β”€ Security Headers
└── Error Handling

Database
β”œβ”€β”€ Supabase PostgreSQL
β”œβ”€β”€ Row Level Security (RLS)
β”œβ”€β”€ Real-time Subscriptions
└── Automatic Backups

Storage
β”œβ”€β”€ AWS S3
β”œβ”€β”€ CloudFront CDN
β”œβ”€β”€ Lifecycle Policies
└── Versioning

🎯 Production Checklist

Before Deployment

  • Set production environment variables
  • Configure AWS S3 bucket policies
  • Set up Supabase production database
  • Configure Clerk production keys
  • Set up custom domain
  • Configure SSL certificates
  • Set up monitoring (health checks)
  • Configure rate limiting
  • Set up error tracking
  • Configure backup policies

Security

  • Enable RLS on Supabase tables
  • Configure S3 bucket policies
  • Set up CORS properly
  • Enable audit logging
  • Configure API rate limits
  • Set up DDoS protection

Performance

  • Enable CloudFront CDN
  • Configure image optimization
  • Set up caching headers
  • Enable compression
  • Configure database indexes

πŸ› Troubleshooting

Common Issues

  1. Build fails: Check environment variables
  2. Files not showing: Verify database connection
  3. Upload fails: Check AWS credentials and bucket permissions
  4. Authentication issues: Verify Clerk configuration
  5. CORS errors: Check middleware configuration

Debug Endpoints

# Check health
curl http://localhost:3001/api/health

# Test file access
curl http://localhost:3001/api/debug/user-files?clerkId=YOUR_CLERK_ID

# List all files (admin)
curl http://localhost:3001/api/admin/all-files

πŸ“Š Monitoring

Health Checks

  • /api/health - Application health
  • /api/debug/simple - Database connection test

Logs

  • Application logs: npm run dev output
  • Database logs: Supabase dashboard
  • AWS logs: CloudWatch

🀝 Contributing

  1. Fork the repository
  2. Create feature branch: git checkout -b feature/new-feature
  3. Commit changes: git commit -am 'Add new feature'
  4. Push to branch: git push origin feature/new-feature
  5. Submit pull request

πŸ“„ License

MIT License - see LICENSE file for details

πŸ†˜ Support

  • Issues: GitHub Issues
  • Documentation: This README
  • API Docs: Available at /api endpoints

Built with ❀️ using Next.js 15, TypeScript, and AWS S3

πŸ› οΈ Technology Stack

  • Frontend: Next.js 15, React 19, TypeScript
  • Styling: Tailwind CSS, Framer Motion, Lucide Icons
  • UI Components: Radix UI, Custom Glass Components
  • Authentication: Clerk
  • Database: Supabase (PostgreSQL)
  • Storage: AWS S3
  • Deployment: Vercel, Node.js

🚦 Getting Started

Prerequisites

  • Node.js 18 or higher
  • npm or yarn package manager
  • AWS S3 bucket
  • Supabase account
  • Clerk account

Installation

  1. Clone the repository

    git clone https://github.com/yourusername/s3-ui.git
    cd s3-ui
  2. Install dependencies

    npm install
  3. Set up environment variables

    cp .env.example .env
  4. Configure your environment

    Edit .env with your credentials:

    # Application
    NODE_ENV=development
    APP_URL=http://localhost:3001
    PORT=3001
    
    # Database (Supabase)
    SUPABASE_URL=your_supabase_project_url
    SUPABASE_ANON_KEY=your_supabase_anon_key
    SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
    
    # Authentication (Clerk)
    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
    CLERK_SECRET_KEY=your_clerk_secret_key
    NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
    NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
    NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
    NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
    
    # AWS S3
    AWS_REGION=us-east-1
    AWS_ACCESS_KEY_ID=your_aws_access_key
    AWS_SECRET_ACCESS_KEY=your_aws_secret_key
    AWS_S3_BUCKET_NAME=your_s3_bucket_name
    
    # Security
    JWT_SECRET=your_jwt_secret_64_characters
    ENCRYPTION_KEY=your_encryption_key_32_characters
  5. Set up the database

    Run the SQL schema in your Supabase database:

    # Copy the contents of supabase-schema.sql and run it in your Supabase SQL editor
  6. Start the development server

    npm run dev
  7. Open your browser

    Navigate to http://localhost:3001

πŸ“š API Documentation

Authentication

The API supports multiple authentication methods:

  1. Session Authentication - Automatic when signed in through the web interface via Clerk
  2. API Key Authentication - Use X-API-Key header or Authorization: Bearer <key> (for programmatic access)

Base URL

  • Development: http://localhost:3001
  • Production: https://your-domain.com

Response Format

All API responses follow a consistent JSON format:

{
  "success": true,
  "data": {},
  "error": "Error message (if applicable)",
  "message": "Success message (if applicable)"
}

Endpoints

File Operations

Upload File

POST /api/upload

Upload a single file to S3 storage.

  • Authentication: Required (Session or API Key)
  • Content-Type: multipart/form-data
  • Body Parameters:
    • file (File, required) - The file to upload
    • prefix (string, optional) - Directory prefix for the file

Example Request:

const formData = new FormData();
formData.append('file', fileObject);
formData.append('prefix', 'documents/'); // optional

const response = await fetch('/api/upload', {
  method: 'POST',
  headers: {
    'X-API-Key': 'your-api-key-here' // if using API key auth
  },
  body: formData
});

Success Response (200):

{
  "success": true,
  "message": "File uploaded successfully",
  "key": "documents/example.pdf",
  "size": 1048576
}

Error Responses:

  • 401 - Unauthorized (missing or invalid authentication)
  • 400 - Bad request (no file provided, storage quota exceeded)
  • 404 - User storage not configured
  • 500 - Server error
List Files

GET /api/objects

Retrieve all files for the authenticated user.

  • Authentication: Required (Session or API Key)
  • Query Parameters: None

Example Request:

const response = await fetch('/api/objects', {
  headers: {
    'X-API-Key': 'your-api-key-here'
  }
});

Success Response (200):

{
  "files": [
    {
      "id": "uuid",
      "file_name": "example.pdf",
      "file_size": 1048576,
      "content_type": "application/pdf",
      "uploaded_at": "2024-01-01T12:00:00Z",
      "s3_key": "documents/example.pdf"
    }
  ]
}
Download File

GET /api/download

Generate a secure download URL for a file.

  • Authentication: Required (Session or API Key)
  • Query Parameters:
    • key (string, required) - The file key/path
    • method (string, optional) - Download method (presigned or direct, default: presigned)

Example Request:

const response = await fetch('/api/download?key=documents/example.pdf&method=presigned', {
  headers: {
    'X-API-Key': 'your-api-key-here'
  }
});

Success Response (200):

{
  "success": true,
  "downloadUrl": "https://s3.amazonaws.com/bucket/signed-url",
  "expiresIn": 3600
}
Delete File

DELETE /api/delete

Delete a file from S3 storage and database.

  • Authentication: Required (Session or API Key)
  • Content-Type: application/json
  • Body Parameters:
    • key (string, required) - The file key/path to delete

Example Request:

const response = await fetch('/api/delete', {
  method: 'DELETE',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'your-api-key-here'
  },
  body: JSON.stringify({
    key: 'documents/example.pdf'
  })
});

Success Response (200):

{
  "success": true,
  "message": "File deleted successfully"
}

API Key Management

List API Keys

GET /api/api-keys

Retrieve all API keys for the authenticated user.

  • Authentication: Required (Session only)

Success Response (200):

{
  "apiKeys": [
    {
      "id": "uuid",
      "key_name": "Mobile App Key",
      "api_key": "ak_1234567890abcdef...",
      "permissions": ["read", "write"],
      "is_active": true,
      "last_used": "2024-01-01T12:00:00Z",
      "expires_at": null,
      "created_at": "2024-01-01T10:00:00Z"
    }
  ]
}
Create API Key

POST /api/api-keys

Create a new API key with specified permissions.

  • Authentication: Required (Session only)
  • Content-Type: application/json
  • Body Parameters:
    • keyName (string, required) - Name for the API key
    • permissions (string[], required) - Array of permissions (read, write, delete)

Example Request:

const response = await fetch('/api/api-keys', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    keyName: 'Mobile App Key',
    permissions: ['read', 'write']
  })
});

Success Response (201):

{
  "success": true,
  "message": "API key created successfully",
  "key": "ak_1234567890abcdef...",
  "keyId": "uuid"
}
Delete API Key

DELETE /api/api-keys?keyId=<id>&action=delete

Delete an existing API key.

  • Authentication: Required (Session only)
  • Query Parameters:
    • keyId (string, required) - The API key ID to delete
    • action (string, required) - Must be "delete"

Success Response (200):

{
  "success": true,
  "message": "API key deleted successfully"
}

User & System

Get User Data

GET /api/user-data

Retrieve user profile and storage information.

  • Authentication: Required (Session or API Key)

Success Response (200):

{
  "user": {
    "id": "user_123",
    "email": "[email protected]",
    "firstName": "John",
    "lastName": "Doe"
  },
  "storage": {
    "used": 52428800,
    "available": 1047619200,
    "total": 1073741824,
    "prefix": "user-user_123"
  },
  "files": [
    {
      "id": "uuid",
      "file_name": "example.pdf",
      "file_size": 1048576,
      "downloadUrl": "https://s3.amazonaws.com/bucket/signed-url"
    }
  ]
}
Health Check

GET /api/health

System health check endpoint for monitoring.

  • Authentication: Not required

Success Response (200):

{
  "status": "healthy",
  "timestamp": "2024-01-01T12:00:00Z",
  "version": "1.0.0",
  "uptime": 3600,
  "environment": "production",
  "services": {
    "database": "healthy",
    "storage": "healthy",
    "auth": "healthy"
  },
  "metrics": {
    "memoryUsage": {
      "used": 128,
      "total": 512,
      "percentage": 25
    },
    "requestCount": 1000
  }
}

HEAD /api/health - Readiness probe (returns 200 if ready, 503 if not)

Authentication Test

GET /api/auth-test

Test authentication status and method.

  • Authentication: Required (Session or API Key)

Success Response (200):

{
  "authenticated": true,
  "method": "api_key",
  "userId": "user_123",
  "permissions": ["read", "write"]
}

Error Handling

All endpoints return consistent error responses:

Error Response Format:

{
  "error": "Error type",
  "message": "Detailed error message",
  "statusCode": 400,
  "context": {
    "timestamp": "2024-01-01T12:00:00Z",
    "requestId": "req_123"
  }
}

Common Error Codes:

  • 400 - Bad Request (invalid parameters, file too large, quota exceeded)
  • 401 - Unauthorized (missing or invalid authentication)
  • 403 - Forbidden (insufficient permissions)
  • 404 - Not Found (user not found, file not found)
  • 429 - Too Many Requests (rate limit exceeded)
  • 500 - Internal Server Error
  • 503 - Service Unavailable (health check failed)

Rate Limiting

API endpoints are protected with rate limiting:

  • Default limit: 100 requests per 15 minutes per IP/API key
  • Headers returned:
    • X-RateLimit-Limit: Maximum requests allowed
    • X-RateLimit-Remaining: Requests remaining in current window
    • X-RateLimit-Reset: Time when the rate limit resets

SDK Examples

JavaScript/Node.js

class S3UIClient {
  constructor(apiKey, baseUrl = 'https://your-domain.com') {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl;
  }

  async uploadFile(file, prefix = '') {
    const formData = new FormData();
    formData.append('file', file);
    if (prefix) formData.append('prefix', prefix);

    const response = await fetch(`${this.baseUrl}/api/upload`, {
      method: 'POST',
      headers: { 'X-API-Key': this.apiKey },
      body: formData
    });

    return response.json();
  }

  async listFiles() {
    const response = await fetch(`${this.baseUrl}/api/objects`, {
      headers: { 'X-API-Key': this.apiKey }
    });

    return response.json();
  }

  async deleteFile(key) {
    const response = await fetch(`${this.baseUrl}/api/delete`, {
      method: 'DELETE',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': this.apiKey
      },
      body: JSON.stringify({ key })
    });

    return response.json();
  }
}

// Usage
const client = new S3UIClient('your-api-key');
await client.uploadFile(fileObject, 'documents/');

Python

import requests

class S3UIClient:
    def __init__(self, api_key, base_url="https://your-domain.com"):
        self.api_key = api_key
        self.base_url = base_url
        self.headers = {"X-API-Key": api_key}

    def upload_file(self, file_path, prefix=""):
        with open(file_path, 'rb') as f:
            files = {'file': f}
            data = {'prefix': prefix} if prefix else {}
            
            response = requests.post(
                f"{self.base_url}/api/upload",
                headers=self.headers,
                files=files,
                data=data
            )
            
        return response.json()

    def list_files(self):
        response = requests.get(
            f"{self.base_url}/api/objects",
            headers=self.headers
        )
        return response.json()

    def delete_file(self, key):
        response = requests.delete(
            f"{self.base_url}/api/delete",
            headers={**self.headers, "Content-Type": "application/json"},
            json={"key": key}
        )
        return response.json()

# Usage
client = S3UIClient("your-api-key")
client.upload_file("document.pdf", "documents/")

🎨 UI Components

Glass Morphism Design System

The app features a custom glass morphism design system:

  • GlassCard - Translucent cards with backdrop blur
  • Loading Spinners - Animated loading indicators
  • File Upload Zone - Drag & drop area with visual feedback
  • Professional Modals - Glass morphism modal dialogs
  • Breadcrumb Navigation - Intuitive navigation component

Animation System

Built with Framer Motion for smooth, professional animations:

  • Page transitions
  • Component entrance animations
  • Hover effects and micro-interactions
  • Loading state animations

πŸ”§ Configuration

Environment Variables

Variable Description Required
SUPABASE_URL Your Supabase project URL βœ…
SUPABASE_ANON_KEY Supabase anonymous key βœ…
SUPABASE_SERVICE_ROLE_KEY Supabase service role key βœ…
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY Clerk publishable key βœ…
CLERK_SECRET_KEY Clerk secret key βœ…
AWS_ACCESS_KEY_ID AWS access key βœ…
AWS_SECRET_ACCESS_KEY AWS secret key βœ…
AWS_S3_BUCKET_NAME S3 bucket name βœ…
JWT_SECRET Secret for API key generation βœ…
ENCRYPTION_KEY 32-character encryption key βœ…

File Upload Limits

  • Maximum file size: 100MB (configurable via MAX_FILE_SIZE)
  • Maximum files per user: 1000 (configurable via MAX_FILES_PER_USER)
  • Supported formats: All file types

πŸš€ Deployment

Vercel (Recommended)

  1. Install Vercel CLI

    npm i -g vercel
  2. Deploy

    vercel --prod
  3. Add environment variables in Vercel dashboard

Traditional Hosting

  1. Build the application

    npm run build
  2. Start production server

    npm start

Health Monitoring

The application includes built-in health monitoring:

  • Health Check: GET /api/health
  • Readiness Check: HEAD /api/health
  • Service Status: Database, Storage, and Auth service monitoring

πŸ›‘οΈ Security Features

  • CORS Protection - Configured for production domains
  • Security Headers - CSP, XSS protection, and frame options
  • Input Validation - Server-side validation for all inputs
  • Error Handling - Secure error messages that don't expose internals
  • API Key Encryption - Encrypted storage of API keys
  • Permission System - Granular API key permissions

πŸ” Monitoring & Debugging

Development Tools

  • TypeScript - Full type checking
  • ESLint - Code quality and consistency
  • Error Boundaries - Graceful error handling in React
  • Structured Logging - Contextual logging throughout the app

Production Monitoring

  • Health check endpoints for uptime monitoring
  • Memory usage tracking
  • Request logging and metrics
  • Error tracking and reporting

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments


Built with ❀️ using modern web technologies

About

XyStorage is a fast, secure, and developer-first cloud storage solution designed to scale with your applications. Whether you're building a SaaS product, managing large datasets, or delivering content at scale, XyStorage gives you the tools you need to store, access, and manage files with ease.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published