Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth Popups not opening for sites like claude.ai #3

Open
praveentrigent opened this issue Nov 14, 2024 · 2 comments
Open

OAuth Popups not opening for sites like claude.ai #3

praveentrigent opened this issue Nov 14, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@praveentrigent
Copy link

@mrivasperez Thanks for building this amazing lightweight browser. I am using this for a different use case of building a super app for AI users. AI users can visit only AI platforms like chatgpt, claude, gemini, mistral, etc because we are navigating them to those platforms using a dropdown in the navigation of our app. I am able to open the apps but many CSP issues are acting as blockers.

For instance:

When opening claude.ai and websites that opens a popup when clicked on login with Google, etc. I see Blocked by browser? error. Along with these:

[Report Only] Refused to frame 'https://www.google.com/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors 'self'".
[GSI_LOGGER]: Failed to open popup window on url: https://accounts.google.com/o/oauth2/v2/auth?gsiwebsdk=3&client_id=1062961139910-l2m55cb9h51u5cuc9c56eb3fevouidh9.apps.googleusercontent.com&scope=openid%20profile%20email&redirect_uri=storagerelay%3A%2F%2Fhttps%2Fclaude.ai%3Fid%3Dauth46631&prompt=consent&access_type=offline&response_type=code&include_g
r

It might require CSP etc configuration in the browser, but how and where does these go in the codebase?
Main process yes!

But I want to make sure all the sites oauth popups to be shown in this browser.

I have tried to add:

const handleNewWindow = (event) => {
        console.log(`Attempting to open new window: ${event.url}`);
        // Option 1: Open in external browser
        // shell.openExternal(event.url);
        // Option 2: Open in a new BrowserWindow within Electron
        
        let newWindow = new BrowserWindow({
          width: 800,
          height: 600,
          webPreferences: {
            preload: `file://${preloadPath}`,
            nodeIntegration: false,
            contextIsolation: true,
            allowpopups // **Allow popups**
          },
        });
        newWindow.loadURL(event.url);
      };

in the webviewcomponent but it didn't work.

I tried to set custom agent header in the ipc handler:

mainWindow.webContents.session.webRequest.onBeforeSendHeaders((details, callback) => {
      details.requestHeaders['User-Agent'] = 
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36';

and tried to manipulate during onHeadersRecieved()

session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
      const responseHeaders = Object.assign({}, details.responseHeaders);

      // Set CSP to the one defined for the service
    /* if (csp) {
      responseHeaders['Content-Security-Policy'] = [csp];
    }
     */
       // Modify CSP to allow necessary domains
      responseHeaders['Content-Security-Policy'] = [
        responseHeaders['content-security-policy'] || responseHeaders['Content-Security-Policy']
          ? responseHeaders['content-security-policy'][0]
            .replace("img-src 'self'", "img-src * data: https://lh3.googleusercontent.com https://www.gstatic.com https://www.google.com")
            .replace("font-src 'self'", "font-src * data: https://ssl.gstatic.com https://fonts.gstatic.com")
            .replace("script-src 'self'", "script-src * 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://www.gstatic.com https://apis.google.com https://www.google.com https://ssl.gstatic.com")
          : "default-src * 'unsafe-inline' 'unsafe-eval' 'self' https://gemini.google.com https://ssl.gstatic.com https://www.google.com https://apis.google.com"
      ];
    
      // Add necessary CORS headers dynamically
      if (!responseHeaders['Access-Control-Allow-Origin']) {
        responseHeaders['Access-Control-Allow-Origin'] = ['*'];
        responseHeaders['Access-Control-Allow-Methods'] = ['GET, POST, PUT, DELETE, OPTIONS'];
        responseHeaders['Access-Control-Allow-Headers'] = ['Origin, X-Requested-With, Content-Type, Accept'];
      }
    
      // callback({ responseHeaders });
      callback({
        responseHeaders: {
          ...details.responseHeaders,
          'Content-Security-Policy': [csp], // Retain specific CSP for each service if provided
          'X-Frame-Options': ['ALLOWALL'], // Ensure services can be embedded
        },
      });
    });
  });

How do I acheive this where user can login to any website and use the sites as in a normal browser?

@mrivasperez mrivasperez added the enhancement New feature or request label Nov 15, 2024
@mrivasperez
Copy link
Owner

Hey @praveentrigent, thank you for your kind words! I am glad you have found this project helpful in developing your own application.

Unfortunately, Google and other authentication providers do not allow for this. (See "Guidance to developers affected by our effort to block less secure browsers and applications." by Google).

There's likely a way to maneuver around this, but it's unlikely to be something Google recommends. I don't have the bandwidth to resolve this issue, but you are welcome to contribute.

If you have a repo, I'd be happy to share some of my time to review your work.

@praveentrigent
Copy link
Author

praveentrigent commented Jan 25, 2025

@mrivasperez Appreciate your response!

I have created an MVP level superapp or controlled browser for the use case of visiting LLM platforms to be used. I have added a centralized CSP and users can only visit websites from the navigation dropdown which is a replacement for the address bar and bookmarks tab. I have implemented a Tabbed Interface and added some amount of custom logic.

And you are right about workarounds that are insecure in practice. So, I am thinking of using a reverse proxy to handle requests on the users' or electron's behalf. After that, I can be ready to contribute on this.

But before adding reverse proxy, I would like to share with you and discuss how does it look so far implementation-wise. Let me know your preferred way of communication & collaboration of contribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants