Skip to content

Commit

Permalink
Add reset masterpass settings option
Browse files Browse the repository at this point in the history
  • Loading branch information
HR committed Aug 4, 2020
1 parent 921d6bb commit 3cfebaa
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 116 deletions.
8 changes: 4 additions & 4 deletions app/core/MasterPass.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ const crypto = require('./crypto'),
// TODO: Make independent from global obj! use param instead

exports.init = async () => {
const MasterPass = await keytar.getPassword(SERVICE, ACCOUNT)
if (!MasterPass) return false
exports.set(MasterPass)
return true
const masterpass = await keytar.getPassword(SERVICE, ACCOUNT)
if (!masterpass) return false
const mpk = await crypto.deriveKey(masterpass, global.creds.mpsalt)
return mpk
}

exports.save = masterpass => keytar.setPassword(SERVICE, ACCOUNT, masterpass)
Expand Down
89 changes: 34 additions & 55 deletions app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
* index.js
* Entry point for app execution
******************************/
// Electron

const { app, dialog } = require('electron'),
const { app, dialog, BrowserWindow } = require('electron'),
packageJson = require('../package.json'),
{ openNewGitHubIssue, debugInfo } = require('electron-util'),
debug = require('electron-debug'),
Expand Down Expand Up @@ -44,14 +43,13 @@ const { checkUpdate } = require('./utils/update')
// Core
const Db = require('./core/Db')
const MasterPass = require('./core/MasterPass')
const MasterPassKey = require('./core/MasterPassKey')
// Windows
const crypter = require('./src/crypter')
const masterPassPrompt = require('./src/masterPassPrompt')
const setup = require('./src/setup')
const settings = require('./src/settings')
const { ERRORS } = require('./config')
// adds debug features like hotkeys for triggering dev tools and reload
require('electron-debug')()

// Debug info
logger.info(`Crypter v${app.getVersion()}`)
Expand All @@ -63,6 +61,11 @@ process.chdir(app.getAppPath())
logger.info(`Changed cwd to: ${process.cwd()}`)
logger.info(`Electron v${process.versions.electron}`)
logger.info(`Electron node v${process.versions.node}`)
// Prevent second instance
const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
}

/**
* Promisification of initialisation
Expand All @@ -80,7 +83,10 @@ const init = function () {

const initMain = function () {
logger.verbose(`initialising Main...`)
return global.mdb.restoreGlobalObj('creds').then(() => MasterPass.init())
return global.mdb
.restoreGlobalObj('creds')
.then(() => MasterPass.init())
.then(mpk => mpk && (global.MasterPassKey = new MasterPassKey(mpk.key)))
}

/**
Expand All @@ -106,13 +112,16 @@ app.on('ready', function () {
// Initialise (open mdb and get creds)
initMain()
.then(mpLoaded => {
logger.verbose('INIT: MasterPass', mpLoaded ? 'loaded' : 'not saved')
logger.verbose(
'INIT: MasterPass',
mpLoaded ? 'loaded' : 'not saved'
)
// Obtain MasterPass, derive MasterPassKey and set globally
return mpLoaded || masterPassPromptWindow()
return mpLoaded || createWindow(masterPassPrompt, false)
})
.then(() => {
// Create the Crypter window and open it
return crypterWindow(fileToCrypt)
return createWindow(crypter, fileToCrypt)
})
.then(() => {
// Quit app after crypterWindow is closed
Expand All @@ -130,7 +139,7 @@ app.on('ready', function () {
// Run Setup
logger.info('Setup run. Creating Setup wizard...')

setupWindow()
createWindow(setup)
.then(() => {
logger.info('MAIN Setup successfully completed. quitting...')
// setup successfully completed
Expand Down Expand Up @@ -210,15 +219,7 @@ app.on('app:quit', () => {

app.on('app:open-settings', () => {
logger.verbose('APP: app:open-settings event emitted')
// Check if not already opened
if (settingsWindowNotOpen) {
settingsWindowNotOpen = false
settingsWindow().then(() => {
logger.verbose('APP: closed settingsWindow')
// Closed so not open anymore
settingsWindowNotOpen = true
})
}
createWindow(settings)
})

app.on('app:check-update', () => {
Expand Down Expand Up @@ -252,47 +253,25 @@ app.on('app:relaunch', () => {
// app.exit(0)
})

app.on('app:reset-masterpass', () => {
logger.verbose('APP: app:reset-masterpass event emitted')
createWindow(masterPassPrompt)
})

/**
* Promisification of windows
**/

// Creates the crypter window
let crypterWindow = function (fileToCrypt) {
return new Promise(function (resolve, reject) {
crypter.window(global, fileToCrypt, function () {
function createWindow (window, ...args) {
const winInst = BrowserWindow.getAllWindows().find(
win => win.getTitle() === window.title
)
// Focus on existing instance
if (winInst) return winInst.focus()
return new Promise((resolve, reject) =>
window.window(global, ...args, err => {
if (err) reject(err)
resolve()
})
})
}

// Creates the setup window
let setupWindow = function () {
return new Promise(function (resolve, reject) {
setup.window(global, function (err) {
if (err) {
reject(err)
} else {
resolve()
}
})
})
}

// Creates the MasterPassPrompt window
let masterPassPromptWindow = function () {
return new Promise(function (resolve, reject) {
masterPassPrompt.window(global, function (err, gotMP) {
if (err || !gotMP) reject(err)
resolve()
})
})
}

// Creates the settings window
let settingsWindow = function () {
return new Promise(function (resolve, reject) {
settings.window(global, function () {
resolve()
})
})
)
}
4 changes: 4 additions & 0 deletions app/src/crypter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ const crypto = require('../core/crypto')
const menuTemplate = require('./mainMenu')
const { isCryptoFile } = require('../utils/utils')
const logger = require('electron-log')
const title = 'Crypter'

exports.title = title

exports.window = function (global, fileToCrypt, callback) {
// creates a new BrowserWindow
let win = new BrowserWindow({
width: 350,
height: 460,
title,
...WINDOW_OPTS
})
// create menu from menuTemplate and set
Expand Down
33 changes: 19 additions & 14 deletions app/src/masterPassPrompt.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
const {app, ipcMain, Menu, BrowserWindow} = require('electron')
const {VIEWS, WINDOW_OPTS} = require('../config')
const { ipcMain, Menu, BrowserWindow } = require('electron')
const { VIEWS, WINDOW_OPTS } = require('../config')
const MasterPass = require('../core/MasterPass')
const MasterPassKey = require('../core/MasterPassKey')
const logger = require('electron-log')
const menuTemplate = require('./menu')
const title = 'MasterPass'

exports.title = title

exports.window = function (global, callback) {
let gotMP = false // init gotMP flag with false
exports.window = function (global, resetOnly, callback) {
let noMP = true // init noMP flag with false
let error = null
const CLOSE_TIMEOUT = 2000

// creates a new BrowserWindow
let win = new BrowserWindow({
width: 300,
height: 460,
title,
...WINDOW_OPTS
})
// create menu from menuTemplate and set
Menu.setApplicationMenu(Menu.buildFromTemplate(menuTemplate))
const qs = resetOnly ? '?reset=true' : ''
// loads masterpassprompt.html view into the BrowserWindow
win.loadURL(VIEWS.MASTERPASSPROMPT)
win.loadURL(VIEWS.MASTERPASSPROMPT + qs)

let webContents = win.webContents

ipcMain.on('checkMasterPass', function (event, masterpass) {
logger.verbose('IPCMAIN: checkMasterPass emitted. Checking MasterPass...')
// Check user submitted MasterPass
MasterPass.check(masterpass)
.then((res) => {
.then(res => {
if (res.match) {
// Password matches
logger.info('IPCMAIN: PASSWORD MATCHES!')
// Save MasterPassKey (while program is running)
global.MasterPassKey = new MasterPassKey(res.key)
// Save for nexg time
// Save for next time
MasterPass.save(masterpass)
// send result match result to masterpassprompt.html
webContents.send('checkMasterPassResult', {
err: null,
match: res.match
})
gotMP = true
noMP = false
// Close after 1 second
setTimeout(function () {
// close window (invokes 'closed') event
Expand All @@ -54,7 +59,7 @@ exports.window = function (global, callback) {
})
}
})
.catch((err) => {
.catch(err => {
// Inform user of error (on render side)
webContents.send('checkMasterPassResult', err.message)
// set error
Expand All @@ -72,7 +77,7 @@ exports.window = function (global, callback) {
logger.verbose('IPCMAIN: setMasterPass emitted Setting Masterpass...')
// derive MasterPassKey, genPassHash and set creds globally
MasterPass.set(masterpass)
.then((mpkey) => {
.then(mpkey => {
// set the derived MasterPassKey globally
global.MasterPassKey = new MasterPassKey(mpkey)
return
Expand All @@ -86,7 +91,7 @@ exports.window = function (global, callback) {
logger.verbose('IPCMAIN: Masterpass has been reset successfully')
webContents.send('setMasterPassResult', null)
})
.catch((err) => {
.catch(err => {
// Inform user of the error that occured while setting the MasterPass
webContents.send('setMasterPassResult', err.message)
error = err
Expand All @@ -95,11 +100,11 @@ exports.window = function (global, callback) {

win.on('closed', function () {
logger.info('win.closed event emitted for PromptWindow')
// send error and gotMP back to callee (masterPassPromptWindow Promise)
callback(error, gotMP)
// send error and noMP back to callee (masterPassPromptWindow Promise)
if (callback) callback(error || noMP)
// close window by setting it to nothing (null)
win = null
})

return win
}
}
6 changes: 4 additions & 2 deletions app/src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ const menuTemplate = require('./menu')
const {CRYPTO, VIEWS, SETTINGS, ERRORS, WINDOW_OPTS} = require('../config')
const logger = require('electron-log')
const fs = require('fs-extra')
const _ = require('lodash')
const title = 'Settings'

exports.title = title
exports.window = function (global, callback) {
// creates a new BrowserWindow
let win = new BrowserWindow({
width: 600,
height: 460,
title,
...WINDOW_OPTS
})
// create menu from menuTemplate and set
Expand Down Expand Up @@ -41,7 +43,7 @@ exports.window = function (global, callback) {
logger.error(err)
webContents.send('importResult', err.message)
} else {
let isCredsObjProp = function (prop, index, array) {
let isCredsObjProp = function (prop) {
return credsObj.hasOwnProperty(prop)
}
let credsFileValid = CRYPTO.MASTERPASS_CREDS_PROPS.every(isCredsObjProp)
Expand Down
4 changes: 4 additions & 0 deletions app/src/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const MasterPass = require('../core/MasterPass')
const MasterPassKey = require('../core/MasterPassKey')
const logger = require('electron-log')
const menuTemplate = require('./menu')
const title = 'Setup'

exports.title = title

exports.window = function (global, callback) {
// setup view controller
Expand All @@ -12,6 +15,7 @@ exports.window = function (global, callback) {
let win = new BrowserWindow({
width: 600,
height: 420,
title,
...WINDOW_OPTS
})

Expand Down
1 change: 0 additions & 1 deletion app/static/crypter.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<html>
<head>
<meta charset="utf-8">
<title>Crypter</title>
<link rel="stylesheet" href="styles/crypter.css">
<script src="js/common.js" type="text/javascript"></script>
<script src="js/crypter.js" type="text/javascript"></script>
Expand Down
7 changes: 7 additions & 0 deletions app/static/js/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ const {REGEX, RESPONSES, COLORS} = require('../config')
const Handlebars = require('handlebars')

/* Shared functions */
function getUrlParameter(name) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
var results = regex.exec(location.search);
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
};

function navigate (panel) {
let oldSel = $('.panel-container > div.current') // get current panel
let sel = $(`#panel-${panel}`) // get panel to navigate to
Expand Down

0 comments on commit 3cfebaa

Please sign in to comment.