diff --git a/email_app/.compilerc b/email_app/.compilerc index d5cc5d8..e5d1932 100644 --- a/email_app/.compilerc +++ b/email_app/.compilerc @@ -26,5 +26,8 @@ ] } } + }, + "text/less": { + "dumpLineNumbers": "comments" } } \ No newline at end of file diff --git a/email_app/.gitignore b/email_app/.gitignore index 845ddcb..af9c934 100644 --- a/email_app/.gitignore +++ b/email_app/.gitignore @@ -8,3 +8,4 @@ Thumbs.db /dist /main.js /main.js.map +/out \ No newline at end of file diff --git a/email_app/README.md b/email_app/README.md index d99e3fa..b634bb5 100644 --- a/email_app/README.md +++ b/email_app/README.md @@ -64,3 +64,9 @@ To package apps with options: ```bash $ npm run package -- --[option] ``` + +## Application Data Model + +The following diagram depicts how the emails are stored in the SAFE network, as well as how the email app stores email accounts information. + + diff --git a/email_app/app/actions/actionTypes.js b/email_app/app/actions/actionTypes.js index eac28c9..1272290 100644 --- a/email_app/app/actions/actionTypes.js +++ b/email_app/app/actions/actionTypes.js @@ -1,21 +1,24 @@ const ACTION_TYPES = { + // Initializer AUTHORISE_APP: 'AUTHORISE_APP', GET_CONFIG: 'GET_CONFIG', REFRESH_EMAIL: 'REFRESH_EMAIL', SET_INITIALIZER_TASK: 'SET_INITIALIZER_TASK', + STORE_NEW_ACCOUNT: 'STORE_NEW_ACCOUNT', - // legacy + // Create Account CREATE_ACCOUNT: 'CREATE_ACCOUNT', CREATE_ACCOUNT_ERROR: 'SET_CREATE_ACCOUNT_ERROR', + // Mail Inbox PUSH_MAIL: 'PUSH_MAIL', - SET_MAIL_PROCESSING: 'SET_MAIL_PROCESSING', + MAIL_PROCESSING: 'MAIL_PROCESSING', CLEAR_MAIL_PROCESSING: 'CLEAR_MAIL_PROCESSING', SET_ACTIVE_MAIL: 'SET_ACTIVE_MAIL', CANCEL_COMPOSE: 'CANCEL_COMPOSE', - CLEAR_INBOX: 'CLEAR_INBOX', - PUSH_TO_INBOX: 'PUSH_TO_INBOX' + PUSH_TO_INBOX: 'PUSH_TO_INBOX', + PUSH_TO_ARCHIVE: 'PUSH_TO_ARCHIVE' }; export default ACTION_TYPES; diff --git a/email_app/app/actions/create_account_actions.js b/email_app/app/actions/create_account_actions.js index 8569023..cb920ea 100644 --- a/email_app/app/actions/create_account_actions.js +++ b/email_app/app/actions/create_account_actions.js @@ -1,28 +1,13 @@ -import { CONSTANTS } from '../constants'; import ACTION_TYPES from './actionTypes'; - -var accountResolver; -var accountRejecter; -const accountPromise = new Promise((resolve, reject) => { - accountResolver = resolve; - accountRejecter = reject; -}); +import { setupAccount } from '../safenet_comm'; export const createAccount = (emailId) => { return function (dispatch, getState) { - dispatch({ + let app = getState().initializer.app; + return dispatch({ type: ACTION_TYPES.CREATE_ACCOUNT, - payload: accountPromise + payload: setupAccount(app, emailId) }); - - // FIXME: store private key for encryption in app's container mapped to emailId - - let app = getState().initializer.app; - return app.mutableData.newRandomPublic(CONSTANTS.INBOX_TAG_TYPE) - .then((md) => md.quickSetup({})) - // FIXME: map this address to emailId in publicNames - .then((md) => accountResolver(md)) - .catch(accountRejecter); }; }; diff --git a/email_app/app/actions/initializer_actions.js b/email_app/app/actions/initializer_actions.js index a2da244..48dc2ef 100644 --- a/email_app/app/actions/initializer_actions.js +++ b/email_app/app/actions/initializer_actions.js @@ -1,65 +1,81 @@ -import { initializeApp, fromAuthURI } from 'safe-app'; - import ACTION_TYPES from './actionTypes'; - -var authResolver; -var authRejecter; -const authPromise = () => new Promise((resolve, reject) => { - authResolver = resolve; - authRejecter = reject; -}); +import { authApp, connect, readConfig, writeConfig, + readInboxEmails, readArchivedEmails } from '../safenet_comm'; export const setInitializerTask = (task) => ({ type: ACTION_TYPES.SET_INITIALIZER_TASK, task }); -export const receiveResponse = (uri) => { +export const onAuthFailure = (err) => { return { type: ACTION_TYPES.AUTHORISE_APP, - payload: fromAuthURI(uri) - .then((app) => authResolver ? authResolver(app) : app) - } + payload: Promise.reject(err) + }; }; -export const authoriseApplication = (appInfo, permissions, opts) => { - +export const receiveResponse = (uri) => { return function (dispatch) { - dispatch({ + return dispatch({ type: ACTION_TYPES.AUTHORISE_APP, - payload: authPromise() + payload: connect(uri) }); + }; +}; - return initializeApp(appInfo) - .then((app) => - process.env.SAFE_FAKE_AUTH - ? app.auth.loginForTest(permissions, opts) - .then(app => authResolver(app)) - : app.auth.genAuthUri(permissions, opts) - .then(resp => app.auth.openUri(resp.uri)) - ).catch(authRejecter); - +export const authoriseApplication = () => { + return function (dispatch) { + return dispatch({ + type: ACTION_TYPES.AUTHORISE_APP, + payload: new Promise((resolve, reject) => { + authApp() + .then(resolve) + .catch(reject); + }) + }) + .catch(_ => {}); }; }; export const refreshConfig = () => { - return function (dispatch, getState) { - dispatch({ + let app = getState().initializer.app; + return dispatch({ type: ACTION_TYPES.GET_CONFIG, - payload: authPromise() + payload: readConfig(app) + }); + }; +}; + +export const storeNewAccount = (account) => { + return function (dispatch, getState) { + let app = getState().initializer.app; + return dispatch({ + type: ACTION_TYPES.STORE_NEW_ACCOUNT, + payload: writeConfig(app, account) }); + }; +}; - let accounts = {}; +export const refreshEmail = (account) => { + return function (dispatch, getState) { let app = getState().initializer.app; - return app.auth.refreshContainerAccess() - .then(() => app.auth.getHomeContainer()) - .then((mdata) => mdata.getEntries() - .then((entries) => entries.forEach((name, valV) => { - accounts[name.toString()] = valV.buf.toString(); - }) - .then(() => authResolver(accounts)) - ) - ).catch(authRejecter); + return dispatch({ + type: ACTION_TYPES.REFRESH_EMAIL, + payload: readInboxEmails(app, account, + (inboxEntry) => { + dispatch({ + type: ACTION_TYPES.PUSH_TO_INBOX, + payload: inboxEntry + }); + }) + .then(() => readArchivedEmails(app, account, + (archiveEntry) => { + dispatch({ + type: ACTION_TYPES.PUSH_TO_ARCHIVE, + payload: archiveEntry + }); + })) + }); }; }; diff --git a/email_app/app/actions/mail_actions.js b/email_app/app/actions/mail_actions.js index e992c3e..3ae1873 100644 --- a/email_app/app/actions/mail_actions.js +++ b/email_app/app/actions/mail_actions.js @@ -1,22 +1,58 @@ import ACTION_TYPES from './actionTypes'; +import { storeEmail, removeInboxEmail, removeArchivedEmail, archiveEmail } from '../safenet_comm'; -export const setMailProcessing = () => ({ - type: ACTION_TYPES.SET_MAIL_PROCESSING -}); +export const sendEmail = (email, to) => { + return function (dispatch, getState) { + let app = getState().initializer.app; + return dispatch({ + type: ACTION_TYPES.MAIL_PROCESSING, + payload: storeEmail(app, email, to) + .then(() => dispatch(clearMailProcessing)) + .then(() => Promise.resolve()) + }); + }; +}; -export const clearMailProcessing= _ => ({ - type: ACTION_TYPES.CLEAR_MAIL_PROCESSING -}); +export const saveEmail = (account, key) => { + return function (dispatch, getState) { + let app = getState().initializer.app; + return dispatch({ + type: ACTION_TYPES.MAIL_PROCESSING, + payload: archiveEmail(app, account, key) + .then(() => dispatch(clearMailProcessing)) + .then(() => Promise.resolve()) + }); + }; +}; -export const setActiveMail = (data) => ({ - type: ACTION_TYPES.SET_ACTIVE_MAIL, - data -}); +export const deleteInboxEmail = (account, key) => { + return function (dispatch, getState) { + let app = getState().initializer.app; + return dispatch({ + type: ACTION_TYPES.MAIL_PROCESSING, + payload: removeInboxEmail(app, account, key) + .then(() => dispatch(clearMailProcessing)) + .then(() => Promise.resolve()) + }); + }; +}; + +export const deleteSavedEmail = (account, key) => { + return function (dispatch, getState) { + let app = getState().initializer.app; + return dispatch({ + type: ACTION_TYPES.MAIL_PROCESSING, + payload: removeArchivedEmail(app, account, key) + .then(() => dispatch(clearMailProcessing)) + .then(() => Promise.resolve()) + }); + }; +}; -export const clearInbox = () => ({ - type: ACTION_TYPES.SET_ACTIVE_MAIL +export const clearMailProcessing = _ => ({ + type: ACTION_TYPES.CLEAR_MAIL_PROCESSING }); -export const cancelCompose = () => ({ +export const cancelCompose = _ => ({ type: ACTION_TYPES.CANCEL_COMPOSE }); diff --git a/email_app/app/actions/nfs_actions.js b/email_app/app/actions/nfs_actions.js deleted file mode 100644 index 71e7500..0000000 --- a/email_app/app/actions/nfs_actions.js +++ /dev/null @@ -1,16 +0,0 @@ -import ACTION_TYPES from './actionTypes'; -import { CONSTANTS } from '../constants'; - -export const writeConfigFile = (coreId) => { - // FIXME: are these even needed? - return { - type: ACTION_TYPES.WRITE_CONFIG_FILE, - coreId - } -}; - -export const getConfigFile = () => { - return { - type: ACTION_TYPES.GET_CONFIG_FILE - }; -}; diff --git a/email_app/app/app.html b/email_app/app/app.html index 899999d..801f634 100755 --- a/email_app/app/app.html +++ b/email_app/app/app.html @@ -8,9 +8,10 @@ +
- + -