From fed896776fd58f9c1fa88750e4df84c3c00556af Mon Sep 17 00:00:00 2001 From: RainLoop Team Date: Sat, 24 May 2014 02:14:16 +0400 Subject: [PATCH] Code refactoring a lot of small fixes (Closes #173) Added login field (ownCloud package) --- Gruntfile.js | 13 +- build/configs/apache2/.htaccess | 5 - build/configs/apache2/dav.mydomain.com | 14 - build/configs/apache2/mydomain.com | 14 - build/configs/nginx/dav.mydomain.com.conf | 43 --- build/configs/nginx/mydomain.com.conf | 48 --- build/owncloud/rainloop-app/INSTALL | 2 +- build/owncloud/rainloop-app/VERSION | 2 +- build/owncloud/rainloop-app/ajax/personal.php | 1 + .../rainloop-app/templates/personal.php | 3 + build/plugin.xml | 6 +- dev/Admin/Security.js | 11 +- dev/Boots/RainLoopApp.js | 5 + dev/Common/Enums.js | 35 ++- dev/Common/Knockout.js | 2 +- dev/Models/FilterConditionModel.js | 8 + dev/Models/FilterModel.js | 36 +++ dev/Settings/Filters.js | 31 ++ dev/Styles/FolderList.less | 1 + dev/Styles/Scroll.less | 46 +-- dev/Styles/Ui.less | 3 +- dev/Styles/_BootstrapFix.less | 15 +- .../AbstractSystemDropDownViewModel.js | 4 +- package.json | 3 +- .../IspConfigChangePasswordDriver.php} | 18 +- .../LICENSE | 0 .../README | 2 +- plugins/ispconfig-change-password/VERSION | 1 + .../index.php | 10 +- plugins/ispmanager-change-password/VERSION | 1 - .../app/libraries/MailSo/Base/HtmlUtils.php | 51 ++-- .../0.0.0/app/libraries/RainLoop/Actions.php | 7 +- .../libraries/RainLoop/Enumerations/Capa.php | 31 +- .../app/libraries/RainLoop/ServiceActions.php | 24 +- rainloop/v/0.0.0/app/templates/Index.html | 2 +- .../Views/{ => Admin}/AdminLogin.html | 0 .../Views/{ => Admin}/AdminMenu.html | 46 +-- .../Views/{ => Admin}/AdminPane.html | 0 .../Views/{ => Admin}/AdminSettingsAbout.html | 25 +- .../{ => Admin}/AdminSettingsBranding.html | 0 .../{ => Admin}/AdminSettingsContacts.html | 0 .../AdminSettingsDomainListItem.html | 0 .../{ => Admin}/AdminSettingsDomains.html | 0 .../{ => Admin}/AdminSettingsGeneral.html | 0 .../{ => Admin}/AdminSettingsLicensing.html | 2 +- .../Views/{ => Admin}/AdminSettingsLogin.html | 0 .../{ => Admin}/AdminSettingsPackages.html | 0 .../AdminSettingsPackagesListItem.html | 0 .../AdminSettingsPackagesTable.html | 0 .../AdminSettingsPluginListItem.html | 0 .../AdminSettingsPluginProperty.html | 54 ++-- .../{ => Admin}/AdminSettingsPlugins.html | 0 .../{ => Admin}/AdminSettingsSecurity.html | 10 +- .../{ => Admin}/AdminSettingsSocial.html | 0 .../Views/{ => Admin}/PopupsActivate.html | 0 .../Views/{ => Admin}/PopupsDomain.html | 0 .../Views/{ => Admin}/PopupsPlugin.html | 0 .../Views/{ => App}/ComposeAttachment.html | 0 .../{ => App}/ComposeAttachmentInProcess.html | 0 .../app/templates/Views/{ => App}/Login.html | 0 .../Views/{ => App}/MailFolderList.html | 0 .../Views/{ => App}/MailFolderListItem.html | 0 .../{ => App}/MailFolderListSystemItem.html | 12 +- .../Views/{ => App}/MailMessageList.html | 0 .../Views/{ => App}/MailMessageListItem.html | 0 .../MailMessageListItemNoPreviewPane.html | 0 .../Views/{ => App}/MailMessageView.html | 0 .../Views/{ => App}/PopupsAddAccount.html | 0 .../Views/{ => App}/PopupsAddOpenPgpKey.html | 0 .../Views/{ => App}/PopupsAdvancedSearch.html | 0 .../Views/{ => App}/PopupsCompose.html | 0 .../Views/{ => App}/PopupsComposeOpenPgp.html | 0 .../Views/{ => App}/PopupsContacts.html | 0 .../Views/{ => App}/PopupsFolderClear.html | 0 .../Views/{ => App}/PopupsFolderCreate.html | 0 .../Views/{ => App}/PopupsFolderSystem.html | 0 .../PopupsGenerateNewOpenPgpKey.html | 0 .../Views/{ => App}/PopupsIdentity.html | 0 .../Views/{ => App}/PopupsTwoFactorTest.html | 0 .../Views/{ => App}/PopupsViewOpenPgpKey.html | 0 .../{ => App}/PopupsWindowSimpleMessage.html | 110 +++---- .../Views/{ => App}/SettingsAccounts.html | 0 .../{ => App}/SettingsChangePassword.html | 0 .../Views/{ => App}/SettingsContacts.html | 0 .../Views/{ => App}/SettingsCustom.html | 4 +- .../templates/Views/App/SettingsFilters.html | 38 +++ .../Views/{ => App}/SettingsFolderItem.html | 0 .../Views/{ => App}/SettingsFolders.html | 0 .../Views/{ => App}/SettingsGeneral.html | 0 .../Views/{ => App}/SettingsIdentities.html | 0 .../Views/{ => App}/SettingsIdentity.html | 0 .../Views/{ => App}/SettingsMenu.html | 46 +-- .../Views/{ => App}/SettingsOpenPGP.html | 0 .../Views/{ => App}/SettingsPane.html | 0 .../Views/{ => App}/SettingsSecurity.html | 0 .../Views/{ => App}/SettingsSocial.html | 0 .../Views/{ => App}/SettingsThemes.html | 0 .../Views/{ => App}/SystemDropDown.html | 8 - .../Views/{ => Common}/Pagenator.html | 0 .../Views/{ => Common}/PopupsAsk.html | 0 .../PopupsKeyboardShortcutsHelp.html | 0 .../Views/{ => Common}/PopupsLanguages.html | 0 rainloop/v/0.0.0/langs/de.ini | 3 +- rainloop/v/0.0.0/langs/en.ini | 8 +- rainloop/v/0.0.0/langs/es.ini | 1 + rainloop/v/0.0.0/langs/fr.ini | 1 + rainloop/v/0.0.0/langs/hu.ini | 1 + rainloop/v/0.0.0/langs/is.ini | 3 +- rainloop/v/0.0.0/langs/it.ini | 1 + rainloop/v/0.0.0/langs/ja-jp.ini | 1 + rainloop/v/0.0.0/langs/ko-kr.ini | 3 +- rainloop/v/0.0.0/langs/lv.ini | 3 +- rainloop/v/0.0.0/langs/nl.ini | 5 +- rainloop/v/0.0.0/langs/no.ini | 1 + rainloop/v/0.0.0/langs/pl.ini | 3 +- rainloop/v/0.0.0/langs/pt-br.ini | 289 +++++++++--------- rainloop/v/0.0.0/langs/pt-pt.ini | 1 + rainloop/v/0.0.0/langs/ro.ini | 7 +- rainloop/v/0.0.0/langs/ru.ini | 3 +- rainloop/v/0.0.0/langs/sk.ini | 1 + rainloop/v/0.0.0/langs/zh-cn.ini | 5 +- rainloop/v/0.0.0/static/css/app.css | 49 +-- rainloop/v/0.0.0/static/css/app.min.css | 2 +- rainloop/v/0.0.0/static/js/admin.js | 156 ++++++---- rainloop/v/0.0.0/static/js/admin.min.js | 8 +- rainloop/v/0.0.0/static/js/app.js | 284 +++++++++++------ rainloop/v/0.0.0/static/js/app.min.js | 18 +- rainloop/v/0.0.0/static/js/boot.js | 6 +- rainloop/v/0.0.0/static/js/libs.js | 104 +++---- 129 files changed, 1016 insertions(+), 804 deletions(-) delete mode 100644 build/configs/apache2/.htaccess delete mode 100644 build/configs/apache2/dav.mydomain.com delete mode 100644 build/configs/apache2/mydomain.com delete mode 100644 build/configs/nginx/dav.mydomain.com.conf delete mode 100644 build/configs/nginx/mydomain.com.conf create mode 100644 dev/Models/FilterConditionModel.js create mode 100644 dev/Models/FilterModel.js create mode 100644 dev/Settings/Filters.js rename plugins/{ispmanager-change-password/IspManagerChangePasswordDriver.php => ispconfig-change-password/IspConfigChangePasswordDriver.php} (91%) rename plugins/{ispmanager-change-password => ispconfig-change-password}/LICENSE (100%) rename plugins/{ispmanager-change-password => ispconfig-change-password}/README (79%) create mode 100644 plugins/ispconfig-change-password/VERSION rename plugins/{ispmanager-change-password => ispconfig-change-password}/index.php (90%) delete mode 100644 plugins/ispmanager-change-password/VERSION rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminLogin.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminMenu.html (97%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminPane.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsAbout.html (74%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsBranding.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsContacts.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsDomainListItem.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsDomains.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsGeneral.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsLicensing.html (99%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsLogin.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsPackages.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsPackagesListItem.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsPackagesTable.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsPluginListItem.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsPluginProperty.html (97%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsPlugins.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsSecurity.html (87%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/AdminSettingsSocial.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/PopupsActivate.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/PopupsDomain.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Admin}/PopupsPlugin.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/ComposeAttachment.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/ComposeAttachmentInProcess.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/Login.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/MailFolderList.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/MailFolderListItem.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/MailFolderListSystemItem.html (98%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/MailMessageList.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/MailMessageListItem.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/MailMessageListItemNoPreviewPane.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/MailMessageView.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsAddAccount.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsAddOpenPgpKey.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsAdvancedSearch.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsCompose.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsComposeOpenPgp.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsContacts.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsFolderClear.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsFolderCreate.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsFolderSystem.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsGenerateNewOpenPgpKey.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsIdentity.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsTwoFactorTest.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsViewOpenPgpKey.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/PopupsWindowSimpleMessage.html (97%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsAccounts.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsChangePassword.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsContacts.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsCustom.html (95%) create mode 100644 rainloop/v/0.0.0/app/templates/Views/App/SettingsFilters.html rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsFolderItem.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsFolders.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsGeneral.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsIdentities.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsIdentity.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsMenu.html (97%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsOpenPGP.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsPane.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsSecurity.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsSocial.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SettingsThemes.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => App}/SystemDropDown.html (92%) rename rainloop/v/0.0.0/app/templates/Views/{ => Common}/Pagenator.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Common}/PopupsAsk.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Common}/PopupsKeyboardShortcutsHelp.html (100%) rename rainloop/v/0.0.0/app/templates/Views/{ => Common}/PopupsLanguages.html (100%) diff --git a/Gruntfile.js b/Gruntfile.js index f54ed152e..a38badb25 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -273,6 +273,8 @@ module.exports = function (grunt) { "dev/Models/FolderModel.js", "dev/Models/AccountModel.js", "dev/Models/IdentityModel.js", + "dev/Models/FilterConditionModel.js", + "dev/Models/FilterModel.js", "dev/Models/OpenPgpKeyModel.js", "dev/ViewModels/PopupsFolderClearViewModel.js", @@ -310,6 +312,7 @@ module.exports = function (grunt) { "dev/Settings/Accounts.js", "dev/Settings/Identity.js", "dev/Settings/Identities.js", + "dev/Settings/Filters.js", "dev/Settings/Security.js", "dev/Settings/Social.js", "dev/Settings/ChangePassword.js", @@ -475,7 +478,7 @@ module.exports = function (grunt) { releasesPath = grunt.config('cfg.releasesPath'), devVersion = grunt.config('cfg.devVersion'), versionFull = version + '.' + release, - versionOwn = '1.1', + versionOwn = grunt.config('pkg.ownCloudPackageVersion'), dist = releasesPath + '/' + versionFull + '/owncloud/' ; @@ -489,12 +492,14 @@ module.exports = function (grunt) { grunt.file.write(dist + 'appinfo/info.xml', content.replace('0.0.0', '' + versionOwn + '')); + grunt.file.write(dist + 'VERSION', versionOwn); + grunt.config.set('cfg.releaseFolder', versionFull); grunt.config.set('cfg.releaseSrcPath', dist); grunt.config.set('cfg.releaseZipFile', 'rainloop-owncloud-app-' + versionOwn + '.zip'); }); - grunt.registerTask('rainloop-clear', 'RainLoop Webmail clear task', function () { + grunt.registerTask('rainloop-clean', 'RainLoop Webmail clean task', function () { var releaseSrcPath = grunt.config('cfg.releaseSrcPath'); if ('' !== releaseSrcPath) { @@ -517,9 +522,9 @@ module.exports = function (grunt) { // --- grunt.registerTask('default', ['less', 'concat', 'cssmin', 'jshint', 'rlmin']); - grunt.registerTask('build', ['default', 'rainloop', 'compress:build', 'md5:build', 'rainloop-clear']); + grunt.registerTask('build', ['default', 'rainloop', 'compress:build', 'md5:build', 'rainloop-clean']); grunt.registerTask('fast', ['less', 'concat']); - grunt.registerTask('owncloud', ['rainloop-owncloud', 'compress:own', 'md5:build', 'rainloop-clear']); + grunt.registerTask('owncloud', ['rainloop-owncloud', 'compress:own', 'md5:build', 'rainloop-clean']); // aliases grunt.registerTask('u', ['uglify']); diff --git a/build/configs/apache2/.htaccess b/build/configs/apache2/.htaccess deleted file mode 100644 index 1d598e27b..000000000 --- a/build/configs/apache2/.htaccess +++ /dev/null @@ -1,5 +0,0 @@ - - RewriteEngine On - RewriteRule /.well-known/carddav /index.php/dav [R,L] - - diff --git a/build/configs/apache2/dav.mydomain.com b/build/configs/apache2/dav.mydomain.com deleted file mode 100644 index deb9be4ba..000000000 --- a/build/configs/apache2/dav.mydomain.com +++ /dev/null @@ -1,14 +0,0 @@ - - AcceptPathInfo On - ServerName dav.mydomain.com - DocumentRoot /var/www/mydomain.com - - RewriteEngine On - RewriteRule /.well-known/carddav /index.php/dav [R,L] - - - Options None - Options +FollowSymlinks - AllowOverride All - - \ No newline at end of file diff --git a/build/configs/apache2/mydomain.com b/build/configs/apache2/mydomain.com deleted file mode 100644 index 92a49b2c5..000000000 --- a/build/configs/apache2/mydomain.com +++ /dev/null @@ -1,14 +0,0 @@ - - AcceptPathInfo On - ServerName mydomain.com - DocumentRoot /var/www/mydomain.com - - RewriteEngine On - RewriteRule /.well-known/carddav /index.php/dav [R,L] - - - Options None - Options +FollowSymlinks - AllowOverride All - - \ No newline at end of file diff --git a/build/configs/nginx/dav.mydomain.com.conf b/build/configs/nginx/dav.mydomain.com.conf deleted file mode 100644 index 10f4a75f2..000000000 --- a/build/configs/nginx/dav.mydomain.com.conf +++ /dev/null @@ -1,43 +0,0 @@ -server { - listen 80; - server_name dav.mydomain.com; - - root /var/www/mydomain.com; - access_log /var/log/nginx/dav.mydomain.com.access.log; - error_log /var/log/nginx/dav.mydomain.com.error.log; - - index index.php; - charset utf-8; - log_not_found off; - - location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { - expires max; - add_header Pragma public; - add_header Cache-Control "public, must-revalidate, proxy-revalidate"; - } - - location = /favicon.ico { access_log off; log_not_found off; } - location = /robots.txt { access_log off; log_not_found off; } - location = /humans.txt { access_log off; log_not_found off; } - location ~ /\.ht { access_log off; log_not_found off; deny all; return 404; } - location ^~ /data { access_log off; log_not_found off; deny all; return 404; } - - # rewrite for carddav autoprovision - rewrite ^/.well-known/carddav / redirect; - - rewrite ^(.*)$ /index.php/dav$1 last; - - # php for carddav only - location ~ /index\.php/dav/.*$ { - include fastcgi_params; - - fastcgi_pass 127.0.0.1:9000; # unix:/var/run/php5-fpm.sock; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - - fastcgi_split_path_info ^(.+\.php)(/[^?]*).*$; - fastcgi_index index.php; - fastcgi_param SCRIPT_NAME index.php; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; - } -} \ No newline at end of file diff --git a/build/configs/nginx/mydomain.com.conf b/build/configs/nginx/mydomain.com.conf deleted file mode 100644 index de022b793..000000000 --- a/build/configs/nginx/mydomain.com.conf +++ /dev/null @@ -1,48 +0,0 @@ -server { - listen 80; - server_name mydomain.com; - - root /var/www/mydomain.com; - access_log /var/log/nginx/mydomain.com.access.log; - error_log /var/log/nginx/mydomain.com.error.log; - - index index.php index.html; - charset utf-8; - log_not_found off; - - location ~* \.(?:ico|css|js|gif|jpe?g|png)$ { - expires max; - add_header Pragma public; - add_header Cache-Control "public, must-revalidate, proxy-revalidate"; - } - - location = /favicon.ico { access_log off; log_not_found off; } - location = /robots.txt { access_log off; log_not_found off; } - location = /humans.txt { access_log off; log_not_found off; } - location ~ /\.ht { access_log off; log_not_found off; deny all; return 404; } - location ^~ /data { access_log off; log_not_found off; deny all; return 404; } - - # rewrite for carddav autoprovision - rewrite ^/.well-known/carddav /index.php/dav/ redirect; - - # php for carddav - location ~ /index\.php/dav/.*$ { - include fastcgi_params; - - fastcgi_pass 127.0.0.1:9000; # unix:/var/run/php5-fpm.sock; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - - fastcgi_split_path_info ^(.+\.php)(/[^?]*).*$; - fastcgi_index index.php; - fastcgi_param SCRIPT_NAME index.php; - fastcgi_param PATH_INFO $fastcgi_path_info; - fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; - } - - # php (other) - location ~ \.php { - include fastcgi_params; - fastcgi_pass 127.0.0.1:9000; # unix:/var/run/php5-fpm.sock; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - } -} \ No newline at end of file diff --git a/build/owncloud/rainloop-app/INSTALL b/build/owncloud/rainloop-app/INSTALL index bb223e8d3..96d62647e 100644 --- a/build/owncloud/rainloop-app/INSTALL +++ b/build/owncloud/rainloop-app/INSTALL @@ -25,5 +25,5 @@ external_sso_key = "super-secret-key" ownCloud: 1) In the Apps > Enable 'RainLoop' plugin 2) In the Settings > Admin > Enter "RainLoop Webmail URL" and "SSO key" - 3) In the Settings > Personal > Type your mail server email and password + 3) In the Settings > Personal > Type your mail server email (login) and password diff --git a/build/owncloud/rainloop-app/VERSION b/build/owncloud/rainloop-app/VERSION index b123147e2..171538eb0 100644 --- a/build/owncloud/rainloop-app/VERSION +++ b/build/owncloud/rainloop-app/VERSION @@ -1 +1 @@ -1.1 \ No newline at end of file +0.0 \ No newline at end of file diff --git a/build/owncloud/rainloop-app/ajax/personal.php b/build/owncloud/rainloop-app/ajax/personal.php index f9b3a0b7a..1791cc880 100644 --- a/build/owncloud/rainloop-app/ajax/personal.php +++ b/build/owncloud/rainloop-app/ajax/personal.php @@ -23,6 +23,7 @@ if (isset($_POST['appname'], $_POST['rainloop-password'], $_POST['rainloop-email $sPostLogin = isset($_POST['rainloop-login']) ? $_POST['rainloop-login'] : ''; OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-email', $sPostEmail); + OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-login', $sPostLogin); $sPass = $_POST['rainloop-password']; if ('******' !== $sPass && '' !== $sPass) diff --git a/build/owncloud/rainloop-app/templates/personal.php b/build/owncloud/rainloop-app/templates/personal.php index 880e00d5e..ca35fc343 100644 --- a/build/owncloud/rainloop-app/templates/personal.php +++ b/build/owncloud/rainloop-app/templates/personal.php @@ -8,6 +8,9 @@ + + diff --git a/build/plugin.xml b/build/plugin.xml index 4dc3ff1ed..39633ae23 100644 --- a/build/plugin.xml +++ b/build/plugin.xml @@ -58,9 +58,9 @@ - + - + @@ -94,5 +94,5 @@ - + diff --git a/dev/Admin/Security.js b/dev/Admin/Security.js index e871c219d..f52922e9a 100644 --- a/dev/Admin/Security.js +++ b/dev/Admin/Security.js @@ -5,7 +5,6 @@ */ function AdminSecurity() { - this.csrfProtection = ko.observable(!!RL.settingsGet('UseTokenProtection')); this.capaOpenPGP = ko.observable(RL.capa(Enums.Capa.OpenPGP)); this.capaTwoFactorAuth = ko.observable(RL.capa(Enums.Capa.TwoFactor)); @@ -28,13 +27,13 @@ function AdminSecurity() this.adminPasswordUpdateSuccess(false); this.adminPasswordNewError(false); }, this); - + this.adminPasswordNew2.subscribe(function () { this.adminPasswordUpdateError(false); this.adminPasswordUpdateSuccess(false); this.adminPasswordNewError(false); }, this); - + this.saveNewAdminPasswordCommand = Utils.createCommand(this, function () { if (this.adminPasswordNew() !== this.adminPasswordNew2()) @@ -78,12 +77,6 @@ AdminSecurity.prototype.onNewAdminPasswordResponse = function (sResult, oData) AdminSecurity.prototype.onBuild = function () { - this.csrfProtection.subscribe(function (bValue) { - RL.remote().saveAdminConfig(Utils.emptyFunction, { - 'TokenProtection': bValue ? '1' : '0' - }); - }); - this.capaOpenPGP.subscribe(function (bValue) { RL.remote().saveAdminConfig(Utils.emptyFunction, { 'CapaOpenPGP': bValue ? '1' : '0' diff --git a/dev/Boots/RainLoopApp.js b/dev/Boots/RainLoopApp.js index 7d85a1783..3a6d92dc8 100644 --- a/dev/Boots/RainLoopApp.js +++ b/dev/Boots/RainLoopApp.js @@ -1072,6 +1072,11 @@ RainLoopApp.prototype.bootstart = function () Utils.removeSettingsViewModel(SettingsThemes); } + if (!RL.capa(Enums.Capa.Filters)) + { + Utils.removeSettingsViewModel(SettingsFilters); + } + if (!bGoogle && !bFacebook && !bTwitter) { Utils.removeSettingsViewModel(SettingsSocialScreen); diff --git a/dev/Common/Enums.js b/dev/Common/Enums.js index 3f7b4fffa..1627ee149 100644 --- a/dev/Common/Enums.js +++ b/dev/Common/Enums.js @@ -37,6 +37,7 @@ Enums.Capa = { 'Prefetch': 'PREFETCH', 'Gravatar': 'GRAVATAR', 'Themes': 'THEMES', + 'Filters': 'FILTERS', 'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS', 'AdditionalIdentities': 'ADDITIONAL_IDENTITIES' }; @@ -278,6 +279,34 @@ Enums.Layout = { 'BottomPreview': 2 }; +/** + * @enum {number} + */ +Enums.FilterConditionField = { + 'From': 0, + 'To': 1, + 'Subject': 2 +}; + +/** + * @enum {number} + */ +Enums.FilterConditionType = { + 'contains': 0, + 'NotContains': 1, + 'EqualTo': 2, + 'NotEqualTo': 3 +}; + +/** + * @enum {number} + */ +Enums.FiltersAction = { + 'None': 0, + 'Move': 1, + 'Delete': 2 +}; + /** * @enum {number} */ @@ -345,7 +374,7 @@ Enums.Notification = { 'NewPasswordShort': 132, 'NewPasswordWeak': 133, 'NewPasswordForbidden': 134, - + 'ContactsSyncError': 140, 'CantGetMessageList': 201, @@ -374,13 +403,13 @@ Enums.Notification = { 'CantDeletePackage': 702, 'InvalidPluginPackage': 703, 'UnsupportedPluginPackage': 704, - + 'LicensingServerIsUnavailable': 710, 'LicensingExpired': 711, 'LicensingBanned': 712, 'DemoSendMessageError': 750, - + 'AccountAlreadyExists': 801, 'MailServerError': 901, diff --git a/dev/Common/Knockout.js b/dev/Common/Knockout.js index 171c63456..9aeddd6da 100644 --- a/dev/Common/Knockout.js +++ b/dev/Common/Knockout.js @@ -80,7 +80,7 @@ ko.bindingHandlers.tooltip3 = { $document.click(function () { $oEl.tooltip('hide'); }); - + Globals.tooltipTrigger.subscribe(function () { $oEl.tooltip('hide'); }); diff --git a/dev/Models/FilterConditionModel.js b/dev/Models/FilterConditionModel.js new file mode 100644 index 000000000..3460800c6 --- /dev/null +++ b/dev/Models/FilterConditionModel.js @@ -0,0 +1,8 @@ +/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ + +/** + * @constructor + */ +function FilterConditionModel() +{ +} diff --git a/dev/Models/FilterModel.js b/dev/Models/FilterModel.js new file mode 100644 index 000000000..47e26c0cf --- /dev/null +++ b/dev/Models/FilterModel.js @@ -0,0 +1,36 @@ +/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ + +/** + * @constructor + */ +function FilterModel() +{ + this.enabled = ko.observable(true); + + this.conditions = ko.observableArray([]); + + this.action = ko.observable(Enums.FiltersAction.None); +} + +FilterModel.prototype.deleteCondition = function (oCondition) +{ + this.conditions.remove(oCondition); +}; + +FilterModel.prototype.addCondition = function () +{ + this.conditions.push(new FilterConditionModel()); +}; + +FilterModel.prototype.parse = function (oItem) +{ + var bResult = false; + if (oItem && 'Object/Filter' === oItem['@Object']) + { + this.name(Utils.pString(oItem['Name'])); + + bResult = true; + } + + return bResult; +}; diff --git a/dev/Settings/Filters.js b/dev/Settings/Filters.js new file mode 100644 index 000000000..76bd00302 --- /dev/null +++ b/dev/Settings/Filters.js @@ -0,0 +1,31 @@ +/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ + +/** + * @constructor + */ +function SettingsFilters() +{ +// var oData = RL.data(); + + this.filters = ko.observableArray([]); + this.filters.loading = ko.observable(false); +} + +Utils.addSettingsViewModel(SettingsFilters, 'SettingsFilters', 'SETTINGS_LABELS/LABEL_FILTERS_NAME', 'filters'); + +//SettingsFilters.prototype.onBuild = function () +//{ +//}; + +SettingsFilters.prototype.deleteFilter = function (oFilter) +{ + this.filters.remove(oFilter); +}; + +SettingsFilters.prototype.addFilter = function () +{ + var oFilter = new FilterModel(); + oFilter.addCondition(); + + this.filters.push(oFilter); +}; diff --git a/dev/Styles/FolderList.less b/dev/Styles/FolderList.less index 83d263b12..e1afd276b 100644 --- a/dev/Styles/FolderList.less +++ b/dev/Styles/FolderList.less @@ -37,6 +37,7 @@ right: 0; overflow: hidden; overflow-y: auto; + min-width: 100px; // padding: 5px; .content { diff --git a/dev/Styles/Scroll.less b/dev/Styles/Scroll.less index e1e09f553..d83c15479 100644 --- a/dev/Styles/Scroll.less +++ b/dev/Styles/Scroll.less @@ -1,24 +1,24 @@ -.nano:before, .nano:after { - display: none; - content: ""; - position: absolute; - left: 0; - width: 100%; - height: 2px; - z-index: 102; - -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.5); - box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.5); -} - -.nano:before { - top: -2px; -} - -.nano:after { - bottom: -2px; -} - -.nano.nano-scrolllimit-top:before, .nano.nano-scrolllimit-bottom:after { - display: block; +.nano:before, .nano:after { + display: none; + content: ""; + position: absolute; + left: 0; + width: 100%; + height: 10px; + z-index: 102; + -webkit-box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3); + box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3); +} + +.nano:before { + top: -10px; +} + +.nano:after { + bottom: -10px; +} + +.nano.nano-scrolllimit-top:before, .nano.nano-scrolllimit-bottom:after { + display: block; } \ No newline at end of file diff --git a/dev/Styles/Ui.less b/dev/Styles/Ui.less index da1f95934..7834529d1 100644 --- a/dev/Styles/Ui.less +++ b/dev/Styles/Ui.less @@ -190,6 +190,7 @@ html.cssanimations { height: 15px; background-color: #ddd; margin: 0 5px; + .box-shadow(0px 0px 3px rgba(0, 0, 0, 0.3)); border-radius: 100%; display: inline-block; @@ -209,7 +210,7 @@ html.cssanimations { -webkit-animation-delay: -0.16s; animation-delay: -0.16s; } - + } @-webkit-keyframes bouncedelay { diff --git a/dev/Styles/_BootstrapFix.less b/dev/Styles/_BootstrapFix.less index aa3ca15d9..e8939d8f1 100644 --- a/dev/Styles/_BootstrapFix.less +++ b/dev/Styles/_BootstrapFix.less @@ -122,6 +122,8 @@ html.rgba.textshadow { .tooltip { font-size: 14px; z-index: 2000 !important; + overflow: hidden; + text-overflow: ellipsis; &.in { .opacity(100); @@ -130,17 +132,20 @@ html.rgba.textshadow { .tooltip-class { } + .tooltip-inner { + max-width: 400px; + text-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + padding: 5px 10px; + .border-radius(2px); + } + .tooltip-big { font-size: 18px; padding: 0 10px; + white-space: nowrap; } } -.tooltip-inner { - padding: 5px 10px; - .border-radius(2px); -} - // Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match .btn-group > .btn:first-child { -webkit-border-top-left-radius: @btnBorderRadius; diff --git a/dev/ViewModels/AbstractSystemDropDownViewModel.js b/dev/ViewModels/AbstractSystemDropDownViewModel.js index c377eb4dd..d914f9210 100644 --- a/dev/ViewModels/AbstractSystemDropDownViewModel.js +++ b/dev/ViewModels/AbstractSystemDropDownViewModel.js @@ -9,7 +9,7 @@ function AbstractSystemDropDownViewModel() KnoinAbstractViewModel.call(this, 'Right', 'SystemDropDown'); var oData = RL.data(); - + this.accounts = oData.accounts; this.accountEmail = oData.accountEmail; this.accountsLoading = oData.accountsLoading; @@ -37,7 +37,7 @@ AbstractSystemDropDownViewModel.prototype.accountClick = function (oAccount, oEv self.accountsLoading(false); }, 1000); } - + return true; }; diff --git a/package.json b/package.json index 0ca96d80a..9c435dc42 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "RainLoop", "title": "RainLoop Webmail", "version": "1.6.7", - "release": "102", + "release": "106", "description": "Simple, modern & fast web-based email client", "homepage": "http://rainloop.net", "main": "Gruntfile.js", @@ -36,6 +36,7 @@ "plugins" ], "readmeFilename": "README.md", + "ownCloudPackageVersion": "1.2", "engines": { "node": ">= 0.8.0" }, diff --git a/plugins/ispmanager-change-password/IspManagerChangePasswordDriver.php b/plugins/ispconfig-change-password/IspConfigChangePasswordDriver.php similarity index 91% rename from plugins/ispmanager-change-password/IspManagerChangePasswordDriver.php rename to plugins/ispconfig-change-password/IspConfigChangePasswordDriver.php index 30be703af..776bda038 100644 --- a/plugins/ispmanager-change-password/IspManagerChangePasswordDriver.php +++ b/plugins/ispconfig-change-password/IspConfigChangePasswordDriver.php @@ -1,6 +1,6 @@ SetLogger($this->Manager()->Actions()->Logger()); $oProvider->SetConfig($sDsn, $sUser, $sPassword); $oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', '')))); @@ -60,7 +60,7 @@ class IspmanagerChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin public function configMapping() { return array( - \RainLoop\Plugins\Property::NewInstance('pdo_dsn')->SetLabel('ISPmanager PDO dsn') + \RainLoop\Plugins\Property::NewInstance('pdo_dsn')->SetLabel('ISPConfig PDO dsn') ->SetDefaultValue('mysql:host=127.0.0.1;dbname=dbispconfig'), \RainLoop\Plugins\Property::NewInstance('user')->SetLabel('DB User') ->SetDefaultValue('root'), diff --git a/plugins/ispmanager-change-password/VERSION b/plugins/ispmanager-change-password/VERSION deleted file mode 100644 index 9f8e9b69a..000000000 --- a/plugins/ispmanager-change-password/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0 \ No newline at end of file diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php b/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php index 0faf1440d..9a7b2fcad 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php @@ -60,7 +60,7 @@ class HtmlUtils { $sHtmlAttrs = $aMatch[1]; } - + $aMatch = array(); if (preg_match('/]+)>/im', $sHtml, $aMatch) && !empty($aMatch[1])) { @@ -71,7 +71,7 @@ class HtmlUtils $sHtml = \preg_replace('/<\/body>/im', '', $sHtml); $sHtml = \preg_replace('/]*)>/im', '', $sHtml); $sHtml = \preg_replace('/<\/html>/im', '', $sHtml); - + return $sHtml; } @@ -83,8 +83,8 @@ class HtmlUtils public static function ClearTags($sHtml) { $aRemoveTags = array( - 'head', 'link', 'base', 'meta', 'title', 'style', 'script', 'bgsound', - 'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset' + 'head', 'link', 'base', 'meta', 'title', 'style', 'script', 'bgsound', 'keygen', 'source', + 'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset', 'video', 'audio' ); $aToRemove = array( @@ -116,6 +116,7 @@ class HtmlUtils '/on(DblClick)/si', '/on(Error)/si', '/on(Focus)/si', + '/on(FormChange)/si', '/on(KeyDown)/si', '/on(KeyPress)/si', '/on(KeyUp)/si', @@ -418,7 +419,7 @@ class HtmlUtils foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement) { $sTagNameLower = \strtolower($oElement->tagName); - + // convert body attributes to styles if ('body' === $sTagNameLower) { @@ -429,7 +430,7 @@ class HtmlUtils 'bottommargin' => '', 'rightmargin' => '' ); - + if (isset($oElement->attributes)) { foreach ($oElement->attributes as $sAttributeName => /* @var $oAttributeNode \DOMNode */ $oAttributeNode) @@ -451,7 +452,7 @@ class HtmlUtils if (\is_array($aItem)) { $oElement->removeAttribute($aItem[0]); - + switch ($sIndex) { case 'text': @@ -484,7 +485,7 @@ class HtmlUtils { $oElement->setAttribute('src', 'javascript:false'); } - + if (\in_array($sTagNameLower, array('a', 'form', 'area'))) { $oElement->setAttribute('target', '_blank'); @@ -500,12 +501,22 @@ class HtmlUtils // $oElement->removeAttribute('style'); // } - @$oElement->removeAttribute('id'); - @$oElement->removeAttribute('class'); - @$oElement->removeAttribute('contenteditable'); - @$oElement->removeAttribute('designmode'); - @$oElement->removeAttribute('data-bind'); - @$oElement->removeAttribute('xmlns'); + foreach (array( + 'id', 'class', 'contenteditable', 'designmode', 'formaction', 'data-bind', 'xmlns' + ) as $sAttr) + { + @$oElement->removeAttribute($sAttr); + } + + foreach (array( + 'load', 'blur', 'error', 'focus', 'formchange', 'change', + 'click', 'dblclick', 'keydown', 'keypress', 'keyup', + 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'mouseout', 'mouseover', 'mouseup', + 'move', 'resize', 'resizeend', 'resizestart', 'scroll', 'select', 'submit', 'upload' + ) as $sAttr) + { + @$oElement->removeAttribute('on'.$sAttr); + } if ($oElement->hasAttribute('href')) { @@ -544,7 +555,7 @@ class HtmlUtils { $oElement->setAttribute('data-x-src', $sSrc); } - + $bHasExternals = true; } else if ('data:image/' === \strtolower(\substr(\trim($sSrc), 0, 11))) @@ -626,7 +637,7 @@ class HtmlUtils foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement) { $sTagNameLower = \strtolower($oElement->tagName); - + if ($oElement->hasAttribute('data-x-src-cid')) { $sCid = $oElement->getAttribute('data-x-src-cid'); @@ -640,7 +651,7 @@ class HtmlUtils $oElement->setAttribute('src', 'cid:'.$sCid); } } - + if ($oElement->hasAttribute('data-x-src-location')) { $sSrc = $oElement->getAttribute('data-x-src-location'); @@ -838,10 +849,10 @@ class HtmlUtils return $sText; } - + /** * @param string $sText - * + * * @return string */ public static function ConvertHtmlToPlain($sText) @@ -937,7 +948,7 @@ class HtmlUtils '\'', '' ), $sText); - + $sText = str_ireplace('
',"\n
", $sText); $sText = strip_tags($sText, ''); $sText = preg_replace("/\n\\s+\n/", "\n", $sText); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php index 9f80109c5..e6a525ebd 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -1295,7 +1295,7 @@ class Actions $aResult['Language'] = $this->ValidateLanguage($sLanguage); $aResult['UserLanguage'] = $bUserLanguage; $aResult['LangLink'] = APP_INDEX_FILE.'?/Lang/0/'.($bAdmin ? 'en' : $aResult['Language']).'/'.$sStaticCache.'/'; - $aResult['TemplatesLink'] = APP_INDEX_FILE.'?/Templates/0/'.$sStaticCache.'/'; + $aResult['TemplatesLink'] = APP_INDEX_FILE.'?/Templates/0/'.($bAdmin ? 'Admin' : 'App').'/'.$sStaticCache.'/'; $aResult['PluginsLink'] = $sPluginsLink; $aResult['EditorDefaultType'] = 'Html' === $aResult['EditorDefaultType'] ? 'Html' : 'Plain'; @@ -6079,7 +6079,10 @@ class Actions { $oConfig = $this->Config(); - $aResult = array(\RainLoop\Enumerations\Capa::PREM); + $aResult = array( + \RainLoop\Enumerations\Capa::PREM, + \RainLoop\Enumerations\Capa::FILTERS + ); if ($oConfig->Get('webmail', 'allow_additional_accounts', false)) { diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Enumerations/Capa.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Enumerations/Capa.php index b252c988f..7982a1585 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Enumerations/Capa.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Enumerations/Capa.php @@ -1,15 +1,16 @@ -oHttp = $oHttp; $this->oActions = $oActions; $this->aPaths = array(); + $this->sQuery = ''; } /** @@ -449,16 +455,18 @@ class ServiceActions $this->oActions->verifyCacheByKey($this->sQuery); } + $bAdmin = false !== \strpos($this->sQuery, 'Admin'); + $sCacheFileName = ''; if ($bCacheEnabled) { - $sCacheFileName = 'TEMPLATES:'.$this->oActions->Plugins()->Hash().APP_VERSION; + $sCacheFileName = 'TEMPLATES:'.($bAdmin ? 'Admin/' : 'App/').$this->oActions->Plugins()->Hash().APP_VERSION; $sResult = $this->Cacher()->Get($sCacheFileName); } if (0 === \strlen($sResult)) { - $sResult = $this->compileTemplates(false); + $sResult = $this->compileTemplates($bAdmin); if ($bCacheEnabled && 0 < \strlen($sCacheFileName)) { $this->Cacher()->Set($sCacheFileName, $sResult); @@ -1021,20 +1029,16 @@ class ServiceActions /** * @param bool $bAdmin = false - * @param bool $bWrapByScriptTag = true * * @return string */ - private function compileTemplates($bAdmin = false, $bWrapByScriptTag = false) + private function compileTemplates($bAdmin = false) { - $sHtml = \RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views', $this->oActions). + $sHtml = \RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views/'.($bAdmin ? 'Admin' : 'App'), $this->oActions). + \RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views/Common', $this->oActions). $this->oActions->Plugins()->CompileTemplate($bAdmin); - return - ($bWrapByScriptTag ? '' : '') - ; + return 'window.rainloopTEMPLATES='.\MailSo\Base\Utils::Php2js(array($sHtml)).';'; } /** diff --git a/rainloop/v/0.0.0/app/templates/Index.html b/rainloop/v/0.0.0/app/templates/Index.html index 49738f558..2663a0e53 100644 --- a/rainloop/v/0.0.0/app/templates/Index.html +++ b/rainloop/v/0.0.0/app/templates/Index.html @@ -11,7 +11,7 @@ -