-
-
Notifications
You must be signed in to change notification settings - Fork 88
Closed
Description
Is your feature request related to a problem? Please describe.
The OAuth2 authorization process typically relies on a redirect_uri pointing to a localhost address (e.g., http://localhost:9000) so that the application can capture the authorization_code.
However, some OAuth providers do not allow localhost redirect URIs.
In this case, it becomes impossible to retrieve the authorization_code and complete the token exchange flow.
Describe the solution you'd like
Add an option allowing the user to choose how the authorization URL is launched:
- either with the system browser (current behavior),
- or by executing an external program, such as a small Node.js script that opens a WebView (e.g., Electron).
An example of an external program that :
- open a webview
- load the authorization URL in a parameter
- intercept the redirect internally, and then performs a 302 redirect to the local server
#!/usr/bin/env electron
import { app, BrowserWindow } from "electron";
const argv = process.argv.slice(2).reduce((acc, arg) => {
const i = arg.indexOf("=");
const key = i == -1 ? arg : arg.slice(0, i);
const value = i == -1 ? true : arg.slice(i + 1);
const cleanKey = key.startsWith("--") ? key.slice(2) : key;
acc[cleanKey] = value;
return acc;
}, {});
async function createWindow() {
const authorizeUrl = argv.authorizeUrl;
const callbackUrl = argv.callbackUrl;
const resetCookies = argv.resetCookies;
const url = new URL(authorizeUrl);
const redirectUrl = url.searchParams.get("redirect_uri");
const mainWindow = new BrowserWindow({
width: 900,
height: 720,
});
if (resetCookies) {
await mainWindow.webContents.session.clearStorageData({
storages: ["cookies"],
});
}
mainWindow.webContents.on("will-redirect", (event, url) => {
if (url.startsWith(redirectUrl)) {
event.preventDefault();
const interceptedUrl = new URL(url);
const newCallbackUrl = new URL(callbackUrl);
interceptedUrl.searchParams.forEach((value, key) => {
newCallbackUrl.searchParams.append(key, value);
});
mainWindow.loadURL(newCallbackUrl.toString());
}
});
mainWindow.loadURL(authorizeUrl);
}
app.whenReady().then(createWindow);
app.on("window-all-closed", () => {
app.quit();
});
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels