-
-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Include the script's directory path #304. - Exclude Windows-specific instructions on non-Windows OS. - Standardize language across dialogs for consistency. Other supporting changes: - Add script diagnostics data collection from main process. - Document script file storage and execution tamper protection in SECURITY.md. - Remove redundant comment in `NodeReadbackFileWriter`. - Centralize error display for uniformity and simplicity. - Simpify `WindowVariablesValidator` to omit checks when not on the renderer process. - Improve and centralize Electron environment detection. - Use more emphatic language (don't worry) in error messages.
- Loading branch information
1 parent
f03fc24
commit 6ada8d4
Showing
34 changed files
with
1,167 additions
and
435 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/application/ScriptDiagnostics/ScriptDiagnosticsCollector.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import { OperatingSystem } from '@/domain/OperatingSystem'; | ||
|
||
export interface ScriptDiagnosticsCollector { | ||
collectDiagnosticInformation(): Promise<ScriptDiagnosticData>; | ||
} | ||
|
||
export interface ScriptDiagnosticData { | ||
readonly scriptsDirectoryAbsolutePath?: string; | ||
readonly currentOperatingSystem?: OperatingSystem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
src/infrastructure/RuntimeEnvironment/Electron/ContextIsolatedElectronDetector.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { ElectronEnvironmentDetector, ElectronProcessType } from './ElectronEnvironmentDetector'; | ||
|
||
export class ContextIsolatedElectronDetector implements ElectronEnvironmentDetector { | ||
constructor( | ||
private readonly nodeProcessAccessor: NodeProcessAccessor = () => globalThis?.process, | ||
private readonly userAgentAccessor: UserAgentAccessor = () => globalThis?.navigator?.userAgent, | ||
) { } | ||
|
||
public isRunningInsideElectron(): boolean { | ||
return isNodeProcessElectronBased(this.nodeProcessAccessor) | ||
|| isUserAgentElectronBased(this.userAgentAccessor); | ||
} | ||
|
||
public determineElectronProcessType(): ElectronProcessType { | ||
const isNodeAccessible = isNodeProcessElectronBased(this.nodeProcessAccessor); | ||
const isBrowserAccessible = isUserAgentElectronBased(this.userAgentAccessor); | ||
if (!isNodeAccessible && !isBrowserAccessible) { | ||
throw new Error('Unable to determine the Electron process type. Neither Node.js nor browser-based Electron contexts were detected.'); | ||
} | ||
if (isNodeAccessible && isBrowserAccessible) { | ||
return 'preloader'; // Only preloader can access both Node.js and browser contexts in Electron with context isolation. | ||
} | ||
if (isNodeAccessible) { | ||
return 'main'; | ||
} | ||
return 'renderer'; | ||
} | ||
} | ||
|
||
export type NodeProcessAccessor = () => NodeJS.Process | undefined; | ||
|
||
function isNodeProcessElectronBased(nodeProcessAccessor: NodeProcessAccessor): boolean { | ||
const nodeProcess = nodeProcessAccessor(); | ||
if (!nodeProcess) { | ||
return false; | ||
} | ||
if (nodeProcess.versions.electron) { | ||
// Electron populates `nodeProcess.versions.electron` with its version, see https://web.archive.org/web/20240113162837/https://www.electronjs.org/docs/latest/api/process#processversionselectron-readonly. | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
export type UserAgentAccessor = () => string | undefined; | ||
|
||
function isUserAgentElectronBased( | ||
userAgentAccessor: UserAgentAccessor, | ||
): boolean { | ||
const userAgent = userAgentAccessor(); | ||
if (userAgent?.includes('Electron')) { | ||
return true; | ||
} | ||
return false; | ||
} |
6 changes: 6 additions & 0 deletions
6
src/infrastructure/RuntimeEnvironment/Electron/ElectronEnvironmentDetector.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export interface ElectronEnvironmentDetector { | ||
isRunningInsideElectron(): boolean; | ||
determineElectronProcessType(): ElectronProcessType; | ||
} | ||
|
||
export type ElectronProcessType = 'main' | 'preloader' | 'renderer'; |
45 changes: 14 additions & 31 deletions
45
src/infrastructure/RuntimeEnvironment/RuntimeEnvironmentFactory.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,32 @@ | ||
import { ElectronEnvironmentDetector } from './Electron/ElectronEnvironmentDetector'; | ||
import { BrowserRuntimeEnvironment } from './Browser/BrowserRuntimeEnvironment'; | ||
import { NodeRuntimeEnvironment } from './Node/NodeRuntimeEnvironment'; | ||
import { RuntimeEnvironment } from './RuntimeEnvironment'; | ||
import { ContextIsolatedElectronDetector } from './Electron/ContextIsolatedElectronDetector'; | ||
|
||
export const CurrentEnvironment = determineAndCreateRuntimeEnvironment({ | ||
window: globalThis.window, | ||
process: globalThis.process, | ||
}); | ||
export const CurrentEnvironment = determineAndCreateRuntimeEnvironment(globalThis.window); | ||
|
||
export function determineAndCreateRuntimeEnvironment( | ||
globalAccessor: GlobalPropertiesAccessor, | ||
globalWindow: Window | undefined | null = globalThis.window, | ||
electronDetector: ElectronEnvironmentDetector = new ContextIsolatedElectronDetector(), | ||
browserEnvironmentFactory: BrowserRuntimeEnvironmentFactory = ( | ||
window, | ||
) => new BrowserRuntimeEnvironment(window), | ||
nodeEnvironmentFactory: NodeRuntimeEnvironmentFactory = ( | ||
process: NodeJS.Process, | ||
) => new NodeRuntimeEnvironment(process), | ||
nodeEnvironmentFactory: NodeRuntimeEnvironmentFactory = () => new NodeRuntimeEnvironment(), | ||
): RuntimeEnvironment { | ||
if (isElectronMainProcess(globalAccessor.process)) { | ||
return nodeEnvironmentFactory(globalAccessor.process); | ||
if ( | ||
electronDetector.isRunningInsideElectron() | ||
&& electronDetector.determineElectronProcessType() === 'main') { | ||
return nodeEnvironmentFactory(); | ||
} | ||
const { window } = globalAccessor; | ||
if (!window) { | ||
if (!globalWindow) { | ||
throw new Error('Unsupported runtime environment: The current context is neither a recognized browser nor a desktop environment.'); | ||
} | ||
return browserEnvironmentFactory(window); | ||
} | ||
|
||
function isElectronMainProcess( | ||
nodeProcess: NodeJS.Process | undefined, | ||
): nodeProcess is NodeJS.Process { | ||
// Electron populates `nodeProcess.versions.electron` with its version, see https://web.archive.org/web/20240113162837/https://www.electronjs.org/docs/latest/api/process#processversionselectron-readonly. | ||
if (!nodeProcess) { | ||
return false; | ||
} | ||
if (nodeProcess.versions.electron) { | ||
return true; | ||
} | ||
return false; | ||
return browserEnvironmentFactory(globalWindow); | ||
} | ||
|
||
export type BrowserRuntimeEnvironmentFactory = (window: Window) => RuntimeEnvironment; | ||
|
||
export type NodeRuntimeEnvironmentFactory = (process: NodeJS.Process) => NodeRuntimeEnvironment; | ||
export type NodeRuntimeEnvironmentFactory = () => NodeRuntimeEnvironment; | ||
|
||
export interface GlobalPropertiesAccessor { | ||
readonly window: Window | undefined; | ||
readonly process: NodeJS.Process | undefined; | ||
} | ||
export type GlobalWindowAccessor = Window | undefined; |
20 changes: 20 additions & 0 deletions
20
src/infrastructure/ScriptDiagnostics/ScriptEnvironmentDiagnosticsCollector.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { ScriptDiagnosticData, ScriptDiagnosticsCollector } from '@/application/ScriptDiagnostics/ScriptDiagnosticsCollector'; | ||
import { RuntimeEnvironment } from '@/infrastructure/RuntimeEnvironment/RuntimeEnvironment'; | ||
import { CurrentEnvironment } from '@/infrastructure/RuntimeEnvironment/RuntimeEnvironmentFactory'; | ||
import { PersistentDirectoryProvider } from '@/infrastructure/CodeRunner/Creation/Directory/PersistentDirectoryProvider'; | ||
import { ScriptDirectoryProvider } from '../CodeRunner/Creation/Directory/ScriptDirectoryProvider'; | ||
|
||
export class ScriptEnvironmentDiagnosticsCollector implements ScriptDiagnosticsCollector { | ||
constructor( | ||
private readonly directoryProvider: ScriptDirectoryProvider = new PersistentDirectoryProvider(), | ||
private readonly environment: RuntimeEnvironment = CurrentEnvironment, | ||
) { } | ||
|
||
public async collectDiagnosticInformation(): Promise<ScriptDiagnosticData> { | ||
const { directoryAbsolutePath } = await this.directoryProvider.provideScriptDirectory(); | ||
return { | ||
scriptsDirectoryAbsolutePath: directoryAbsolutePath, | ||
currentOperatingSystem: this.environment.os, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.