Skip to content

Conversation

Copy link

Copilot AI commented May 28, 2025

Thanks for assigning this issue to me. I'm starting to work on it and will keep this PR's description up to date as I form a plan and make progress.

Original issue description:

https://docs.github.com/en/apps/creating-github-apps/writing-code-for-a-github-app/building-a-login-with-github-button-with-a-github-app

To implement GitHub login in a Chrome extension, follow these steps using OAuth 2.0 and Chrome's Identity API. This approach avoids embedding secrets in your extension by leveraging the Implicit Grant flow.

1. Set Up a GitHub OAuth App

  • Go to GitHub Developer Settings → "OAuth Apps" → "New OAuth App".
  • Application Name: Your extension's name.
  • Homepage URL: https://<your-extension-id>.chromiumapp.org (use chrome.identity.getRedirectURL() later).
  • Authorization callback URL:
    https://<your-extension-id>.chromiumapp.org/provider_cb
    (Replace <your-extension-id> with your actual ID from chrome://extensions).
  • Note the Client ID (you’ll need this later).

2. Update Manifest.json

Add these permissions and configurations:

{
  "manifest_version": 3,
  "permissions": ["identity"],
  "host_permissions": ["https://github.com/*", "https://api.github.com/*"],
  "background": {
    "service_worker": "background.js"
  }
}

3. Implement Authentication Flow

Create background.js to handle OAuth:

// GitHub OAuth Config
const CLIENT_ID = 'YOUR_GITHUB_CLIENT_ID';
const AUTH_URL = `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}`;
const TOKEN_VALIDATION_URL = 'https://api.github.com/user';

// Launch GitHub OAuth flow
function authenticate() {
  const authParams = {
    url: `${AUTH_URL}&redirect_uri=${encodeURIComponent(chrome.identity.getRedirectURL())}`,
    interactive: true
  };

  chrome.identity.launchWebAuthFlow(authParams, (redirectUrl) => {
    if (chrome.runtime.lastError || !redirectUrl) {
      console.error('Auth failed: ', chrome.runtime.lastError);
      return;
    }

    // Extract access_token from URL fragment
    const url = new URL(redirectUrl);
    const params = new URLSearchParams(url.hash.slice(1));
    const accessToken = params.get('access_token');

    if (accessToken) {
      validateToken(accessToken); // Validate & store token
    }
  });
}

// Validate token with GitHub API
function validateToken(token) {
  fetch(TOKEN_VALIDATION_URL, {
    headers: { 'Authorization': `token ${token}` }
  })
  .then(response => response.json())
  .then(data => {
    if (data.login) {
      chrome.storage.local.set({ githubToken: token, user: data.login });
      console.log('Logged in as:', data.login);
    }
  })
  .catch(error => console.error('Token validation failed:', error));
}

// Trigger authentication (e.g., from popup UI)
chrome.runtime.onMessage.addListener((request) => {
  if (request.action === 'login') authenticate();
});

4. Create Popup UI (popup.html)

<!DOCTYPE html>
<button id="login">Login with GitHub</button>
<script src="popup.js"></script>

5. Popup Logic (popup.js)

document.getElementById('login').addEventListener('click', () => {
  chrome.runtime.sendMessage({ action: 'login' });
});

// Check login status on load
chrome.storage.local.get(['user'], (result) => {
  if (result.user) {
    alert(`Logged in as: ${result.user}`);
  }
});

6. Key Security Notes

  • Never use Client Secret: Browser extensions are public, so the Implicit flow is used without a secret.
  • Token Storage: Tokens are stored in chrome.storage.local (encrypted at rest).
  • State Parameter: Add a state parameter to prevent CSRF (omitted here for brevity; generate a nonce).

7. Testing

  1. Load your extension in Chrome via chrome://extensions (Developer mode → "Load unpacked").
  2. Click the extension icon and use the login button.

Troubleshooting:

  • Redirect URI Mismatch: Ensure the callback URL in GitHub matches chrome.identity.getRedirectURL() (check console for the actual URL).
  • Scope: Add &scope=user to AUTH_URL if you need user data.
  • CORS: GitHub API supports browser requests, so no issues.

Final Flow:

  1. User clicks login in the popup.
  2. Chrome opens a GitHub auth window.
  3. GitHub redirects to chromiumapp.org with access_token in the URL fragment.
  4. Extension validates the token with GitHub API.
  5. User info is stored in chrome.storage.

This method securely handles GitHub OAuth without a backend server. For production, add error handling and token refresh logic (GitHub tokens expire after 8 hours by default—prompt users to re-authenticate when needed).

Fixes #62.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@loganbek
Copy link
Owner

loganbek commented Jul 3, 2025

@copilot give this another shot.

Co-authored-by: loganbek <9355004+loganbek@users.noreply.github.com>
Copy link
Author

Copilot AI commented Jul 3, 2025

@copilot give this another shot.

I've implemented the GitHub OAuth login functionality as requested. The implementation includes:

  • GitHub OAuth 2.0 authentication flow using Chrome's Identity API
  • Login/logout UI in the popup with persistent status
  • GitHub Client ID configuration in the extension options
  • Token validation and secure storage
  • Proper error handling and user feedback

Key features added:

  • Updated manifest.json with identity and GitHub permissions
  • Added OAuth flow to background.js
  • Enhanced popup with GitHub login section
  • Added Client ID configuration to options page

To test: Configure your GitHub OAuth App Client ID in the extension options, then use the "Login with GitHub" button in the popup.

Commit: 23d9e59

Copilot AI requested a review from loganbek July 3, 2025 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Github Login Capability.

2 participants