mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-11-22 08:32:43 +03:00
fix: failed to load blobs in electron (#1927)
This commit is contained in:
parent
934e242116
commit
42756045bb
@ -1,16 +1,10 @@
|
||||
import type { RequestInit } from 'undici';
|
||||
import { fetch, ProxyAgent } from 'undici';
|
||||
|
||||
const redirectUri = 'https://affine.pro/client/auth-callback';
|
||||
|
||||
export const oauthEndpoint = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${process.env.AFFINE_GOOGLE_CLIENT_ID}&redirect_uri=${redirectUri}&response_type=code&scope=openid https://www.googleapis.com/auth/userinfo.email profile&access_type=offline&customParameters={"prompt":"select_account"}`;
|
||||
|
||||
const tokenEndpoint = 'https://oauth2.googleapis.com/token';
|
||||
|
||||
export const exchangeToken = async (code: string) => {
|
||||
const httpProxy = process.env.HTTP_PROXY || process.env.http_proxy;
|
||||
const proxyAgent = httpProxy ? new ProxyAgent(httpProxy) : undefined;
|
||||
|
||||
export const getExchangeTokenParams = (code: string) => {
|
||||
const postData = {
|
||||
code,
|
||||
client_id: process.env.AFFINE_GOOGLE_CLIENT_ID || '',
|
||||
@ -18,15 +12,12 @@ export const exchangeToken = async (code: string) => {
|
||||
redirect_uri: redirectUri,
|
||||
grant_type: 'authorization_code',
|
||||
};
|
||||
const requestOptions: RequestInit = {
|
||||
const requestInit: RequestInit = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams(postData).toString(),
|
||||
dispatcher: proxyAgent,
|
||||
};
|
||||
return fetch(tokenEndpoint, requestOptions).then(response => {
|
||||
return response.json();
|
||||
});
|
||||
return { requestInit, url: tokenEndpoint };
|
||||
};
|
||||
|
@ -7,7 +7,7 @@ import { BrowserWindow, ipcMain, nativeTheme } from 'electron';
|
||||
import fs from 'fs-extra';
|
||||
import { parse } from 'url';
|
||||
|
||||
import { exchangeToken, oauthEndpoint } from './google-auth';
|
||||
import { getExchangeTokenParams, oauthEndpoint } from './google-auth';
|
||||
|
||||
const AFFINE_ROOT = path.join(os.homedir(), '.affine');
|
||||
|
||||
@ -40,29 +40,24 @@ export const registerHandlers = () => {
|
||||
logger.info('sidebar visibility change', visible);
|
||||
});
|
||||
|
||||
ipcMain.handle('ui:google-sign-in', async () => {
|
||||
ipcMain.handle('ui:get-google-oauth-code', async () => {
|
||||
logger.info('starting google sign in ...');
|
||||
shell.openExternal(oauthEndpoint);
|
||||
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const handleOpenUrl = async (_: any, url: string) => {
|
||||
const mainWindow = BrowserWindow.getAllWindows().find(
|
||||
w => !w.isDestroyed()
|
||||
);
|
||||
const urlObj = parse(url.replace('??', '?'), true);
|
||||
if (!mainWindow || !url.startsWith('affine://')) return;
|
||||
if (!mainWindow || !url.startsWith('affine://auth-callback')) return;
|
||||
const code = urlObj.query['code'] as string;
|
||||
if (!code) return;
|
||||
|
||||
logger.info('google sign in code received from callback', code);
|
||||
|
||||
const token = (await exchangeToken(code)) as {
|
||||
id_token: string;
|
||||
};
|
||||
|
||||
app.removeListener('open-url', handleOpenUrl);
|
||||
resolve(token.id_token);
|
||||
logger.info('google sign in successful', token);
|
||||
resolve(getExchangeTokenParams(code));
|
||||
};
|
||||
|
||||
app.on('open-url', handleOpenUrl);
|
||||
@ -70,7 +65,7 @@ export const registerHandlers = () => {
|
||||
setTimeout(() => {
|
||||
reject(new Error('Timed out'));
|
||||
app.removeListener('open-url', handleOpenUrl);
|
||||
}, 60000);
|
||||
}, 30000);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -36,6 +36,7 @@ export function registerProtocol() {
|
||||
const realpath = toAbsolutePath(url);
|
||||
// console.log('realpath', realpath, 'for', url);
|
||||
callback(realpath);
|
||||
return true;
|
||||
});
|
||||
|
||||
protocol.registerFileProtocol('assets', (request, callback) => {
|
||||
@ -43,6 +44,7 @@ export function registerProtocol() {
|
||||
const realpath = toAbsolutePath(url);
|
||||
// console.log('realpath', realpath, 'for', url);
|
||||
callback(realpath);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@ -60,7 +62,6 @@ export function registerProtocol() {
|
||||
'DELETE',
|
||||
'OPTIONS',
|
||||
];
|
||||
// responseHeaders['Content-Security-Policy'] = ["default-src 'self'"];
|
||||
}
|
||||
|
||||
callback({ responseHeaders });
|
||||
|
2
apps/electron/layers/preload/preload.d.ts
vendored
2
apps/electron/layers/preload/preload.d.ts
vendored
@ -7,6 +7,6 @@ interface Window {
|
||||
*
|
||||
* @see https://github.com/cawa-93/dts-for-context-bridge
|
||||
*/
|
||||
readonly apis: { workspaceSync: (id: string) => Promise<any>; onThemeChange: (theme: string) => Promise<any>; onSidebarVisibilityChange: (visible: boolean) => Promise<any>; googleSignIn: () => Promise<string>; updateEnv: (env: string, value: string) => void; };
|
||||
readonly apis: { workspaceSync: (id: string) => Promise<any>; onThemeChange: (theme: string) => Promise<any>; onSidebarVisibilityChange: (visible: boolean) => Promise<any>; getGoogleOauthCode: () => Promise<{ requestInit: RequestInit; url: string; }>; updateEnv: (env: string, value: string) => void; };
|
||||
readonly appInfo: { electron: boolean; isMacOS: boolean; };
|
||||
}
|
||||
|
@ -31,9 +31,11 @@ contextBridge.exposeInMainWorld('apis', {
|
||||
ipcRenderer.invoke('ui:sidebar-visibility-change', visible),
|
||||
|
||||
/**
|
||||
* Try sign in using Google and return a Google IDToken
|
||||
* Try sign in using Google and return a request object to exchange the code for a token
|
||||
* Not exchange in Node side because it is easier to do it in the renderer with VPN
|
||||
*/
|
||||
googleSignIn: (): Promise<string> => ipcRenderer.invoke('ui:google-sign-in'),
|
||||
getGoogleOauthCode: (): Promise<{ requestInit: RequestInit; url: string }> =>
|
||||
ipcRenderer.invoke('ui:get-google-oauth-code'),
|
||||
|
||||
/**
|
||||
* Secret backdoor to update environment variables in main process
|
||||
|
@ -52,7 +52,10 @@ const getPersistenceAllWorkspace = () => {
|
||||
item.id,
|
||||
(k: string) =>
|
||||
// fixme: token could be expired
|
||||
({ api: '/api/workspace', token: getLoginStorage()?.token }[k])
|
||||
({
|
||||
api: prefixUrl + 'api/workspace',
|
||||
token: getLoginStorage()?.token,
|
||||
}[k])
|
||||
);
|
||||
const affineWorkspace: AffineWorkspace = {
|
||||
...item,
|
||||
|
@ -67,10 +67,13 @@ export const setLoginStorage = (login: LoginResponse) => {
|
||||
};
|
||||
|
||||
const signInWithElectron = async (firebaseAuth: FirebaseAuth) => {
|
||||
const code = await window.apis?.googleSignIn();
|
||||
const credential = GoogleAuthProvider.credential(code);
|
||||
if (window.apis) {
|
||||
const { url, requestInit } = await window.apis.getGoogleOauthCode();
|
||||
const { id_token } = await fetch(url, requestInit).then(res => res.json());
|
||||
const credential = GoogleAuthProvider.credential(id_token);
|
||||
const user = await signInWithCredential(firebaseAuth, credential);
|
||||
return await user.user.getIdToken();
|
||||
}
|
||||
};
|
||||
|
||||
export const clearLoginStorage = () => {
|
||||
|
Loading…
Reference in New Issue
Block a user