Skip to content
This repository was archived by the owner on Jan 7, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
7e082d9
Getting the SD handle of an existing file directly from the FILE_INDE…
Dec 9, 2016
326ab7c
fix/packaging_issue: resolve packaging issue
Mar 3, 2017
1910e77
chore/java_email_app: refactor typo
hitman401 Mar 7, 2017
6c182a0
Merge pull request #157 from krishnaIndia/java_email_app
hitman401 Mar 13, 2017
f410cf2
fix/build_config: remove unwanted build configuration
Mar 13, 2017
8b01f0d
Merge pull request #155 from shankar2105/web_hosting_fixes
hitman401 Mar 13, 2017
b9a1e38
fix/folder_structure: update folder structure
Mar 21, 2017
5d81cb9
Merge pull request #158 from shankar2105/MAID-2024
hitman401 Mar 21, 2017
d45bf04
fix/style: resolve create service style
Mar 21, 2017
5c85cf8
Merge pull request #159 from shankar2105/MAID-2024
hitman401 Mar 21, 2017
23d6dfc
chore/README.md: update README.md
Mar 23, 2017
42c97a0
Merge pull request #160 from shankar2105/readme_update
hitman401 Mar 23, 2017
ef3a11f
fix/upload: resolve upload issue
Mar 23, 2017
0fda097
Merge pull request #161 from shankar2105/upload_patch
hitman401 Mar 23, 2017
5c36371
chore/readme: update README.md
Mar 23, 2017
a4bdef8
Merge pull request #162 from shankar2105/readme_update
hitman401 Mar 23, 2017
271e76f
Merge remote-tracking branch 'upstream/master'
bochaco Mar 27, 2017
c73857d
feat/Enabling the flow for the creation of an eamil account
bochaco Apr 3, 2017
617f111
feat/Changing account creation to become an initializer actions
bochaco Apr 4, 2017
0bd993f
Merge branch 'MAID-2001-migrate-to-new-api' of https://github.com/boc…
bochaco Apr 4, 2017
fe16381
fix/Styles Reenable less-styles
gnunicorn Apr 5, 2017
659138c
feat/Adding first draft of mail inbox
bochaco Apr 5, 2017
79bebc3
feat/Creating accounts and email inbox & first draft to send email wi…
bochaco Apr 7, 2017
7214bb1
feat/Adding first draft for removing emails
bochaco Apr 10, 2017
f6a031b
Merge branch 'master' into MAID-2001-migrate-to-new-api
bochaco Apr 11, 2017
4a48a5e
feat/Draft code for email compose, send email, delete & archive, and …
bochaco Apr 11, 2017
3655403
fix/Fixing style rendering
bochaco Apr 12, 2017
c033dc3
feat/Minor fixes & enabling authorisation flow with authenticator
bochaco Apr 18, 2017
c02a422
feat/Encryption: encrypt emails and inbox entries with libsodium
bochaco Apr 18, 2017
92fa543
feat/Finalising authorisation flow with authenticator
bochaco Apr 19, 2017
0980919
fix/packaging_config: resolve packaging issue
Apr 20, 2017
615c8af
Merge pull request #1 from shankar2105/gab/MAID-2001-migrate-to-new-api
bochaco Apr 20, 2017
c2547d4
feat/Reorganising the code to keep safenet access code in a separate …
bochaco Apr 21, 2017
a787057
feat/Enabling archival of emails and removal of emails from archive
bochaco Apr 21, 2017
82752ae
fix/Removing unnecessary permissions from inbox and archive MDs
bochaco Apr 21, 2017
c91de96
fix/Removal of emails with a work around to overcome a limitation in …
bochaco Apr 21, 2017
a61f519
refactor/Minor additional reorganisation of the safenet_comm code
bochaco Apr 22, 2017
93650c5
feat/Enabling the use of home container to store email account config…
bochaco Apr 23, 2017
e8479c7
fix/Minor fix in the authorisation flow with authenticator
bochaco Apr 24, 2017
e39006d
feat/Making the archive to be a private MD
bochaco Apr 24, 2017
a809953
docs/Design: creating a diagram detailing the internal data layout
bochaco Apr 24, 2017
481d4c5
docs/Adding the Data Model diagram to the README
bochaco Apr 24, 2017
43df45e
feat/Enhancing errors handling
bochaco Apr 25, 2017
d02ddaf
feat/Storing the auth URI in local storage and renew it when it becom…
bochaco Apr 25, 2017
b560b8b
feat/Verifying email ids and reporting error when they are invalid or…
bochaco Apr 27, 2017
223cd85
docs/Updating repo URLs in README
bochaco Apr 27, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions email_app/.compilerc
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@
]
}
}
},
"text/less": {
"dumpLineNumbers": "comments"
}
}
1 change: 1 addition & 0 deletions email_app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Thumbs.db
/dist
/main.js
/main.js.map
/out
6 changes: 6 additions & 0 deletions email_app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

![Email App Data Model](./design/EmailApp-DataModel.png)
11 changes: 7 additions & 4 deletions email_app/app/actions/actionTypes.js
Original file line number Diff line number Diff line change
@@ -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;
23 changes: 4 additions & 19 deletions email_app/app/actions/create_account_actions.js
Original file line number Diff line number Diff line change
@@ -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);
};
};

Expand Down
94 changes: 55 additions & 39 deletions email_app/app/actions/initializer_actions.js
Original file line number Diff line number Diff line change
@@ -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
});
}))
});
};
};
62 changes: 49 additions & 13 deletions email_app/app/actions/mail_actions.js
Original file line number Diff line number Diff line change
@@ -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
});
16 changes: 0 additions & 16 deletions email_app/app/actions/nfs_actions.js

This file was deleted.

7 changes: 4 additions & 3 deletions email_app/app/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
<link rel="stylesheet" href="../node_modules/open-sans-fontface/open-sans.css">
<link rel="stylesheet" href="../node_modules/material-design-lite/material.min.css">
<script src="../node_modules/material-design-lite/material.min.js"></script>
<link rel="stylesheet" href="./less/main.less" />
</head>
<body style="overflow: hidden; background-color: rgba(0,0,0,0); margin: 0" >
<div id="App"></div>
<div id="root"></div>
</body>

<script type="text/jsx">
Expand All @@ -20,12 +21,12 @@

const render = () => {
const App = require('./app').default;
ReactDOM.render(<AppContainer><App /></AppContainer>, document.getElementById('App'));
ReactDOM.render(<AppContainer><App /></AppContainer>, document.getElementById('root'));
}

render();
if (module.hot) {
module.hot.accept(render);
}
</script>
</html>
</html>
17 changes: 6 additions & 11 deletions email_app/app/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,23 @@ import { syncHistoryWithStore } from 'react-router-redux';
import { ipcRenderer as ipc } from 'electron';
import routes from './routes';
import configureStore from './store/configureStore';
import { receiveResponse } from "./actions/initializer_actions";
import { receiveResponse, onAuthFailure } from "./actions/initializer_actions";

const store = configureStore();
const history = syncHistoryWithStore(hashHistory, store);


const listenForAuthReponse = (event, response) => {
// TODO parse response
if (response) {
ipc.on('auth-response', (event, response) => {
if (response && response.indexOf('safe-') == 0) {
store.dispatch(receiveResponse(response)); // TODO do it concurrently (no to linked dispatch)
} else {
// store.dispatch(onAuthFailure(new Error('Authorisation failed')));
store.dispatch(onAuthFailure(new Error('Authorisation failed')));
}
};

ipc.on('auth-response', listenForAuthReponse);

});

export default class App extends React.Component {
render() {
return (<Provider store={store}>
<Router history={history} routes={routes(store)} />
</Provider>);
}
}
}
Loading