To send emails to other SAFE Network users, you need to know their email ID.
First, the app retrieves the encryption key associated with the appendable data that belongs to the recipient. Then, it encrypts the email using that encryption key and saves it as immutable data. Finally, it appends the immutable data that represents the email to the appendable data of the recipient.
Contents
Copy {
"subject": "Test",
"from": "example",
"time": "Fri, 16 Sep 2016 10:49:44 GMT",
"body": "123"
}
Get the appendable data of the recipient
Before fetching the encryption key of the recipient, the app needs to obtain an appendable data handle.
Get a data identifier handle
First, the app fetches a data identifier handle for the appendable data of the recipient.
Copy POST /data-id/appendable-data
data_id_handle_actions.js
Copy export const getAppendableDataIdHandle = (token, name) => ({
type: ACTION_TYPES.GET_STRUCTURED_DATA_ID_HANDLE,
payload: {
request: {
method: 'post',
url: '/data-id/appendable-data',
headers: {
'Authorization': token
},
data: {
isPrivate: true,
name
}
}
}
});
The name of the appendable data is obtained by hashing the email ID of the recipient:
app_utils.js
Copy export const hashEmailId = emailId => {
return crypto.createHash('sha256').update(emailId).digest('base64');
};
Get an appendable data handle
The app fetches an appendable data handle using the data identifier handle previously obtained.
Copy GET /appendable-data/handle/:dataIdHandle
appendable_data_actions.js
Copy export const fetchAppendableDataHandle = (token, dataIdHandle) => { // id => appendable data id
return {
type: ACTION_TYPES.FETCH_APPENDABLE_DATA_HANDLER,
payload: {
request: {
url: `/appendable-data/handle/${dataIdHandle}`,
headers: {
'Authorization': token,
'Is-Private': true
}
}
}
};
};
Drop the data identifier handle
The app drops the data identifier handle for the appendable data of the recipient.
Copy DELETE /data-id/:handleId
data_id_handle_actions.js
Copy export const dropHandler = (token, handleId) => ({
type: ACTION_TYPES.DROP_HANDLER,
payload: {
request: {
method: 'delete',
url: `/data-id/${handleId}`,
headers: {
'Authorization': token
}
}
}
});
Get the encryption key of the recipient
After the appendable data handle is successfully obtained, the app fetches an handle for the public encryption key of the recipient. By encrypting your email using that encryption key, only the recipient will be able to read it. This is known as asymmetric encryption.
Copy GET /appendable-data/encrypt-key/:handleId
appendable_data_actions.js
Copy export const getEncryptedKey = (token, handleId) => ({
type: ACTION_TYPES.GET_ENCRYPTED_KEY,
payload: {
request: {
url: `/appendable-data/encrypt-key/${handleId}`,
headers: {
'Authorization': token
}
}
}
});
Get a cipher options handle
The app fetches a cipher options handle for asymmetric encryption using the encryption key handle of the recipient.
Copy GET /cipher-opts/:encType/:keyHandle?
cipher-opts_actions.js
Copy export const getCipherOptsHandle = (token, encType, keyHandle='') => ({
type: ACTION_TYPES.GET_CIPHER_OPTS_HANDLE,
payload: {
request: {
url: `/cipher-opts/${encType}/${keyHandle}`,
headers: {
'Authorization': token,
}
}
}
});
Drop the encryption key handle
The app drops the encryption key handle of the recipient.
Copy DELETE /appendable-data/encrypt-key/:handleId
appendable_data_actions.js
Copy export const deleteEncryptedKey = (token, handleId) => ({
type: ACTION_TYPES.DELETE_ENCRYPTED_KEY,
payload: {
request: {
method: 'delete',
url: `/appendable-data/encrypt-key/${handleId}`,
headers: {
'Authorization': token
}
}
}
});
Create the email
The app creates an email using the cipher handle that contains the encryption key of the recipient.
Get an immutable data writer handle
First, the app fetches an immutable data writer handle.
Copy GET /immutable-data/writer
immutable_data_actions.js
Copy export const createImmutableDataWriterHandle = (token) => ({
type: ACTION_TYPES.CREATE_IMMUT_WRITER_HANDLE,
payload: {
request: {
url: `/immutable-data/writer`,
headers: {
'Authorization': token
}
}
}
});
Write immutable data
The app stores the email as immutable data using the immutable data writer handle.
Copy POST /immutable-data/:handleId
immutable_data_actions.js
Copy export const writeImmutableData = (token, handleId, data) => {
const dataByteArray = new Uint8Array(new Buffer(JSON.stringify(data)));
return {
type: ACTION_TYPES.WRITE_IMMUT_DATA,
payload: {
request: {
method: 'post',
url: `/immutable-data/${handleId}`,
headers: {
'content-type': 'text/plain',
'Authorization': token
},
data: dataByteArray
}
}
};
};
Close the immutable data writer
The app encrypts the data map of the email using the cipher handle that contains the encryption key handle of the recipient. The data map is stored as immutable data on the SAFE Network.
Copy PUT /immutable-data/:handleId/:cipherOptsHandle
immutable_data_actions.js
Copy export const putImmutableData = (token, handleId, cipherOptsHandle) => ({
type: ACTION_TYPES.PUT_IMMUT_DATA,
payload: {
request: {
method: 'put',
url: `/immutable-data/${handleId}/${cipherOptsHandle}`,
headers: {
'Authorization': token,
}
}
}
});
Once the write operation is successful, the API returns a data identifier handle for the data map of the email.
Drop the immutable data writer handle
The app drops the immutable data writer handle.
Copy DELETE /immutable-data/writer/:handleId
immutable_data_actions.js
Copy export const closeImmutableDataWriter = (token, handleId) => ({
type: ACTION_TYPES.CLOSE_IMMUT_DATA_WRITER,
payload: {
request: {
method: 'delete',
url: `/immutable-data/writer/${handleId}`,
headers: {
'Authorization': token,
}
}
}
});
Append the email to the appendable data
The app adds the data identifier handle representing your email to the appendable data of the recipient.
Copy PUT /appendable-data/:handleId/:dataIdHandle
appendable_data_actions.js
Copy export const appendAppendableData = (token, handleId, dataIdHandle) => ({
type: ACTION_TYPES.APPEND_APPENDABLE_DATA,
payload: {
request: {
method: 'put',
url: `/appendable-data/${handleId}/${dataIdHandle}`,
headers: {
'Authorization': token
}
}
}
});
Drop the appendable data handle
After your email is successfully appended to the appendable data of the recipient, the app drops the appendable data handle.
Copy DELETE /appendable-data/handle/:handleId
appendable_data_actions.js
Copy export const dropAppendableDataHandle = (token, handleId) => ({
type: ACTION_TYPES.DROP_APPENDABLE_DATA_HANDLE,
payload: {
request: {
method: 'delete',
url: `/appendable-data/handle/${handleId}`,
headers: {
'Authorization': token
}
}
}
});