mirror of
https://github.com/ONLYOFFICE/CommunityServer.git
synced 2025-04-18 13:24:01 +03:00
Update to v12.0.1
This commit is contained in:
parent
9f0d509e55
commit
adc7314d9b
89
CHANGELOG.md
89
CHANGELOG.md
@ -1,5 +1,94 @@
|
||||
# Change log
|
||||
|
||||
## Version 12.0.1
|
||||
|
||||
### General portal changes
|
||||
|
||||
* Fixed issue with deep linking.
|
||||
* Fixed Migration feature.
|
||||
* Storing indexing status as a list instead of a field for ElasticSearch API.
|
||||
* Enhanced Backup service.
|
||||
* Fixed unavailable Feed after data restoring (Bug #58135).
|
||||
* Fixed invalid ‘Fork me on GitHub’ button link in the Sample (Bug #57588).
|
||||
* Portal users and guests are no more able to make the API SMTP settings request (Bug #57244).
|
||||
* Fixed issue with displaying a new company name (after changing White Label settings) in the password change emails and other similar requests (Bug #56435).
|
||||
* Personal user info is hidden from those who has no access to the People module (Bug #57851).
|
||||
* A drop-down menu in the calendar added when clicking on a month/year (Bug #54767).
|
||||
* Displaying an input cursor in the search bar when filtering with a drop-down list of users (Bug #57317).
|
||||
|
||||
### Server installations
|
||||
|
||||
* Removed storage_root parameter when starting Mail services.
|
||||
* Fixed dotnet dependency installation.
|
||||
* Fixed msttcore-fonts installation.
|
||||
* Upgraded elasticsearch to version 7.16.3 in packages.
|
||||
* Fixed memory allocation for elasticsearch.
|
||||
* Fixed issue with config files after updating on Windows (Bug #50992).
|
||||
* Fixed issue with security configs when making GET requests (Bug #57254).
|
||||
* Fixed issue with mail services when installing on RedHat 8.6 and Centos 8 (Bug #57624).
|
||||
|
||||
### Documents module
|
||||
|
||||
* Changed frequency of displaying a hint page when opening a file in Private Room from the web version.
|
||||
* Updated layout of the files list due to new Favorites icons.
|
||||
* Restriction to open DOC files for editing on mobile devices (Bug #57373).
|
||||
* Added new filtering parameters searchInContent and withSubfolders to API methods.
|
||||
* Changed type of some API methods from GET to PUT/POST (Bug #57371).
|
||||
* Users and their emails are not displayed in mentions if there isn’t access to the People module (Bug #58037).
|
||||
|
||||
### Mail module
|
||||
|
||||
* Added ‘On top’ button when zooming in empty folders (Bug #57671).
|
||||
* Fixed issue with sending an email with a link to a non-editable file in the trial portal version (Bug #54637).
|
||||
* Fixed DOCXF and OFORM icons when attaching files as a link (Bug #57657).
|
||||
* Fixed issue with forwarding emails added to the Templates (Bug #57466).
|
||||
* Fixed issue with filter settings (Bug #57200).
|
||||
* Fixed issue with selecting emails as read/unread (Bug #57390).
|
||||
* Fixed issue with the pop-up notification about a disabled account when printing out emails (Bug #57324).
|
||||
* Fixed issue with re-opening of email signature settings (Bug #57322).
|
||||
* Fixed issue with using the filter when selecting a date by custom period (Bug #57510).
|
||||
* Fixed issue with downloading a file when clicking on the .docxf/.oform format link in Chrome (Bug #57651).
|
||||
|
||||
### People module
|
||||
|
||||
* Fixed Active connections check.
|
||||
* Fixed issue with generating a CardDav book in case user emails contain capital letters (Bug #57831).
|
||||
* Updated drop-down tooltip when setting a password (Bug #57673).
|
||||
* Fixed issue with the https link in the invitation email when importing users (Bug #57519).
|
||||
|
||||
### Projects module
|
||||
|
||||
* Fixed issue with displaying the Time Tracking entry after its creation (Bug #57901)
|
||||
* Fixed issue with closing CKEditor window after editing a task title (Bug #57625).
|
||||
* Restriction of using XSS script in the milestone title (Bug #57559).
|
||||
* Restriction of using XSS script in the Gantt Chart status (Bug #57256).
|
||||
* Fixed issue with the incorrect link to the re-opened task in Telegram notifications (Bug #58107).
|
||||
* Fixed issue with custom task status when re-opening it (Bug #57140).
|
||||
* Administrator is automatically added to the project team when administrator assigns a task to themselves (Bug #57052).
|
||||
* Fixed issue with filtering overdue milestones (Bug #57356).
|
||||
* Fixed issue with filtering tasks when changing the Responsible: Me filter (Bug #57354).
|
||||
* Fixed displaying of date format in Gantt Chart to match the format set on the portal (Bug #57370).
|
||||
|
||||
### CRM module
|
||||
|
||||
* Restriction of using XSS script in the Products & Services settings (Bug #57242).
|
||||
* Fixed issue with the drop-down list in Invoices when page scrolling (Bug #57578).
|
||||
* Removed ‘Show total amount’ link for deals without a budget (Bug #57386).
|
||||
|
||||
### Calendar module
|
||||
|
||||
* Updated functionality of attaching files from the Documents module.
|
||||
* Restriction to access events of other users using the historybyid.json method (Bug #58057).
|
||||
* Fixed issue with unsubscribing from the event (Bug #58118).
|
||||
* Restriction of using XSS script in To-do list (Bug #57307).
|
||||
* Fixed issue with the doubled window in the mini-calendar when selecting a month/year (Bug #57480)
|
||||
* Fixed issue with the CalDav link when the HTTPS certificate is activated (Bug #53265).
|
||||
|
||||
### Control Panel
|
||||
|
||||
* Fixed issue with brand logos after updating in the Docker installation (Bug #57331).
|
||||
* Fixed issue with data import from Google Workspace in case the archive contains incorrect meta-information files (Bug #57617).
|
||||
|
||||
## Version 12.0.0
|
||||
|
||||
### General portal changes
|
||||
|
@ -17,6 +17,11 @@ location / {
|
||||
internal;
|
||||
}
|
||||
|
||||
location ~ (\.config$) {
|
||||
error_page 404 /404.htm;
|
||||
return 404;
|
||||
}
|
||||
|
||||
gzip on;
|
||||
gzip_comp_level 2;
|
||||
gzip_min_length 1000;
|
||||
|
@ -8,7 +8,7 @@ Type=notify
|
||||
User=onlyoffice
|
||||
Group=onlyoffice
|
||||
WorkingDirectory=/var/www/onlyoffice/Services/MailAggregator
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailAggregator/ASC.Mail.Aggregator.Service.dll --urls=http://0.0.0.0:5025 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --'$STORAGE_ROOT'=/var/www/onlyoffice/Data --log:dir=/var/log/onlyoffice/mail --log:name=mail-aggregator --ENVIRONMENT=production
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailAggregator/ASC.Mail.Aggregator.Service.dll --urls=http://0.0.0.0:5025 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --log:dir=/var/log/onlyoffice/mail --log:name=mail-aggregator --ENVIRONMENT=production
|
||||
Environment=OPENSSL_CONF=/etc/onlyoffice/communityserver/openssl.cnf
|
||||
TimeoutSec=600
|
||||
|
||||
|
@ -8,7 +8,7 @@ Type=notify
|
||||
User=onlyoffice
|
||||
Group=onlyoffice
|
||||
WorkingDirectory=/var/www/onlyoffice/Services/MailCleaner/
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailCleaner/ASC.Mail.StorageCleaner.Service.dll --urls=http://0.0.0.0:5032 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --'$STORAGE_ROOT'=/var/www/onlyoffice/Data --log:dir=/var/log/onlyoffice/mail --log:name=mail-storagecleaner --ENVIRONMENT=production
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailCleaner/ASC.Mail.StorageCleaner.Service.dll --urls=http://0.0.0.0:5032 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --log:dir=/var/log/onlyoffice/mail --log:name=mail-storagecleaner --ENVIRONMENT=production
|
||||
TimeoutSec=600
|
||||
|
||||
Restart=no
|
||||
|
@ -8,7 +8,7 @@ Type=notify
|
||||
User=onlyoffice
|
||||
Group=onlyoffice
|
||||
WorkingDirectory=/var/www/onlyoffice/Services/MailImap/
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailImap/ASC.Mail.ImapSync.dll --urls=http://0.0.0.0:5026 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --'$STORAGE_ROOT'=/var/www/onlyoffice/Data --log:dir=/var/log/onlyoffice/mail --log:name=mail-imapsync --ENVIRONMENT=production
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailImap/ASC.Mail.ImapSync.dll --urls=http://0.0.0.0:5026 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --log:dir=/var/log/onlyoffice/mail --log:name=mail-imapsync --ENVIRONMENT=production
|
||||
Environment=OPENSSL_CONF=/etc/onlyoffice/communityserver/openssl.cnf
|
||||
TimeoutSec=600
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
[Unit]
|
||||
Description=ONLYOFFICE MailImap Service
|
||||
Description=ONLYOFFICE MailWatchdog Service
|
||||
After=network.target syslog.target mysqld.service
|
||||
Wants=mysqld.service
|
||||
|
||||
@ -8,7 +8,7 @@ Type=notify
|
||||
User=onlyoffice
|
||||
Group=onlyoffice
|
||||
WorkingDirectory=/var/www/onlyoffice/Services/MailWatchdog/
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailWatchdog/ASC.Mail.Watchdog.Service.dll --urls=http://0.0.0.0:5031 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --'$STORAGE_ROOT'=/var/www/onlyoffice/Data --log:dir=/var/log/onlyoffice/mail --log:name=mail-watchdog --ENVIRONMENT=production
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailWatchdog/ASC.Mail.Watchdog.Service.dll --urls=http://0.0.0.0:5031 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --log:dir=/var/log/onlyoffice/mail --log:name=mail-watchdog --ENVIRONMENT=production
|
||||
TimeoutSec=600
|
||||
|
||||
Restart=no
|
||||
|
@ -50,7 +50,7 @@ apply_connection_string(){
|
||||
sed "s!\"database\":.*!\"database\":\"${DB_NAME}\"!" -i ${APP_SERVICES_DIR}/ASC.UrlShortener/config/config.json
|
||||
|
||||
fi
|
||||
sed -i "s/Server=.*/Server=$DB_HOST;Port=3306;Database=$DB_NAME;User ID=$DB_USER;Password=$DB_PWD;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false\",/g" /etc/onlyoffice/communityserver/appsettings.production.json
|
||||
sed -i "s/Server=.*/Server=$DB_HOST;Port=3306;Database=$DB_NAME;User ID=$DB_USER;Password=$DB_PWD;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false\",/g" /etc/{{package_sysname}}/communityserver/appsettings.production.json
|
||||
}
|
||||
|
||||
apply_core_machinekey(){
|
||||
@ -67,7 +67,7 @@ apply_core_machinekey(){
|
||||
|
||||
if [ ! -z $CORE_MACHINEKEY ]; then
|
||||
sed "s!\"core\.machinekey\":.*!\"core\.machinekey\":\"${CORE_MACHINEKEY}\",!" -i ${APP_SERVICES_DIR}/ASC.UrlShortener/config/config.json
|
||||
sed "s!\"machinekey\":.*!\"machinekey\":\"${CORE_MACHINEKEY}\",!" -i /etc/onlyoffice/communityserver/appsettings.production.json
|
||||
sed "s!\"machinekey\":.*!\"machinekey\":\"${CORE_MACHINEKEY}\",!" -i /etc/{{package_sysname}}/communityserver/appsettings.production.json
|
||||
fi
|
||||
}
|
||||
|
||||
@ -314,6 +314,12 @@ END
|
||||
sed -i "s/Dlog4j2.formatMsgNoLookups.*/Dlog4j2.formatMsgNoLookups=true/" /etc/elasticsearch/jvm.options
|
||||
fi
|
||||
|
||||
if ! grep -q "ingest.geoip.downloader.enabled" /etc/elasticsearch/elasticsearch.yml; then
|
||||
echo "ingest.geoip.downloader.enabled: false" >> /etc/elasticsearch/elasticsearch.yml
|
||||
else
|
||||
sed -i "s/ingest.geoip.downloader.enabled.*/ingest.geoip.downloader.enabled: false/" /etc/elasticsearch/elasticsearch.yml
|
||||
fi
|
||||
|
||||
TOTAL_MEMORY=$(free -m | grep -oP '\d+' | head -n 1);
|
||||
MEMORY_REQUIREMENTS=12228; #RAM ~4*3Gb
|
||||
|
||||
|
@ -58,5 +58,5 @@ sed 's_\(\"DefaultApiSchema":\).*,_\1 "https",_' -i ${APP_CONFIG_DIR}/mail.produ
|
||||
|
||||
mv -f default-onlyoffice-ssl.conf ${NGINX_CONF_DIR}/onlyoffice.conf
|
||||
|
||||
service onlyofficeMailAggregator restart
|
||||
service nginx reload
|
||||
systemctl restart onlyofficeMailAggregator
|
||||
systemctl reload nginx
|
||||
|
@ -16,6 +16,6 @@ sed '/certificate"/s!\(value\s*=\s*\"\).*\"!\1\"!' -i ${APP_SERVICES_ROOT_DIR}/J
|
||||
sed '/certificatePassword/s/\(value\s*=\s*\"\).*\"/\1\"/' -i ${APP_SERVICES_ROOT_DIR}/Jabber/ASC.Xmpp.Server.Launcher.exe.config
|
||||
sed '/startTls/s/\(value\s*=\s*\"\).*\"/\1none\"/' -i ${APP_SERVICES_ROOT_DIR}/Jabber/ASC.Xmpp.Server.Launcher.exe.config
|
||||
|
||||
service onlyofficeJabber restart
|
||||
service onlyofficeMailAggregator restart
|
||||
service nginx reload
|
||||
systemctl restart onlyofficeJabber
|
||||
systemctl restart onlyofficeMailAggregator
|
||||
systemctl reload nginx
|
||||
|
@ -14,7 +14,7 @@ cat > ${LETSENCRYPT_ROOT_DIR}/renewal-hooks/deploy/mailserver.sh <<END
|
||||
cp -f ${LETSENCRYPT_ROOT_DIR}/live/$1/fullchain.pem ${ROOT_DIR}/mail.onlyoffice.crt
|
||||
cp -f ${LETSENCRYPT_ROOT_DIR}/live/$1/privkey.pem ${ROOT_DIR}/mail.onlyoffice.key
|
||||
|
||||
service nginx reload
|
||||
systemctl reload nginx
|
||||
|
||||
END
|
||||
|
||||
|
@ -28,7 +28,7 @@ cp -f ${LETSENCRYPT_ROOT_DIR}/live/$1/fullchain.pem ${ROOT_DIR}/onlyoffice.crt
|
||||
cp -f ${LETSENCRYPT_ROOT_DIR}/live/$1/privkey.pem ${ROOT_DIR}/onlyoffice.key
|
||||
cp -f ${LETSENCRYPT_ROOT_DIR}/live/$1/chain.pem ${ROOT_DIR}/stapling.trusted.crt
|
||||
|
||||
service nginx reload
|
||||
systemctl reload nginx
|
||||
|
||||
END
|
||||
|
||||
|
@ -17,6 +17,11 @@ location / {
|
||||
internal;
|
||||
}
|
||||
|
||||
location ~ (\.(config|rpmsave)$) {
|
||||
error_page 404 /404.htm;
|
||||
return 404;
|
||||
}
|
||||
|
||||
gzip on;
|
||||
gzip_comp_level 2;
|
||||
gzip_min_length 1000;
|
||||
|
@ -8,7 +8,7 @@ Type=notify
|
||||
User=onlyoffice
|
||||
Group=onlyoffice
|
||||
WorkingDirectory=/var/www/onlyoffice/Services/MailAggregator
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailAggregator/ASC.Mail.Aggregator.Service.dll --urls=http://0.0.0.0:5025 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --'$STORAGE_ROOT'=/var/www/onlyoffice/Data --log:dir=/var/log/onlyoffice/mail --log:name=mail-aggregator --ENVIRONMENT=production
|
||||
ExecStart=/usr/bin/dotnet /var/www/onlyoffice/Services/MailAggregator/ASC.Mail.Aggregator.Service.dll --urls=http://0.0.0.0:5025 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --log:dir=/var/log/onlyoffice/mail --log:name=mail-aggregator --ENVIRONMENT=production
|
||||
TimeoutSec=600
|
||||
|
||||
Restart=no
|
||||
|
@ -8,7 +8,7 @@ Type=notify
|
||||
User=onlyoffice
|
||||
Group=onlyoffice
|
||||
WorkingDirectory=/var/www/onlyoffice/Services/MailCleaner/
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailCleaner/ASC.Mail.StorageCleaner.Service.dll --urls=http://0.0.0.0:5032 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --'$STORAGE_ROOT'=/var/www/onlyoffice/Data --log:dir=/var/log/onlyoffice/mail --log:name=mail-storagecleaner --ENVIRONMENT=production
|
||||
ExecStart=/usr/bin/dotnet /var/www/onlyoffice/Services/MailCleaner/ASC.Mail.StorageCleaner.Service.dll --urls=http://0.0.0.0:5032 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --log:dir=/var/log/onlyoffice/mail --log:name=mail-storagecleaner --ENVIRONMENT=production
|
||||
TimeoutSec=600
|
||||
|
||||
Restart=no
|
||||
|
@ -8,7 +8,7 @@ Type=notify
|
||||
User=onlyoffice
|
||||
Group=onlyoffice
|
||||
WorkingDirectory=/var/www/onlyoffice/Services/MailImap/
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailImap/ASC.Mail.ImapSync.dll --urls=http://0.0.0.0:5026 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --'$STORAGE_ROOT'=/var/www/onlyoffice/Data --log:dir=/var/log/onlyoffice/mail --log:name=mail-imapsync --ENVIRONMENT=production
|
||||
ExecStart=/usr/bin/dotnet /var/www/onlyoffice/Services/MailImap/ASC.Mail.ImapSync.dll --urls=http://0.0.0.0:5026 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --log:dir=/var/log/onlyoffice/mail --log:name=mail-imapsync --ENVIRONMENT=production
|
||||
TimeoutSec=600
|
||||
|
||||
Restart=no
|
||||
|
@ -1,5 +1,5 @@
|
||||
[Unit]
|
||||
Description=ONLYOFFICE MailImap Service
|
||||
Description=ONLYOFFICE MailWatchdog Service
|
||||
After=network.target syslog.target mysqld.service
|
||||
Wants=mysqld.service
|
||||
|
||||
@ -8,7 +8,7 @@ Type=notify
|
||||
User=onlyoffice
|
||||
Group=onlyoffice
|
||||
WorkingDirectory=/var/www/onlyoffice/Services/MailWatchdog/
|
||||
ExecStart=/usr/share/dotnet/dotnet /var/www/onlyoffice/Services/MailWatchdog/ASC.Mail.Watchdog.Service.dll --urls=http://0.0.0.0:5031 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --'$STORAGE_ROOT'=/var/www/onlyoffice/Data --log:dir=/var/log/onlyoffice/mail --log:name=mail-watchdog --ENVIRONMENT=production
|
||||
ExecStart=/usr/bin/dotnet /var/www/onlyoffice/Services/MailWatchdog/ASC.Mail.Watchdog.Service.dll --urls=http://0.0.0.0:5031 --pathToConf=/etc/onlyoffice/communityserver --pathToNlogConf=/etc/onlyoffice/communityserver --log:dir=/var/log/onlyoffice/mail --log:name=mail-watchdog --ENVIRONMENT=production
|
||||
TimeoutSec=600
|
||||
|
||||
Restart=no
|
||||
|
@ -397,6 +397,12 @@ else
|
||||
sed -i "s/Dlog4j2.formatMsgNoLookups.*/Dlog4j2.formatMsgNoLookups=true/" ${ELASTIC_SEARCH_JAVA_CONF_PATH}
|
||||
fi
|
||||
|
||||
if ! grep -q "ingest.geoip.downloader.enabled" ${ELASTIC_SEARCH_CONF_PATH}; then
|
||||
echo "ingest.geoip.downloader.enabled: false" >> ${ELASTIC_SEARCH_CONF_PATH}
|
||||
else
|
||||
sed -i "s/ingest.geoip.downloader.enabled.*/ingest.geoip.downloader.enabled: false/" ${ELASTIC_SEARCH_CONF_PATH}
|
||||
fi
|
||||
|
||||
TOTAL_MEMORY=$(free -m | grep -oP '\d+' | head -n 1);
|
||||
MEMORY_REQUIREMENTS=12228; #RAM ~4*3Gb
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
%global package_header_tag_url http://onlyoffice.com/
|
||||
%global package_header_tag_vendor Ascensio System SIA
|
||||
%global package_header_tag_packager Ascensio System SIA <support@onlyoffice.com>
|
||||
%global package_header_tag_requires mono-complete >= 6.8.0, nginx >= 1.9.5, mysql-server >= 5.7.0, wget, mono-webserver-hyperfastcgi, nodejs >= 12.0.0, redis >= 3.0.0, elasticsearch = 7.10.0-1, python3 >= 3.6, ffmpeg, jq
|
||||
%global package_header_tag_requires mono-complete >= 6.8.0, nginx >= 1.9.5, mysql-server >= 5.7.0, wget, mono-webserver-hyperfastcgi, nodejs >= 12.0.0, redis >= 3.0.0, elasticsearch = 7.16.3-1, python3 >= 3.6, ffmpeg, jq
|
||||
%global package_section_description "Community Server is a free open-source collaborative system developed to manage documents, projects, customer relationship and emails, all in one place."
|
||||
%global package_services god monoserve monoserveApiSystem onlyofficeSocketIO onlyofficeThumb onlyofficeTelegram onlyofficeBackup onlyofficeFeed onlyofficeIndex onlyofficeNotify onlyofficeMailAggregator onlyofficeMailWatchdog onlyofficeMailCleaner onlyofficeMailImap onlyofficeStorageMigrate onlyofficeStorageEncryption onlyofficeUrlShortener onlyofficeWebDav onlyofficeAutoCleanUp onlyofficeRadicale onlyofficeThumbnailBuilder onlyofficeSsoAuth
|
||||
|
||||
|
@ -1380,7 +1380,8 @@ CREATE TABLE IF NOT EXISTS `login_events` (
|
||||
`active` int(10) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `date` (`date`),
|
||||
KEY `tenant_id` (`tenant_id`,`user_id`)
|
||||
KEY `tenant_id` (`tenant_id`,`user_id`),
|
||||
KEY `active` (`active`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `mail_alerts` (
|
||||
|
@ -8,8 +8,10 @@ BEGIN
|
||||
IF NOT EXISTS(SELECT * FROM information_schema.`COLUMNS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'files_file' AND COLUMN_NAME = 'encrypted') THEN
|
||||
ALTER TABLE `files_file` ADD COLUMN `encrypted` INT(1) NOT NULL DEFAULT '0' AFTER `changes`;
|
||||
END IF;
|
||||
|
||||
INSERT IGNORE INTO core_settings(tenant, id, value) values (-1, 'CompanyWhiteLabelSettings', 0xF547048A4865171587D9CEBC8A496C601D96031F2C1C3E9160353942EE765DACD316F4B5F42892436FC4A21B9A6DF8FFD3BC4036B47E3A5A1B4C881B26609869FEBB6848BD88C02EEAC6A4CCB3E8F404290812F0E6E124A552BE81A58C64BB8BD3C9A8C0EDE1F9421281DE0C7AF82733C0B754E97EFFFA5A75607A91957896CBECF9563FC831300DC8E7C930A55B298EB82D6F69E0ED6E4D8752607F1881F61B032306E0F069A5F69F086A177EB41AC06F889EB0B39CBFD4B5CDB763E996554DEADB9C71CF3EF86F4A0354A864A10639DFD29B5C6D5DCDA9D4B0988EE406948BCB54C6A70ADC6C00577174285CEBCD76);
|
||||
|
||||
IF NOT EXISTS(SELECT * FROM core_settings WHERE tenant = -1 AND id = 'CustomMode') THEN
|
||||
INSERT IGNORE INTO core_settings(tenant, id, value) values (-1, 'CompanyWhiteLabelSettings', 0xF547048A4865171587D9CEBC8A496C601D96031F2C1C3E9160353942EE765DACD316F4B5F42892436FC4A21B9A6DF8FFD3BC4036B47E3A5A1B4C881B26609869FEBB6848BD88C02EEAC6A4CCB3E8F404290812F0E6E124A552BE81A58C64BB8BD3C9A8C0EDE1F9421281DE0C7AF82733C0B754E97EFFFA5A75607A91957896CBECF9563FC831300DC8E7C930A55B298EB82D6F69E0ED6E4D8752607F1881F61B032306E0F069A5F69F086A177EB41AC06F889EB0B39CBFD4B5CDB763E996554DEADB9C71CF3EF86F4A0354A864A10639DFD29B5C6D5DCDA9D4B0988EE406948BCB54C6A70ADC6C00577174285CEBCD76);
|
||||
END IF;
|
||||
|
||||
END DLM00
|
||||
|
||||
|
@ -100,9 +100,11 @@ BEGIN
|
||||
SET `textValue` = REPLACE(`textValue`, 'products/crm', 'Products/CRM')
|
||||
WHERE `fileid` = (SELECT `id` FROM `res_files` WHERE `resName` = 'WebstudioNotifyPatternResource.resx');
|
||||
|
||||
UPDATE `core_settings`
|
||||
SET `value`=0xF547048A4865171587D9CEBC8A496C601D96031F2C1C3E9160353942EE765DACD316F4B5F42892436FC4A21B9A6DF8FFD3BC4036B47E3A5A1B4C881B26609869FEBB6848BD88C02EEAC6A4CCB3E8F404290812F0E6E124A552BE81A58C64BB8BD3C9A8C0EDE1F9421281DE0C7AF82733A4BCE515E85694C4DDA78E22652BA2891FCE9578F97285A81E12FEDF5D6558611E3AA3E03EADDCAA98287C64A5510757A881B00C3345E6FC1E22B607CA2D753C63F1ED94C92366DBA0E4C2E6DB16F44A8AB091007AA7505D17E41530643C1FFAE822F8F99FD2E30C0DEF82DF65C43324507F3E5C68E4C5E22BE8A40C24423485
|
||||
WHERE `tenant`=-1 AND `id`='CompanyWhiteLabelSettings';
|
||||
IF NOT EXISTS(SELECT * FROM core_settings WHERE tenant = -1 AND id = 'CustomMode') THEN
|
||||
UPDATE `core_settings`
|
||||
SET `value`=0xF547048A4865171587D9CEBC8A496C601D96031F2C1C3E9160353942EE765DACD316F4B5F42892436FC4A21B9A6DF8FFD3BC4036B47E3A5A1B4C881B26609869FEBB6848BD88C02EEAC6A4CCB3E8F404290812F0E6E124A552BE81A58C64BB8BD3C9A8C0EDE1F9421281DE0C7AF82733A4BCE515E85694C4DDA78E22652BA2891FCE9578F97285A81E12FEDF5D6558611E3AA3E03EADDCAA98287C64A5510757A881B00C3345E6FC1E22B607CA2D753C63F1ED94C92366DBA0E4C2E6DB16F44A8AB091007AA7505D17E41530643C1FFAE822F8F99FD2E30C0DEF82DF65C43324507F3E5C68E4C5E22BE8A40C24423485
|
||||
WHERE `tenant`=-1 AND `id`='CompanyWhiteLabelSettings';
|
||||
END IF;
|
||||
|
||||
END DLM00
|
||||
|
||||
|
@ -255,6 +255,10 @@ BEGIN
|
||||
ALTER TABLE `login_events` ADD COLUMN `active` INT(10) NOT NULL DEFAULT '0' AFTER `description`;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS(SELECT * FROM information_schema.`STATISTICS` WHERE `TABLE_SCHEMA` = DATABASE() AND `TABLE_NAME` = 'login_events' AND `INDEX_NAME` = 'active') THEN
|
||||
ALTER TABLE `login_events` ADD INDEX `active` (`active`);
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS(SELECT * FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'calendar_events' AND COLUMN_NAME = 'has_attachments') THEN
|
||||
ALTER TABLE `calendar_events` ADD COLUMN `has_attachments` TINYINT(1) NOT NULL DEFAULT '0' AFTER `time_zone`;
|
||||
END IF;
|
||||
@ -264,9 +268,20 @@ BEGIN
|
||||
ALTER TABLE `mail_mail` ADD COLUMN `read_request_status` TINYINT(1) NOT NULL DEFAULT '0' AFTER `chain_date`;
|
||||
END IF;
|
||||
|
||||
UPDATE `core_settings`
|
||||
SET `value`=0xF547048A4865171587D9CEBC8A496C601D96031F2C1C3E9160353942EE765DACD316F4B5F42892436FC4A21B9A6DF8FFB511FD7F2A41135A1ACECB919F9FF3691847BCA535553925BAFB396012A2DA500065FA6442611833F0D7D8A969640FFD1D53B6ECCB3544FB029695943A88542597525CE31E346F289A9B077E9564A9570A81E48AB1654D43B1D8BDC901D588D86BC6FDDD6AFFC611440E6E5AAEB644DEBC4D9D131A4456610F5118ABD672BFAF383830347D52FD714729C9050876A2BF63C430C6DF4FCCAE1F61EC14D5DA5522104AC4D1EB0E47D12083C3540B424A1373FF6345EBD2CC0F0D048F7F987DD45B
|
||||
WHERE `tenant`=-1 AND `id`='CompanyWhiteLabelSettings';
|
||||
IF NOT EXISTS(SELECT * FROM core_settings WHERE tenant = -1 AND id = 'CustomMode') THEN
|
||||
UPDATE `core_settings`
|
||||
SET `value`=0xF547048A4865171587D9CEBC8A496C601D96031F2C1C3E9160353942EE765DACD316F4B5F42892436FC4A21B9A6DF8FFB511FD7F2A41135A1ACECB919F9FF3691847BCA535553925BAFB396012A2DA500065FA6442611833F0D7D8A969640FFD1D53B6ECCB3544FB029695943A88542597525CE31E346F289A9B077E9564A9570A81E48AB1654D43B1D8BDC901D588D86BC6FDDD6AFFC611440E6E5AAEB644DEBC4D9D131A4456610F5118ABD672BFAF383830347D52FD714729C9050876A2BF63C430C6DF4FCCAE1F61EC14D5DA5522104AC4D1EB0E47D12083C3540B424A1373FF6345EBD2CC0F0D048F7F987DD45B
|
||||
WHERE `tenant`=-1 AND `id`='CompanyWhiteLabelSettings';
|
||||
END IF;
|
||||
|
||||
IF EXISTS(SELECT * FROM core_settings WHERE tenant = -1 AND id = 'CustomMode') THEN
|
||||
UPDATE `core_settings`
|
||||
SET `value`=0xF547048A4865171587D9CEBC8A496C6058DF4F90020290E3BB59C0B7C027FBA70FB0863A8FBC33232A20DB226B8D5D4F7B363F0C4497E997383720E1B39BB95416F7227F55DEBADDF28FC81D15971C1E1417B9C652B36964BAC4820225F7127BD391ED7A57C1F65C0AEB3450AB23603D5D49EA55AA20A98198CA01741ED1D971FCE56FD6AA98FF466DC6330CE50C66461D08B1BAE7C87218A48504BBD846AA83CF1FF0DB6D377D39C972C61EFCD682088EE868FB230A032DAEF2AD037BD4E19209FAE102500553888219C39F3B404B7166EFDCDC6E64AB6D48116512C00CA720B34591D75672932931B3A0EFF63751B8CE77A275C2614A98056A431B74683F411536C17EBB200FABB222CA0E1BBE58AB84D94CC1179C57ED6723227DD8BCA296
|
||||
WHERE `tenant`=-1 AND `id`='CompanyWhiteLabelSettings';
|
||||
|
||||
DELETE FROM `files_converts` WHERE `input` = '.docx' AND `output` = '.docxf';
|
||||
DELETE FROM `files_converts` WHERE `input` = '.docxf';
|
||||
END IF;
|
||||
|
||||
END DLM00
|
||||
|
||||
|
@ -72,6 +72,11 @@ namespace ASC.Common.Data
|
||||
get { return Command.Transaction != null; }
|
||||
}
|
||||
|
||||
public bool IsDisposed
|
||||
{
|
||||
get { return disposed; }
|
||||
}
|
||||
|
||||
public DbConnection Connection
|
||||
{
|
||||
get { return Command.Connection; }
|
||||
@ -298,7 +303,7 @@ namespace ASC.Common.Data
|
||||
public DbConnection Connection { get { return dbManager.Connection; } }
|
||||
public string DatabaseId { get { return dbManager.DatabaseId; } }
|
||||
public bool InTransaction { get { return dbManager.InTransaction; } }
|
||||
|
||||
public bool IsDisposed { get { return dbManager.IsDisposed; } }
|
||||
public IDbTransaction BeginTransaction()
|
||||
{
|
||||
return dbManager.BeginTransaction();
|
||||
|
@ -30,6 +30,7 @@ namespace ASC.Common.Data
|
||||
DbConnection Connection { get; }
|
||||
string DatabaseId { get; }
|
||||
bool InTransaction { get; }
|
||||
bool IsDisposed { get; }
|
||||
|
||||
IDbTransaction BeginTransaction();
|
||||
|
||||
|
@ -38,6 +38,7 @@ namespace ASC.Common.Data
|
||||
|
||||
public string DatabaseId { get; private set; }
|
||||
public bool InTransaction { get { return localDb.InTransaction; } }
|
||||
public bool IsDisposed { get { return disposed; } }
|
||||
|
||||
public DbConnection Connection
|
||||
{
|
||||
|
@ -40,6 +40,21 @@ namespace ASC.Geolocation
|
||||
this.dbid = dbid;
|
||||
}
|
||||
|
||||
public bool HasData()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var db = DbManager.FromHttpContext(dbid))
|
||||
{
|
||||
return db.ExecuteScalar<bool>("select exists(select 1 from dbip_location)");
|
||||
}
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
log.Error(error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public IPGeolocationInfo GetIPGeolocation(string ip)
|
||||
{
|
||||
|
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
@ -57,6 +59,27 @@ namespace ASC.Common.Radicale
|
||||
return GetDavResponse(response);
|
||||
}
|
||||
|
||||
public static void Remove(DavRequest davRequest)
|
||||
{
|
||||
var request = WebRequest.Create(davRequest.Url);
|
||||
request.Method = "DELETE";
|
||||
|
||||
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(davRequest.Authorization)));
|
||||
request.Headers.Add("X_REWRITER_URL", davRequest.Header);
|
||||
|
||||
using (var response = request.GetResponse())
|
||||
using (var responseStream = response.GetResponseStream())
|
||||
{
|
||||
if (responseStream != null)
|
||||
{
|
||||
using (var readStream = new StreamReader(responseStream)){
|
||||
var result = readStream.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
public async static Task RemoveAsync(DavRequest davRequest)
|
||||
{
|
||||
davRequest.Method = "DELETE";
|
||||
@ -67,7 +90,15 @@ namespace ASC.Common.Radicale
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var hc = new HttpClient())
|
||||
var httpHandler = new HttpClientHandler();
|
||||
|
||||
//HACK: http://ubuntuforums.org/showthread.php?t=1841740
|
||||
if (Type.GetType("Mono.Runtime") != null)
|
||||
{
|
||||
httpHandler.ServerCertificateCustomValidationCallback = delegate { return true; };
|
||||
}
|
||||
|
||||
using (var hc = new HttpClient(httpHandler))
|
||||
{
|
||||
hc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(davRequest.Authorization)));
|
||||
if (!String.IsNullOrEmpty(davRequest.Header)) hc.DefaultRequestHeaders.Add("X_REWRITER_URL", davRequest.Header);
|
||||
|
@ -115,8 +115,7 @@ namespace ASC.Core
|
||||
return false;
|
||||
}
|
||||
|
||||
var settingLoginEvents = DbLoginEventsManager.GetLoginEventIds(tenant, userid);
|
||||
if (loginEventId != 0 && !settingLoginEvents.Contains(loginEventId))
|
||||
if (!DbLoginEventsManager.IsActiveLoginEvent(tenant, userid, loginEventId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -51,29 +51,38 @@ namespace ASC.Core.Data
|
||||
MessageAction.LoginSuccessViaApiTfa
|
||||
};
|
||||
|
||||
public static List<int> GetLoginEventIds(int tenantId, Guid userId)
|
||||
public static bool IsActiveLoginEvent(int tenantId, Guid userId, int loginEventId)
|
||||
{
|
||||
var commonKey = GetCacheKey(tenantId, userId);
|
||||
var cacheKeys = cache.Get<List<int>>(commonKey);
|
||||
if (cacheKeys != null)
|
||||
if (loginEventId == 0) return true;
|
||||
|
||||
var cacheKey = GetCacheKey(tenantId, userId);
|
||||
|
||||
var cachedLoginEvents = cache.Get<Dictionary<int, bool>>(cacheKey);
|
||||
if (cachedLoginEvents != null)
|
||||
{
|
||||
return cacheKeys;
|
||||
if (cachedLoginEvents.ContainsKey(loginEventId))
|
||||
{
|
||||
return cachedLoginEvents[loginEventId];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cachedLoginEvents = new Dictionary<int, bool>();
|
||||
}
|
||||
|
||||
using (var db = GetDbManager())
|
||||
{
|
||||
var where = GetActiveConnectionsWhere(tenantId, userId);
|
||||
var query = new SqlQuery("login_events")
|
||||
.Select("id")
|
||||
.Where(where);
|
||||
var resultList = db.ExecuteList(query).Select(row => (int)row[0]).ToList();
|
||||
.Select("active")
|
||||
.Where("id", loginEventId);
|
||||
|
||||
if (resultList != null)
|
||||
{
|
||||
cache.Insert(commonKey, resultList, expirationTimeout);
|
||||
}
|
||||
var isActive = db.ExecuteScalar<bool>(query);
|
||||
|
||||
return resultList;
|
||||
cachedLoginEvents.Add(loginEventId, isActive);
|
||||
|
||||
cache.Insert(cacheKey, cachedLoginEvents, expirationTimeout);
|
||||
|
||||
return isActive;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ namespace ASC.Data.Backup.Service
|
||||
set { this["period"] = value; }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("workerCount", DefaultValue = 1)]
|
||||
[ConfigurationProperty("workerCount", DefaultValue = 2)]
|
||||
public int WorkerCount
|
||||
{
|
||||
get { return (int)this["workerCount"]; }
|
||||
|
@ -455,7 +455,7 @@ namespace ASC.Data.Backup.Tasks
|
||||
var s = obj[i] as string;
|
||||
if (s != null)
|
||||
{
|
||||
sw.Write("'" + s.Replace("\r", "\\r").Replace("\n", "\\n") + "'");
|
||||
sw.Write("'" + s.Replace("\\", "\\\\").Replace("\r", "\\r").Replace("'", "\\'").Replace("\n", "\\n") + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -265,73 +265,14 @@ namespace ASC.Data.Backup.Tasks
|
||||
|
||||
try
|
||||
{
|
||||
commandText = commandText.Replace("\\r", "\r").Replace("\\n", "\n");
|
||||
await dbManager.ExecuteNonQueryAsync(commandText, null);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (commandText.StartsWith("REPLACE INTO"))
|
||||
{
|
||||
var innerValues = commandText.Split(',').ToList();
|
||||
for (int i = 0; i < innerValues.Count(); i++)
|
||||
{
|
||||
var flag1 = false;
|
||||
var flag2 = false;
|
||||
if (innerValues[i].StartsWith("("))
|
||||
{
|
||||
flag1 = true;
|
||||
innerValues[i] = innerValues[i].TrimStart('(');
|
||||
}
|
||||
else if (innerValues[i].EndsWith(")") && !innerValues[i].StartsWith("'")
|
||||
|| innerValues[i].EndsWith("')") && innerValues[i] != "')")
|
||||
{
|
||||
flag2 = true;
|
||||
innerValues[i] = innerValues[i].TrimEnd(')');
|
||||
}
|
||||
if (i == innerValues.Count() - 1)
|
||||
{
|
||||
innerValues[i] = innerValues[i].Remove(innerValues[i].Length - 2, 2);
|
||||
}
|
||||
if (innerValues[i].StartsWith("\'") && ((!innerValues[i].EndsWith("\'") || innerValues[i] == "'")
|
||||
|| i != innerValues.Count() - 1 && (!innerValues[i + 1].StartsWith("\'") && innerValues[i + 1].EndsWith("\'") && !innerValues[i + 1].StartsWith("(\'") || innerValues[i + 1] == "'")))
|
||||
{
|
||||
innerValues[i] += "," + innerValues[i + 1];
|
||||
innerValues.RemoveAt(i + 1);
|
||||
}
|
||||
if (innerValues[i].StartsWith("\'") && innerValues[i].EndsWith("\'"))
|
||||
{
|
||||
if (innerValues[i] != "''")
|
||||
{
|
||||
var sw = new StringWriter();
|
||||
sw.Write("0x");
|
||||
foreach (var b in Encoding.UTF8.GetBytes(innerValues[i].Trim('\'')))
|
||||
sw.Write("{0:x2}", b);
|
||||
innerValues[i] = string.Format("CONVERT({0} USING utf8)", sw.ToString());
|
||||
}
|
||||
}
|
||||
if (flag1)
|
||||
{
|
||||
innerValues[i] = "(" + innerValues[i];
|
||||
}
|
||||
else if (flag2)
|
||||
{
|
||||
innerValues[i] = innerValues[i] + ")";
|
||||
}
|
||||
if (i == innerValues.Count() - 1)
|
||||
{
|
||||
innerValues[i] = innerValues[i] + ");";
|
||||
}
|
||||
}
|
||||
commandText = string.Join(",", innerValues).ToString();
|
||||
await dbManager.ExecuteNonQueryAsync(commandText, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(1000);//avoiding deadlock
|
||||
await dbManager.ExecuteNonQueryAsync(commandText, null);
|
||||
}
|
||||
Thread.Sleep(2000);//avoiding deadlock
|
||||
await dbManager.ExecuteNonQueryAsync(commandText, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -224,7 +224,7 @@ namespace ASC.Data.Backup.Tasks
|
||||
{
|
||||
if (u.Contains(".upgrade."))
|
||||
{
|
||||
RunMysqlFile(s, null).Wait();
|
||||
RunMysqlFile(s, "default", null).Wait();
|
||||
}
|
||||
else if (u.Contains(".data") || u.Contains(".upgrade"))
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
{
|
||||
public class DataProvider : IDisposable
|
||||
{
|
||||
private readonly IDbManager db;
|
||||
private IDbManager _db;
|
||||
private const string DBId = "calendar";
|
||||
private const string _calendarTable = "calendar_calendars cal";
|
||||
private const string _calendarItemTable = "calendar_calendar_item cal_itm";
|
||||
@ -63,9 +63,21 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
}
|
||||
}
|
||||
|
||||
private IDbManager db
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_db == null || _db.IsDisposed)
|
||||
{
|
||||
_db = DbManager.FromHttpContext(DBId);
|
||||
}
|
||||
return _db;
|
||||
}
|
||||
}
|
||||
|
||||
public DataProvider()
|
||||
{
|
||||
db = DbManager.FromHttpContext(DBId);
|
||||
_db = DbManager.FromHttpContext(DBId);
|
||||
}
|
||||
|
||||
public List<UserViewSettings> GetUserViewSettings(Guid userId, List<string> calendarIds)
|
||||
@ -116,9 +128,6 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
|
||||
public List<Calendar> LoadTodoCalendarsForUser(Guid userId)
|
||||
{
|
||||
var groups = CoreContext.UserManager.GetUserGroups(userId).Select(g => g.ID).ToList();
|
||||
groups.AddRange(
|
||||
CoreContext.UserManager.GetUserGroups(userId, Core.Users.Constants.SysGroupCategoryId).Select(g => g.ID));
|
||||
var currentTenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId;
|
||||
var queryGetCalIds = new SqlQuery(_calendarTable)
|
||||
.Select("cal.id")
|
||||
@ -145,10 +154,7 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
}
|
||||
public List<Calendar> LoadCalendarsForUser(Guid userId, out int newCalendarsCount)
|
||||
{
|
||||
var groups = CoreContext.UserManager.GetUserGroups(userId).Select(g => g.ID).ToList();
|
||||
groups.AddRange(
|
||||
CoreContext.UserManager.GetUserGroups(userId, Core.Users.Constants.SysGroupCategoryId).Select(g => g.ID));
|
||||
|
||||
var groups = GetUserGroups(userId);
|
||||
var currentTenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId;
|
||||
var queryGetCalIds = new SqlQuery(_calendarItemTable)
|
||||
.Select("cal_itm.calendar_id")
|
||||
@ -191,8 +197,7 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
|
||||
public List<Calendar> LoadSubscriptionsForUser(Guid userId)
|
||||
{
|
||||
var groups = CoreContext.UserManager.GetUserGroups(userId).Select(g => g.ID).ToList();
|
||||
groups.AddRange(CoreContext.UserManager.GetUserGroups(userId, Core.Users.Constants.SysGroupCategoryId).Select(g => g.ID));
|
||||
var groups = GetUserGroups(userId);
|
||||
|
||||
var calIds = db.ExecuteList(new SqlQuery(_calendarItemTable).Select("cal_itm.calendar_id")
|
||||
.InnerJoin(_calendarTable, Exp.EqColumns("cal.id", "cal_itm.calendar_id"))
|
||||
@ -675,12 +680,7 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
{
|
||||
using (var tr = db.BeginTransaction())
|
||||
{
|
||||
var groups =
|
||||
CoreContext.UserManager.GetUserGroups(viewSettings.UserId).Select(g => g.ID).ToList();
|
||||
groups.AddRange(
|
||||
CoreContext.UserManager.GetUserGroups(viewSettings.UserId,
|
||||
Core.Users.Constants.SysGroupCategoryId)
|
||||
.Select(g => g.ID));
|
||||
var groups = GetUserGroups(viewSettings.UserId);
|
||||
|
||||
var q = new SqlQuery("calendar_events e")
|
||||
.Select(cc.SelectQuery)
|
||||
@ -949,8 +949,7 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
}
|
||||
internal List<Event> LoadSharedEvents(Guid userId, int tenantId, DateTime utcStartDate, DateTime utcEndDate)
|
||||
{
|
||||
var groups = CoreContext.UserManager.GetUserGroups(userId).Select(g => g.ID).ToList();
|
||||
groups.AddRange(CoreContext.UserManager.GetUserGroups(userId, Core.Users.Constants.SysGroupCategoryId).Select(g => g.ID));
|
||||
var groups = GetUserGroups(userId);
|
||||
|
||||
var evIds = db.ExecuteList(
|
||||
new SqlQuery(_eventTable).Select("evt.id")
|
||||
@ -1470,6 +1469,15 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
|
||||
}
|
||||
|
||||
public List<Guid> GetUserGroups(Guid userId)
|
||||
{
|
||||
var groups = CoreContext.UserManager.GetUserGroups(userId).Select(g => g.ID).ToList();
|
||||
|
||||
groups.AddRange(CoreContext.UserManager.GetUserGroups(userId, Core.Users.Constants.SysGroupCategoryId).Select(g => g.ID));
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
#region Event Notifications
|
||||
|
||||
internal static int GetBeforeMinutes(EventAlertType eventAlertType)
|
||||
@ -1792,9 +1800,9 @@ namespace ASC.Api.Calendar.BusinessObjects
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (HttpContext.Current == null && db != null)
|
||||
if (HttpContext.Current == null && _db != null)
|
||||
{
|
||||
db.Dispose();
|
||||
_db.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -494,10 +494,10 @@ namespace ASC.Api.Calendar
|
||||
if (int.TryParse(calendarId, out calId))
|
||||
{
|
||||
var cal = _dataProvider.GetCalendarById(calId);
|
||||
return (cal != null ? new CalendarWrapper(cal) : null);
|
||||
return CanRead(cal) ? new CalendarWrapper(cal) : null;
|
||||
}
|
||||
|
||||
//external
|
||||
//external
|
||||
var extCalendar = CalendarManager.Instance.GetCalendarForUser(SecurityContext.CurrentAccount.ID, calendarId);
|
||||
if (extCalendar != null)
|
||||
{
|
||||
@ -828,11 +828,13 @@ namespace ASC.Api.Calendar
|
||||
if (CheckUserEmail(owner))
|
||||
{
|
||||
await UpdateCalDavCalendar(name, description, backgroundColor, oldCal.calDavGuid, myUri, owner.Email);
|
||||
CoreContext.TenantManager.SetCurrentTenant(currentTenantId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await UpdateCalDavCalendar(name, description, backgroundColor, oldCal.calDavGuid, myUri, _email);
|
||||
CoreContext.TenantManager.SetCurrentTenant(currentTenantId);
|
||||
}
|
||||
var pic = PublicItemCollection.GetForCalendar(oldCal);
|
||||
if (pic.Items.Count > 1)
|
||||
@ -857,6 +859,7 @@ namespace ASC.Api.Calendar
|
||||
{
|
||||
await UpdateSharedCalDavCalendarAsync(dataProvider, name, description, backgroundColor, oldCal.calDavGuid, myUri, sharingOptionsList, events, calendarId, cal.calDavGuid, tenant.TenantId, DateTime.Now, targetCalendar.TimeZones[0], cal.TimeZone)
|
||||
.ConfigureAwait(false);
|
||||
CoreContext.TenantManager.SetCurrentTenant(currentTenantId);
|
||||
}
|
||||
|
||||
|
||||
@ -867,6 +870,7 @@ namespace ASC.Api.Calendar
|
||||
if (oldSharingList.Count > 0)
|
||||
{
|
||||
await ReplaceUpdateCalDavSharingEvent(oldSharingList, myUri, cal).ConfigureAwait(false);
|
||||
CoreContext.TenantManager.SetCurrentTenant(currentTenantId);
|
||||
}
|
||||
|
||||
return new CalendarWrapper(cal);
|
||||
@ -937,11 +941,14 @@ namespace ASC.Api.Calendar
|
||||
public async Task RemoveCalendar(int calendarId)
|
||||
{
|
||||
var cal = _dataProvider.GetCalendarById(calendarId);
|
||||
|
||||
//check permissions
|
||||
CheckPermissions(cal, CalendarAccessRights.FullAccessAction);
|
||||
|
||||
var events = cal.LoadEvents(SecurityContext.CurrentAccount.ID, DateTime.MinValue, DateTime.MaxValue);
|
||||
|
||||
var pic = PublicItemCollection.GetForCalendar(cal);
|
||||
//check permissions
|
||||
CheckPermissions(cal, CalendarAccessRights.FullAccessAction);
|
||||
|
||||
//clear old rights
|
||||
CoreContext.AuthorizationManager.RemoveAllAces(cal);
|
||||
var caldavGuid = _dataProvider.RemoveCalendar(calendarId);
|
||||
@ -954,7 +961,6 @@ namespace ASC.Api.Calendar
|
||||
var caldavHost = myUri.Host;
|
||||
if (caldavGuid != Guid.Empty)
|
||||
{
|
||||
Logger.Info("RADICALE REWRITE URL: " + myUri);
|
||||
|
||||
var currentUser = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID);
|
||||
var currentUserEmail = CheckUserEmail(currentUser) ? CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).Email : null;
|
||||
@ -1138,7 +1144,6 @@ namespace ASC.Api.Calendar
|
||||
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
|
||||
var caldavHost = myUri.Host;
|
||||
|
||||
Logger.Info("RADICALE REWRITE URL: " + myUri);
|
||||
|
||||
if (userEmail == null) return;
|
||||
|
||||
@ -1525,10 +1530,10 @@ namespace ASC.Api.Calendar
|
||||
|
||||
|
||||
|
||||
Logger.Info(String.Format("UpdateCalDavEvent eventURl: {0}", eventURl));
|
||||
Logger.Debug(String.Format("UpdateCalDavEvent eventURl: {0}", eventURl));
|
||||
|
||||
string ics = calDavCal.GetCollection(eventURl, authorization).Result.Data;
|
||||
Logger.Info(String.Format("UpdateCalDavEvent: {0}", ics));
|
||||
Logger.Debug(String.Format("UpdateCalDavEvent: {0}", ics));
|
||||
var existEvent = _dataProvider.GetEventIdByUid(eventGuid + "%", calendarId); // new function
|
||||
var existCalendar = _dataProvider.GetCalendarById(calendarId);
|
||||
|
||||
@ -1929,6 +1934,16 @@ namespace ASC.Api.Calendar
|
||||
[Read("{calendarId}/icalurl")]
|
||||
public string GetCalendariCalUrl(string calendarId)
|
||||
{
|
||||
int calId;
|
||||
if (int.TryParse(calendarId, out calId))
|
||||
{
|
||||
var cal = _dataProvider.GetCalendarById(calId);
|
||||
if (!CanRead(cal))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
var sig = Signature.Create(SecurityContext.CurrentAccount.ID, calendarId);
|
||||
var path = UrlPath.ResolveUrl(() => new CalendarApi().GetCalendariCalStream(calendarId, sig));
|
||||
return new Uri(_context.RequestContext.HttpContext.Request.GetUrlRewriter(), VirtualPathUtility.ToAbsolute("~/" + path)).ToString();
|
||||
@ -2127,7 +2142,6 @@ namespace ASC.Api.Calendar
|
||||
var calDavCalendar = new CalDavCalendar(calDavGuid.ToString(), isShared);
|
||||
var calUrl = calDavCalendar.GetRadicaleUrl(myUri.ToString(), userName, isShared, false, true, calDavGuid.ToString());
|
||||
|
||||
Logger.Info("RADICALE REWRITE URL: " + myUri);
|
||||
|
||||
var calDavResponse = calDavCalendar.GetCollection(calUrl, GetUserAuthorization(userName)).Result;
|
||||
|
||||
@ -2635,6 +2649,8 @@ namespace ASC.Api.Calendar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
var calendar = LoadInternalCalendars().First(x => (!x.IsSubscription && x.IsTodo != 1));
|
||||
@ -2677,12 +2693,12 @@ namespace ASC.Api.Calendar
|
||||
private async Task<int> ImportEvents(int calendarId, IEnumerable<Ical.Net.Calendar> cals, IEnumerable<HttpPostedFileBase> docs = null)
|
||||
{
|
||||
var counter = 0;
|
||||
var existCalendar = _dataProvider.GetCalendarById(calendarId);
|
||||
|
||||
CheckPermissions(_dataProvider.GetCalendarById(calendarId), CalendarAccessRights.FullAccessAction);
|
||||
CheckPermissions(existCalendar, CalendarAccessRights.FullAccessAction);
|
||||
|
||||
if (cals == null) return counter;
|
||||
|
||||
var existCalendar = _dataProvider.GetCalendarById(calendarId);
|
||||
var existCalendarViewSettings = existCalendar.ViewSettings == null ? null : existCalendar.ViewSettings.FirstOrDefault();
|
||||
var existCalendarTimeZone = existCalendarViewSettings == null ? existCalendar.TimeZone : existCalendarViewSettings.TimeZone;
|
||||
|
||||
@ -4260,7 +4276,6 @@ namespace ASC.Api.Calendar
|
||||
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
|
||||
var caldavHost = myUri.Host;
|
||||
|
||||
Logger.Info("RADICALE REWRITE URL: " + myUri);
|
||||
|
||||
var currentUserName = userSharingInfo.Email.ToLower() + "@" + caldavHost;
|
||||
|
||||
@ -4334,7 +4349,6 @@ namespace ASC.Api.Calendar
|
||||
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
|
||||
var caldavHost = myUri.Host;
|
||||
|
||||
Logger.Info("RADICALE REWRITE URL: " + myUri);
|
||||
|
||||
var currentUserName = user.Email.ToLower() + "@" + caldavHost;
|
||||
|
||||
@ -4344,6 +4358,7 @@ namespace ASC.Api.Calendar
|
||||
|
||||
try
|
||||
{
|
||||
updatedEvents.Add(guid);
|
||||
var calDavCalendar = new CalDavCalendar(calendarId, false);
|
||||
var authorization = calDavCalendar.GetSystemAuthorization();
|
||||
var davRequest = new DavRequest()
|
||||
@ -4351,7 +4366,7 @@ namespace ASC.Api.Calendar
|
||||
Url = requestDeleteUrl,
|
||||
Authorization = authorization
|
||||
};
|
||||
await RadicaleClient.RemoveAsync(davRequest).ConfigureAwait(false);
|
||||
RadicaleClient.Remove(davRequest);
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
@ -4412,7 +4427,6 @@ namespace ASC.Api.Calendar
|
||||
var calDavServerUrl = myUri.Scheme + "://" + myUri.Host + "/caldav";
|
||||
var caldavHost = myUri.Host;
|
||||
|
||||
Logger.Info("RADICALE REWRITE URL: " + myUri);
|
||||
|
||||
var currentUserName = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).Email.ToLower() + "@" + caldavHost;
|
||||
var _email = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).Email;
|
||||
@ -4811,10 +4825,6 @@ namespace ASC.Api.Calendar
|
||||
|
||||
if (caldavGuid != "")
|
||||
{
|
||||
|
||||
Logger.Info("RADICALE REWRITE URL: " + myUri);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
var calDavCalendar = new CalDavCalendar(calendarId, false);
|
||||
@ -4940,6 +4950,11 @@ namespace ASC.Api.Calendar
|
||||
|
||||
if (cal == null) return null;
|
||||
|
||||
if (!CanRead(cal, evt))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int evtId;
|
||||
EventHistory history = null;
|
||||
|
||||
@ -5105,6 +5120,21 @@ namespace ASC.Api.Calendar
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CanRead(BusinessObjects.Calendar cal, Event evt = null)
|
||||
{
|
||||
if (cal != null && (cal.OwnerId == SecurityContext.CurrentAccount.ID || cal.SharingOptions.PublicForItem(SecurityContext.CurrentAccount.ID)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (evt != null && evt.SharingOptions.PublicForItem(SecurityContext.CurrentAccount.ID))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sharing access parameters to the calendar with the ID specified in the request.
|
||||
/// </summary>
|
||||
@ -5121,6 +5151,11 @@ namespace ASC.Api.Calendar
|
||||
if (cal == null)
|
||||
throw new Exception(Resources.CalendarApiResource.ErrorItemNotFound);
|
||||
|
||||
if (!CanRead(cal))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return PublicItemCollection.GetForCalendar(cal);
|
||||
}
|
||||
|
||||
|
@ -92,13 +92,14 @@ namespace ASC.Api.Documents
|
||||
/// <short>Get sections</short>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="withsubfolders">Root folders with or without subfolders</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <param name="withoutTrash">Root folders with or without trash</param>
|
||||
/// <param name="withoutAdditionalFolder">Root folders with or without additional folders</param>
|
||||
/// <category>Folders</category>
|
||||
/// <returns>Sections</returns>
|
||||
[Read("@root")]
|
||||
public IEnumerable<FolderContentWrapper> GetRootFolders(Guid userIdOrGroupId, FilterType filterType, bool withsubfolders, bool withoutTrash, bool withoutAdditionalFolder)
|
||||
public IEnumerable<FolderContentWrapper> GetRootFolders(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders, bool withoutTrash, bool withoutAdditionalFolder)
|
||||
{
|
||||
var IsVisitor = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsVisitor();
|
||||
var IsOutsider = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsOutsider();
|
||||
@ -161,7 +162,7 @@ namespace ASC.Api.Documents
|
||||
result.Add((int)Global.FolderTrash);
|
||||
}
|
||||
|
||||
return result.Select(r => ToFolderContentWrapper(r, userIdOrGroupId, filterType));
|
||||
return result.Select(r => ToFolderContentWrapper(r, userIdOrGroupId, filterType, searchInContent, withSubfolders));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -171,11 +172,13 @@ namespace ASC.Api.Documents
|
||||
/// <category>Folders</category>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>My documents section contents</returns>
|
||||
[Read("@my")]
|
||||
public FolderContentWrapper GetMyFolder(Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetMyFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(Global.FolderMy, userIdOrGroupId, filterType);
|
||||
return ToFolderContentWrapper(Global.FolderMy, userIdOrGroupId, filterType, searchInContent, withSubfolders);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -185,11 +188,13 @@ namespace ASC.Api.Documents
|
||||
/// <category>Folders</category>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>Project section contents</returns>
|
||||
[Read("@projects")]
|
||||
public FolderContentWrapper GetProjectsFolder(Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetProjectsFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(Global.FolderProjects, userIdOrGroupId, filterType);
|
||||
return ToFolderContentWrapper(Global.FolderProjects, userIdOrGroupId, filterType, searchInContent, withSubfolders);
|
||||
}
|
||||
|
||||
|
||||
@ -200,11 +205,13 @@ namespace ASC.Api.Documents
|
||||
/// <category>Folders</category>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>Common section contents</returns>
|
||||
[Read("@common")]
|
||||
public FolderContentWrapper GetCommonFolder(Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetCommonFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(Global.FolderCommon, userIdOrGroupId, filterType);
|
||||
return ToFolderContentWrapper(Global.FolderCommon, userIdOrGroupId, filterType, searchInContent, withSubfolders);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -214,11 +221,13 @@ namespace ASC.Api.Documents
|
||||
/// <category>Folders</category>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>Shared section contents</returns>
|
||||
[Read("@share")]
|
||||
public FolderContentWrapper GetShareFolder(Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetShareFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(Global.FolderShare, userIdOrGroupId, filterType);
|
||||
return ToFolderContentWrapper(Global.FolderShare, userIdOrGroupId, filterType, searchInContent, withSubfolders);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -228,11 +237,13 @@ namespace ASC.Api.Documents
|
||||
/// <category>Folders</category>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>Recent section contents</returns>
|
||||
[Read("@recent")]
|
||||
public FolderContentWrapper GetRecentFolder(Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetRecentFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(Global.FolderRecent, userIdOrGroupId, filterType);
|
||||
return ToFolderContentWrapper(Global.FolderRecent, userIdOrGroupId, filterType, searchInContent, withSubfolders);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -242,11 +253,13 @@ namespace ASC.Api.Documents
|
||||
/// <category>Folders</category>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>Favorite section contents</returns>
|
||||
[Read("@favorites")]
|
||||
public FolderContentWrapper GetFavoritesFolder(Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetFavoritesFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(Global.FolderFavorites, userIdOrGroupId, filterType);
|
||||
return ToFolderContentWrapper(Global.FolderFavorites, userIdOrGroupId, filterType, searchInContent, withSubfolders);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -256,11 +269,13 @@ namespace ASC.Api.Documents
|
||||
/// <category>Folders</category>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>Template section contents</returns>
|
||||
[Read("@templates")]
|
||||
public FolderContentWrapper GetTemplatesFolder(Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetTemplatesFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(Global.FolderTemplates, userIdOrGroupId, filterType);
|
||||
return ToFolderContentWrapper(Global.FolderTemplates, userIdOrGroupId, filterType, searchInContent, withSubfolders);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -270,11 +285,13 @@ namespace ASC.Api.Documents
|
||||
/// <category>Folders</category>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>Trash section contents</returns>
|
||||
[Read("@trash")]
|
||||
public FolderContentWrapper GetTrashFolder(Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetTrashFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(Global.FolderTrash, userIdOrGroupId, filterType);
|
||||
return ToFolderContentWrapper(Global.FolderTrash, userIdOrGroupId, filterType, searchInContent, withSubfolders);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -287,11 +304,13 @@ namespace ASC.Api.Documents
|
||||
/// <param name="folderId">Folder ID</param>
|
||||
/// <param name="userIdOrGroupId" optional="true">User or group ID</param>
|
||||
/// <param name="filterType" optional="true">Filter type</param>
|
||||
/// <param name="searchInContent">Search in content files</param>
|
||||
/// <param name="withSubfolders">Root folders with or without subfolders</param>
|
||||
/// <returns>Folder contents</returns>
|
||||
[Read("{folderId}")]
|
||||
public FolderContentWrapper GetFolder(String folderId, Guid userIdOrGroupId, FilterType filterType)
|
||||
public FolderContentWrapper GetFolder(String folderId, Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
return ToFolderContentWrapper(folderId, userIdOrGroupId, filterType).NotFoundIfNull();
|
||||
return ToFolderContentWrapper(folderId, userIdOrGroupId, filterType, searchInContent, withSubfolders).NotFoundIfNull();
|
||||
|
||||
}
|
||||
|
||||
@ -549,6 +568,11 @@ namespace ASC.Api.Documents
|
||||
{
|
||||
Configuration configuration;
|
||||
var file = DocumentServiceHelper.GetParams(fileId, version, doc, true, true, true, out configuration);
|
||||
if (configuration.EditorConfig.ModeWrite && FileConverter.MustConvert(file))
|
||||
{
|
||||
file = DocumentServiceHelper.GetParams(file.ID, file.Version, doc, false, false, false, out configuration);
|
||||
}
|
||||
|
||||
configuration.Type = Configuration.EditorType.External;
|
||||
|
||||
if (file.RootFolderType == FolderType.Privacy
|
||||
@ -1877,7 +1901,7 @@ namespace ASC.Api.Documents
|
||||
}
|
||||
|
||||
|
||||
private FolderContentWrapper ToFolderContentWrapper(object folderId, Guid userIdOrGroupId, FilterType filterType)
|
||||
private FolderContentWrapper ToFolderContentWrapper(object folderId, Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders)
|
||||
{
|
||||
OrderBy orderBy = null;
|
||||
SortedByType sortBy;
|
||||
@ -1893,8 +1917,8 @@ namespace ASC.Api.Documents
|
||||
filterType == FilterType.ByUser,
|
||||
userIdOrGroupId.ToString(),
|
||||
_context.FilterValue,
|
||||
false,
|
||||
false,
|
||||
searchInContent,
|
||||
withSubfolders,
|
||||
orderBy),
|
||||
startIndex);
|
||||
}
|
||||
|
@ -34,6 +34,20 @@ namespace ASC.Api.Projects
|
||||
{
|
||||
#region milestone
|
||||
|
||||
///<summary>
|
||||
///Returns a list of the recent milestones within all the portal projects.
|
||||
///</summary>
|
||||
///<short>
|
||||
///Get recent milestones
|
||||
///</short>
|
||||
///<category>Milestones</category>
|
||||
///<returns>List of milestones</returns>
|
||||
[Read(@"milestone")]
|
||||
public IEnumerable<MilestoneWrapper> GetRecentMilestones()
|
||||
{
|
||||
return EngineFactory.MilestoneEngine.GetRecentMilestones((int)Count).Select(MilestoneWrapperSelector).ToList();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
///Returns a list of all the upcoming milestones within all the portal projects.
|
||||
///</summary>
|
||||
@ -42,8 +56,8 @@ namespace ASC.Api.Projects
|
||||
///</short>
|
||||
///<category>Milestones</category>
|
||||
///<returns>List of milestones</returns>
|
||||
[Read(@"milestone")]
|
||||
public IEnumerable<MilestoneWrapper> GetMilestones()
|
||||
[Read(@"milestone/upcoming")]
|
||||
public IEnumerable<MilestoneWrapper> GetUpcomingMilestones()
|
||||
{
|
||||
return EngineFactory.MilestoneEngine.GetUpcomingMilestones((int)Count).Select(MilestoneWrapperSelector).ToList();
|
||||
}
|
||||
|
@ -1166,7 +1166,7 @@ namespace ASC.Api.Projects
|
||||
var project = EngineFactory.ProjectEngine.GetByID(id).NotFoundIfNull();
|
||||
|
||||
if (ProjectSecurity.CanReadFiles(project))
|
||||
return documentsApi.GetFolder(EngineFactory.FileEngine.GetRoot(id).ToString(), Guid.Empty, FilterType.None);
|
||||
return documentsApi.GetFolder(EngineFactory.FileEngine.GetRoot(id).ToString(), Guid.Empty, FilterType.None, false, false);
|
||||
|
||||
throw new SecurityException("Access to files is denied");
|
||||
}
|
||||
|
@ -605,6 +605,7 @@ namespace ASC.Api.Projects
|
||||
TaskStatus? status,
|
||||
int? progress)
|
||||
{
|
||||
var projectEngine = EngineFactory.ProjectEngine;
|
||||
var taskEngine = EngineFactory.TaskEngine;
|
||||
var task = taskEngine.GetByID(taskid).NotFoundIfNull();
|
||||
|
||||
@ -617,6 +618,8 @@ namespace ASC.Api.Projects
|
||||
|
||||
var distinctResponsibles = new List<Guid>(responsibles.Distinct());
|
||||
|
||||
var acceptance = task.Responsibles.Count == 0 && distinctResponsibles.Count == 1 && distinctResponsibles.First() == CurrentUserId;
|
||||
|
||||
var hasChanges = !(task.Responsibles.Count == distinctResponsibles.Count && task.Responsibles.All(distinctResponsibles.Contains));
|
||||
|
||||
task.Responsibles = distinctResponsibles;
|
||||
@ -637,7 +640,7 @@ namespace ASC.Api.Projects
|
||||
{
|
||||
if (task.Project.ID != projectID.Value)
|
||||
{
|
||||
var project = EngineFactory.ProjectEngine.GetByID(projectID.Value).NotFoundIfNull();
|
||||
var project = projectEngine.GetByID(projectID.Value).NotFoundIfNull();
|
||||
task.Project = project;
|
||||
hasChanges = true;
|
||||
}
|
||||
@ -651,6 +654,14 @@ namespace ASC.Api.Projects
|
||||
if (hasChanges)
|
||||
{
|
||||
taskEngine.SaveOrUpdate(task, null, notify);
|
||||
|
||||
if (acceptance)
|
||||
{
|
||||
if (!projectEngine.IsInTeam(task.Project.ID, CurrentUserId))
|
||||
{
|
||||
projectEngine.AddToTeam(task.Project, CurrentUserId, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status.HasValue)
|
||||
@ -1024,6 +1035,7 @@ namespace ASC.Api.Projects
|
||||
var subtask = task.SubTasks.Find(r => r.ID == subtaskid).NotFoundIfNull();
|
||||
|
||||
var hasChanges = false;
|
||||
var acceptance = subtask.Responsible == Guid.Empty && responsible == CurrentUserId;
|
||||
|
||||
subtask.Responsible = Update.IfNotEquals(subtask.Responsible, responsible, ref hasChanges);
|
||||
subtask.Title = Update.IfNotEmptyAndNotEquals(subtask.Title, title, ref hasChanges);
|
||||
@ -1031,6 +1043,16 @@ namespace ASC.Api.Projects
|
||||
if (hasChanges)
|
||||
{
|
||||
EngineFactory.SubtaskEngine.SaveOrUpdate(subtask, task);
|
||||
|
||||
if (acceptance)
|
||||
{
|
||||
var projectEngine = EngineFactory.ProjectEngine;
|
||||
if (!projectEngine.IsInTeam(task.Project.ID, responsible))
|
||||
{
|
||||
projectEngine.AddToTeam(task.Project, responsible, false);
|
||||
}
|
||||
}
|
||||
|
||||
MessageService.Send(Request, MessageAction.SubtaskUpdated, MessageTarget.Create(subtask.ID), task.Project.Title, task.Title, subtask.Title);
|
||||
}
|
||||
|
||||
|
@ -1937,8 +1937,7 @@ namespace ASC.Api.Settings
|
||||
|
||||
private static void DemandWhiteLabelPermission()
|
||||
{
|
||||
if (!CoreContext.Configuration.Standalone
|
||||
&& (!TenantLogoManager.WhiteLabelEnabled || !TenantLogoManager.WhiteLabelPaid))
|
||||
if (!TenantLogoManager.WhiteLabelEnabled)
|
||||
{
|
||||
throw new BillingException(Resource.ErrorNotAllowedOption, "WhiteLabel");
|
||||
}
|
||||
@ -1948,11 +1947,6 @@ namespace ASC.Api.Settings
|
||||
{
|
||||
TenantExtra.DemandControlPanelPermission();
|
||||
|
||||
if (!CoreContext.Configuration.Standalone)
|
||||
{
|
||||
throw new BillingException(Resource.ErrorNotAllowedOption, "SSBranding");
|
||||
}
|
||||
|
||||
if (CoreContext.Configuration.CustomMode)
|
||||
{
|
||||
throw new SecurityException();
|
||||
|
@ -70,8 +70,6 @@ namespace ASC.Api.Settings
|
||||
if (smtpSettings == null)
|
||||
throw new ArgumentNullException("smtpSettings");
|
||||
|
||||
SecurityContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
|
||||
var settingConfig = ToSmtpSettingsConfig(smtpSettings);
|
||||
|
||||
CoreContext.Configuration.SmtpSettings = settingConfig;
|
||||
@ -96,7 +94,6 @@ namespace ASC.Api.Settings
|
||||
|
||||
if (!CoreContext.Configuration.SmtpSettings.IsDefaultSettings)
|
||||
{
|
||||
SecurityContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
CoreContext.Configuration.SmtpSettings = null;
|
||||
}
|
||||
|
||||
@ -226,6 +223,8 @@ namespace ASC.Api.Settings
|
||||
{
|
||||
throw new BillingException(Resource.ErrorNotAllowedOption, "Smtp");
|
||||
}
|
||||
|
||||
SecurityContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +136,6 @@ namespace ASC.Api.Employee
|
||||
Terminated = (ApiDateTime)userInfo.TerminatedDate;
|
||||
|
||||
WorkFrom = (ApiDateTime)userInfo.WorkFromDate;
|
||||
Email = userInfo.Email;
|
||||
|
||||
if (!string.IsNullOrEmpty(userInfo.Location))
|
||||
{
|
||||
@ -148,11 +147,6 @@ namespace ASC.Api.Employee
|
||||
Notes = userInfo.Notes;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(userInfo.MobilePhone))
|
||||
{
|
||||
MobilePhone = userInfo.MobilePhone;
|
||||
}
|
||||
|
||||
MobilePhoneActivationStatus = userInfo.MobilePhoneActivationStatus;
|
||||
|
||||
if (!string.IsNullOrEmpty(userInfo.CultureName))
|
||||
@ -160,7 +154,17 @@ namespace ASC.Api.Employee
|
||||
CultureName = userInfo.CultureName;
|
||||
}
|
||||
|
||||
FillConacts(userInfo);
|
||||
if (userInfo.CanViewPrivateData())
|
||||
{
|
||||
Email = userInfo.Email;
|
||||
|
||||
if (!string.IsNullOrEmpty(userInfo.MobilePhone))
|
||||
{
|
||||
MobilePhone = userInfo.MobilePhone;
|
||||
}
|
||||
|
||||
FillConacts(userInfo);
|
||||
}
|
||||
|
||||
if (CheckContext(context, "groups") || CheckContext(context, "department"))
|
||||
{
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace ASC.ElasticSearch.Core
|
||||
@ -24,7 +25,7 @@ namespace ASC.ElasticSearch.Core
|
||||
public class State
|
||||
{
|
||||
[DataMember]
|
||||
public string Indexing { get; set; }
|
||||
public List<string> Indexing { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public DateTime? LastIndexed { get; set; }
|
||||
|
@ -411,7 +411,7 @@ namespace ASC.ElasticSearch
|
||||
|
||||
async Task IIndexer.ReIndex()
|
||||
{
|
||||
while (Launcher.IsStarted && Launcher.Indexing == Wrapper.IndexName)
|
||||
while (Launcher.IsStarted && Launcher.Indexing.Contains(Wrapper.IndexName))
|
||||
{
|
||||
await Task.Delay(10000);
|
||||
}
|
||||
|
@ -178,23 +178,7 @@ namespace ASC.ElasticSearch
|
||||
|
||||
if (e.Response != null)
|
||||
{
|
||||
Logger.Error(e.Response.HttpStatusCode);
|
||||
|
||||
if (e.Response.HttpStatusCode == 413 || e.Response.HttpStatusCode == 403 || e.Response.HttpStatusCode == 408)
|
||||
{
|
||||
data.Where(r => r != null).ToList().ForEach(r => Index(r, immediately));
|
||||
}
|
||||
else if (e.Response.HttpStatusCode == 429)
|
||||
{
|
||||
Thread.Sleep(60000);
|
||||
if (retry < 10)
|
||||
{
|
||||
Index(data.Where(r => r != null).ToList(), immediately, retry++);
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
IndexRetry(e, data, immediately, retry);
|
||||
}
|
||||
}
|
||||
catch (AggregateException e) //ElasticsearchClientException
|
||||
@ -203,27 +187,9 @@ namespace ASC.ElasticSearch
|
||||
|
||||
var inner = e.InnerExceptions.OfType<ElasticsearchClientException>().FirstOrDefault();
|
||||
|
||||
|
||||
if (inner != null)
|
||||
{
|
||||
Logger.Error(inner);
|
||||
|
||||
if (inner.Response.HttpStatusCode == 413 || inner.Response.HttpStatusCode == 403)
|
||||
{
|
||||
Logger.Error(inner.Response.HttpStatusCode);
|
||||
data.Where(r => r != null).ToList().ForEach(r => Index(r, immediately));
|
||||
}
|
||||
else if (inner.Response.HttpStatusCode == 429)
|
||||
{
|
||||
Thread.Sleep(60000);
|
||||
if (retry < 10)
|
||||
{
|
||||
Index(data.Where(r => r != null).ToList(), immediately, retry++);
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
IndexRetry(inner, data, immediately, retry);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -232,6 +198,27 @@ namespace ASC.ElasticSearch
|
||||
}
|
||||
}
|
||||
|
||||
private static void IndexRetry(ElasticsearchClientException e, List<T> data, bool immediately = true, int retry = 0)
|
||||
{
|
||||
Logger.Error(e);
|
||||
|
||||
if (e.Response.HttpStatusCode == 413 || e.Response.HttpStatusCode == 403 || e.Response.HttpStatusCode == 408)
|
||||
{
|
||||
data.Where(r => r != null).ToList().ForEach(r => Index(r, immediately));
|
||||
}
|
||||
else if (e.Response.HttpStatusCode == 429)
|
||||
{
|
||||
Thread.Sleep(60000);
|
||||
if (retry < 10)
|
||||
{
|
||||
Index(data.Where(r => r != null).ToList(), immediately, retry++);
|
||||
return;
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task IndexAsync(List<T> data, bool immediately = true, int retry = 0)
|
||||
{
|
||||
if (!Support || !data.Any()) return;
|
||||
@ -246,23 +233,7 @@ namespace ASC.ElasticSearch
|
||||
|
||||
if (e.Response != null)
|
||||
{
|
||||
Logger.Error(e.Response.HttpStatusCode);
|
||||
|
||||
if (e.Response.HttpStatusCode == 413 || e.Response.HttpStatusCode == 403 || e.Response.HttpStatusCode == 408)
|
||||
{
|
||||
data.Where(r => r != null).ToList().ForEach(r => Index(r, immediately));
|
||||
}
|
||||
else if (e.Response.HttpStatusCode == 429)
|
||||
{
|
||||
await Task.Delay(60000);
|
||||
if (retry < 10)
|
||||
{
|
||||
await IndexAsync(data.Where(r => r != null).ToList(), immediately, retry++);
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
await IndexRetryAsync(e, data, immediately, retry);
|
||||
}
|
||||
}
|
||||
catch (AggregateException e) //ElasticsearchClientException
|
||||
@ -271,27 +242,9 @@ namespace ASC.ElasticSearch
|
||||
|
||||
var inner = e.InnerExceptions.OfType<ElasticsearchClientException>().FirstOrDefault();
|
||||
|
||||
|
||||
if (inner != null)
|
||||
{
|
||||
Logger.Error(inner);
|
||||
|
||||
if (inner.Response.HttpStatusCode == 413 || inner.Response.HttpStatusCode == 403)
|
||||
{
|
||||
Logger.Error(inner.Response.HttpStatusCode);
|
||||
data.Where(r => r != null).ToList().ForEach(r => Index(r, immediately));
|
||||
}
|
||||
else if (inner.Response.HttpStatusCode == 429)
|
||||
{
|
||||
await Task.Delay(60000);
|
||||
if (retry < 10)
|
||||
{
|
||||
await IndexAsync(data.Where(r => r != null).ToList(), immediately, retry++);
|
||||
return;
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
await IndexRetryAsync(inner, data, immediately, retry);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -300,6 +253,30 @@ namespace ASC.ElasticSearch
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task IndexRetryAsync(ElasticsearchClientException e, List<T> data, bool immediately = true, int retry = 0)
|
||||
{
|
||||
Logger.Error(e);
|
||||
|
||||
if (e.Response.HttpStatusCode == 413 || e.Response.HttpStatusCode == 403 || e.Response.HttpStatusCode == 408)
|
||||
{
|
||||
foreach (var r in data.Where(r => r != null))
|
||||
{
|
||||
await IndexAsync(r, immediately);
|
||||
}
|
||||
}
|
||||
else if (e.Response.HttpStatusCode == 429)
|
||||
{
|
||||
await Task.Delay(60000);
|
||||
if (retry < 10)
|
||||
{
|
||||
await IndexAsync(data.Where(r => r != null).ToList(), immediately, retry++);
|
||||
return;
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Update(T data, bool immediately = true, params Expression<Func<T, object>>[] fields)
|
||||
{
|
||||
if (!Support) return;
|
||||
|
@ -41,9 +41,14 @@ namespace ASC.ElasticSearch
|
||||
|
||||
internal static ServiceHost Searcher { get; private set; }
|
||||
internal static bool IsStarted { get; private set; }
|
||||
internal static string Indexing { get; private set; }
|
||||
internal static List<string> Indexing { get; private set; }
|
||||
internal static DateTime? LastIndexed { get; private set; }
|
||||
|
||||
static Launcher()
|
||||
{
|
||||
Indexing = new List<string>();
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Searcher = new ServiceHost(typeof(Service.Service));
|
||||
@ -101,8 +106,9 @@ namespace ASC.ElasticSearch
|
||||
if (!IsStarted) return;
|
||||
|
||||
logger.DebugFormat("Product check {0}", product.IndexName);
|
||||
Indexing = product.IndexName;
|
||||
Indexing.Add(product.IndexName);
|
||||
product.Check();
|
||||
Indexing.Remove(product.IndexName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -112,7 +118,7 @@ namespace ASC.ElasticSearch
|
||||
});
|
||||
|
||||
IsStarted = false;
|
||||
Indexing = null;
|
||||
Indexing.Clear();
|
||||
|
||||
timer = new Timer(_ => IndexAll(), null, TimeSpan.Zero, TimeSpan.Zero);
|
||||
}
|
||||
@ -155,8 +161,9 @@ namespace ASC.ElasticSearch
|
||||
if (!IsStarted) return;
|
||||
|
||||
logger.DebugFormat("Product {0}", product.IndexName);
|
||||
Indexing = product.IndexName;
|
||||
Indexing.Add(product.IndexName);
|
||||
product.IndexAll();
|
||||
Indexing.Remove(product.IndexName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -168,7 +175,7 @@ namespace ASC.ElasticSearch
|
||||
timer.Change(Period, Period);
|
||||
LastIndexed = DateTime.UtcNow;
|
||||
IsStarted = false;
|
||||
Indexing = null;
|
||||
Indexing.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -316,7 +316,7 @@ namespace ASC.Mail.Core.Engine
|
||||
|
||||
draft.ChangeSmileLinks(Log);
|
||||
|
||||
draft.ChangeAttachedFileLinksAddresses(Log);
|
||||
draft.ChangeAttachedFileLinksAddresses(Log, scheme);
|
||||
|
||||
draft.ChangeAttachedFileLinksImages(Log);
|
||||
|
||||
|
@ -355,7 +355,7 @@ namespace ASC.Mail.Extensions
|
||||
};
|
||||
}
|
||||
|
||||
public static void ChangeAttachedFileLinksAddresses(this MailDraftData draft, ILog log = null)
|
||||
public static void ChangeAttachedFileLinksAddresses(this MailDraftData draft, ILog log = null, string scheme = default(string))
|
||||
{
|
||||
if (log == null)
|
||||
log = new NullLog();
|
||||
@ -404,9 +404,10 @@ namespace ASC.Mail.Extensions
|
||||
var sharedInfo =
|
||||
fileStorageService.GetSharedInfo(new ItemList<string> { objectId })
|
||||
.Find(r => r.SubjectId == FileConstant.ShareLinkId);
|
||||
linkNode.SetAttributeValue("href", sharedInfo.Link);
|
||||
var link = CorrectUrlScheme(sharedInfo.Link, scheme, log);
|
||||
linkNode.SetAttributeValue("href", link);
|
||||
log.InfoFormat("ChangeAttachedFileLinks() Change file link href: {0}", fileId);
|
||||
setLinks.Add(new Tuple<string, string>(fileId, sharedInfo.Link));
|
||||
setLinks.Add(new Tuple<string, string>(fileId, link));
|
||||
}
|
||||
|
||||
linkNodes = doc.DocumentNode.SelectNodes("//div[contains(@class,'mailmessage-filelink')]");
|
||||
@ -662,5 +663,35 @@ namespace ASC.Mail.Extensions
|
||||
mailboxId = mailboxId
|
||||
};
|
||||
}
|
||||
|
||||
private static string CorrectUrlScheme(string url, string scheme, ILog log)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(scheme))
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
var uriBuilder = new UriBuilder(url);
|
||||
|
||||
if (uriBuilder.Scheme == scheme)
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
var hadDefaultPort = uriBuilder.Uri.IsDefaultPort;
|
||||
|
||||
uriBuilder.Scheme = scheme;
|
||||
uriBuilder.Port = hadDefaultPort ? -1 : uriBuilder.Port;
|
||||
|
||||
return uriBuilder.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Error(ex);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,8 +48,14 @@ namespace ASC.Migration.GoogleWorkspace.Models
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
if (ShouldIgnoreFile(entry, entries)) continue;
|
||||
|
||||
try
|
||||
{
|
||||
if (ShouldIgnoreFile(entry, entries)) continue;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"Metainformation file {entry} is invalid", ex);
|
||||
}
|
||||
filteredEntries.Add(entry);
|
||||
}
|
||||
|
||||
@ -349,7 +355,15 @@ namespace ASC.Migration.GoogleWorkspace.Models
|
||||
if (commentsVersionMatch.Success)
|
||||
{
|
||||
var baseName = entry.Substring(0, entry.Length - commentsVersionMatch.Groups[0].Value.Length);
|
||||
baseName = baseName.Insert(baseName.LastIndexOf("."), commentsVersionMatch.Groups[1].Value);
|
||||
var lastIndex = baseName.LastIndexOf(".");
|
||||
if (lastIndex < 0)
|
||||
{
|
||||
baseName = baseName + commentsVersionMatch.Groups[1].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseName = baseName.Insert(baseName.LastIndexOf("."), commentsVersionMatch.Groups[1].Value);
|
||||
}
|
||||
|
||||
if (entries.Contains(baseName)) return true;
|
||||
if (entries
|
||||
@ -362,7 +376,15 @@ namespace ASC.Migration.GoogleWorkspace.Models
|
||||
if (infoVersionMatch.Success)
|
||||
{
|
||||
var baseName = entry.Substring(0, entry.Length - infoVersionMatch.Groups[0].Length);
|
||||
baseName = baseName.Insert(baseName.LastIndexOf("."), infoVersionMatch.Groups[1].Value);
|
||||
var lastIndex = baseName.LastIndexOf(".");
|
||||
if (lastIndex < 0)
|
||||
{
|
||||
baseName = baseName + infoVersionMatch.Groups[1].Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
baseName = baseName.Insert(baseName.LastIndexOf("."), infoVersionMatch.Groups[1].Value);
|
||||
}
|
||||
|
||||
if (entries.Contains(baseName)) return true;
|
||||
if (entries
|
||||
|
@ -62,12 +62,16 @@ namespace ASC.Migration.NextcloudWorkspace.Models.Parse
|
||||
|
||||
if (!hasPhoto)
|
||||
{
|
||||
var appdataDir = Directory.GetDirectories(Path.Combine(rootFolder, "data")).Where(dir => dir.Split(Path.DirectorySeparatorChar).Last().StartsWith("appdata_")).First();
|
||||
if (appdataDir != null)
|
||||
var appdataDirs = Directory.GetDirectories(Path.Combine(rootFolder, "data")).Where(dir => dir.Split(Path.DirectorySeparatorChar).Last().StartsWith("appdata_"));
|
||||
if (appdataDirs.Any())
|
||||
{
|
||||
var pathToAvatarDir = Path.Combine(appdataDir, "avatar", Key);
|
||||
pathToPhoto = File.Exists(Path.Combine(pathToAvatarDir, "generated")) ? null : Path.Combine(pathToAvatarDir, "avatar.jpg");
|
||||
hasPhoto = pathToPhoto != null ? true : false;
|
||||
var appdataDir = appdataDirs.First();
|
||||
if (appdataDir != null)
|
||||
{
|
||||
var pathToAvatarDir = Path.Combine(appdataDir, "avatar", Key);
|
||||
pathToPhoto = File.Exists(Path.Combine(pathToAvatarDir, "generated")) ? null : Path.Combine(pathToAvatarDir, "avatar.jpg");
|
||||
hasPhoto = pathToPhoto != null ? true : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
string[] userName = User.Data.DisplayName.Split(' ');
|
||||
|
@ -141,6 +141,7 @@ namespace IpGeolocationConverter
|
||||
|
||||
var cells = line.Split(Separator);
|
||||
var newCells = new List<string>();
|
||||
var numericСolumns = new List<string>() { "Latitude", "Longitude", "Unique geoname ID", "Time Zone offset" };
|
||||
|
||||
for (var i = 0; i < ColumnNames.Count; i++)
|
||||
{
|
||||
@ -164,6 +165,11 @@ namespace IpGeolocationConverter
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(value) && numericСolumns.Contains(columnName))
|
||||
{
|
||||
value = "0";
|
||||
}
|
||||
|
||||
newCells.Add(value);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
using ASC.Web.Core;
|
||||
using ASC.Web.Core.Users;
|
||||
using ASC.Web.Studio.Utility;
|
||||
|
||||
@ -107,10 +108,22 @@ namespace ASC.Core.Users
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static bool CanViewPrivateData(this UserInfo userInfo)
|
||||
{
|
||||
if (SecurityContext.CurrentAccount.ID == userInfo.ID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var peopleModule = WebItemManager.Instance[WebItemManager.PeopleProductID];
|
||||
|
||||
return peopleModule != null && !peopleModule.IsDisabled();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// return absolute profile link
|
||||
/// </summary>
|
||||
/// <param name="userInfo"></param>
|
||||
/// <param name="userInfo"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetUserProfilePageURLGeneral(this UserInfo userInfo)
|
||||
{
|
||||
|
@ -37,6 +37,14 @@ namespace ASC.Web.Core.WhiteLabel
|
||||
}
|
||||
|
||||
public static bool WhiteLabelEnabled
|
||||
{
|
||||
get
|
||||
{
|
||||
return CoreContext.Configuration.Standalone || CoreContext.TenantManager.GetTenantQuota(TenantProvider.CurrentTenantID).WhiteLabel;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsVisibleWhiteLabelSettings
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
@ -46,7 +54,7 @@ namespace ASC.Web.Core.WhiteLabel
|
||||
static TenantLogoManager()
|
||||
{
|
||||
var hideSettings = (ConfigurationManagerExtension.AppSettings["web.hide-settings"] ?? "").Split(new[] { ',', ';', ' ' });
|
||||
WhiteLabelEnabled = !hideSettings.Contains("WhiteLabel", StringComparer.CurrentCultureIgnoreCase);
|
||||
IsVisibleWhiteLabelSettings = !hideSettings.Contains("WhiteLabel", StringComparer.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
|
||||
@ -90,6 +98,11 @@ namespace ASC.Web.Core.WhiteLabel
|
||||
return tenantWhiteLabelSettings.GetAbsoluteLogoPath(WhiteLabelLogoTypeEnum.Dark, general);
|
||||
}
|
||||
|
||||
if (IsVisibleWhiteLabelSettings)
|
||||
{
|
||||
return TenantWhiteLabelSettings.GetAbsoluteDefaultLogoPath(WhiteLabelLogoTypeEnum.Dark, general);
|
||||
}
|
||||
|
||||
/*** simple scheme ***/
|
||||
var tenantInfoSettings = TenantInfoSettings.Load();
|
||||
return tenantInfoSettings.GetAbsoluteCompanyLogoPath();
|
||||
@ -144,14 +157,6 @@ namespace ASC.Web.Core.WhiteLabel
|
||||
return !SecurityContext.IsAuthenticated;
|
||||
}
|
||||
|
||||
public static bool WhiteLabelPaid
|
||||
{
|
||||
get
|
||||
{
|
||||
return CoreContext.TenantManager.GetTenantQuota(TenantProvider.CurrentTenantID).WhiteLabel;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get logo stream or null in case of default logo
|
||||
/// </summary>
|
||||
@ -163,6 +168,11 @@ namespace ASC.Web.Core.WhiteLabel
|
||||
return tenantWhiteLabelSettings.GetWhitelabelLogoData(WhiteLabelLogoTypeEnum.Dark, true);
|
||||
}
|
||||
|
||||
if (IsVisibleWhiteLabelSettings)
|
||||
{
|
||||
return TenantWhiteLabelSettings.GetPartnerStorageLogoData(WhiteLabelLogoTypeEnum.Dark, true);
|
||||
}
|
||||
|
||||
/*** simple scheme ***/
|
||||
var tenantInfoSettings = TenantInfoSettings.Load();
|
||||
return tenantInfoSettings.GetStorageLogoData();
|
||||
|
@ -24,6 +24,7 @@ using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Core;
|
||||
using ASC.Core.Common.Settings;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Data.Storage;
|
||||
@ -467,7 +468,7 @@ namespace ASC.Web.Core.WhiteLabel
|
||||
return storage.IsFile(fileName) ? storage.GetReadStream(fileName) : null;
|
||||
}
|
||||
|
||||
private Stream GetPartnerStorageLogoData(WhiteLabelLogoTypeEnum type, bool general)
|
||||
public static Stream GetPartnerStorageLogoData(WhiteLabelLogoTypeEnum type, bool general)
|
||||
{
|
||||
var partnerSettings = LoadForDefaultTenant();
|
||||
|
||||
@ -595,11 +596,15 @@ namespace ASC.Web.Core.WhiteLabel
|
||||
|
||||
private void SetNewLogoText(int tenantId, bool restore = false)
|
||||
{
|
||||
WhiteLabelHelper.DefaultLogoText = DefaultLogoText;
|
||||
|
||||
var partnerSettings = LoadForDefaultTenant();
|
||||
|
||||
if (restore && String.IsNullOrEmpty(partnerSettings._logoText))
|
||||
var logoText = partnerSettings._logoText;
|
||||
|
||||
WhiteLabelHelper.DefaultLogoText = CoreContext.Configuration.CustomMode && !string.IsNullOrEmpty(logoText)
|
||||
? logoText
|
||||
: DefaultLogoText;
|
||||
|
||||
if (restore && string.IsNullOrEmpty(logoText))
|
||||
{
|
||||
WhiteLabelHelper.RestoreOldText(tenantId);
|
||||
}
|
||||
|
@ -247,12 +247,6 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
product = WebItemManager.Instance[(Guid)CallContext.GetData("asc.web.product_id")] as IProduct;
|
||||
}
|
||||
|
||||
var logoText = TenantWhiteLabelSettings.DefaultLogoText;
|
||||
if ((TenantExtra.Enterprise || CoreContext.Configuration.CustomMode) && !MailWhiteLabelSettings.Instance.IsDefault)
|
||||
{
|
||||
logoText = TenantLogoManager.GetLogoText();
|
||||
}
|
||||
|
||||
request.Arguments.Add(new TagValue(CommonTags.AuthorID, aid));
|
||||
request.Arguments.Add(new TagValue(CommonTags.AuthorName, aname));
|
||||
request.Arguments.Add(new TagValue(CommonTags.AuthorUrl, CommonLinkUtility.GetFullAbsolutePath(CommonLinkUtility.GetUserProfile(aid))));
|
||||
@ -265,7 +259,7 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
request.Arguments.Add(new TagValue(CommonTags.ProfileUrl, CommonLinkUtility.GetFullAbsolutePath(CommonLinkUtility.GetMyStaff())));
|
||||
request.Arguments.Add(new TagValue(CommonTags.RecipientSubscriptionConfigURL, CommonLinkUtility.GetMyStaff()));
|
||||
request.Arguments.Add(new TagValue(CommonTags.HelpLink, CommonLinkUtility.GetHelpLink(false)));
|
||||
request.Arguments.Add(new TagValue(CommonTags.LetterLogoText, logoText));
|
||||
request.Arguments.Add(new TagValue(CommonTags.LetterLogoText, TenantLogoManager.GetLogoText()));
|
||||
request.Arguments.Add(new TagValue(CommonTags.MailWhiteLabelSettings, MailWhiteLabelSettings.Instance));
|
||||
request.Arguments.Add(new TagValue(CommonTags.SendFrom, CoreContext.TenantManager.GetCurrentTenant().Name));
|
||||
request.Arguments.Add(new TagValue(CommonTags.ImagePath, StudioNotifyHelper.GetNotificationImageUrl("").TrimEnd('/')));
|
||||
|
@ -1082,12 +1082,51 @@ namespace ASC.Web.Studio.Core.Notify
|
||||
{
|
||||
var confirmUrl = CommonLinkUtility.GetConfirmationUrl(user.Email, ConfirmType.Activation);
|
||||
|
||||
if (HttpContext.Current == null)
|
||||
{
|
||||
confirmUrl = CorrectUrlScheme(confirmUrl);
|
||||
}
|
||||
|
||||
return confirmUrl + String.Format("&uid={0}&firstname={1}&lastname={2}",
|
||||
SecurityContext.CurrentAccount.ID,
|
||||
HttpUtility.UrlEncode(user.FirstName),
|
||||
HttpUtility.UrlEncode(user.LastName));
|
||||
}
|
||||
|
||||
private static string CorrectUrlScheme(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
var tenantId = CoreContext.TenantManager.GetCurrentTenant().TenantId;
|
||||
var cachedRewriteUrlStr = Common.Caching.AscCache.Default.Get<string>("REWRITE_URL" + tenantId);
|
||||
|
||||
if (string.IsNullOrEmpty(cachedRewriteUrlStr))
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
var cachedRewriteUriScheme = new Uri(cachedRewriteUrlStr).Scheme;
|
||||
var uriBuilder = new UriBuilder(url);
|
||||
|
||||
if (uriBuilder.Scheme == cachedRewriteUriScheme)
|
||||
{
|
||||
return url;
|
||||
}
|
||||
|
||||
var hadDefaultPort = uriBuilder.Uri.IsDefaultPort;
|
||||
|
||||
uriBuilder.Scheme = cachedRewriteUriScheme;
|
||||
uriBuilder.Port = hadDefaultPort ? -1 : uriBuilder.Port;
|
||||
|
||||
return uriBuilder.ToString();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogManager.GetLogger("ASC.Notify").Error(ex);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public void SendRegData(UserInfo u)
|
||||
|
@ -204,8 +204,7 @@ namespace ASC.Web.Studio.Core.Users
|
||||
|
||||
text.AppendFormat("{0} ", Resource.ErrorPasswordMessage);
|
||||
text.AppendFormat(Resource.ErrorPasswordLength, passwordSettings.MinLength, PasswordSettings.MaxLength);
|
||||
text.AppendFormat(", {0}", Resource.ErrorPasswordOnlyLatinLetters);
|
||||
text.AppendFormat(", {0}", Resource.ErrorPasswordNoSpaces);
|
||||
text.AppendFormat(", {0}", Resource.ErrorPasswordOnlyASCII);
|
||||
|
||||
if (passwordSettings.UpperCase)
|
||||
text.AppendFormat(", {0}", Resource.ErrorPasswordNoUpperCase);
|
||||
|
@ -128,6 +128,8 @@ namespace ASC.Web.Studio.Masters.MasterResources
|
||||
|
||||
private static object PrepareUserInfo(UserInfo userInfo)
|
||||
{
|
||||
var displayPrivate = userInfo.CanViewPrivateData();
|
||||
|
||||
return new
|
||||
{
|
||||
id = userInfo.ID,
|
||||
@ -143,9 +145,9 @@ namespace ASC.Web.Studio.Masters.MasterResources
|
||||
isOutsider = userInfo.IsOutsider(),
|
||||
isAdmin = userInfo.IsAdmin(),
|
||||
isOwner = userInfo.IsOwner(),
|
||||
contacts = GetContacts(userInfo),
|
||||
contacts = displayPrivate ? GetContacts(userInfo) : null,
|
||||
created = userInfo.CreateDate,
|
||||
email = userInfo.Email,
|
||||
email = displayPrivate ? userInfo.Email : string.Empty,
|
||||
isLDAP = userInfo.IsLDAP(),
|
||||
isSSO = userInfo.IsSSO(),
|
||||
isTerminated = userInfo.Status == EmployeeStatus.Terminated
|
||||
|
@ -49,6 +49,15 @@
|
||||
<div id="connectionsBlockContainer" class="user-block">
|
||||
<div class="tabs-section">
|
||||
<span class="header-base"><%= Resource.ActiveConnections %></span>
|
||||
<% if (IsEmptyDbip) { %>
|
||||
<span id="emptyDbipSwitcher"class="HelpCenterSwitcher expl"></span>
|
||||
<div id="emptyDbipHelper"class="popup_helper">
|
||||
<%= Resource.GeolocationNotAvailable %>
|
||||
<% if (!string.IsNullOrEmpty(HelpLink)) { %>
|
||||
<a href="<%= HelpLink + "/administration/active-connections.aspx" %>" target="_blank"><%= Resource.LearnMore %></a>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
<span id="switcherConnectionsButton" class="toggle-button"
|
||||
data-switcher="1" data-showtext="<%= Resource.Show %>" data-hidetext="<%= Resource.Hide %>">
|
||||
<%= Resource.Show %>
|
||||
|
@ -20,6 +20,7 @@ using System.Web;
|
||||
|
||||
using ASC.Core;
|
||||
using ASC.Core.Users;
|
||||
using ASC.Geolocation;
|
||||
using ASC.Web.Studio.Core.Users;
|
||||
using ASC.Web.Studio.PublicResources;
|
||||
using ASC.Web.Studio.UserControls.Users;
|
||||
@ -47,6 +48,10 @@ namespace ASC.Web.Studio
|
||||
|
||||
protected ProfileHelper Helper;
|
||||
|
||||
protected string HelpLink;
|
||||
|
||||
protected bool IsEmptyDbip;
|
||||
|
||||
protected override void OnPreInit(EventArgs e)
|
||||
{
|
||||
base.OnPreInit(e);
|
||||
@ -95,6 +100,10 @@ namespace ASC.Web.Studio
|
||||
{
|
||||
_phSubscriptionView.Controls.Add(LoadControl(UserSubscriptions.Location));
|
||||
}
|
||||
|
||||
HelpLink = CommonLinkUtility.GetHelpLink();
|
||||
IsEmptyDbip = CoreContext.Configuration.Standalone && !new GeolocationHelper("teamlabsite").HasData();
|
||||
|
||||
_phConnectionsView.Controls.Add(LoadControl(UserConnections.Location));
|
||||
}
|
||||
|
||||
|
@ -59,10 +59,10 @@ DealListView
|
||||
display: none;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
#dealList .showTotalAmount{
|
||||
#showTotalAmount{
|
||||
display: none;
|
||||
}
|
||||
#dealList .showTotalAmount, #dealList .showTotalAmount:hover, #dealList .showTotalAmount:active{
|
||||
#showTotalAmount, #showTotalAmount:hover, #showTotalAmount:active{
|
||||
color: @textColorBlackDark;
|
||||
}
|
||||
#showMoreDealsButtons{
|
||||
|
@ -207,7 +207,7 @@ namespace ASC.Web.CRM
|
||||
CRMInvoiceResource.CreateNewInvoiceItem :
|
||||
String.Format(CRMInvoiceResource.UpdateInvoiceItem, targetInvoiceItem.Title);
|
||||
|
||||
headerView.HeaderText = PageTitle;
|
||||
headerView.HeaderText = PageTitle.HtmlEncode();
|
||||
TitleContentHolder.Controls.Add(headerView);
|
||||
|
||||
var invoiceProductsViewControl = (InvoiceItemActionView)LoadControl(InvoiceItemActionView.Location);
|
||||
|
@ -44,7 +44,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<td style="text-align:right;">
|
||||
<a style="margin-right: 25px;" class="baseLinkAction showTotalAmount"
|
||||
<a id="showTotalAmount" class="baseLinkAction" style="margin-right: 25px;"
|
||||
onclick="ASC.CRM.ListDealView.showExchangeRatePopUp();" href="javascript:void(0)">
|
||||
${ASC.CRM.Resources.CRMDealResource.ShowTotalAmount}
|
||||
</a>
|
||||
@ -146,7 +146,7 @@
|
||||
${ASC.CRM.Resources.CRMJSResource.LoadingProcessing}
|
||||
</a>
|
||||
</div>
|
||||
<a style="float: right;margin-top: 20px;margin-right: 8px;" class="baseLinkAction showTotalAmount"
|
||||
<a id="showTotalAmount" class="baseLinkAction" style="float: right;margin-top: 20px;margin-right: 8px;"
|
||||
onclick="ASC.CRM.ListDealView.showExchangeRatePopUp();" href="javascript:void(0)">
|
||||
${ASC.CRM.Resources.CRMDealResource.ShowTotalAmount}
|
||||
</a>
|
||||
|
@ -336,9 +336,9 @@ ASC.CRM.ListDealView = (function() {
|
||||
_renderSimpleDealsPageNavigator();
|
||||
|
||||
if (ASC.CRM.ListDealView.bidList.length == 0) {
|
||||
jq("#dealList .showTotalAmount").hide();
|
||||
jq("#showTotalAmount").hide();
|
||||
} else {
|
||||
jq("#dealList .showTotalAmount").show();
|
||||
jq("#showTotalAmount").show();
|
||||
}
|
||||
|
||||
window.scrollTo(0, 0);
|
||||
@ -2696,9 +2696,9 @@ ASC.CRM.DealTabView = (function () {
|
||||
jq.tmpl("dealTmpl", ASC.CRM.DealTabView.dealList).prependTo("#dealTable tbody");
|
||||
|
||||
if (ASC.CRM.ListDealView.bidList.length == 0) {
|
||||
jq("#dealList .showTotalAmount").hide();
|
||||
jq("#showTotalAmount").hide();
|
||||
} else {
|
||||
jq("#dealList .showTotalAmount").show();
|
||||
jq("#showTotalAmount").show();
|
||||
}
|
||||
LoadingBanner.hideLoading();
|
||||
};
|
||||
@ -2712,9 +2712,9 @@ ASC.CRM.DealTabView = (function () {
|
||||
ASC.CRM.Common.RegisterContactInfoCard();
|
||||
|
||||
if (ASC.CRM.ListDealView.bidList.length == 0) {
|
||||
jq("#dealList .showTotalAmount").hide();
|
||||
jq("#showTotalAmount").hide();
|
||||
} else {
|
||||
jq("#dealList .showTotalAmount").show();
|
||||
jq("#showTotalAmount").show();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1384,8 +1384,7 @@ ASC.CRM.TaskActionView = new function() {
|
||||
}
|
||||
});
|
||||
|
||||
if (jq.browser.mobile)
|
||||
jq("#ui-datepicker-div").addClass("blockMsg");
|
||||
jq("#ui-datepicker-div").addClass("blockMsg");
|
||||
|
||||
_initTaskCategorySelector();
|
||||
|
||||
|
@ -1104,55 +1104,55 @@ body.mobile #contentVersions .version-comment-edit {
|
||||
body.media-width-1620-0 .file-row .entry-title,
|
||||
body.media-width-1620-0 .file-row .entry-descr { width: 952px; }
|
||||
body.media-width-1620-0 .file-row .entry-title .name { max-width: 768px; }
|
||||
body.media-width-1620-0 .file-row.folder-row .entry-title .name { max-width: 894px; }
|
||||
body.media-width-1620-0 .file-row.folder-row .entry-title .name { max-width: 870px; }
|
||||
body.media-width-1620-0 #filesMainContent.compact .file-row .entry-title { width: 854px; }
|
||||
body.media-width-1620-0 #filesMainContent.compact .file-row .entry-title .name { max-width: 670px; }
|
||||
body.media-width-1620-0 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 796px; }
|
||||
body.media-width-1620-0 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 772px; }
|
||||
|
||||
|
||||
body.media-width-0-1620 .file-row .entry-title,
|
||||
body.media-width-0-1620 .file-row .entry-descr { width: 752px; }
|
||||
body.media-width-0-1620 .file-row .entry-title .name { max-width: 568px; }
|
||||
body.media-width-0-1620 .file-row.folder-row .entry-title .name { max-width: 694px; }
|
||||
body.media-width-0-1620 .file-row.folder-row .entry-title .name { max-width: 670px; }
|
||||
body.media-width-0-1620 #filesMainContent.compact .file-row .entry-title { width: 654px; }
|
||||
body.media-width-0-1620 #filesMainContent.compact .file-row .entry-title .name { max-width: 470px; }
|
||||
body.media-width-0-1620 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 596px; }
|
||||
body.media-width-0-1620 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 572px; }
|
||||
|
||||
|
||||
body.media-width-0-1420 .file-row .entry-title,
|
||||
body.media-width-0-1420 .file-row .entry-descr { width: 600px; }
|
||||
body.media-width-0-1420 .file-row .entry-title .name { max-width: 416px; }
|
||||
body.media-width-0-1420 .file-row.folder-row .entry-title .name { max-width: 542px; }
|
||||
body.media-width-0-1420 .file-row.folder-row .entry-title .name { max-width: 518px; }
|
||||
body.media-width-0-1420 #filesMainContent.compact .file-row .entry-title { width: 494px; }
|
||||
body.media-width-0-1420 #filesMainContent.compact .file-row .entry-title .name { max-width: 310px; }
|
||||
body.media-width-0-1420 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 436px; }
|
||||
body.media-width-0-1420 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 412px; }
|
||||
|
||||
|
||||
body.media-width-0-1260 .file-row .entry-title,
|
||||
body.media-width-0-1260 .file-row .entry-descr { width: 540px; }
|
||||
body.media-width-0-1260 .file-row .entry-title .name { max-width: 356px; }
|
||||
body.media-width-0-1260 .file-row.folder-row .entry-title .name { max-width: 482px; }
|
||||
body.media-width-0-1260 .file-row.folder-row .entry-title .name { max-width: 458px; }
|
||||
body.media-width-0-1260 #filesMainContent.compact .file-row .entry-title { width: 434px; }
|
||||
body.media-width-0-1260 #filesMainContent.compact .file-row .entry-title .name { max-width: 250px; }
|
||||
body.media-width-0-1260 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 376px; }
|
||||
body.media-width-0-1260 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 352px; }
|
||||
|
||||
|
||||
body.media-width-0-1200 .file-row .entry-title,
|
||||
body.media-width-0-1200.file-row .entry-descr { width: 480px; }
|
||||
body.media-width-0-1200 .file-row .entry-title .name { max-width: 296px; }
|
||||
body.media-width-0-1200 .file-row.folder-row .entry-title .name { max-width: 422px; }
|
||||
body.media-width-0-1200 .file-row.folder-row .entry-title .name { max-width: 398px; }
|
||||
body.media-width-0-1200 #filesMainContent.compact .file-row .entry-title { width: 374px; }
|
||||
body.media-width-0-1200 #filesMainContent.compact .file-row .entry-title .name { max-width: 190px; }
|
||||
body.media-width-0-1200 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 316px; }
|
||||
body.media-width-0-1200 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 292px; }
|
||||
|
||||
|
||||
body.media-width-0-1140 .file-row .entry-title,
|
||||
body.media-width-0-1140 .file-row .entry-descr { width: 420px; }
|
||||
body.media-width-0-1140 .file-row .entry-title .name { max-width: 236px; }
|
||||
body.media-width-0-1140 .file-row.folder-row .entry-title .name { max-width: 362px; }
|
||||
body.media-width-0-1140 .file-row.folder-row .entry-title .name { max-width: 338px; }
|
||||
body.media-width-0-1140 #filesMainContent.compact .file-row .entry-title { width: 283px; }
|
||||
body.media-width-0-1140 #filesMainContent.compact .file-row .entry-title .name { max-width: 130px; }
|
||||
body.media-width-0-1140 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 256px; }
|
||||
body.media-width-0-1140 #filesMainContent.compact .file-row .entry-title .name { max-width: 82px; }
|
||||
body.media-width-0-1140 #filesMainContent.compact .file-row.folder-row .entry-title .name { max-width: 184px; }
|
||||
|
||||
|
||||
body[class*='media-width'] .file-row.row-rename .entry-title .name,
|
||||
|
@ -16,6 +16,8 @@
|
||||
<li>
|
||||
<a id="createPresentation" class="dropdown-item"><%= FilesUCResource.ButtonCreatePresentation %></a>
|
||||
</li>
|
||||
<% if (EnableCreateForm)
|
||||
{ %>
|
||||
<li>
|
||||
<a id="createMasterFormPointer" class="dropdown-item dropdown-with-item"><%= FilesUCResource.ButtonCreateFormTemplate %></a>
|
||||
<div id="createMasterFormPanel" class="studio-action-panel">
|
||||
@ -30,6 +32,7 @@
|
||||
</div>
|
||||
<asp:PlaceHolder ID="FileChoisePopupHolder" runat="server"></asp:PlaceHolder>
|
||||
</li>
|
||||
<% } %>
|
||||
<% if (FileUtility.ExtsWebTemplate.Any())
|
||||
{ %>
|
||||
<li>
|
||||
|
@ -18,6 +18,7 @@
|
||||
using System;
|
||||
using System.Web.UI;
|
||||
|
||||
using ASC.Core;
|
||||
using ASC.Web.Core.Files;
|
||||
using ASC.Web.Files.Classes;
|
||||
|
||||
@ -31,14 +32,19 @@ namespace ASC.Web.Files.Controls
|
||||
}
|
||||
|
||||
protected bool EnableCreateFile;
|
||||
protected bool EnableCreateForm;
|
||||
|
||||
public object FolderIDCurrentRoot { get; set; }
|
||||
|
||||
protected void Page_Load(object sender, EventArgs e)
|
||||
{
|
||||
EnableCreateFile = FileUtility.ExtsWebEdited.Count != 0;
|
||||
EnableCreateForm = !CoreContext.Configuration.CustomMode;
|
||||
|
||||
FileChoisePopupHolder.Controls.Add(LoadControl(FileChoisePopup.Location));
|
||||
if (EnableCreateForm)
|
||||
{
|
||||
FileChoisePopupHolder.Controls.Add(LoadControl(FileChoisePopup.Location));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -66,13 +66,15 @@ namespace ASC.Web.Files.Controls
|
||||
? string.Format(@"<div class=""empty-folder-create empty-folder-create-editor"">
|
||||
<a class=""link dotline plus empty-folder-create-document"">{0}</a>,
|
||||
<a class=""link dotline empty-folder-create-spreadsheet"">{1}</a>,
|
||||
<a class=""link dotline empty-folder-create-presentation"">{2}</a>,
|
||||
<a class=""link dotline empty-folder-create-masterform"">{3}</a>
|
||||
<a class=""link dotline empty-folder-create-presentation"">{2}</a>{3}
|
||||
</div>",
|
||||
FilesUCResource.ButtonCreateText,
|
||||
FilesUCResource.ButtonCreateSpreadsheet,
|
||||
FilesUCResource.ButtonCreatePresentation,
|
||||
FilesUCResource.ButtonCreateFormTemplate)
|
||||
CoreContext.Configuration.CustomMode
|
||||
? string.Empty
|
||||
: string.Format(@",{0}<a class=""link dotline empty-folder-create-masterform"">{1}</a>", Environment.NewLine, FilesUCResource.ButtonCreateFormTemplate)
|
||||
)
|
||||
: string.Empty;
|
||||
|
||||
var strCreateFolder =
|
||||
|
@ -113,7 +113,7 @@
|
||||
<% } %>
|
||||
<li id="filesOpen"><a class="dropdown-item with-icon preview first-section">
|
||||
<%= FilesUCResource.OpenFile %></a></li>
|
||||
<% if (!Global.IsOutsider)
|
||||
<% if (!Global.IsOutsider && !CoreContext.Configuration.CustomMode)
|
||||
{ %>
|
||||
<li id="filesCreateForm"><a class="dropdown-item with-icon create-form first-section">
|
||||
<%= FilesUCResource.ButtonMakeForm %></a></li>
|
||||
|
@ -21,7 +21,7 @@ window.ASC.Files.PrivateRoomOpenFile = (function () {
|
||||
console.log("custom protocol not detected");
|
||||
},
|
||||
function () {
|
||||
localStorage.setItem('protocoldetector', 1);
|
||||
sessionStorage.setItem('protocoldetector', 1);
|
||||
},
|
||||
function () {
|
||||
console.log("custom protocol detection is not supported");
|
||||
|
@ -80,7 +80,7 @@
|
||||
<input type="text" readonly="readonly" />
|
||||
</div>
|
||||
<div class="link-share-action-block">
|
||||
<% if (!Request.DesktopApp() && !CoreContext.Configuration.CustomMode)
|
||||
<% if (!Request.DesktopApp() || !CoreContext.Configuration.CustomMode)
|
||||
{ %>
|
||||
<div class="link-share-social">
|
||||
<span><%= FilesUCResource.ShareTo %>:</span>
|
||||
|
@ -178,11 +178,14 @@
|
||||
<input type="checkbox" value="<%= (int)FileShare.CustomFilter %>" <%= DefaultSharingAccessRightsSetting.Contains(FileShare.CustomFilter) ? "checked=\"checked\"" : string.Empty %> />
|
||||
<%= FilesJSResource.AceStatusEnum_CustomFilter %> <span class="gray-text">(<%= FilesUCResource.DefaultSharingAccessRightsSettingCustomFilterInfo %>)</span>
|
||||
</label>
|
||||
<% if (!CoreContext.Configuration.CustomMode)
|
||||
{ %>
|
||||
<br />
|
||||
<label>
|
||||
<input type="checkbox" value="<%= (int)FileShare.FillForms %>" <%= DefaultSharingAccessRightsSetting.Contains(FileShare.FillForms) ? "checked=\"checked\"" : string.Empty %> />
|
||||
<%= FilesJSResource.AceStatusEnum_FillForms %> <span class="gray-text">(<%= FilesUCResource.DefaultSharingAccessRightsSettingFillFormsInfo %>)</span>
|
||||
</label>
|
||||
<% } %>
|
||||
</div>
|
||||
|
||||
<% } %>
|
||||
|
@ -28,6 +28,7 @@ using System.Web;
|
||||
using ASC.Core;
|
||||
using ASC.Files.Core;
|
||||
using ASC.MessagingSystem;
|
||||
using ASC.Web.Core;
|
||||
using ASC.Web.Core.Client;
|
||||
using ASC.Web.Core.Files;
|
||||
using ASC.Web.Core.Mobile;
|
||||
@ -497,7 +498,7 @@ namespace ASC.Web.Files
|
||||
DefaultType = (IsMobile ? Services.DocumentService.Configuration.EditorType.Mobile : Services.DocumentService.Configuration.EditorType.Desktop).ToString().ToLower(),
|
||||
TabId = _tabId.ToString(),
|
||||
ThirdPartyApp = _thirdPartyApp,
|
||||
CanGetUsers = SecurityContext.IsAuthenticated && !CoreContext.Configuration.Personal,
|
||||
CanGetUsers = SecurityContext.IsAuthenticated && !CoreContext.Configuration.Personal && WebItemSecurity.IsAvailableForMe(WebItemManager.PeopleProductID),
|
||||
PageTitlePostfix = GetPageTitlePostfix()
|
||||
};
|
||||
|
||||
|
@ -879,7 +879,13 @@ namespace ASC.Web.Files.Services.DocumentService
|
||||
public string Logo
|
||||
{
|
||||
set { }
|
||||
get { return CommonLinkUtility.GetFullAbsolutePath(TenantWhiteLabelSettings.GetAbsoluteDefaultLogoPath(WhiteLabelLogoTypeEnum.Dark, !_configuration.EditorConfig.Customization.IsRetina)); }
|
||||
get
|
||||
{
|
||||
return
|
||||
CoreContext.Configuration.Standalone
|
||||
? CommonLinkUtility.GetFullAbsolutePath(TenantLogoManager.GetLogoDark(!_configuration.EditorConfig.Customization.IsRetina))
|
||||
: CommonLinkUtility.GetFullAbsolutePath(TenantWhiteLabelSettings.GetAbsoluteDefaultLogoPath(WhiteLabelLogoTypeEnum.Dark, !_configuration.EditorConfig.Customization.IsRetina));
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember(Name = "mail")]
|
||||
|
@ -250,7 +250,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return new ItemList<FileEntry>(entries);
|
||||
}
|
||||
|
||||
[ActionName("folders-create"), HttpGet]
|
||||
[ActionName("folders-create"), HttpPost]
|
||||
public Folder CreateNewFolder(String parentId, String title)
|
||||
{
|
||||
if (string.IsNullOrEmpty(title) || String.IsNullOrEmpty(parentId)) throw new ArgumentException();
|
||||
@ -276,7 +276,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("folders-rename"), HttpGet]
|
||||
[ActionName("folders-rename"), HttpPut]
|
||||
public Folder FolderRename(String folderId, String title)
|
||||
{
|
||||
using (var tagDao = GetTagDao())
|
||||
@ -423,7 +423,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("folders-files-createfile"), HttpGet]
|
||||
[ActionName("folders-files-createfile"), HttpPost]
|
||||
public File CreateNewFile(String parentId, String title, String templateId, bool enableExternalExt = false)
|
||||
{
|
||||
using (var fileDao = GetFileDao())
|
||||
@ -456,6 +456,9 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
|
||||
var fileExt = FileUtility.GetFileExtension(title);
|
||||
|
||||
ErrorIf(fileExt == FileUtility.MasterFormExtension && CoreContext.Configuration.CustomMode, FilesCommonResource.ErrorMassage_BadRequest);
|
||||
|
||||
if (!enableExternalExt && fileExt != FileUtility.MasterFormExtension)
|
||||
{
|
||||
fileExt = FileUtility.GetInternalExtension(title);
|
||||
@ -671,7 +674,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("startedit"), HttpGet, AllowAnonymous]
|
||||
[ActionName("startedit"), HttpPost, AllowAnonymous]
|
||||
public string StartEdit(String fileId, bool editingAlone = false, String doc = null)
|
||||
{
|
||||
try
|
||||
@ -728,7 +731,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("folders-files-rename"), HttpGet]
|
||||
[ActionName("folders-files-rename"), HttpPut]
|
||||
public File FileRename(String fileId, String title)
|
||||
{
|
||||
try
|
||||
@ -775,7 +778,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("folders-files-updateToVersion"), HttpGet]
|
||||
[ActionName("folders-files-updateToVersion"), HttpPut]
|
||||
public KeyValuePair<File, ItemList<File>> UpdateToVersion(String fileId, int version)
|
||||
{
|
||||
var file = EntryManager.UpdateToVersionFile(fileId, version);
|
||||
@ -794,7 +797,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return new KeyValuePair<File, ItemList<File>>(file, GetFileHistory(fileId));
|
||||
}
|
||||
|
||||
[ActionName("folders-files-updateComment"), HttpGet]
|
||||
[ActionName("folders-files-updateComment"), HttpPut]
|
||||
public string UpdateComment(String fileId, int version, String comment)
|
||||
{
|
||||
using (var fileDao = GetFileDao())
|
||||
@ -813,7 +816,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return comment;
|
||||
}
|
||||
|
||||
[ActionName("folders-files-completeVersion"), HttpGet]
|
||||
[ActionName("folders-files-completeVersion"), HttpPut]
|
||||
public KeyValuePair<File, ItemList<File>> CompleteVersion(String fileId, int version, bool continueVersion)
|
||||
{
|
||||
var file = EntryManager.CompleteVersionFile(fileId, version, continueVersion);
|
||||
@ -835,7 +838,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return new KeyValuePair<File, ItemList<File>>(file, GetFileHistory(fileId));
|
||||
}
|
||||
|
||||
[ActionName("folders-files-lock"), HttpGet]
|
||||
[ActionName("folders-files-lock"), HttpPut]
|
||||
public File LockFile(String fileId, bool lockfile)
|
||||
{
|
||||
using (var tagDao = GetTagDao())
|
||||
@ -1006,7 +1009,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("restore-version"), HttpGet, AllowAnonymous]
|
||||
[ActionName("restore-version"), HttpPut, AllowAnonymous]
|
||||
public ItemList<EditHistory> RestoreVersion(String fileId, int version, String url = null, String doc = null)
|
||||
{
|
||||
File file;
|
||||
@ -1181,7 +1184,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("markasread"), HttpPost]
|
||||
[ActionName("markasread"), HttpPut]
|
||||
public ItemList<FileOperationResult> MarkAsRead([FromBody] ItemList<String> items)
|
||||
{
|
||||
if (items.Count == 0) return GetTasksStatuses();
|
||||
@ -1320,7 +1323,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("thirdparty-delete"), HttpGet]
|
||||
[ActionName("thirdparty-delete"), HttpDelete]
|
||||
public object DeleteThirdParty(String providerId)
|
||||
{
|
||||
using (var providerDao = GetProviderDao())
|
||||
@ -1345,7 +1348,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("thirdparty"), HttpGet]
|
||||
[ActionName("thirdparty"), HttpPut]
|
||||
public bool ChangeAccessToThirdparty(bool enable)
|
||||
{
|
||||
ErrorIf(!Global.IsAdministrator, FilesCommonResource.ErrorMassage_SecurityException);
|
||||
@ -1370,7 +1373,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return true;
|
||||
}
|
||||
|
||||
[ActionName("docusign-delete"), HttpGet]
|
||||
[ActionName("docusign-delete"), HttpDelete]
|
||||
public object DeleteDocuSign()
|
||||
{
|
||||
DocuSignToken.DeleteToken();
|
||||
@ -1406,7 +1409,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return fileOperations.GetOperationResults();
|
||||
}
|
||||
|
||||
[ActionName("tasks"), HttpGet]
|
||||
[ActionName("tasks"), HttpPut]
|
||||
public ItemList<FileOperationResult> TerminateTasks()
|
||||
{
|
||||
ErrorIf(!SecurityContext.IsAuthenticated, FilesCommonResource.ErrorMassage_SecurityException);
|
||||
@ -1414,7 +1417,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return fileOperations.CancelOperations();
|
||||
}
|
||||
|
||||
[ActionName("bulkdownload"), HttpPost]
|
||||
[ActionName("bulkdownload"), HttpPut]
|
||||
public ItemList<FileOperationResult> BulkDownload([FromBody] Dictionary<String, String> items)
|
||||
{
|
||||
Dictionary<object, string> folders;
|
||||
@ -1495,7 +1498,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return result;
|
||||
}
|
||||
|
||||
[ActionName("moveorcopy"), HttpPost]
|
||||
[ActionName("moveorcopy"), HttpPut]
|
||||
public ItemList<FileOperationResult> MoveOrCopyItems([FromBody] ItemList<string> items, string destFolderId, FileConflictResolveType resolve, bool ic, bool deleteAfter = false)
|
||||
{
|
||||
ErrorIf(resolve == FileConflictResolveType.Overwrite && CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsVisitor(), FilesCommonResource.ErrorMassage_SecurityException);
|
||||
@ -1516,7 +1519,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return result;
|
||||
}
|
||||
|
||||
[ActionName("folders-files"), HttpPost]
|
||||
[ActionName("folders-files"), HttpPut]
|
||||
public ItemList<FileOperationResult> DeleteItems(string action, [FromBody] ItemList<String> items, bool ignoreException = false, bool deleteAfter = false, bool immediately = false)
|
||||
{
|
||||
List<object> foldersId;
|
||||
@ -1526,7 +1529,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return fileOperations.Delete(foldersId, filesId, ignoreException, !deleteAfter, immediately, GetHttpHeaders());
|
||||
}
|
||||
|
||||
[ActionName("emptytrash"), HttpGet]
|
||||
[ActionName("emptytrash"), HttpPut]
|
||||
public ItemList<FileOperationResult> EmptyTrash()
|
||||
{
|
||||
using (var folderDao = GetFolderDao())
|
||||
@ -1733,7 +1736,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
|
||||
#region Favorites Manager
|
||||
|
||||
[ActionName("file-favorite"), HttpGet]
|
||||
[ActionName("file-favorite"), HttpPut]
|
||||
public bool ToggleFileFavorite(String fileId, bool favorite)
|
||||
{
|
||||
if (favorite)
|
||||
@ -2108,7 +2111,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
}
|
||||
}
|
||||
|
||||
[ActionName("setacelink"), HttpGet]
|
||||
[ActionName("setacelink"), HttpPut]
|
||||
public bool SetAceLink(String fileId, FileShare share)
|
||||
{
|
||||
FileEntry file;
|
||||
@ -2295,7 +2298,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return new ItemList<EncryptionKeyPair>(fileKeyPair);
|
||||
}
|
||||
|
||||
[ActionName("external"), HttpGet]
|
||||
[ActionName("external"), HttpPut]
|
||||
public bool ChangeExternalShareSettings(bool enable)
|
||||
{
|
||||
ErrorIf(!Global.IsAdministrator, FilesCommonResource.ErrorMassage_SecurityException);
|
||||
@ -2312,7 +2315,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return FilesSettings.ExternalShare;
|
||||
}
|
||||
|
||||
[ActionName("externalsocialmedia"), HttpGet]
|
||||
[ActionName("externalsocialmedia"), HttpPut]
|
||||
public bool ChangeExternalShareSocialMediaSettings(bool enable)
|
||||
{
|
||||
ErrorIf(!Global.IsAdministrator, FilesCommonResource.ErrorMassage_SecurityException);
|
||||
@ -2480,7 +2483,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return true;
|
||||
}
|
||||
|
||||
[ActionName("updateifexist"), HttpGet]
|
||||
[ActionName("updateifexist"), HttpPut]
|
||||
public bool UpdateIfExist(bool set)
|
||||
{
|
||||
ErrorIf(CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsVisitor(), FilesCommonResource.ErrorMassage_SecurityException);
|
||||
@ -2491,7 +2494,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return FilesSettings.UpdateIfExist;
|
||||
}
|
||||
|
||||
[ActionName("forcesave"), HttpGet]
|
||||
[ActionName("forcesave"), HttpPut]
|
||||
public bool Forcesave(bool set)
|
||||
{
|
||||
FilesSettings.Forcesave = set;
|
||||
@ -2500,7 +2503,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return FilesSettings.Forcesave;
|
||||
}
|
||||
|
||||
[ActionName("storeforcesave"), HttpGet]
|
||||
[ActionName("storeforcesave"), HttpPut]
|
||||
public bool StoreForcesave(bool set)
|
||||
{
|
||||
ErrorIf(!Global.IsAdministrator, FilesCommonResource.ErrorMassage_SecurityException);
|
||||
@ -2538,7 +2541,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return FilesSettings.TemplatesSection;
|
||||
}
|
||||
|
||||
[ActionName("changedeleteconfrim"), HttpGet]
|
||||
[ActionName("changedeleteconfrim"), HttpPut]
|
||||
public bool ChangeDeleteConfrim(bool set)
|
||||
{
|
||||
FilesSettings.ConfirmDelete = set;
|
||||
@ -2566,7 +2569,7 @@ namespace ASC.Web.Files.Services.WCFService
|
||||
return FilesSettings.DefaultSharingAccessRights;
|
||||
}
|
||||
|
||||
[ActionName("downloadtargz"), HttpGet]
|
||||
[ActionName("downloadtargz"), HttpPut]
|
||||
public ICompress ChangeDownloadTarGz(bool set)
|
||||
{
|
||||
FilesSettings.DownloadTarGz = set;
|
||||
|
@ -104,6 +104,11 @@ namespace ASC.Web.Files.Utils
|
||||
|
||||
public static Stream Exec(File file, string toExtension)
|
||||
{
|
||||
if ((toExtension == FileUtility.MasterFormExtension || FileUtility.ExtsWebRestrictedEditing.Contains(toExtension)) && CoreContext.Configuration.CustomMode)
|
||||
{
|
||||
throw new Exception(FilesCommonResource.ErrorMassage_BadRequest);
|
||||
}
|
||||
|
||||
if (!EnableConvert(file, toExtension))
|
||||
{
|
||||
using (var fileDao = Global.DaoFactory.GetFileDao())
|
||||
|
@ -971,7 +971,7 @@ window.ASC.Files.Actions = (function () {
|
||||
if (winEditor && winEditor.location) {
|
||||
winEditor.location.href = urlForFileOpenWebEditor;
|
||||
} else {
|
||||
if (localStorage.getItem("protocoldetector") == 1) {
|
||||
if (sessionStorage.getItem("protocoldetector") == 1) {
|
||||
openCustomProtocolInIframe(customUrlForFileOpenDesktopEditor);
|
||||
} else {
|
||||
window.open(urlForOpenPrivate, "_blank");
|
||||
@ -1046,7 +1046,7 @@ window.ASC.Files.Actions = (function () {
|
||||
var entryData = ASC.Files.UI.getObjectData(fileObj);
|
||||
if (!ASC.Desktop && entryData && entryData.encrypted) {
|
||||
var viewerParameters = viewerUrl.slice(viewerUrl.indexOf("&"));
|
||||
if (localStorage.getItem("protocoldetector") == 1) {
|
||||
if (sessionStorage.getItem("protocoldetector") == 1) {
|
||||
var customProtocolViewerUrl = ASC.Files.Utility.GetFileCustomProtocolEditorUrl(fileId) + viewerParameters;
|
||||
openCustomProtocolInIframe(customProtocolViewerUrl);
|
||||
} else {
|
||||
|
@ -336,6 +336,7 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
}
|
||||
break;
|
||||
case "post":
|
||||
case "put":
|
||||
data = (contentType == "text/xml" || contentType == "application/xml"
|
||||
? ASC.Files.Common.jsonToXml(arguments[4])
|
||||
: (contentType == "application/json"
|
||||
@ -489,12 +490,12 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
|
||||
var createFolder = function (eventType, params) {
|
||||
params.ajaxsync = true;
|
||||
request("get", "xml", eventType, params, "folders-create?parentId=" + encodeURIComponent(params.parentFolderID) + "&title=" + encodeURIComponent(params.title));
|
||||
request("post", "xml", eventType, params, null, "folders-create?parentId=" + encodeURIComponent(params.parentFolderID) + "&title=" + encodeURIComponent(params.title));
|
||||
};
|
||||
|
||||
var createNewFile = function (eventType, params) {
|
||||
params.ajaxsync = true;
|
||||
request("get", "xml", eventType, params, "folders-files-createfile?parentId=" + encodeURIComponent(params.folderID || "") + "&title=" + encodeURIComponent(params.fileTitle) + "&templateId=" + encodeURIComponent(params.templateId || ""));
|
||||
request("post", "xml", eventType, params, null, "folders-files-createfile?parentId=" + encodeURIComponent(params.folderID || "") + "&title=" + encodeURIComponent(params.fileTitle) + "&templateId=" + encodeURIComponent(params.templateId || ""));
|
||||
};
|
||||
|
||||
var getFolderItems = function (eventType, params, data) {
|
||||
@ -528,15 +529,15 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var setCurrentVersion = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "folders-files-updateToVersion?fileId=" + encodeURIComponent(params.fileId) + "&version=" + params.version);
|
||||
request("put", "json", eventType, params, null, "folders-files-updateToVersion?fileId=" + encodeURIComponent(params.fileId) + "&version=" + params.version);
|
||||
};
|
||||
|
||||
var updateComment = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "folders-files-updateComment?fileId=" + encodeURIComponent(params.fileId) + "&version=" + params.version + "&comment=" + encodeURIComponent(params.comment));
|
||||
request("put", "json", eventType, params, null, "folders-files-updateComment?fileId=" + encodeURIComponent(params.fileId) + "&version=" + params.version + "&comment=" + encodeURIComponent(params.comment));
|
||||
};
|
||||
|
||||
var completeVersion = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "folders-files-completeversion?fileId=" + encodeURIComponent(params.fileId) + "&version=" + params.version + "&continueVersion=" + params.continueVersion);
|
||||
request("put", "json", eventType, params, null, "folders-files-completeversion?fileId=" + encodeURIComponent(params.fileId) + "&version=" + params.version + "&continueVersion=" + params.continueVersion);
|
||||
};
|
||||
|
||||
var getSiblingsImage = function (eventType, params, data) {
|
||||
@ -548,11 +549,11 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var renameFolder = function (eventType, params) {
|
||||
request("get", "xml", eventType, params, "folders-rename?folderId=" + encodeURIComponent(params.folderId) + "&title=" + encodeURIComponent(params.newname));
|
||||
request("put", "xml", eventType, params, null, "folders-rename?folderId=" + encodeURIComponent(params.folderId) + "&title=" + encodeURIComponent(params.newname));
|
||||
};
|
||||
|
||||
var renameFile = function (eventType, params) {
|
||||
request("get", "xml", eventType, params, "folders-files-rename?fileId=" + encodeURIComponent(params.fileId) + "&title=" + encodeURIComponent(params.newname));
|
||||
request("put", "xml", eventType, params, null, "folders-files-rename?fileId=" + encodeURIComponent(params.fileId) + "&title=" + encodeURIComponent(params.newname));
|
||||
};
|
||||
|
||||
var moveFilesCheck = function (eventType, params, data) {
|
||||
@ -560,21 +561,21 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var moveItems = function (eventType, params, data) {
|
||||
request("post", "json", eventType, params, data, "moveorcopy?destFolderId=" + encodeURIComponent(params.folderToId) + "&resolve=" + params.resolve + "&ic=" + (params.isCopyOperation == true));
|
||||
request("put", "json", eventType, params, data, "moveorcopy?destFolderId=" + encodeURIComponent(params.folderToId) + "&resolve=" + params.resolve + "&ic=" + (params.isCopyOperation == true));
|
||||
};
|
||||
|
||||
var deleteItem = function (eventType, params, data) {
|
||||
request("post", "json", eventType, params, data, "folders-files?action=delete");
|
||||
request("put", "json", eventType, params, data, "folders-files?action=delete");
|
||||
};
|
||||
|
||||
var emptyTrash = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "emptytrash");
|
||||
request("put", "json", eventType, params, null, "emptytrash");
|
||||
};
|
||||
|
||||
var download = function (eventType, params, data) {
|
||||
params.showLoading = true;
|
||||
params.ajaxcontentType = "application/json";
|
||||
request("post", "json", eventType, params, data, "bulkdownload");
|
||||
request("put", "json", eventType, params, data, "bulkdownload");
|
||||
};
|
||||
|
||||
var getTasksStatuses = function (eventType, params) {
|
||||
@ -582,7 +583,7 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var terminateTasks = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "tasks");
|
||||
request("put", "json", eventType, params, null, "tasks");
|
||||
};
|
||||
|
||||
var checkEditing = function (eventType, params, data) {
|
||||
@ -590,7 +591,7 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var setAceLink = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "setacelink?fileId=" + encodeURIComponent(params.fileId) + "&share=" + params.share);
|
||||
request("put", "json", eventType, params, null, "setacelink?fileId=" + encodeURIComponent(params.fileId) + "&share=" + params.share);
|
||||
};
|
||||
|
||||
var getSharedInfo = function (eventType, params, data) {
|
||||
@ -626,11 +627,11 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var changeExternalShareSettings = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "external?enable=" + (params.enable === true));
|
||||
request("put", "json", eventType, params, null, "external?enable=" + (params.enable === true));
|
||||
};
|
||||
|
||||
var changeExternalShareSocialMediaSettings = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "externalsocialmedia?enable=" + (params.enable === true));
|
||||
request("put", "json", eventType, params, null, "externalsocialmedia?enable=" + (params.enable === true));
|
||||
};
|
||||
|
||||
var checkConversion = function (eventType, params, data) {
|
||||
@ -638,19 +639,19 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var updateIfExist = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "updateifexist?set=" + params.value);
|
||||
request("put", "json", eventType, params, null, "updateifexist?set=" + params.value);
|
||||
};
|
||||
|
||||
var forcesave = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "forcesave?set=" + params.value);
|
||||
request("put", "json", eventType, params, null, "forcesave?set=" + params.value);
|
||||
};
|
||||
|
||||
var storeForcesave = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "storeforcesave?set=" + params.value);
|
||||
request("put", "json", eventType, params, null, "storeforcesave?set=" + params.value);
|
||||
};
|
||||
|
||||
var changeDeleteConfrim = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "changedeleteconfrim?set=" + params.value);
|
||||
request("put", "json", eventType, params, null, "changedeleteconfrim?set=" + params.value);
|
||||
};
|
||||
|
||||
var getThirdParty = function (eventType, params) {
|
||||
@ -664,11 +665,11 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var deleteThirdParty = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "thirdparty-delete?providerId=" + params.providerId);
|
||||
request("delete", "json", eventType, params, "thirdparty-delete?providerId=" + params.providerId);
|
||||
};
|
||||
|
||||
var changeAccessToThirdparty = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "thirdparty?enable=" + (params.enable === true));
|
||||
request("put", "json", eventType, params, null, "thirdparty?enable=" + (params.enable === true));
|
||||
};
|
||||
|
||||
var saveDocuSign = function (eventType, params, data) {
|
||||
@ -677,7 +678,7 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var deleteDocuSign = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "docusign-delete");
|
||||
request("delete", "json", eventType, params, "docusign-delete");
|
||||
};
|
||||
|
||||
var sendDocuSign = function (eventType, params, data) {
|
||||
@ -685,7 +686,7 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var markAsRead = function (eventType, params, data) {
|
||||
request("post", "json", eventType, params, data, "markasread");
|
||||
request("put", "json", eventType, params, data, "markasread");
|
||||
};
|
||||
|
||||
var getNews = function (eventType, params) {
|
||||
@ -698,11 +699,11 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var lockFile = function (eventType, params) {
|
||||
request("get", "xml", eventType, params, "folders-files-lock?fileId=" + encodeURIComponent(params.fileId) + "&lockfile=" + (params.lock === true));
|
||||
request("put", "xml", eventType, params, null, "folders-files-lock?fileId=" + encodeURIComponent(params.fileId) + "&lockfile=" + (params.lock === true));
|
||||
};
|
||||
|
||||
var toggleFavorite = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "file-favorite?fileId=" + encodeURIComponent(params.fileId) + "&favorite=" + (params.favorite === true));
|
||||
request("put", "json", eventType, params, null, "file-favorite?fileId=" + encodeURIComponent(params.fileId) + "&favorite=" + (params.favorite === true));
|
||||
};
|
||||
|
||||
var getEditHistory = function (eventType, params) {
|
||||
@ -714,7 +715,7 @@ window.ASC.Files.ServiceManager = (function () {
|
||||
};
|
||||
|
||||
var restoreVersion = function (eventType, params) {
|
||||
request("get", "json", eventType, params, "restore-version?fileId=" + encodeURIComponent(params.fileID) + "&version=" + params.version + "&url=" + encodeURIComponent(params.url) + params.shareLinkParam);
|
||||
request("put", "json", eventType, params, null, "restore-version?fileId=" + encodeURIComponent(params.fileID) + "&version=" + params.version + "&url=" + encodeURIComponent(params.url) + params.shareLinkParam);
|
||||
};
|
||||
|
||||
var getMailAccounts = function (eventType, params) {
|
||||
|
@ -50,6 +50,15 @@
|
||||
<div id="connectionsBlockContainer" class="user-block">
|
||||
<div class="tabs-section">
|
||||
<span class="header-base"><%= PeopleResource.LblActiveConnections %></span>
|
||||
<% if (IsEmptyDbip) { %>
|
||||
<span id="emptyDbipSwitcher"class="HelpCenterSwitcher expl"></span>
|
||||
<div id="emptyDbipHelper"class="popup_helper">
|
||||
<%= Resource.GeolocationNotAvailable %>
|
||||
<% if (!string.IsNullOrEmpty(HelpLink)) { %>
|
||||
<a href="<%= HelpLink + "/administration/active-connections.aspx" %>" target="_blank"><%= Resource.LearnMore %></a>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } %>
|
||||
<span id="switcherConnectionsButton" class="toggle-button"
|
||||
data-switcher="1" data-showtext="<%= Resource.Show %>" data-hidetext="<%= Resource.Hide %>">
|
||||
<%= Resource.Show %>
|
||||
|
@ -21,6 +21,7 @@ using System.Web;
|
||||
|
||||
using ASC.Core;
|
||||
using ASC.Core.Users;
|
||||
using ASC.Geolocation;
|
||||
using ASC.Web.Core;
|
||||
using ASC.Web.Studio;
|
||||
using ASC.Web.Studio.Core.Users;
|
||||
@ -34,6 +35,10 @@ namespace ASC.Web.People
|
||||
{
|
||||
public ProfileHelper ProfileHelper;
|
||||
|
||||
protected string HelpLink;
|
||||
|
||||
protected bool IsEmptyDbip;
|
||||
|
||||
protected bool IsAdmin()
|
||||
{
|
||||
return WebItemSecurity.IsProductAdministrator(WebItemManager.PeopleProductID, SecurityContext.CurrentAccount.ID);
|
||||
@ -69,6 +74,9 @@ namespace ASC.Web.People
|
||||
|
||||
private void InitConnectionsView()
|
||||
{
|
||||
HelpLink = CommonLinkUtility.GetHelpLink();
|
||||
IsEmptyDbip = CoreContext.Configuration.Standalone && !new GeolocationHelper("teamlabsite").HasData();
|
||||
|
||||
_phConnectionsView.Controls.Add(LoadControl(UserConnections.Location));
|
||||
}
|
||||
|
||||
|
@ -173,6 +173,21 @@ namespace ASC.Projects.Data.DAO
|
||||
.ConvertAll(converter);
|
||||
}
|
||||
|
||||
public List<Milestone> GetRecentMilestones(int offset, int max, params int[] projects)
|
||||
{
|
||||
var query = CreateQuery()
|
||||
.SetFirstResult(offset)
|
||||
.SetMaxResults(max)
|
||||
.OrderBy("t.create_on", false);
|
||||
|
||||
if (projects != null && 0 < projects.Length)
|
||||
{
|
||||
query.Where(Exp.In("p.id", projects));
|
||||
}
|
||||
|
||||
return Db.ExecuteList(query).ConvertAll(converter);
|
||||
}
|
||||
|
||||
public List<Milestone> GetUpcomingMilestones(int offset, int max, params int[] projects)
|
||||
{
|
||||
var query = CreateQuery()
|
||||
|
@ -119,6 +119,23 @@ namespace ASC.Projects.Engine
|
||||
return milestones;
|
||||
}
|
||||
|
||||
public List<Milestone> GetRecentMilestones(int max, params int[] projects)
|
||||
{
|
||||
var offset = 0;
|
||||
var milestones = new List<Milestone>();
|
||||
while (true)
|
||||
{
|
||||
var packet = DaoFactory.MilestoneDao.GetRecentMilestones(offset, 2 * max, projects);
|
||||
milestones.AddRange(packet.Where(CanRead));
|
||||
if (max <= milestones.Count || packet.Count() < 2 * max)
|
||||
{
|
||||
break;
|
||||
}
|
||||
offset += 2 * max;
|
||||
}
|
||||
return milestones.Count <= max ? milestones : milestones.GetRange(0, max);
|
||||
}
|
||||
|
||||
public List<Milestone> GetUpcomingMilestones(int max, params int[] projects)
|
||||
{
|
||||
var offset = 0;
|
||||
|
@ -35,6 +35,8 @@ namespace ASC.Projects.Core.DataInterfaces
|
||||
|
||||
List<Milestone> GetByStatus(int projectId, MilestoneStatus milestoneStatus);
|
||||
|
||||
List<Milestone> GetRecentMilestones(int offset, int max, params int[] projects);
|
||||
|
||||
List<Milestone> GetUpcomingMilestones(int offset, int max, params int[] projects);
|
||||
|
||||
List<Milestone> GetLateMilestones(int offset, int max);
|
||||
|
@ -1753,7 +1753,7 @@ namespace ASC.Web.Projects.Core.Model.Services.NotifyService {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Projects [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Task resumed: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID).
|
||||
/// Looks up a localized string similar to Projects [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Task resumed: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID).
|
||||
/// </summary>
|
||||
public static string subject_TaskResumed_tg {
|
||||
get {
|
||||
|
@ -920,7 +920,7 @@ ONLYOFFICE™ Komandası
|
||||
<value>Layihələr [$ProjectTitle]. Tapşırıq davam etdirildi: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Layihələr [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Tapşırıq davam etdirildi: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Layihələr [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Tapşırıq davam etdirildi: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Heç kim</value>
|
||||
|
@ -703,7 +703,7 @@ Projekt: "$ProjectTitle":"${__VirtualRootPath}/Products/Projects/Projects.aspx?p
|
||||
<value>Projekty [$ProjectTitle]. Obnoven úkol: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Projekty [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Obnoven úkol: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Projekty [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Obnoven úkol: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Nikdo</value>
|
||||
|
@ -749,7 +749,7 @@ $AdditionalData
|
||||
<value>Projekt [$ProjectTitle]. Aufgabe fortgesetzt: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Projekt [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Aufgabe fortgesetzt: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Projekt [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Aufgabe fortgesetzt: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Keine zuständige Person</value>
|
||||
|
@ -752,7 +752,7 @@ $AdditionalData
|
||||
<value>Proyectos [$ProjectTitle]. Tarea reanudada: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Proyectos [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Tarea reanudada: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Proyectos [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Tarea reanudada: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Sin responsable</value>
|
||||
|
@ -757,7 +757,7 @@ $AdditionalData
|
||||
<value>Projets [$ProjectTitle]. Tâche reprise: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Projets [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Tâche reprise : [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Projets [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Tâche reprise : [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Sans responsable</value>
|
||||
|
@ -749,7 +749,7 @@ $AdditionalData
|
||||
<value>Progetti [$ProjectTitle]. Attività ripresa: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Progetti [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Ripresa dell'attività: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Progetti [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Ripresa dell'attività: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Nessun responsabile</value>
|
||||
|
@ -760,7 +760,7 @@ $AdditionalData
|
||||
<value>プロジェクト [$ProjectTitle]. タスクが再開: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>プロジェクト [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). タスクが再開されました: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>プロジェクト [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). タスクが再開されました: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>誰もない</value>
|
||||
|
@ -754,7 +754,7 @@ $AdditionalData
|
||||
<value>Projetos [$ProjectTitle]. Tarefa retomada: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Projetos [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Tarefa retomada: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Projetos [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Tarefa retomada: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Ninguém</value>
|
||||
|
@ -750,7 +750,7 @@ $AdditionalData
|
||||
<value>Projects [$ProjectTitle]. Task resumed: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Projects [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Task resumed: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Projects [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Task resumed: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Nobody</value>
|
||||
|
@ -750,7 +750,7 @@ $AdditionalData
|
||||
<value>Проекты [$ProjectTitle]. Возобновлена задача: $EntityTitle</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>Проекты [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Возобновлена задача: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>Проекты [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID). Возобновлена задача: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>Без ответственного</value>
|
||||
|
@ -786,7 +786,7 @@ $AdditionalData
|
||||
<value>項目[$ ProjectTitle].任務</value>
|
||||
</data>
|
||||
<data name="subject_TaskResumed_tg" xml:space="preserve">
|
||||
<value>專案 [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID).任務恢復: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID)</value>
|
||||
<value>專案 [$ProjectTitle](${__VirtualRootPath}/products/projects/projects.aspx?prjID=$ProjectID).任務恢復: [$EntityTitle](${__VirtualRootPath}/products/projects/tasks.aspx?prjID=$ProjectID&ID=$EntityID)</value>
|
||||
</data>
|
||||
<data name="subtaskWithoutResponsible" xml:space="preserve">
|
||||
<value>沒人</value>
|
||||
|
@ -509,7 +509,7 @@ $AdditionalData
|
||||
<body styler="ASC.Notify.Textile.JabberStyler,ASC.Notify.Textile">
|
||||
$__AuthorName
|
||||
|
||||
${__VirtualRootPath}/Products/Projects/Tasks.aspx?prjID=$ProjectID
|
||||
${__VirtualRootPath}/Products/Projects/Tasks.aspx?prjID=$ProjectID&ID=$EntityID
|
||||
</body>
|
||||
</pattern>
|
||||
<pattern id="TaskResumed" sender="telegram.sender">
|
||||
|
@ -296,7 +296,7 @@
|
||||
<div id="statusListTaskContainer" class="studio-action-panel gantt-context-menu">
|
||||
<ul id="statusListTask" class="dropdown-content">
|
||||
<% foreach(var s in Statuses) { %>
|
||||
<li data-id="<%= s.Id %>" class="<%= s.Id %> dropdown-item" style="background: url('data:<%= s.ImageType %>;base64,<%= s.Image %>') no-repeat 2px 4px"><%= s.Title %></li>
|
||||
<li data-id="<%= s.Id %>" class="<%= s.Id %> dropdown-item" style="background: url('data:<%= s.ImageType %>;base64,<%= s.Image %>') no-repeat 2px 4px"><%: s.Title %></li>
|
||||
<%} %>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -193,7 +193,7 @@ namespace ASC.Web.Projects.Masters.ClientScripts
|
||||
{
|
||||
id = r.UserInfo.ID,
|
||||
displayName = DisplayUserSettings.GetFullUserName(r.UserInfo.ID),
|
||||
email = r.UserInfo.Email,
|
||||
email = r.UserInfo.CanViewPrivateData() ? r.UserInfo.Email : string.Empty,
|
||||
userName = r.UserInfo.UserName,
|
||||
avatarSmall = UserPhotoManager.GetSmallPhotoURL(r.UserInfo.ID),
|
||||
avatar = UserPhotoManager.GetBigPhotoURL(r.UserInfo.ID),
|
||||
|
@ -87,6 +87,15 @@ namespace ASC.Web.Projects.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to All unsaved data will be lost. Continue?.
|
||||
/// </summary>
|
||||
public static string ConfirmContinueMessage {
|
||||
get {
|
||||
return ResourceManager.GetString("ConfirmContinueMessage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Contacts.
|
||||
/// </summary>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user