docs(readme): enhance OAuth app setup and environment config instructions

- Add detailed step-by-step guides for Microsoft Azure and Google Cloud OAuth app registration
- Specify required API permissions and redirect URIs for both providers
- Include security note emphasizing client secrets stored only on backend
- Update environment variable configuration for frontend and backend with examples
- Enhance UI badges to conditionally display connection direction and status
- Revise Azure and Google setup instructions in the app interface for clarity and completeness
- Improve alert sections to clearly separate frontend and backend environment file instructions
This commit is contained in:
MUIS1436
2026-01-31 16:19:05 +05:00
parent 42841bcd83
commit 6f14c89aa4
2 changed files with 152 additions and 49 deletions

View File

@@ -39,31 +39,75 @@ npm install
cd .. cd ..
``` ```
### 3. Configure Environment Variables ### 3. Configure OAuth Applications
**Frontend (`.env`):** #### Step A: Microsoft Azure (OneDrive)
Create a `.env` file in the root directory:
1. Go to **[Azure Portal](https://portal.azure.com)** → **Azure Active Directory****App registrations**
2. Click **"New registration"**
3. Fill in:
- **Name**: `CloudStream Transfer` (or any name)
- **Supported account types**: "Accounts in any organizational directory and personal Microsoft accounts"
- **Redirect URI**: Select "Single-page application (SPA)" and enter:
- Development: `http://localhost:5173/auth/callback`
- Production: `https://yourdomain.com/auth/callback`
4. Click **Register**
5. Copy the **Application (client) ID** → This is your `VITE_MS_CLIENT_ID`
6. Go to **Certificates & secrets****New client secret**
- Add a description and expiry
- Copy the **Value** immediately (shown only once) → This is your `MS_CLIENT_SECRET`
7. Go to **API permissions****Add a permission****Microsoft Graph****Delegated permissions**
- Add: `Files.Read`, `Files.Read.All`, `Files.ReadWrite`, `Files.ReadWrite.All`, `User.Read`
- Click **Grant admin consent** (if you're an admin)
#### Step B: Google Cloud (Google Drive)
1. Go to **[Google Cloud Console](https://console.cloud.google.com)**
2. Create a new project or select existing one
3. Go to **APIs & Services****Enabled APIs & Services**
- Click **+ ENABLE APIS AND SERVICES**
- Search for **"Google Drive API"** and **Enable** it
4. Go to **APIs & Services****Credentials**
5. Click **+ CREATE CREDENTIALS** → **OAuth client ID**
- If prompted, configure the **OAuth consent screen** first:
- User Type: External
- App name, support email, developer email (required fields)
- Scopes: Add `https://www.googleapis.com/auth/drive`
6. Back to Credentials → **OAuth client ID**:
- Application type: **Web application**
- Name: `CloudStream Transfer`
- Authorized redirect URIs:
- `http://localhost:5173/auth/callback` (development)
- `https://yourdomain.com/auth/callback` (production)
7. Click **Create**
8. Copy **Client ID** → This is your `VITE_GOOGLE_CLIENT_ID`
9. Copy **Client Secret** → This is your `GOOGLE_CLIENT_SECRET`
#### Step C: Create Environment Files
**Frontend (`.env` in root directory):**
```env ```env
VITE_MS_CLIENT_ID=your_microsoft_client_id VITE_MS_CLIENT_ID=your_microsoft_client_id
VITE_GOOGLE_CLIENT_ID=your_google_client_id VITE_GOOGLE_CLIENT_ID=your_google_client_id
``` ```
**Backend (`server/.env`):** **Backend (`server/.env`):**
Create a `.env` file in the `server` directory:
```env ```env
PORT=3001 PORT=9173
# Microsoft Graph Credentials
# Microsoft (same Client ID as frontend + secret)
VITE_MS_CLIENT_ID=your_microsoft_client_id VITE_MS_CLIENT_ID=your_microsoft_client_id
MS_CLIENT_SECRET=your_microsoft_client_secret MS_CLIENT_SECRET=your_microsoft_client_secret
# Google Drive Credentials # Google (same Client ID as frontend + secret)
VITE_GOOGLE_CLIENT_ID=your_google_client_id VITE_GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret GOOGLE_CLIENT_SECRET=your_google_client_secret
# Must match your OAuth app redirect URI
REDIRECT_URI=http://localhost:5173/auth/callback REDIRECT_URI=http://localhost:5173/auth/callback
``` ```
> **Note:** You must register applications in both Azure Portal and Google Cloud Console. > **🔐 Security Note**: Client IDs are public (like your app's name). Client Secrets are private and ONLY stored on the backend - never exposed to browsers. Your files are safe!
> Ensure the Redirect URI is set to `http://localhost:5173/auth/callback`.
### 4. Run the Application ### 4. Run the Application

View File

@@ -404,21 +404,43 @@ function App() {
</div> </div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Badge variant={authState.onedrive ? 'default' : 'secondary'} {direction === 'onedrive-to-google' ? (
className={cn( <>
"transition-all duration-300 shadow-md", <Badge variant={authState.onedrive ? 'default' : 'secondary'}
authState.onedrive && 'bg-gradient-to-r from-blue-500 to-blue-600 shadow-blue-500/50' className={cn(
)}> "transition-all duration-300 shadow-md",
{authState.onedrive ? '✓ OneDrive Connected' : 'OneDrive'} authState.onedrive && 'bg-gradient-to-r from-blue-500 to-blue-600 shadow-blue-500/50'
</Badge> )}>
<ArrowRight className="w-5 h-5 text-slate-400 animate-pulse" /> {authState.onedrive ? '✓ OneDrive Connected' : 'OneDrive'}
<Badge variant={authState.googledrive ? 'default' : 'secondary'} </Badge>
className={cn( <ArrowRight className="w-5 h-5 text-purple-500 animate-pulse" />
"transition-all duration-300 shadow-md", <Badge variant={authState.googledrive ? 'default' : 'secondary'}
authState.googledrive && 'bg-gradient-to-r from-green-500 to-emerald-600 shadow-green-500/50' className={cn(
)}> "transition-all duration-300 shadow-md",
{authState.googledrive ? '✓ Google Drive Connected' : 'Google Drive'} authState.googledrive && 'bg-gradient-to-r from-green-500 to-emerald-600 shadow-green-500/50'
</Badge> )}>
{authState.googledrive ? '✓ Google Drive Connected' : 'Google Drive'}
</Badge>
</>
) : (
<>
<Badge variant={authState.googledrive ? 'default' : 'secondary'}
className={cn(
"transition-all duration-300 shadow-md",
authState.googledrive && 'bg-gradient-to-r from-green-500 to-emerald-600 shadow-green-500/50'
)}>
{authState.googledrive ? '✓ Google Drive Connected' : 'Google Drive'}
</Badge>
<ArrowRight className="w-5 h-5 text-purple-500 animate-pulse" />
<Badge variant={authState.onedrive ? 'default' : 'secondary'}
className={cn(
"transition-all duration-300 shadow-md",
authState.onedrive && 'bg-gradient-to-r from-blue-500 to-blue-600 shadow-blue-500/50'
)}>
{authState.onedrive ? '✓ OneDrive Connected' : 'OneDrive'}
</Badge>
</>
)}
</div> </div>
</div> </div>
</div> </div>
@@ -470,47 +492,84 @@ function App() {
<div className="p-6 bg-gradient-to-br from-blue-50 to-blue-100 dark:from-blue-900/30 dark:to-blue-800/30 rounded-xl border-2 border-blue-200 dark:border-blue-700 shadow-lg hover:shadow-xl transition-shadow duration-300"> <div className="p-6 bg-gradient-to-br from-blue-50 to-blue-100 dark:from-blue-900/30 dark:to-blue-800/30 rounded-xl border-2 border-blue-200 dark:border-blue-700 shadow-lg hover:shadow-xl transition-shadow duration-300">
<h4 className="font-bold text-lg text-blue-700 dark:text-blue-300 mb-4 flex items-center gap-2"> <h4 className="font-bold text-lg text-blue-700 dark:text-blue-300 mb-4 flex items-center gap-2">
<Cloud className="w-5 h-5" /> <Cloud className="w-5 h-5" />
Microsoft OneDrive Step 1: Microsoft Azure
</h4> </h4>
<ol className="text-sm space-y-2 text-slate-700 dark:text-slate-300 list-decimal list-inside"> <ol className="text-sm space-y-2 text-slate-700 dark:text-slate-300 list-decimal list-inside">
<li>Go to <a href="https://portal.azure.com" target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 underline hover:text-blue-700 dark:hover:text-blue-300">Azure Portal</a></li> <li>Go to <a href="https://portal.azure.com" target="_blank" rel="noopener noreferrer" className="text-blue-600 dark:text-blue-400 underline hover:text-blue-700 dark:hover:text-blue-300">Azure Portal</a> Azure AD App registrations</li>
<li>Navigate to Azure AD &gt; App registrations</li> <li>Click <strong>"New registration"</strong></li>
<li>Click "New registration"</li> <li>Set account type: "Personal Microsoft accounts"</li>
<li className="break-all">Set redirect URI: <code className="bg-blue-200/50 dark:bg-blue-800/50 px-2 py-1 rounded text-xs font-mono">{window.location.origin}/auth/callback</code></li> <li>Add Redirect URI (SPA): <code className="bg-blue-200/50 dark:bg-blue-800/50 px-2 py-0.5 rounded text-xs font-mono break-all">{window.location.origin}/auth/callback</code></li>
<li>Add API permissions: Files.Read, Files.Read.All</li> <li>Copy <strong>Application (client) ID</strong></li>
<li>Copy Client ID to environment variable</li> <li>Go to Certificates & secrets New client secret</li>
<li>Copy the <strong>secret Value</strong> immediately</li>
<li>Go to API permissions Add: <code className="text-xs">Files.Read.All, Files.ReadWrite.All, User.Read</code></li>
</ol> </ol>
</div> </div>
<div className="p-6 bg-gradient-to-br from-green-50 to-emerald-100 dark:from-green-900/30 dark:to-emerald-800/30 rounded-xl border-2 border-green-200 dark:border-green-700 shadow-lg hover:shadow-xl transition-shadow duration-300"> <div className="p-6 bg-gradient-to-br from-green-50 to-emerald-100 dark:from-green-900/30 dark:to-emerald-800/30 rounded-xl border-2 border-green-200 dark:border-green-700 shadow-lg hover:shadow-xl transition-shadow duration-300">
<h4 className="font-bold text-lg text-green-700 dark:text-green-300 mb-4 flex items-center gap-2"> <h4 className="font-bold text-lg text-green-700 dark:text-green-300 mb-4 flex items-center gap-2">
<Cloud className="w-5 h-5" /> <Cloud className="w-5 h-5" />
Google Drive Step 2: Google Cloud
</h4> </h4>
<ol className="text-sm space-y-2 text-slate-700 dark:text-slate-300 list-decimal list-inside"> <ol className="text-sm space-y-2 text-slate-700 dark:text-slate-300 list-decimal list-inside">
<li>Go to <a href="https://console.cloud.google.com" target="_blank" rel="noopener noreferrer" className="text-green-600 dark:text-green-400 underline hover:text-green-700 dark:hover:text-green-300">Google Cloud Console</a></li> <li>Go to <a href="https://console.cloud.google.com" target="_blank" rel="noopener noreferrer" className="text-green-600 dark:text-green-400 underline hover:text-green-700 dark:hover:text-green-300">Google Cloud Console</a></li>
<li>Create or select a project</li> <li>Create or select a project</li>
<li>Enable Google Drive API</li> <li>Enable <strong>Google Drive API</strong></li>
<li>Create OAuth 2.0 credentials</li> <li>Configure OAuth consent screen (External)</li>
<li className="break-all">Set redirect URI: <code className="bg-green-200/50 dark:bg-green-800/50 px-2 py-1 rounded text-xs font-mono">{window.location.origin}/auth/callback</code></li> <li>Create OAuth 2.0 credentials (Web app)</li>
<li>Copy Client ID to environment variable</li> <li>Add Redirect URI: <code className="bg-green-200/50 dark:bg-green-800/50 px-2 py-0.5 rounded text-xs font-mono break-all">{window.location.origin}/auth/callback</code></li>
<li>Copy <strong>Client ID</strong> and <strong>Client Secret</strong></li>
<li>Add scope: <code className="text-xs">https://www.googleapis.com/auth/drive</code></li>
</ol> </ol>
</div> </div>
</div> </div>
<Alert className="bg-gradient-to-r from-blue-50 to-purple-50 dark:from-slate-800 dark:to-slate-700 border-2 border-blue-200 dark:border-blue-700 shadow-lg">
<div className="flex items-start gap-3"> {/* Environment Files Section */}
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-blue-500/20 flex items-center justify-center"> <div className="grid md:grid-cols-2 gap-6">
<Info className="w-4 h-4 text-blue-600 dark:text-blue-400" /> <Alert className="bg-gradient-to-r from-blue-50 to-purple-50 dark:from-slate-800 dark:to-slate-700 border-2 border-blue-200 dark:border-blue-700 shadow-lg">
<div className="flex items-start gap-3">
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-blue-500/20 flex items-center justify-center">
<Info className="w-4 h-4 text-blue-600 dark:text-blue-400" />
</div>
<div className="flex-1">
<div className="font-semibold text-blue-900 dark:text-blue-100 mb-2">Step 3: Frontend .env</div>
<AlertDescription className="text-sm text-slate-700 dark:text-slate-300 space-y-1">
<p>Create <code className="bg-blue-200/50 dark:bg-blue-800/50 px-2 py-0.5 rounded font-mono text-xs">.env</code> in root:</p>
<div className="space-y-1 mt-2">
<code className="block bg-blue-200/50 dark:bg-blue-800/50 px-3 py-1.5 rounded font-mono text-xs">VITE_MS_CLIENT_ID=your_ms_id</code>
<code className="block bg-blue-200/50 dark:bg-blue-800/50 px-3 py-1.5 rounded font-mono text-xs">VITE_GOOGLE_CLIENT_ID=your_google_id</code>
</div>
</AlertDescription>
</div>
</div> </div>
<div className="flex-1"> </Alert>
<div className="font-semibold text-blue-900 dark:text-blue-100 mb-2">💡 Environment Setup</div> <Alert className="bg-gradient-to-r from-amber-50 to-orange-50 dark:from-slate-800 dark:to-slate-700 border-2 border-amber-200 dark:border-amber-700 shadow-lg">
<AlertDescription className="text-sm text-slate-700 dark:text-slate-300 space-y-1"> <div className="flex items-start gap-3">
<p>Create a <code className="bg-blue-200/50 dark:bg-blue-800/50 px-2 py-0.5 rounded font-mono text-xs">.env</code> file with:</p> <div className="flex-shrink-0 w-8 h-8 rounded-full bg-amber-500/20 flex items-center justify-center">
<div className="space-y-1 mt-2"> <Settings className="w-4 h-4 text-amber-600 dark:text-amber-400" />
<code className="block bg-blue-200/50 dark:bg-blue-800/50 px-3 py-1.5 rounded font-mono text-xs">VITE_MS_CLIENT_ID=your_microsoft_id</code> </div>
<code className="block bg-blue-200/50 dark:bg-blue-800/50 px-3 py-1.5 rounded font-mono text-xs">VITE_GOOGLE_CLIENT_ID=your_google_id</code> <div className="flex-1">
</div> <div className="font-semibold text-amber-900 dark:text-amber-100 mb-2">Step 4: Backend server/.env</div>
</AlertDescription> <AlertDescription className="text-sm text-slate-700 dark:text-slate-300 space-y-1">
<div className="space-y-1">
<code className="block bg-amber-200/50 dark:bg-amber-800/50 px-3 py-1 rounded font-mono text-xs">PORT=9173</code>
<code className="block bg-amber-200/50 dark:bg-amber-800/50 px-3 py-1 rounded font-mono text-xs">VITE_MS_CLIENT_ID=your_ms_id</code>
<code className="block bg-amber-200/50 dark:bg-amber-800/50 px-3 py-1 rounded font-mono text-xs">MS_CLIENT_SECRET=your_ms_secret</code>
<code className="block bg-amber-200/50 dark:bg-amber-800/50 px-3 py-1 rounded font-mono text-xs">VITE_GOOGLE_CLIENT_ID=your_google_id</code>
<code className="block bg-amber-200/50 dark:bg-amber-800/50 px-3 py-1 rounded font-mono text-xs">GOOGLE_CLIENT_SECRET=your_google_secret</code>
<code className="block bg-amber-200/50 dark:bg-amber-800/50 px-3 py-1 rounded font-mono text-xs">REDIRECT_URI={window.location.origin}/auth/callback</code>
</div>
</AlertDescription>
</div>
</div> </div>
</Alert>
</div>
<Alert className="bg-gradient-to-r from-green-50 to-emerald-50 dark:from-green-900/20 dark:to-emerald-900/20 border-2 border-green-300 dark:border-green-700">
<div className="flex items-center gap-3">
<CheckCircle2 className="w-5 h-5 text-green-600 dark:text-green-400" />
<AlertDescription className="text-green-800 dark:text-green-200">
<strong>🔐 Security:</strong> Client Secrets are stored ONLY on the backend server - never exposed to browsers. Your files are safe!
</AlertDescription>
</div> </div>
</Alert> </Alert>
</CardContent> </CardContent>