mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Source refactoring
This commit is contained in:
parent
09b04740e7
commit
104ac0806a
27 changed files with 204 additions and 715 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -5,7 +5,6 @@
|
||||||
/rainloop.sublime-project
|
/rainloop.sublime-project
|
||||||
/rainloop.sublime-workspace
|
/rainloop.sublime-workspace
|
||||||
/rainloop/v/0.0.0/static/css/*.css
|
/rainloop/v/0.0.0/static/css/*.css
|
||||||
/rainloop/v/0.0.0/static/js/*.js
|
|
||||||
/rainloop/v/0.0.0/static/js/**/*.js
|
/rainloop/v/0.0.0/static/js/**/*.js
|
||||||
/node_modules
|
/node_modules
|
||||||
/build/local
|
/build/local
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@
|
||||||
"jquery" : true,
|
"jquery" : true,
|
||||||
|
|
||||||
"globals": {
|
"globals": {
|
||||||
|
"RL_COMMUNITY" : true,
|
||||||
"module" : true,
|
"module" : true,
|
||||||
"require" : true,
|
"require" : true,
|
||||||
"ko" : true,
|
"ko" : true,
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,11 @@
|
||||||
*/
|
*/
|
||||||
Globals.startMicrotime = (new window.Date()).getTime();
|
Globals.startMicrotime = (new window.Date()).getTime();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
Globals.community = RL_COMMUNITY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {?}
|
* @type {?}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@
|
||||||
*/
|
*/
|
||||||
HtmlEditor.prototype.clearSignatureSigns = function (sText)
|
HtmlEditor.prototype.clearSignatureSigns = function (sText)
|
||||||
{
|
{
|
||||||
return sText.replace(/(\u0002|\u0003|\u200C|\u200D)/g, '');
|
return sText.replace(/(\u200C|<x-signature>|<\/x-signature>)/g, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -861,10 +861,7 @@
|
||||||
;
|
;
|
||||||
|
|
||||||
sText = sHtml
|
sText = sHtml
|
||||||
// specials for signature
|
.replace(/<x-signature>([\s\S]*)<\/x-signature>/gm, '\u200C$1\u200C')
|
||||||
.replace(/\u0002\u0002/g, '\u200C\u200C')
|
|
||||||
.replace(/\u0003\u0003/g, '\u200D\u200D')
|
|
||||||
|
|
||||||
.replace(/<pre[^>]*>([\s\S\r\n]*)<\/pre>/gmi, convertPre)
|
.replace(/<pre[^>]*>([\s\S\r\n]*)<\/pre>/gmi, convertPre)
|
||||||
.replace(/[\s]+/gm, ' ')
|
.replace(/[\s]+/gm, ' ')
|
||||||
.replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gmi, fixAttibuteValue)
|
.replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gmi, fixAttibuteValue)
|
||||||
|
|
@ -1012,16 +1009,12 @@
|
||||||
sPlain = aText.join("\n");
|
sPlain = aText.join("\n");
|
||||||
|
|
||||||
sPlain = sPlain
|
sPlain = sPlain
|
||||||
|
|
||||||
// specials for signature
|
|
||||||
.replace(/\u200C\u200C/g, '\u0002\u0002')
|
|
||||||
.replace(/\u200D\u200D/g, '\u0003\u0003')
|
|
||||||
|
|
||||||
// .replace(/~~~\/blockquote~~~\n~~~blockquote~~~/g, '\n')
|
// .replace(/~~~\/blockquote~~~\n~~~blockquote~~~/g, '\n')
|
||||||
.replace(/&/g, '&')
|
.replace(/&/g, '&')
|
||||||
.replace(/>/g, '>').replace(/</g, '<')
|
.replace(/>/g, '>').replace(/</g, '<')
|
||||||
.replace(/~~~blockquote~~~[\s]*/g, '<blockquote>')
|
.replace(/~~~blockquote~~~[\s]*/g, '<blockquote>')
|
||||||
.replace(/[\s]*~~~\/blockquote~~~/g, '</blockquote>')
|
.replace(/[\s]*~~~\/blockquote~~~/g, '</blockquote>')
|
||||||
|
.replace(/\u200C([\s\S]*)\u200C/g, '<x-signature>$1</x-signature>')
|
||||||
.replace(/\n/g, '<br />')
|
.replace(/\n/g, '<br />')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,8 +38,16 @@
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/Login'),
|
kn.addSettingsViewModel(require('Settings/Admin/Login'),
|
||||||
'AdminSettingsLogin', 'TABS_LABELS/LABEL_LOGIN_NAME', 'login');
|
'AdminSettingsLogin', 'TABS_LABELS/LABEL_LOGIN_NAME', 'login');
|
||||||
|
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/Branding'),
|
if (RL_COMMUNITY)
|
||||||
'AdminSettingsBranding', 'TABS_LABELS/LABEL_BRANDING_NAME', 'branding');
|
{
|
||||||
|
kn.addSettingsViewModel(require('Settings/Admin/Branding'),
|
||||||
|
'AdminSettingsBranding', 'TABS_LABELS/LABEL_BRANDING_NAME', 'branding');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
kn.addSettingsViewModel(require('Settings/Admin/Prem/Branding'),
|
||||||
|
'AdminSettingsBranding', 'TABS_LABELS/LABEL_BRANDING_NAME', 'branding');
|
||||||
|
}
|
||||||
|
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/Contacts'),
|
kn.addSettingsViewModel(require('Settings/Admin/Contacts'),
|
||||||
'AdminSettingsContacts', 'TABS_LABELS/LABEL_CONTACTS_NAME', 'contacts');
|
'AdminSettingsContacts', 'TABS_LABELS/LABEL_CONTACTS_NAME', 'contacts');
|
||||||
|
|
@ -56,11 +64,14 @@
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/Plugins'),
|
kn.addSettingsViewModel(require('Settings/Admin/Plugins'),
|
||||||
'AdminSettingsPlugins', 'TABS_LABELS/LABEL_PLUGINS_NAME', 'plugins');
|
'AdminSettingsPlugins', 'TABS_LABELS/LABEL_PLUGINS_NAME', 'plugins');
|
||||||
|
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/Packages'),
|
if (!RL_COMMUNITY)
|
||||||
'AdminSettingsPackages', 'TABS_LABELS/LABEL_PACKAGES_NAME', 'packages');
|
{
|
||||||
|
kn.addSettingsViewModel(require('Settings/Admin/Prem/Packages'),
|
||||||
|
'AdminSettingsPackages', 'TABS_LABELS/LABEL_PACKAGES_NAME', 'packages');
|
||||||
|
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/Licensing'),
|
kn.addSettingsViewModel(require('Settings/Admin/Prem/Licensing'),
|
||||||
'AdminSettingsLicensing', 'TABS_LABELS/LABEL_LICENSING_NAME', 'licensing');
|
'AdminSettingsLicensing', 'TABS_LABELS/LABEL_LICENSING_NAME', 'licensing');
|
||||||
|
}
|
||||||
|
|
||||||
kn.addSettingsViewModel(require('Settings/Admin/About'),
|
kn.addSettingsViewModel(require('Settings/Admin/About'),
|
||||||
'AdminSettingsAbout', 'TABS_LABELS/LABEL_ABOUT_NAME', 'about');
|
'AdminSettingsAbout', 'TABS_LABELS/LABEL_ABOUT_NAME', 'about');
|
||||||
|
|
|
||||||
2
dev/Settings/.gitignore
vendored
Normal file
2
dev/Settings/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/Admin/Prem/**
|
||||||
|
/Admin/_Prem/**
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
Translator = require('Common/Translator'),
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
CoreStore = require('Stores/Admin/Core')
|
CoreStore = require('Stores/Admin/Core'),
|
||||||
|
AppStore = require('Stores/Admin/App')
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -34,6 +35,8 @@
|
||||||
this.coreRemoteRelease = CoreStore.coreRemoteRelease;
|
this.coreRemoteRelease = CoreStore.coreRemoteRelease;
|
||||||
this.coreVersionCompare = CoreStore.coreVersionCompare;
|
this.coreVersionCompare = CoreStore.coreVersionCompare;
|
||||||
|
|
||||||
|
this.community = RL_COMMUNITY || AppStore.community();
|
||||||
|
|
||||||
this.coreRemoteVersionHtmlDesc = ko.computed(function () {
|
this.coreRemoteVersionHtmlDesc = ko.computed(function () {
|
||||||
Translator.trigger();
|
Translator.trigger();
|
||||||
return Translator.i18n('TAB_ABOUT/HTML_NEW_VERSION', {'VERSION': this.coreRemoteVersion()});
|
return Translator.i18n('TAB_ABOUT/HTML_NEW_VERSION', {'VERSION': this.coreRemoteVersion()});
|
||||||
|
|
@ -78,7 +81,7 @@
|
||||||
|
|
||||||
AboutAdminSettings.prototype.onBuild = function ()
|
AboutAdminSettings.prototype.onBuild = function ()
|
||||||
{
|
{
|
||||||
if (this.access())
|
if (this.access() && !this.community)
|
||||||
{
|
{
|
||||||
require('App/Admin').reloadCoreData();
|
require('App/Admin').reloadCoreData();
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +89,7 @@
|
||||||
|
|
||||||
AboutAdminSettings.prototype.updateCoreData = function ()
|
AboutAdminSettings.prototype.updateCoreData = function ()
|
||||||
{
|
{
|
||||||
if (!this.coreUpdating())
|
if (!this.coreUpdating() && !this.community)
|
||||||
{
|
{
|
||||||
require('App/Admin').updateCoreData();
|
require('App/Admin').updateCoreData();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
this.loginPowered = ko.observable(!!Settings.settingsGet('LoginPowered'));
|
this.loginPowered = ko.observable(!!Settings.settingsGet('LoginPowered'));
|
||||||
|
|
||||||
|
this.community = RL_COMMUNITY || AppStore.community();
|
||||||
}
|
}
|
||||||
|
|
||||||
BrandingAdminSettings.prototype.onBuild = function ()
|
BrandingAdminSettings.prototype.onBuild = function ()
|
||||||
|
|
@ -76,85 +78,6 @@
|
||||||
Remote = require('Remote/Admin/Ajax')
|
Remote = require('Remote/Admin/Ajax')
|
||||||
;
|
;
|
||||||
|
|
||||||
if (this.capa())
|
|
||||||
{
|
|
||||||
_.delay(function () {
|
|
||||||
|
|
||||||
var
|
|
||||||
f1 = Utils.settingsSaveHelperSimpleFunction(self.loginLogo.trigger, self),
|
|
||||||
f2 = Utils.settingsSaveHelperSimpleFunction(self.loginDescription.trigger, self),
|
|
||||||
f3 = Utils.settingsSaveHelperSimpleFunction(self.loginCss.trigger, self),
|
|
||||||
f4 = Utils.settingsSaveHelperSimpleFunction(self.userLogo.trigger, self),
|
|
||||||
f5 = Utils.settingsSaveHelperSimpleFunction(self.userLogoTitle.trigger, self),
|
|
||||||
f6 = Utils.settingsSaveHelperSimpleFunction(self.loginBackground.trigger, self),
|
|
||||||
f7 = Utils.settingsSaveHelperSimpleFunction(self.userCss.trigger, self),
|
|
||||||
f8 = Utils.settingsSaveHelperSimpleFunction(self.welcomePageUrl.trigger, self),
|
|
||||||
f9 = Utils.settingsSaveHelperSimpleFunction(self.welcomePageDisplay.trigger, self)
|
|
||||||
;
|
|
||||||
|
|
||||||
self.loginLogo.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f1, {
|
|
||||||
'LoginLogo': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.loginDescription.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f2, {
|
|
||||||
'LoginDescription': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.loginCss.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f3, {
|
|
||||||
'LoginCss': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.userLogo.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f4, {
|
|
||||||
'UserLogo': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.userLogoTitle.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f5, {
|
|
||||||
'UserLogoTitle': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.loginBackground.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f6, {
|
|
||||||
'LoginBackground': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.userCss.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f7, {
|
|
||||||
'UserCss': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.welcomePageUrl.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f8, {
|
|
||||||
'WelcomePageUrl': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.welcomePageDisplay.subscribe(function (sValue) {
|
|
||||||
Remote.saveAdminConfig(f9, {
|
|
||||||
'WelcomePageDisplay': Utils.trim(sValue)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
self.loginPowered.subscribe(function (bValue) {
|
|
||||||
Remote.saveAdminConfig(null, {
|
|
||||||
'LoginPowered': bValue ? '1' : '0'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
}, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
_.delay(function () {
|
_.delay(function () {
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var
|
|
||||||
ko = require('ko'),
|
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
|
||||||
LicenseStore = require('Stores/Admin/License')
|
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function LicensingAdminSettings()
|
|
||||||
{
|
|
||||||
this.licensing = LicenseStore.licensing;
|
|
||||||
this.licensingProcess = LicenseStore.licensingProcess;
|
|
||||||
this.licenseValid = LicenseStore.licenseValid;
|
|
||||||
this.licenseExpired = LicenseStore.licenseExpired;
|
|
||||||
this.licenseError = LicenseStore.licenseError;
|
|
||||||
this.licenseTrigger = LicenseStore.licenseTrigger;
|
|
||||||
|
|
||||||
this.adminDomain = ko.observable('');
|
|
||||||
this.subscriptionEnabled = ko.observable(!!Settings.settingsGet('SubscriptionEnabled'));
|
|
||||||
|
|
||||||
this.licenseTrigger.subscribe(function () {
|
|
||||||
if (this.subscriptionEnabled())
|
|
||||||
{
|
|
||||||
require('App/Admin').reloadLicensing(true);
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
LicensingAdminSettings.prototype.onBuild = function ()
|
|
||||||
{
|
|
||||||
if (this.subscriptionEnabled())
|
|
||||||
{
|
|
||||||
require('App/Admin').reloadLicensing(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LicensingAdminSettings.prototype.onShow = function ()
|
|
||||||
{
|
|
||||||
this.adminDomain(Settings.settingsGet('AdminDomain'));
|
|
||||||
};
|
|
||||||
|
|
||||||
LicensingAdminSettings.prototype.showActivationForm = function ()
|
|
||||||
{
|
|
||||||
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Activate'));
|
|
||||||
};
|
|
||||||
|
|
||||||
LicensingAdminSettings.prototype.showTrialForm = function ()
|
|
||||||
{
|
|
||||||
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Activate'), [true]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
LicensingAdminSettings.prototype.licenseIsUnlim = function ()
|
|
||||||
{
|
|
||||||
return 1898625600 === this.licenseExpired() || 1898625700 === this.licenseExpired();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
LicensingAdminSettings.prototype.licenseExpiredMomentValue = function ()
|
|
||||||
{
|
|
||||||
var
|
|
||||||
moment = require('moment'),
|
|
||||||
iTime = this.licenseExpired(),
|
|
||||||
oM = moment.unix(iTime)
|
|
||||||
;
|
|
||||||
|
|
||||||
return this.licenseIsUnlim() ? 'Never' :
|
|
||||||
(iTime && (oM.format('LL') + ' (' + oM.from(moment()) + ')'));
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = LicensingAdminSettings;
|
|
||||||
|
|
||||||
}());
|
|
||||||
|
|
@ -1,113 +0,0 @@
|
||||||
|
|
||||||
(function () {
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var
|
|
||||||
window = require('window'),
|
|
||||||
_ = require('_'),
|
|
||||||
ko = require('ko'),
|
|
||||||
|
|
||||||
Enums = require('Common/Enums'),
|
|
||||||
Translator = require('Common/Translator'),
|
|
||||||
|
|
||||||
PackageStore = require('Stores/Admin/Package'),
|
|
||||||
Remote = require('Remote/Admin/Ajax')
|
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function PackagesAdminSettings()
|
|
||||||
{
|
|
||||||
this.packagesError = ko.observable('');
|
|
||||||
|
|
||||||
this.packages = PackageStore.packages;
|
|
||||||
this.packagesReal = PackageStore.packagesReal;
|
|
||||||
this.packagesMainUpdatable = PackageStore.packagesMainUpdatable;
|
|
||||||
|
|
||||||
this.packagesCurrent = this.packages.filter(function (oItem) {
|
|
||||||
return oItem && '' !== oItem['installed'] && !oItem['compare'];
|
|
||||||
});
|
|
||||||
|
|
||||||
this.packagesAvailableForUpdate = this.packages.filter(function (oItem) {
|
|
||||||
return oItem && '' !== oItem['installed'] && !!oItem['compare'];
|
|
||||||
});
|
|
||||||
|
|
||||||
this.packagesAvailableForInstallation = this.packages.filter(function (oItem) {
|
|
||||||
return oItem && '' === oItem['installed'];
|
|
||||||
});
|
|
||||||
|
|
||||||
this.visibility = ko.computed(function () {
|
|
||||||
return PackageStore.packages.loading() ? 'visible' : 'hidden';
|
|
||||||
}, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
PackagesAdminSettings.prototype.onShow = function ()
|
|
||||||
{
|
|
||||||
this.packagesError('');
|
|
||||||
};
|
|
||||||
|
|
||||||
PackagesAdminSettings.prototype.onBuild = function ()
|
|
||||||
{
|
|
||||||
require('App/Admin').reloadPackagesList();
|
|
||||||
};
|
|
||||||
|
|
||||||
PackagesAdminSettings.prototype.requestHelper = function (oPackage, bInstall)
|
|
||||||
{
|
|
||||||
var self = this;
|
|
||||||
return function (sResult, oData) {
|
|
||||||
|
|
||||||
if (Enums.StorageResultType.Success !== sResult || !oData || !oData.Result)
|
|
||||||
{
|
|
||||||
if (oData && oData.ErrorCode)
|
|
||||||
{
|
|
||||||
self.packagesError(Translator.getNotification(oData.ErrorCode));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self.packagesError(Translator.getNotification(
|
|
||||||
bInstall ? Enums.Notification.CantInstallPackage : Enums.Notification.CantDeletePackage));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_.each(self.packages(), function (oItem) {
|
|
||||||
if (oItem && oPackage && oItem['loading']() && oPackage['file'] === oItem['file'])
|
|
||||||
{
|
|
||||||
oPackage['loading'](false);
|
|
||||||
oItem['loading'](false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Enums.StorageResultType.Success === sResult && oData && oData.Result && oData.Result['Reload'])
|
|
||||||
{
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
require('App/Admin').reloadPackagesList();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
PackagesAdminSettings.prototype.deletePackage = function (oPackage)
|
|
||||||
{
|
|
||||||
if (oPackage)
|
|
||||||
{
|
|
||||||
oPackage['loading'](true);
|
|
||||||
Remote.packageDelete(this.requestHelper(oPackage, false), oPackage);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PackagesAdminSettings.prototype.installPackage = function (oPackage)
|
|
||||||
{
|
|
||||||
if (oPackage)
|
|
||||||
{
|
|
||||||
oPackage['loading'](true);
|
|
||||||
Remote.packageInstall(this.requestHelper(oPackage, true), oPackage);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = PackagesAdminSettings;
|
|
||||||
|
|
||||||
}());
|
|
||||||
|
|
@ -12,7 +12,10 @@
|
||||||
Translator = require('Common/Translator'),
|
Translator = require('Common/Translator'),
|
||||||
|
|
||||||
Settings = require('Storage/Settings'),
|
Settings = require('Storage/Settings'),
|
||||||
|
|
||||||
|
AppStore = require('Stores/Admin/App'),
|
||||||
PluginStore = require('Stores/Admin/Plugin'),
|
PluginStore = require('Stores/Admin/Plugin'),
|
||||||
|
|
||||||
Remote = require('Remote/Admin/Ajax')
|
Remote = require('Remote/Admin/Ajax')
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -26,6 +29,8 @@
|
||||||
this.plugins = PluginStore.plugins;
|
this.plugins = PluginStore.plugins;
|
||||||
this.pluginsError = PluginStore.plugins.error;
|
this.pluginsError = PluginStore.plugins.error;
|
||||||
|
|
||||||
|
this.community = RL_COMMUNITY || AppStore.community();
|
||||||
|
|
||||||
this.visibility = ko.computed(function () {
|
this.visibility = ko.computed(function () {
|
||||||
return PluginStore.plugins.loading() ? 'visible' : 'hidden';
|
return PluginStore.plugins.loading() ? 'visible' : 'hidden';
|
||||||
}, this);
|
}, this);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
this.interfaceAnimation.valueHasMutated();
|
this.interfaceAnimation.valueHasMutated();
|
||||||
|
|
||||||
this.prem = ko.observable(false);
|
this.prem = ko.observable(false);
|
||||||
|
this.community = ko.observable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppStore.prototype.populate = function()
|
AppStore.prototype.populate = function()
|
||||||
|
|
@ -39,6 +40,7 @@
|
||||||
this.interfaceAnimation(!!Settings.settingsGet('InterfaceAnimation'));
|
this.interfaceAnimation(!!Settings.settingsGet('InterfaceAnimation'));
|
||||||
|
|
||||||
this.prem(!!Settings.settingsGet('PremType'));
|
this.prem(!!Settings.settingsGet('PremType'));
|
||||||
|
this.community(!!Settings.settingsGet('Community'));
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = AppStore;
|
module.exports = AppStore;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
this.version = ko.observable(Settings.settingsGet('Version'));
|
this.version = ko.observable(Settings.settingsGet('Version'));
|
||||||
|
|
||||||
this.capa = !!Settings.settingsGet('PremType');
|
this.capa = !!Settings.settingsGet('PremType');
|
||||||
|
this.community = RL_COMMUNITY;
|
||||||
|
|
||||||
this.adminManLoading = ko.computed(function () {
|
this.adminManLoading = ko.computed(function () {
|
||||||
return '000' !== [
|
return '000' !== [
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,11 @@
|
||||||
{
|
{
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
if (0 < this.messageListChecked().length)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
window.clearTimeout(this.iGoToUpUpOrDownDownTimeout);
|
window.clearTimeout(this.iGoToUpUpOrDownDownTimeout);
|
||||||
this.iGoToUpUpOrDownDownTimeout = window.setTimeout(function () {
|
this.iGoToUpUpOrDownDownTimeout = window.setTimeout(function () {
|
||||||
|
|
||||||
|
|
|
||||||
37
gulpfile.js
37
gulpfile.js
|
|
@ -6,6 +6,7 @@ var
|
||||||
cfg = {
|
cfg = {
|
||||||
devVersion: '0.0.0',
|
devVersion: '0.0.0',
|
||||||
releasesPath: 'build/dist/releases',
|
releasesPath: 'build/dist/releases',
|
||||||
|
community: true,
|
||||||
|
|
||||||
rainloopBuilded: false,
|
rainloopBuilded: false,
|
||||||
destPath: '',
|
destPath: '',
|
||||||
|
|
@ -220,6 +221,16 @@ gulp.task('css:main-begin', ['less:main'], function() {
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gulp.task('package:community-on', function() {
|
||||||
|
cfg.community = true;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('package:community-off', function() {
|
||||||
|
cfg.community = false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
gulp.task('css:clear-less', ['css:main-begin'], function() {
|
gulp.task('css:clear-less', ['css:main-begin'], function() {
|
||||||
|
|
||||||
return gulp.src(cfg.paths.staticCSS + cfg.paths.less.main.name, {read: false})
|
return gulp.src(cfg.paths.staticCSS + cfg.paths.less.main.name, {read: false})
|
||||||
|
|
@ -290,6 +301,7 @@ gulp.task('js:webpack:clear', function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('js:webpack', ['js:webpack:clear'], function(callback) {
|
gulp.task('js:webpack', ['js:webpack:clear'], function(callback) {
|
||||||
|
|
||||||
var
|
var
|
||||||
webpack = require('webpack'),
|
webpack = require('webpack'),
|
||||||
webpackCfg = require('./webpack.config.js')
|
webpackCfg = require('./webpack.config.js')
|
||||||
|
|
@ -300,6 +312,13 @@ gulp.task('js:webpack', ['js:webpack:clear'], function(callback) {
|
||||||
webpackCfg.output.publicPath = cfg.paths.staticJS;
|
webpackCfg.output.publicPath = cfg.paths.staticJS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (webpackCfg && webpackCfg.plugins)
|
||||||
|
{
|
||||||
|
webpackCfg.plugins.push(new webpack.DefinePlugin({
|
||||||
|
'RL_COMMUNITY': !!cfg.community
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
webpack(webpackCfg, function(err, stats) {
|
webpack(webpackCfg, function(err, stats) {
|
||||||
if (err) {
|
if (err) {
|
||||||
throw new gutil.PluginError('webpack', err);
|
throw new gutil.PluginError('webpack', err);
|
||||||
|
|
@ -466,7 +485,7 @@ gulp.task('rainloop:setup', ['rainloop:copy'], function() {
|
||||||
cfg.destPath = cfg.releasesPath + '/webmail/' + versionFull + '/';
|
cfg.destPath = cfg.releasesPath + '/webmail/' + versionFull + '/';
|
||||||
cfg.cleanPath = dist;
|
cfg.cleanPath = dist;
|
||||||
cfg.zipSrcPath = dist;
|
cfg.zipSrcPath = dist;
|
||||||
cfg.zipFile = 'rainloop-' + versionFull + '.zip';
|
cfg.zipFile = 'rainloop-' + (cfg.community ? 'community-' : '') + versionFull + '.zip';
|
||||||
cfg.md5File = cfg.zipFile;
|
cfg.md5File = cfg.zipFile;
|
||||||
|
|
||||||
cfg.rainloopBuilded = true;
|
cfg.rainloopBuilded = true;
|
||||||
|
|
@ -538,7 +557,7 @@ gulp.task('rainloop:owncloud:setup', ['rainloop:owncloud:copy',
|
||||||
cfg.destPath = cfg.releasesPath + '/owncloud/' + versionFull + '/';
|
cfg.destPath = cfg.releasesPath + '/owncloud/' + versionFull + '/';
|
||||||
cfg.cleanPath = dist;
|
cfg.cleanPath = dist;
|
||||||
cfg.zipSrcPath = dist;
|
cfg.zipSrcPath = dist;
|
||||||
cfg.zipFile = 'rainloop-owncloud-app-' + versionFull + '.zip';
|
cfg.zipFile = 'rainloop-owncloud-app-' + (cfg.community ? '' : 'premium-') + versionFull + '.zip';
|
||||||
cfg.md5File = cfg.zipFile;
|
cfg.md5File = cfg.zipFile;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
@ -562,12 +581,16 @@ gulp.task('default', ['js:libs', 'js:boot', 'js:openpgp', 'js:min', 'css:main:mi
|
||||||
gulp.task('fast', ['js:app', 'js:admin', 'js:chunks', 'css:main']);
|
gulp.task('fast', ['js:app', 'js:admin', 'js:chunks', 'css:main']);
|
||||||
|
|
||||||
gulp.task('rainloop:start', ['js:lint', 'rainloop:copy', 'rainloop:setup']);
|
gulp.task('rainloop:start', ['js:lint', 'rainloop:copy', 'rainloop:setup']);
|
||||||
gulp.task('rainloop', ['rainloop:start', 'rainloop:zip', 'rainloop:md5', 'rainloop:clean']);
|
|
||||||
|
|
||||||
gulp.task('owncloud', ['rainloop:owncloud:copy',
|
gulp.task('rainloop', ['package:community-on', 'rainloop:start', 'rainloop:zip', 'rainloop:md5', 'rainloop:clean']);
|
||||||
|
gulp.task('rainloop+', ['package:community-off', 'rainloop']);
|
||||||
|
|
||||||
|
gulp.task('owncloud', ['package:community-on', 'rainloop:owncloud:copy',
|
||||||
'rainloop:owncloud:copy-rainloop', 'rainloop:owncloud:copy-rainloop:clean',
|
'rainloop:owncloud:copy-rainloop', 'rainloop:owncloud:copy-rainloop:clean',
|
||||||
'rainloop:owncloud:setup', 'rainloop:owncloud:zip', 'rainloop:owncloud:md5', 'rainloop:owncloud:clean']);
|
'rainloop:owncloud:setup', 'rainloop:owncloud:zip', 'rainloop:owncloud:md5', 'rainloop:owncloud:clean']);
|
||||||
|
|
||||||
|
gulp.task('owncloud+', ['package:community-off', 'owncloud']);
|
||||||
|
|
||||||
//WATCH
|
//WATCH
|
||||||
gulp.task('watch', ['fast'], function() {
|
gulp.task('watch', ['fast'], function() {
|
||||||
gulp.watch(cfg.paths.globjs, {interval: 1000}, ['js:app', 'js:admin']);
|
gulp.watch(cfg.paths.globjs, {interval: 1000}, ['js:app', 'js:admin']);
|
||||||
|
|
@ -578,10 +601,10 @@ gulp.task('watch', ['fast'], function() {
|
||||||
gulp.task('build', ['rainloop']);
|
gulp.task('build', ['rainloop']);
|
||||||
gulp.task('js:hint', ['js:lint']);
|
gulp.task('js:hint', ['js:lint']);
|
||||||
|
|
||||||
gulp.task('own', ['owncloud']);
|
|
||||||
gulp.task('rl', ['rainloop']);
|
|
||||||
gulp.task('w', ['watch']);
|
gulp.task('w', ['watch']);
|
||||||
gulp.task('f', ['fast']);
|
gulp.task('f', ['fast']);
|
||||||
gulp.task('o', ['owncloud']);
|
|
||||||
gulp.task('b', ['build']);
|
gulp.task('b', ['build']);
|
||||||
|
gulp.task('b+', ['build+']);
|
||||||
|
gulp.task('o', ['owncloud']);
|
||||||
|
gulp.task('o+', ['owncloud+']);
|
||||||
gulp.task('h', ['js:lint']);
|
gulp.task('h', ['js:lint']);
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "RainLoop",
|
"name": "RainLoop",
|
||||||
"title": "RainLoop Webmail",
|
"title": "RainLoop Webmail",
|
||||||
"version": "1.8.4",
|
"version": "1.9.0",
|
||||||
"release": "314",
|
"release": "315",
|
||||||
"description": "Simple, modern & fast web-based email client",
|
"description": "Simple, modern & fast web-based email client",
|
||||||
"homepage": "http://rainloop.net",
|
"homepage": "http://rainloop.net",
|
||||||
"main": "gulpfile.js",
|
"main": "gulpfile.js",
|
||||||
|
|
|
||||||
2
rainloop/v/0.0.0/app/libraries/RainLoop/.gitignore
vendored
Normal file
2
rainloop/v/0.0.0/app/libraries/RainLoop/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
/Prem/**
|
||||||
|
/_Prem/**
|
||||||
|
|
@ -110,6 +110,11 @@ class Actions
|
||||||
*/
|
*/
|
||||||
private $oTwoFactorAuthProvider;
|
private $oTwoFactorAuthProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \RainLoop\Providers\Prem
|
||||||
|
*/
|
||||||
|
private $oPremProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \RainLoop\Config\Application
|
* @var \RainLoop\Config\Application
|
||||||
*/
|
*/
|
||||||
|
|
@ -146,6 +151,7 @@ class Actions
|
||||||
$this->oSuggestionsProvider = null;
|
$this->oSuggestionsProvider = null;
|
||||||
$this->oChangePasswordProvider = null;
|
$this->oChangePasswordProvider = null;
|
||||||
$this->oTwoFactorAuthProvider = null;
|
$this->oTwoFactorAuthProvider = null;
|
||||||
|
$this->oPremProvider = null;
|
||||||
|
|
||||||
$this->sSpecAuthToken = '';
|
$this->sSpecAuthToken = '';
|
||||||
|
|
||||||
|
|
@ -738,6 +744,28 @@ class Actions
|
||||||
return $this->oTwoFactorAuthProvider;
|
return $this->oTwoFactorAuthProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \RainLoop\Providers\Prem
|
||||||
|
*/
|
||||||
|
public function PremProvider()
|
||||||
|
{
|
||||||
|
if (null === $this->oPremProvider)
|
||||||
|
{
|
||||||
|
if (\file_exists(APP_VERSION_ROOT_PATH.'app/libraries/RainLoop/Prem/Provider.php'))
|
||||||
|
{
|
||||||
|
$this->oPremProvider = new \RainLoop\Prem\Provider(
|
||||||
|
$this->Config(), $this->Logger(), $this->Cacher(null, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->oPremProvider = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->oPremProvider;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $bLocal = false
|
* @param bool $bLocal = false
|
||||||
*
|
*
|
||||||
|
|
@ -1248,20 +1276,6 @@ class Actions
|
||||||
return $this->GetAccountFromCustomToken($this->getAuthToken(), $bThrowExceptionOnFalse);
|
return $this->GetAccountFromCustomToken($this->getAuthToken(), $bThrowExceptionOnFalse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
private function PremType()
|
|
||||||
{
|
|
||||||
static $bResult = null;
|
|
||||||
if (null === $bResult)
|
|
||||||
{
|
|
||||||
$bResult = $this->licenseParser($this->licenseHelper(false, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $bResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $bAdmin
|
* @param bool $bAdmin
|
||||||
* @param string $sAuthAccountHash = ''
|
* @param string $sAuthAccountHash = ''
|
||||||
|
|
@ -1278,6 +1292,8 @@ class Actions
|
||||||
$oAccount = null;
|
$oAccount = null;
|
||||||
$oConfig = $this->Config();
|
$oConfig = $this->Config();
|
||||||
|
|
||||||
|
$oPremProvider = $this->PremProvider();
|
||||||
|
|
||||||
$aResult = array(
|
$aResult = array(
|
||||||
'Version' => APP_VERSION,
|
'Version' => APP_VERSION,
|
||||||
'Auth' => false,
|
'Auth' => false,
|
||||||
|
|
@ -1329,7 +1345,8 @@ class Actions
|
||||||
'UseImapSubscribe' => (bool) $oConfig->Get('labs', 'use_imap_list_subscribe', true),
|
'UseImapSubscribe' => (bool) $oConfig->Get('labs', 'use_imap_list_subscribe', true),
|
||||||
'AllowAppendMessage' => (bool) $oConfig->Get('labs', 'allow_message_append', false),
|
'AllowAppendMessage' => (bool) $oConfig->Get('labs', 'allow_message_append', false),
|
||||||
'MaterialDesign' => (bool) $oConfig->Get('labs', 'use_material_design', true),
|
'MaterialDesign' => (bool) $oConfig->Get('labs', 'use_material_design', true),
|
||||||
'PremType' => $this->PremType(),
|
'Community' => true,
|
||||||
|
'PremType' => false,
|
||||||
'Admin' => array(),
|
'Admin' => array(),
|
||||||
'Capa' => array(),
|
'Capa' => array(),
|
||||||
'AttahcmentsActions' => array(),
|
'AttahcmentsActions' => array(),
|
||||||
|
|
@ -1383,21 +1400,15 @@ class Actions
|
||||||
$aResult['Title'] = $oConfig->Get('webmail', 'title', '');
|
$aResult['Title'] = $oConfig->Get('webmail', 'title', '');
|
||||||
$aResult['LoadingDescription'] = $oConfig->Get('webmail', 'loading_description', '');
|
$aResult['LoadingDescription'] = $oConfig->Get('webmail', 'loading_description', '');
|
||||||
|
|
||||||
if ($this->PremType())
|
if ($oPremProvider)
|
||||||
{
|
{
|
||||||
$aResult['LoginLogo'] = $oConfig->Get('branding', 'login_logo', '');
|
$oPremProvider->PopulateAppData($aResult);
|
||||||
$aResult['LoginBackground'] = $oConfig->Get('branding', 'login_background', '');
|
|
||||||
$aResult['LoginCss'] = $oConfig->Get('branding', 'login_css', '');
|
|
||||||
$aResult['LoginDescription'] = $oConfig->Get('branding', 'login_desc', '');
|
|
||||||
$aResult['LoginPowered'] = !!$oConfig->Get('branding', 'login_powered', true);
|
|
||||||
$aResult['UserLogo'] = $oConfig->Get('branding', 'user_logo', '');
|
|
||||||
$aResult['UserLogoTitle'] = $oConfig->Get('branding', 'user_logo_title', '');
|
|
||||||
$aResult['UserCss'] = $oConfig->Get('branding', 'user_css', '');
|
|
||||||
$aResult['WelcomePageUrl'] = $oConfig->Get('branding', 'welcome_page_url', '');
|
|
||||||
$aResult['WelcomePageDisplay'] = \strtolower($oConfig->Get('branding', 'welcome_page_display', 'none'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$aResult['LoadingDescriptionEsc'] = \htmlspecialchars($aResult['LoadingDescription'], ENT_QUOTES|ENT_IGNORE, 'UTF-8');
|
if ('' !== $aResult['LoadingDescription'] && 'RainLoop' !== $aResult['LoadingDescription'])
|
||||||
|
{
|
||||||
|
$aResult['LoadingDescriptionEsc'] = @\htmlspecialchars($aResult['LoadingDescription'], ENT_QUOTES|ENT_IGNORE, 'UTF-8');
|
||||||
|
}
|
||||||
|
|
||||||
$oSettings = null;
|
$oSettings = null;
|
||||||
$oSettingsLocal = null;
|
$oSettingsLocal = null;
|
||||||
|
|
@ -3318,7 +3329,11 @@ class Actions
|
||||||
}
|
}
|
||||||
else if ($bVersionsCache)
|
else if ($bVersionsCache)
|
||||||
{
|
{
|
||||||
$this->removeOldVersion();
|
$oPremProvider = $this->PremProvider();
|
||||||
|
if ($oPremProvider)
|
||||||
|
{
|
||||||
|
$oPremProvider->ClearOldVersion();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->Plugins()->RunHook('service.app-delay-start-end');
|
$this->Plugins()->RunHook('service.app-delay-start-end');
|
||||||
|
|
@ -3354,7 +3369,7 @@ class Actions
|
||||||
* @param string $sType = 'string'
|
* @param string $sType = 'string'
|
||||||
* @param callable|null $mStringCallback = null
|
* @param callable|null $mStringCallback = null
|
||||||
*/
|
*/
|
||||||
private function setConfigFromParams(&$oConfig, $sParamName, $sConfigSector, $sConfigName, $sType = 'string', $mStringCallback = null)
|
public function setConfigFromParams(&$oConfig, $sParamName, $sConfigSector, $sConfigName, $sType = 'string', $mStringCallback = null)
|
||||||
{
|
{
|
||||||
$sValue = $this->GetActionParam($sParamName, '');
|
$sValue = $this->GetActionParam($sParamName, '');
|
||||||
if ($this->HasActionParam($sParamName))
|
if ($this->HasActionParam($sParamName))
|
||||||
|
|
@ -3531,26 +3546,6 @@ class Actions
|
||||||
$this->setConfigFromParams($oConfig, 'Title', 'webmail', 'title', 'string');
|
$this->setConfigFromParams($oConfig, 'Title', 'webmail', 'title', 'string');
|
||||||
$this->setConfigFromParams($oConfig, 'LoadingDescription', 'webmail', 'loading_description', 'string');
|
$this->setConfigFromParams($oConfig, 'LoadingDescription', 'webmail', 'loading_description', 'string');
|
||||||
|
|
||||||
if ($this->HasOneOfActionParams(array(
|
|
||||||
'LoginLogo', 'LoginBackground', 'LoginDescription', 'LoginCss', 'LoginPowered',
|
|
||||||
'UserLogo', 'UserLogoTitle', 'UserCss',
|
|
||||||
'WelcomePageUrl', 'WelcomePageDisplay'
|
|
||||||
)) && $this->PremType())
|
|
||||||
{
|
|
||||||
$this->setConfigFromParams($oConfig, 'LoginLogo', 'branding', 'login_logo', 'string');
|
|
||||||
$this->setConfigFromParams($oConfig, 'LoginBackground', 'branding', 'login_background', 'string');
|
|
||||||
$this->setConfigFromParams($oConfig, 'LoginDescription', 'branding', 'login_desc', 'string');
|
|
||||||
$this->setConfigFromParams($oConfig, 'LoginCss', 'branding', 'login_css', 'string');
|
|
||||||
$this->setConfigFromParams($oConfig, 'LoginPowered', 'branding', 'login_powered', 'bool');
|
|
||||||
|
|
||||||
$this->setConfigFromParams($oConfig, 'UserLogo', 'branding', 'user_logo', 'string');
|
|
||||||
$this->setConfigFromParams($oConfig, 'UserLogoTitle', 'branding', 'user_logo_title', 'string');
|
|
||||||
$this->setConfigFromParams($oConfig, 'UserCss', 'branding', 'user_css', 'string');
|
|
||||||
|
|
||||||
$this->setConfigFromParams($oConfig, 'WelcomePageUrl', 'branding', 'welcome_page_url', 'string');
|
|
||||||
$this->setConfigFromParams($oConfig, 'WelcomePageDisplay', 'branding', 'welcome_page_display', 'string');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setConfigFromParams($oConfig, 'TokenProtection', 'security', 'csrf_protection', 'bool');
|
$this->setConfigFromParams($oConfig, 'TokenProtection', 'security', 'csrf_protection', 'bool');
|
||||||
$this->setConfigFromParams($oConfig, 'EnabledPlugins', 'plugins', 'enable', 'bool');
|
$this->setConfigFromParams($oConfig, 'EnabledPlugins', 'plugins', 'enable', 'bool');
|
||||||
|
|
||||||
|
|
@ -3573,6 +3568,12 @@ class Actions
|
||||||
$this->setConfigFromParams($oConfig, 'DropboxEnable', 'social', 'dropbox_enable', 'bool');
|
$this->setConfigFromParams($oConfig, 'DropboxEnable', 'social', 'dropbox_enable', 'bool');
|
||||||
$this->setConfigFromParams($oConfig, 'DropboxApiKey', 'social', 'dropbox_api_key', 'string');
|
$this->setConfigFromParams($oConfig, 'DropboxApiKey', 'social', 'dropbox_api_key', 'string');
|
||||||
|
|
||||||
|
$oPremProvider = $this->PremProvider();
|
||||||
|
if ($oPremProvider)
|
||||||
|
{
|
||||||
|
$oPremProvider->PremSection($this, $oConfig);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->DefaultResponse(__FUNCTION__, $oConfig->Save());
|
return $this->DefaultResponse(__FUNCTION__, $oConfig->Save());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3647,144 +3648,6 @@ class Actions
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sDomain
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
// public function domainPathHelper($sDomain)
|
|
||||||
// {
|
|
||||||
// $sDomain = \strtolower(\trim($sDomain));
|
|
||||||
//
|
|
||||||
// $sTempDomain = \preg_replace('/^(webmail|email|mail)\./', '', $sDomain);
|
|
||||||
// if (false === \strpos($sTempDomain, '.'))
|
|
||||||
// {
|
|
||||||
// $sTempDomain = $sDomain;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// $sDomainPrefix = $sTempDomain;
|
|
||||||
// if (false === \strpos($sDomainPrefix, '.'))
|
|
||||||
// {
|
|
||||||
// $sDomainPrefix = $sTempDomain;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// $sDomainPrefix = \substr(\preg_replace('/[^a-z0-9]+/', '', $sDomainPrefix), 0, 2);
|
|
||||||
// $sDomainPrefix = \str_pad($sDomainPrefix, 2, '_');
|
|
||||||
//
|
|
||||||
// return 'd/'.\substr($sDomainPrefix, 0, 1).'/'.$sDomainPrefix.'/'.\urlencode($sTempDomain);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function licenseHelper($sForce = false, $bLongCache = false, $iFastCacheTimeInMin = 10, $iLongCacheTimeInDays = 3)
|
|
||||||
{
|
|
||||||
$sDomain = \trim(APP_SITE);
|
|
||||||
|
|
||||||
$oCacher = $this->Cacher(null, true);
|
|
||||||
$oHttp = \MailSo\Base\Http::SingletonInstance();
|
|
||||||
|
|
||||||
if (0 === \strlen($sDomain) || $oHttp->CheckLocalhost($sDomain) || !$oCacher || !$oCacher->Verify(true))
|
|
||||||
{
|
|
||||||
return 'NO';
|
|
||||||
}
|
|
||||||
|
|
||||||
$sDomainKeyValue = \RainLoop\KeyPathHelper::LicensingDomainKeyValue($sDomain);
|
|
||||||
$sDomainLongKeyValue = \RainLoop\KeyPathHelper::LicensingDomainKeyOtherValue($sDomain);
|
|
||||||
|
|
||||||
$sValue = '';
|
|
||||||
if (!$sForce)
|
|
||||||
{
|
|
||||||
if ($bLongCache)
|
|
||||||
{
|
|
||||||
$bLock = $oCacher->GetLock($sDomainLongKeyValue);
|
|
||||||
$iTime = $bLock ? 0 : $oCacher->GetTimer($sDomainLongKeyValue);
|
|
||||||
|
|
||||||
if ($bLock || (0 < $iTime && \time() < $iTime + (60 * 60 * 24) * $iLongCacheTimeInDays))
|
|
||||||
{
|
|
||||||
$sValue = $oCacher->Get($sDomainLongKeyValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$iTime = $oCacher->GetTimer($sDomainKeyValue);
|
|
||||||
if (0 < $iTime && \time() < $iTime + 60 * $iFastCacheTimeInMin)
|
|
||||||
{
|
|
||||||
$sValue = $oCacher->Get($sDomainKeyValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 === \strlen($sValue))
|
|
||||||
{
|
|
||||||
if ($bLongCache)
|
|
||||||
{
|
|
||||||
if (!$oCacher->SetTimer($sDomainLongKeyValue))
|
|
||||||
{
|
|
||||||
return 'NO';
|
|
||||||
}
|
|
||||||
|
|
||||||
$oCacher->SetLock($sDomainLongKeyValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
$iCode = 0;
|
|
||||||
$sContentType = '';
|
|
||||||
|
|
||||||
// $sValue = $oHttp->GetUrlAsString(APP_STATUS_PATH.$this->domainPathHelper($sDomain),
|
|
||||||
// 'RainLoop/'.APP_VERSION, $sContentType, $iCode, $this->Logger(), 5,
|
|
||||||
// $this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', ''),
|
|
||||||
// array(), false
|
|
||||||
// );
|
|
||||||
|
|
||||||
$sValue = $oHttp->GetUrlAsString(APP_API_PATH.'status/'.\urlencode($sDomain),
|
|
||||||
'RainLoop/'.APP_VERSION, $sContentType, $iCode, $this->Logger(), 5,
|
|
||||||
$this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', ''),
|
|
||||||
array(), false
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->Logger()->Write($sValue);
|
|
||||||
|
|
||||||
/*if (404 === $iCode)
|
|
||||||
{
|
|
||||||
$sValue = 'NO';
|
|
||||||
}
|
|
||||||
else */if (200 !== $iCode)
|
|
||||||
{
|
|
||||||
$sValue = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$oCacher->SetTimer($sDomainKeyValue);
|
|
||||||
|
|
||||||
$oCacher->Set($sDomainKeyValue, $sValue);
|
|
||||||
$oCacher->Set($sDomainLongKeyValue, $sValue);
|
|
||||||
|
|
||||||
if ($bLongCache)
|
|
||||||
{
|
|
||||||
$oCacher->RemoveLock($sDomainLongKeyValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $sValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sInput
|
|
||||||
* @param int $iExpired = 0
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function licenseParser($sInput, &$iExpired = 0)
|
|
||||||
{
|
|
||||||
$aMatch = array();
|
|
||||||
if (\preg_match('/^EXPIRED:([\d]+)$/', $sInput, $aMatch))
|
|
||||||
{
|
|
||||||
$iExpired = (int) $aMatch[1];
|
|
||||||
return \time() < $iExpired;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
|
@ -3797,14 +3660,16 @@ class Actions
|
||||||
$mResult = false;
|
$mResult = false;
|
||||||
$iErrorCode = -1;
|
$iErrorCode = -1;
|
||||||
|
|
||||||
if (2 < \strlen(APP_SITE))
|
$oPremProvider = $this->PremProvider();
|
||||||
|
|
||||||
|
if ($oPremProvider && 2 < \strlen(APP_SITE))
|
||||||
{
|
{
|
||||||
$sValue = $this->licenseHelper($bForce);
|
$sValue = $oPremProvider->Fetcher($bForce);
|
||||||
|
|
||||||
$this->requestSleep();
|
$this->requestSleep();
|
||||||
|
|
||||||
$iExpired = 0;
|
$iExpired = 0;
|
||||||
if ($this->licenseParser($sValue, $iExpired))
|
if ($oPremProvider->Parser($sValue, $iExpired))
|
||||||
{
|
{
|
||||||
$mResult = array(
|
$mResult = array(
|
||||||
'Banned' => false,
|
'Banned' => false,
|
||||||
|
|
@ -3846,23 +3711,12 @@ class Actions
|
||||||
$mResult = false;
|
$mResult = false;
|
||||||
$iErrorCode = -1;
|
$iErrorCode = -1;
|
||||||
|
|
||||||
if (2 < \strlen($sDomain) && 2 < \strlen($sKey) && $sDomain === APP_SITE)
|
$oPrem = $this->PremProvider();
|
||||||
|
|
||||||
|
if ($oPrem && 2 < \strlen($sDomain) && 2 < \strlen($sKey) && $sDomain === APP_SITE)
|
||||||
{
|
{
|
||||||
$iCode = 0;
|
$iCode = 0;
|
||||||
$sContentType = '';
|
$sValue = $oPrem->Activate($sDomain, $sKey, $iCode);
|
||||||
|
|
||||||
$oHttp = \MailSo\Base\Http::SingletonInstance();
|
|
||||||
|
|
||||||
$sValue = $oHttp->GetUrlAsString(APP_API_PATH.'activate/'.\urlencode($sDomain).'/'.\urlencode($sKey),
|
|
||||||
'RainLoop/'.APP_VERSION, $sContentType, $iCode, $this->Logger(), 10,
|
|
||||||
$this->Config()->Get('labs', 'curl_proxy', ''), $this->Config()->Get('labs', 'curl_proxy_auth', ''),
|
|
||||||
array(), false
|
|
||||||
);
|
|
||||||
|
|
||||||
if (200 !== $iCode)
|
|
||||||
{
|
|
||||||
$sValue = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->requestSleep();
|
$this->requestSleep();
|
||||||
|
|
||||||
|
|
@ -3878,6 +3732,7 @@ class Actions
|
||||||
else if (\preg_match('/^ERROR:(.+)$/', $sValue, $aMatch) && !empty($aMatch[1]))
|
else if (\preg_match('/^ERROR:(.+)$/', $sValue, $aMatch) && !empty($aMatch[1]))
|
||||||
{
|
{
|
||||||
$mResult = trim($aMatch[1]);
|
$mResult = trim($aMatch[1]);
|
||||||
|
|
||||||
$this->Logger()->Write('Activation error for: '.$sKey.' ('.$sDomain.')', \MailSo\Log\Enumerations\Type::ERROR);
|
$this->Logger()->Write('Activation error for: '.$sKey.' ('.$sDomain.')', \MailSo\Log\Enumerations\Type::ERROR);
|
||||||
$this->Logger()->Write($mResult, \MailSo\Log\Enumerations\Type::ERROR);
|
$this->Logger()->Write($mResult, \MailSo\Log\Enumerations\Type::ERROR);
|
||||||
}
|
}
|
||||||
|
|
@ -4479,10 +4334,10 @@ class Actions
|
||||||
$this->IsAdminLoggined();
|
$this->IsAdminLoggined();
|
||||||
|
|
||||||
$bReal = false;
|
$bReal = false;
|
||||||
$sNewVersion = '';
|
|
||||||
|
|
||||||
$bRainLoopUpdatable = $this->rainLoopUpdatable();
|
$bRainLoopUpdatable = $this->rainLoopUpdatable();
|
||||||
$bRainLoopAccess = $this->rainLoopCoreAccess();
|
$bRainLoopAccess = $this->rainLoopCoreAccess();
|
||||||
|
$oPremProvider = $this->PremProvider();
|
||||||
|
|
||||||
$aData = array();
|
$aData = array();
|
||||||
if ($bRainLoopUpdatable && $bRainLoopAccess)
|
if ($bRainLoopUpdatable && $bRainLoopAccess)
|
||||||
|
|
@ -4491,132 +4346,14 @@ class Actions
|
||||||
}
|
}
|
||||||
|
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
if ($bReal && !empty($aData['file']))
|
if ($bReal && $oPremProvider && !empty($aData['file']))
|
||||||
{
|
{
|
||||||
$sTmp = $this->downloadRemotePackageByUrl($aData['file']);
|
$bResult = $oPremProvider->UpdateCore($this, $aData['file']);
|
||||||
if (!empty($sTmp))
|
|
||||||
{
|
|
||||||
include_once APP_VERSION_ROOT_PATH.'app/libraries/pclzip/pclzip.lib.php';
|
|
||||||
|
|
||||||
$oArchive = new \PclZip($sTmp);
|
|
||||||
$sTmpFolder = APP_PRIVATE_DATA.\md5($sTmp);
|
|
||||||
|
|
||||||
\mkdir($sTmpFolder);
|
|
||||||
if (\is_dir($sTmpFolder))
|
|
||||||
{
|
|
||||||
$bResult = 0 !== $oArchive->extract(PCLZIP_OPT_PATH, $sTmpFolder);
|
|
||||||
if (!$bResult)
|
|
||||||
{
|
|
||||||
$this->Logger()->Write('Cannot extract package files: '.$oArchive->errorInfo(), \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($bResult && \file_exists($sTmpFolder.'/index.php') &&
|
|
||||||
\is_writable(APP_INDEX_ROOT_PATH.'rainloop/') &&
|
|
||||||
\is_writable(APP_INDEX_ROOT_PATH.'index.php') &&
|
|
||||||
\is_dir($sTmpFolder.'/rainloop/'))
|
|
||||||
{
|
|
||||||
$aMatch = array();
|
|
||||||
$sIndexFile = \file_get_contents($sTmpFolder.'/index.php');
|
|
||||||
if (\preg_match('/\'APP_VERSION\', \'([^\']+)\'/', $sIndexFile, $aMatch) && !empty($aMatch[1]))
|
|
||||||
{
|
|
||||||
$sNewVersion = \trim($aMatch[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($sNewVersion))
|
|
||||||
{
|
|
||||||
$this->Logger()->Write('Unknown version', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
|
||||||
}
|
|
||||||
else if (!\is_dir(APP_INDEX_ROOT_PATH.'rainloop/v/'.$sNewVersion))
|
|
||||||
{
|
|
||||||
\MailSo\Base\Utils::CopyDir($sTmpFolder.'/rainloop/', APP_INDEX_ROOT_PATH.'rainloop/');
|
|
||||||
|
|
||||||
if (\is_dir(APP_INDEX_ROOT_PATH.'rainloop/v/'.$sNewVersion) &&
|
|
||||||
\is_file(APP_INDEX_ROOT_PATH.'rainloop/v/'.$sNewVersion.'/index.php'))
|
|
||||||
{
|
|
||||||
$bResult = \copy($sTmpFolder.'/index.php', APP_INDEX_ROOT_PATH.'index.php');
|
|
||||||
|
|
||||||
if ($bResult)
|
|
||||||
{
|
|
||||||
if (\MailSo\Base\Utils::FunctionExistsAndEnabled('opcache_invalidate'))
|
|
||||||
{
|
|
||||||
@\opcache_invalidate(APP_INDEX_ROOT_PATH.'index.php', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\MailSo\Base\Utils::FunctionExistsAndEnabled('apc_delete_file'))
|
|
||||||
{
|
|
||||||
@\apc_delete_file(APP_INDEX_ROOT_PATH.'index.php');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->Logger()->Write('Cannot copy new package files', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
|
||||||
$this->Logger()->Write($sTmpFolder.'/rainloop/ -> '.APP_INDEX_ROOT_PATH.'rainloop/', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!empty($sNewVersion))
|
|
||||||
{
|
|
||||||
$this->Logger()->Write('"'.$sNewVersion.'" version already installed', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ($bResult)
|
|
||||||
{
|
|
||||||
$this->Logger()->Write('Cannot validate package files', \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
|
||||||
}
|
|
||||||
|
|
||||||
\MailSo\Base\Utils::RecRmDir($sTmpFolder);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->Logger()->Write('Cannot create tmp folder: '.$sTmpFolder, \MailSo\Log\Enumerations\Type::ERROR, 'INSTALLER');
|
|
||||||
}
|
|
||||||
|
|
||||||
@\unlink($sTmp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->DefaultResponse(__FUNCTION__, $bResult);
|
return $this->DefaultResponse(__FUNCTION__, $bResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeOldVersion()
|
|
||||||
{
|
|
||||||
$sVPath = APP_INDEX_ROOT_PATH.'rainloop/v/';
|
|
||||||
|
|
||||||
$this->Logger()->Write('Versions GC: Begin');
|
|
||||||
|
|
||||||
$aDirs = @\array_map('basename', @\array_filter(@\glob($sVPath.'*'), 'is_dir'));
|
|
||||||
|
|
||||||
$this->Logger()->Write('Versions GC: Count:'.(\is_array($aDirs) ? \count($aDirs) : 0));
|
|
||||||
|
|
||||||
if (\is_array($aDirs) && 5 < \count($aDirs))
|
|
||||||
{
|
|
||||||
\uasort($aDirs, 'version_compare');
|
|
||||||
|
|
||||||
foreach ($aDirs as $sName)
|
|
||||||
{
|
|
||||||
if (APP_DEV_VERSION !== $sName && APP_VERSION !== $sName)
|
|
||||||
{
|
|
||||||
$this->Logger()->Write('Versions GC: Begin to remove "'.$sVPath.$sName.'" version');
|
|
||||||
|
|
||||||
if (@\unlink($sVPath.$sName.'/index.php'))
|
|
||||||
{
|
|
||||||
@\MailSo\Base\Utils::RecRmDir($sVPath.$sName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->Logger()->Write('Versions GC (Error): index file cant be removed from"'.$sVPath.$sName.'"',
|
|
||||||
\MailSo\Log\Enumerations\Type::ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Logger()->Write('Versions GC: End to remove "'.$sVPath.$sName.'" version');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Logger()->Write('Versions GC: End');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
|
|
@ -4658,7 +4395,7 @@ class Actions
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function downloadRemotePackageByUrl($sUrl)
|
public function downloadRemotePackageByUrl($sUrl)
|
||||||
{
|
{
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
$sTmp = APP_PRIVATE_DATA.\md5(\microtime(true).$sUrl).'.zip';
|
$sTmp = APP_PRIVATE_DATA.\md5(\microtime(true).$sUrl).'.zip';
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@
|
||||||
<i class="icon-spinner animated" style="margin-top: 2px" data-bind="style: {'visibility': adminManLoadingVisibility }"></i>
|
<i class="icon-spinner animated" style="margin-top: 2px" data-bind="style: {'visibility': adminManLoadingVisibility }"></i>
|
||||||
|
|
||||||
RainLoop
|
RainLoop
|
||||||
<span data-bind="visible: capa">(<span data-i18n="TOP_PANEL/LABEL_PREMIUM"></span>)</span>
|
<span data-bind="visible: capa && !community">(<span data-i18n="TOP_PANEL/LABEL_PREMIUM"></span>)</span>
|
||||||
—
|
—
|
||||||
<span data-i18n="TOP_PANEL/LABEL_ADMIN_PANEL"></span>
|
<span data-i18n="TOP_PANEL/LABEL_ADMIN_PANEL"></span>
|
||||||
|
|
||||||
(<span data-bind="text: adminDomain"></span>)
|
<span data-bind="visible: !community">(<span data-bind="text: adminDomain"></span>)</span>
|
||||||
</h4>
|
</h4>
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
<a class="btn single btn-narrow" data-bind="click: logoutClick">
|
<a class="btn single btn-narrow" data-bind="click: logoutClick">
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,10 @@
|
||||||
<div class="row" style="min-width: 800px;">
|
<div class="row" style="min-width: 800px;">
|
||||||
<div class="span4">
|
<div class="span4">
|
||||||
<div class="rl-logo"></div>
|
<div class="rl-logo"></div>
|
||||||
<div style="margin-left: 45px;">
|
<div style="margin-left: 30px;">
|
||||||
2015 © <span data-i18n="TAB_ABOUT/LABEL_ALL_RIGHTS_RESERVED"></span>
|
2015 © <span data-i18n="TAB_ABOUT/LABEL_ALL_RIGHTS_RESERVED"></span>
|
||||||
<br />
|
<br />
|
||||||
<a class="g-ui-link" href="http://www.rainloop.net/" target="_blank">http://rainloop.net/</a>
|
<a class="g-ui-link" href="http://www.rainloop.net/" target="_blank" style="padding-left: 0">http://rainloop.net/</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="span8 rl-desc">
|
<div class="span8 rl-desc">
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
</span>
|
</span>
|
||||||
</h4>
|
</h4>
|
||||||
<h4 style="color: #aaa; font-weight: normal;" data-i18n="TAB_ABOUT/LABEL_TAG_HINT"></h4>
|
<h4 style="color: #aaa; font-weight: normal;" data-i18n="TAB_ABOUT/LABEL_TAG_HINT"></h4>
|
||||||
<h5 style="font-weight: normal; margin-top: 40px;">
|
<h5 style="font-weight: normal; margin-top: 40px;" data-bind="visible: !community">
|
||||||
<div data-bind="visible: 'error' === statusType()">
|
<div data-bind="visible: 'error' === statusType()">
|
||||||
<i class="icon-warning" style="color: red"></i>
|
<i class="icon-warning" style="color: red"></i>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs" data-bind="visible: !community">
|
||||||
<li class="active">
|
<li class="active">
|
||||||
<a class="i18n" data-i18n="TAB_BRANDING/LEGEND_LOGIN"
|
<a class="i18n" data-i18n="TAB_BRANDING/LEGEND_LOGIN"
|
||||||
href="#branding-login-section-id" data-toggle="tab"></a>
|
href="#branding-login-section-id" data-toggle="tab"></a>
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<br />
|
<br />
|
||||||
<div class="row">
|
<div class="row" data-bind="visible: !community">
|
||||||
<div class="tab-content span12">
|
<div class="tab-content span12">
|
||||||
<div class="tab-pane active" id="branding-login-section-id">
|
<div class="tab-pane active" id="branding-login-section-id">
|
||||||
|
|
||||||
|
|
@ -214,7 +214,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" data-bind="visible: !capa()">
|
<div class="row" data-bind="visible: !capa() && !community">
|
||||||
<div class="alert span8" style="margin-top: 10px;" data-i18n="[html]TAB_BRANDING/HTML_ALERT_PREMIUM"></div>
|
<div class="alert span8" style="margin-top: 10px;" data-i18n="[html]TAB_BRANDING/HTML_ALERT_PREMIUM"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,10 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="alert alert-info span8" data-bind="visible: 0 === plugins().length">
|
<div class="alert alert-info span8" data-bind="visible: 0 === plugins().length">
|
||||||
<span data-i18n="TAB_PLUGINS/ALERT_NO_PLUGINS"></span>
|
<span data-i18n="TAB_PLUGINS/ALERT_NO_PLUGINS"></span>
|
||||||
<br /><br />
|
<div data-bind="visible: !community">
|
||||||
<strong><a href="#/packages" data-i18n="TAB_PLUGINS/LINK_INSTALL_NEW"></a></strong>
|
<br />
|
||||||
|
<strong><a href="#/packages" data-i18n="TAB_PLUGINS/LINK_INSTALL_NEW"></a></strong>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="span8" data-bind="visible: 0 < plugins().length">
|
<div class="span8" data-bind="visible: 0 < plugins().length">
|
||||||
<blockquote><p class="muted" data-i18n="TAB_PLUGINS/HINT_CLICK_NAME"></p></blockquote>
|
<blockquote><p class="muted" data-i18n="TAB_PLUGINS/HINT_CLICK_NAME"></p></blockquote>
|
||||||
|
|
|
||||||
|
|
@ -199,25 +199,25 @@ Options -Indexes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sClearedSiteName = preg_replace('/^(www|demo|rainloop|webmail|email|mail|imap|imap4|smtp|pop|pop3)\./i', '', trim(APP_SITE));
|
// $sClearedSiteName = preg_replace('/^(www|demo|rainloop|webmail|email|mail|imap|imap4|smtp|pop|pop3)\./i', '', trim(APP_SITE));
|
||||||
if (!empty($sClearedSiteName) && @file_exists(APP_VERSION_ROOT_PATH.'app/domains/default.ini.dist') &&
|
// if (!empty($sClearedSiteName) && @file_exists(APP_VERSION_ROOT_PATH.'app/domains/default.ini.dist') &&
|
||||||
!@file_exists(APP_PRIVATE_DATA.'domains/'.$sClearedSiteName.'.ini'))
|
// !@file_exists(APP_PRIVATE_DATA.'domains/'.$sClearedSiteName.'.ini'))
|
||||||
{
|
// {
|
||||||
$sConfigTemplate = @file_get_contents(APP_VERSION_ROOT_PATH.'app/domains/default.ini.dist');
|
// $sConfigTemplate = @file_get_contents(APP_VERSION_ROOT_PATH.'app/domains/default.ini.dist');
|
||||||
if (!empty($sConfigTemplate))
|
// if (!empty($sConfigTemplate))
|
||||||
{
|
// {
|
||||||
@file_put_contents(APP_PRIVATE_DATA.'domains/'.$sClearedSiteName.'.ini', strtr($sConfigTemplate, array(
|
// @file_put_contents(APP_PRIVATE_DATA.'domains/'.$sClearedSiteName.'.ini', strtr($sConfigTemplate, array(
|
||||||
'IMAP_HOST' => 'localhost' !== $sClearedSiteName? 'imap.'.$sClearedSiteName : $sClearedSiteName,
|
// 'IMAP_HOST' => 'localhost' !== $sClearedSiteName? 'imap.'.$sClearedSiteName : $sClearedSiteName,
|
||||||
'IMAP_PORT' => '993',
|
// 'IMAP_PORT' => '993',
|
||||||
'SMTP_HOST' => 'localhost' !== $sClearedSiteName? 'smtp.'.$sClearedSiteName : $sClearedSiteName,
|
// 'SMTP_HOST' => 'localhost' !== $sClearedSiteName? 'smtp.'.$sClearedSiteName : $sClearedSiteName,
|
||||||
'SMTP_PORT' => '465'
|
// 'SMTP_PORT' => '465'
|
||||||
)));
|
// )));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// unset($sConfigTemplate);
|
||||||
|
// }
|
||||||
|
|
||||||
unset($sConfigTemplate);
|
unset($aFiles, $sFile, $sNewFileName, $sNewFile);
|
||||||
}
|
|
||||||
|
|
||||||
unset($aFiles, $sFile, $sNewFileName, $sNewFile, $sClearedSiteName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,50 +4,38 @@ rl_signature_replacer = function (editor, sText, sSignature, bHtml, bInsertBefor
|
||||||
if (!bHtml)
|
if (!bHtml)
|
||||||
{
|
{
|
||||||
sText = sText
|
sText = sText
|
||||||
.replace(/\u200C\u200C/g, '\u0002\u0002')
|
.replace(/\u200C([\s\S]*)\u200C/g, '<x-signature>$1</x-signature>')
|
||||||
.replace(/\u200D\u200D/g, '\u0003\u0003')
|
.replace(/\u200C/g, '')
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sText = sText.replace(/<x-signature>[\s\S]*<\/x-signature>/gm, '');
|
||||||
|
|
||||||
var
|
var
|
||||||
sTextWithoutSignature = sText
|
bEmptyText = '' === $.trim(sText),
|
||||||
.replace(/\u0002\u0002[\s\S]*\u0002\u0002/gm, '')
|
|
||||||
.replace(/\u0003\u0003[\s\S]*\u0003\u0003/gm, ''),
|
|
||||||
bEmptyText = '' === $.trim(sTextWithoutSignature),
|
|
||||||
sNewLine = (bHtml ? '<br />' : "\n")
|
sNewLine = (bHtml ? '<br />' : "\n")
|
||||||
;
|
;
|
||||||
|
|
||||||
if (!bEmptyText && bHtml)
|
if (!bEmptyText && bHtml)
|
||||||
{
|
{
|
||||||
bEmptyText = '' !== $.trim(editor.__plainUtils.htmlToPlain(sTextWithoutSignature));
|
bEmptyText = '' !== $.trim(editor.__plainUtils.htmlToPlain(sText));
|
||||||
}
|
|
||||||
|
|
||||||
if (!/\u0002\u0002/gm.test(sText))
|
|
||||||
{
|
|
||||||
sText = "\u0002\u0002\u0002\u0002" + sText;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!/\u0003\u0003/gm.test(sText))
|
|
||||||
{
|
|
||||||
sText = sText + "\u0003\u0003\u0003\u0003";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bInsertBefore)
|
if (bInsertBefore)
|
||||||
{
|
{
|
||||||
sText = sText.replace(/\u0002\u0002[\s\S]*\u0002\u0002/gm, "\u0002\u0002" + sSignature + (bEmptyText ? '' : sNewLine) + "\u0002\u0002");
|
sText = '<x-signature>' + sSignature + (bEmptyText ? '' : sNewLine) + '</x-signature>' + sText;
|
||||||
sText = sText.replace(/\u0003\u0003[\s\S]*\u0003\u0003/gm, "\u0003\u0003\u0003\u0003");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sText = sText.replace(/\u0002\u0002[\s\S]*\u0002\u0002/gm, "\u0002\u0002\u0002\u0002");
|
sText = sText + '<x-signature>' + (bEmptyText ? '' : sNewLine) + sSignature + '</x-signature>';
|
||||||
sText = sText.replace(/\u0003\u0003[\s\S]*\u0003\u0003/gm, "\u0003\u0003" + (bEmptyText ? '' : sNewLine) + sSignature + "\u0003\u0003");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bHtml)
|
if (!bHtml)
|
||||||
{
|
{
|
||||||
sText = sText
|
sText = sText
|
||||||
.replace(/\u0002\u0002/g, '\u200C\u200C')
|
.replace(/<x-signature>([\s\S]*)<\/x-signature>/gm, '\u200C$1\u200C')
|
||||||
.replace(/\u0003\u0003/g, '\u200D\u200D')
|
.replace(/<x-signature>/gm, '')
|
||||||
|
.replace(/<\/x-signature>/gm, '')
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,8 +78,7 @@ CKEDITOR.plugins.add('signature', {
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.__plain.setRawData(
|
editor.__plain.setRawData(
|
||||||
rl_signature_replacer(editor,
|
rl_signature_replacer(editor, editor.__plain.getRawData(), sResultSignature, false, bInsertBefore));
|
||||||
editor.__plain.getRawData(), sResultSignature, false, bInsertBefore));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -105,8 +92,7 @@ CKEDITOR.plugins.add('signature', {
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.setData(
|
editor.setData(
|
||||||
rl_signature_replacer(editor,
|
rl_signature_replacer(editor, editor.getData(), sResultSignature, true, bInsertBefore));
|
||||||
editor.getData(), sResultSignature, true, bInsertBefore));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
|
|
|
||||||
40
vendors/ckeditor-plugins/signature/plugin.js
vendored
40
vendors/ckeditor-plugins/signature/plugin.js
vendored
|
|
@ -4,50 +4,38 @@ rl_signature_replacer = function (editor, sText, sSignature, bHtml, bInsertBefor
|
||||||
if (!bHtml)
|
if (!bHtml)
|
||||||
{
|
{
|
||||||
sText = sText
|
sText = sText
|
||||||
.replace(/\u200C\u200C/g, '\u0002\u0002')
|
.replace(/\u200C([\s\S]*)\u200C/g, '<x-signature>$1</x-signature>')
|
||||||
.replace(/\u200D\u200D/g, '\u0003\u0003')
|
.replace(/\u200C/g, '')
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sText = sText.replace(/<x-signature>[\s\S]*<\/x-signature>/gm, '');
|
||||||
|
|
||||||
var
|
var
|
||||||
sTextWithoutSignature = sText
|
bEmptyText = '' === $.trim(sText),
|
||||||
.replace(/\u0002\u0002[\s\S]*\u0002\u0002/gm, '')
|
|
||||||
.replace(/\u0003\u0003[\s\S]*\u0003\u0003/gm, ''),
|
|
||||||
bEmptyText = '' === $.trim(sTextWithoutSignature),
|
|
||||||
sNewLine = (bHtml ? '<br />' : "\n")
|
sNewLine = (bHtml ? '<br />' : "\n")
|
||||||
;
|
;
|
||||||
|
|
||||||
if (!bEmptyText && bHtml)
|
if (!bEmptyText && bHtml)
|
||||||
{
|
{
|
||||||
bEmptyText = '' !== $.trim(editor.__plainUtils.htmlToPlain(sTextWithoutSignature));
|
bEmptyText = '' !== $.trim(editor.__plainUtils.htmlToPlain(sText));
|
||||||
}
|
|
||||||
|
|
||||||
if (!/\u0002\u0002/gm.test(sText))
|
|
||||||
{
|
|
||||||
sText = "\u0002\u0002\u0002\u0002" + sText;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!/\u0003\u0003/gm.test(sText))
|
|
||||||
{
|
|
||||||
sText = sText + "\u0003\u0003\u0003\u0003";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bInsertBefore)
|
if (bInsertBefore)
|
||||||
{
|
{
|
||||||
sText = sText.replace(/\u0002\u0002[\s\S]*\u0002\u0002/gm, "\u0002\u0002" + sSignature + (bEmptyText ? '' : sNewLine) + "\u0002\u0002");
|
sText = '<x-signature>' + sSignature + (bEmptyText ? '' : sNewLine) + '</x-signature>' + sText;
|
||||||
sText = sText.replace(/\u0003\u0003[\s\S]*\u0003\u0003/gm, "\u0003\u0003\u0003\u0003");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sText = sText.replace(/\u0002\u0002[\s\S]*\u0002\u0002/gm, "\u0002\u0002\u0002\u0002");
|
sText = sText + '<x-signature>' + (bEmptyText ? '' : sNewLine) + sSignature + '</x-signature>';
|
||||||
sText = sText.replace(/\u0003\u0003[\s\S]*\u0003\u0003/gm, "\u0003\u0003" + (bEmptyText ? '' : sNewLine) + sSignature + "\u0003\u0003");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bHtml)
|
if (!bHtml)
|
||||||
{
|
{
|
||||||
sText = sText
|
sText = sText
|
||||||
.replace(/\u0002\u0002/g, '\u200C\u200C')
|
.replace(/<x-signature>([\s\S]*)<\/x-signature>/gm, '\u200C$1\u200C')
|
||||||
.replace(/\u0003\u0003/g, '\u200D\u200D')
|
.replace(/<x-signature>/gm, '')
|
||||||
|
.replace(/<\/x-signature>/gm, '')
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,8 +78,7 @@ CKEDITOR.plugins.add('signature', {
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.__plain.setRawData(
|
editor.__plain.setRawData(
|
||||||
rl_signature_replacer(editor,
|
rl_signature_replacer(editor, editor.__plain.getRawData(), sResultSignature, false, bInsertBefore));
|
||||||
editor.__plain.getRawData(), sResultSignature, false, bInsertBefore));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -105,8 +92,7 @@ CKEDITOR.plugins.add('signature', {
|
||||||
}
|
}
|
||||||
|
|
||||||
editor.setData(
|
editor.setData(
|
||||||
rl_signature_replacer(editor,
|
rl_signature_replacer(editor, editor.getData(), sResultSignature, true, bInsertBefore));
|
||||||
editor.getData(), sResultSignature, true, bInsertBefore));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue