SymphonyElectron/js/cryptoLib/index.js
Keerthi Niranjan c8b45e091e 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
2017-08-28 12:13:58 +05:30

169 lines
5.6 KiB
JavaScript

'use strict';
const electron = require('electron');
const app = electron.app;
const path = require('path');
const fs = require('fs');
const archiver = require('archiver');
const extract = require('extract-zip');
const isDevEnv = require('../utils/misc.js').isDevEnv;
const crypto = require('./crypto');
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 TEMPORARY_PATH = isDevEnv ? path.join(__dirname, '..', '..') : userData;
class Crypto {
constructor(userId, key) {
let INDEX_VERSION = 'v1';
this.indexDataFolder = INDEX_DATA_FOLDER + '_' + userId + '_' + INDEX_VERSION;
this.permanentIndexFolderName = 'search_index_' + userId + '_' + INDEX_VERSION;
this.dump = TEMPORARY_PATH;
this.key = key;
this.extractToPath = `${TEMPORARY_PATH}/data/${this.permanentIndexFolderName}`;
this.encryptedIndex = `${TEMPORARY_PATH}/${this.permanentIndexFolderName}.enc`;
this.dataFolder = DATA_FOLDER;
this.zipErrored = false;
}
/**
* Creates a zip of the data folder and encrypting
* removing the data folder and the dump files
* @returns {Promise}
*/
encryption() {
return new Promise((resolve, reject) => {
if (!fs.existsSync(this.indexDataFolder)){
// will be handling after implementing in client app
reject();
return;
}
const zipArchive = archiver('zip');
let output = fs.createWriteStream(`${this.dump}/${this.permanentIndexFolderName}.zip`);
zipArchive.on('end', () => {
if (!fs.existsSync(`${this.dump}/${this.permanentIndexFolderName}.zip`)){
// will be handling after implementing in client app
reject();
return;
}
const input = fs.createReadStream(`${this.dump}/${this.permanentIndexFolderName}.zip`);
const outputEncryption = fs.createWriteStream(this.encryptedIndex);
let config = {
key: this.key
};
const encrypt = crypto.encrypt(config);
input.pipe(encrypt).pipe(outputEncryption).on('finish', (err) => {
if (err) {
reject(new Error(err));
}
if (!this.zipErrored) {
fs.unlinkSync(`${this.dump}/${this.permanentIndexFolderName}.zip`);
resolve('Success');
}
});
});
zipArchive.pipe(output);
zipArchive.directory(this.indexDataFolder + '/', false);
zipArchive.finalize((err) => {
if (err) {
this.zipErrored = true;
reject(new Error(err));
}
});
});
}
/**
* Decrypting the .enc file and unzipping
* removing the .enc file and the dump files
* @returns {Promise}
*/
decryption() {
return new Promise((resolve, reject) => {
if (!fs.existsSync(this.encryptedIndex)){
// will be handling after implementing in client app
reject();
return;
}
const input = fs.createReadStream(this.encryptedIndex);
const output = fs.createWriteStream(`${this.dump}/decrypted.zip`);
let config = {
key: this.key
};
const decrypt = crypto.decrypt(config);
input.pipe(decrypt).pipe(output).on('finish', () => {
if (!fs.existsSync(`${this.dump}/decrypted.zip`)){
// will be handling after implementing in client app
reject();
return;
}
let readStream = fs.createReadStream(`${this.dump}/decrypted.zip`);
readStream
.on('data', (data) => {
if (!data) {
reject(new Error("error reading zip"));
}
extractZip();
})
.on('error', (error) => {
reject(new Error(error.message));
});
});
let extractZip = () => {
extract(`${this.dump}/decrypted.zip`, {dir: `${this.extractToPath}`}, (err) => {
if (err) {
reject(new Error(err));
}
fs.unlink(`${this.dump}/decrypted.zip`, () => {
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
* @param location
*/
static deleteFolderRecursive(location) {
if (fs.existsSync(location)) {
fs.readdirSync(location).forEach((file) => {
let curPath = location + "/" + file;
if (fs.lstatSync(curPath).isDirectory()) {
Crypto.deleteFolderRecursive(curPath);
} else {
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(location);
}
}
}
module.exports = Crypto;