aboutsummaryrefslogtreecommitdiffstats
path: root/packages/main/src/infrastructure
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-04-26 16:55:57 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-05-16 00:55:02 +0200
commitb971de0717a66ae6085670fe5d3a469e236a9446 (patch)
treec64352908648512bad713fc1e91dd5f07a66968c /packages/main/src/infrastructure
parentrefactor: remove json5 dependency (diff)
downloadsophie-b971de0717a66ae6085670fe5d3a469e236a9446.tar.gz
sophie-b971de0717a66ae6085670fe5d3a469e236a9446.tar.zst
sophie-b971de0717a66ae6085670fe5d3a469e236a9446.zip
refactor: config file saving and debugging
Reduce the number of dependencies and the amount of code running in a security sensitive context. Instead of a deep comparison, we just compare the serialized versions of the config files. Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/main/src/infrastructure')
-rw-r--r--packages/main/src/infrastructure/config/ConfigRepository.ts5
-rw-r--r--packages/main/src/infrastructure/config/impl/ConfigFile.ts12
-rw-r--r--packages/main/src/infrastructure/electron/impl/devTools.ts43
-rw-r--r--packages/main/src/infrastructure/electron/impl/hardenSession.ts14
4 files changed, 37 insertions, 37 deletions
diff --git a/packages/main/src/infrastructure/config/ConfigRepository.ts b/packages/main/src/infrastructure/config/ConfigRepository.ts
index e00f5a0..67bffb0 100644
--- a/packages/main/src/infrastructure/config/ConfigRepository.ts
+++ b/packages/main/src/infrastructure/config/ConfigRepository.ts
@@ -18,17 +18,16 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import type Config from '../../stores/config/Config';
22import type Disposer from '../../utils/Disposer'; 21import type Disposer from '../../utils/Disposer';
23 22
24export type ReadConfigResult = 23export type ReadConfigResult =
25 | { found: true; data: unknown } 24 | { found: true; contents: string }
26 | { found: false }; 25 | { found: false };
27 26
28export default interface ConfigPersistence { 27export default interface ConfigPersistence {
29 readConfig(): Promise<ReadConfigResult>; 28 readConfig(): Promise<ReadConfigResult>;
30 29
31 writeConfig(config: Config): Promise<void>; 30 writeConfig(contents: string): Promise<void>;
32 31
33 watchConfig(callback: () => Promise<void>, throttleMs: number): Disposer; 32 watchConfig(callback: () => Promise<void>, throttleMs: number): Disposer;
34} 33}
diff --git a/packages/main/src/infrastructure/config/impl/ConfigFile.ts b/packages/main/src/infrastructure/config/impl/ConfigFile.ts
index c4e6d22..8b110a2 100644
--- a/packages/main/src/infrastructure/config/impl/ConfigFile.ts
+++ b/packages/main/src/infrastructure/config/impl/ConfigFile.ts
@@ -24,7 +24,6 @@ import path from 'node:path';
24 24
25import { throttle } from 'lodash-es'; 25import { throttle } from 'lodash-es';
26 26
27import type Config from '../../../stores/config/Config';
28import type Disposer from '../../../utils/Disposer'; 27import type Disposer from '../../../utils/Disposer';
29import isErrno from '../../../utils/isErrno'; 28import isErrno from '../../../utils/isErrno';
30import { getLogger } from '../../../utils/log'; 29import { getLogger } from '../../../utils/log';
@@ -48,9 +47,9 @@ export default class ConfigFile implements ConfigRepository {
48 } 47 }
49 48
50 async readConfig(): Promise<ReadConfigResult> { 49 async readConfig(): Promise<ReadConfigResult> {
51 let configStr: string; 50 let contents: string;
52 try { 51 try {
53 configStr = await readFile(this.configFilePath, 'utf8'); 52 contents = await readFile(this.configFilePath, 'utf8');
54 } catch (error) { 53 } catch (error) {
55 if (isErrno(error, 'ENOENT')) { 54 if (isErrno(error, 'ENOENT')) {
56 log.debug('Config file', this.configFilePath, 'was not found'); 55 log.debug('Config file', this.configFilePath, 'was not found');
@@ -61,15 +60,14 @@ export default class ConfigFile implements ConfigRepository {
61 log.info('Read config file', this.configFilePath); 60 log.info('Read config file', this.configFilePath);
62 return { 61 return {
63 found: true, 62 found: true,
64 data: JSON.parse(configStr), 63 contents,
65 }; 64 };
66 } 65 }
67 66
68 async writeConfig(configSnapshot: Config): Promise<void> { 67 async writeConfig(contents: string): Promise<void> {
69 const configJson = JSON.stringify(configSnapshot, undefined, 2);
70 this.writingConfig = true; 68 this.writingConfig = true;
71 try { 69 try {
72 await writeFile(this.configFilePath, configJson, 'utf8'); 70 await writeFile(this.configFilePath, contents, 'utf8');
73 const { mtime } = await stat(this.configFilePath); 71 const { mtime } = await stat(this.configFilePath);
74 log.trace('Config file', this.configFilePath, 'last written at', mtime); 72 log.trace('Config file', this.configFilePath, 'last written at', mtime);
75 this.timeLastWritten = mtime; 73 this.timeLastWritten = mtime;
diff --git a/packages/main/src/infrastructure/electron/impl/devTools.ts b/packages/main/src/infrastructure/electron/impl/devTools.ts
index 10f4545..6db88d1 100644
--- a/packages/main/src/infrastructure/electron/impl/devTools.ts
+++ b/packages/main/src/infrastructure/electron/impl/devTools.ts
@@ -18,34 +18,32 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import type { BrowserWindow } from 'electron'; 21import { app, type BrowserWindow } from 'electron';
22
23/* eslint-disable
24 import/no-extraneous-dependencies,
25 global-require,
26 @typescript-eslint/no-var-requires,
27 unicorn/prefer-module --
28 Hack to lazily require a CJS module from an ES module transpiled into a CJS module.
29*/
22 30
23/** 31/**
24 * URL prefixes Sophie is allowed load in dev mode. 32 * Makes sure we use a separate data dir for development.
25 *
26 * In dev mode, in addition to the application itself,
27 * Sophie must be able do download and load the devtools and related extensions,
28 * so we have to make exceptions in the UI process request filter.
29 */ 33 */
30export const DEVMODE_ALLOWED_URL_PREFIXES = [ 34export function ensureDevDataDir(): void {
31 'chrome-extension:', 35 // Use alternative directory when debugging to avoid clobbering the main installation.
32 'devtools:', 36 app.setPath('userData', `${app.getPath('userData')}-dev`);
33 'https://clients2.google.com/service/update2/crx', 37 const userData = app.getPath('userData');
34 'https://clients2.googleusercontent.com/crx', 38 const mkdirp = require('mkdirp') as typeof import('mkdirp');
35]; 39 mkdirp.sync(userData);
40}
36 41
37/** 42/**
38 * Enables using source maps for node stack traces. 43 * Enables using source maps for node stack traces.
39 */ 44 */
40export function enableStacktraceSourceMaps(): void { 45export function enableStacktraceSourceMaps(): void {
41 const sourceMapSupport = 46 const sourceMapSupport =
42 /* eslint-disable-next-line
43 import/no-extraneous-dependencies,
44 global-require,
45 @typescript-eslint/no-var-requires,
46 unicorn/prefer-module --
47 Hack to lazily require a CJS module from an ES module transpiled into a CJS module.
48 */
49 require('source-map-support') as typeof import('source-map-support'); 47 require('source-map-support') as typeof import('source-map-support');
50 sourceMapSupport.install(); 48 sourceMapSupport.install();
51} 49}
@@ -61,13 +59,6 @@ export async function installDevToolsExtensions(): Promise<void> {
61 default: installExtension, 59 default: installExtension,
62 REACT_DEVELOPER_TOOLS, 60 REACT_DEVELOPER_TOOLS,
63 REDUX_DEVTOOLS, 61 REDUX_DEVTOOLS,
64 /* eslint-disable-next-line
65 import/no-extraneous-dependencies,
66 global-require,
67 @typescript-eslint/no-var-requires,
68 unicorn/prefer-module --
69 Hack to lazily require a CJS module from an ES module transpiled into a CJS module.
70 */
71 } = require('electron-devtools-installer') as typeof import('electron-devtools-installer'); 62 } = require('electron-devtools-installer') as typeof import('electron-devtools-installer');
72 await installExtension([REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS], { 63 await installExtension([REACT_DEVELOPER_TOOLS, REDUX_DEVTOOLS], {
73 forceDownload: false, 64 forceDownload: false,
diff --git a/packages/main/src/infrastructure/electron/impl/hardenSession.ts b/packages/main/src/infrastructure/electron/impl/hardenSession.ts
index 10b694a..53675a7 100644
--- a/packages/main/src/infrastructure/electron/impl/hardenSession.ts
+++ b/packages/main/src/infrastructure/electron/impl/hardenSession.ts
@@ -25,7 +25,19 @@ import type { Session } from 'electron';
25import { getLogger } from '../../../utils/log'; 25import { getLogger } from '../../../utils/log';
26import type Resources from '../../resources/Resources'; 26import type Resources from '../../resources/Resources';
27 27
28import { DEVMODE_ALLOWED_URL_PREFIXES } from './devTools'; 28/**
29 * URL prefixes Sophie is allowed load in dev mode.
30 *
31 * In dev mode, in addition to the application itself,
32 * Sophie must be able do download and load the devtools and related extensions,
33 * so we have to make exceptions in the UI process request filter.
34 */
35export const DEVMODE_ALLOWED_URL_PREFIXES = [
36 'chrome-extension:',
37 'devtools:',
38 'https://clients2.google.com/service/update2/crx',
39 'https://clients2.googleusercontent.com/crx',
40];
29 41
30const log = getLogger('hardenSession'); 42const log = getLogger('hardenSession');
31 43