mirror of
https://github.com/oxen-io/session-desktop.git
synced 2023-12-14 02:12:57 +01:00
c59b196487
Sending our public key in header of message Now attaching our key to the source field when sending messages, allows messages to be decrypted with the fallback cypher Now polling the server for messages every 5 seconds Sending the source device with messages Added mock respond function to request to leave it that same as the websocket stuff. RetrieveMessages now just returns the result Polling now continues if the server responds with an error. Returning only the result from sendMessage and retrieveMessages Revert commenting of unreachable code Refactored http logic into own file Revert a change to websocket-resources
455 lines
13 KiB
JavaScript
455 lines
13 KiB
JavaScript
const path = require('path');
|
|
const packageJson = require('./package.json');
|
|
const importOnce = require('node-sass-import-once');
|
|
const rimraf = require('rimraf');
|
|
const mkdirp = require('mkdirp');
|
|
const spectron = require('spectron');
|
|
const asar = require('asar');
|
|
const fs = require('fs');
|
|
const assert = require('assert');
|
|
const sass = require('node-sass');
|
|
|
|
/* eslint-disable more/no-then, no-console */
|
|
|
|
module.exports = grunt => {
|
|
const bower = grunt.file.readJSON('bower.json');
|
|
const components = [];
|
|
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
|
for (const i in bower.concat.app) {
|
|
components.push(bower.concat.app[i]);
|
|
}
|
|
|
|
const libtextsecurecomponents = [];
|
|
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
|
for (const i in bower.concat.libtextsecure) {
|
|
libtextsecurecomponents.push(bower.concat.libtextsecure[i]);
|
|
}
|
|
|
|
grunt.loadNpmTasks('grunt-sass');
|
|
|
|
grunt.initConfig({
|
|
pkg: grunt.file.readJSON('package.json'),
|
|
concat: {
|
|
components: {
|
|
src: components,
|
|
dest: 'js/components.js',
|
|
},
|
|
util_worker: {
|
|
src: [
|
|
'components/bytebuffer/dist/ByteBufferAB.js',
|
|
'components/long/dist/Long.js',
|
|
'js/util_worker_tasks.js',
|
|
],
|
|
dest: 'js/util_worker.js',
|
|
},
|
|
libtextsecurecomponents: {
|
|
src: libtextsecurecomponents,
|
|
dest: 'libtextsecure/components.js',
|
|
},
|
|
test: {
|
|
src: [
|
|
'node_modules/mocha/mocha.js',
|
|
'node_modules/chai/chai.js',
|
|
'test/_test.js',
|
|
],
|
|
dest: 'test/test.js',
|
|
},
|
|
// TODO: Move errors back down?
|
|
libtextsecure: {
|
|
options: {
|
|
banner: ';(function() {\n',
|
|
footer: '})();\n',
|
|
},
|
|
src: [
|
|
'libtextsecure/errors.js',
|
|
'libtextsecure/libsignal-protocol.js',
|
|
'libtextsecure/protocol_wrapper.js',
|
|
|
|
'libtextsecure/crypto.js',
|
|
'libtextsecure/storage.js',
|
|
'libtextsecure/storage/user.js',
|
|
'libtextsecure/storage/groups.js',
|
|
'libtextsecure/storage/unprocessed.js',
|
|
'libtextsecure/protobufs.js',
|
|
'libtextsecure/helpers.js',
|
|
'libtextsecure/stringview.js',
|
|
'libtextsecure/event_target.js',
|
|
'libtextsecure/account_manager.js',
|
|
'libtextsecure/websocket-resources.js',
|
|
'libtextsecure/http-resources.js',
|
|
'libtextsecure/message_receiver.js',
|
|
'libtextsecure/outgoing_message.js',
|
|
'libtextsecure/sendmessage.js',
|
|
'libtextsecure/sync_request.js',
|
|
'libtextsecure/contacts_parser.js',
|
|
'libtextsecure/ProvisioningCipher.js',
|
|
'libtextsecure/task_with_timeout.js',
|
|
],
|
|
dest: 'js/libtextsecure.js',
|
|
},
|
|
libloki: {
|
|
src: ['libloki/libloki-protocol.js'],
|
|
dest: 'js/libloki.js',
|
|
},
|
|
libtextsecuretest: {
|
|
src: [
|
|
'node_modules/jquery/dist/jquery.js',
|
|
'components/mock-socket/dist/mock-socket.js',
|
|
'node_modules/mocha/mocha.js',
|
|
'node_modules/chai/chai.js',
|
|
'libtextsecure/test/_test.js',
|
|
],
|
|
dest: 'libtextsecure/test/test.js',
|
|
},
|
|
},
|
|
sass: {
|
|
options: {
|
|
implementation: sass,
|
|
sourceMap: true,
|
|
importer: importOnce,
|
|
},
|
|
dev: {
|
|
files: {
|
|
'stylesheets/manifest.css': 'stylesheets/manifest.scss',
|
|
},
|
|
},
|
|
},
|
|
copy: {
|
|
deps: {
|
|
files: [
|
|
{
|
|
src: 'components/mp3lameencoder/lib/Mp3LameEncoder.js',
|
|
dest: 'js/Mp3LameEncoder.min.js',
|
|
},
|
|
{
|
|
src: 'components/webaudiorecorder/lib/WebAudioRecorderMp3.js',
|
|
dest: 'js/WebAudioRecorderMp3.js',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
watch: {
|
|
libtextsecure: {
|
|
files: ['./libtextsecure/*.js', './libtextsecure/storage/*.js'],
|
|
tasks: ['concat:libtextsecure'],
|
|
},
|
|
libloki: {
|
|
files: ['./libloki/*.js'],
|
|
tasks: ['concat:libloki'],
|
|
},
|
|
protobuf: {
|
|
files: ['./protos/SignalService.proto'],
|
|
tasks: ['exec:build-protobuf'],
|
|
},
|
|
sass: {
|
|
files: ['./stylesheets/*.scss'],
|
|
tasks: ['sass'],
|
|
},
|
|
transpile: {
|
|
files: ['./ts/**/*.ts'],
|
|
tasks: ['exec:transpile'],
|
|
},
|
|
},
|
|
exec: {
|
|
'tx-pull-new': {
|
|
cmd: 'tx pull -a --minimum-perc=80',
|
|
},
|
|
'tx-pull': {
|
|
cmd: 'tx pull',
|
|
},
|
|
transpile: {
|
|
cmd: 'yarn transpile',
|
|
},
|
|
'build-protobuf': {
|
|
cmd: 'yarn build-protobuf',
|
|
},
|
|
},
|
|
'test-release': {
|
|
osx: {
|
|
archive: `mac/${
|
|
packageJson.productName
|
|
}.app/Contents/Resources/app.asar`,
|
|
appUpdateYML: `mac/${
|
|
packageJson.productName
|
|
}.app/Contents/Resources/app-update.yml`,
|
|
exe: `mac/${packageJson.productName}.app/Contents/MacOS/${
|
|
packageJson.productName
|
|
}`,
|
|
},
|
|
mas: {
|
|
archive: 'mas/Signal.app/Contents/Resources/app.asar',
|
|
appUpdateYML: 'mac/Signal.app/Contents/Resources/app-update.yml',
|
|
exe: `mas/${packageJson.productName}.app/Contents/MacOS/${
|
|
packageJson.productName
|
|
}`,
|
|
},
|
|
linux: {
|
|
archive: 'linux-unpacked/resources/app.asar',
|
|
exe: `linux-unpacked/${packageJson.name}`,
|
|
},
|
|
win: {
|
|
archive: 'win-unpacked/resources/app.asar',
|
|
appUpdateYML: 'win-unpacked/resources/app-update.yml',
|
|
exe: `win-unpacked/${packageJson.productName}.exe`,
|
|
},
|
|
},
|
|
gitinfo: {}, // to be populated by grunt gitinfo
|
|
});
|
|
|
|
Object.keys(grunt.config.get('pkg').devDependencies).forEach(key => {
|
|
if (/^grunt(?!(-cli)?$)/.test(key)) {
|
|
// ignore grunt and grunt-cli
|
|
grunt.loadNpmTasks(key);
|
|
}
|
|
});
|
|
|
|
// Transifex does not understand placeholders, so this task patches all non-en
|
|
// locales with missing placeholders
|
|
grunt.registerTask('locale-patch', () => {
|
|
const en = grunt.file.readJSON('_locales/en/messages.json');
|
|
grunt.file.recurse('_locales', (abspath, rootdir, subdir, filename) => {
|
|
if (subdir === 'en' || filename !== 'messages.json') {
|
|
return;
|
|
}
|
|
const messages = grunt.file.readJSON(abspath);
|
|
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
for (const key in messages) {
|
|
if (en[key] !== undefined && messages[key] !== undefined) {
|
|
if (
|
|
en[key].placeholders !== undefined &&
|
|
messages[key].placeholders === undefined
|
|
) {
|
|
messages[key].placeholders = en[key].placeholders;
|
|
}
|
|
}
|
|
}
|
|
|
|
grunt.file.write(abspath, `${JSON.stringify(messages, null, 4)}\n`);
|
|
});
|
|
});
|
|
|
|
grunt.registerTask('getExpireTime', () => {
|
|
grunt.task.requires('gitinfo');
|
|
const gitinfo = grunt.config.get('gitinfo');
|
|
const commited = gitinfo.local.branch.current.lastCommitTime;
|
|
const time = Date.parse(commited) + 1000 * 60 * 60 * 24 * 90;
|
|
grunt.file.write(
|
|
'config/local-production.json',
|
|
`${JSON.stringify({ buildExpiration: time })}\n`
|
|
);
|
|
});
|
|
|
|
grunt.registerTask('clean-release', () => {
|
|
rimraf.sync('release');
|
|
mkdirp.sync('release');
|
|
});
|
|
|
|
function runTests(environment, cb) {
|
|
let failure;
|
|
const { Application } = spectron;
|
|
const electronBinary =
|
|
process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
|
const app = new Application({
|
|
path: path.join(__dirname, 'node_modules', '.bin', electronBinary),
|
|
args: [path.join(__dirname, 'main.js')],
|
|
env: {
|
|
NODE_ENV: environment,
|
|
},
|
|
requireName: 'unused',
|
|
});
|
|
|
|
function getMochaResults() {
|
|
// eslint-disable-next-line no-undef
|
|
return window.mochaResults;
|
|
}
|
|
|
|
app
|
|
.start()
|
|
.then(() =>
|
|
app.client.waitUntil(
|
|
() =>
|
|
app.client
|
|
.execute(getMochaResults)
|
|
.then(data => Boolean(data.value)),
|
|
10000,
|
|
'Expected to find window.mochaResults set!'
|
|
)
|
|
)
|
|
.then(() => app.client.execute(getMochaResults))
|
|
.then(data => {
|
|
const results = data.value;
|
|
if (results.failures > 0) {
|
|
console.error(results.reports);
|
|
failure = () =>
|
|
grunt.fail.fatal(`Found ${results.failures} failing unit tests.`);
|
|
return app.client.log('browser');
|
|
}
|
|
grunt.log.ok(`${results.passes} tests passed.`);
|
|
return null;
|
|
})
|
|
.then(logs => {
|
|
if (logs) {
|
|
console.error();
|
|
console.error('Because tests failed, printing browser logs:');
|
|
console.error(logs);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
failure = () =>
|
|
grunt.fail.fatal(
|
|
`Something went wrong: ${error.message} ${error.stack}`
|
|
);
|
|
})
|
|
.then(() => {
|
|
// We need to use the failure variable and this early stop to clean up before
|
|
// shutting down. Grunt's fail methods are the only way to set the return value,
|
|
// but they shut the process down immediately!
|
|
if (failure) {
|
|
console.log();
|
|
console.log('Main process logs:');
|
|
return app.client.getMainProcessLogs().then(logs => {
|
|
logs.forEach(log => {
|
|
console.log(log);
|
|
});
|
|
|
|
return app.stop();
|
|
});
|
|
}
|
|
return app.stop();
|
|
})
|
|
.then(() => {
|
|
if (failure) {
|
|
failure();
|
|
}
|
|
cb();
|
|
})
|
|
.catch(error => {
|
|
console.error('Second-level error:', error.message, error.stack);
|
|
if (failure) {
|
|
failure();
|
|
}
|
|
cb();
|
|
});
|
|
}
|
|
|
|
grunt.registerTask(
|
|
'unit-tests',
|
|
'Run unit tests w/Electron',
|
|
function thisNeeded() {
|
|
const environment = grunt.option('env') || 'test';
|
|
const done = this.async();
|
|
|
|
runTests(environment, done);
|
|
}
|
|
);
|
|
|
|
grunt.registerTask(
|
|
'lib-unit-tests',
|
|
'Run libtextsecure unit tests w/Electron',
|
|
function thisNeeded() {
|
|
const environment = grunt.option('env') || 'test-lib';
|
|
const done = this.async();
|
|
|
|
runTests(environment, done);
|
|
}
|
|
);
|
|
|
|
grunt.registerMultiTask(
|
|
'test-release',
|
|
'Test packaged releases',
|
|
function thisNeeded() {
|
|
const dir = grunt.option('dir') || 'dist';
|
|
const environment = grunt.option('env') || 'production';
|
|
const config = this.data;
|
|
const archive = [dir, config.archive].join('/');
|
|
const files = [
|
|
'config/default.json',
|
|
`config/${environment}.json`,
|
|
`config/local-${environment}.json`,
|
|
];
|
|
|
|
console.log(this.target, archive);
|
|
const releaseFiles = files.concat(config.files || []);
|
|
releaseFiles.forEach(fileName => {
|
|
console.log(fileName);
|
|
try {
|
|
asar.statFile(archive, fileName);
|
|
return true;
|
|
} catch (e) {
|
|
console.log(e);
|
|
throw new Error(`Missing file ${fileName}`);
|
|
}
|
|
});
|
|
|
|
if (config.appUpdateYML) {
|
|
const appUpdateYML = [dir, config.appUpdateYML].join('/');
|
|
if (fs.existsSync(appUpdateYML)) {
|
|
console.log('auto update ok');
|
|
} else {
|
|
throw new Error(`Missing auto update config ${appUpdateYML}`);
|
|
}
|
|
}
|
|
|
|
const done = this.async();
|
|
// A simple test to verify a visible window is opened with a title
|
|
const { Application } = spectron;
|
|
|
|
const app = new Application({
|
|
path: [dir, config.exe].join('/'),
|
|
requireName: 'unused',
|
|
});
|
|
|
|
app
|
|
.start()
|
|
.then(() => app.client.getWindowCount())
|
|
.then(count => {
|
|
assert.equal(count, 1);
|
|
console.log('window opened');
|
|
})
|
|
.then(() =>
|
|
// Get the window's title
|
|
app.client.getTitle()
|
|
)
|
|
.then(title => {
|
|
// Verify the window's title
|
|
assert.equal(title, packageJson.productName);
|
|
console.log('title ok');
|
|
})
|
|
.then(() => {
|
|
assert(
|
|
app.chromeDriver.logLines.indexOf(`NODE_ENV ${environment}`) > -1
|
|
);
|
|
console.log('environment ok');
|
|
})
|
|
.then(
|
|
() =>
|
|
// Successfully completed test
|
|
app.stop(),
|
|
error =>
|
|
// Test failed!
|
|
app.stop().then(() => {
|
|
grunt.fail.fatal(`Test failed: ${error.message} ${error.stack}`);
|
|
})
|
|
)
|
|
.then(done);
|
|
}
|
|
);
|
|
|
|
grunt.registerTask('tx', [
|
|
'exec:tx-pull-new',
|
|
'exec:tx-pull',
|
|
'locale-patch',
|
|
]);
|
|
grunt.registerTask('dev', ['default', 'watch']);
|
|
grunt.registerTask('test', ['unit-tests', 'lib-unit-tests']);
|
|
grunt.registerTask('date', ['gitinfo', 'getExpireTime']);
|
|
grunt.registerTask('default', [
|
|
'exec:build-protobuf',
|
|
'exec:transpile',
|
|
'concat',
|
|
'copy:deps',
|
|
'sass',
|
|
'date',
|
|
]);
|
|
};
|