From 26a77bfb6b5b18d6c0e8b98e1e4c4d938ccb951c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Oct 2025 01:33:00 +0000 Subject: [PATCH 1/3] Initial plan From 352b7ecaf5bd37920365cfdfdd07841c19cea5fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Oct 2025 01:40:33 +0000 Subject: [PATCH 2/3] Fix organization loading error and improve PAT documentation - Handle missing read:org permission gracefully in getUserOrganizations() - Return empty array instead of throwing when org permission is missing - Update error message to guide users on missing permission - Clarify that read:org/Members permission is optional in documentation - Update README, PATSetupInstructions, and PATLogin error messages Co-authored-by: litlfred <662242+litlfred@users.noreply.github.com> --- README.md | 5 ++++- src/components/OrganizationSelection.js | 12 +++++++++++- src/components/PATLogin.js | 2 +- src/components/PATSetupInstructions.css | 18 ++++++++++++++++++ src/components/PATSetupInstructions.js | 6 +++++- src/services/githubService.js | 9 +++++++++ 6 files changed, 48 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c226f5a466..6cd7707394 100644 --- a/README.md +++ b/README.md @@ -180,10 +180,13 @@ For **fine-grained tokens**: - **Contents**: Read and Write (for editing DAK content) - **Metadata**: Read (for repository information) - **Pull requests**: Read and Write (for creating pull requests) +- **Members**: Read-only (optional - only needed if you want to list organizations you're a member of) For **classic tokens**: - **repo**: Full control of private repositories (for editing DAK content) -- **read:org**: Read org and team membership (for listing organization repositories) +- **read:org**: Read org and team membership (optional - only needed if you want to list organizations you're a member of) + +**Note**: The `read:org` scope (classic) or `Members: Read-only` permission (fine-grained) is only needed if you want to see and select organizations you're a member of. You can still use your personal account and the WHO organization without this permission. This authentication method is fully compatible with static deployments and requires no backend server. diff --git a/src/components/OrganizationSelection.js b/src/components/OrganizationSelection.js index 2e3055fb0c..b48016cc77 100644 --- a/src/components/OrganizationSelection.js +++ b/src/components/OrganizationSelection.js @@ -103,7 +103,17 @@ const OrganizationSelection = () => { setOrganizations(orgsData); } catch (error) { console.error('Error fetching organizations:', error); - setError('Failed to fetch organizations. Please check your connection and try again.'); + + // Provide helpful error message based on error type + let errorMessage = 'Failed to fetch organizations. '; + if (error.status === 403 || error.status === 401) { + errorMessage = 'Unable to list your organizations. Your Personal Access Token needs the "read:org" scope (classic tokens) or "Members: Read-only" permission (fine-grained tokens) to list organizations. You can still use your personal account or select WHO.'; + } else { + errorMessage += 'Please check your connection and try again.'; + } + + setError(errorMessage); + // Fallback to mock data for demonstration (which includes WHO) try { const mockOrgs = await getMockOrganizations(); diff --git a/src/components/PATLogin.js b/src/components/PATLogin.js index 1c6f9cabc2..23aadc2e15 100644 --- a/src/components/PATLogin.js +++ b/src/components/PATLogin.js @@ -63,7 +63,7 @@ const PATLogin = ({ onAuthSuccess }) => { if (err.status === 401) { setError("Invalid Personal Access Token. Please check your token and try again."); } else if (err.status === 403) { - setError("Token doesn't have sufficient permissions. Please ensure your token has 'repo' and 'read:org' scopes."); + setError("Token doesn't have sufficient permissions. Please ensure your token has 'repo' scope (classic) or 'Contents: Read and Write' + 'Pull requests: Read and Write' (fine-grained)."); } else { setError("Authentication failed. Please check your connection and try again."); } diff --git a/src/components/PATSetupInstructions.css b/src/components/PATSetupInstructions.css index a62a909b8d..997c2b9c60 100644 --- a/src/components/PATSetupInstructions.css +++ b/src/components/PATSetupInstructions.css @@ -78,6 +78,24 @@ color: #856404; } +.info-note { + background: #e6f3ff; + border: 1px solid #b3d9ff; + border-radius: 4px; + padding: 0.75rem; + margin: 0.5rem 0; + font-size: 0.9rem; + color: #004085; +} + +.info-note code { + background: rgba(0, 64, 133, 0.1); + padding: 0.2em 0.4em; + border-radius: 3px; + font-family: 'Courier New', Courier, monospace; + font-size: 0.85em; +} + .benefits-section, .security-note { background: white; diff --git a/src/components/PATSetupInstructions.js b/src/components/PATSetupInstructions.js index 8261e6e92e..8db128d27a 100644 --- a/src/components/PATSetupInstructions.js +++ b/src/components/PATSetupInstructions.js @@ -32,12 +32,16 @@ const PATSetupInstructions = () => {
For classic tokens, select these scopes:
read:org for classic or Members: Read-only for fine-grained) is only needed if you want to see organizations you're a member of. You can still use your personal account and the WHO organization without it.
+