mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-10-09 15:58:34 +00:00
e28a591554
Enables GitHub Device Flow authentication through the main process to bypass CORS issues by introducing IPC bridge handlers and updating the adapter to use them when available. Improves error handling and logging for easier debugging. Wraps settings in a toast provider to support user notifications.
86 lines
2.4 KiB
JavaScript
86 lines
2.4 KiB
JavaScript
/**
|
|
* GitHub OAuth Bridge (main process)
|
|
*
|
|
* Renderer fetches to `github.com/login/*` are blocked by CORS.
|
|
* This bridge proxies GitHub Device Flow endpoints via the main process.
|
|
*/
|
|
|
|
const GITHUB_CLIENT_ID = "Ov23liuLdkw1H393rtT4";
|
|
const GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
|
|
const GITHUB_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
|
|
|
|
/**
|
|
* @param {Electron.IpcMain} ipcMain
|
|
*/
|
|
function registerHandlers(ipcMain) {
|
|
ipcMain.handle("netcatty:github:deviceFlow:start", async (_event, payload) => {
|
|
const clientId = payload?.clientId || GITHUB_CLIENT_ID;
|
|
const scope = payload?.scope || "gist read:user";
|
|
|
|
const res = await fetch(GITHUB_DEVICE_CODE_URL, {
|
|
method: "POST",
|
|
headers: {
|
|
Accept: "application/json",
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
},
|
|
body: new URLSearchParams({
|
|
client_id: clientId,
|
|
scope,
|
|
}).toString(),
|
|
});
|
|
|
|
const text = await res.text();
|
|
if (!res.ok) {
|
|
throw new Error(`GitHub device flow failed: ${res.status} - ${text}`);
|
|
}
|
|
|
|
let data;
|
|
try {
|
|
data = JSON.parse(text);
|
|
} catch {
|
|
throw new Error(`GitHub device flow invalid JSON: ${text.slice(0, 200)}`);
|
|
}
|
|
|
|
return {
|
|
deviceCode: data.device_code,
|
|
userCode: data.user_code,
|
|
verificationUri: data.verification_uri,
|
|
expiresAt: Date.now() + (data.expires_in || 0) * 1000,
|
|
interval: data.interval || 5,
|
|
};
|
|
});
|
|
|
|
ipcMain.handle("netcatty:github:deviceFlow:poll", async (_event, payload) => {
|
|
const clientId = payload?.clientId || GITHUB_CLIENT_ID;
|
|
const deviceCode = payload?.deviceCode;
|
|
if (!deviceCode) throw new Error("Missing deviceCode");
|
|
|
|
const res = await fetch(GITHUB_ACCESS_TOKEN_URL, {
|
|
method: "POST",
|
|
headers: {
|
|
Accept: "application/json",
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
},
|
|
body: new URLSearchParams({
|
|
client_id: clientId,
|
|
device_code: deviceCode,
|
|
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
}).toString(),
|
|
});
|
|
|
|
const text = await res.text();
|
|
if (!res.ok) {
|
|
throw new Error(`GitHub token polling failed: ${res.status} - ${text}`);
|
|
}
|
|
|
|
try {
|
|
return JSON.parse(text);
|
|
} catch {
|
|
throw new Error(`GitHub token polling invalid JSON: ${text.slice(0, 200)}`);
|
|
}
|
|
});
|
|
}
|
|
|
|
module.exports = { registerHandlers };
|
|
|