Gracefully handle wrong encryption passwords.

Until now we just showed integrity error which could be one of many issues.
Now we show an explicit error message and only clear the encryption password
cache rather than the whole cache.
master
Tom Hacohen 5 years ago
parent dfd6914cd9
commit 46fe1ceeb6

@ -54,6 +54,17 @@ const syncInfoSelector = createSelector(
(etesync, journals, entries, userInfo) => { (etesync, journals, entries, userInfo) => {
const derived = etesync.encryptionKey; const derived = etesync.encryptionKey;
let asymmetricCryptoManager: EteSync.AsymmetricCryptoManager; let asymmetricCryptoManager: EteSync.AsymmetricCryptoManager;
try {
const userInfoCryptoManager = new EteSync.CryptoManager(etesync.encryptionKey, 'userInfo');
userInfo.verify(userInfoCryptoManager);
} catch (error) {
if (error instanceof EteSync.IntegrityError) {
throw new EteSync.EncryptionPasswordError(error.message);
} else {
throw error;
}
}
return journals.reduce( return journals.reduce(
(ret, journal) => { (ret, journal) => {
const journalEntries = entries.get(journal.uid); const journalEntries = entries.get(journal.uid);

@ -32,6 +32,14 @@ export class IntegrityError extends ExtendableError {
} }
} }
export class EncryptionPasswordError extends ExtendableError {
constructor(message: any) {
super(message);
Object.setPrototypeOf(this, EncryptionPasswordError.prototype);
this.name = this.constructor.name;
}
}
// FIXME: Make secure + types // FIXME: Make secure + types
function CastJson(json: any, to: any) { function CastJson(json: any, to: any) {
return Object.assign(to, json); return Object.assign(to, json);

@ -1,8 +1,9 @@
import * as React from 'react'; import * as React from 'react';
import { persistor } from '../store'; import { store, persistor } from '../store';
import { resetKey } from '../store/actions';
import { IntegrityError } from '../api/EteSync'; import { EncryptionPasswordError, IntegrityError } from '../api/EteSync';
import PrettyError from '../widgets/PrettyError'; import PrettyError from '../widgets/PrettyError';
class ErrorBoundary extends React.Component { class ErrorBoundary extends React.Component {
@ -16,7 +17,9 @@ class ErrorBoundary extends React.Component {
} }
public componentDidCatch(error: Error, info: any) { public componentDidCatch(error: Error, info: any) {
if (error instanceof IntegrityError) { if (error instanceof EncryptionPasswordError) {
store.dispatch(resetKey());
} else if (error instanceof IntegrityError) {
persistor.purge(); persistor.purge();
} }
@ -25,21 +28,29 @@ class ErrorBoundary extends React.Component {
public render() { public render() {
const { error } = this.state; const { error } = this.state;
if (error && error instanceof IntegrityError) { if (error) {
return ( if (error instanceof EncryptionPasswordError) {
<div> return (
<h2>Integrity Error</h2> <div>
<p> <h2>Wrong Encryption Password</h2>
This probably means you put in the wrong encryption password. <p>
</p> It looks like you've entered the wrong encryption password, please refresh the page and try again.
<p> </p>
Please log out from the menu, refresh the page and try again. </div>
</p> );
<pre> } else if (error instanceof IntegrityError) {
{error.message} return (
</pre> <div>
</div> <h2>Integrity Error</h2>
); <p>
Please log out from the menu, refresh the page and try again, and if the problem persists, contact support.
</p>
<pre>
{error.message}
</pre>
</div>
);
}
} }
if (error) { if (error) {

@ -36,6 +36,13 @@ export const { deriveKey } = createActions({
}, },
}); });
export const resetKey = createAction(
'RESET_KEY',
() => {
return null;
}
);
export const login = (username: string, password: string, encryptionPassword: string, server: string) => { export const login = (username: string, password: string, encryptionPassword: string, server: string) => {
return (dispatch: any) => { return (dispatch: any) => {
dispatch(fetchCredentials(username, password, server)).then(() => dispatch(fetchCredentials(username, password, server)).then(() =>

@ -84,6 +84,9 @@ export const encryptionKeyReducer = handleActions(
[actions.deriveKey.toString()]: (state: {key: string | null}, action: any) => ( [actions.deriveKey.toString()]: (state: {key: string | null}, action: any) => (
{key: action.payload} {key: action.payload}
), ),
[actions.resetKey.toString()]: (state: {key: string | null}, action: any) => (
{key: null}
),
[actions.logout.toString()]: (state: {key: string | null}, action: any) => { [actions.logout.toString()]: (state: {key: string | null}, action: any) => {
return {out: true, key: null}; return {out: true, key: null};
}, },

Loading…
Cancel
Save