fix: loading old url with ip address cause not loading

This commit is contained in:
lin onetwo 2023-06-19 22:59:33 +08:00
parent 8b694460f5
commit 018057f92f
7 changed files with 42 additions and 40 deletions

View file

@ -8,3 +8,5 @@ export const githubDesktopUrl = 'https://desktop.github.com/';
* This is currently unused, because it always entering /#safe:safe , very annoying. And even entered, the url can still not containing this. So I decided not support enter/quit safe mode now.
*/
export const safeModeHash = '#:safe';
export const getDefaultHTTPServerIP = (port: number) => `http://${defaultServerIP}:${port}`;
export const getDefaultTidGiUrl = (workspaceID: string) => `tidgi://${workspaceID}`;

View file

@ -20,7 +20,6 @@ import { List, ListItem, ListItemText } from '@/components/ListItem';
import { useRestartSnackbar } from '@/components/RestartSnackbar';
import { TokenForm } from '@/components/TokenForm';
import { wikiPictureExtensions } from '@/constants/fileNames';
import { useActualIp } from '@services/native/hooks';
import { SupportedStorageServices } from '@services/types';
import { isEqual } from 'lodash';
import { SyncedWikiDescription } from '../AddWorkspace/Description';
@ -173,7 +172,6 @@ export default function EditWorkspace(): JSX.Element {
const fallbackUserName = usePromiseValue<string>(async () => (await window.service.auth.get('userName')) as string, '');
const rememberLastPageVisited = usePromiseValue(async () => await window.service.preference.get('rememberLastPageVisited'));
const actualIP = useActualIp(homeUrl, workspaceID);
if (workspaceID === undefined) {
return <Root>Error {workspaceID ?? '-'} not exists</Root>;
}
@ -230,17 +228,17 @@ export default function EditWorkspace(): JSX.Element {
id='outlined-full-width'
label={t('EditWorkspace.LastVisitState')}
helperText={t('Preference.RememberLastVisitState')}
placeholder={actualIP}
placeholder={homeUrl}
value={lastUrl}
onChange={(event) => {
workspaceSetter({
...workspace,
lastUrl: (event.target.value || actualIP) ?? '',
lastUrl: (event.target.value || homeUrl) ?? '',
});
}}
/>
)}
<ServerOptions actualIP={actualIP} workspace={workspace} workspaceSetter={workspaceSetter} />
<ServerOptions workspace={workspace} workspaceSetter={workspaceSetter} />
</>
)}
{isSubWiki && (

View file

@ -23,8 +23,9 @@ import { DEFAULT_USER_NAME, getTidGiAuthHeaderWithToken } from '@/constants/auth
import { WikiChannel } from '@/constants/channels';
import { rootTiddlers } from '@/constants/defaultTiddlerNames';
import { tlsCertExtensions, tlsKeyExtensions } from '@/constants/fileNames';
import { defaultServerIP } from '@/constants/urls';
import { defaultServerIP, getDefaultHTTPServerIP } from '@/constants/urls';
import { usePromiseValue } from '@/helpers/useServiceValue';
import { useActualIp } from '@services/native/hooks';
import { IWorkspace } from '@services/workspaces/interface';
const AServerOptionsAccordion = styled(Accordion)`
@ -48,13 +49,12 @@ const AuthTokenTextAndButtonContainer = styled.div`
`;
export interface IServerOptionsProps {
actualIP: string | undefined;
workspace: IWorkspace;
workspaceSetter: (newValue: IWorkspace, requestSaveAndRestart?: boolean | undefined) => void;
}
export function ServerOptions(props: IServerOptionsProps) {
const { t } = useTranslation();
const { workspace, actualIP, workspaceSetter } = props;
const { workspace, workspaceSetter } = props;
const {
https = { enabled: false },
port,
@ -67,6 +67,7 @@ export function ServerOptions(props: IServerOptionsProps) {
userName,
id,
} = (workspace ?? {}) as unknown as IWorkspace;
const actualIP = useActualIp(getDefaultHTTPServerIP(port), id);
// some feature need a username to work, so if userName is empty, assign a fallbackUserName DEFAULT_USER_NAME
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const fallbackUserName = usePromiseValue<string>(async () => (await window.service.auth.get('userName')) as string, '');

View file

@ -12,6 +12,7 @@ import type { IWorkspaceService } from '@services/workspaces/interface';
import type { IWorkspaceViewService } from '@services/workspacesView/interface';
import { MetaDataChannel, ViewChannel, WindowChannel } from '@/constants/channels';
import { getDefaultTidGiUrl } from '@/constants/urls';
import { isMac, isWin } from '@/helpers/system';
import { IAuthenticationService } from '@services/auth/interface';
import { lazyInject } from '@services/container';
@ -319,26 +320,21 @@ export class View implements IViewService {
workspace,
sharedWebPreferences,
loadInitialUrlWithCatch: async () => {
// await this.loadUrlForView(workspace, view, windowName);
await this.loadUrlForView(workspace, view, windowName);
},
});
await setupIpcServerRoutesHandlers(view, workspace.id);
// await this.loadUrlForView(workspace, view, windowName);
setupIpcServerRoutesHandlers(view, workspace.id);
await this.loadUrlForView(workspace, view, windowName);
}
public async loadUrlForView(workspace: IWorkspace, view: BrowserView, windowName: WindowNames): Promise<void> {
const { rememberLastPageVisited } = await this.preferenceService.getPreferences();
// fix some case that local ip can't be load
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const urlToReplace = rememberLastPageVisited ? workspace.lastUrl ?? workspace.homeUrl : workspace.homeUrl;
const replacedUrl = await this.nativeService.getLocalHostUrlWithActualInfo(urlToReplace, workspace.id);
logger.debug(`Load initialUrl: ${replacedUrl} for windowName ${windowName} for workspace ${workspace.name}`, {
urlToReplace,
replacedUrl,
});
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing, @typescript-eslint/strict-boolean-expressions
const urlToLoad = (rememberLastPageVisited ? workspace.lastUrl ?? workspace.homeUrl : workspace.homeUrl) || getDefaultTidGiUrl(workspace.id);
try {
logger.debug(
`loadInitialUrlWithCatch(): view.webContents: ${String(view.webContents)} ${replacedUrl} for windowName ${windowName} for workspace ${workspace.name}`,
`loadUrlForView(): view.webContents: ${String(view.webContents)} urlToLoad: ${urlToLoad} for windowName ${windowName} for workspace ${workspace.name}`,
{ stack: new Error('stack').stack?.replace('Error:', '') },
);
if (await this.workspaceService.workspaceDidFailLoad(workspace.id)) {
@ -350,14 +346,16 @@ export class View implements IViewService {
didFailLoadErrorMessage: null,
isLoading: true,
});
await view.webContents.loadURL(replacedUrl);
logger.debug('loadInitialUrlWithCatch() await loadURL() done');
// DEBUG devTool
// view.webContents.openDevTools({ mode: 'detach' });
await view.webContents.loadURL(urlToLoad);
logger.debug('loadUrlForView() await loadURL() done');
const unregisterContextMenu = await this.menuService.initContextMenuForWindowWebContents(view.webContents);
view.webContents.on('destroyed', () => {
unregisterContextMenu();
});
} catch (error) {
logger.warn(new ViewLoadUrlError(replacedUrl, `${(error as Error).message} ${(error as Error).stack ?? ''}`));
logger.warn(new ViewLoadUrlError(urlToLoad, `${(error as Error).message} ${(error as Error).stack ?? ''}`));
}
}

View file

@ -8,15 +8,14 @@ import { IWikiService } from '@services/wiki/interface';
import { IWorkspaceService } from '@services/workspaces/interface';
import type { ITiddlerFields } from 'tiddlywiki';
export async function setupIpcServerRoutesHandlers(view: BrowserView, workspaceID: string) {
const urlBase = `tidgi://${workspaceID}`;
export function setupIpcServerRoutesHandlers(view: BrowserView, workspaceID: string) {
const workspaceService = container.get<IWorkspaceService>(serviceIdentifier.Workspace);
const authService = container.get<IAuthenticationService>(serviceIdentifier.Authentication);
const wikiService = container.get<IWikiService>(serviceIdentifier.Wiki);
const methods = [
{
method: 'GET',
path: /^\/$/,
path: /^\/?$/,
name: 'getIndex',
handler: async (_request: GlobalRequest, _parameters: RegExpMatchArray | null) =>
await wikiService.callWikiIpcServerRoute(workspaceID, 'getIndex', (await workspaceService.get(workspaceID))?.rootTiddler ?? '$:/core/save/lazy-images'),
@ -83,16 +82,20 @@ export async function setupIpcServerRoutesHandlers(view: BrowserView, workspaceI
async function handlerCallback(request: GlobalRequest): Promise<GlobalResponse> {
const parsedUrl = new URL(request.url);
// Iterate through methods to find matching routes
// DEBUG: console parsedUrl
console.log(`parsedUrl`, parsedUrl);
try {
for (const route of methods) {
// DEBUG: console parsedUrl.pathname
console.log(`parsedUrl.pathname`, parsedUrl.pathname, request.method === route.method, route.name, route.path.test(parsedUrl.pathname));
if (request.method === route.method && route.path.test(parsedUrl.pathname)) {
// Get the parameters in the URL path
const parameters = parsedUrl.pathname.match(route.path);
logger.debug(`loadHTMLStringForView: ${route.name}`, { parsedUrl, parameters });
logger.debug(`setupIpcServerRoutesHandlers.handlerCallback: ${route.name}`, { parsedUrl, parameters });
// Call the handler of the route to process the request and return the result
const responseData = await route.handler(request, parameters);
if (responseData === undefined) {
const statusText = `loadHTMLStringForView: responseData is undefined ${request.url}`;
const statusText = `setupIpcServerRoutesHandlers.handlerCallback: responseData is undefined ${request.url}`;
logger.warn(statusText);
return new Response(undefined, { status: 404, statusText });
}
@ -102,7 +105,7 @@ export async function setupIpcServerRoutesHandlers(view: BrowserView, workspaceI
} catch (error) {
return new Response(undefined, { status: 500, statusText: `${(error as Error).message} ${(error as Error).stack ?? ''}` });
}
const statusText = `loadHTMLStringForView: tidgi protocol is not handled ${request.url}`;
const statusText = `setupIpcServerRoutesHandlers.handlerCallback: tidgi protocol is not handled ${request.url}`;
logger.warn(statusText);
return new Response(undefined, { status: 404, statusText });
}
@ -111,13 +114,9 @@ export async function setupIpcServerRoutesHandlers(view: BrowserView, workspaceI
view.webContents.session.protocol.handle(`tidgi`, handlerCallback);
const handled = view.webContents.session.protocol.isProtocolHandled(`tidgi`);
if (!handled) {
logger.warn(`loadHTMLStringForView: tidgi protocol is not handled`);
logger.warn(`setupIpcServerRoutesHandlers.handlerCallback: tidgi protocol is not handled`);
}
logger.info(`view.webContents.loadURL(${urlBase}/)`);
// DEBUG devTool
// view.webContents.openDevTools({ mode: 'detach' });
await view.webContents.loadURL(`${urlBase}/`);
} catch (error) {
logger.error(`loadHTMLStringForView: ${(error as Error).message}`);
logger.error(`setupIpcServerRoutesHandlers.handlerCallback: ${(error as Error).message}`);
}
}

View file

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
import { getDefaultHTTPServerIP } from '@/constants/urls';
import type { WindowMeta, WindowNames } from '@services/windows/WindowProperties';
function getInfoTiddlerFields(updateInfoTiddlersCallback: (infos: Array<{ text: string; title: string }>) => void) {
@ -20,7 +21,7 @@ function getInfoTiddlerFields(updateInfoTiddlersCallback: (infos: Array<{ text:
const setLocationProperty = function(name: string, value: string) {
asyncInfoTiddlerFields.push({ title: '$:/info/url/' + name, text: value });
};
const localHostUrl = await window.service.native.getLocalHostUrlWithActualInfo(workspace.homeUrl, workspaceID);
const localHostUrl = await window.service.native.getLocalHostUrlWithActualInfo(getDefaultHTTPServerIP(workspace.port), workspaceID);
const urlObject = new URL(localHostUrl);
setLocationProperty('full', (localHostUrl).split('#')[0]);
setLocationProperty('host', urlObject.host);

View file

@ -13,8 +13,9 @@ import path from 'path';
import { BehaviorSubject, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { defaultServerIP } from '@/constants/urls';
import { getDefaultTidGiUrl } from '@/constants/urls';
import { fixSettingFileWhenError } from '@/helpers/configSetting';
import { IAuthenticationService } from '@services/auth/interface';
import { lazyInject } from '@services/container';
import { i18n } from '@services/libs/i18n';
import { logger } from '@services/libs/log';
@ -29,7 +30,6 @@ import { WindowNames } from '@services/windows/WindowProperties';
import type { IWorkspaceViewService } from '@services/workspacesView/interface';
import type { INewWorkspaceConfig, IWorkspace, IWorkspaceMetaData, IWorkspaceService, IWorkspaceWithMetadata } from './interface';
import { workspaceSorter } from './utils';
import { IAuthenticationService } from '@services/auth/interface';
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
const debouncedSetSettingFile = debounce(async (workspaces: Record<string, IWorkspace>) => {
@ -291,8 +291,11 @@ export class Workspace implements IWorkspaceService {
fixingValues.tagName = workspaceToSanitize.tagName.replaceAll('\n', '');
}
// before 0.8.0, tidgi was loading http content, so lastUrl will be http protocol, but later we switch to tidgi:// protocol, so old value can't be used.
if (workspaceToSanitize.lastUrl?.startsWith('tidgi')) {
fixingValues.lastUrl = '';
if (!workspaceToSanitize.lastUrl?.startsWith('tidgi')) {
fixingValues.lastUrl = null;
}
if (!workspaceToSanitize.homeUrl?.startsWith('tidgi')) {
fixingValues.homeUrl = getDefaultTidGiUrl(workspaceToSanitize.id);
}
if (workspaceToSanitize.tokenAuth && !workspaceToSanitize.authToken) {
fixingValues.authToken = this.authService.generateOneTimeAdminAuthTokenForWorkspaceSync(workspaceToSanitize.id);
@ -475,7 +478,7 @@ export class Workspace implements IWorkspaceService {
disableNotifications: false,
hibernated: false,
hibernateWhenUnused: false,
homeUrl: `http://${defaultServerIP}:${newWorkspaceConfig.port}`,
homeUrl: getDefaultTidGiUrl(newID),
id: newID,
lastUrl: null,
lastNodeJSArgv: [],