mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-11-28 19:53:53 -06:00
SEARCH-154 & SEARCH-116
1. Getting the key and the userId from the client app 2. Creating a encrypted file as soon as the batch indexes are merged 3. Deleting the data folder when the quits 4. Few changes in the encryption and decryption
This commit is contained in:
parent
8d73e930ed
commit
c8b45e091e
@ -99,7 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var search = new ssf.Search("user_data");
|
var search = new ssf.Search("7078106230763", "7078106230763");
|
||||||
var buttonEl = document.getElementById('search');
|
var buttonEl = document.getElementById('search');
|
||||||
var merge = document.getElementById('merge');
|
var merge = document.getElementById('merge');
|
||||||
var buttonIndex = document.getElementById('index');
|
var buttonIndex = document.getElementById('index');
|
||||||
@ -193,8 +193,11 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
merge.addEventListener('click', function () {
|
merge.addEventListener('click', function () {
|
||||||
search.mergeIndexBatches();
|
search.mergeIndexBatches().then(function () {
|
||||||
resultsEl.innerHTML = 'Merged';
|
search.encryptIndex();
|
||||||
|
}).catch(function (err) {
|
||||||
|
resultsEl.innerHTML = 'Error: ' + err;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
timestamp.addEventListener('click', function () {
|
timestamp.addEventListener('click', function () {
|
||||||
|
@ -4,30 +4,26 @@ const app = electron.app;
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const archiver = require('archiver');
|
const archiver = require('archiver');
|
||||||
const zipArchive = archiver('zip');
|
|
||||||
const extract = require('extract-zip');
|
const extract = require('extract-zip');
|
||||||
const isDevEnv = require('../utils/misc.js').isDevEnv;
|
const isDevEnv = require('../utils/misc.js').isDevEnv;
|
||||||
const crypto = require('./crypto');
|
const crypto = require('./crypto');
|
||||||
|
|
||||||
const userData = path.join(app.getPath('userData'));
|
const userData = path.join(app.getPath('userData'));
|
||||||
|
const DATA_FOLDER = isDevEnv ? './data' : path.join(userData, 'data');
|
||||||
const INDEX_DATA_FOLDER = isDevEnv ? './data/search_index' : path.join(userData, 'data/search_index');
|
const INDEX_DATA_FOLDER = isDevEnv ? './data/search_index' : path.join(userData, 'data/search_index');
|
||||||
const TEMPORARY_PATH = isDevEnv ? path.join(__dirname, '..', '..') : userData;
|
const TEMPORARY_PATH = isDevEnv ? path.join(__dirname, '..', '..') : userData;
|
||||||
|
|
||||||
class Crypto {
|
class Crypto {
|
||||||
|
|
||||||
// TODO: Need to pass key for encryption and decryption
|
constructor(userId, key) {
|
||||||
constructor() {
|
|
||||||
|
|
||||||
// will be handling after implementing in client app
|
|
||||||
let userId = 'user_data';
|
|
||||||
let INDEX_VERSION = 'v1';
|
let INDEX_VERSION = 'v1';
|
||||||
// will be handling after implementing in client app
|
|
||||||
|
|
||||||
this.indexDataFolder = INDEX_DATA_FOLDER + '_' + userId + '_' + INDEX_VERSION;
|
this.indexDataFolder = INDEX_DATA_FOLDER + '_' + userId + '_' + INDEX_VERSION;
|
||||||
this.permanentIndexFolderName = 'search_index_' + userId + '_' + INDEX_VERSION;
|
this.permanentIndexFolderName = 'search_index_' + userId + '_' + INDEX_VERSION;
|
||||||
this.dump = TEMPORARY_PATH;
|
this.dump = TEMPORARY_PATH;
|
||||||
|
this.key = key;
|
||||||
this.extractToPath = `${TEMPORARY_PATH}/data/${this.permanentIndexFolderName}`;
|
this.extractToPath = `${TEMPORARY_PATH}/data/${this.permanentIndexFolderName}`;
|
||||||
this.encryptedIndex = `${INDEX_DATA_FOLDER + '_' + userId + '_' + INDEX_VERSION}.enc`;
|
this.encryptedIndex = `${TEMPORARY_PATH}/${this.permanentIndexFolderName}.enc`;
|
||||||
|
this.dataFolder = DATA_FOLDER;
|
||||||
this.zipErrored = false;
|
this.zipErrored = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +32,7 @@ class Crypto {
|
|||||||
* removing the data folder and the dump files
|
* removing the data folder and the dump files
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
encryption(key) {
|
encryption() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
if (!fs.existsSync(this.indexDataFolder)){
|
if (!fs.existsSync(this.indexDataFolder)){
|
||||||
@ -45,6 +41,7 @@ class Crypto {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const zipArchive = archiver('zip');
|
||||||
let output = fs.createWriteStream(`${this.dump}/${this.permanentIndexFolderName}.zip`);
|
let output = fs.createWriteStream(`${this.dump}/${this.permanentIndexFolderName}.zip`);
|
||||||
|
|
||||||
|
|
||||||
@ -59,23 +56,17 @@ class Crypto {
|
|||||||
const input = fs.createReadStream(`${this.dump}/${this.permanentIndexFolderName}.zip`);
|
const input = fs.createReadStream(`${this.dump}/${this.permanentIndexFolderName}.zip`);
|
||||||
const outputEncryption = fs.createWriteStream(this.encryptedIndex);
|
const outputEncryption = fs.createWriteStream(this.encryptedIndex);
|
||||||
let config = {
|
let config = {
|
||||||
key: key
|
key: this.key
|
||||||
};
|
};
|
||||||
const encrypt = crypto.encrypt(config);
|
const encrypt = crypto.encrypt(config);
|
||||||
|
|
||||||
input.pipe(encrypt).pipe(outputEncryption).on('finish', (err, res) => {
|
input.pipe(encrypt).pipe(outputEncryption).on('finish', (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
reject(new Error(err));
|
reject(new Error(err));
|
||||||
}
|
}
|
||||||
if (!this.zipErrored) {
|
if (!this.zipErrored) {
|
||||||
fs.unlinkSync(`${this.dump}/${this.permanentIndexFolderName}.zip`);
|
fs.unlinkSync(`${this.dump}/${this.permanentIndexFolderName}.zip`);
|
||||||
Crypto.deleteFolderRecursive(this.indexDataFolder)
|
resolve('Success');
|
||||||
.then(function () {
|
|
||||||
resolve(res);
|
|
||||||
})
|
|
||||||
.catch(function (error) {
|
|
||||||
reject(new Error(error))
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -98,7 +89,7 @@ class Crypto {
|
|||||||
* removing the .enc file and the dump files
|
* removing the .enc file and the dump files
|
||||||
* @returns {Promise}
|
* @returns {Promise}
|
||||||
*/
|
*/
|
||||||
decryption(key) {
|
decryption() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
if (!fs.existsSync(this.encryptedIndex)){
|
if (!fs.existsSync(this.encryptedIndex)){
|
||||||
@ -110,7 +101,7 @@ class Crypto {
|
|||||||
const input = fs.createReadStream(this.encryptedIndex);
|
const input = fs.createReadStream(this.encryptedIndex);
|
||||||
const output = fs.createWriteStream(`${this.dump}/decrypted.zip`);
|
const output = fs.createWriteStream(`${this.dump}/decrypted.zip`);
|
||||||
let config = {
|
let config = {
|
||||||
key: key
|
key: this.key
|
||||||
};
|
};
|
||||||
const decrypt = crypto.decrypt(config);
|
const decrypt = crypto.decrypt(config);
|
||||||
|
|
||||||
@ -141,36 +132,37 @@ class Crypto {
|
|||||||
reject(new Error(err));
|
reject(new Error(err));
|
||||||
}
|
}
|
||||||
fs.unlink(`${this.dump}/decrypted.zip`, () => {
|
fs.unlink(`${this.dump}/decrypted.zip`, () => {
|
||||||
fs.unlink(this.encryptedIndex, () => {
|
resolve('success');
|
||||||
resolve('success');
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deleting the data index folder
|
||||||
|
* when the app is closed
|
||||||
|
*/
|
||||||
|
deleteFolders() {
|
||||||
|
Crypto.deleteFolderRecursive(this.dataFolder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removing all the folders and files inside the data folder
|
* Removing all the folders and files inside the data folder
|
||||||
* @param {String} location
|
* @param location
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
*/
|
||||||
static deleteFolderRecursive(location) {
|
static deleteFolderRecursive(location) {
|
||||||
return new Promise((resolve, reject) => {
|
if (fs.existsSync(location)) {
|
||||||
if (fs.existsSync(location)) {
|
fs.readdirSync(location).forEach((file) => {
|
||||||
fs.readdirSync(location).forEach((file) => {
|
let curPath = location + "/" + file;
|
||||||
let curPath = location + "/" + file;
|
if (fs.lstatSync(curPath).isDirectory()) {
|
||||||
if (fs.lstatSync(curPath).isDirectory()) {
|
Crypto.deleteFolderRecursive(curPath);
|
||||||
Crypto.deleteFolderRecursive(curPath);
|
} else {
|
||||||
} else {
|
fs.unlinkSync(curPath);
|
||||||
fs.unlinkSync(curPath);
|
}
|
||||||
}
|
});
|
||||||
});
|
fs.rmdirSync(location);
|
||||||
resolve(fs.rmdirSync(location));
|
}
|
||||||
} else {
|
|
||||||
reject('no file');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
js/main.js
19
js/main.js
@ -92,23 +92,8 @@ app.on('activate', function () {
|
|||||||
|
|
||||||
app.on('will-quit', function (e) {
|
app.on('will-quit', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
crypto.deleteFolders();
|
||||||
/**
|
app.exit();
|
||||||
* This is for demo purpose only
|
|
||||||
* will be removing this after implementing
|
|
||||||
* in client-app
|
|
||||||
*/
|
|
||||||
// Will be handling this in SEARCH-206
|
|
||||||
let key = "XrwVgWR4czB1a9scwvgRUNbXiN3W0oWq7oUBenyq7bo="; // temporary only
|
|
||||||
crypto.encryption(key)
|
|
||||||
.then(function () {
|
|
||||||
// will be handling after implementing in client app
|
|
||||||
app.exit();
|
|
||||||
})
|
|
||||||
.catch(function () {
|
|
||||||
// will be handling after implementing client app
|
|
||||||
app.exit();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// adds 'symphony' as a protocol
|
// adds 'symphony' as a protocol
|
||||||
|
@ -13,8 +13,7 @@ const isMac = require('../utils/misc.js').isMac;
|
|||||||
const libSymphonySearch = require('./searchLibrary');
|
const libSymphonySearch = require('./searchLibrary');
|
||||||
|
|
||||||
// Crypto Library
|
// Crypto Library
|
||||||
const Cryotp = require('../cryptoLib');
|
const Crypto = require('../cryptoLib');
|
||||||
const crypto = new Cryotp();
|
|
||||||
|
|
||||||
// Path for the exec file and the user data folder
|
// Path for the exec file and the user data folder
|
||||||
const userData = path.join(app.getPath('userData'));
|
const userData = path.join(app.getPath('userData'));
|
||||||
@ -23,9 +22,12 @@ const execPath = path.dirname(app.getPath('exe'));
|
|||||||
// Constants paths for temp indexing folders
|
// Constants paths for temp indexing folders
|
||||||
const TEMP_BATCH_INDEX_FOLDER = isDevEnv ? './data/temp_batch_indexes' : path.join(userData, 'data/temp_batch_indexes');
|
const TEMP_BATCH_INDEX_FOLDER = isDevEnv ? './data/temp_batch_indexes' : path.join(userData, 'data/temp_batch_indexes');
|
||||||
const TEMP_REAL_TIME_INDEX = isDevEnv ? './data/temp_realtime_index' : path.join(userData, 'data/temp_realtime_index');
|
const TEMP_REAL_TIME_INDEX = isDevEnv ? './data/temp_realtime_index' : path.join(userData, 'data/temp_realtime_index');
|
||||||
|
// Main User Index path
|
||||||
const INDEX_PREFIX = isDevEnv ? './data/search_index' : path.join(userData, 'data/search_index');
|
const INDEX_PREFIX = isDevEnv ? './data/search_index' : path.join(userData, 'data/search_index');
|
||||||
|
// Folder contains real time, batch and user index
|
||||||
const INDEX_DATA_FOLDER = isDevEnv ? './data' : path.join(userData, 'data');
|
const INDEX_DATA_FOLDER = isDevEnv ? './data' : path.join(userData, 'data');
|
||||||
const SEARCH_PERIOD_SUBTRACTOR = 3 * 31 * 24 * 60 * 60 * 1000;//3 months
|
//3 Months
|
||||||
|
const SEARCH_PERIOD_SUBTRACTOR = 3 * 31 * 24 * 60 * 60 * 1000;
|
||||||
const MINIMUM_DATE = '0000000000000';
|
const MINIMUM_DATE = '0000000000000';
|
||||||
const MAXIMUM_DATE = '9999999999999';
|
const MAXIMUM_DATE = '9999999999999';
|
||||||
const INDEX_VERSION = 'v1';
|
const INDEX_VERSION = 'v1';
|
||||||
@ -49,23 +51,23 @@ class Search {
|
|||||||
/**
|
/**
|
||||||
* Constructor for the SymphonySearchEngine library
|
* Constructor for the SymphonySearchEngine library
|
||||||
* @param userId (for the index folder name)
|
* @param userId (for the index folder name)
|
||||||
|
* @param key
|
||||||
*/
|
*/
|
||||||
constructor(userId) {
|
constructor(userId, key) {
|
||||||
this.isInitialized = false;
|
this.isInitialized = false;
|
||||||
this.userId = 'user_data';
|
this.userId = userId;
|
||||||
// Will be handling this in SEARCH-206
|
this.key = key;
|
||||||
this.key = "XrwVgWR4czB1a9scwvgRUNbXiN3W0oWq7oUBenyq7bo="; // temporary only
|
this.indexFolderName = INDEX_PREFIX + '_' + this.userId + '_' + INDEX_VERSION;
|
||||||
this.startIndexingFromDate = (new Date().getTime() - SEARCH_PERIOD_SUBTRACTOR).toString();
|
|
||||||
this.indexFolderName = INDEX_PREFIX + '_' + userId + '_' + INDEX_VERSION;
|
|
||||||
this.dataFolder = INDEX_DATA_FOLDER;
|
this.dataFolder = INDEX_DATA_FOLDER;
|
||||||
this.realTimeIndex = TEMP_REAL_TIME_INDEX;
|
this.realTimeIndex = TEMP_REAL_TIME_INDEX;
|
||||||
this.batchIndex = TEMP_BATCH_INDEX_FOLDER;
|
this.batchIndex = TEMP_BATCH_INDEX_FOLDER;
|
||||||
this.messageData = [];
|
this.messageData = [];
|
||||||
|
this.crypto = new Crypto(userId, key);
|
||||||
this.decryptAndInit();
|
this.decryptAndInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
decryptAndInit() {
|
decryptAndInit() {
|
||||||
crypto.decryption(this.key).then(() => {
|
this.crypto.decryption().then(() => {
|
||||||
this.init();
|
this.init();
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.init();
|
this.init();
|
||||||
@ -93,6 +95,7 @@ class Search {
|
|||||||
Search.indexValidator(this.indexFolderName);
|
Search.indexValidator(this.indexFolderName);
|
||||||
Search.indexValidator(this.realTimeIndex);
|
Search.indexValidator(this.realTimeIndex);
|
||||||
let indexDateStartFrom = new Date().getTime() - SEARCH_PERIOD_SUBTRACTOR;
|
let indexDateStartFrom = new Date().getTime() - SEARCH_PERIOD_SUBTRACTOR;
|
||||||
|
// Deleting all the messages except 3 Months from now
|
||||||
libSymphonySearch.symSEDeleteMessages(this.indexFolderName, null,
|
libSymphonySearch.symSEDeleteMessages(this.indexFolderName, null,
|
||||||
MINIMUM_DATE, indexDateStartFrom.toString());
|
MINIMUM_DATE, indexDateStartFrom.toString());
|
||||||
this.isInitialized = true;
|
this.isInitialized = true;
|
||||||
@ -131,11 +134,14 @@ class Search {
|
|||||||
* created from indexBatch()
|
* created from indexBatch()
|
||||||
*/
|
*/
|
||||||
mergeIndexBatches() {
|
mergeIndexBatches() {
|
||||||
libSymphonySearch.symSEMergePartialIndexAsync(this.indexFolderName, this.batchIndex, (err) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (err) {
|
libSymphonySearch.symSEMergePartialIndexAsync(this.indexFolderName, this.batchIndex, (err, res) => {
|
||||||
throw new Error(err);
|
if (err) {
|
||||||
}
|
reject(new Error(err));
|
||||||
libSymphonySearch.symSERemoveFolder(this.batchIndex)
|
}
|
||||||
|
libSymphonySearch.symSERemoveFolder(this.batchIndex);
|
||||||
|
resolve(res);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +192,18 @@ class Search {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypting the index after the merging the index
|
||||||
|
* to the main user index
|
||||||
|
*/
|
||||||
|
encryptIndex() {
|
||||||
|
this.crypto.encryption().then(() => {
|
||||||
|
return 'Success'
|
||||||
|
}).catch((e) => {
|
||||||
|
throw new Error(e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This returns the search results
|
* This returns the search results
|
||||||
* which returns a char *
|
* which returns a char *
|
||||||
|
Loading…
Reference in New Issue
Block a user