Show main window on correct password;

pull/77/head
Mikunj 6 years ago
parent 65015063d2
commit 6620244d03

@ -1684,5 +1684,13 @@
"copiedMnemonic": { "copiedMnemonic": {
"message": "Copied mnemonic to clipboard", "message": "Copied mnemonic to clipboard",
"description": "A toast message telling the user that the mnemonic was copied" "description": "A toast message telling the user that the mnemonic was copied"
},
"launcherViewTitle": {
"message": "Type in your password",
"description": "The title shown when user needs to type in a password to unlock the messenger"
},
"unlock": {
"message": "Unlock"
} }
} }

@ -0,0 +1,9 @@
const { sha512 } = require('js-sha512');
const generateHash = (phrase) => sha512(phrase);
const matchesHash = (phrase, hash) => sha512(phrase) === hash;
module.exports = {
generateHash,
matchesHash,
};

@ -598,7 +598,7 @@
</script> </script>
<script type='text/x-tmpl-mustache' id='standalone'> <script type='text/x-tmpl-mustache' id='standalone'>
<div id='standalone' class='step'> <div class='step standalone'>
<div class='inner'> <div class='inner'>
<div class='step-body'> <div class='step-body'>
<div class='header'>Create your Loki Messenger Account</div> <div class='header'>Create your Loki Messenger Account</div>

@ -1,6 +1,5 @@
/* global i18n: false */ /* global i18n: false */
/* global Whisper: false */ /* global Whisper: false */
/* global $: false */
/* eslint-disable no-new */ /* eslint-disable no-new */
@ -11,17 +10,32 @@
window.Whisper = window.Whisper || {}; window.Whisper = window.Whisper || {};
Whisper.LauncherView = Whisper.View.extend({ Whisper.LauncherView = Whisper.View.extend({
className: 'launcher full-screen-flow', className: 'launcher full-screen-flow standalone-fullscreen',
templateName: 'launcher', templateName: 'launcher',
events: {
'click #unlock-button': 'onLogin',
},
initialize() { initialize() {
this.render(); this.render();
}, },
render_attributes() { render_attributes() {
return { return {
title: 'Type in your password', title: i18n('launcherViewTitle'),
buttonText: 'Unlock', buttonText: i18n('unlock'),
}; };
}, },
async onLogin() {
const passPhrase = this.$('#passPhrase').val();
this.setError('');
try {
await window.onLogin(passPhrase);
} catch (e) {
this.setError(`Error: ${e}`);
}
},
setError(string) {
this.$('.error').text(string);
},
}); });
})(); })();

@ -17,11 +17,14 @@
<style> <style>
</style> </style>
<script type='text/x-tmpl-mustache' id='launcher'> <script type='text/x-tmpl-mustache' id='launcher'>
<div class='content' id='standalone'> <div class='content-wrapper standalone'>
<h2>{{ title }}</h2> <div class='content'>
<div class='inputs'> <h2>{{ title }}</h2>
<input class='form-control' type='text' id='mnemonic' placeholder='Password' autocomplete='off' spellcheck='false' /> <div class='inputs'>
<a class='button'>{{ buttonText }}</a> <input class='form-control' type='text' id='passPhrase' placeholder='Password' autocomplete='off' spellcheck='false' />
<a class='button' id='unlock-button'>{{ buttonText }}</a>
<div class='error'></div>
</div>
</div> </div>
</div> </div>
</script> </script>

@ -4,6 +4,7 @@ const { ipcRenderer } = require('electron');
const url = require('url'); const url = require('url');
const i18n = require('./js/modules/i18n'); const i18n = require('./js/modules/i18n');
const passwordUtil = require('./app/password_util');
const userConfig = require('./app/user_config'); const userConfig = require('./app/user_config');
const config = url.parse(window.location.toString(), true).query; const config = url.parse(window.location.toString(), true).query;
@ -22,10 +23,20 @@ window.Signal = Signal.setup({
getRegionCode: () => null, getRegionCode: () => null,
}); });
window.passwordUtil = passwordUtil;
window.userConfig = userConfig; window.userConfig = userConfig;
window.getEnvironment = () => config.environment; window.getEnvironment = () => config.environment;
window.getVersion = () => config.version; window.getVersion = () => config.version;
window.getAppInstance = () => config.appInstance; window.getAppInstance = () => config.appInstance;
window.onLogin = (passPhrase) => ipcRenderer.send('launcher_login', passPhrase); window.onLogin = (passPhrase) => new Promise((resolve, reject) => {
ipcRenderer.once('launcher-login-response', (event, error) => {
if (error) {
return reject(error);
}
return resolve();
});
ipcRenderer.send('launcher-login', passPhrase);
});
require('./js/logging'); require('./js/logging');

@ -51,6 +51,7 @@ const config = require('./app/config');
// Very important to put before the single instance check, since it is based on the // Very important to put before the single instance check, since it is based on the
// userData directory. // userData directory.
const userConfig = require('./app/user_config'); const userConfig = require('./app/user_config');
const passwordUtil = require('./app/password_util');
const importMode = const importMode =
process.argv.some(arg => arg === '--import') || config.get('import'); process.argv.some(arg => arg === '--import') || config.get('import');
@ -306,12 +307,6 @@ function createWindow() {
mainWindow.flashFrame(false); mainWindow.flashFrame(false);
}); });
// Ingested in preload.js via a sendSync call
ipc.on('locale-data', event => {
// eslint-disable-next-line no-param-reassign
event.returnValue = locale.messages;
});
if (config.environment === 'test') { if (config.environment === 'test') {
mainWindow.loadURL(prepareURL([__dirname, 'test', 'index.html'])); mainWindow.loadURL(prepareURL([__dirname, 'test', 'index.html']));
} else if (config.environment === 'test-lib') { } else if (config.environment === 'test-lib') {
@ -460,12 +455,6 @@ function showLauncher() {
captureClicks(launcherWindow); captureClicks(launcherWindow);
// Ingested in preload.js via a sendSync call
ipc.on('locale-data', event => {
// eslint-disable-next-line no-param-reassign
event.returnValue = locale.messages;
});
launcherWindow.on('close', e => { launcherWindow.on('close', e => {
// If the application is terminating, just do the default // If the application is terminating, just do the default
if ( if (
@ -732,6 +721,19 @@ app.on('ready', async () => {
locale = loadLocale({ appLocale, logger }); locale = loadLocale({ appLocale, logger });
} }
const key = getDefaultSQLKey();
// If we have a password set then show the launcher
// Otherwise show the main window
const passHash = userConfig.get('passHash');
if (passHash) {
showLauncher();
} else {
await showMainWindow(key);
}
});
function getDefaultSQLKey() {
let key = userConfig.get('key'); let key = userConfig.get('key');
if (!key) { if (!key) {
console.log( console.log(
@ -742,15 +744,8 @@ app.on('ready', async () => {
userConfig.set('key', key); userConfig.set('key', key);
} }
// If we have a password set then show the launcher return key;
// Otherwise show the main window }
const passHash = userConfig.get('passHash');
if (!passHash) {
showLauncher();
} else {
await showMainWindow(key);
}
});
async function showMainWindow(sqlKey) { async function showMainWindow(sqlKey) {
const userDataPath = await getRealPath(app.getPath('userData')); const userDataPath = await getRealPath(app.getPath('userData'));
@ -908,6 +903,12 @@ app.on('web-contents-created', (createEvent, contents) => {
}); });
}); });
// Ingested in preload.js via a sendSync call
ipc.on('locale-data', event => {
// eslint-disable-next-line no-param-reassign
event.returnValue = locale.messages;
});
ipc.on('set-badge-count', (event, count) => { ipc.on('set-badge-count', (event, count) => {
app.setBadgeCount(count); app.setBadgeCount(count);
}); });
@ -961,6 +962,31 @@ ipc.on('update-tray-icon', (event, unreadCount) => {
} }
}); });
// Launch screen related IPC calls
ipc.on('launcher-login', async (event, passPhrase) => {
const sendError = (e) => event.sender.send('launcher-login-response', e);
// Check if the phrase matches with the hash we have stored
const hash = userConfig.get('passHash');
const hashMatches = passPhrase && passwordUtil.matchesHash(passPhrase, hash);
if (hash && !hashMatches) {
sendError('Invalid password');
return;
}
// If we don't have a hash then use the default sql key to unlock the db
const key = hash ? passPhrase : getDefaultSQLKey();
try {
await showMainWindow(key);
if (launcherWindow) {
launcherWindow.close();
launcherWindow = null;
}
} catch (e) {
sendError('Failed to decrypt SQL database');
}
});
// Debug Log-related IPC calls // Debug Log-related IPC calls
ipc.on('show-debug-log', showDebugLogWindow); ipc.on('show-debug-log', showDebugLogWindow);

@ -805,7 +805,7 @@ textarea {
overflow-y: auto; overflow-y: auto;
} }
#standalone { .standalone {
color: $color-dark-05; color: $color-dark-05;
height: auto; height: auto;
padding: 0; padding: 0;

@ -1,10 +1,16 @@
.launcher { .launcher {
display: flex; .content-wrapper {
align-items: center; display: flex;
justify-content: center; align-items: center;
height: 100%; justify-content: center;
background: $color-dark-85; color: $color-dark-05;
color: $color-dark-05; width: 100%;
height: 100%;
}
.content {
margin: 3em;
}
.inputs { .inputs {
display: flex; display: flex;
@ -14,4 +20,10 @@
input { input {
width: 30em; width: 30em;
} }
.error {
font-weight: bold;
font-size: 16px;
margin-top: 1em;
}
} }

Loading…
Cancel
Save