# 🔐 Dropbox OAuth2 Credentials Setup Guide

## Overview

This guide will help you set up Dropbox OAuth2 credentials with **refresh tokens** for automatic token renewal. This ensures your application never loses access to Dropbox due to expired tokens.

---

## 📋 What You'll Get

After following this guide, you'll have these credentials:
- ✅ **App Key** (Client ID)
- ✅ **App Secret** (Client Secret)
- ✅ **Refresh Token** (Never expires!)

---

## 🚀 Step-by-Step Setup

### Step 1: Create a Dropbox App

1. **Go to Dropbox App Console**
   - Visit: https://www.dropbox.com/developers/apps
   - Sign in with your Dropbox account

2. **Click "Create app"**

3. **Choose API Settings:**
   - **Choose an API**: Select **"Scoped access"**
   - **Choose the type of access**: Select **"Full Dropbox"**
   - **Name your app**: Enter a unique name (e.g., `CSSAwards-FileStorage`)
   - Click **"Create app"**

---

### Step 2: Configure App Permissions

1. **Go to the Permissions tab**
   
2. **Enable these permissions:**
   - ✅ `files.content.write` - Upload files
   - ✅ `files.content.read` - Read files
   - ✅ `files.content.delete` - Delete files (optional)
   - ✅ `sharing.write` - Create shared links
   - ✅ `sharing.read` - Read shared links

3. **Click "Submit"** at the bottom

---

### Step 3: Get Your App Key and App Secret

1. **Go to the Settings tab**

2. **Find "App key" and "App secret":**
   ```
   App key: abc123xyz456...
   App secret: [Show] ← Click to reveal
   ```

3. **Copy both values:**
   - **App Key** (also called Client ID)
   - **App Secret** (also called Client Secret)
   
4. **Save these in a secure location** (you'll need them soon)

---

### Step 4: Enable OAuth2 Authorization Code Flow

1. **Still in the Settings tab**, scroll down to **"OAuth 2"** section

2. **Add Redirect URI:**
   - In the "Redirect URIs" field, add: `http://localhost`
   - Click **"Add"**
   
   > This is needed to get the authorization code

---

### Step 5: Get Authorization Code

1. **Create the Authorization URL** by replacing `YOUR_APP_KEY` with your actual App Key:

```
https://www.dropbox.com/oauth2/authorize?client_id=sie2iy5wvassus9
&response_type=code&token_access_type=offline
```

**Example:**
```
https://www.dropbox.com/oauth2/authorize?client_id=abc123xyz456&response_type=code&token_access_type=offline
```

⚠️ **Important**: Include `&token_access_type=offline` to get a refresh token!

2. **Open this URL in your browser**

3. **Click "Allow"** to authorize the app

4. **You'll be redirected to:**
```
http://localhost/?code=AUTHORIZATION_CODE_HERE
```

5. **Copy the entire authorization code** from the URL
   - It's the value after `code=`
   - Example: `code=abc123XYZ789def456...`

---

### Step 6: Exchange Authorization Code for Refresh Token

Now we'll exchange the authorization code for a refresh token using a simple script.

#### Option A: Using Node.js Script (Recommended)

1. **Create a file** named `get-dropbox-tokens.js` in your Backend folder:

```javascript
import fetch from 'node-fetch';

const APP_KEY = 'YOUR_APP_KEY_HERE';
const APP_SECRET = 'YOUR_APP_SECRET_HERE';
const AUTHORIZATION_CODE = 'YOUR_AUTHORIZATION_CODE_HERE';

async function getTokens() {
  try {
    const params = new URLSearchParams();
    params.append('code', AUTHORIZATION_CODE);
    params.append('grant_type', 'authorization_code');
    params.append('client_id', APP_KEY);
    params.append('client_secret', APP_SECRET);

    const response = await fetch('https://api.dropbox.com/oauth2/token', {
      method: 'POST',
      body: params.toString(),
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    });

    const data = await response.json();
    
    if (response.ok) {
      console.log('✅ Success! Here are your tokens:\n');
      console.log('Access Token:', data.access_token);
      console.log('\n🔑 REFRESH TOKEN (Save this!):', data.refresh_token);
      console.log('\nAdd these to your .env file:');
      console.log(`DROPBOX_APP_KEY=${APP_KEY}`);
      console.log(`DROPBOX_APP_SECRET=${APP_SECRET}`);
      console.log(`DROPBOX_REFRESH_TOKEN=${data.refresh_token}`);
    } else {
      console.error('❌ Error:', data);
    }
  } catch (error) {
    console.error('❌ Error:', error.message);
  }
}

getTokens();
```

2. **Replace the values:**
   - `YOUR_APP_KEY_HERE` → Your App Key from Step 3
   - `YOUR_APP_SECRET_HERE` → Your App Secret from Step 3
   - `YOUR_AUTHORIZATION_CODE_HERE` → Authorization code from Step 5

3. **Run the script:**
```bash
node get-dropbox-tokens.js
```

4. **Copy the REFRESH TOKEN** from the output

#### Option B: Using cURL (Alternative)

If you prefer using cURL, run this command (replace the values):

```bash
curl -X POST https://api.dropbox.com/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "code=YOUR_AUTHORIZATION_CODE" \
  -d "grant_type=authorization_code" \
  -d "client_id=YOUR_APP_KEY" \
  -d "client_secret=YOUR_APP_SECRET"
```

---

### Step 7: Update Your .env File

1. **Open** `Backend/.env`

2. **Add or update these lines:**

```env
# Dropbox OAuth2 Configuration
DROPBOX_APP_KEY=abc123xyz456...
DROPBOX_APP_SECRET=xyz789abc123...
DROPBOX_REFRESH_TOKEN=def456ghi789...
```

3. **Replace with your actual values** from the previous steps

4. **Remove the old token** if it exists:
```env
# Remove this line if present:
# DROPBOX_ACCESS_TOKEN=sl.xxx...
```

---

### Step 8: Test the Setup

1. **Restart your server:**
```bash
npm start
```

2. **Run the test script:**
```bash
node test-dropbox-connection.js
```

Expected output:
```
🔄 Refreshing Dropbox access token...
✅ Dropbox access token refreshed successfully
📤 Uploading file to Dropbox...
✅ File uploaded to Dropbox
✅ All tests passed!
🎉 Dropbox integration is working correctly!
```

---

## 📝 Summary of Credentials

After completing all steps, you should have:

| Credential | Format | Example | Where to Find |
|------------|--------|---------|---------------|
| **App Key** | alphanumeric | `abc123xyz456` | Settings tab in Dropbox App Console |
| **App Secret** | alphanumeric | `xyz789abc123` | Settings tab (click "Show") |
| **Refresh Token** | long string | `def456ghi789...` | Generated via OAuth2 flow (Step 6) |

---

## 🔐 Security Best Practices

1. ✅ **Never commit .env file** to Git
   - Add `.env` to `.gitignore`

2. ✅ **Use different apps** for development and production
   - Create separate Dropbox apps for each environment

3. ✅ **Rotate credentials** periodically
   - Generate new refresh tokens every 6-12 months

4. ✅ **Keep credentials secure**
   - Don't share them in chat, email, or screenshots
   - Use environment variables, never hardcode

---

## 🔄 How Token Refresh Works

```
1. App starts → No access token
2. App calls getDropboxAccessToken()
3. Uses refresh token to get new access token
4. Access token stored in memory (valid for 4 hours)
5. On upload/delete, use current access token
6. If token expired (401 error), refresh and retry
7. Repeat as needed (refresh token never expires!)
```

---

## ❓ Troubleshooting

### "Invalid authorization code"
- **Cause**: Authorization code already used or expired
- **Solution**: Generate a new authorization code (repeat Step 5)

### "Invalid client_id or client_secret"
- **Cause**: Wrong App Key or App Secret
- **Solution**: Double-check values in Dropbox App Console

### "Missing required scopes"
- **Cause**: Permissions not enabled
- **Solution**: Go to Permissions tab and enable required permissions (Step 2)

### "redirect_uri mismatch"
- **Cause**: Wrong redirect URI
- **Solution**: Make sure you added `http://localhost` in Step 4

### "Token refresh failed"
- **Cause**: Wrong refresh token or credentials in .env
- **Solution**: Verify all three values are correct in .env file

---

## 🆘 Need Help?

1. **Check logs** in your terminal for detailed error messages
2. **Verify credentials** in `.env` file
3. **Test manually** using the script in Step 6
4. **Review permissions** in Dropbox App Console
5. **Check Dropbox API status**: https://status.dropbox.com/

---

## ✅ Final Checklist

Before deploying to production:

- [ ] Created Dropbox app
- [ ] Enabled all required permissions
- [ ] Got App Key and App Secret
- [ ] Generated authorization code
- [ ] Exchanged code for refresh token
- [ ] Added all 3 credentials to .env file
- [ ] Tested with `node test-dropbox-connection.js`
- [ ] Tested file upload through the application
- [ ] Verified files appear in Dropbox
- [ ] Added .env to .gitignore
- [ ] Created separate app for production (recommended)

---

## 📚 Additional Resources

- **Dropbox OAuth Guide**: https://developers.dropbox.com/oauth-guide
- **Dropbox API Documentation**: https://www.dropbox.com/developers/documentation
- **Scoped Access**: https://developers.dropbox.com/oauth-guide#scoped-access

---

**Last Updated**: November 14, 2025  
**Version**: 2.0 (OAuth2 with Refresh Token)
