Split configuration into low and high traffic files
Also, we're now handling config ourselves instead of using electron-config and config dependencies.
This commit is contained in:
parent
f59ec92fef
commit
998c35dcb3
9 changed files with 112 additions and 103 deletions
58
app/base_config.js
Normal file
58
app/base_config.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const _ = require('lodash');
|
||||||
|
|
||||||
|
const ENCODING = 'utf8';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
start,
|
||||||
|
};
|
||||||
|
|
||||||
|
function start(name, targetPath) {
|
||||||
|
let cachedValue = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const text = fs.readFileSync(targetPath, ENCODING);
|
||||||
|
cachedValue = JSON.parse(text);
|
||||||
|
console.log(`config/get: Successfully read ${name} config file`);
|
||||||
|
|
||||||
|
if (!cachedValue) {
|
||||||
|
console.log(
|
||||||
|
`config/get: ${name} config value was falsy, cache is now empty object`
|
||||||
|
);
|
||||||
|
cachedValue = Object.create(null);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (error.code !== 'ENOENT') {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`config/get: Did not find ${name} config file, cache is now empty object`
|
||||||
|
);
|
||||||
|
cachedValue = Object.create(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(keyPath) {
|
||||||
|
return _.get(cachedValue, keyPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function set(keyPath, value) {
|
||||||
|
_.set(cachedValue, keyPath, value);
|
||||||
|
console.log(`config/set: Saving ${name} config to disk`);
|
||||||
|
const text = JSON.stringify(cachedValue, null, ' ');
|
||||||
|
fs.writeFileSync(targetPath, text, ENCODING);
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove() {
|
||||||
|
console.log(`config/remove: Deleting ${name} config from disk`);
|
||||||
|
fs.unlinkSync(targetPath);
|
||||||
|
cachedValue = Object.create(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
set,
|
||||||
|
get,
|
||||||
|
remove,
|
||||||
|
};
|
||||||
|
}
|
12
app/ephemeral_config.js
Normal file
12
app/ephemeral_config.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const { app } = require('electron');
|
||||||
|
|
||||||
|
const { start } = require('./base_config');
|
||||||
|
|
||||||
|
const userDataPath = app.getPath('userData');
|
||||||
|
const targetPath = path.join(userDataPath, 'ephemeral.json');
|
||||||
|
|
||||||
|
const ephemeralConfig = start('ephemeral', targetPath);
|
||||||
|
|
||||||
|
module.exports = ephemeralConfig;
|
|
@ -1,62 +0,0 @@
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const crypto = require('crypto');
|
|
||||||
|
|
||||||
const { app } = require('electron');
|
|
||||||
|
|
||||||
const ENCODING = 'utf8';
|
|
||||||
const userDataPath = app.getPath('userData');
|
|
||||||
const targetPath = path.join(userDataPath, 'key.txt');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
get,
|
|
||||||
set,
|
|
||||||
initialize,
|
|
||||||
remove,
|
|
||||||
};
|
|
||||||
|
|
||||||
function get() {
|
|
||||||
try {
|
|
||||||
const key = fs.readFileSync(targetPath, ENCODING);
|
|
||||||
console.log('key/get: Successfully read key file');
|
|
||||||
return key;
|
|
||||||
} catch (error) {
|
|
||||||
if (error.code === 'ENOENT') {
|
|
||||||
console.log('key/get: Could not find key file, returning null');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function set(key) {
|
|
||||||
console.log('key/set: Saving key to disk');
|
|
||||||
fs.writeFileSync(targetPath, key, ENCODING);
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove() {
|
|
||||||
console.log('key/remove: Deleting key from disk');
|
|
||||||
fs.unlinkSync(targetPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initialize({ userConfig }) {
|
|
||||||
const keyFromConfig = userConfig.get('key');
|
|
||||||
const keyFromStore = get();
|
|
||||||
|
|
||||||
let key = keyFromStore || keyFromConfig;
|
|
||||||
if (!key) {
|
|
||||||
console.log(
|
|
||||||
'key/initialize: Generating new encryption key, since we did not find it on disk'
|
|
||||||
);
|
|
||||||
// https://www.zetetic.net/sqlcipher/sqlcipher-api/#key
|
|
||||||
key = crypto.randomBytes(32).toString('hex');
|
|
||||||
set(key);
|
|
||||||
} else if (keyFromConfig) {
|
|
||||||
set(key);
|
|
||||||
console.log('key/initialize: Removing key from config.json');
|
|
||||||
userConfig.delete('key');
|
|
||||||
}
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
|
@ -1,6 +1,7 @@
|
||||||
const electron = require('electron');
|
const electron = require('electron');
|
||||||
const sql = require('./sql');
|
const sql = require('./sql');
|
||||||
const { remove } = require('./key_management');
|
const { remove: removeUserConfig } = require('./user_config');
|
||||||
|
const { remove: removeEphemeralConfig } = require('./ephemeral_config');
|
||||||
|
|
||||||
const { ipcMain } = electron;
|
const { ipcMain } = electron;
|
||||||
|
|
||||||
|
@ -41,7 +42,8 @@ function initialize() {
|
||||||
|
|
||||||
ipcMain.on(ERASE_SQL_KEY, async event => {
|
ipcMain.on(ERASE_SQL_KEY, async event => {
|
||||||
try {
|
try {
|
||||||
remove();
|
removeUserConfig();
|
||||||
|
removeEphemeralConfig();
|
||||||
event.sender.send(`${ERASE_SQL_KEY}-done`);
|
event.sender.send(`${ERASE_SQL_KEY}-done`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorForDisplay = error && error.stack ? error.stack : error;
|
const errorForDisplay = error && error.stack ? error.stack : error;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const { app } = require('electron');
|
const { app } = require('electron');
|
||||||
const ElectronConfig = require('electron-config');
|
|
||||||
|
|
||||||
|
const { start } = require('./base_config');
|
||||||
const config = require('./config');
|
const config = require('./config');
|
||||||
|
|
||||||
// use a separate data directory for development
|
// Use separate data directory for development
|
||||||
if (config.has('storageProfile')) {
|
if (config.has('storageProfile')) {
|
||||||
const userData = path.join(
|
const userData = path.join(
|
||||||
app.getPath('appData'),
|
app.getPath('appData'),
|
||||||
|
@ -17,7 +17,9 @@ if (config.has('storageProfile')) {
|
||||||
|
|
||||||
console.log(`userData: ${app.getPath('userData')}`);
|
console.log(`userData: ${app.getPath('userData')}`);
|
||||||
|
|
||||||
// this needs to be below our update to the appData path
|
const userDataPath = app.getPath('userData');
|
||||||
const userConfig = new ElectronConfig();
|
const targetPath = path.join(userDataPath, 'config.json');
|
||||||
|
|
||||||
|
const userConfig = start('user', targetPath);
|
||||||
|
|
||||||
module.exports = userConfig;
|
module.exports = userConfig;
|
||||||
|
|
|
@ -34,11 +34,15 @@
|
||||||
this.render();
|
this.render();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
await Database.clear();
|
||||||
await Database.close();
|
await Database.close();
|
||||||
window.log.info('All database connections closed. Starting delete.');
|
window.log.info(
|
||||||
|
'All database connections closed. Starting database drop.'
|
||||||
|
);
|
||||||
|
await Database.drop();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.log.error(
|
||||||
'Something went wrong closing all database connections.'
|
'Something went wrong deleting IndexedDB data then dropping database.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,15 +50,14 @@
|
||||||
},
|
},
|
||||||
async clearAllData() {
|
async clearAllData() {
|
||||||
try {
|
try {
|
||||||
await Promise.all([
|
await Logs.deleteAll();
|
||||||
Logs.deleteAll(),
|
|
||||||
Database.drop(),
|
|
||||||
window.Signal.Data.removeAll(),
|
|
||||||
window.Signal.Data.removeOtherData(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
// SQLCipher
|
||||||
|
await window.Signal.Data.removeAll();
|
||||||
await window.Signal.Data.close();
|
await window.Signal.Data.close();
|
||||||
await window.Signal.Data.removeDB();
|
await window.Signal.Data.removeDB();
|
||||||
|
|
||||||
|
await window.Signal.Data.removeOtherData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
window.log.error(
|
window.log.error(
|
||||||
'Something went wrong deleting all data:',
|
'Something went wrong deleting all data:',
|
||||||
|
|
24
main.js
24
main.js
|
@ -4,6 +4,7 @@ const path = require('path');
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const pify = require('pify');
|
const pify = require('pify');
|
||||||
|
@ -62,7 +63,7 @@ const attachments = require('./app/attachments');
|
||||||
const attachmentChannel = require('./app/attachment_channel');
|
const attachmentChannel = require('./app/attachment_channel');
|
||||||
const autoUpdate = require('./app/auto_update');
|
const autoUpdate = require('./app/auto_update');
|
||||||
const createTrayIcon = require('./app/tray_icon');
|
const createTrayIcon = require('./app/tray_icon');
|
||||||
const keyManagement = require('./app/key_management');
|
const ephemeralConfig = require('./app/ephemeral_config');
|
||||||
const logging = require('./app/logging');
|
const logging = require('./app/logging');
|
||||||
const sql = require('./app/sql');
|
const sql = require('./app/sql');
|
||||||
const sqlChannels = require('./app/sql_channel');
|
const sqlChannels = require('./app/sql_channel');
|
||||||
|
@ -115,7 +116,14 @@ if (!process.mas) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let windowConfig = userConfig.get('window');
|
const windowFromUserConfig = userConfig.get('window');
|
||||||
|
const windowFromEphemeral = ephemeralConfig.get('window');
|
||||||
|
let windowConfig = windowFromEphemeral || windowFromUserConfig;
|
||||||
|
if (windowFromUserConfig) {
|
||||||
|
userConfig.set('window', null);
|
||||||
|
ephemeralConfig.set('window', windowConfig);
|
||||||
|
}
|
||||||
|
|
||||||
const loadLocale = require('./app/locale').load;
|
const loadLocale = require('./app/locale').load;
|
||||||
|
|
||||||
// Both of these will be set after app fires the 'ready' event
|
// Both of these will be set after app fires the 'ready' event
|
||||||
|
@ -285,7 +293,7 @@ function createWindow() {
|
||||||
'Updating BrowserWindow config: %s',
|
'Updating BrowserWindow config: %s',
|
||||||
JSON.stringify(windowConfig)
|
JSON.stringify(windowConfig)
|
||||||
);
|
);
|
||||||
userConfig.set('window', windowConfig);
|
ephemeralConfig.set('window', windowConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
const debouncedCaptureStats = _.debounce(captureAndSaveWindowStats, 500);
|
const debouncedCaptureStats = _.debounce(captureAndSaveWindowStats, 500);
|
||||||
|
@ -619,7 +627,15 @@ app.on('ready', async () => {
|
||||||
locale = loadLocale({ appLocale, logger });
|
locale = loadLocale({ appLocale, logger });
|
||||||
}
|
}
|
||||||
|
|
||||||
const key = keyManagement.initialize({ userConfig });
|
let key = userConfig.get('key');
|
||||||
|
if (!key) {
|
||||||
|
console.log(
|
||||||
|
'key/initialize: Generating new encryption key, since we did not find it on disk'
|
||||||
|
);
|
||||||
|
// https://www.zetetic.net/sqlcipher/sqlcipher-api/#key
|
||||||
|
key = crypto.randomBytes(32).toString('hex');
|
||||||
|
userConfig.set('key', key);
|
||||||
|
}
|
||||||
await sql.initialize({ configDir: userDataPath, key });
|
await sql.initialize({ configDir: userDataPath, key });
|
||||||
await sqlChannels.initialize();
|
await sqlChannels.initialize();
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
"styleguide": "styleguidist server"
|
"styleguide": "styleguidist server"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#ed4f4d179ac010c6347b291cbd4c2ebe5c773741",
|
||||||
"@sindresorhus/is": "^0.8.0",
|
"@sindresorhus/is": "^0.8.0",
|
||||||
"archiver": "^2.1.1",
|
"archiver": "^2.1.1",
|
||||||
"backbone": "^1.3.3",
|
"backbone": "^1.3.3",
|
||||||
|
@ -49,10 +50,8 @@
|
||||||
"bunyan": "^1.8.12",
|
"bunyan": "^1.8.12",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"config": "^1.28.1",
|
"config": "^1.28.1",
|
||||||
"electron-config": "^1.0.0",
|
|
||||||
"electron-editor-context-menu": "^1.1.1",
|
"electron-editor-context-menu": "^1.1.1",
|
||||||
"electron-is-dev": "^0.3.0",
|
"electron-is-dev": "^0.3.0",
|
||||||
"@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#ed4f4d179ac010c6347b291cbd4c2ebe5c773741",
|
|
||||||
"electron-unhandled": "https://github.com/scottnonnenberg-signal/electron-unhandled.git#7496187472aa561d39fcd4c843a54ffbef0a388c",
|
"electron-unhandled": "https://github.com/scottnonnenberg-signal/electron-unhandled.git#7496187472aa561d39fcd4c843a54ffbef0a388c",
|
||||||
"electron-updater": "^2.21.10",
|
"electron-updater": "^2.21.10",
|
||||||
"emoji-datasource": "4.0.0",
|
"emoji-datasource": "4.0.0",
|
||||||
|
|
21
yarn.lock
21
yarn.lock
|
@ -1647,15 +1647,6 @@ concat-stream@^1.5.0:
|
||||||
readable-stream "^2.2.2"
|
readable-stream "^2.2.2"
|
||||||
typedarray "^0.0.6"
|
typedarray "^0.0.6"
|
||||||
|
|
||||||
conf@^1.0.0:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/conf/-/conf-1.1.1.tgz#238d0a3090ac4916ed2d40c7e81d7a11667bc7ba"
|
|
||||||
dependencies:
|
|
||||||
dot-prop "^4.1.0"
|
|
||||||
env-paths "^1.0.0"
|
|
||||||
make-dir "^1.0.0"
|
|
||||||
pkg-up "^2.0.0"
|
|
||||||
|
|
||||||
config@^1.28.1:
|
config@^1.28.1:
|
||||||
version "1.28.1"
|
version "1.28.1"
|
||||||
resolved "https://registry.yarnpkg.com/config/-/config-1.28.1.tgz#7625d2a1e4c90f131d8a73347982d93c3873282d"
|
resolved "https://registry.yarnpkg.com/config/-/config-1.28.1.tgz#7625d2a1e4c90f131d8a73347982d93c3873282d"
|
||||||
|
@ -2423,12 +2414,6 @@ electron-chromedriver@~1.8.0:
|
||||||
electron-download "^4.1.0"
|
electron-download "^4.1.0"
|
||||||
extract-zip "^1.6.5"
|
extract-zip "^1.6.5"
|
||||||
|
|
||||||
electron-config@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/electron-config/-/electron-config-1.0.0.tgz#069d044cc794f04784ae72f12916725d3c8c39af"
|
|
||||||
dependencies:
|
|
||||||
conf "^1.0.0"
|
|
||||||
|
|
||||||
electron-download-tf@4.3.4:
|
electron-download-tf@4.3.4:
|
||||||
version "4.3.4"
|
version "4.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/electron-download-tf/-/electron-download-tf-4.3.4.tgz#b03740b2885aa2ad3f8784fae74df427f66d5165"
|
resolved "https://registry.yarnpkg.com/electron-download-tf/-/electron-download-tf-4.3.4.tgz#b03740b2885aa2ad3f8784fae74df427f66d5165"
|
||||||
|
@ -6428,12 +6413,6 @@ pkg-dir@^2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
find-up "^2.1.0"
|
find-up "^2.1.0"
|
||||||
|
|
||||||
pkg-up@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
|
|
||||||
dependencies:
|
|
||||||
find-up "^2.1.0"
|
|
||||||
|
|
||||||
pkginfo@0.4.0:
|
pkginfo@0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65"
|
resolved "https://registry.yarnpkg.com/pkginfo/-/pkginfo-0.4.0.tgz#349dbb7ffd38081fcadc0853df687f0c7744cd65"
|
||||||
|
|
Loading…
Add table
Reference in a new issue