fix: not allow user to choose sub directory as jan data folder
Signed-off-by: James <james@jan.ai>
This commit is contained in:
parent
96aded6b03
commit
282dd58d05
@ -12,6 +12,7 @@ export enum AppRoute {
|
||||
updateAppConfiguration = 'updateAppConfiguration',
|
||||
relaunch = 'relaunch',
|
||||
joinPath = 'joinPath',
|
||||
isSubdirectory = 'isSubdirectory',
|
||||
baseName = 'baseName',
|
||||
startServer = 'startServer',
|
||||
stopServer = 'stopServer',
|
||||
|
||||
@ -22,7 +22,11 @@ const executeOnMain: (extension: string, method: string, ...args: any[]) => Prom
|
||||
* @param {object} network - Optional object to specify proxy/whether to ignore SSL certificates.
|
||||
* @returns {Promise<any>} A promise that resolves when the file is downloaded.
|
||||
*/
|
||||
const downloadFile: (url: string, fileName: string, network?: { proxy?: string, ignoreSSL?: boolean }) => Promise<any> = (url, fileName, network) => {
|
||||
const downloadFile: (
|
||||
url: string,
|
||||
fileName: string,
|
||||
network?: { proxy?: string; ignoreSSL?: boolean }
|
||||
) => Promise<any> = (url, fileName, network) => {
|
||||
return global.core?.api?.downloadFile(url, fileName, network)
|
||||
}
|
||||
|
||||
@ -87,6 +91,17 @@ const getResourcePath: () => Promise<string> = () => global.core.api?.getResourc
|
||||
const log: (message: string, fileName?: string) => void = (message, fileName) =>
|
||||
global.core.api?.log(message, fileName)
|
||||
|
||||
/**
|
||||
* Check whether the path is a subdirectory of another path.
|
||||
*
|
||||
* @param from - The path to check.
|
||||
* @param to - The path to check against.
|
||||
*
|
||||
* @returns {Promise<boolean>} - A promise that resolves with a boolean indicating whether the path is a subdirectory.
|
||||
*/
|
||||
const isSubdirectory: (from: string, to: string) => Promise<boolean> = (from: string, to: string) =>
|
||||
global.core.api?.isSubdirectory(from, to)
|
||||
|
||||
/**
|
||||
* Register extension point function type definition
|
||||
*/
|
||||
@ -94,7 +109,7 @@ export type RegisterExtensionPoint = (
|
||||
extensionName: string,
|
||||
extensionId: string,
|
||||
method: Function,
|
||||
priority?: number,
|
||||
priority?: number
|
||||
) => void
|
||||
|
||||
/**
|
||||
@ -111,5 +126,6 @@ export {
|
||||
openExternalUrl,
|
||||
baseName,
|
||||
log,
|
||||
isSubdirectory,
|
||||
FileStat,
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { app, ipcMain, dialog, shell } from 'electron'
|
||||
import { join, basename } from 'path'
|
||||
import { join, basename, relative as getRelative, isAbsolute } from 'path'
|
||||
import { WindowManager } from './../managers/window'
|
||||
import { getResourcePath } from './../utils/path'
|
||||
import { AppRoute, AppConfiguration } from '@janhq/core'
|
||||
@ -50,6 +50,27 @@ export function handleAppIPCs() {
|
||||
join(...paths)
|
||||
)
|
||||
|
||||
/**
|
||||
* Checks if the given path is a subdirectory of the given directory.
|
||||
*
|
||||
* @param _event - The IPC event object.
|
||||
* @param from - The path to check.
|
||||
* @param to - The directory to check against.
|
||||
*
|
||||
* @returns {Promise<boolean>} - A promise that resolves with the result.
|
||||
*/
|
||||
ipcMain.handle(
|
||||
AppRoute.isSubdirectory,
|
||||
async (_event, from: string, to: string) => {
|
||||
const relative = getRelative(from, to)
|
||||
const isSubdir =
|
||||
relative && !relative.startsWith('..') && !isAbsolute(relative)
|
||||
|
||||
if (isSubdir === '') return false
|
||||
else return isSubdir
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* Retrieve basename from given path, respect to the current OS.
|
||||
*/
|
||||
|
||||
@ -10,15 +10,12 @@ import {
|
||||
ModalClose,
|
||||
Button,
|
||||
} from '@janhq/uikit'
|
||||
import { atom, useAtom, useAtomValue } from 'jotai'
|
||||
|
||||
import { errorAtom } from '.'
|
||||
import { atom, useAtom } from 'jotai'
|
||||
|
||||
export const showChangeFolderErrorAtom = atom(false)
|
||||
|
||||
const ModalErrorSetDestGlobal = () => {
|
||||
const [show, setShow] = useAtom(showChangeFolderErrorAtom)
|
||||
const error = useAtomValue(errorAtom)
|
||||
return (
|
||||
<Modal open={show} onOpenChange={setShow}>
|
||||
<ModalPortal />
|
||||
@ -30,7 +27,6 @@ const ModalErrorSetDestGlobal = () => {
|
||||
Oops! Something went wrong. Jan data folder remains the same. Please
|
||||
try again.
|
||||
</p>
|
||||
<p className="text-muted-foreground">{error}</p>
|
||||
<ModalFooter>
|
||||
<div className="flex gap-x-2">
|
||||
<ModalClose asChild onClick={() => setShow(false)}>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { Fragment, useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import { fs, AppConfiguration } from '@janhq/core'
|
||||
import { fs, AppConfiguration, isSubdirectory } from '@janhq/core'
|
||||
import { Button, Input } from '@janhq/uikit'
|
||||
import { atom, useSetAtom } from 'jotai'
|
||||
import { useSetAtom } from 'jotai'
|
||||
import { PencilIcon, FolderOpenIcon } from 'lucide-react'
|
||||
|
||||
import Loader from '@/containers/Loader'
|
||||
@ -18,8 +18,6 @@ import ModalErrorSetDestGlobal, {
|
||||
|
||||
import ModalSameDirectory, { showSamePathModalAtom } from './ModalSameDirectory'
|
||||
|
||||
export const errorAtom = atom('')
|
||||
|
||||
const DataFolder = () => {
|
||||
const [janDataFolderPath, setJanDataFolderPath] = useState('')
|
||||
const [showLoader, setShowLoader] = useState(false)
|
||||
@ -27,7 +25,6 @@ const DataFolder = () => {
|
||||
const setShowSameDirectory = useSetAtom(showSamePathModalAtom)
|
||||
const setShowChangeFolderError = useSetAtom(showChangeFolderErrorAtom)
|
||||
const [destinationPath, setDestinationPath] = useState(undefined)
|
||||
const setError = useSetAtom(errorAtom)
|
||||
|
||||
useEffect(() => {
|
||||
window.core?.api
|
||||
@ -46,6 +43,15 @@ const DataFolder = () => {
|
||||
return
|
||||
}
|
||||
|
||||
const appConfiguration: AppConfiguration =
|
||||
await window.core?.api?.getAppConfigurations()
|
||||
const currentJanDataFolder = appConfiguration.data_folder
|
||||
|
||||
if (await isSubdirectory(currentJanDataFolder, destFolder)) {
|
||||
setShowSameDirectory(true)
|
||||
return
|
||||
}
|
||||
|
||||
setDestinationPath(destFolder)
|
||||
setShowDirectoryConfirm(true)
|
||||
}, [janDataFolderPath, setShowSameDirectory, setShowDirectoryConfirm])
|
||||
@ -68,14 +74,12 @@ const DataFolder = () => {
|
||||
setShowLoader(false)
|
||||
}, 1200)
|
||||
await window.core?.api?.relaunch()
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
} catch (e) {
|
||||
console.error(`Error: ${e}`)
|
||||
setError(e.message)
|
||||
setShowLoader(false)
|
||||
setShowChangeFolderError(true)
|
||||
}
|
||||
}, [destinationPath, setError, setShowChangeFolderError])
|
||||
}, [destinationPath, setShowChangeFolderError])
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user