Fix windows fast-glob usage in lint-deps test task
* Introduce normalize-path wherever we use fastGlob * CI: Update yarn version; install yarn via npm on windows * Add more logging to Grunt file spectron usage * Lock core.js to what it was resolving to before: 2.4.1 * test/index.html: Remove nonexistent test file * test/index.html: Remove missing registration.js * preload.js: Introduce client-side logging for load failures * Gruntfile: Introduce better debuggability if prod test fails * Reintroduce glob for searches inside asar
This commit is contained in:
parent
455c7449e3
commit
1726e1b77a
11 changed files with 497 additions and 440 deletions
|
@ -5,7 +5,7 @@ os:
|
||||||
- linux
|
- linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
before_install:
|
before_install:
|
||||||
- npm install -g yarn@1.17.3
|
- npm install -g yarn@1.22.0
|
||||||
install:
|
install:
|
||||||
- yarn install --frozen-lockfile
|
- yarn install --frozen-lockfile
|
||||||
script:
|
script:
|
||||||
|
|
53
Gruntfile.js
53
Gruntfile.js
|
@ -1,4 +1,4 @@
|
||||||
const path = require('path');
|
const { join } = require('path');
|
||||||
const packageJson = require('./package.json');
|
const packageJson = require('./package.json');
|
||||||
const importOnce = require('node-sass-import-once');
|
const importOnce = require('node-sass-import-once');
|
||||||
const rimraf = require('rimraf');
|
const rimraf = require('rimraf');
|
||||||
|
@ -223,9 +223,13 @@ module.exports = grunt => {
|
||||||
const { Application } = spectron;
|
const { Application } = spectron;
|
||||||
const electronBinary =
|
const electronBinary =
|
||||||
process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
||||||
|
|
||||||
|
const path = join(__dirname, 'node_modules', '.bin', electronBinary);
|
||||||
|
const args = [join(__dirname, 'main.js')];
|
||||||
|
console.log('Starting path', path, 'with args', args);
|
||||||
const app = new Application({
|
const app = new Application({
|
||||||
path: path.join(__dirname, 'node_modules', '.bin', electronBinary),
|
path,
|
||||||
args: [path.join(__dirname, 'main.js')],
|
args,
|
||||||
env: {
|
env: {
|
||||||
NODE_ENV: environment,
|
NODE_ENV: environment,
|
||||||
},
|
},
|
||||||
|
@ -239,19 +243,24 @@ module.exports = grunt => {
|
||||||
|
|
||||||
app
|
app
|
||||||
.start()
|
.start()
|
||||||
.then(() =>
|
.then(() => {
|
||||||
app.client.waitUntil(
|
console.log('App started. Now waiting for test results...');
|
||||||
|
return app.client.waitUntil(
|
||||||
() =>
|
() =>
|
||||||
app.client
|
app.client
|
||||||
.execute(getMochaResults)
|
.execute(getMochaResults)
|
||||||
.then(data => Boolean(data.value)),
|
.then(data => Boolean(data.value)),
|
||||||
25000,
|
25000,
|
||||||
'Expected to find window.mochaResults set!'
|
'Expected to find window.mochaResults set!'
|
||||||
)
|
);
|
||||||
)
|
})
|
||||||
.then(() => app.client.execute(getMochaResults))
|
.then(() => app.client.execute(getMochaResults))
|
||||||
.then(data => {
|
.then(data => {
|
||||||
const results = data.value;
|
const results = data.value;
|
||||||
|
if (!results) {
|
||||||
|
failure = () => grunt.fail.fatal("Couldn't extract test results.");
|
||||||
|
return app.client.log('browser');
|
||||||
|
}
|
||||||
if (results.failures > 0) {
|
if (results.failures > 0) {
|
||||||
console.error(results.reports);
|
console.error(results.reports);
|
||||||
failure = () =>
|
failure = () =>
|
||||||
|
@ -368,14 +377,23 @@ module.exports = grunt => {
|
||||||
// A simple test to verify a visible window is opened with a title
|
// A simple test to verify a visible window is opened with a title
|
||||||
const { Application } = spectron;
|
const { Application } = spectron;
|
||||||
|
|
||||||
|
const path = [dir, config.exe].join('/');
|
||||||
|
console.log('Starting path', path);
|
||||||
const app = new Application({
|
const app = new Application({
|
||||||
path: [dir, config.exe].join('/'),
|
path,
|
||||||
requireName: 'unused',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app
|
const sleep = millis =>
|
||||||
.start()
|
new Promise(resolve => setTimeout(resolve, millis));
|
||||||
.then(() => app.client.getWindowCount())
|
|
||||||
|
Promise.race([app.start(), sleep(15000)])
|
||||||
|
.then(() => {
|
||||||
|
if (!app.isRunning()) {
|
||||||
|
throw new Error('Application failed to start');
|
||||||
|
}
|
||||||
|
|
||||||
|
return app.client.getWindowCount();
|
||||||
|
})
|
||||||
.then(count => {
|
.then(count => {
|
||||||
assert.equal(count, 1);
|
assert.equal(count, 1);
|
||||||
console.log('window opened');
|
console.log('window opened');
|
||||||
|
@ -405,6 +423,17 @@ module.exports = grunt => {
|
||||||
grunt.fail.fatal(`Test failed: ${error.message} ${error.stack}`);
|
grunt.fail.fatal(`Test failed: ${error.message} ${error.stack}`);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
.catch(error => {
|
||||||
|
console.log('Main process logs:');
|
||||||
|
app.client.getMainProcessLogs().then(logs => {
|
||||||
|
logs.forEach(log => {
|
||||||
|
console.log(log);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Test failed!
|
||||||
|
grunt.fail.fatal(`Failure! ${error.message} ${error.stack}`);
|
||||||
|
});
|
||||||
|
})
|
||||||
.then(done);
|
.then(done);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,9 +3,12 @@ const path = require('path');
|
||||||
const { app, dialog, shell, remote } = require('electron');
|
const { app, dialog, shell, remote } = require('electron');
|
||||||
|
|
||||||
const fastGlob = require('fast-glob');
|
const fastGlob = require('fast-glob');
|
||||||
|
const glob = require('glob');
|
||||||
|
const pify = require('pify');
|
||||||
const fse = require('fs-extra');
|
const fse = require('fs-extra');
|
||||||
const toArrayBuffer = require('to-arraybuffer');
|
const toArrayBuffer = require('to-arraybuffer');
|
||||||
const { map, isArrayBuffer, isString } = require('lodash');
|
const { map, isArrayBuffer, isString } = require('lodash');
|
||||||
|
const normalizePath = require('normalize-path');
|
||||||
const sanitizeFilename = require('sanitize-filename');
|
const sanitizeFilename = require('sanitize-filename');
|
||||||
const getGuid = require('uuid/v4');
|
const getGuid = require('uuid/v4');
|
||||||
|
|
||||||
|
@ -25,7 +28,7 @@ const DRAFT_PATH = 'drafts.noindex';
|
||||||
|
|
||||||
exports.getAllAttachments = async userDataPath => {
|
exports.getAllAttachments = async userDataPath => {
|
||||||
const dir = exports.getPath(userDataPath);
|
const dir = exports.getPath(userDataPath);
|
||||||
const pattern = path.join(dir, '**', '*');
|
const pattern = normalizePath(path.join(dir, '**', '*'));
|
||||||
|
|
||||||
const files = await fastGlob(pattern, { onlyFiles: true });
|
const files = await fastGlob(pattern, { onlyFiles: true });
|
||||||
return map(files, file => path.relative(dir, file));
|
return map(files, file => path.relative(dir, file));
|
||||||
|
@ -33,7 +36,7 @@ exports.getAllAttachments = async userDataPath => {
|
||||||
|
|
||||||
exports.getAllStickers = async userDataPath => {
|
exports.getAllStickers = async userDataPath => {
|
||||||
const dir = exports.getStickersPath(userDataPath);
|
const dir = exports.getStickersPath(userDataPath);
|
||||||
const pattern = path.join(dir, '**', '*');
|
const pattern = normalizePath(path.join(dir, '**', '*'));
|
||||||
|
|
||||||
const files = await fastGlob(pattern, { onlyFiles: true });
|
const files = await fastGlob(pattern, { onlyFiles: true });
|
||||||
return map(files, file => path.relative(dir, file));
|
return map(files, file => path.relative(dir, file));
|
||||||
|
@ -41,7 +44,7 @@ exports.getAllStickers = async userDataPath => {
|
||||||
|
|
||||||
exports.getAllDraftAttachments = async userDataPath => {
|
exports.getAllDraftAttachments = async userDataPath => {
|
||||||
const dir = exports.getDraftPath(userDataPath);
|
const dir = exports.getDraftPath(userDataPath);
|
||||||
const pattern = path.join(dir, '**', '*');
|
const pattern = normalizePath(path.join(dir, '**', '*'));
|
||||||
|
|
||||||
const files = await fastGlob(pattern, { onlyFiles: true });
|
const files = await fastGlob(pattern, { onlyFiles: true });
|
||||||
return map(files, file => path.relative(dir, file));
|
return map(files, file => path.relative(dir, file));
|
||||||
|
@ -51,7 +54,9 @@ exports.getBuiltInImages = async () => {
|
||||||
const dir = path.join(__dirname, '../images');
|
const dir = path.join(__dirname, '../images');
|
||||||
const pattern = path.join(dir, '**', '*.svg');
|
const pattern = path.join(dir, '**', '*.svg');
|
||||||
|
|
||||||
const files = await fastGlob(pattern, { onlyFiles: true });
|
// Note: we cannot use fast-glob here because, inside of .asar files, readdir will not
|
||||||
|
// honor the withFileTypes flag: https://github.com/electron/electron/issues/19074
|
||||||
|
const files = await pify(glob)(pattern, { nodir: true });
|
||||||
return map(files, file => path.relative(dir, file));
|
return map(files, file => path.relative(dir, file));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ install:
|
||||||
- systeminfo | findstr /C:"OS"
|
- systeminfo | findstr /C:"OS"
|
||||||
- set PATH=C:\Ruby23-x64\bin;%PATH%
|
- set PATH=C:\Ruby23-x64\bin;%PATH%
|
||||||
- ps: Install-Product node 12.13.0 x64
|
- ps: Install-Product node 12.13.0 x64
|
||||||
- ps: .\build\install-yarn.ps1
|
- npm install -g yarn@1.22.0
|
||||||
- yarn install --frozen-lockfile
|
- yarn install --frozen-lockfile
|
||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
# via https://gist.github.com/FeodorFitsner/1056703ec92bd6a3012c15fe78a5e162
|
|
||||||
|
|
||||||
Write-Host "Installing Yarn..." -ForegroundColor Cyan
|
|
||||||
|
|
||||||
Write-Host "Downloading..."
|
|
||||||
$msiPath = "$env:TEMP\yarn.msi"
|
|
||||||
(New-Object Net.WebClient).DownloadFile('https://github.com/yarnpkg/yarn/releases/download/v1.17.3/yarn-1.17.3.msi', $msiPath)
|
|
||||||
|
|
||||||
Write-Host "Installing..."
|
|
||||||
cmd /c start /wait msiexec /i "$msiPath" /quiet
|
|
||||||
|
|
||||||
Write-Host "Yarn installed" -ForegroundColor Green
|
|
|
@ -88,6 +88,7 @@
|
||||||
"form-data": "2.3.2",
|
"form-data": "2.3.2",
|
||||||
"fs-extra": "5.0.0",
|
"fs-extra": "5.0.0",
|
||||||
"fuse.js": "3.4.4",
|
"fuse.js": "3.4.4",
|
||||||
|
"glob": "7.1.6",
|
||||||
"google-libphonenumber": "3.2.6",
|
"google-libphonenumber": "3.2.6",
|
||||||
"got": "8.2.0",
|
"got": "8.2.0",
|
||||||
"he": "1.2.0",
|
"he": "1.2.0",
|
||||||
|
@ -173,6 +174,7 @@
|
||||||
"@types/memoizee": "0.4.2",
|
"@types/memoizee": "0.4.2",
|
||||||
"@types/mkdirp": "0.5.2",
|
"@types/mkdirp": "0.5.2",
|
||||||
"@types/mocha": "5.0.0",
|
"@types/mocha": "5.0.0",
|
||||||
|
"@types/normalize-path": "3.0.0",
|
||||||
"@types/pify": "3.0.2",
|
"@types/pify": "3.0.2",
|
||||||
"@types/qs": "6.5.1",
|
"@types/qs": "6.5.1",
|
||||||
"@types/react": "16.8.5",
|
"@types/react": "16.8.5",
|
||||||
|
@ -200,7 +202,7 @@
|
||||||
"babel-plugin-lodash": "3.3.4",
|
"babel-plugin-lodash": "3.3.4",
|
||||||
"bower": "1.8.2",
|
"bower": "1.8.2",
|
||||||
"chai": "4.1.2",
|
"chai": "4.1.2",
|
||||||
"core-js": "2.4.0",
|
"core-js": "2.4.1",
|
||||||
"cross-env": "5.2.0",
|
"cross-env": "5.2.0",
|
||||||
"css-loader": "3.2.0",
|
"css-loader": "3.2.0",
|
||||||
"dashdash": "1.14.1",
|
"dashdash": "1.14.1",
|
||||||
|
|
801
preload.js
801
preload.js
|
@ -1,408 +1,419 @@
|
||||||
/* global Whisper, window */
|
/* global Whisper, window */
|
||||||
|
|
||||||
const electron = require('electron');
|
/* eslint-disable global-require, no-inner-declarations */
|
||||||
const semver = require('semver');
|
|
||||||
const curve = require('curve25519-n');
|
|
||||||
const { installGetter, installSetter } = require('./preload_utils');
|
|
||||||
|
|
||||||
const { deferredToPromise } = require('./js/modules/deferred_to_promise');
|
try {
|
||||||
|
const electron = require('electron');
|
||||||
|
const semver = require('semver');
|
||||||
|
const curve = require('curve25519-n');
|
||||||
|
const { installGetter, installSetter } = require('./preload_utils');
|
||||||
|
|
||||||
const { remote } = electron;
|
const { deferredToPromise } = require('./js/modules/deferred_to_promise');
|
||||||
const { app } = remote;
|
|
||||||
const { systemPreferences } = remote.require('electron');
|
|
||||||
|
|
||||||
window.PROTO_ROOT = 'protos';
|
const { remote } = electron;
|
||||||
const config = require('url').parse(window.location.toString(), true).query;
|
const { app } = remote;
|
||||||
|
const { systemPreferences } = remote.require('electron');
|
||||||
|
|
||||||
let title = config.name;
|
window.PROTO_ROOT = 'protos';
|
||||||
if (config.environment !== 'production') {
|
const config = require('url').parse(window.location.toString(), true).query;
|
||||||
title += ` - ${config.environment}`;
|
|
||||||
}
|
|
||||||
if (config.appInstance) {
|
|
||||||
title += ` - ${config.appInstance}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.platform = process.platform;
|
let title = config.name;
|
||||||
window.getTitle = () => title;
|
if (config.environment !== 'production') {
|
||||||
window.getEnvironment = () => config.environment;
|
title += ` - ${config.environment}`;
|
||||||
window.getAppInstance = () => config.appInstance;
|
|
||||||
window.getVersion = () => config.version;
|
|
||||||
window.isImportMode = () => config.importMode;
|
|
||||||
window.getExpiration = () => config.buildExpiration;
|
|
||||||
window.getNodeVersion = () => config.node_version;
|
|
||||||
window.getHostName = () => config.hostname;
|
|
||||||
window.getServerTrustRoot = () => config.serverTrustRoot;
|
|
||||||
window.isBehindProxy = () => Boolean(config.proxyUrl);
|
|
||||||
|
|
||||||
function setSystemTheme() {
|
|
||||||
window.systemTheme = systemPreferences.isDarkMode() ? 'dark' : 'light';
|
|
||||||
}
|
|
||||||
|
|
||||||
setSystemTheme();
|
|
||||||
|
|
||||||
window.subscribeToSystemThemeChange = fn => {
|
|
||||||
if (!systemPreferences.subscribeNotification) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
systemPreferences.subscribeNotification(
|
if (config.appInstance) {
|
||||||
'AppleInterfaceThemeChangedNotification',
|
title += ` - ${config.appInstance}`;
|
||||||
() => {
|
}
|
||||||
setSystemTheme();
|
|
||||||
fn();
|
window.platform = process.platform;
|
||||||
|
window.getTitle = () => title;
|
||||||
|
window.getEnvironment = () => config.environment;
|
||||||
|
window.getAppInstance = () => config.appInstance;
|
||||||
|
window.getVersion = () => config.version;
|
||||||
|
window.isImportMode = () => config.importMode;
|
||||||
|
window.getExpiration = () => config.buildExpiration;
|
||||||
|
window.getNodeVersion = () => config.node_version;
|
||||||
|
window.getHostName = () => config.hostname;
|
||||||
|
window.getServerTrustRoot = () => config.serverTrustRoot;
|
||||||
|
window.isBehindProxy = () => Boolean(config.proxyUrl);
|
||||||
|
|
||||||
|
function setSystemTheme() {
|
||||||
|
window.systemTheme = systemPreferences.isDarkMode() ? 'dark' : 'light';
|
||||||
|
}
|
||||||
|
|
||||||
|
setSystemTheme();
|
||||||
|
|
||||||
|
window.subscribeToSystemThemeChange = fn => {
|
||||||
|
if (!systemPreferences.subscribeNotification) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
);
|
systemPreferences.subscribeNotification(
|
||||||
};
|
'AppleInterfaceThemeChangedNotification',
|
||||||
|
() => {
|
||||||
window.isBeforeVersion = (toCheck, baseVersion) => {
|
setSystemTheme();
|
||||||
try {
|
fn();
|
||||||
return semver.lt(toCheck, baseVersion);
|
|
||||||
} catch (error) {
|
|
||||||
window.log.error(
|
|
||||||
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.wrapDeferred = deferredToPromise;
|
|
||||||
|
|
||||||
const ipc = electron.ipcRenderer;
|
|
||||||
const localeMessages = ipc.sendSync('locale-data');
|
|
||||||
|
|
||||||
window.setBadgeCount = count => ipc.send('set-badge-count', count);
|
|
||||||
|
|
||||||
// We never do these in our code, so we'll prevent it everywhere
|
|
||||||
window.open = () => null;
|
|
||||||
// eslint-disable-next-line no-eval, no-multi-assign
|
|
||||||
window.eval = global.eval = () => null;
|
|
||||||
|
|
||||||
window.drawAttention = () => {
|
|
||||||
window.log.info('draw attention');
|
|
||||||
ipc.send('draw-attention');
|
|
||||||
};
|
|
||||||
window.showWindow = () => {
|
|
||||||
window.log.info('show window');
|
|
||||||
ipc.send('show-window');
|
|
||||||
};
|
|
||||||
|
|
||||||
window.setAutoHideMenuBar = autoHide =>
|
|
||||||
ipc.send('set-auto-hide-menu-bar', autoHide);
|
|
||||||
|
|
||||||
window.setMenuBarVisibility = visibility =>
|
|
||||||
ipc.send('set-menu-bar-visibility', visibility);
|
|
||||||
|
|
||||||
window.restart = () => {
|
|
||||||
window.log.info('restart');
|
|
||||||
ipc.send('restart');
|
|
||||||
};
|
|
||||||
|
|
||||||
window.closeAbout = () => ipc.send('close-about');
|
|
||||||
window.readyForUpdates = () => ipc.send('ready-for-updates');
|
|
||||||
|
|
||||||
window.updateTrayIcon = unreadCount =>
|
|
||||||
ipc.send('update-tray-icon', unreadCount);
|
|
||||||
|
|
||||||
ipc.on('set-up-with-import', () => {
|
|
||||||
Whisper.events.trigger('setupWithImport');
|
|
||||||
});
|
|
||||||
|
|
||||||
ipc.on('set-up-as-new-device', () => {
|
|
||||||
Whisper.events.trigger('setupAsNewDevice');
|
|
||||||
});
|
|
||||||
|
|
||||||
ipc.on('set-up-as-standalone', () => {
|
|
||||||
Whisper.events.trigger('setupAsStandalone');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Settings-related events
|
|
||||||
|
|
||||||
window.showSettings = () => ipc.send('show-settings');
|
|
||||||
window.showPermissionsPopup = () => ipc.send('show-permissions-popup');
|
|
||||||
|
|
||||||
ipc.on('show-keyboard-shortcuts', () => {
|
|
||||||
window.Events.showKeyboardShortcuts();
|
|
||||||
});
|
|
||||||
ipc.on('add-dark-overlay', () => {
|
|
||||||
window.Events.addDarkOverlay();
|
|
||||||
});
|
|
||||||
ipc.on('remove-dark-overlay', () => {
|
|
||||||
window.Events.removeDarkOverlay();
|
|
||||||
});
|
|
||||||
|
|
||||||
installGetter('device-name', 'getDeviceName');
|
|
||||||
|
|
||||||
installGetter('theme-setting', 'getThemeSetting');
|
|
||||||
installSetter('theme-setting', 'setThemeSetting');
|
|
||||||
installGetter('hide-menu-bar', 'getHideMenuBar');
|
|
||||||
installSetter('hide-menu-bar', 'setHideMenuBar');
|
|
||||||
|
|
||||||
installGetter('notification-setting', 'getNotificationSetting');
|
|
||||||
installSetter('notification-setting', 'setNotificationSetting');
|
|
||||||
installGetter('audio-notification', 'getAudioNotification');
|
|
||||||
installSetter('audio-notification', 'setAudioNotification');
|
|
||||||
|
|
||||||
installGetter('spell-check', 'getSpellCheck');
|
|
||||||
installSetter('spell-check', 'setSpellCheck');
|
|
||||||
|
|
||||||
window.getMediaPermissions = () =>
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
ipc.once('get-success-media-permissions', (_event, error, value) => {
|
|
||||||
if (error) {
|
|
||||||
return reject(new Error(error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolve(value);
|
|
||||||
});
|
|
||||||
ipc.send('get-media-permissions');
|
|
||||||
});
|
|
||||||
|
|
||||||
window.getBuiltInImages = () =>
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
ipc.once('get-success-built-in-images', (_event, error, value) => {
|
|
||||||
if (error) {
|
|
||||||
return reject(new Error(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve(value);
|
|
||||||
});
|
|
||||||
ipc.send('get-built-in-images');
|
|
||||||
});
|
|
||||||
|
|
||||||
installGetter('is-primary', 'isPrimary');
|
|
||||||
installGetter('sync-request', 'getSyncRequest');
|
|
||||||
installGetter('sync-time', 'getLastSyncTime');
|
|
||||||
installSetter('sync-time', 'setLastSyncTime');
|
|
||||||
|
|
||||||
ipc.on('delete-all-data', () => {
|
|
||||||
const { deleteAllData } = window.Events;
|
|
||||||
if (deleteAllData) {
|
|
||||||
deleteAllData();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ipc.on('show-sticker-pack', (_event, info) => {
|
|
||||||
const { packId, packKey } = info;
|
|
||||||
const { showStickerPack } = window.Events;
|
|
||||||
if (showStickerPack) {
|
|
||||||
showStickerPack(packId, packKey);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ipc.on('install-sticker-pack', (_event, info) => {
|
|
||||||
const { packId, packKey } = info;
|
|
||||||
const { installStickerPack } = window.Events;
|
|
||||||
if (installStickerPack) {
|
|
||||||
installStickerPack(packId, packKey);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ipc.on('get-ready-for-shutdown', async () => {
|
|
||||||
const { shutdown } = window.Events || {};
|
|
||||||
if (!shutdown) {
|
|
||||||
window.log.error('preload shutdown handler: shutdown method not found');
|
|
||||||
ipc.send('now-ready-for-shutdown');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await shutdown();
|
|
||||||
ipc.send('now-ready-for-shutdown');
|
|
||||||
} catch (error) {
|
|
||||||
ipc.send(
|
|
||||||
'now-ready-for-shutdown',
|
|
||||||
error && error.stack ? error.stack : error
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addSetupMenuItems = () => ipc.send('add-setup-menu-items');
|
|
||||||
window.removeSetupMenuItems = () => ipc.send('remove-setup-menu-items');
|
|
||||||
|
|
||||||
// We pull these dependencies in now, from here, because they have Node.js dependencies
|
|
||||||
|
|
||||||
require('./js/logging');
|
|
||||||
|
|
||||||
if (config.proxyUrl) {
|
|
||||||
window.log.info('Using provided proxy url');
|
|
||||||
}
|
|
||||||
|
|
||||||
window.nodeSetImmediate = setImmediate;
|
|
||||||
|
|
||||||
const { initialize: initializeWebAPI } = require('./js/modules/web_api');
|
|
||||||
|
|
||||||
window.WebAPI = initializeWebAPI({
|
|
||||||
url: config.serverUrl,
|
|
||||||
cdnUrl: config.cdnUrl,
|
|
||||||
certificateAuthority: config.certificateAuthority,
|
|
||||||
contentProxyUrl: config.contentProxyUrl,
|
|
||||||
proxyUrl: config.proxyUrl,
|
|
||||||
version: config.version,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Linux seems to periodically let the event loop stop, so this is a global workaround
|
|
||||||
setInterval(() => {
|
|
||||||
window.nodeSetImmediate(() => {});
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
const { autoOrientImage } = require('./js/modules/auto_orient_image');
|
|
||||||
|
|
||||||
window.autoOrientImage = autoOrientImage;
|
|
||||||
window.dataURLToBlobSync = require('blueimp-canvas-to-blob');
|
|
||||||
window.emojiData = require('emoji-datasource');
|
|
||||||
window.filesize = require('filesize');
|
|
||||||
window.libphonenumber = require('google-libphonenumber').PhoneNumberUtil.getInstance();
|
|
||||||
window.libphonenumber.PhoneNumberFormat = require('google-libphonenumber').PhoneNumberFormat;
|
|
||||||
window.loadImage = require('blueimp-load-image');
|
|
||||||
window.getGuid = require('uuid/v4');
|
|
||||||
|
|
||||||
window.React = require('react');
|
|
||||||
window.ReactDOM = require('react-dom');
|
|
||||||
window.moment = require('moment');
|
|
||||||
window.PQueue = require('p-queue').default;
|
|
||||||
|
|
||||||
const Signal = require('./js/modules/signal');
|
|
||||||
const i18n = require('./js/modules/i18n');
|
|
||||||
const Attachments = require('./app/attachments');
|
|
||||||
|
|
||||||
const { locale } = config;
|
|
||||||
window.i18n = i18n.setup(locale, localeMessages);
|
|
||||||
window.moment.updateLocale(locale, {
|
|
||||||
relativeTime: {
|
|
||||||
s: window.i18n('timestamp_s'),
|
|
||||||
m: window.i18n('timestamp_m'),
|
|
||||||
h: window.i18n('timestamp_h'),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
window.moment.locale(locale);
|
|
||||||
|
|
||||||
const userDataPath = app.getPath('userData');
|
|
||||||
window.baseAttachmentsPath = Attachments.getPath(userDataPath);
|
|
||||||
window.baseStickersPath = Attachments.getStickersPath(userDataPath);
|
|
||||||
window.baseTempPath = Attachments.getTempPath(userDataPath);
|
|
||||||
window.baseDraftPath = Attachments.getDraftPath(userDataPath);
|
|
||||||
window.Signal = Signal.setup({
|
|
||||||
Attachments,
|
|
||||||
userDataPath,
|
|
||||||
getRegionCode: () => window.storage.get('regionCode'),
|
|
||||||
logger: window.log,
|
|
||||||
});
|
|
||||||
|
|
||||||
function wrapWithPromise(fn) {
|
|
||||||
return (...args) => Promise.resolve(fn(...args));
|
|
||||||
}
|
|
||||||
function typedArrayToArrayBuffer(typedArray) {
|
|
||||||
const { buffer, byteOffset, byteLength } = typedArray;
|
|
||||||
return buffer.slice(byteOffset, byteLength + byteOffset);
|
|
||||||
}
|
|
||||||
const externalCurve = {
|
|
||||||
generateKeyPair: () => {
|
|
||||||
const { privKey, pubKey } = curve.generateKeyPair();
|
|
||||||
|
|
||||||
return {
|
|
||||||
privKey: typedArrayToArrayBuffer(privKey),
|
|
||||||
pubKey: typedArrayToArrayBuffer(pubKey),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
createKeyPair: incomingKey => {
|
|
||||||
const incomingKeyBuffer = Buffer.from(incomingKey);
|
|
||||||
const { privKey, pubKey } = curve.createKeyPair(incomingKeyBuffer);
|
|
||||||
|
|
||||||
return {
|
|
||||||
privKey: typedArrayToArrayBuffer(privKey),
|
|
||||||
pubKey: typedArrayToArrayBuffer(pubKey),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
calculateAgreement: (pubKey, privKey) => {
|
|
||||||
const pubKeyBuffer = Buffer.from(pubKey);
|
|
||||||
const privKeyBuffer = Buffer.from(privKey);
|
|
||||||
|
|
||||||
const buffer = curve.calculateAgreement(pubKeyBuffer, privKeyBuffer);
|
|
||||||
|
|
||||||
return typedArrayToArrayBuffer(buffer);
|
|
||||||
},
|
|
||||||
verifySignature: (pubKey, message, signature) => {
|
|
||||||
const pubKeyBuffer = Buffer.from(pubKey);
|
|
||||||
const messageBuffer = Buffer.from(message);
|
|
||||||
const signatureBuffer = Buffer.from(signature);
|
|
||||||
|
|
||||||
const result = curve.verifySignature(
|
|
||||||
pubKeyBuffer,
|
|
||||||
messageBuffer,
|
|
||||||
signatureBuffer
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
calculateSignature: (privKey, message) => {
|
|
||||||
const privKeyBuffer = Buffer.from(privKey);
|
|
||||||
const messageBuffer = Buffer.from(message);
|
|
||||||
|
|
||||||
const buffer = curve.calculateSignature(privKeyBuffer, messageBuffer);
|
|
||||||
|
|
||||||
return typedArrayToArrayBuffer(buffer);
|
|
||||||
},
|
|
||||||
validatePubKeyFormat: pubKey => {
|
|
||||||
const pubKeyBuffer = Buffer.from(pubKey);
|
|
||||||
|
|
||||||
return curve.validatePubKeyFormat(pubKeyBuffer);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
externalCurve.ECDHE = externalCurve.calculateAgreement;
|
|
||||||
externalCurve.Ed25519Sign = externalCurve.calculateSignature;
|
|
||||||
externalCurve.Ed25519Verify = externalCurve.verifySignature;
|
|
||||||
const externalCurveAsync = {
|
|
||||||
generateKeyPair: wrapWithPromise(externalCurve.generateKeyPair),
|
|
||||||
createKeyPair: wrapWithPromise(externalCurve.createKeyPair),
|
|
||||||
calculateAgreement: wrapWithPromise(externalCurve.calculateAgreement),
|
|
||||||
verifySignature: async (...args) => {
|
|
||||||
// The async verifySignature function has a different signature than the sync function
|
|
||||||
const verifyFailed = externalCurve.verifySignature(...args);
|
|
||||||
if (verifyFailed) {
|
|
||||||
throw new Error('Invalid signature');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
calculateSignature: wrapWithPromise(externalCurve.calculateSignature),
|
|
||||||
validatePubKeyFormat: wrapWithPromise(externalCurve.validatePubKeyFormat),
|
|
||||||
ECDHE: wrapWithPromise(externalCurve.ECDHE),
|
|
||||||
Ed25519Sign: wrapWithPromise(externalCurve.Ed25519Sign),
|
|
||||||
Ed25519Verify: wrapWithPromise(externalCurve.Ed25519Verify),
|
|
||||||
};
|
|
||||||
window.libsignal = window.libsignal || {};
|
|
||||||
window.libsignal.externalCurve = externalCurve;
|
|
||||||
window.libsignal.externalCurveAsync = externalCurveAsync;
|
|
||||||
|
|
||||||
// Pulling these in separately since they access filesystem, electron
|
|
||||||
window.Signal.Backup = require('./js/modules/backup');
|
|
||||||
window.Signal.Debug = require('./js/modules/debug');
|
|
||||||
window.Signal.Logs = require('./js/modules/logs');
|
|
||||||
|
|
||||||
// Add right-click listener for selected text and urls
|
|
||||||
const contextMenu = require('electron-context-menu');
|
|
||||||
|
|
||||||
contextMenu({
|
|
||||||
showInspectElement: false,
|
|
||||||
shouldShowMenu: (event, params) =>
|
|
||||||
Boolean(
|
|
||||||
!params.isEditable &&
|
|
||||||
params.mediaType === 'none' &&
|
|
||||||
(params.linkURL || params.selectionText)
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
// We pull this in last, because the native module involved appears to be sensitive to
|
|
||||||
// /tmp mounted as noexec on Linux.
|
|
||||||
require('./js/spell_check');
|
|
||||||
|
|
||||||
if (config.environment === 'test') {
|
|
||||||
/* eslint-disable global-require, import/no-extraneous-dependencies */
|
|
||||||
window.test = {
|
|
||||||
fastGlob: require('fast-glob'),
|
|
||||||
fse: require('fs-extra'),
|
|
||||||
tmp: require('tmp'),
|
|
||||||
path: require('path'),
|
|
||||||
basePath: __dirname,
|
|
||||||
attachmentsPath: window.Signal.Migrations.attachmentsPath,
|
|
||||||
};
|
};
|
||||||
/* eslint-enable global-require, import/no-extraneous-dependencies */
|
|
||||||
|
window.isBeforeVersion = (toCheck, baseVersion) => {
|
||||||
|
try {
|
||||||
|
return semver.lt(toCheck, baseVersion);
|
||||||
|
} catch (error) {
|
||||||
|
window.log.error(
|
||||||
|
`isBeforeVersion error: toCheck: ${toCheck}, baseVersion: ${baseVersion}`,
|
||||||
|
error && error.stack ? error.stack : error
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.wrapDeferred = deferredToPromise;
|
||||||
|
|
||||||
|
const ipc = electron.ipcRenderer;
|
||||||
|
const localeMessages = ipc.sendSync('locale-data');
|
||||||
|
|
||||||
|
window.setBadgeCount = count => ipc.send('set-badge-count', count);
|
||||||
|
|
||||||
|
// We never do these in our code, so we'll prevent it everywhere
|
||||||
|
window.open = () => null;
|
||||||
|
// eslint-disable-next-line no-eval, no-multi-assign
|
||||||
|
window.eval = global.eval = () => null;
|
||||||
|
|
||||||
|
window.drawAttention = () => {
|
||||||
|
window.log.info('draw attention');
|
||||||
|
ipc.send('draw-attention');
|
||||||
|
};
|
||||||
|
window.showWindow = () => {
|
||||||
|
window.log.info('show window');
|
||||||
|
ipc.send('show-window');
|
||||||
|
};
|
||||||
|
|
||||||
|
window.setAutoHideMenuBar = autoHide =>
|
||||||
|
ipc.send('set-auto-hide-menu-bar', autoHide);
|
||||||
|
|
||||||
|
window.setMenuBarVisibility = visibility =>
|
||||||
|
ipc.send('set-menu-bar-visibility', visibility);
|
||||||
|
|
||||||
|
window.restart = () => {
|
||||||
|
window.log.info('restart');
|
||||||
|
ipc.send('restart');
|
||||||
|
};
|
||||||
|
|
||||||
|
window.closeAbout = () => ipc.send('close-about');
|
||||||
|
window.readyForUpdates = () => ipc.send('ready-for-updates');
|
||||||
|
|
||||||
|
window.updateTrayIcon = unreadCount =>
|
||||||
|
ipc.send('update-tray-icon', unreadCount);
|
||||||
|
|
||||||
|
ipc.on('set-up-with-import', () => {
|
||||||
|
Whisper.events.trigger('setupWithImport');
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('set-up-as-new-device', () => {
|
||||||
|
Whisper.events.trigger('setupAsNewDevice');
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('set-up-as-standalone', () => {
|
||||||
|
Whisper.events.trigger('setupAsStandalone');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Settings-related events
|
||||||
|
|
||||||
|
window.showSettings = () => ipc.send('show-settings');
|
||||||
|
window.showPermissionsPopup = () => ipc.send('show-permissions-popup');
|
||||||
|
|
||||||
|
ipc.on('show-keyboard-shortcuts', () => {
|
||||||
|
window.Events.showKeyboardShortcuts();
|
||||||
|
});
|
||||||
|
ipc.on('add-dark-overlay', () => {
|
||||||
|
window.Events.addDarkOverlay();
|
||||||
|
});
|
||||||
|
ipc.on('remove-dark-overlay', () => {
|
||||||
|
window.Events.removeDarkOverlay();
|
||||||
|
});
|
||||||
|
|
||||||
|
installGetter('device-name', 'getDeviceName');
|
||||||
|
|
||||||
|
installGetter('theme-setting', 'getThemeSetting');
|
||||||
|
installSetter('theme-setting', 'setThemeSetting');
|
||||||
|
installGetter('hide-menu-bar', 'getHideMenuBar');
|
||||||
|
installSetter('hide-menu-bar', 'setHideMenuBar');
|
||||||
|
|
||||||
|
installGetter('notification-setting', 'getNotificationSetting');
|
||||||
|
installSetter('notification-setting', 'setNotificationSetting');
|
||||||
|
installGetter('audio-notification', 'getAudioNotification');
|
||||||
|
installSetter('audio-notification', 'setAudioNotification');
|
||||||
|
|
||||||
|
installGetter('spell-check', 'getSpellCheck');
|
||||||
|
installSetter('spell-check', 'setSpellCheck');
|
||||||
|
|
||||||
|
window.getMediaPermissions = () =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
ipc.once('get-success-media-permissions', (_event, error, value) => {
|
||||||
|
if (error) {
|
||||||
|
return reject(new Error(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve(value);
|
||||||
|
});
|
||||||
|
ipc.send('get-media-permissions');
|
||||||
|
});
|
||||||
|
|
||||||
|
window.getBuiltInImages = () =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
ipc.once('get-success-built-in-images', (_event, error, value) => {
|
||||||
|
if (error) {
|
||||||
|
return reject(new Error(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve(value);
|
||||||
|
});
|
||||||
|
ipc.send('get-built-in-images');
|
||||||
|
});
|
||||||
|
|
||||||
|
installGetter('is-primary', 'isPrimary');
|
||||||
|
installGetter('sync-request', 'getSyncRequest');
|
||||||
|
installGetter('sync-time', 'getLastSyncTime');
|
||||||
|
installSetter('sync-time', 'setLastSyncTime');
|
||||||
|
|
||||||
|
ipc.on('delete-all-data', () => {
|
||||||
|
const { deleteAllData } = window.Events;
|
||||||
|
if (deleteAllData) {
|
||||||
|
deleteAllData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('show-sticker-pack', (_event, info) => {
|
||||||
|
const { packId, packKey } = info;
|
||||||
|
const { showStickerPack } = window.Events;
|
||||||
|
if (showStickerPack) {
|
||||||
|
showStickerPack(packId, packKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('install-sticker-pack', (_event, info) => {
|
||||||
|
const { packId, packKey } = info;
|
||||||
|
const { installStickerPack } = window.Events;
|
||||||
|
if (installStickerPack) {
|
||||||
|
installStickerPack(packId, packKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('get-ready-for-shutdown', async () => {
|
||||||
|
const { shutdown } = window.Events || {};
|
||||||
|
if (!shutdown) {
|
||||||
|
window.log.error('preload shutdown handler: shutdown method not found');
|
||||||
|
ipc.send('now-ready-for-shutdown');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await shutdown();
|
||||||
|
ipc.send('now-ready-for-shutdown');
|
||||||
|
} catch (error) {
|
||||||
|
ipc.send(
|
||||||
|
'now-ready-for-shutdown',
|
||||||
|
error && error.stack ? error.stack : error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addSetupMenuItems = () => ipc.send('add-setup-menu-items');
|
||||||
|
window.removeSetupMenuItems = () => ipc.send('remove-setup-menu-items');
|
||||||
|
|
||||||
|
// We pull these dependencies in now, from here, because they have Node.js dependencies
|
||||||
|
|
||||||
|
require('./js/logging');
|
||||||
|
|
||||||
|
if (config.proxyUrl) {
|
||||||
|
window.log.info('Using provided proxy url');
|
||||||
|
}
|
||||||
|
|
||||||
|
window.nodeSetImmediate = setImmediate;
|
||||||
|
|
||||||
|
const { initialize: initializeWebAPI } = require('./js/modules/web_api');
|
||||||
|
|
||||||
|
window.WebAPI = initializeWebAPI({
|
||||||
|
url: config.serverUrl,
|
||||||
|
cdnUrl: config.cdnUrl,
|
||||||
|
certificateAuthority: config.certificateAuthority,
|
||||||
|
contentProxyUrl: config.contentProxyUrl,
|
||||||
|
proxyUrl: config.proxyUrl,
|
||||||
|
version: config.version,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Linux seems to periodically let the event loop stop, so this is a global workaround
|
||||||
|
setInterval(() => {
|
||||||
|
window.nodeSetImmediate(() => {});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
const { autoOrientImage } = require('./js/modules/auto_orient_image');
|
||||||
|
|
||||||
|
window.autoOrientImage = autoOrientImage;
|
||||||
|
window.dataURLToBlobSync = require('blueimp-canvas-to-blob');
|
||||||
|
window.emojiData = require('emoji-datasource');
|
||||||
|
window.filesize = require('filesize');
|
||||||
|
window.libphonenumber = require('google-libphonenumber').PhoneNumberUtil.getInstance();
|
||||||
|
window.libphonenumber.PhoneNumberFormat = require('google-libphonenumber').PhoneNumberFormat;
|
||||||
|
window.loadImage = require('blueimp-load-image');
|
||||||
|
window.getGuid = require('uuid/v4');
|
||||||
|
|
||||||
|
window.React = require('react');
|
||||||
|
window.ReactDOM = require('react-dom');
|
||||||
|
window.moment = require('moment');
|
||||||
|
window.PQueue = require('p-queue').default;
|
||||||
|
|
||||||
|
const Signal = require('./js/modules/signal');
|
||||||
|
const i18n = require('./js/modules/i18n');
|
||||||
|
const Attachments = require('./app/attachments');
|
||||||
|
|
||||||
|
const { locale } = config;
|
||||||
|
window.i18n = i18n.setup(locale, localeMessages);
|
||||||
|
window.moment.updateLocale(locale, {
|
||||||
|
relativeTime: {
|
||||||
|
s: window.i18n('timestamp_s'),
|
||||||
|
m: window.i18n('timestamp_m'),
|
||||||
|
h: window.i18n('timestamp_h'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
window.moment.locale(locale);
|
||||||
|
|
||||||
|
const userDataPath = app.getPath('userData');
|
||||||
|
window.baseAttachmentsPath = Attachments.getPath(userDataPath);
|
||||||
|
window.baseStickersPath = Attachments.getStickersPath(userDataPath);
|
||||||
|
window.baseTempPath = Attachments.getTempPath(userDataPath);
|
||||||
|
window.baseDraftPath = Attachments.getDraftPath(userDataPath);
|
||||||
|
window.Signal = Signal.setup({
|
||||||
|
Attachments,
|
||||||
|
userDataPath,
|
||||||
|
getRegionCode: () => window.storage.get('regionCode'),
|
||||||
|
logger: window.log,
|
||||||
|
});
|
||||||
|
|
||||||
|
function wrapWithPromise(fn) {
|
||||||
|
return (...args) => Promise.resolve(fn(...args));
|
||||||
|
}
|
||||||
|
function typedArrayToArrayBuffer(typedArray) {
|
||||||
|
const { buffer, byteOffset, byteLength } = typedArray;
|
||||||
|
return buffer.slice(byteOffset, byteLength + byteOffset);
|
||||||
|
}
|
||||||
|
const externalCurve = {
|
||||||
|
generateKeyPair: () => {
|
||||||
|
const { privKey, pubKey } = curve.generateKeyPair();
|
||||||
|
|
||||||
|
return {
|
||||||
|
privKey: typedArrayToArrayBuffer(privKey),
|
||||||
|
pubKey: typedArrayToArrayBuffer(pubKey),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
createKeyPair: incomingKey => {
|
||||||
|
const incomingKeyBuffer = Buffer.from(incomingKey);
|
||||||
|
const { privKey, pubKey } = curve.createKeyPair(incomingKeyBuffer);
|
||||||
|
|
||||||
|
return {
|
||||||
|
privKey: typedArrayToArrayBuffer(privKey),
|
||||||
|
pubKey: typedArrayToArrayBuffer(pubKey),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
calculateAgreement: (pubKey, privKey) => {
|
||||||
|
const pubKeyBuffer = Buffer.from(pubKey);
|
||||||
|
const privKeyBuffer = Buffer.from(privKey);
|
||||||
|
|
||||||
|
const buffer = curve.calculateAgreement(pubKeyBuffer, privKeyBuffer);
|
||||||
|
|
||||||
|
return typedArrayToArrayBuffer(buffer);
|
||||||
|
},
|
||||||
|
verifySignature: (pubKey, message, signature) => {
|
||||||
|
const pubKeyBuffer = Buffer.from(pubKey);
|
||||||
|
const messageBuffer = Buffer.from(message);
|
||||||
|
const signatureBuffer = Buffer.from(signature);
|
||||||
|
|
||||||
|
const result = curve.verifySignature(
|
||||||
|
pubKeyBuffer,
|
||||||
|
messageBuffer,
|
||||||
|
signatureBuffer
|
||||||
|
);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
calculateSignature: (privKey, message) => {
|
||||||
|
const privKeyBuffer = Buffer.from(privKey);
|
||||||
|
const messageBuffer = Buffer.from(message);
|
||||||
|
|
||||||
|
const buffer = curve.calculateSignature(privKeyBuffer, messageBuffer);
|
||||||
|
|
||||||
|
return typedArrayToArrayBuffer(buffer);
|
||||||
|
},
|
||||||
|
validatePubKeyFormat: pubKey => {
|
||||||
|
const pubKeyBuffer = Buffer.from(pubKey);
|
||||||
|
|
||||||
|
return curve.validatePubKeyFormat(pubKeyBuffer);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
externalCurve.ECDHE = externalCurve.calculateAgreement;
|
||||||
|
externalCurve.Ed25519Sign = externalCurve.calculateSignature;
|
||||||
|
externalCurve.Ed25519Verify = externalCurve.verifySignature;
|
||||||
|
const externalCurveAsync = {
|
||||||
|
generateKeyPair: wrapWithPromise(externalCurve.generateKeyPair),
|
||||||
|
createKeyPair: wrapWithPromise(externalCurve.createKeyPair),
|
||||||
|
calculateAgreement: wrapWithPromise(externalCurve.calculateAgreement),
|
||||||
|
verifySignature: async (...args) => {
|
||||||
|
// The async verifySignature function has a different signature than the
|
||||||
|
// sync function
|
||||||
|
const verifyFailed = externalCurve.verifySignature(...args);
|
||||||
|
if (verifyFailed) {
|
||||||
|
throw new Error('Invalid signature');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
calculateSignature: wrapWithPromise(externalCurve.calculateSignature),
|
||||||
|
validatePubKeyFormat: wrapWithPromise(externalCurve.validatePubKeyFormat),
|
||||||
|
ECDHE: wrapWithPromise(externalCurve.ECDHE),
|
||||||
|
Ed25519Sign: wrapWithPromise(externalCurve.Ed25519Sign),
|
||||||
|
Ed25519Verify: wrapWithPromise(externalCurve.Ed25519Verify),
|
||||||
|
};
|
||||||
|
window.libsignal = window.libsignal || {};
|
||||||
|
window.libsignal.externalCurve = externalCurve;
|
||||||
|
window.libsignal.externalCurveAsync = externalCurveAsync;
|
||||||
|
|
||||||
|
// Pulling these in separately since they access filesystem, electron
|
||||||
|
window.Signal.Backup = require('./js/modules/backup');
|
||||||
|
window.Signal.Debug = require('./js/modules/debug');
|
||||||
|
window.Signal.Logs = require('./js/modules/logs');
|
||||||
|
|
||||||
|
// Add right-click listener for selected text and urls
|
||||||
|
const contextMenu = require('electron-context-menu');
|
||||||
|
|
||||||
|
contextMenu({
|
||||||
|
showInspectElement: false,
|
||||||
|
shouldShowMenu: (event, params) =>
|
||||||
|
Boolean(
|
||||||
|
!params.isEditable &&
|
||||||
|
params.mediaType === 'none' &&
|
||||||
|
(params.linkURL || params.selectionText)
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
// We pull this in last, because the native module involved appears to be sensitive to
|
||||||
|
// /tmp mounted as noexec on Linux.
|
||||||
|
require('./js/spell_check');
|
||||||
|
|
||||||
|
if (config.environment === 'test') {
|
||||||
|
/* eslint-disable global-require, import/no-extraneous-dependencies */
|
||||||
|
window.test = {
|
||||||
|
fastGlob: require('fast-glob'),
|
||||||
|
normalizePath: require('normalize-path'),
|
||||||
|
fse: require('fs-extra'),
|
||||||
|
tmp: require('tmp'),
|
||||||
|
path: require('path'),
|
||||||
|
basePath: __dirname,
|
||||||
|
attachmentsPath: window.Signal.Migrations.attachmentsPath,
|
||||||
|
};
|
||||||
|
/* eslint-enable global-require, import/no-extraneous-dependencies */
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
window.log.info('preload error!', error.stack);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.log.info('preload complete');
|
||||||
|
|
|
@ -239,14 +239,23 @@ describe('Backup', () => {
|
||||||
it('exports then imports to produce the same data we started with', async function thisNeeded() {
|
it('exports then imports to produce the same data we started with', async function thisNeeded() {
|
||||||
this.timeout(6000);
|
this.timeout(6000);
|
||||||
|
|
||||||
const { attachmentsPath, fse, fastGlob, path, tmp } = window.test;
|
const {
|
||||||
|
attachmentsPath,
|
||||||
|
fse,
|
||||||
|
fastGlob,
|
||||||
|
normalizePath,
|
||||||
|
path,
|
||||||
|
tmp,
|
||||||
|
} = window.test;
|
||||||
const {
|
const {
|
||||||
upgradeMessageSchema,
|
upgradeMessageSchema,
|
||||||
loadAttachmentData,
|
loadAttachmentData,
|
||||||
} = window.Signal.Migrations;
|
} = window.Signal.Migrations;
|
||||||
|
|
||||||
const staticKeyPair = await libsignal.KeyHelper.generateIdentityKeyPair();
|
const staticKeyPair = await libsignal.KeyHelper.generateIdentityKeyPair();
|
||||||
const attachmentsPattern = path.join(attachmentsPath, '**');
|
const attachmentsPattern = normalizePath(
|
||||||
|
path.join(attachmentsPath, '**')
|
||||||
|
);
|
||||||
|
|
||||||
const OUR_NUMBER = '+12025550000';
|
const OUR_NUMBER = '+12025550000';
|
||||||
const CONTACT_ONE_NUMBER = '+12025550001';
|
const CONTACT_ONE_NUMBER = '+12025550001';
|
||||||
|
@ -528,7 +537,9 @@ describe('Backup', () => {
|
||||||
console.log(
|
console.log(
|
||||||
'Backup test: Ensure that all attachments made it to backup dir'
|
'Backup test: Ensure that all attachments made it to backup dir'
|
||||||
);
|
);
|
||||||
const backupAttachmentPattern = path.join(backupDir, 'attachments/*');
|
const backupAttachmentPattern = normalizePath(
|
||||||
|
path.join(backupDir, 'attachments/*')
|
||||||
|
);
|
||||||
const backupAttachments = fastGlob.sync(backupAttachmentPattern);
|
const backupAttachments = fastGlob.sync(backupAttachmentPattern);
|
||||||
console.log({ backupAttachments });
|
console.log({ backupAttachments });
|
||||||
assert.strictEqual(ATTACHMENT_COUNT, backupAttachments.length);
|
assert.strictEqual(ATTACHMENT_COUNT, backupAttachments.length);
|
||||||
|
|
|
@ -433,7 +433,6 @@
|
||||||
<script type="text/javascript" src="../js/reliable_trigger.js" data-cover></script>
|
<script type="text/javascript" src="../js/reliable_trigger.js" data-cover></script>
|
||||||
<script type="text/javascript" src="test.js"></script>
|
<script type="text/javascript" src="test.js"></script>
|
||||||
|
|
||||||
<script type='text/javascript' src='../js/registration.js' data-cover></script>
|
|
||||||
<script type="text/javascript" src="../js/chromium.js" data-cover></script>
|
<script type="text/javascript" src="../js/chromium.js" data-cover></script>
|
||||||
<script type="text/javascript" src="../js/database.js" data-cover></script>
|
<script type="text/javascript" src="../js/database.js" data-cover></script>
|
||||||
<script type="text/javascript" src="../js/storage.js" data-cover></script>
|
<script type="text/javascript" src="../js/storage.js" data-cover></script>
|
||||||
|
@ -477,7 +476,6 @@
|
||||||
<script type="text/javascript" src="models/messages_test.js"></script>
|
<script type="text/javascript" src="models/messages_test.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript" src="libphonenumber_util_test.js"></script>
|
<script type="text/javascript" src="libphonenumber_util_test.js"></script>
|
||||||
<script type="text/javascript" src="conversation_controller_test.js"></script>
|
|
||||||
<script type="text/javascript" src="storage_test.js"></script>
|
<script type="text/javascript" src="storage_test.js"></script>
|
||||||
<script type="text/javascript" src="keychange_listener_test.js"></script>
|
<script type="text/javascript" src="keychange_listener_test.js"></script>
|
||||||
<script type="text/javascript" src="reliable_trigger_test.js"></script>
|
<script type="text/javascript" src="reliable_trigger_test.js"></script>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { join, relative } from 'path';
|
import { join, relative } from 'path';
|
||||||
|
import normalizePath from 'normalize-path';
|
||||||
|
|
||||||
import { sync as fgSync } from 'fast-glob';
|
import { sync as fgSync } from 'fast-glob';
|
||||||
import { forEach, some, values } from 'lodash';
|
import { forEach, some, values } from 'lodash';
|
||||||
|
@ -36,7 +37,7 @@ const rulesPath = join(__dirname, 'rules.json');
|
||||||
const exceptionsPath = join(__dirname, 'exceptions.json');
|
const exceptionsPath = join(__dirname, 'exceptions.json');
|
||||||
const basePath = join(__dirname, '../../..');
|
const basePath = join(__dirname, '../../..');
|
||||||
|
|
||||||
const searchPattern = join(basePath, '**/*.{js,ts,tsx}');
|
const searchPattern = normalizePath(join(basePath, '**/*.{js,ts,tsx}'));
|
||||||
|
|
||||||
const rules: Array<RuleType> = loadJSON(rulesPath);
|
const rules: Array<RuleType> = loadJSON(rulesPath);
|
||||||
const exceptions: Array<ExceptionType> = loadJSON(exceptionsPath);
|
const exceptions: Array<ExceptionType> = loadJSON(exceptionsPath);
|
||||||
|
|
28
yarn.lock
28
yarn.lock
|
@ -2081,6 +2081,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.40.tgz#4314888d5cd537945d73e9ce165c04cc550144a4"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.40.tgz#4314888d5cd537945d73e9ce165c04cc550144a4"
|
||||||
integrity sha512-RRSjdwz63kS4u7edIwJUn8NqKLLQ6LyqF/X4+4jp38MBT3Vwetewi2N4dgJEshLbDwNgOJXNYoOwzVZUSSLhkQ==
|
integrity sha512-RRSjdwz63kS4u7edIwJUn8NqKLLQ6LyqF/X4+4jp38MBT3Vwetewi2N4dgJEshLbDwNgOJXNYoOwzVZUSSLhkQ==
|
||||||
|
|
||||||
|
"@types/normalize-path@3.0.0":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/normalize-path/-/normalize-path-3.0.0.tgz#bb5c46cab77b93350b4cf8d7ff1153f47189ae31"
|
||||||
|
integrity sha512-Nd8y/5t/7CRakPYiyPzr/IAfYusy1FkcZYFEAcoMZkwpJv2n4Wm+olW+e7xBdHEXhOnWdG9ddbar0gqZWS4x5Q==
|
||||||
|
|
||||||
"@types/pify@3.0.2":
|
"@types/pify@3.0.2":
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/pify/-/pify-3.0.2.tgz#1bc75dac43e31dba981c37e0a08edddc1b49cd39"
|
resolved "https://registry.yarnpkg.com/@types/pify/-/pify-3.0.2.tgz#1bc75dac43e31dba981c37e0a08edddc1b49cd39"
|
||||||
|
@ -5139,19 +5144,14 @@ core-js-pure@^3.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.2.1.tgz#879a23699cff46175bfd2d09158b5c50645a3c45"
|
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.2.1.tgz#879a23699cff46175bfd2d09158b5c50645a3c45"
|
||||||
integrity sha512-+qpvnYrsi/JDeQTArB7NnNc2VoMYLE1YSkziCDHgjexC2KH7OFiGhLUd3urxfyWmNjSwSW7NYXPWHMhuIJx9Ow==
|
integrity sha512-+qpvnYrsi/JDeQTArB7NnNc2VoMYLE1YSkziCDHgjexC2KH7OFiGhLUd3urxfyWmNjSwSW7NYXPWHMhuIJx9Ow==
|
||||||
|
|
||||||
core-js@2.4.0:
|
core-js@2.4.1, core-js@^2.4.0:
|
||||||
version "2.4.0"
|
version "2.4.1"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.0.tgz#df408ab46d01aff91c01c3e7971935d422c54f81"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
|
||||||
integrity sha1-30CKtG0Br/kcAcPnlxk11CLFT4E=
|
|
||||||
|
|
||||||
core-js@^1.0.0:
|
core-js@^1.0.0:
|
||||||
version "1.2.7"
|
version "1.2.7"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||||
|
|
||||||
core-js@^2.4.0:
|
|
||||||
version "2.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
|
|
||||||
|
|
||||||
core-js@^2.4.1:
|
core-js@^2.4.1:
|
||||||
version "2.5.4"
|
version "2.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.4.tgz#f2c8bf181f2a80b92f360121429ce63a2f0aeae0"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.4.tgz#f2c8bf181f2a80b92f360121429ce63a2f0aeae0"
|
||||||
|
@ -7919,6 +7919,18 @@ glob@7.1.3:
|
||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
path-is-absolute "^1.0.0"
|
path-is-absolute "^1.0.0"
|
||||||
|
|
||||||
|
glob@7.1.6:
|
||||||
|
version "7.1.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||||
|
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||||
|
dependencies:
|
||||||
|
fs.realpath "^1.0.0"
|
||||||
|
inflight "^1.0.4"
|
||||||
|
inherits "2"
|
||||||
|
minimatch "^3.0.4"
|
||||||
|
once "^1.3.0"
|
||||||
|
path-is-absolute "^1.0.0"
|
||||||
|
|
||||||
glob@^6.0.1, glob@^6.0.4:
|
glob@^6.0.1, glob@^6.0.4:
|
||||||
version "6.0.4"
|
version "6.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
|
resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
|
||||||
|
|
Loading…
Reference in a new issue