Show main window on correct password;

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

@ -1684,5 +1684,13 @@
"copiedMnemonic": {
"message": "Copied mnemonic to clipboard",
"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 type='text/x-tmpl-mustache' id='standalone'>
<div id='standalone' class='step'>
<div class='step standalone'>
<div class='inner'>
<div class='step-body'>
<div class='header'>Create your Loki Messenger Account</div>

@ -1,6 +1,5 @@
/* global i18n: false */
/* global Whisper: false */
/* global $: false */
/* eslint-disable no-new */
@ -11,17 +10,32 @@
window.Whisper = window.Whisper || {};
Whisper.LauncherView = Whisper.View.extend({
className: 'launcher full-screen-flow',
className: 'launcher full-screen-flow standalone-fullscreen',
templateName: 'launcher',
events: {
'click #unlock-button': 'onLogin',
},
initialize() {
this.render();
},
render_attributes() {
return {
title: 'Type in your password',
buttonText: 'Unlock',
title: i18n('launcherViewTitle'),
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>
<script type='text/x-tmpl-mustache' id='launcher'>
<div class='content' id='standalone'>
<h2>{{ title }}</h2>
<div class='inputs'>
<input class='form-control' type='text' id='mnemonic' placeholder='Password' autocomplete='off' spellcheck='false' />
<a class='button'>{{ buttonText }}</a>
<div class='content-wrapper standalone'>
<div class='content'>
<h2>{{ title }}</h2>
<div class='inputs'>
<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>
</script>

@ -4,6 +4,7 @@ const { ipcRenderer } = require('electron');
const url = require('url');
const i18n = require('./js/modules/i18n');
const passwordUtil = require('./app/password_util');
const userConfig = require('./app/user_config');
const config = url.parse(window.location.toString(), true).query;
@ -22,10 +23,20 @@ window.Signal = Signal.setup({
getRegionCode: () => null,
});
window.passwordUtil = passwordUtil;
window.userConfig = userConfig;
window.getEnvironment = () => config.environment;
window.getVersion = () => config.version;
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');

@ -51,6 +51,7 @@ const config = require('./app/config');
// Very important to put before the single instance check, since it is based on the
// userData directory.
const userConfig = require('./app/user_config');
const passwordUtil = require('./app/password_util');
const importMode =
process.argv.some(arg => arg === '--import') || config.get('import');
@ -306,12 +307,6 @@ function createWindow() {
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') {
mainWindow.loadURL(prepareURL([__dirname, 'test', 'index.html']));
} else if (config.environment === 'test-lib') {
@ -460,12 +455,6 @@ function showLauncher() {
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 => {
// If the application is terminating, just do the default
if (
@ -732,6 +721,19 @@ app.on('ready', async () => {
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');
if (!key) {
console.log(
@ -742,15 +744,8 @@ app.on('ready', async () => {
userConfig.set('key', key);
}
// 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);
}
});
return key;
}
async function showMainWindow(sqlKey) {
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) => {
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
ipc.on('show-debug-log', showDebugLogWindow);

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

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

Loading…
Cancel
Save