streamflix-api / src /shared /modules /upload /box-storage /BOX_STORAGE_GUIDE.md
Akshar2325
feat(box-storage): add box.com cloud storage integration
c5b7daf
|
Raw
History Blame
10.3 kB

Box.com Storage Integration

Complete guide for Box.com OAuth 2.0 cloud storage integration with automatic token management and file streaming.

πŸ“‹ Table of Contents


✨ Features

  • βœ… OAuth 2.0 User Authentication
  • βœ… Automatic token refresh and persistence (box-tokens.json)
  • βœ… File upload with automatic folder routing (IMAGE/VIDEO/DOCUMENT)
  • βœ… File streaming through your server (supports images, videos, PDFs, audio, etc.)
  • βœ… File deletion by ID
  • βœ… No manual token management required

πŸš€ Setup Guide

Step 1: Create a Box Custom App

  1. Go to Box Developer Console
  2. Click "Create New App"
  3. Select "Custom App"
  4. Choose "User Authentication (OAuth 2.0)" ⚠️ (NOT JWT or Client Credentials)
  5. Name your app (e.g., "Streamflix API")

Step 2: Configure OAuth Settings

  1. In your app's Configuration tab:
    • Copy Client ID and Client Secret
    • Add redirect URI: http://localhost:5119/box/oauth/callback
    • Enable scopes:
      • βœ… Read all files and folders
      • βœ… Write all files and folders
    • Save changes

Step 3: Get Folder IDs

  1. Log in to Box.com
  2. Create your folder structure:
    Streamflix/
    β”œβ”€β”€ images/
    β”œβ”€β”€ videos/
    └── documents/
    
  3. Open each folder and copy the ID from the URL:
    https://app.box.com/folder/358198319436
                               ^^^^^^^^^^^^
                               This is the folder ID
    

Step 4: Configure Environment Variables

Update your .env file:

# Box.com OAuth 2.0 Configuration
BOX_CLIENT_ID="your_client_id_here"
BOX_CLIENT_SECRET="your_client_secret_here"
BOX_REDIRECT_URI="http://localhost:5119/box/oauth/callback"

# Box Folder IDs (get from Box.com URLs)
BOX_STREAMFLIX_FOLDER_ID="358198319436"  # Main folder
BOX_IMAGES_FOLDER_ID="358199056099"      # For IMAGE type uploads
BOX_VIDEOS_FOLDER_ID="358199692412"      # For VIDEO type uploads
BOX_DOCUMENTS_FOLDER_ID="358199056099"   # For DOCUMENT type uploads

# App URL (for generating content URLs)
APP_URL="http://localhost:5119"

Step 5: Authorize Your Application (One-Time)

  1. Start your application:

    npm run start:dev
    
  2. Visit the authorization URL in your browser:

    http://localhost:5119/box/oauth/authorize
    
  3. Log in to Box.com and grant access

  4. Done! Tokens are automatically saved to box-tokens.json


βš™οΈ Configuration

Automatic Token Management

  • Tokens are stored in box-tokens.json (already in .gitignore)
  • Access tokens automatically refresh every ~1 hour
  • Refresh tokens are automatically updated when Box issues new ones
  • No manual intervention required after initial authorization

Folder Routing

When uploading files, specify the fileType parameter:

  • fileType=IMAGE β†’ Uploads to BOX_IMAGES_FOLDER_ID
  • fileType=VIDEO β†’ Uploads to BOX_VIDEOS_FOLDER_ID
  • fileType=DOCUMENT β†’ Uploads to BOX_DOCUMENTS_FOLDER_ID
  • No parameter β†’ Uploads to BOX_STREAMFLIX_FOLDER_ID (main folder)

πŸ“‘ API Endpoints

1. OAuth Authorization

Start OAuth Flow

GET /box/oauth/authorize

Redirects to Box.com for user authorization (one-time setup).

OAuth Callback (Automatically called by Box)

GET /box/oauth/callback?code={code}

Exchanges authorization code for tokens and saves to box-tokens.json.


2. Upload File

POST /box/upload

Query Parameters:

  • fileType (optional): IMAGE, VIDEO, or DOCUMENT
  • customFilename (optional): Custom filename without extension

Form Data:

  • file: Binary file data

Example Request:

curl -X POST "http://localhost:5119/box/upload?fileType=IMAGE" \
  -F "file=@photo.jpg"

Response:

{
  "success": true,
  "name": "1766841360028-photo.jpg",
  "boxFileId": "2087753948639",
  "size": 357909,
  "folderId": "358199056099",
  "publicUrl": "https://app.box.com/s/xxxxx",
  "contentUrl": "http://localhost:5119/box/file/2087753948639",
  "extraData": {
    "sha1": "22a487ac758861029dfa5791d94c8d50c51b909e",
    "createdAt": "2025-12-27T05:16:01-08:00",
    "modifiedAt": "2025-12-27T05:16:01-08:00"
  }
}

Use contentUrl for direct file access!


3. Stream File Content

GET /box/file/:fileId

Streams file content through your server. Works for images, videos, PDFs, audio, and more.

Example:

<!-- Display image -->
<img src="http://localhost:5119/box/file/2087753948639" />

<!-- Embed video -->
<video controls>
  <source src="http://localhost:5119/box/file/2087753948639" />
</video>

<!-- Embed PDF -->
<iframe src="http://localhost:5119/box/file/2087753948639"></iframe>

Supported Features:

  • βœ… Images display inline
  • βœ… Videos support seeking (Accept-Ranges header)
  • βœ… PDFs display in browser
  • βœ… Audio files play inline
  • βœ… Text files display inline
  • βœ… Cached for 1 year (optimal performance)

4. Delete File

DELETE /box/by-id?fileId={fileId}

Query Parameters:

  • fileId (required): Box file ID

Example:

curl -X DELETE "http://localhost:5119/box/by-id?fileId=2087753948639"

Response:

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

🎯 Usage Examples

Upload and Display Image

// Upload
const formData = new FormData();
formData.append('file', imageFile);

const response = await fetch(
  'http://localhost:5119/box/upload?fileType=IMAGE',
  {
    method: 'POST',
    body: formData,
  },
);

const data = await response.json();

// Display using contentUrl
const img = document.createElement('img');
img.src = data.contentUrl; // http://localhost:5119/box/file/2087753948639
document.body.appendChild(img);

Upload and Play Video

// Upload
const formData = new FormData();
formData.append('file', videoFile);

const response = await fetch(
  'http://localhost:5119/box/upload?fileType=VIDEO',
  {
    method: 'POST',
    body: formData,
  },
);

const data = await response.json();

// Play video
const video = document.createElement('video');
video.src = data.contentUrl;
video.controls = true;
document.body.appendChild(video);

Delete File

const fileId = '2087753948639';

await fetch(`http://localhost:5119/box/by-id?fileId=${fileId}`, {
  method: 'DELETE',
});

🎨 File Type Support

Images (Display Inline)

  • JPG/JPEG, PNG, GIF, WebP, SVG, BMP, ICO, TIFF

Videos (Play Inline with Seeking)

  • MP4, WebM, OGG, AVI, MOV, WMV, FLV, MKV, M4V, 3GP

Audio (Play Inline)

  • MP3, WAV, OGG, M4A, AAC, FLAC

Documents (Display Inline)

  • PDF (viewable in browser)
  • Word, Excel, PowerPoint (will download)

Text (Display Inline)

  • TXT, HTML, CSS, JS, JSON, XML, CSV, Markdown

Archives (Download)

  • ZIP, RAR, 7Z, TAR, GZ

πŸ”§ Troubleshooting

"No tokens found! Please authorize via OAuth"

Solution: Run the OAuth flow once:

http://localhost:5119/box/oauth/authorize

"Refresh token expired!"

Solution: The refresh token has expired. Re-authorize:

http://localhost:5119/box/oauth/authorize

"Box OAuth credentials not configured"

Solution: Check your .env file:

  • BOX_CLIENT_ID must be set
  • BOX_CLIENT_SECRET must be set
  • Restart your application after updating .env

File downloads instead of displaying inline

Cause: Incorrect MIME type or Content-Disposition header

Solution: Already fixed! The stream endpoint now:

  • Detects MIME types from file extensions
  • Sets Content-Disposition: inline
  • Supports 50+ file formats

Video won't seek/skip

Cause: Missing Accept-Ranges header

Solution: Already fixed! The stream endpoint now includes:

Accept-Ranges: bytes

This enables video seeking in all browsers.


Images are resized/compressed

Answer: No! Files are streamed byte-for-byte from Box.com with no modifications. What you upload is exactly what gets delivered.


πŸ” Security Notes

  1. Never commit box-tokens.json - Already in .gitignore
  2. Keep .env secure - Never commit to version control
  3. Use environment variables in production
  4. Rotate tokens if compromised (re-run OAuth flow)

πŸ“ Technical Details

Token Flow

  1. Initial Authorization (one-time)

    • User visits /box/oauth/authorize
    • Redirected to Box.com
    • User grants access
    • Tokens saved to box-tokens.json
  2. Automatic Refresh (background)

    • Access token expires after 60 minutes
    • Service automatically refreshes using refresh token
    • New tokens saved to box-tokens.json
    • If Box issues new refresh token, it's automatically updated
  3. Persistence

    • Tokens survive application restarts
    • Loaded from box-tokens.json on startup
    • No manual intervention required

File Streaming

  • Files are streamed, not downloaded to server
  • Zero server storage used
  • Supports large files (videos, archives)
  • Browser caching enabled for optimal performance
  • Range requests supported for video seeking

πŸ“š Additional Resources


πŸŽ‰ Quick Start Checklist

  • Create Box Custom App with OAuth 2.0
  • Get Client ID and Client Secret
  • Create folder structure in Box.com
  • Get folder IDs from URLs
  • Update .env file
  • Start application
  • Visit /box/oauth/authorize
  • Grant access to Box
  • Test upload: POST /box/upload
  • Test display: Use contentUrl in browser
  • Done! πŸš€

Need help? Check the troubleshooting section or contact support.