/home/ivoiecob/email.hirewise-va.com/modules/CoreParanoidEncryptionWebclientPlugin/js/manager.js
'use strict';
var
_ = require('underscore'),
TextUtils = require('%PathToCoreWebclientModule%/js/utils/Text.js'),
Utils = require('%PathToCoreWebclientModule%/js/utils/Common.js'),
Ajax = require('%PathToCoreWebclientModule%/js/Ajax.js'),
App = require('%PathToCoreWebclientModule%/js/App.js'),
Browser = require('%PathToCoreWebclientModule%/js/Browser.js'),
Screens = require('%PathToCoreWebclientModule%/js/Screens.js'),
Popups = require('%PathToCoreWebclientModule%/js/Popups.js'),
ConfirmPopup = require('%PathToCoreWebclientModule%/js/popups/ConfirmPopup.js'),
ConfirmEncryptionPopup = require('modules/%ModuleName%/js/popups/ConfirmEncryptionPopup.js'),
ConfirmUploadPopup = require('modules/%ModuleName%/js/popups/ConfirmUploadPopup.js'),
InitializationVectorPopup = require('modules/%ModuleName%/js/popups/InitializationVectorPopup.js'),
Settings = require('modules/%ModuleName%/js/Settings.js'),
Crypto = null,
OpenPgpEncryptor = null,
AwaitConfirmationQueue = [], //List of files waiting for the user to decide on encryption
isConfirmPopupShown = false,
FilesView = null
;
function IsHttpsEnable()
{
return window.location.protocol === "https:";
}
function ShowUploadPopup(sUid, oFileInfo, fUpload, fCancel, sErrorText)
{
if (isConfirmPopupShown)
{
AwaitConfirmationQueue.push({
sUid: sUid,
oFileInfo: oFileInfo
});
}
else
{
setTimeout(function () {
Popups.showPopup(ConfirmUploadPopup, [
fUpload,
fCancel,
AwaitConfirmationQueue.length,
_.map(AwaitConfirmationQueue, function(element) {
return element.oFileInfo.FileName;
}),
sErrorText
]);
}, 10);
isConfirmPopupShown = true;
AwaitConfirmationQueue.push({
sUid: sUid,
oFileInfo: oFileInfo
});
}
}
function StartModule (ModulesManager)
{
ModulesManager.run('SettingsWebclient', 'registerSettingsTab', [
function () { return require('modules/%ModuleName%/js/views/ParanoidEncryptionSettingsFormView.js'); },
Settings.HashModuleName,
TextUtils.i18n('%MODULENAME%/LABEL_SETTINGS_TAB')
]);
App.subscribeEvent('AbstractFileModel::FileDownload::before', function (oParams) {
if (!oParams.File || !oParams.File.IS_FILE) {
// it might be attachment, Paranoid doesn't work with them
return;
}
var
oFile = oParams.File,
oExtendedProps = oFile?.oExtendedProps || false,
iv = oExtendedProps?.InitializationVector || false,
sParanoidEncryptedKey = oExtendedProps?.ParanoidKey || false,
sParanoidEncryptedKeyShared = oExtendedProps?.ParanoidKeyShared || false,
bIsOwnFile = oFile.sOwnerName === App.getUserPublicId(),
bSharedWithMe = oFile.sharedWithMe()
;
//User can decrypt only own or shared files
if (!Settings.enableJscrypto() || !iv
|| !(bIsOwnFile || bSharedWithMe))
{
//regular upload will start in Jua in this case
}
else if (!IsHttpsEnable())
{
Screens.showError(TextUtils.i18n('%MODULENAME%/ERROR_HTTPS_NEEDED'));
oParams.CancelDownload = true;
}
else
{
oParams.CustomDownloadHandler = function () {
Crypto.downloadDividedFile(
oFile,
iv,
null,
null,
bSharedWithMe && sParanoidEncryptedKeyShared
? sParanoidEncryptedKeyShared
: sParanoidEncryptedKey
);
};
}
});
App.subscribeEvent('Jua::FileUpload::before', function (oParams) {
var
sUid = oParams.sUid,
sModuleName = oParams.sModuleName,
oFileInfo = oParams.oFileInfo,
fOnChunkEncryptCallback = oParams.fOnChunkReadyCallback,
fRegularUploadFileCallback = oParams.fRegularUploadFileCallback,
fCancelFunction = oParams.fCancelFunction,
fStartUploadCallback = function (oFileInfo, sUid, fOnChunkEncryptCallback) {
if (!Settings.AllowMultiChunkUpload && oFileInfo.File.size > Crypto.iChunkSize)
{
Screens.showError(TextUtils.i18n('%MODULENAME%/ERROR_FILE_SIZE_LIMIT', {'VALUE': Settings.ChunkSizeMb}));
fCancelFunction(sUid);
Crypto.oChunkQueue.isProcessed = false;
Crypto.checkQueue();
}
else
{
// Starts upload an encrypted file
Crypto.startUpload(
oFileInfo,
sUid,
fOnChunkEncryptCallback,
_.bind(function () {
fCancelFunction(sUid);
Crypto.oChunkQueue.isProcessed = false;
Crypto.checkQueue();
}, this)
);
}
},
fUpload = _.bind(function () {
AwaitConfirmationQueue.forEach(function (element) {
fRegularUploadFileCallback(element.sUid, element.oFileInfo);
});
AwaitConfirmationQueue = [];
isConfirmPopupShown = false;
}, this),
fEncrypt = _.bind(function () {
AwaitConfirmationQueue.forEach(function (element) {
// if another file is being uploaded now - add a file to the queue
Crypto.oChunkQueue.aFiles.push({
fStartUploadCallback: fStartUploadCallback,
oFileInfo: element.oFileInfo,
sUid: element.sUid,
fOnChunkEncryptCallback: fOnChunkEncryptCallback
});
});
AwaitConfirmationQueue = [];
isConfirmPopupShown = false;
if (!Crypto.oChunkQueue.isProcessed)
{
Crypto.oChunkQueue.isProcessed = true;
Crypto.checkQueue();
}
}),
fCancel = _.bind(function () {
AwaitConfirmationQueue.forEach(function (element) {
fCancelFunction(element.sUid);
});
AwaitConfirmationQueue = [];
isConfirmPopupShown = false;
})
;
if (Settings.enableJscrypto() &&
Settings.EncryptionAllowedModules &&
Settings.EncryptionAllowedModules.length > 0 &&
Settings.EncryptionAllowedModules.includes(sModuleName) &&
(
oParams.sStorageType === 'encrypted' ||
oParams.sStorageType === 'personal' && Settings.EnableInPersonalStorage
)
)
{
if (!IsHttpsEnable())
{
if (oParams.sStorageType === 'personal' && Settings.EnableInPersonalStorage)
{
//for AskMe encryption mode show dialog with warning and regular upload button
ShowUploadPopup(sUid, oFileInfo, fUpload, fCancel, TextUtils.i18n('%MODULENAME%/ERROR_HTTPS_NEEDED'));
}
else
{
//for Always encryption mode show error
Screens.showError(TextUtils.i18n('%MODULENAME%/ERROR_HTTPS_NEEDED'));
fCancelFunction(sUid);
}
}
else if (!oFileInfo.EncryptWithoutConfirm && oParams.sStorageType === 'personal' && Settings.EnableInPersonalStorage)
{
if (isConfirmPopupShown)
{
AwaitConfirmationQueue.push({
sUid: sUid,
oFileInfo: oFileInfo
});
}
else
{
setTimeout(function () {
Popups.showPopup(ConfirmEncryptionPopup, [
fEncrypt,
fUpload,
fCancel,
AwaitConfirmationQueue.length,
_.map(AwaitConfirmationQueue, function(element) {
return element.oFileInfo.FileName;
})
]);
}, 10);
isConfirmPopupShown = true;
AwaitConfirmationQueue.push({
sUid: sUid,
oFileInfo: oFileInfo
});
}
}
else
{
if (Crypto.oChunkQueue.isProcessed === true)
{ // if another file is being uploaded now - add a file to the queue
Crypto.oChunkQueue.aFiles.push({
fStartUploadCallback: fStartUploadCallback,
oFileInfo: oFileInfo,
sUid: sUid,
fOnChunkEncryptCallback: fOnChunkEncryptCallback
});
}
else
{ // If the queue is not busy - start uploading
fStartUploadCallback(oFileInfo, sUid, fOnChunkEncryptCallback);
}
}
}
else
{
fRegularUploadFileCallback(sUid, oFileInfo);
}
});
App.subscribeEvent('CFilesView::FileDownloadCancel', function (oParams) {
if (Settings.enableJscrypto() && IsHttpsEnable())
{
oParams.oFile.stopDownloading();
}
});
App.subscribeEvent('CFilesView::FileUploadCancel', function (oParams) {
if (Settings.enableJscrypto() && IsHttpsEnable())
{
//clear queue
Crypto.oChunkQueue.aFiles.forEach(function (oData, index, array) {
oParams.fOnUploadCancelCallback(oData.sUid, oData.oFileInfo.FileName);
});
Crypto.oChunkQueue.aFiles = [];
Crypto.stopUploading(oParams.sFileUploadUid , oParams.fOnUploadCancelCallback, oParams.sFileUploadName);
}
else if (_.isFunction(oParams.fOnUploadCancelCallback))
{
oParams.fOnUploadCancelCallback(oParams.sFileUploadUid, oParams.sFileUploadName);
}
});
App.subscribeEvent('Jua::FileUploadingError', function () {
if (Settings.enableJscrypto() && IsHttpsEnable())
{
Crypto.oChunkQueue.isProcessed = false;
Crypto.checkQueue();
}
});
App.subscribeEvent('FilesWebclient::ParseFile::after', function (aParams) {
let
oFile = aParams[0],
oExtendedProps = oFile?.oExtendedProps || false,
iv = oExtendedProps?.InitializationVector || false,
bIsEncrypted = !!iv,
sParanoidEncryptedKey = oExtendedProps?.ParanoidKey || false,
sParanoidEncryptedKeyShared = oExtendedProps?.ParanoidKeyShared || false,
bIsImage = (/\.(png|jpe?g|gif)$/).test(oFile.fileName().toLowerCase()),
bIsOwnFile = oFile.sOwnerName === App.getUserPublicId(),
bSharedWithMe = oFile.sharedWithMe()
;
if (bIsEncrypted)
{
oFile.thumbnailSrc('');
if (
(bIsOwnFile || bSharedWithMe)
&& bIsImage
&& Settings.enableJscrypto()
)
{// change view action for images
oFile.oActionsData.view.Handler = () => {
Crypto.viewEncryptedImage(
oFile,
iv,
bSharedWithMe && sParanoidEncryptedKeyShared
? sParanoidEncryptedKeyShared
: sParanoidEncryptedKey
);
};
}
else
{// remove view action for non-images
oFile.removeAction('view');
}
oFile.removeAction('list');
oFile.bIsSecure(true);
oFile.onSecureIconClick = (oItem) => {
Popups.showPopup(InitializationVectorPopup, [oFile, iv]);
};
}
});
App.subscribeEvent('FileViewerWebclientPlugin::FilesCollection::after', function (oParams) {
oParams.aFilesCollection(_.filter(oParams.aFilesCollection(), function (oArg) {
return !(typeof(oArg.oExtendedProps) !== 'undefined' && typeof(oArg.oExtendedProps.InitializationVector) !== 'undefined');
}));
});
Settings.enableJscrypto.subscribe(function(newValue) {
if (FilesView !== null)
{
FilesView.requestStorages();
}
});
App.subscribeEvent('FilesWebclient::ConstructView::after', function (oParams) {
if ('CFilesView' === oParams.Name)
{
FilesView = oParams.View;
var ComposeMessageWithAttachments = ModulesManager.run('MailWebclient', 'getComposeMessageWithAttachments');
if (_.isFunction(ComposeMessageWithAttachments))
{
FilesView.executeSend = function ()
{
var
aItems = this.selector.listCheckedAndSelected(),
aFileItems = _.filter(aItems, function (oItem) {
return oItem && oItem.IS_FILE;
}, this),
bHasEncrypted = false,
aFilesData = _.map(aFileItems, function (oItem) {
var bItemEncrypted = !!(oItem.oExtendedProps && oItem.oExtendedProps.InitializationVector)
bHasEncrypted = bHasEncrypted || bItemEncrypted;
return {
'Storage': oItem.storageType(),
'Path': oItem.path(),
'Name': oItem.id() || oItem.fileName(),
'IsEncrypted': bItemEncrypted
};
})
;
if (this.bAllowSendEmails && aFileItems.length > 0)
{
if (bHasEncrypted)
{
Popups.showPopup(ConfirmPopup, [TextUtils.i18n('%MODULENAME%/ALERT_SEND_ENCRYPTED_FILES'), function (bSendAnyway) {
if (bSendAnyway)
{
Ajax.send('Files', 'SaveFilesAsTempFiles', { 'Files': aFilesData }, function (oResponse) {
if (oResponse.Result)
{
ComposeMessageWithAttachments(oResponse.Result);
}
}, this);
}
}.bind(this)]);
}
else
{
Ajax.send('Files', 'SaveFilesAsTempFiles', { 'Files': aFilesData }, function (oResponse) {
if (oResponse.Result)
{
ComposeMessageWithAttachments(oResponse.Result);
}
}, this);
}
}
};
FilesView.sendCommand = Utils.createCommand(FilesView, FilesView.executeSend, function () {
if (!this.isZipFolder() && this.allSelectedFilesReady())
{
var
aItems = this.selector.listCheckedAndSelected(),
aFileItems = _.filter(aItems, function (oItem) {
return oItem && oItem.IS_FILE;
}, this)
;
return (aFileItems.length > 0);
}
return false;
});
}
}
});
const PrepareShares = require('modules/%ModuleName%/js/utils/PrepareShares.js');
App.subscribeEvent('SharedFiles::UpdateShare::before', PrepareShares.onBeforeUpdateShare);
App.subscribeEvent('SharedFiles::OpenFilesSharePopup', oParams => {
if (oParams.IsDir)
{
oParams.DialogHintText(TextUtils.i18n('%MODULENAME%/INFO_SHARING_FOLDER'));
}
});
}
module.exports = function (oAppData) {
Settings.init(oAppData);
return {
/**
* Runs before application start. Subscribes to the event before post displaying.
*
* @param {Object} ModulesManager
*/
start: function (ModulesManager) {
Crypto = require('modules/%ModuleName%/js/CCrypto.js');
OpenPgpEncryptor = ModulesManager.run('OpenPgpWebclient', 'getOpenPgpEncryptor');
var bBlobSavingEnable = window.Blob && window.URL && _.isFunction(window.URL.createObjectURL);
// Module can't work without saving blob and shouldn't be initialized.
if (bBlobSavingEnable)
{
if (Browser.chrome && !IsHttpsEnable())
{
// Module can't work without https.0
// Module should be initialized to display message about https enabling.
StartModule(ModulesManager);
}
else if (window.crypto && window.crypto.subtle)
{
if (!Browser.edge)
{
StartModule(ModulesManager);
}
// var sPassword = window.crypto.getRandomValues(new Uint8Array(16));
// // window.crypto can't work with PBKDF2 in Edge.
// // Checks if it works (in case if it will work in Edge one day) and then inizializes module.
// window.crypto.subtle.importKey('raw', sPassword, {name: 'PBKDF2'}, false, ['deriveBits', 'deriveKey'])
// .then(function () {
// StartModule(ModulesManager);
// });
}
}
},
getConfirmEncryptionPopup () {
return Settings.EnableInPersonalStorage ? ConfirmEncryptionPopup : false;
},
isEnabled () {
return Settings.enableJscrypto() && IsHttpsEnable();
}
};
};