diff --git a/src/SyncGate.tsx b/src/SyncGate.tsx index e1df568..4842c43 100644 --- a/src/SyncGate.tsx +++ b/src/SyncGate.tsx @@ -54,6 +54,17 @@ const syncInfoSelector = createSelector( (etesync, journals, entries, userInfo) => { const derived = etesync.encryptionKey; 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( (ret, journal) => { const journalEntries = entries.get(journal.uid); diff --git a/src/api/EteSync.ts b/src/api/EteSync.ts index 9663a8d..33bac81 100644 --- a/src/api/EteSync.ts +++ b/src/api/EteSync.ts @@ -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 function CastJson(json: any, to: any) { return Object.assign(to, json); diff --git a/src/components/ErrorBoundary.tsx b/src/components/ErrorBoundary.tsx index 4d84667..9c5cc6c 100644 --- a/src/components/ErrorBoundary.tsx +++ b/src/components/ErrorBoundary.tsx @@ -1,8 +1,9 @@ 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'; class ErrorBoundary extends React.Component { @@ -16,7 +17,9 @@ class ErrorBoundary extends React.Component { } public componentDidCatch(error: Error, info: any) { - if (error instanceof IntegrityError) { + if (error instanceof EncryptionPasswordError) { + store.dispatch(resetKey()); + } else if (error instanceof IntegrityError) { persistor.purge(); } @@ -25,21 +28,29 @@ class ErrorBoundary extends React.Component { public render() { const { error } = this.state; - if (error && error instanceof IntegrityError) { - return ( -
-

Integrity Error

-

- This probably means you put in the wrong encryption password. -

-

- Please log out from the menu, refresh the page and try again. -

-
-            {error.message}
-          
-
- ); + if (error) { + if (error instanceof EncryptionPasswordError) { + return ( +
+

Wrong Encryption Password

+

+ It looks like you've entered the wrong encryption password, please refresh the page and try again. +

+
+ ); + } else if (error instanceof IntegrityError) { + return ( +
+

Integrity Error

+

+ Please log out from the menu, refresh the page and try again, and if the problem persists, contact support. +

+
+                {error.message}
+            
+
+ ); + } } if (error) { diff --git a/src/store/actions.ts b/src/store/actions.ts index 327c125..4a54087 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -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) => { return (dispatch: any) => { dispatch(fetchCredentials(username, password, server)).then(() => diff --git a/src/store/reducers.ts b/src/store/reducers.ts index 9957883..65ad14b 100644 --- a/src/store/reducers.ts +++ b/src/store/reducers.ts @@ -84,6 +84,9 @@ export const encryptionKeyReducer = handleActions( [actions.deriveKey.toString()]: (state: {key: string | null}, action: any) => ( {key: action.payload} ), + [actions.resetKey.toString()]: (state: {key: string | null}, action: any) => ( + {key: null} + ), [actions.logout.toString()]: (state: {key: string | null}, action: any) => { return {out: true, key: null}; },