Ensure proper file permissions on startup
Co-authored-by: Scott Nonnenberg <scott@signal.org>
This commit is contained in:
parent
6b56dd4ce0
commit
8d9ccd3c0a
10 changed files with 289 additions and 24 deletions
59
main.js
59
main.js
|
@ -3,9 +3,12 @@
|
|||
const path = require('path');
|
||||
const url = require('url');
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const fs = require('fs-extra');
|
||||
const crypto = require('crypto');
|
||||
const qs = require('qs');
|
||||
const normalizePath = require('normalize-path');
|
||||
const fg = require('fast-glob');
|
||||
const PQueue = require('p-queue').default;
|
||||
|
||||
const _ = require('lodash');
|
||||
const pify = require('pify');
|
||||
|
@ -16,6 +19,10 @@ const GlobalErrors = require('./app/global_errors');
|
|||
|
||||
GlobalErrors.addHandler();
|
||||
|
||||
// Set umask early on in the process lifecycle to ensure file permissions are
|
||||
// set such that only we have read access to our files
|
||||
process.umask(0o077);
|
||||
|
||||
const getRealPath = pify(fs.realpath);
|
||||
const {
|
||||
app,
|
||||
|
@ -863,6 +870,8 @@ app.on('ready', async () => {
|
|||
}
|
||||
|
||||
setupMenu();
|
||||
|
||||
ensureFilePermissions(['config.json', 'sql/db.sqlite']);
|
||||
});
|
||||
|
||||
function setupMenu(options) {
|
||||
|
@ -1195,3 +1204,51 @@ ipc.on('install-sticker-pack', (_event, packId, packKeyHex) => {
|
|||
const packKey = Buffer.from(packKeyHex, 'hex').toString('base64');
|
||||
mainWindow.webContents.send('install-sticker-pack', { packId, packKey });
|
||||
});
|
||||
|
||||
ipc.on('ensure-file-permissions', async event => {
|
||||
await ensureFilePermissions();
|
||||
event.reply('ensure-file-permissions-done');
|
||||
});
|
||||
|
||||
/**
|
||||
* Ensure files in the user's data directory have the proper permissions.
|
||||
* Optionally takes an array of file paths to exclusively affect.
|
||||
*
|
||||
* @param {string[]} [onlyFiles] - Only ensure permissions on these given files
|
||||
*/
|
||||
async function ensureFilePermissions(onlyFiles) {
|
||||
console.log('Begin ensuring permissions');
|
||||
|
||||
const start = Date.now();
|
||||
const userDataPath = await getRealPath(app.getPath('userData'));
|
||||
// fast-glob uses `/` for all platforms
|
||||
const userDataGlob = normalizePath(path.join(userDataPath, '**', '*'));
|
||||
|
||||
// Determine files to touch
|
||||
const files = onlyFiles
|
||||
? onlyFiles.map(f => path.join(userDataPath, f))
|
||||
: await fg(userDataGlob, {
|
||||
markDirectories: true,
|
||||
onlyFiles: false,
|
||||
ignore: ['**/Singleton*'],
|
||||
});
|
||||
|
||||
console.log(`Ensuring file permissions for ${files.length} files`);
|
||||
|
||||
// Touch each file in a queue
|
||||
const q = new PQueue({ concurrency: 5 });
|
||||
q.addAll(
|
||||
files.map(f => async () => {
|
||||
const isDir = f.endsWith('/');
|
||||
try {
|
||||
await fs.chmod(path.normalize(f), isDir ? 0o700 : 0o600);
|
||||
} catch (error) {
|
||||
console.error('ensureFilePermissions: Error from chmod', error.message);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
await q.onEmpty();
|
||||
|
||||
console.log(`Finish ensuring permissions in ${Date.now() - start}ms`);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue