mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-18 18:41:52 +08:00
fix(electron): do not use async callback in onBeforeSendHeaders (#7894)
it seems using async callback for onBeforeSendHeaders may crash the app. the main reason why it is async is to read the cookies from session. fix AF-1172
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
|
|
||||||
import type { App, BrowserWindow } from 'electron';
|
import type { App } from 'electron';
|
||||||
import { ipcMain } from 'electron';
|
|
||||||
|
|
||||||
import { buildType, CLOUD_BASE_URL, isDev } from './config';
|
import { buildType, CLOUD_BASE_URL, isDev } from './config';
|
||||||
import { mainWindowOrigin } from './constants';
|
import { mainWindowOrigin } from './constants';
|
||||||
@@ -103,20 +102,8 @@ async function handleOauthJwt(url: string) {
|
|||||||
),
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
let hiddenWindow: BrowserWindow | null = null;
|
|
||||||
|
|
||||||
ipcMain.once('affine:login', () => {
|
|
||||||
hiddenWindow?.destroy();
|
|
||||||
if (urlObj.searchParams.get('next') === 'onboarding') {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
||||||
mainWindow.loadURL(mainWindowOrigin + '/auth/onboarding');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// hacks to refresh auth state in the main window
|
// hacks to refresh auth state in the main window
|
||||||
hiddenWindow = await handleOpenUrlInHiddenWindow(
|
await handleOpenUrlInHiddenWindow(mainWindowOrigin + '/auth/signIn');
|
||||||
mainWindowOrigin + '/auth/signIn'
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error('failed to open url in popup', e);
|
logger.error('failed to open url in popup', e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import { join } from 'node:path';
|
|||||||
import { net, protocol, session } from 'electron';
|
import { net, protocol, session } from 'electron';
|
||||||
|
|
||||||
import { CLOUD_BASE_URL } from './config';
|
import { CLOUD_BASE_URL } from './config';
|
||||||
import { logger } from './logger';
|
import { getCookies } from './windows-manager';
|
||||||
import { getCookie } from './windows-manager';
|
|
||||||
|
|
||||||
protocol.registerSchemesAsPrivileged([
|
protocol.registerSchemesAsPrivileged([
|
||||||
{
|
{
|
||||||
@@ -104,33 +103,23 @@ export function registerProtocol() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
|
session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
|
||||||
(async () => {
|
const url = new URL(details.url);
|
||||||
const url = new URL(details.url);
|
const pathname = url.pathname;
|
||||||
const pathname = url.pathname;
|
// if sending request to the cloud, attach the session cookie
|
||||||
// if sending request to the cloud, attach the session cookie
|
if (isNetworkResource(pathname)) {
|
||||||
if (isNetworkResource(pathname)) {
|
const cookie = getCookies();
|
||||||
const cookie = await getCookie(CLOUD_BASE_URL);
|
if (cookie) {
|
||||||
if (cookie) {
|
const cookieString = cookie.map(c => `${c.name}=${c.value}`).join('; ');
|
||||||
const cookieString = cookie
|
details.requestHeaders['cookie'] = cookieString;
|
||||||
.map(c => `${c.name}=${c.value}`)
|
|
||||||
.join('; ');
|
|
||||||
details.requestHeaders['cookie'] = cookieString;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the referer and origin headers
|
|
||||||
details.requestHeaders['referer'] ??= CLOUD_BASE_URL;
|
|
||||||
details.requestHeaders['origin'] ??= CLOUD_BASE_URL;
|
|
||||||
}
|
}
|
||||||
callback({
|
|
||||||
cancel: false,
|
// add the referer and origin headers
|
||||||
requestHeaders: details.requestHeaders,
|
details.requestHeaders['referer'] ??= CLOUD_BASE_URL;
|
||||||
});
|
details.requestHeaders['origin'] ??= CLOUD_BASE_URL;
|
||||||
})().catch(e => {
|
}
|
||||||
logger.error('failed to attach cookie', e);
|
callback({
|
||||||
callback({
|
cancel: false,
|
||||||
cancel: false,
|
requestHeaders: details.requestHeaders,
|
||||||
requestHeaders: details.requestHeaders,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { join } from 'node:path';
|
|||||||
import {
|
import {
|
||||||
app,
|
app,
|
||||||
type CookiesSetDetails,
|
type CookiesSetDetails,
|
||||||
|
session,
|
||||||
type View,
|
type View,
|
||||||
type WebContents,
|
type WebContents,
|
||||||
WebContentsView,
|
WebContentsView,
|
||||||
@@ -22,7 +23,7 @@ import {
|
|||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
|
||||||
import { isMacOS } from '../../shared/utils';
|
import { isMacOS } from '../../shared/utils';
|
||||||
import { isDev } from '../config';
|
import { CLOUD_BASE_URL, isDev } from '../config';
|
||||||
import { mainWindowOrigin, shellViewUrl } from '../constants';
|
import { mainWindowOrigin, shellViewUrl } from '../constants';
|
||||||
import { ensureHelperProcess } from '../helper-process';
|
import { ensureHelperProcess } from '../helper-process';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
@@ -185,6 +186,8 @@ export class WebContentViewsManager {
|
|||||||
*/
|
*/
|
||||||
readonly tabAction$ = new Subject<TabAction>();
|
readonly tabAction$ = new Subject<TabAction>();
|
||||||
|
|
||||||
|
cookies: Electron.Cookie[] = [];
|
||||||
|
|
||||||
readonly activeWorkbenchId$ = this.tabViewsMeta$.pipe(
|
readonly activeWorkbenchId$ = this.tabViewsMeta$.pipe(
|
||||||
map(m => m?.activeWorkbenchId ?? m?.workbenches[0].id)
|
map(m => m?.activeWorkbenchId ?? m?.workbenches[0].id)
|
||||||
);
|
);
|
||||||
@@ -672,7 +675,6 @@ export class WebContentViewsManager {
|
|||||||
disposables.push(
|
disposables.push(
|
||||||
windowReadyToShow$.subscribe(w => {
|
windowReadyToShow$.subscribe(w => {
|
||||||
handleWebContentsResize().catch(logger.error);
|
handleWebContentsResize().catch(logger.error);
|
||||||
|
|
||||||
const screenSizeChangeEvents = ['resize', 'maximize', 'unmaximize'];
|
const screenSizeChangeEvents = ['resize', 'maximize', 'unmaximize'];
|
||||||
const onResize = () => {
|
const onResize = () => {
|
||||||
if (this.activeWorkbenchView) {
|
if (this.activeWorkbenchView) {
|
||||||
@@ -689,6 +691,23 @@ export class WebContentViewsManager {
|
|||||||
// add shell view
|
// add shell view
|
||||||
this.createAndAddView('shell').catch(logger.error);
|
this.createAndAddView('shell').catch(logger.error);
|
||||||
(async () => {
|
(async () => {
|
||||||
|
const updateCookies = () => {
|
||||||
|
session.defaultSession.cookies
|
||||||
|
.get({
|
||||||
|
url: CLOUD_BASE_URL,
|
||||||
|
})
|
||||||
|
.then(cookies => {
|
||||||
|
this.cookies = cookies;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
logger.error('failed to get cookies', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
updateCookies();
|
||||||
|
session.defaultSession.cookies.on('changed', () => {
|
||||||
|
updateCookies();
|
||||||
|
});
|
||||||
|
|
||||||
if (this.tabViewsMeta.workbenches.length === 0) {
|
if (this.tabViewsMeta.workbenches.length === 0) {
|
||||||
// create a default view (e.g., on first launch)
|
// create a default view (e.g., on first launch)
|
||||||
await this.addTab();
|
await this.addTab();
|
||||||
@@ -705,40 +724,17 @@ export class WebContentViewsManager {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
setCookie = async (cookie: CookiesSetDetails) => {
|
setCookie = async (cookiesSetDetails: CookiesSetDetails) => {
|
||||||
const views = this.allViews;
|
const views = this.allViews;
|
||||||
if (!views) {
|
if (!views) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.info('setting cookie to main window view(s)', cookie);
|
logger.info('setting cookie to main window view(s)', cookiesSetDetails);
|
||||||
for (const view of views) {
|
for (const view of views) {
|
||||||
await view.webContents.session.cookies.set(cookie);
|
await view.webContents.session.cookies.set(cookiesSetDetails);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
removeCookie = async (url: string, name: string) => {
|
|
||||||
const views = this.allViews;
|
|
||||||
if (!views) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
logger.info('removing cookie from main window view(s)', { url, name });
|
|
||||||
for (const view of views) {
|
|
||||||
await view.webContents.session.cookies.remove(url, name);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
getCookie = (url?: string, name?: string) => {
|
|
||||||
// all webviews share the same session
|
|
||||||
const view = this.allViews?.at(0);
|
|
||||||
if (!view) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return view.webContents.session.cookies.get({
|
|
||||||
url,
|
|
||||||
name,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
getViewById = (id: string) => {
|
getViewById = (id: string) => {
|
||||||
if (id === 'shell') {
|
if (id === 'shell') {
|
||||||
return this.shellView;
|
return this.shellView;
|
||||||
@@ -865,12 +861,8 @@ export async function setCookie(
|
|||||||
return WebContentViewsManager.instance.setCookie(details);
|
return WebContentViewsManager.instance.setCookie(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function removeCookie(url: string, name: string): Promise<void> {
|
export function getCookies() {
|
||||||
return WebContentViewsManager.instance.removeCookie(url, name);
|
return WebContentViewsManager.instance.cookies;
|
||||||
}
|
|
||||||
|
|
||||||
export async function getCookie(url?: string, name?: string) {
|
|
||||||
return WebContentViewsManager.instance.getCookie(url, name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is no proper way to listen to webContents resize event
|
// there is no proper way to listen to webContents resize event
|
||||||
|
|||||||
Reference in New Issue
Block a user