fix: handle bad access when accessing paths (#2375)
This commit is contained in:
@@ -1,10 +1,7 @@
|
|||||||
import { MessageType } from '../test/TestIpcMessage'
|
|
||||||
import { Store } from './javascripts/Main/Store/Store'
|
import { Store } from './javascripts/Main/Store/Store'
|
||||||
import { StoreKeys } from './javascripts/Main/Store/StoreKeys'
|
import { StoreKeys } from './javascripts/Main/Store/StoreKeys'
|
||||||
import { Paths, Urls } from './javascripts/Main/Types/Paths'
|
import { Paths, Urls } from './javascripts/Main/Types/Paths'
|
||||||
import { UpdateState } from './javascripts/Main/UpdateManager'
|
import { UpdateState } from './javascripts/Main/UpdateManager'
|
||||||
import { handleTestMessage } from './javascripts/Main/Utils/Testing'
|
|
||||||
import { isTesting } from './javascripts/Main/Utils/Utils'
|
|
||||||
import { WindowState } from './javascripts/Main/Window'
|
import { WindowState } from './javascripts/Main/Window'
|
||||||
|
|
||||||
export class AppState {
|
export class AppState {
|
||||||
@@ -27,12 +24,6 @@ export class AppState {
|
|||||||
this.store.set(StoreKeys.LastRunVersion, this.version)
|
this.store.set(StoreKeys.LastRunVersion, this.version)
|
||||||
|
|
||||||
this.updates = new UpdateState(this)
|
this.updates = new UpdateState(this)
|
||||||
|
|
||||||
if (isTesting()) {
|
|
||||||
handleTestMessage(MessageType.AppStateCall, (method, ...args) => {
|
|
||||||
;(this as any)[method](...args)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public isRunningVersionForFirstTime(): boolean {
|
public isRunningVersionForFirstTime(): boolean {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
import { app, ipcMain, shell } from 'electron'
|
import { app, ipcMain, shell } from 'electron'
|
||||||
import log from 'electron-log'
|
import log from 'electron-log'
|
||||||
import fs from 'fs-extra'
|
import fs from 'fs-extra'
|
||||||
@@ -9,8 +10,6 @@ import { Store } from './javascripts/Main/Store/Store'
|
|||||||
import { StoreKeys } from './javascripts/Main/Store/StoreKeys'
|
import { StoreKeys } from './javascripts/Main/Store/StoreKeys'
|
||||||
import { isSnap } from './javascripts/Main/Types/Constants'
|
import { isSnap } from './javascripts/Main/Types/Constants'
|
||||||
import { Paths } from './javascripts/Main/Types/Paths'
|
import { Paths } from './javascripts/Main/Types/Paths'
|
||||||
import { setupTesting } from './javascripts/Main/Utils/Testing'
|
|
||||||
import { isTesting } from './javascripts/Main/Utils/Utils'
|
|
||||||
import { CommandLineArgs } from './javascripts/Shared/CommandLineArgs'
|
import { CommandLineArgs } from './javascripts/Shared/CommandLineArgs'
|
||||||
|
|
||||||
enableExperimentalFeaturesForFileAccessFix()
|
enableExperimentalFeaturesForFileAccessFix()
|
||||||
@@ -39,10 +38,6 @@ if (userDataPathIndex > 0) {
|
|||||||
migrateSnapStorage()
|
migrateSnapStorage()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTesting()) {
|
|
||||||
setupTesting()
|
|
||||||
}
|
|
||||||
|
|
||||||
log.transports.file.level = 'info'
|
log.transports.file.level = 'info'
|
||||||
|
|
||||||
process.on('uncaughtException', (err) => {
|
process.on('uncaughtException', (err) => {
|
||||||
@@ -96,8 +91,12 @@ function migrateSnapStorage() {
|
|||||||
fs.moveSync(fullFilePath, path.join(dest, fileName), {
|
fs.moveSync(fullFilePath, path.join(dest, fileName), {
|
||||||
overwrite: false,
|
overwrite: false,
|
||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error) {
|
||||||
console.error(`Migration: error occured while moving ${fullFilePath} to ${dest}:`, error?.message ?? error)
|
console.error(
|
||||||
|
`Migration: error occured while moving ${fullFilePath} to ${dest}:`,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(error as any)?.message ?? error,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,18 +109,22 @@ function migrateSnapStorage() {
|
|||||||
* Backups location has not been altered by the user. Move it to the
|
* Backups location has not been altered by the user. Move it to the
|
||||||
* user documents directory
|
* user documents directory
|
||||||
*/
|
*/
|
||||||
console.log(`Migration: moving ${store.data.backupsLocation} to ${Paths.documentsDir}`)
|
const documentsDir = Paths.documentsDir
|
||||||
const newLocation = path.join(Paths.documentsDir, path.basename(store.data.backupsLocation))
|
console.log(`Migration: moving ${store.data.backupsLocation} to ${documentsDir}`)
|
||||||
try {
|
if (documentsDir) {
|
||||||
fs.copySync(store.data.backupsLocation, newLocation)
|
const newLocation = path.join(documentsDir, path.basename(store.data.backupsLocation))
|
||||||
} catch (error: any) {
|
try {
|
||||||
console.error(
|
fs.copySync(store.data.backupsLocation, newLocation)
|
||||||
`Migration: error occured while moving ${store.data.backupsLocation} to ${Paths.documentsDir}:`,
|
} catch (error) {
|
||||||
error?.message ?? error,
|
console.error(
|
||||||
)
|
`Migration: error occured while moving ${store.data.backupsLocation} to ${documentsDir}:`,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(error as any)?.message ?? error,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
store.set(StoreKeys.LegacyTextBackupsLocation, newLocation)
|
||||||
|
console.log('Migration: finished moving backups directory.')
|
||||||
}
|
}
|
||||||
store.set(StoreKeys.LegacyTextBackupsLocation, newLocation)
|
|
||||||
console.log('Migration: finished moving backups directory.')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export class FilesBackupManager implements FileBackupsDevice {
|
|||||||
return value === true
|
return value === true
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserDocumentsDirectory(): Promise<string> {
|
async getUserDocumentsDirectory(): Promise<string | undefined> {
|
||||||
return Paths.documentsDir
|
return Paths.documentsDir
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,7 +103,12 @@ export class FilesBackupManager implements FileBackupsDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const LegacyTextBackupsDirectory = 'Standard Notes Backups'
|
const LegacyTextBackupsDirectory = 'Standard Notes Backups'
|
||||||
return path.join(Paths.homeDir, LegacyTextBackupsDirectory)
|
const homeDir = Paths.homeDir
|
||||||
|
if (homeDir) {
|
||||||
|
return path.join(homeDir, LegacyTextBackupsDirectory)
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
private getFileBackupsMappingFilePath(backupsLocation: string): string {
|
private getFileBackupsMappingFilePath(backupsLocation: string): string {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { compareVersions } from 'compare-versions'
|
import { compareVersions } from 'compare-versions'
|
||||||
import log from 'electron-log'
|
import log from 'electron-log'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ export class RemoteBridge implements CrossProcessBridge {
|
|||||||
return this.fileBackups.migrateLegacyFileBackupsToNewStructure(newPath)
|
return this.fileBackups.migrateLegacyFileBackupsToNewStructure(newPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserDocumentsDirectory(): Promise<string> {
|
getUserDocumentsDirectory(): Promise<string | undefined> {
|
||||||
return this.fileBackups.getUserDocumentsDirectory()
|
return this.fileBackups.getUserDocumentsDirectory()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,11 +36,19 @@ export const Paths = {
|
|||||||
get userDataDir(): string {
|
get userDataDir(): string {
|
||||||
return app.getPath('userData')
|
return app.getPath('userData')
|
||||||
},
|
},
|
||||||
get homeDir(): string {
|
get homeDir(): string | undefined {
|
||||||
return app.getPath('home')
|
try {
|
||||||
|
return app.getPath('home')
|
||||||
|
} catch (error) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
},
|
},
|
||||||
get documentsDir(): string {
|
get documentsDir(): string | undefined {
|
||||||
return app.getPath('documents')
|
try {
|
||||||
|
return app.getPath('documents')
|
||||||
|
} catch (error) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
},
|
},
|
||||||
get tempDir(): string {
|
get tempDir(): string {
|
||||||
return app.getPath('temp')
|
return app.getPath('temp')
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ export class DesktopDevice extends WebOrDesktopDevice implements DesktopDeviceIn
|
|||||||
return this.remoteBridge.wasLegacyTextBackupsExplicitlyDisabled()
|
return this.remoteBridge.wasLegacyTextBackupsExplicitlyDisabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserDocumentsDirectory(): Promise<string> {
|
getUserDocumentsDirectory(): Promise<string | undefined> {
|
||||||
return this.remoteBridge.getUserDocumentsDirectory()
|
return this.remoteBridge.getUserDocumentsDirectory()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ interface PlaintextBackupsMethods {
|
|||||||
interface TextBackupsMethods {
|
interface TextBackupsMethods {
|
||||||
getTextBackupsCount(location: string): Promise<number>
|
getTextBackupsCount(location: string): Promise<number>
|
||||||
saveTextBackupData(location: string, data: string): Promise<void>
|
saveTextBackupData(location: string, data: string): Promise<void>
|
||||||
getUserDocumentsDirectory(): Promise<string>
|
getUserDocumentsDirectory(): Promise<string | undefined>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LegacyBackupsMethods {
|
interface LegacyBackupsMethods {
|
||||||
|
|||||||
@@ -160,14 +160,21 @@ export class FilesBackupService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async automaticallyEnableTextBackupsIfPreferenceNotSet(): Promise<void> {
|
private async automaticallyEnableTextBackupsIfPreferenceNotSet(): Promise<void> {
|
||||||
if (this.storage.getValue(StorageKey.TextBackupsEnabled) == undefined) {
|
if (this.storage.getValue(StorageKey.TextBackupsEnabled) != undefined) {
|
||||||
this.storage.setValue(StorageKey.TextBackupsEnabled, true)
|
return
|
||||||
const location = await this.device.joinPaths(
|
|
||||||
await this.device.getUserDocumentsDirectory(),
|
|
||||||
await this.prependWorkspacePathForPath(TextBackupsDirectoryName),
|
|
||||||
)
|
|
||||||
this.storage.setValue(StorageKey.TextBackupsLocation, location)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.storage.setValue(StorageKey.TextBackupsEnabled, true)
|
||||||
|
const documentsDir = await this.device.getUserDocumentsDirectory()
|
||||||
|
if (!documentsDir) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const location = await this.device.joinPaths(
|
||||||
|
documentsDir,
|
||||||
|
await this.prependWorkspacePathForPath(TextBackupsDirectoryName),
|
||||||
|
)
|
||||||
|
this.storage.setValue(StorageKey.TextBackupsLocation, location)
|
||||||
}
|
}
|
||||||
|
|
||||||
openAllDirectoriesContainingBackupFiles(): void {
|
openAllDirectoriesContainingBackupFiles(): void {
|
||||||
|
|||||||
@@ -170,6 +170,9 @@ export class HomeServerService
|
|||||||
let location = await this.getHomeServerDataLocation()
|
let location = await this.getHomeServerDataLocation()
|
||||||
if (!location) {
|
if (!location) {
|
||||||
const documentsDirectory = await this.desktopDevice.getUserDocumentsDirectory()
|
const documentsDirectory = await this.desktopDevice.getUserDocumentsDirectory()
|
||||||
|
if (!documentsDirectory) {
|
||||||
|
return
|
||||||
|
}
|
||||||
location = `${documentsDirectory}/${this.HOME_SERVER_DATA_DIRECTORY_NAME}`
|
location = `${documentsDirectory}/${this.HOME_SERVER_DATA_DIRECTORY_NAME}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user