From 678eedf95f75449a1060432b50a5fa7da9cd1e0e Mon Sep 17 00:00:00 2001 From: JenkinsRobo Date: Thu, 29 Feb 2024 12:12:53 +0000 Subject: [PATCH] Update to v12.6.0 --- CHANGELOG.md | 150 +++ build/WinSW3.0.0.exe | Bin 0 -> 667648 bytes build/install/deb/debian/compat | 2 +- .../deb/debian/onlyofficeSocketIO.service | 1 + .../deb/debian/onlyofficeSsoAuth.service | 1 + .../deb/debian/onlyofficeThumb.service | 1 + .../deb/debian/onlyofficeUrlShortener.service | 1 + .../deb/debian/onlyofficeWebDav.service | 1 + build/install/deb/debian/postinst | 94 +- build/install/deb/debian/rules | 99 +- build/install/install.bat | 12 + build/install/rpm/common.spec | 58 +- .../rpm/onlyoffice-communityserver.spec | 2 +- build/install/uninstall.bat | 13 + build/msbuild/ASC.Web.Core.BuildTask.dll | Bin 27648 -> 27648 bytes build/msbuild/deploy.proj | 76 +- build/run/Radicale.xml | 11 + build/run/SocketIO.xml | 10 + build/run/SsoAuth.xml | 10 + build/run/Thumb.xml | 10 + build/run/UrlShortener.xml | 10 + build/run/WebDav.xml | 10 + build/sql/onlyoffice.data.sql | 1 - build/sql/onlyoffice.upgradev126.sql | 14 + build/start/command.ps1 | 48 + build/start/start.bat | 15 + build/start/stop.bat | 15 + .../ASC.Common/Data/MultiRegionalDbManager.cs | 17 +- common/ASC.Common/Web/MimeMapping.cs | 11 +- .../ASC.Core.Common/Billing/ITariffService.cs | 2 + .../ASC.Core.Common/Billing/TariffService.cs | 136 +- .../Caching/CachedTenantService.cs | 7 + .../Context/Impl/TenantManager.cs | 33 +- common/ASC.Core.Common/Core/ITenantService.cs | 2 + common/ASC.Core.Common/Data/DbBaseService.cs | 3 + .../Data/DbLoginEventsManager.cs | 25 + common/ASC.Core.Common/Data/DbQuotaService.cs | 42 +- .../ASC.Core.Common/Data/DbTenantService.cs | 48 +- common/ASC.Core.Common/Data/DbUserService.cs | 38 +- common/ASC.Core.Common/HostedSolution.cs | 16 +- .../MultiRegionHostedSolution.cs | 45 +- .../Notify/Senders/SmtpSender.cs | 17 +- common/ASC.Core.Common/Tenants/TenantUtil.cs | 3 +- common/ASC.Data.Backup/ASC.Data.Backup.csproj | 6 + .../Service/BackupConfiguration.cs | 55 +- .../Service/BackupMailServerFilesService.cs | 319 +++++ .../ASC.Data.Backup/Service/BackupService.cs | 4 + .../ASC.Data.Backup/Service/BackupWorker.cs | 7 +- .../Storage/BackupStorageFactory.cs | 31 + .../ASC.Data.Backup/Tasks/BackupPortalTask.cs | 205 ++- common/ASC.Data.Backup/Tasks/DbFactory.cs | 6 +- common/ASC.Data.Backup/Tasks/KeyHelper.cs | 5 + .../Tasks/Modules/MailModuleSpecifics.cs | 80 +- .../Tasks/Modules/MailTableSpecifics.cs | 115 ++ .../Tasks/RestoreMailTableTask.cs | 166 +++ .../Tasks/RestorePortalTask.cs | 67 +- common/ASC.Data.Storage/BaseStorage.cs | 7 + .../CommonChunkedUploadSessionHolder.cs | 10 +- .../ModuleConfigurationElement.cs | 7 + .../ASC.Data.Storage/Configuration/Schema.cs | 1 + .../DiscStorage/DiscDataStore.cs | 7 +- .../GoogleCloud/GoogleCloudStorage.cs | 16 +- common/ASC.Data.Storage/IDataStore.cs | 14 + .../RackspaceCloud/RackspaceCloudStorage.cs | 10 +- common/ASC.Data.Storage/S3/S3Storage.cs | 25 +- .../Selectel/SelectelStorage.cs | 10 +- common/ASC.Data.Storage/StorageHandler.cs | 10 +- .../NotifyTemplateResource.Designer.cs | 6 +- .../NotifyTemplateResource.az-Latn-AZ.resx | 2 +- .../Resources/NotifyTemplateResource.bg.resx | 2 +- .../Resources/NotifyTemplateResource.cs.resx | 2 +- .../Resources/NotifyTemplateResource.de.resx | 2 +- .../Resources/NotifyTemplateResource.es.resx | 2 +- .../Resources/NotifyTemplateResource.fr.resx | 2 +- .../Resources/NotifyTemplateResource.it.resx | 2 +- .../Resources/NotifyTemplateResource.lv.resx | 2 +- .../Resources/NotifyTemplateResource.nl.resx | 2 +- .../Resources/NotifyTemplateResource.pl.resx | 2 +- .../NotifyTemplateResource.pt-BR.resx | 2 +- .../Resources/NotifyTemplateResource.resx | 2 +- .../Resources/NotifyTemplateResource.ru.resx | 2 +- .../Resources/NotifyTemplateResource.sk.resx | 2 +- .../Resources/NotifyTemplateResource.tr.resx | 2 +- .../Resources/NotifyTemplateResource.uk.resx | 2 +- .../Resources/NotifyTemplateResource.vi.resx | 2 +- .../NotifyTemplateResource.zh-CN.resx | 2 +- .../NotifyTemplateResource.zh-TW.resx | 2 +- module/ASC.Api/ASC.Api.CRM/ASC.Api.CRM.csproj | 4 - module/ASC.Api/ASC.Api.CRM/CRMApi.Contacts.cs | 195 +-- .../ASC.Api.Calendar/ASC.Api.Calendar.csproj | 5 +- .../iCalParser/DDayICalParser.cs | 4 +- .../ASC.Api.Community/Events/EventApi.cs | 7 +- .../ASC.Api/ASC.Api.Documents/DocumentsApi.cs | 64 +- .../ASC.Api/ASC.Api.Mail/ASC.Api.Mail.csproj | 2 +- .../ASC.Api/ASC.Api.Migration/MigrationApi.cs | 10 +- .../ASC.Api.Projects/ProjectApi.Projects.cs | 4 +- .../ASC.Api/ASC.Api.Security/SecurityApi.cs | 18 +- .../ASC.Api/ASC.Api.Settings/SettingsApi.cs | 5 +- module/ASC.Api/ASC.Employee/EmployeeApi.cs | 2 + .../ASC.Api/ASC.Specific/ASC.Specific.csproj | 5 - .../ASC.AuditTrail/AuditEventsRepository.cs | 21 +- .../ASC.ElasticSearch/Engine/BaseIndexer.cs | 2 +- module/ASC.ElasticSearch/Service/Launcher.cs | 13 +- module/ASC.ElasticSearch/Service/Service.cs | 2 +- module/ASC.Files.AutoCleanUp/Worker.cs | 2 +- module/ASC.Files.Thirdparty/Box/BoxFileDao.cs | 20 +- .../Dropbox/DropboxFileDao.cs | 20 +- .../GoogleDrive/GoogleDriveFileDao.cs | 20 +- .../OneDrive/OneDriveFileDao.cs | 20 +- .../ProviderDao/ProviderDaoBase.cs | 2 +- .../ProviderDao/ProviderFileDao.cs | 12 +- .../SharePoint/SharePointFileDao.cs | 20 +- .../Sharpbox/SharpBoxFileDao.cs | 20 +- module/ASC.Files.ThumbnailBuilder/Builder.cs | 3 +- .../ConfigSection.cs | 2 +- module/ASC.Mail/ASC.Mail/ASC.Mail.csproj | 5 +- module/ASC.Mail/ASC.Mail/Utils/MailUtil.cs | 2 +- ...C.Mail.Aggregator.CollectionService.csproj | 147 --- .../AggregatorService.cs | 1119 ----------------- .../App.config | 111 -- .../HealthCheckService.cs | 37 - .../Program.Options.cs | 38 - .../Program.cs | 62 - .../Properties/AssemblyInfo.cs | 35 - .../Queue/Data/Extensions.cs | 56 - .../Queue/Data/MailboxData.cs | 49 - .../Queue/Data/TaskData.cs | 36 - .../Queue/Data/TenantData.cs | 35 - .../Queue/MailQueueItemSettings.cs | 104 -- .../Queue/QueueManager.cs | 633 ---------- .../Queue/SignalrWorker.cs | 193 --- .../mail.agg.log4net.config | 137 -- .../mail.agg.nlog.config | 21 - .../ASC.Mail.DomainParser.csproj | 341 ----- .../Services/ASC.Mail.DomainParser/App.config | 29 - .../Services/ASC.Mail.DomainParser/Program.cs | 149 --- .../Properties/AssemblyInfo.cs | 35 - .../XmlData/1und1.de.xml | 65 - .../XmlData/abc.plala.or.jp.xml | 24 - .../XmlData/agate.plala.or.jp.xml | 24 - .../XmlData/alice.it.xml | 30 - .../XmlData/amail.plala.or.jp.xml | 24 - .../XmlData/amber.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/aol.com.xml | 45 - .../XmlData/apost.plala.or.jp.xml | 24 - .../XmlData/aqua.plala.or.jp.xml | 24 - .../XmlData/arcor.de.xml | 57 - .../XmlData/arubapec.it.xml | 34 - .../ASC.Mail.DomainParser/XmlData/att.net.xml | 35 - .../XmlData/avsmedia.com.xml | 22 - .../XmlData/avsmedia.net.xml | 21 - .../XmlData/ballade.plala.or.jp.xml | 24 - .../XmlData/bay.wind.ne.jp.xml | 28 - .../XmlData/bb-niigata.jp.xml | 22 - .../XmlData/beige.plala.or.jp.xml | 24 - .../XmlData/biglobe.ne.jp.xml | 23 - .../XmlData/bigpond.com.xml | 28 - .../XmlData/blue.plala.or.jp.xml | 24 - .../XmlData/bluemail.ch.xml | 31 - .../XmlData/bluewin.ch.xml | 30 - .../XmlData/bmail.plala.or.jp.xml | 24 - .../XmlData/bolero.plala.or.jp.xml | 24 - .../XmlData/bpost.plala.or.jp.xml | 24 - .../XmlData/broba.cc.xml | 25 - .../XmlData/brown.plala.or.jp.xml | 24 - .../XmlData/camel.plala.or.jp.xml | 24 - .../XmlData/cameo.plala.or.jp.xml | 24 - .../XmlData/cc9.ne.jp.xml | 21 - .../XmlData/cek.ne.jp.xml | 21 - .../XmlData/cgl.ucsf.edu.xml | 22 - .../XmlData/charter.com.xml | 52 - .../XmlData/clio.ne.jp.xml | 22 - .../XmlData/cmail.plala.or.jp.xml | 24 - .../XmlData/co1.wind.ne.jp.xml | 25 - .../XmlData/co2.wind.ne.jp.xml | 25 - .../XmlData/co3.wind.ne.jp.xml | 25 - .../XmlData/cocoa.plala.or.jp.xml | 24 - .../XmlData/coda.plala.or.jp.xml | 24 - .../XmlData/comcast.net.xml | 22 - .../XmlData/concerto.plala.or.jp.xml | 24 - .../XmlData/coral.plala.or.jp.xml | 24 - .../XmlData/courante.plala.or.jp.xml | 24 - .../XmlData/cpost.plala.or.jp.xml | 24 - .../XmlData/cream.plala.or.jp.xml | 24 - .../XmlData/dan.wind.ne.jp.xml | 28 - .../XmlData/dance.plala.or.jp.xml | 24 - .../XmlData/dd.iij4u.or.jp.xml | 33 - .../ASC.Mail.DomainParser/XmlData/df.eu.xml | 33 - .../XmlData/dmail.plala.or.jp.xml | 24 - .../XmlData/earthlink.net.xml | 35 - .../XmlData/ebony.plala.or.jp.xml | 24 - .../XmlData/email.it.xml | 33 - .../XmlData/email.plala.or.jp.xml | 24 - .../XmlData/ewetel.de.xml | 23 - .../XmlData/fantasy.plala.or.jp.xml | 24 - .../XmlData/flamenco.plala.or.jp.xml | 24 - .../XmlData/fmail.plala.or.jp.xml | 24 - .../XmlData/francetelecom.fr.xml | 31 - .../ASC.Mail.DomainParser/XmlData/free.fr.xml | 62 - .../XmlData/freenet.de.xml | 56 - .../XmlData/fuga.plala.or.jp.xml | 24 - .../XmlData/gandi.net.xml | 58 - .../XmlData/gmail.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/gmx.com.xml | 72 -- .../ASC.Mail.DomainParser/XmlData/gmx.net.xml | 66 - .../XmlData/go.tvm.ne.jp.xml | 22 - .../ASC.Mail.DomainParser/XmlData/goo.jp.xml | 22 - .../XmlData/googlemail.com.xml | 52 - .../XmlData/grape.plala.or.jp.xml | 24 - .../XmlData/gray.plala.or.jp.xml | 24 - .../XmlData/hal.ne.jp.xml | 22 - .../XmlData/hana.or.jp.xml | 22 - .../XmlData/hotmail.com.xml | 37 - .../XmlData/i.softbank.jp.xml | 22 - .../XmlData/ic-net.or.jp.xml | 22 - .../XmlData/iijmio-mail.jp.xml | 26 - .../XmlData/iiyama-catv.ne.jp.xml | 21 - .../XmlData/imail.plala.or.jp.xml | 24 - .../XmlData/inbox.lt.xml | 26 - .../XmlData/inbox.lv.xml | 26 - .../XmlData/indigo.plala.or.jp.xml | 24 - .../XmlData/inet-shibata.or.jp.xml | 22 - .../XmlData/internode.on.net.xml | 32 - .../ASC.Mail.DomainParser/XmlData/ipax.at.xml | 28 - .../XmlData/ivory.plala.or.jp.xml | 24 - .../XmlData/iwafune.ne.jp.xml | 22 - .../XmlData/jade.plala.or.jp.xml | 24 - .../XmlData/janis.or.jp.xml | 23 - .../XmlData/jet.ne.jp.xml | 29 - .../XmlData/ji.jet.ne.jp.xml | 22 - .../XmlData/jmail.plala.or.jp.xml | 24 - .../XmlData/kabelmail.de.xml | 31 - .../XmlData/kelcom.net.xml | 21 - .../XmlData/khaki.plala.or.jp.xml | 24 - .../XmlData/kl.wind.ne.jp.xml | 32 - .../XmlData/kmail.plala.or.jp.xml | 24 - .../XmlData/kokuyou.ne.jp.xml | 21 - .../XmlData/lapis.plala.or.jp.xml | 24 - .../XmlData/laposte.net.xml | 37 - .../XmlData/lemon.plala.or.jp.xml | 24 - .../XmlData/libero.it.xml | 34 - .../XmlData/lilac.plala.or.jp.xml | 24 - .../XmlData/lime.plala.or.jp.xml | 24 - .../XmlData/mahoroba.ne.jp.xml | 22 - .../XmlData/mail.com.xml | 248 ---- .../ASC.Mail.DomainParser/XmlData/mail.dk.xml | 22 - .../XmlData/mail.iwafune.ne.jp.xml | 22 - .../ASC.Mail.DomainParser/XmlData/mail.ru.xml | 42 - .../XmlData/mail.telenor.dk.xml | 121 -- .../XmlData/mail.wind.ne.jp.xml | 29 - .../XmlData/maroon.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/me.com.xml | 31 - .../XmlData/minuet.plala.or.jp.xml | 24 - .../XmlData/ml.murakami.ne.jp.xml | 22 - .../XmlData/mnet.ne.jp.xml | 22 - .../XmlData/mopera.net.xml | 50 - .../XmlData/mozilla.com.xml | 23 - .../XmlData/mx1.tiki.ne.jp.xml | 54 - .../XmlData/navy.plala.or.jp.xml | 24 - .../XmlData/nctsoft.com.xml | 22 - .../XmlData/nifty.com.xml | 22 - .../ASC.Mail.DomainParser/XmlData/nsat.jp.xml | 22 - .../ASC.Mail.DomainParser/XmlData/o2.pl.xml | 35 - .../XmlData/olive.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/onet.pl.xml | 38 - .../XmlData/opal.plala.or.jp.xml | 24 - .../XmlData/orange.plala.or.jp.xml | 24 - .../XmlData/orchid.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/ovh.net.xml | 32 - .../XmlData/pal.kijimadaira.jp.xml | 21 - .../XmlData/palette.plala.or.jp.xml | 24 - .../XmlData/parabox.or.jp.xml | 22 - .../ASC.Mail.DomainParser/XmlData/pdx.edu.xml | 41 - .../XmlData/peach.plala.or.jp.xml | 24 - .../XmlData/peoplepc.com.xml | 29 - .../XmlData/plum.plala.or.jp.xml | 24 - .../XmlData/po.dcn.ne.jp.xml | 21 - .../XmlData/po.wind.ne.jp.xml | 28 - .../XmlData/polka.plala.or.jp.xml | 24 - .../XmlData/pop.shibata.ne.jp.xml | 23 - .../XmlData/posteo.de.xml | 25 - .../XmlData/purple.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/qip.ru.xml | 52 - .../XmlData/rainbow.plala.or.jp.xml | 24 - .../XmlData/rambler.ru.xml | 40 - .../XmlData/red.plala.or.jp.xml | 24 - .../XmlData/rmail.plala.or.jp.xml | 24 - .../XmlData/rondo.plala.or.jp.xml | 24 - .../XmlData/rose.plala.or.jp.xml | 24 - .../XmlData/rouge.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/rr.com.xml | 25 - .../XmlData/ruby.plala.or.jp.xml | 24 - .../XmlData/sakunet.ne.jp.xml | 21 - .../XmlData/sea.plala.or.jp.xml | 24 - .../XmlData/sepia.plala.or.jp.xml | 24 - .../XmlData/serenade.plala.or.jp.xml | 24 - .../XmlData/seznam.cz.xml | 26 - .../ASC.Mail.DomainParser/XmlData/sfr.fr.xml | 36 - .../XmlData/silk.plala.or.jp.xml | 24 - .../XmlData/silver.plala.or.jp.xml | 24 - .../XmlData/sky.plala.or.jp.xml | 24 - .../XmlData/skynet.be.xml | 35 - .../XmlData/smail.plala.or.jp.xml | 24 - .../XmlData/snow.plala.or.jp.xml | 24 - .../XmlData/so.wind.ne.jp.xml | 25 - .../XmlData/sonata.plala.or.jp.xml | 24 - .../XmlData/strato.de.xml | 43 - .../XmlData/studenti.univr.it.xml | 22 - .../XmlData/suite.plala.or.jp.xml | 24 - .../XmlData/sympatico.ca.xml | 30 - .../XmlData/symphony.plala.or.jp.xml | 24 - .../XmlData/t-online.de.xml | 37 - .../XmlData/taupe.plala.or.jp.xml | 24 - .../XmlData/terra.es.xml | 29 - .../XmlData/tiki.ne.jp.xml | 24 - .../XmlData/tiscali.cz.xml | 25 - .../XmlData/tiscali.it.xml | 31 - .../XmlData/tmail.plala.or.jp.xml | 24 - .../XmlData/toccata.plala.or.jp.xml | 24 - .../XmlData/topaz.plala.or.jp.xml | 24 - .../XmlData/trio.plala.or.jp.xml | 24 - .../XmlData/umail.plala.or.jp.xml | 24 - .../XmlData/umich.edu.xml | 22 - .../XmlData/upcmail.nl.xml | 23 - .../XmlData/verizon.net.xml | 22 - .../XmlData/versatel.de.xml | 43 - .../XmlData/violet.plala.or.jp.xml | 24 - .../XmlData/vm.aikis.or.jp.xml | 22 - .../XmlData/vmail.plala.or.jp.xml | 24 - .../XmlData/vp.tiki.ne.jp.xml | 24 - .../XmlData/waltz.plala.or.jp.xml | 24 - .../XmlData/wave.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/web.de.xml | 55 - .../XmlData/white.plala.or.jp.xml | 24 - .../XmlData/wildwestdomains.com.xml | 37 - .../XmlData/wine.plala.or.jp.xml | 24 - .../XmlData/wmail.plala.or.jp.xml | 24 - .../ASC.Mail.DomainParser/XmlData/wp.pl.xml | 22 - .../XmlData/xmail.plala.or.jp.xml | 24 - .../XmlData/xp.wind.jp.xml | 24 - .../XmlData/xpost.plala.or.jp.xml | 24 - .../XmlData/xs4all.nl.xml | 22 - .../XmlData/xtra.co.nz.xml | 22 - .../XmlData/yahoo.co.jp.xml | 22 - .../XmlData/yahoo.com.xml | 41 - .../XmlData/yandex.ru.xml | 39 - .../XmlData/ybb.ne.jp.xml | 22 - .../XmlData/yellow.plala.or.jp.xml | 24 - .../XmlData/ymail.plala.or.jp.xml | 24 - .../XmlData/ypost.plala.or.jp.xml | 24 - .../XmlData/ziggo.nl.xml | 25 - .../XmlData/zmail.plala.or.jp.xml | 24 - .../XmlData/zpost.plala.or.jp.xml | 24 - .../ASC.Mail.EmlDownloader.csproj | 103 -- .../ASC.Mail.EmlDownloader/App.config | 58 - .../ASC.Mail.EmlDownloader/Program.Options.cs | 34 - .../ASC.Mail.EmlDownloader/Program.cs | 168 --- .../Properties/AssemblyInfo.cs | 35 - .../ASC.Mail.PasswordFinder.csproj | 119 -- .../ASC.Mail.PasswordFinder/App.config | 64 - .../Program.Options.cs | 43 - .../ASC.Mail.PasswordFinder/Program.cs | 314 ----- .../Properties/AssemblyInfo.cs | 36 - .../ASC.Mail.Reloader.csproj | 132 -- .../Services/ASC.Mail.Reloader/App.config | 73 -- .../ASC.Mail.Reloader/Program.Options.cs | 46 - .../Services/ASC.Mail.Reloader/Program.cs | 332 ----- .../Properties/AssemblyInfo.cs | 36 - .../ASC.Mail.StorageCleaner.Service.csproj | 140 --- .../ASC.Mail.StorageCleaner/App.config | 85 -- .../HealthCheckService.cs | 33 - .../ASC.Mail.StorageCleaner/Program.cs | 53 - .../Properties/AssemblyInfo.cs | 35 - .../StorageCleanerService.cs | 257 ---- .../mail.cln.log4net.config | 113 -- .../mail.cln.nlog.config | 19 - .../ASC.Mail.Watchdog.Service.csproj | 148 --- .../ASC.Mail.Watchdog.Service/App.config | 59 - .../HealthCheckService.cs | 33 - .../Program.Options.cs | 31 - .../ASC.Mail.Watchdog.Service/Program.cs | 53 - .../Properties/AssemblyInfo.cs | 35 - .../Properties/Resources.Designer.cs | 63 - .../Properties/Resources.resx | 117 -- .../Properties/Settings.Designer.cs | 26 - .../Properties/Settings.settings | 5 - .../WatchdogService.Designer.cs | 37 - .../WatchdogService.cs | 158 --- .../mail.dog.log4net.config | 112 -- .../mail.dog.nlog.config | 19 - .../LoginProviders/TwitterLoginProvider.cs | 2 - .../ASC.Thrdparty/ASC.Thrdparty.csproj | 93 -- module/ASC.Thrdparty/ASC.Thrdparty/Message.cs | 51 - .../ASC.Thrdparty/Properties/AssemblyInfo.cs | 34 - .../ASC.Thrdparty/SocialMediaException.cs | 44 - .../ASC.Thrdparty/Twitter/Exceptions.cs | 59 - .../ASC.Thrdparty/Twitter/TwitterApiInfo.cs | 27 - .../Twitter/TwitterDataProvider.cs | 139 -- .../ASC.Thrdparty/Twitter/TwitterUserInfo.cs | 37 - module/ASC.Thrdparty/ASC.Thrdparty/app.config | 7 - module/ASC.WebDav/helper/logger.js | 2 +- .../resource/customVirtualResource.js | 6 +- module/ASC.WebDav/server/config.js | 11 +- module/ASC.WebDav/server/webDavServer.js | 2 +- .../Bundling/GoogleCloudStorageTransform.cs | 2 +- web/core/ASC.Web.Core/CookiesManager.cs | 28 +- .../Extensions/WebItemExtension.cs | 9 +- .../ASC.Web.Core/Files/DocumentService.cs | 11 +- web/core/ASC.Web.Core/Files/FileUtility.cs | 13 +- .../ASC.Web.Core/Utility/ModeThemeSettings.cs | 2 +- web/core/ASC.Web.Core/WebItemContext.cs | 1 + .../WhiteLabel/TenantWhiteLabelSettings.cs | 7 +- .../ASC.Web.Studio/ASC.Web.Studio.csproj | 89 +- .../Core/EmailOperationService.cs | 64 +- web/studio/ASC.Web.Studio/Default.aspx | 2 +- web/studio/ASC.Web.Studio/Default.aspx.cs | 16 +- web/studio/ASC.Web.Studio/Global.asax.cs | 15 +- .../FCKEditorFileUploadHandler.cs | 7 +- .../HttpHandlers/UrlProxyHandler.cs | 5 +- .../Products/CRM/ASC.Web.CRM.csproj | 139 +- .../CRM/App_Themes/dark/dark-params.less | 7 +- .../CRM/App_Themes/default/css/common.less | 42 +- .../CRM/App_Themes/default/css/contacts.less | 76 +- .../CRM/App_Themes/default/css/crm.less | 1 - .../CRM/App_Themes/default/css/invoices.less | 2 +- .../CRM/App_Themes/default/css/params.less | 7 +- .../CRM/App_Themes/default/css/settings.less | 8 +- .../App_Themes/default/css/socialmedia.less | 193 --- .../CRM/App_Themes/default/css/tasks.less | 6 +- .../default/images/empty_screen_twitter.svg | 6 - .../App_Themes/default/images/icons-dark.svg | 66 + .../default/images/product_logolarge_dark.svg | 16 + .../CRM/App_Themes/default/images/twitter.png | Bin 606 -> 0 bytes .../CRM/Classes/ContactPhotoManager.cs | 10 +- .../CRM/Classes/RegisterClientScriptHelper.cs | 19 +- .../SocialMedia/SocialMediaAccountNotFound.cs | 26 - .../SocialMediaImageDescription.cs | 33 - .../CRM/Classes/SocialMedia/SocialMediaUI.cs | 154 --- .../Classes/SocialMedia/TwitterApiHelper.cs | 44 - .../CRM/Configuration/ProductEntryPoint.cs | 1 + .../Controls/Contacts/ContactActionView.ascx | 19 +- .../Controls/Contacts/ContactDetailsView.ascx | 26 - .../Contacts/ContactDetailsView.ascx.cs | 5 +- .../Contacts/ContactFullCardView.ascx | 2 +- .../CRM/Masters/BasicTemplate.Master.cs | 1 - .../ClientScripts/CRMSettingsResources.cs | 3 +- .../ClientLocalizationResources.cs | 2 - .../Resources/CRMCommonResource.Designer.cs | 9 - .../Resources/CRMCommonResource.ar-AE.resx | 3 - .../CRMCommonResource.az-Latn-AZ.resx | 3 - .../CRM/Resources/CRMCommonResource.bg.resx | 3 - .../Resources/CRMCommonResource.bs-BA.resx | 3 - .../CRM/Resources/CRMCommonResource.ca.resx | 3 - .../CRM/Resources/CRMCommonResource.cs.resx | 3 - .../CRM/Resources/CRMCommonResource.de.resx | 3 - .../CRM/Resources/CRMCommonResource.el.resx | 3 - .../CRM/Resources/CRMCommonResource.es.resx | 3 - .../CRM/Resources/CRMCommonResource.et.resx | 3 - .../CRM/Resources/CRMCommonResource.fi.resx | 3 - .../CRM/Resources/CRMCommonResource.fr.resx | 3 - .../CRM/Resources/CRMCommonResource.hr.resx | 3 - .../CRM/Resources/CRMCommonResource.id.resx | 3 - .../CRM/Resources/CRMCommonResource.it.resx | 3 - .../CRM/Resources/CRMCommonResource.ja.resx | 3 - .../CRM/Resources/CRMCommonResource.ka.resx | 3 - .../CRM/Resources/CRMCommonResource.ko.resx | 3 - .../CRM/Resources/CRMCommonResource.lt.resx | 3 - .../CRM/Resources/CRMCommonResource.lv.resx | 3 - .../Resources/CRMCommonResource.nb-NO.resx | 3 - .../CRM/Resources/CRMCommonResource.nl.resx | 3 - .../CRM/Resources/CRMCommonResource.pl.resx | 3 - .../Resources/CRMCommonResource.pt-BR.resx | 3 - .../CRM/Resources/CRMCommonResource.pt.resx | 3 - .../CRM/Resources/CRMCommonResource.resx | 3 - .../CRM/Resources/CRMCommonResource.ru.resx | 3 - .../CRM/Resources/CRMCommonResource.sk.resx | 3 - .../CRM/Resources/CRMCommonResource.sl.resx | 3 - .../CRMCommonResource.sr-Latn-CS.resx | 3 - .../CRM/Resources/CRMCommonResource.sv.resx | 3 - .../CRM/Resources/CRMCommonResource.tr.resx | 3 - .../CRM/Resources/CRMCommonResource.uk.resx | 3 - .../CRM/Resources/CRMCommonResource.vi.resx | 3 - .../Resources/CRMCommonResource.zh-CN.resx | 3 - .../Resources/CRMCommonResource.zh-TW.resx | 3 - .../Resources/CRMContactResource.Designer.cs | 18 - .../CRMContactResource.az-Latn-AZ.resx | 6 - .../CRM/Resources/CRMContactResource.bg.resx | 6 - .../Resources/CRMContactResource.bs-BA.resx | 6 - .../CRM/Resources/CRMContactResource.cs.resx | 6 - .../CRM/Resources/CRMContactResource.de.resx | 6 - .../CRM/Resources/CRMContactResource.es.resx | 6 - .../CRM/Resources/CRMContactResource.fi.resx | 6 - .../CRM/Resources/CRMContactResource.fr.resx | 6 - .../CRM/Resources/CRMContactResource.id.resx | 6 - .../CRM/Resources/CRMContactResource.it.resx | 6 - .../CRM/Resources/CRMContactResource.ja.resx | 3 - .../CRM/Resources/CRMContactResource.ka.resx | 3 - .../CRM/Resources/CRMContactResource.ko.resx | 3 - .../CRM/Resources/CRMContactResource.lt.resx | 6 - .../CRM/Resources/CRMContactResource.lv.resx | 6 - .../CRM/Resources/CRMContactResource.nl.resx | 6 - .../CRM/Resources/CRMContactResource.pl.resx | 6 - .../Resources/CRMContactResource.pt-BR.resx | 6 - .../CRM/Resources/CRMContactResource.pt.resx | 3 - .../CRM/Resources/CRMContactResource.resx | 6 - .../CRM/Resources/CRMContactResource.ru.resx | 6 - .../CRM/Resources/CRMContactResource.sk.resx | 10 - .../CRM/Resources/CRMContactResource.sl.resx | 6 - .../CRM/Resources/CRMContactResource.sv.resx | 6 - .../CRM/Resources/CRMContactResource.tr.resx | 6 - .../CRM/Resources/CRMContactResource.uk.resx | 6 - .../CRM/Resources/CRMContactResource.vi.resx | 6 - .../Resources/CRMContactResource.zh-CN.resx | 6 - .../Resources/CRMContactResource.zh-TW.resx | 6 - .../CRM/Resources/CRMJSResource.Designer.cs | 27 - .../CRM/Resources/CRMJSResource.ar-AE.resx | 9 - .../Resources/CRMJSResource.az-Latn-AZ.resx | 9 - .../CRM/Resources/CRMJSResource.bg.resx | 9 - .../CRM/Resources/CRMJSResource.bs-BA.resx | 9 - .../CRM/Resources/CRMJSResource.cs.resx | 9 - .../CRM/Resources/CRMJSResource.de.resx | 9 - .../CRM/Resources/CRMJSResource.es.resx | 9 - .../CRM/Resources/CRMJSResource.fi.resx | 9 - .../CRM/Resources/CRMJSResource.fr.resx | 9 - .../CRM/Resources/CRMJSResource.id.resx | 9 - .../CRM/Resources/CRMJSResource.it.resx | 9 - .../CRM/Resources/CRMJSResource.ja.resx | 9 - .../CRM/Resources/CRMJSResource.ka.resx | 9 - .../CRM/Resources/CRMJSResource.ko.resx | 9 - .../CRM/Resources/CRMJSResource.lt.resx | 9 - .../CRM/Resources/CRMJSResource.lv.resx | 9 - .../CRM/Resources/CRMJSResource.nl.resx | 9 - .../CRM/Resources/CRMJSResource.pl.resx | 9 - .../CRM/Resources/CRMJSResource.pt-BR.resx | 9 - .../CRM/Resources/CRMJSResource.pt.resx | 9 - .../Products/CRM/Resources/CRMJSResource.resx | 9 - .../CRM/Resources/CRMJSResource.ru.resx | 9 - .../CRM/Resources/CRMJSResource.sk.resx | 15 - .../CRM/Resources/CRMJSResource.sl.resx | 9 - .../CRM/Resources/CRMJSResource.sv.resx | 9 - .../CRM/Resources/CRMJSResource.tr.resx | 9 - .../CRM/Resources/CRMJSResource.uk.resx | 9 - .../CRM/Resources/CRMJSResource.vi.resx | 9 - .../CRM/Resources/CRMJSResource.zh-CN.resx | 9 - .../CRM/Resources/CRMJSResource.zh-TW.resx | 9 - .../CRMSocialMediaResource.Designer.cs | 180 --- .../CRMSocialMediaResource.ar-AE.resx | 79 -- .../CRMSocialMediaResource.az-Latn-AZ.resx | 100 -- .../Resources/CRMSocialMediaResource.bg.resx | 100 -- .../CRMSocialMediaResource.bs-BA.resx | 100 -- .../Resources/CRMSocialMediaResource.ca.resx | 79 -- .../Resources/CRMSocialMediaResource.cs.resx | 100 -- .../Resources/CRMSocialMediaResource.da.resx | 79 -- .../Resources/CRMSocialMediaResource.de.resx | 100 -- .../Resources/CRMSocialMediaResource.el.resx | 100 -- .../Resources/CRMSocialMediaResource.es.resx | 100 -- .../Resources/CRMSocialMediaResource.et.resx | 76 -- .../Resources/CRMSocialMediaResource.fa.resx | 76 -- .../Resources/CRMSocialMediaResource.fi.resx | 79 -- .../Resources/CRMSocialMediaResource.fr.resx | 100 -- .../Resources/CRMSocialMediaResource.hr.resx | 70 -- .../Resources/CRMSocialMediaResource.hu.resx | 61 - .../Resources/CRMSocialMediaResource.id.resx | 79 -- .../Resources/CRMSocialMediaResource.it.resx | 100 -- .../Resources/CRMSocialMediaResource.ja.resx | 79 -- .../Resources/CRMSocialMediaResource.ka.resx | 70 -- .../Resources/CRMSocialMediaResource.ko.resx | 79 -- .../Resources/CRMSocialMediaResource.lt.resx | 79 -- .../Resources/CRMSocialMediaResource.lv.resx | 100 -- .../Resources/CRMSocialMediaResource.nl.resx | 100 -- .../Resources/CRMSocialMediaResource.pl.resx | 100 -- .../CRMSocialMediaResource.pt-BR.resx | 100 -- .../Resources/CRMSocialMediaResource.pt.resx | 79 -- .../CRM/Resources/CRMSocialMediaResource.resx | 100 -- .../Resources/CRMSocialMediaResource.ro.resx | 100 -- .../Resources/CRMSocialMediaResource.ru.resx | 100 -- .../Resources/CRMSocialMediaResource.sk.resx | 114 -- .../Resources/CRMSocialMediaResource.sl.resx | 79 -- .../Resources/CRMSocialMediaResource.sv.resx | 100 -- .../Resources/CRMSocialMediaResource.tr.resx | 100 -- .../Resources/CRMSocialMediaResource.uk.resx | 101 -- .../Resources/CRMSocialMediaResource.vi.resx | 100 -- .../CRMSocialMediaResource.zh-CN.resx | 100 -- .../CRMSocialMediaResource.zh-TW.resx | 100 -- .../CRM/Templates/ContactsTemplates.html | 75 -- .../Products/CRM/Utils/ExportToCSV.cs | 4 +- .../Utils/Import/CSV/ImportDataOperation.cs | 4 +- .../Products/CRM/Utils/MailSender.cs | 4 +- .../Products/CRM/Utils/PdfCreator.cs | 6 +- .../Products/CRM/js/contacts.js | 227 ++-- .../Products/CRM/js/socialmedia.js | 448 ------- .../Community/ASC.Web.Community.csproj | 2 + .../App_Themes/dark/dark-params.less | 9 +- .../default/images/product_logolarge_dark.svg | 34 + .../Community/App_Themes/default/params.less | 9 +- .../BookmarkingUserControl.ascx.cs | 38 + .../CreateBookmarkUserControl.ascx | 2 +- .../UserControls/PostListControl.ascx.cs | 3 +- .../Modules/News/Code/PollVoteHandler.cs | 36 +- .../Modules/Wiki/Handlers/WikiFileHandler.cs | 18 +- .../Community/Modules/Wiki/ListFiles.aspx | 2 +- .../Community/Modules/Wiki/content/main.less | 26 +- .../Community/Product/CommunityProduct.cs | 1 + .../Products/Files/ASC.Web.Files.csproj | 9 +- .../Files/App_Themes/bright-blue/params.less | 3 +- .../App_Themes/dark-bright-blue/params.less | 3 +- .../App_Themes/dark-dark-green/params.less | 3 +- .../App_Themes/dark-deep-blue/params.less | 3 +- .../Files/App_Themes/dark-default/params.less | 14 +- .../Files/App_Themes/dark-green/params.less | 3 +- .../App_Themes/dark-pure-orange/params.less | 3 +- .../App_Themes/dark-wild-pink/params.less | 3 +- .../Files/App_Themes/deep-blue/params.less | 3 +- .../Files/App_Themes/default/common.less | 4 +- .../default/images/product_logolarge.svg | 30 +- .../default/images/product_logolarge_dark.svg | 30 + .../Files/App_Themes/default/params.less | 14 +- .../Files/App_Themes/pure-orange/params.less | 3 +- .../Files/App_Themes/wild-pink/params.less | 3 +- .../Files/Configuration/ProductEntryPoint.cs | 1 + .../ChunkUploadDialog/chunkuploaddialog.less | 2 +- .../ChunkUploadDialog/chunkuploadmanager.js | 100 +- .../Controls/ContentList/ContentList.ascx | 12 +- .../Controls/ContentList/ContentList.ascx.cs | 1 + .../Controls/ContentList/contentlist.less | 224 ++-- .../ContentList/images/version_operation.png | Bin 917 -> 0 bytes .../ContentList/images/version_operation.svg | 15 + .../Files/Controls/CreateMenu/CreateMenu.ascx | 7 +- .../Files/Controls/CreateMenu/createmenu.js | 2 +- .../Files/Controls/Desktop/desktop.js | 19 +- .../Files/Controls/EmptyFolder/emptyfolder.js | 2 +- .../FileSelector/FileSelector.ascx.cs | 1 + .../Controls/FileSelector/fileselector.js | 66 +- .../Controls/FileSelector/fileselector.less | 16 +- .../Controls/MainContent/MainContent.ascx | 32 + .../SharingDialog/images/link-dark.svg | 3 + .../SharingDialog/images/settings-dark.svg | 10 + .../SharingDialog/images/user-dark.svg | 3 + .../Controls/SharingDialog/sharingdialog.js | 30 +- .../Controls/SharingDialog/sharingdialog.less | 70 +- .../Files/Controls/ThirdParty/thirdparty.js | 20 +- .../Files/Controls/ThirdParty/thirdparty.less | 8 - .../Products/Files/Controls/Tree/tree.less | 2 +- .../UnsubscribeDialog/unsubscribedialog.js | 19 +- .../Files/Core/Dao/Interfaces/IFileDao.cs | 9 +- .../Files/Core/Dao/TeamlabDao/FileDao.cs | 87 +- .../Products/Files/Core/Entries/FileEntry.cs | 32 +- .../Files/Core/Entries/FileReferenceData.cs | 4 +- .../Products/Files/Core/Entries/Tag.cs | 10 + .../Products/Files/Core/FilterTypeEnum.cs | 2 + .../Files/Core/Security/FileSecurity.cs | 12 +- .../Products/Files/DocEditor.aspx.cs | 9 +- .../Products/Files/FileChoice.aspx.cs | 5 +- .../ClientScripts/FilesConstantsResources.cs | 3 +- .../Resources/FilesCommonResource.Designer.cs | 4 +- .../FilesCommonResource.az-Latn-AZ.resx | 4 +- .../Files/Resources/FilesCommonResource.resx | 4 +- .../Resources/FilesJSResource.Designer.cs | 9 + .../Files/Resources/FilesJSResource.resx | 3 + .../Resources/FilesUCResource.Designer.cs | 32 +- .../Resources/FilesUCResource.az-Latn-AZ.resx | 3 - .../Files/Resources/FilesUCResource.resx | 18 +- .../Services/DocumentService/Configuration.cs | 26 +- .../DocumentServiceConnector.cs | 9 +- .../DocumentService/DocumentServiceHelper.cs | 3 +- .../DocumentService/DocumentServiceParams.cs | 3 + .../FileOperations/FileDeleteOperation.cs | 2 +- .../FileOperations/FileDownloadOperation.cs | 2 +- .../FileOperations/FileMoveCopyOperation.cs | 4 +- .../FileStorageServiceController.cs | 94 +- .../WCFService/IFileStorageService.cs | 11 +- .../Products/Files/ThirdPartyApp/BoxApp.cs | 2 +- .../Files/ThirdPartyApp/GoogleDriveApp.cs | 4 +- .../Files/Utils/ChunkedUploadSessionHolder.cs | 7 +- .../Products/Files/Utils/EntryManager.cs | 51 +- .../Products/Files/Utils/FileConverter.cs | 20 +- .../Products/Files/Utils/FileMarker.cs | 19 +- .../Products/Files/js/actionmanager.js | 120 +- .../Products/Files/js/editor.js | 72 +- .../Products/Files/js/eventhandler.js | 13 +- .../Products/Files/js/foldermanager.js | 56 +- .../Products/Files/js/servicemanager.js | 18 +- .../ASC.Web.Studio/Products/Files/js/ui.js | 84 +- .../Products/People/ASC.Web.People.csproj | 1 + .../App_Themes/default/css/birthdays.less | 4 +- .../default/images/product_logolarge_dark.svg | 38 + .../Products/People/Core/PeopleProduct.cs | 1 + .../Products/People/ProfileAction.aspx.cs | 5 + .../Resources/PeopleResource.Designer.cs | 9 + .../People/Resources/PeopleResource.resx | 3 + .../People/Templates/PeopleTemplates.html | 3 + .../Products/People/js/peopleactions.js | 9 + .../Products/Projects/ASC.Web.Projects.csproj | 3 + .../Projects/App_Themes/dark/dark-params.less | 8 +- .../App_Themes/default/css/alltasks.less | 166 +-- .../App_Themes/default/css/common.less | 372 +++--- .../App_Themes/default/css/ganttchart.less | 1 + .../App_Themes/default/css/params.less | 6 + .../default/images/product_logolarge_dark.svg | 24 + .../Configuration/ProductEntryPoint.cs | 1 + .../Common/ProjectDocumentsPopup.ascx.cs | 2 +- .../Core/Model/Domain/CustomStatus.cs | 6 +- .../Products/Projects/Settings.aspx.cs | 7 +- .../Products/Projects/js/taskdescription.js | 10 +- .../Products/Sample/ASC.Web.Sample.csproj | 2 + .../images/product_logo_large_dark.svg | 13 + .../Sample/Configuration/ProductEntryPoint.cs | 1 + .../Products/Sample/js/script.js | 17 +- .../CustomModeResource.ru.resx | 2 +- .../PublicResources/Resource.Designer.cs | 20 +- .../PublicResources/Resource.az-Latn-AZ.resx | 6 - .../PublicResources/Resource.bg.resx | 6 - .../PublicResources/Resource.cs.resx | 6 - .../PublicResources/Resource.de.resx | 6 - .../PublicResources/Resource.es.resx | 6 - .../PublicResources/Resource.fi.resx | 6 - .../PublicResources/Resource.fr.resx | 6 - .../PublicResources/Resource.it.resx | 6 - .../PublicResources/Resource.ja.resx | 6 - .../PublicResources/Resource.lv.resx | 6 - .../PublicResources/Resource.nl.resx | 6 - .../PublicResources/Resource.pl.resx | 6 - .../PublicResources/Resource.pt-BR.resx | 6 - .../PublicResources/Resource.resx | 8 +- .../PublicResources/Resource.ru.resx | 8 +- .../PublicResources/Resource.sk.resx | 6 - .../PublicResources/Resource.tr.resx | 6 - .../PublicResources/Resource.uk.resx | 6 - .../PublicResources/Resource.vi.resx | 6 - .../PublicResources/Resource.zh-CN.resx | 6 - .../PublicResources/ResourceJS.Designer.cs | 18 + .../PublicResources/ResourceJS.resx | 6 + .../UserControlsCommonResource.Designer.cs | 4 +- .../UserControlsCommonResource.resx | 4 +- .../Common/Attachments/css/attachments.less | 2 +- .../Common/Attachments/js/attachments.js | 13 +- .../Common/Authorize/Authorize.ascx.cs | 3 +- .../Common/MediaViewer/mediaplayer.js | 4 +- .../Common/MediaViewer/mediaplayer.less | 38 +- .../Common/Support/SupportChat.ascx.cs | 13 +- .../UserControls/Feed/css/feed.less | 2 +- .../css/Default/ldapsettings.less | 12 +- .../ShareLinkPassword/js/sharelinkpassword.js | 5 + .../css/singlesignonsettings.less | 6 +- .../TariffSettings/TariffNotify.ascx.cs | 2 +- .../Management/TariffSettings/TariffSaas.ascx | 16 +- .../TariffSettings/TariffSaas.ascx.cs | 16 +- .../TariffSettings/css/tariffsaas.less | 876 ++++++------- .../TariffSettings/js/tariffdesktop.js | 1 + .../Management/TfaControls/ConfirmTfa.ascx.cs | 2 +- .../Management/TfaControls/js/resetapp.js | 8 +- .../Management/TfaControls/js/showbackup.js | 3 +- .../ProductQuotes/js/product_quotes.js | 6 +- .../ProductQuotes/js/user_quota_controller.js | 8 +- .../AuthCommunications.ascx.cs | 3 + .../Users/UserProfile/UserEmailControl.ascx | 9 +- .../UserProfile/UserProfileActions.ascx.cs | 2 +- .../Users/UserProfile/UserProfileControl.ascx | 4 +- .../UserProfile/UserProfileControl.ascx.cs | 2 +- .../UserProfile/UserProfileEditControl.ascx | 2 +- .../css/images/social-icons-grey-dark.svg | 25 + .../css/images/social-icons-grey.png | Bin 6537 -> 0 bytes .../css/images/social-icons-grey.svg | 25 + .../css/profileeditcontrol_style.less | 4 +- .../css/userprofilecontrol_style.less | 21 +- .../UserProfile/js/userprofilecontrol.js | 16 +- .../UserProfile/js/userprofileeditcontrol.js | 12 +- .../css/img/icons_titles.png | Bin 2496 -> 0 bytes .../css/img/icons_titles.svg | 41 + .../UserSubscriptions/css/subscriptions.less | 28 +- .../ASC.Web.Studio/Utility/RefererURL.cs | 54 +- .../addons/calendar/ASC.Web.Calendar.csproj | 3 +- .../addons/calendar/Addon/CalendarAddon.cs | 1 + .../default/images/product_logolarge.svg | 120 +- .../default/images/product_logolarge_dark.svg | 68 + .../DocumentsPopup/DocumentsPopup.ascx.cs | 2 +- .../fullcalendar/css/fullcalendar.less | 11 +- .../UserControls/fullcalendar/fullcalendar.js | 14 +- .../addons/mail/ASC.Web.Mail.csproj | 5 + .../addons/mail/Addon/MailAddon.cs | 1 + .../mail/App_Themes/dark/dark-params.less | 4 +- .../default/images/background_sprite.png | Bin 293 -> 307 bytes .../default/images/background_sprite_dark.png | Bin 0 -> 571 bytes .../default/images/product_logolarge_dark.svg | 26 + .../App_Themes/default/less/accounts.less | 1 + .../mail/App_Themes/default/less/message.less | 7 +- .../DocumentsPopup/DocumentsPopup.ascx.cs | 2 +- .../ASC.Web.Studio/addons/mail/OAuth.aspx.cs | 19 +- .../addons/talk/ASC.Web.Talk.csproj | 8 + .../addons/talk/Addon/TalkAddon.cs | 1 + .../default/images/product_logolarge_dark.svg | 11 + .../ASC.Web.Studio/addons/talk/Default.aspx | 4 +- .../addons/talk/Default.aspx.cs | 11 +- .../talk/css/dark/dark-talk.overview.less | 43 +- .../addons/talk/css/dark/params.less | 3 +- .../addons/talk/css/default/params.less | 3 +- .../talk/css/default/talk.overview.less | 4 +- web/studio/ASC.Web.Studio/confirm.aspx.cs | 18 +- .../ASC.Web.Studio/js/asc/api/api.factory.js | 56 - .../ASC.Web.Studio/js/asc/api/asc.teamlab.js | 61 - .../js/asc/core/asc.files.utility.js | 35 +- .../js/asc/core/basetemplate.master.init.js | 27 +- .../ASC.Web.Studio/js/asc/core/common.js | 16 +- .../ASC.Web.Studio/js/asc/core/headscript.js | 2 +- .../js/asc/plugins/jquery-advansedfilter.js | 5 +- .../skins/bright-blue/params.less | 1 + .../skins/dark-default/dark-params.less | 77 +- .../skins/dark-green/params.less | 1 + .../skins/dark-img/toast_icon01.png | Bin 0 -> 745 bytes .../skins/dark-img/toast_icon02.png | Bin 0 -> 591 bytes .../skins/deep-blue/params.less | 3 +- .../skins/default/actionpanel.less | 9 +- .../ASC.Web.Studio/skins/default/buttons.less | 12 +- .../ASC.Web.Studio/skins/default/common.less | 12 +- .../skins/default/common_style.less | 201 ++- .../default/common_style.wide-screen.less | 6 +- .../skins/default/contentmenu.less | 28 +- .../skins/default/empty-screen-control.less | 210 ++-- .../skins/default/filetype_style.less | 35 +- .../ASC.Web.Studio/skins/default/helper.less | 124 +- .../default/images/filetype/file_dps.png | Bin 0 -> 854 bytes .../default/images/filetype/file_dpt.png | Bin 0 -> 836 bytes .../skins/default/images/filetype/file_et.png | Bin 0 -> 762 bytes .../default/images/filetype/file_ett.png | Bin 0 -> 765 bytes .../default/images/filetype/file_mhtml.png | Bin 0 -> 1148 bytes .../default/images/filetype/file_stw.png | Bin 0 -> 746 bytes .../default/images/filetype/file_sxc.png | Bin 0 -> 873 bytes .../default/images/filetype/file_sxi.png | Bin 0 -> 874 bytes .../default/images/filetype/file_sxw.png | Bin 0 -> 809 bytes .../default/images/filetype/file_wps.png | Bin 0 -> 773 bytes .../default/images/filetype/file_wpt.png | Bin 0 -> 737 bytes .../images/filetype/retina/file_dps.png | Bin 0 -> 2351 bytes .../images/filetype/retina/file_dpt.png | Bin 0 -> 2152 bytes .../images/filetype/retina/file_et.png | Bin 0 -> 1920 bytes .../images/filetype/retina/file_ett.png | Bin 0 -> 1956 bytes .../images/filetype/retina/file_mhtml.png | Bin 0 -> 2837 bytes .../images/filetype/retina/file_stw.png | Bin 0 -> 2394 bytes .../images/filetype/retina/file_sxc.png | Bin 0 -> 2462 bytes .../images/filetype/retina/file_sxi.png | Bin 0 -> 2272 bytes .../images/filetype/retina/file_sxw.png | Bin 0 -> 2475 bytes .../images/filetype/retina/file_wps.png | Bin 0 -> 2466 bytes .../images/filetype/retina/file_wpt.png | Bin 0 -> 2220 bytes .../images/filetype/thumb/file_dps.png | Bin 0 -> 1794 bytes .../images/filetype/thumb/file_dpt.png | Bin 0 -> 1624 bytes .../default/images/filetype/thumb/file_et.png | Bin 0 -> 1484 bytes .../images/filetype/thumb/file_ett.png | Bin 0 -> 1522 bytes .../images/filetype/thumb/file_mhtml.png | Bin 0 -> 1782 bytes .../images/filetype/thumb/file_stw.png | Bin 0 -> 1801 bytes .../images/filetype/thumb/file_sxc.png | Bin 0 -> 1992 bytes .../images/filetype/thumb/file_sxi.png | Bin 0 -> 1753 bytes .../images/filetype/thumb/file_sxw.png | Bin 0 -> 1964 bytes .../images/filetype/thumb/file_wps.png | Bin 0 -> 1912 bytes .../images/filetype/thumb/file_wpt.png | Bin 0 -> 1753 bytes .../default/images/icon-controlpanel-dark.svg | 9 + .../skins/default/images/logo/pdf.ico | Bin 0 -> 5430 bytes .../images/svg/context/icon_come_back.svg | 4 + .../default/images/svg/documents-icons.svg | 6 +- .../images/svg/documents/pencilgraydark.svg | 3 + .../skins/default/images/svg/people/copy.svg | 4 + .../images/svg/people/pencilgraydark.svg | 3 + .../images/svg/projects/check_tick-dark.svg | 3 + .../images/svg/projects/inbox-dark.svg | 3 + .../images/svg/projects/pause-dark.svg | 4 + .../images/svg/share/access_comment_dark.svg | 3 + .../images/svg/share/access_deny_dark.svg | 4 + .../images/svg/share/access_filter_dark.svg | 3 + .../images/svg/share/access_form_dark.svg | 3 + .../images/svg/share/access_full_dark.svg | 4 + .../images/svg/share/access_owner_dark.svg | 3 + .../images/svg/share/access_read_dark.svg | 15 + .../images/svg/share/access_review_dark.svg | 3 + .../images/svg/share/access_varies_dark.svg | 8 + .../default/images/svg/share/close_dark.svg | 12 + .../images/svg/share/group_avatar_dark.svg | 16 + .../images/svg/share/lifetime_dark.svg | 4 + .../images/svg/share/password_dark.svg | 3 + .../default/images/svg/share/trash_dark.svg | 3 + .../default/jquery-advansedfilter-fix.less | 23 +- .../default/jquery-advansedfilter-theme.less | 17 +- .../ASC.Web.Studio/skins/default/links.less | 4 +- .../ASC.Web.Studio/skins/default/params.less | 54 +- .../skins/default/topstudiopanel.less | 21 +- .../skins/default/userselector.less | 104 +- .../ASC.Web.Studio/skins/page_default.less | 6 +- .../skins/page_default_dark.less | 45 +- .../skins/pure-orange/params.less | 1 + .../skins/wild-pink/params.less | 1 + .../ASC.Web.Studio/web.appsettings.config | 20 +- .../ASC.Web.Studio/web.consumers.config | 2 - web/studio/ASC.Web.Studio/web.storage.config | 8 +- 890 files changed, 6294 insertions(+), 21906 deletions(-) create mode 100644 build/WinSW3.0.0.exe create mode 100644 build/install/install.bat create mode 100644 build/install/uninstall.bat create mode 100644 build/run/Radicale.xml create mode 100644 build/run/SocketIO.xml create mode 100644 build/run/SsoAuth.xml create mode 100644 build/run/Thumb.xml create mode 100644 build/run/UrlShortener.xml create mode 100644 build/run/WebDav.xml create mode 100644 build/sql/onlyoffice.upgradev126.sql create mode 100644 build/start/command.ps1 create mode 100644 build/start/start.bat create mode 100644 build/start/stop.bat create mode 100644 common/ASC.Data.Backup/Service/BackupMailServerFilesService.cs create mode 100644 common/ASC.Data.Backup/Tasks/Modules/MailTableSpecifics.cs create mode 100644 common/ASC.Data.Backup/Tasks/RestoreMailTableTask.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/ASC.Mail.Aggregator.CollectionService.csproj delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/AggregatorService.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/App.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/HealthCheckService.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Program.Options.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Program.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Properties/AssemblyInfo.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/Extensions.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/MailboxData.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/TaskData.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/TenantData.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/MailQueueItemSettings.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/QueueManager.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/SignalrWorker.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/mail.agg.log4net.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/mail.agg.nlog.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/ASC.Mail.DomainParser.csproj delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/App.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/Program.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/Properties/AssemblyInfo.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/1und1.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/abc.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/agate.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/alice.it.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/amail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/amber.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/aol.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/apost.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/aqua.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/arcor.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/arubapec.it.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/att.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/avsmedia.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/avsmedia.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ballade.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bay.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bb-niigata.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/beige.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/biglobe.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bigpond.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/blue.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bluemail.ch.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bluewin.ch.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bolero.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bpost.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/broba.cc.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/brown.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/camel.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cameo.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cc9.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cek.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cgl.ucsf.edu.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/charter.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/clio.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co1.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co2.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co3.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cocoa.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/coda.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/comcast.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/concerto.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/coral.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/courante.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cpost.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cream.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dan.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dance.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dd.iij4u.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/df.eu.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/earthlink.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ebony.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/email.it.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/email.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ewetel.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fantasy.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/flamenco.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/francetelecom.fr.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/free.fr.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/freenet.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fuga.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gandi.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmx.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmx.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/go.tvm.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/goo.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/googlemail.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/grape.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gray.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hal.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hana.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hotmail.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/i.softbank.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ic-net.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iijmio-mail.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iiyama-catv.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/imail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inbox.lt.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inbox.lv.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/indigo.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inet-shibata.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/internode.on.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ipax.at.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ivory.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iwafune.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jade.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/janis.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jet.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ji.jet.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kabelmail.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kelcom.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/khaki.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kl.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kokuyou.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lapis.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/laposte.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lemon.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/libero.it.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lilac.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lime.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mahoroba.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.dk.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.iwafune.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.ru.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.telenor.dk.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/maroon.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/me.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/minuet.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ml.murakami.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mnet.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mopera.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mozilla.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mx1.tiki.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/navy.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nctsoft.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nifty.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nsat.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/o2.pl.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/olive.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/onet.pl.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/opal.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/orange.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/orchid.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ovh.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pal.kijimadaira.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/palette.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/parabox.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pdx.edu.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/peach.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/peoplepc.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/plum.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/po.dcn.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/po.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/polka.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pop.shibata.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/posteo.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/purple.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/qip.ru.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rainbow.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rambler.ru.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/red.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rondo.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rose.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rouge.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rr.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ruby.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sakunet.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sea.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sepia.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/serenade.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/seznam.cz.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sfr.fr.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/silk.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/silver.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sky.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/skynet.be.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/smail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/snow.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/so.wind.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sonata.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/strato.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/studenti.univr.it.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/suite.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sympatico.ca.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/symphony.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/t-online.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/taupe.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/terra.es.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiki.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiscali.cz.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiscali.it.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/toccata.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/topaz.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/trio.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/umail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/umich.edu.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/upcmail.nl.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/verizon.net.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/versatel.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/violet.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vm.aikis.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vp.tiki.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/waltz.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wave.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/web.de.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/white.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wildwestdomains.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wine.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wp.pl.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xp.wind.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xpost.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xs4all.nl.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xtra.co.nz.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yahoo.co.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yahoo.com.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yandex.ru.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ybb.ne.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yellow.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ymail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ypost.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ziggo.nl.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/zmail.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/zpost.plala.or.jp.xml delete mode 100644 module/ASC.Mail/Services/ASC.Mail.EmlDownloader/ASC.Mail.EmlDownloader.csproj delete mode 100644 module/ASC.Mail/Services/ASC.Mail.EmlDownloader/App.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Program.Options.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Program.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Properties/AssemblyInfo.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.PasswordFinder/ASC.Mail.PasswordFinder.csproj delete mode 100644 module/ASC.Mail/Services/ASC.Mail.PasswordFinder/App.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Program.Options.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Program.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Properties/AssemblyInfo.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Reloader/ASC.Mail.Reloader.csproj delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Reloader/App.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Reloader/Program.Options.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Reloader/Program.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Reloader/Properties/AssemblyInfo.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.StorageCleaner/ASC.Mail.StorageCleaner.Service.csproj delete mode 100644 module/ASC.Mail/Services/ASC.Mail.StorageCleaner/App.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.StorageCleaner/HealthCheckService.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.StorageCleaner/Program.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.StorageCleaner/Properties/AssemblyInfo.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.StorageCleaner/StorageCleanerService.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.StorageCleaner/mail.cln.log4net.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.StorageCleaner/mail.cln.nlog.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/ASC.Mail.Watchdog.Service.csproj delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/App.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/HealthCheckService.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Program.Options.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Program.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/AssemblyInfo.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Resources.Designer.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Resources.resx delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Settings.Designer.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Settings.settings delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/WatchdogService.Designer.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/WatchdogService.cs delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/mail.dog.log4net.config delete mode 100644 module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/mail.dog.nlog.config delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/ASC.Thrdparty.csproj delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/Message.cs delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/Properties/AssemblyInfo.cs delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/SocialMediaException.cs delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/Twitter/Exceptions.cs delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterApiInfo.cs delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterDataProvider.cs delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterUserInfo.cs delete mode 100644 module/ASC.Thrdparty/ASC.Thrdparty/app.config delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/socialmedia.less delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/empty_screen_twitter.svg create mode 100644 web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/icons-dark.svg create mode 100644 web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/product_logolarge_dark.svg delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/twitter.png delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaAccountNotFound.cs delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaImageDescription.cs delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaUI.cs delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/TwitterApiHelper.cs delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.Designer.cs delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ar-AE.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.az-Latn-AZ.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.bg.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.bs-BA.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ca.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.cs.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.da.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.de.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.el.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.es.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.et.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fa.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fi.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fr.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.hr.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.hu.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.id.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.it.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ja.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ka.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ko.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.lt.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.lv.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.nl.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pl.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pt-BR.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pt.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ro.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ru.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sk.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sl.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sv.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.tr.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.uk.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.vi.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.zh-CN.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.zh-TW.resx delete mode 100644 web/studio/ASC.Web.Studio/Products/CRM/js/socialmedia.js create mode 100644 web/studio/ASC.Web.Studio/Products/Community/App_Themes/default/images/product_logolarge_dark.svg create mode 100644 web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/images/product_logolarge_dark.svg delete mode 100644 web/studio/ASC.Web.Studio/Products/Files/Controls/ContentList/images/version_operation.png create mode 100644 web/studio/ASC.Web.Studio/Products/Files/Controls/ContentList/images/version_operation.svg create mode 100644 web/studio/ASC.Web.Studio/Products/Files/Controls/SharingDialog/images/link-dark.svg create mode 100644 web/studio/ASC.Web.Studio/Products/Files/Controls/SharingDialog/images/settings-dark.svg create mode 100644 web/studio/ASC.Web.Studio/Products/Files/Controls/SharingDialog/images/user-dark.svg create mode 100644 web/studio/ASC.Web.Studio/Products/People/App_Themes/default/images/product_logolarge_dark.svg create mode 100644 web/studio/ASC.Web.Studio/Products/Projects/App_Themes/default/images/product_logolarge_dark.svg create mode 100644 web/studio/ASC.Web.Studio/Products/Sample/App_Themes/default/images/product_logo_large_dark.svg create mode 100644 web/studio/ASC.Web.Studio/UserControls/Users/UserProfile/css/images/social-icons-grey-dark.svg delete mode 100644 web/studio/ASC.Web.Studio/UserControls/Users/UserProfile/css/images/social-icons-grey.png create mode 100644 web/studio/ASC.Web.Studio/UserControls/Users/UserProfile/css/images/social-icons-grey.svg delete mode 100644 web/studio/ASC.Web.Studio/UserControls/Users/UserSubscriptions/css/img/icons_titles.png create mode 100644 web/studio/ASC.Web.Studio/UserControls/Users/UserSubscriptions/css/img/icons_titles.svg create mode 100644 web/studio/ASC.Web.Studio/addons/calendar/App_Themes/default/images/product_logolarge_dark.svg create mode 100644 web/studio/ASC.Web.Studio/addons/mail/App_Themes/default/images/background_sprite_dark.png create mode 100644 web/studio/ASC.Web.Studio/addons/mail/App_Themes/default/images/product_logolarge_dark.svg create mode 100644 web/studio/ASC.Web.Studio/addons/talk/App_Themes/default/images/product_logolarge_dark.svg rename module/ASC.Thrdparty/ASC.Thrdparty/SocialNetworks.cs => web/studio/ASC.Web.Studio/addons/talk/css/dark/dark-talk.overview.less (84%) create mode 100644 web/studio/ASC.Web.Studio/skins/dark-img/toast_icon01.png create mode 100644 web/studio/ASC.Web.Studio/skins/dark-img/toast_icon02.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_dps.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_dpt.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_et.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_ett.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_mhtml.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_stw.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_sxc.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_sxi.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_sxw.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_wps.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/file_wpt.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_dps.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_dpt.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_et.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_ett.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_mhtml.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_stw.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_sxc.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_sxi.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_sxw.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_wps.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/retina/file_wpt.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_dps.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_dpt.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_et.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_ett.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_mhtml.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_stw.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_sxc.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_sxi.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_sxw.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_wps.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/filetype/thumb/file_wpt.png create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/icon-controlpanel-dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/logo/pdf.ico create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/context/icon_come_back.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/documents/pencilgraydark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/people/copy.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/people/pencilgraydark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/projects/check_tick-dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/projects/inbox-dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/projects/pause-dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_comment_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_deny_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_filter_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_form_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_full_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_owner_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_read_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_review_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/access_varies_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/close_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/group_avatar_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/lifetime_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/password_dark.svg create mode 100644 web/studio/ASC.Web.Studio/skins/default/images/svg/share/trash_dark.svg rename module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterMessage.cs => web/studio/ASC.Web.Studio/skins/page_default_dark.less (74%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b2cd6d25c..09b75b5405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,155 @@ # Change log +## Version 12.6.0 + +### General portal changes + +* Edited sources build. +* Removed mail services transferred to a separate repository (#1378). +* Hidden tariff for 1 and 3 years in SaaS. +* Fixed issue when the ‘With opportunities’ filter does not display contacts that are specified as primary ones in Opportunities but are not specified on the Participants tab (Bug 61833). +* Fixed issue when the drop-down menu in the counter of the space occupied by a user goes out of the browser frame (Bug 61911). +* Added the ‘Copy email’ button for actions with user’s email (Bug 60814). +* Fixed issue when some GUI elements are displayed incorrectly when increasing the font in the browser settings (Bug 62342). +* Fixed issue when the ‘Color’ caption in the calendar editing window from the ‘Other Calendars’ list is formatted in bold (Bug 58850). +* Fixed issue when the uploaded contact logo does not displayed in the contact list (Bug 62378). +* Fixed issue with using the system theme by default for new users (Bug 62067). +* Fixed issue when the filter by group does not work (Bug 58230). +* Fixed issue when the request to upload an image to the server can be performed without cookie (Bug 62933). +* Fixed issue when the ‘Folder title’ field is missing in the ‘Change connection settings’ window for some third-party storages (Bug 62617). +* Fixed issue with an excess dividing line in the menu for a deactivated external link (Bug 62620). +* Fixed issue when the ‘Advanced settings’ menu differs in the Sharing Settings window of the manager and in the editor in the Common documents (Bug 62666). +* Added the ability to restrict access rights to the application files for the Others group (Bug 61602). +* Fixed issue with redirect to the portal main page when opening Control Panel after a day on Ubuntu 22.10 (Bug 62076). +* Fixed the Server-Side Request Forgery (SSRF) vulnerability (Bug 55994). +* Fixed the 'Could not resolve current tenant' error when exporting a large number of contacts (Bug 62984). +* Fixed issue when the password recovery link does not work in EU and SG regions (Bug 62126). +* Replaced the mysql_native_password authorization plugin with a modern one (Bug 62854). +* Fixed issue with the ability to send requests to ApiSystem when expanding the default machinekey (Bug 62489) +* Implemented the recalculation progress bar (Bug 60900). +* Fixed issue when the “To” time is set incorrectly when selecting an area for an event in the Day, Week viewing mode (Bug 62118). +* Fixed issue with the direct link to connect Gmail Gmail via oauth (addons/mail/oauth.aspx) (Bug 62813). +* Fixed issue with the XSS in the “Your subscription has expired” banner (Bug 63457). +* Fixed issue with the XSS sent in the attachment file is triggered (Bug 62497). +* Fixed issue when the page scrolls down when clicking Home/End in the search field (toolbar) (Bug 63526). +* Fixed issue when Open Redirect is possible for an authentication link (refererurl) on the portal (Bug 63328). +* Fixed issue when the quick external link is available for administrators only (Bug 63550). +* Fixed issue with the 'Account' error when trying to log in as a blocked user (Bug 63629). +* Fixed issue when there is an ability to send the Change Email message to any participant under the user (Bug 63538). +* Fixed issue when logout from the portal occurs for the administrator logged in as a user when performing the ‘Log out from all active connections’ action (Bug 63630). +* Fixed issue when old indexes are not removed when upgrading the Elasticsearch version (Bug 63584). +* Fixed issue when the onlyofficeAutoCleanUp service is not removed after updating to v.12.5 (Bug 63684) +* Fixed the "/uploadComplete 500" error when uploading an archive (Bug 64024). +* Fixed issue when the large backup file is not removed from S3 (Bug 63838). +* Fixed issue when the PUT /api/2.0/settings/modetheme.json 401 (Unauthorized) error appears in the console when opening a folder via the external link if the dark theme is set in the system (Bug 64285). +* Fixed issue when the size of the created file is added to the statistics of the administrator who performed the backup after performing backup (Bug 63783). +* Fixed issue when the XSS is triggered by a direct link to a malicious SVG file (Bug 64203). +* Updated versions of all related components to the actual ones (nodejs, python, PostgreSQL) (Bug 62063) +* Fixed issue when the VC++ 2015 additional packages are not updated for older versions (Windows) (Bug 63771). +* Fixed issue with the HTML injection in the Recover Access message (Administrator Message Settings) (Bug 64685). +* Reduced the number of characters displayed in the action button title for the parent folder (Bug 64462). +* Fixed the "undefined (reading 'response')" error in the console when opening the Controls section (Bug 64592). +* Fixed issue when the page title does not return to the default value from Common Settings (Bug 64641). +* Fixed issue when the text in the URL bar blends into the background if the portal dark theme is set (Bug 64589). +* Fixed the "/imagescss/quotebord-b.gif 404 (Not Found)" error when quoting a message (Bug 64577). +* Fixed issue when closing / opening a task fails with the following error "Uncaught TypeError: Cannot read properties of null (reading 'unselectable')" onChrome (Bug 64562). +* Fixed the "ASC.Api.Exceptions.ItemNotFoundException (0x80004005): Item not found" error in logs after removing a project (Bug 64569). +* Fixed issue with the XSS via a direct link to the uploaded malicious file on the Wiki page (Bug 64580). +* Fixed issue with the XSS uploaded files in the forum topic (Bug 64571). +* Fixed the "/Images/volume.svg 404 (Not Found" error when opening an audio file (Bug 64551). +* Fixed issue when the Actions button for the parent folder no longer appears after deleting a subfolder via the Actions menu for the parent folder in the ‘Shared with me’ section (Bug 64465). +* Fixed issue with the ‘Sharing settings’ option in the drop-down menu for the parent folder with external access (Bug 64434). +* Fixed issue with the ‘Sharing settings’ option in the drop-down menu for the parent folder for a Guest in the ‘Shared with me’ section (Bug 64468). +* Fixed issue when the Actions menu button on the Participants tab of the main contact disappears after clicking (Bug 63888). +* Fixed issue when the function to reset the application is not displayed in the user profile if his IP address is listed in exceptions (Bug 64487). +* Fixed issue when the .sxc, .et, .ett, .sxi, .dps, .dpt, .sxw, .stw, .wps, .wpt formats are not converted via the manager (Bug 64705). +* Fixed issue when the .sxi format is not supported (Bug 64708). +* Fixed issue when there are no icons for the .sxc, .et, .ett, .sxi, .dps, .dpt, .sxw, .stw, .wps, .wpt formats (Bug 64706). +* Fixed issue when search by folder contents cannot be performed in the ‘Create form template from file’ window (Bug 64687). +* Fixed issue when the ‘Create form template from file’ window does not correspond to layouts (Bug 64647). +* Fixed issue when the authorization page uses the system theme, regardless of the one selected in the profile (Bug 64588). +* Fixed issue with the ‘Delete’ button in the menu of the parent folder for a third-party storage folder (Bug 64758). +* Fixed issue when the files moved from ‘My Documents’ to Google Drive are displayed in the ‘Common’ section in the statistics (Bug 64393). +* Fixed issue when the ‘No files in this folder’ placeholder does not appear after moving all files from a subfolder with external access (Bug 64644). +* Fixed issue when the folder deleted via the parent folder menu appears again on the ‘Shared with me’ page (Bug 64620). +* Fixed issue with the ‘Back’ button in a subfolder with external access via an inherited link (Bug 64643). +* Edited the Twitter functionality description (Bug 64858). +* Fixed the ‘An item with the same key has already been added.’ error when clicking the ‘Common’ folder counter on the user’s portal (Bug 64862). +* Fixed issue when an empty folder with the same name is duplicated when uploading from the local disk using the drag’n’drop method (Bug 62858). +* Fixed the "Index was out of range. Must be non-negative and less than the size of the collection." error in svcIndexer.data.log (Bug 64630). +* Fixed issue when all sessions are not logged out when changing an email by the portal administrator (Bug 61574). +* Fixed issue when the Mail Server data (connected domains and mailboxes) is not saved in the backup (Bug 33720). +* Fixed issue when the disk space quota is displayed in the profile under the user without rights (Bug 64909). +* Fixed issue when it’s possible to create a user on a custom mail domain without setting a password (Bug 65083). +* Fixed issue when the Imap Sync icon wraps to a new line when reducing the browser window (or setting Zoom to 200%) (Bug 65266). +* Fixed issue with an incoming event less than 30 minutes long from Google or Outlook comes with the wrong time (-1 hour) (Bug 65387). +* Fixed issue when emails from the custom domain are not sent after restoring the portal from SaaS to the server version (Bug 65462). +* Fixed issue when the MX record is not updated after restoring the portal (Bug 65460). +* Updated incorrect links (Bug 65278) +* Fixed issue when the date in the CRM filter is limited to December 2023 (Bug 65683). +* Fixed issue when creating a document in a task is performed with the following error: "Uncaught TypeError: Cannot read properties of null (reading 'document')" (Bug 65737). +* Fixed issue when the ICS file contains an incorrect PRODID attribute (Bug 65571). +* Fixed issue when backup to Google Cloud fails when enabling Public Access Prevention (Bug 65678). +* Fixed issue with endless loading Portal memory quota (Bug 66134). +* Fixed issue when the user who does not have access to the Community module can download any file from the Wiki (Bug 66298). +* Fixed issue with the black portal logo in the PDF Editor with the light theme (Bug 66304). +* Fixed issue when the /api/2.0/portal/startbackup method allows creating backup in My Documents (Bug 66307). +* Fixed issue when the POST /ajaxpro/ASC.Web.UserControls.Bookmarking.BookmarkingUserControl,ASC.Web.Community.ashx method allows a user who does not have access to the Community module to create a bookmark (Bug 66347). +* Fixed issue when the /api/2.0/security/activeconnections/logout/{loginEventId} method is available to users who do not have administrator rights (Bug 66390). +* Removed/replaced ONLYOFFICE Sample Form (.oform) on the portal (Bug 66407). +* Fixed error when converting XML (Bug 66491). +* Fixed issue with the loader when hovering over the Actions button of the parent folder again after deleting a subfolder via the same menu (Bug 66436). +* Added a new icon for the PDF Editor. +* Filling out PDF instead of OFORM is now used. +* Conversion DOCXF to OFORM is no longer supported. +* Added templates for empty files in ar-SA and sr-Latn-RS. +* The history when sharing for external users is now available only to authorized users. +* Closed the functionality for copying text from the editor when the DenyDownload option is set for a file. +* Fixed the ability to enable recaptcha for the login page. Added the description to the Help Center. +* Added display of an error in the title of the landing page for an external link to a file when access to it is closed. +* Edited the birthday page for several birthdays on the same day with long titles. +* Fixed bugs related to the dark theme (#1324, #1336, #1364, #1381, #1383, #1387, #1394, #1409) +* Fixed the bug with the ability to select several answers when voting in a poll with only one choice. +* Completely removed Twitter from CRM (#1371) +* Fixed the GetByFilter method (the target parameter was not passed into the request). +* Fixes for compatibility with DocSpace (#1358 ,#1359 ,#1363) +* Fixed the “ArgumentOutOfRangeException: The absolute expiration value must be in the future” error when specified zero blocking time. +* Added the .mhtml format icon. +* Added setting focus to the password field. + +### Documents module + +* File formats of the OOXML group (docm dotm dotx potm potx ppsm pptm xlsm xltm xltx) are opened for editing without conversion to docx, xlsx, pptx. They will be available for encryption in Private rooms (#1301). Now it’s also possible to share files for commenting – docm dotm dotx potm potx ppsm pptm xlsm xltm xltx, for reviewing – docm dotm dotx, for a custom filter – xlsm xltm xltx. (#1302) +* Added opening for new formats: sxc, et, ett, sxi, dps, dpt, sxw, stw, wps, wpt (Docs v7.4 required). (#1305) +* Conversion when loading and before opening a non-OOXML format is now performed to the ooxml format (not to docx, xlsx, pptx depending on the type). This way the files will be converted to the format selected by DS. For example, if the doc file contains a macros, it will be converted to docm, not to docx. (#1304) +* Users with access for reading are transferred to the editor to be able to specify full access to the protected region in the spreadsheet (Docs v7.4 required). (#1354) +* When adding data to a spreadsheet via an external link to another spreadsheet, the update is available from the edited file (Docs v7.5 required). +* Added the ability to open the editor for an external data source spreadsheet in a new tab if the data is inserted to the spreadsheet via an external link (Docs v7.5 required). +* Added templates for empty files for si-LK, ar-SA and sr-Latn-RS cultures. +* Added new formats for generating thumbnails (#1366) +* Added uiTheme in Desktop v7.5 when portal:login (For Bug 57821 - The color of the connected portal tab does not correspond to the interface theme). +* Generating a form template from a local DOCX file (#1362) +* Added a drop-down list with actions for a parent folder (#1367) +* Added a filter to the fileselector (#1385) +* The pdf format is now considered as fillable one instead of oform. +* Removed docxf to oform conversion. + +### Mail module + +* Fixed an error in recording auto-reply parameters in email services. Due to this error, a user accidentally did not receive emails if there was an overdue auto-reply. +* Fixed SQL requests for calculating counters of read messages in folders. +* Fixed SQL requests for working with emails in custom folders (moving/removing/adding tags). +* Fixed issue when the Mail Server data (connected domains and mailboxes) is not saved in the backup (Bug 33720). + +### Control Panel + +* Added the ability to restrict access rights to the application files for the Others group (Bug 61602). +* Fixed issue with redirect to the portal main page when opening Control Panel after a day on Ubuntu 22.10 (Bug 62076). +* Fixed retrieving data error when opening the backup page (Bug 63163). +* Fixed issue when backup with Mail is not performed after disabling and enabling encryption (added text about stopping services and the instruction to the Help Center) (Bug 64223). +* Fixed issue when features are not saved to the new tariff when setting a quota for the portal (Bug 65324). +* Edited sources build. + ## Version 12.5.2 ### General portal changes diff --git a/build/WinSW3.0.0.exe b/build/WinSW3.0.0.exe new file mode 100644 index 0000000000000000000000000000000000000000..de3014513bd77a59092bf4f6c48f241e0c3d3537 GIT binary patch literal 667648 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 z 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 h)}H2qNw+?= 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

(W`)kU$ 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/dev/null 2>&1 || ( service mysql start >/dev/null 2>&1 && $MYSQL -e ";" >/dev/null ) + MYSQL_AUTHENTICATION_PLUGIN=$($MYSQL -e "SHOW VARIABLES LIKE 'default_authentication_plugin';" -s | awk '{print $2}') + MYSQL_AUTHENTICATION_PLUGIN=${MYSQL_AUTHENTICATION_PLUGIN:-caching_sha2_password} + + if ! grep -q "^default-authentication-plugin" ${CNF_PATH}; then + sed "/\[mysqld\]/a default-authentication-plugin = ${MYSQL_AUTHENTICATION_PLUGIN}" -i ${CNF_PATH} + else + sed "s/default-authentication-plugin.*/default-authentication-plugin = ${MYSQL_AUTHENTICATION_PLUGIN}/" -i ${CNF_PATH} || true # ignore errors + fi + if [ "${DB_USER}" = "root" ]; then - # allow MySql.Data.dll connect via mysql_native_password with root and empty password - $MYSQL -D "mysql" -e "ALTER USER '${DB_USER}'@'localhost' IDENTIFIED WITH mysql_native_password BY '${DB_PWD}'" >/dev/null 2>&1 \ - || $MYSQL -D "mysql" -e "UPDATE user SET plugin='mysql_native_password', Password = PASSWORD('${DB_PWD}') WHERE user='${DB_USER}' and host='localhost';" + # allow MySql.Data.dll connect via $MYSQL_AUTHENTICATION_PLUGIN with root and empty password + $MYSQL -D "mysql" -e "ALTER USER '${DB_USER}'@'localhost' IDENTIFIED WITH ${MYSQL_AUTHENTICATION_PLUGIN} BY '${DB_PWD}'" >/dev/null 2>&1 \ + || $MYSQL -D "mysql" -e "UPDATE user SET plugin='${MYSQL_AUTHENTICATION_PLUGIN}', Password = PASSWORD('${DB_PWD}') WHERE user='${DB_USER}' and host='localhost';" fi service mysql restart @@ -225,6 +232,8 @@ case "$1" in usermod -aG {{package_sysname}},nginx {{package_sysname}} + [ ! -z "$2" ] && OLDER_PACKAGE_VERSION=$(awk -F. '{ printf("%d%03d%03d%03d", $1,$2,$3,$4); }' <<< $2) + install_db apply_connection_string apply_core_machinekey @@ -244,16 +253,6 @@ case "$1" in # needed for signalr service mkdir -p -m 700 "$DIR/.config/.mono/keypairs" - - chown {{package_sysname}}:{{package_sysname}} $DIR - chown {{package_sysname}}:{{package_sysname}} $APP_DATA_DIR - chown {{package_sysname}}:{{package_sysname}} -R $DIR/Services/ - chown {{package_sysname}}:{{package_sysname}} -R $DIR/WebStudio/ - chown {{package_sysname}}:{{package_sysname}} -R $DIR/Sql/ - chown {{package_sysname}}:{{package_sysname}} -R $DIR/Tools/ - chown {{package_sysname}}:{{package_sysname}} -R $DIR/ApiSystem/ - chown {{package_sysname}}:{{package_sysname}} -R $DIR/.config/ - chown {{package_sysname}}:{{package_sysname}} $LOG_DIR chown nginx:nginx -R /var/cache/nginx/{{package_sysname}} chown {{package_sysname}}:nginx -R /var/run/{{package_sysname}} @@ -305,6 +304,10 @@ END $MYSQL "$DB_NAME" -e "TRUNCATE webstudio_index"; fi + if [ -d "${APP_DATA_DIR}/Index" ]; then + find ${APP_DATA_DIR}/Index -maxdepth 1 \! -name "v${ELASTIC_SEARCH_VERSION}" -type d -regex '.*/v[0-9]+\.[0-9]+\.[0-9]+.*' -exec rm -rf {} \; + fi + mkdir -p "$LOG_DIR/Index" mkdir -p "$APP_INDEX_DIR" chown -R elasticsearch:elasticsearch "$APP_INDEX_DIR" @@ -345,17 +348,21 @@ END MEMORY_REQUIREMENTS=12228; #RAM ~4*3Gb if [ ${TOTAL_MEMORY} -gt ${MEMORY_REQUIREMENTS} ]; then - if ! grep -q "[-]Xms1g" /etc/elasticsearch/jvm.options; then - echo "-Xms4g" >> /etc/elasticsearch/jvm.options - else - sed -i "s/-Xms1g/-Xms4g/" /etc/elasticsearch/jvm.options - fi + ELASTICSEATCH_MEMORY="4g" + else + ELASTICSEATCH_MEMORY="1g" + fi - if ! grep -q "[-]Xmx1g" /etc/elasticsearch/jvm.options; then - echo "-Xmx4g" >> /etc/elasticsearch/jvm.options - else - sed -i "s/-Xmx1g/-Xmx4g/" /etc/elasticsearch/jvm.options - fi + if grep -qE "^[^#]*-Xms[0-9]g" /etc/elasticsearch/jvm.options; then + sed -i "s/-Xms[0-9]g/-Xms${ELASTICSEATCH_MEMORY}/" /etc/elasticsearch/jvm.options + else + echo "-Xms${ELASTICSEATCH_MEMORY}" >> /etc/elasticsearch/jvm.options + fi + + if grep -qE "^[^#]*-Xmx[0-9]g" /etc/elasticsearch/jvm.options; then + sed -i "s/-Xmx[0-9]g/-Xmx${ELASTICSEATCH_MEMORY}/" /etc/elasticsearch/jvm.options + else + echo "-Xmx${ELASTICSEATCH_MEMORY}" >> /etc/elasticsearch/jvm.options fi if [ -d /etc/elasticsearch/ ]; then @@ -444,6 +451,10 @@ EOF sed 's,{{SERVICE_SSO_AUTH_HOST_ADDR}},'"${SERVICE_SSO_AUTH_HOST_ADDR}"',' -i ${NGINX_ROOT_DIR}/includes/{{package_sysname}}-communityserver-proxy-to-controlpanel.conf; sed '/web\.controlpanel\.url/s/\(value\s*=\s*\"\)[^\"]*\"/\1\/controlpanel\/\"/' -i ${APP_ROOT_DIR}/web.appsettings.config; sed '/web\.controlpanel\.url/s/\(value\s*=\s*\"\)[^\"]*\"/\1\/controlpanel\/\"/' -i ${APP_SERVICES_DIR}/TeamLabSvc/TeamLabSvc.exe.config; + + if systemctl is-active {{package_sysname}}ControlPanel | grep -q ^active; then + service {{package_sysname}}ControlPanel restart >/dev/null 2>&1 + fi fi # end @@ -451,13 +462,13 @@ EOF db_get {{package_sysname}}-communityserver/imapsync-start-date || true MAIL_IMAPSYNC_START_DATE="${RET:-$(date +"%Y-%m-%dT%H:%M:%S")}"; [ -z "$RET" ] && db_set {{package_sysname}}-communityserver/imapsync-start-date ${MAIL_IMAPSYNC_START_DATE} || true - sed 's_\(\"ImapSyncStartDate":\).*,_\1 "'${MAIL_IMAPSYNC_START_DATE}'",_' -i /etc/{{package_sysname}}/communityserver/mail.production.json + sed 's_\(\"ImapSyncStartDate":\).*,_\1 "'${MAIL_IMAPSYNC_START_DATE}'",_' -i $CONFIG_DIR/mail.production.json sed "/mail\.imap-sync-start-date/s/value=\"\S*\"/value=\"${MAIL_IMAPSYNC_START_DATE}\"/g" -i ${APP_ROOT_DIR}/web.appsettings.config - sed "s!\"value\":.*!\"value\":\ \"${APP_DATA_DIR}\"!" -i /etc/{{package_sysname}}/communityserver/storage.production.json - sed "s!\"folder\":.*,!\"folder\":\ \"${APP_SERVICES_DIR}\",!" -i /etc/{{package_sysname}}/communityserver/appsettings.production.json + sed "s!\"value\":.*!\"value\":\ \"${APP_DATA_DIR}\"!" -i $CONFIG_DIR/storage.production.json + sed "s!\"folder\":.*,!\"folder\":\ \"${APP_SERVICES_DIR}\",!" -i $CONFIG_DIR/appsettings.production.json - OPENSSL_CONF="/etc/{{package_sysname}}/communityserver/openssl.cnf" + OPENSSL_CONF="$CONFIG_DIR/openssl.cnf" if [ ! -f $OPENSSL_CONF ]; then cp /etc/ssl/openssl.cnf $OPENSSL_CONF; sed '/new_oids$/a openssl_conf = default_conf' -i $OPENSSL_CONF @@ -514,6 +525,17 @@ CipherString = $CIPHERSTRING \n" >> $OPENSSL_CONF if systemctl is-active monoserve | grep -q "active"; then curl --silent --output /dev/null http://127.0.0.1/api/2.0/warmup/restart.json || true fi + + chown {{package_sysname}}:{{package_sysname}} $DIR + chown {{package_sysname}}:{{package_sysname}} $APP_DATA_DIR + chown {{package_sysname}}:{{package_sysname}} -R $DIR/Services/ + chown {{package_sysname}}:{{package_sysname}} -R $DIR/WebStudio/ + chown {{package_sysname}}:{{package_sysname}} -R $DIR/Sql/ + chown {{package_sysname}}:{{package_sysname}} -R $DIR/Tools/ + chown {{package_sysname}}:{{package_sysname}} -R $DIR/ApiSystem/ + chown {{package_sysname}}:{{package_sysname}} -R $DIR/.config/ + chown {{package_sysname}}:{{package_sysname}} -R $CONFIG_DIR + chown {{package_sysname}}:{{package_sysname}} $LOG_DIR ;; abort-upgrade|abort-remove|abort-deconfigure) diff --git a/build/install/deb/debian/rules b/build/install/deb/debian/rules index 7ac01e1ff5..5bd7ef13af 100644 --- a/build/install/deb/debian/rules +++ b/build/install/deb/debian/rules @@ -7,74 +7,33 @@ %: dh $@ --with=systemd -override_dh_systemd_enable: - dh_systemd_enable --name=monoserve - dh_systemd_enable --name=monoserveApiSystem - dh_systemd_enable --name={{package_sysname}}Feed - dh_systemd_enable --name={{package_sysname}}SocketIO - dh_systemd_enable --name={{package_sysname}}Telegram - dh_systemd_enable --name={{package_sysname}}Thumb - dh_systemd_enable --name={{package_sysname}}UrlShortener - dh_systemd_enable --name={{package_sysname}}FilesTrashCleaner - dh_systemd_enable --name={{package_sysname}}WebDav - dh_systemd_enable --name={{package_sysname}}Radicale - dh_systemd_enable --name={{package_sysname}}Index - dh_systemd_enable --name={{package_sysname}}Notify - dh_systemd_enable --name={{package_sysname}}Backup - dh_systemd_enable --name={{package_sysname}}StorageMigrate - dh_systemd_enable --name={{package_sysname}}StorageEncryption - dh_systemd_enable --name={{package_sysname}}MailAggregator - dh_systemd_enable --name={{package_sysname}}MailWatchdog - dh_systemd_enable --name={{package_sysname}}MailCleaner - dh_systemd_enable --name={{package_sysname}}MailImap - dh_systemd_enable --name={{package_sysname}}ThumbnailBuilder - dh_systemd_enable --name={{package_sysname}}SsoAuth - dh_systemd_enable --name=god +override_dh_auto_install: + dh_auto_install + dh_installsystemd --name=monoserve + dh_installsystemd --name=monoserveApiSystem + dh_installsystemd --name={{package_sysname}}Feed + dh_installsystemd --name={{package_sysname}}SocketIO + dh_installsystemd --name={{package_sysname}}Telegram + dh_installsystemd --name={{package_sysname}}Thumb + dh_installsystemd --name={{package_sysname}}UrlShortener + dh_installsystemd --name={{package_sysname}}FilesTrashCleaner + dh_installsystemd --name={{package_sysname}}WebDav + dh_installsystemd --name={{package_sysname}}Radicale + dh_installsystemd --name={{package_sysname}}Index + dh_installsystemd --name={{package_sysname}}Notify + dh_installsystemd --name={{package_sysname}}Backup + dh_installsystemd --name={{package_sysname}}StorageMigrate + dh_installsystemd --name={{package_sysname}}StorageEncryption + dh_installsystemd --name={{package_sysname}}MailAggregator + dh_installsystemd --name={{package_sysname}}MailWatchdog + dh_installsystemd --name={{package_sysname}}MailCleaner + dh_installsystemd --name={{package_sysname}}MailImap + dh_installsystemd --name={{package_sysname}}ThumbnailBuilder + dh_installsystemd --name={{package_sysname}}SsoAuth + dh_installsystemd --name=god -override_dh_installinit: - dh_installinit --name=monoserve - dh_installinit --name=monoserveApiSystem - dh_installinit --name={{package_sysname}}Feed - dh_installinit --name={{package_sysname}}SocketIO - dh_installinit --name={{package_sysname}}Telegram - dh_installinit --name={{package_sysname}}Thumb - dh_installinit --name={{package_sysname}}UrlShortener - dh_installinit --name={{package_sysname}}FilesTrashCleaner - dh_installinit --name={{package_sysname}}WebDav - dh_installinit --name={{package_sysname}}Radicale - dh_installinit --name={{package_sysname}}Index - dh_installinit --name={{package_sysname}}Notify - dh_installinit --name={{package_sysname}}Backup - dh_installinit --name={{package_sysname}}StorageMigrate - dh_installinit --name={{package_sysname}}StorageEncryption - dh_installinit --name={{package_sysname}}MailAggregator - dh_installinit --name={{package_sysname}}MailWatchdog - dh_installinit --name={{package_sysname}}MailCleaner - dh_installinit --name={{package_sysname}}MailImap - dh_installinit --name={{package_sysname}}ThumbnailBuilder - dh_installinit --name={{package_sysname}}SsoAuth - dh_installinit --name=god - -override_dh_systemd_start: - dh_systemd_start --name=monoserve - dh_systemd_start --name=monoserveApiSystem - dh_systemd_start --name={{package_sysname}}Feed - dh_systemd_start --name={{package_sysname}}SocketIO - dh_systemd_start --name={{package_sysname}}Telegram - dh_systemd_start --name={{package_sysname}}Thumb - dh_systemd_start --name={{package_sysname}}UrlShortener - dh_systemd_start --name={{package_sysname}}FilesTrashCleaner - dh_systemd_start --name={{package_sysname}}WebDav - dh_systemd_start --name={{package_sysname}}Radicale - dh_systemd_start --name={{package_sysname}}Index - dh_systemd_start --name={{package_sysname}}Notify - dh_systemd_start --name={{package_sysname}}Backup - dh_systemd_start --name={{package_sysname}}StorageMigrate - dh_systemd_start --name={{package_sysname}}StorageEncryption - dh_systemd_start --name={{package_sysname}}MailAggregator - dh_systemd_start --name={{package_sysname}}MailWatchdog - dh_systemd_start --name={{package_sysname}}MailCleaner - dh_systemd_start --name={{package_sysname}}MailImap - dh_systemd_start --name={{package_sysname}}ThumbnailBuilder - dh_systemd_start --name={{package_sysname}}SsoAuth - dh_systemd_start --name=god \ No newline at end of file +execute_after_dh_fixperms: + find \ + "debian/{{package_sysname}}-communityserver/etc/{{package_sysname}}/communityserver/" \ + "debian/{{package_sysname}}-communityserver/var/www/{{package_sysname}}/" \ + -type f -regex '.*\(json\|config\)' ! -path '*node_modules*' -exec chmod o-rwx {} \; diff --git a/build/install/install.bat b/build/install/install.bat new file mode 100644 index 0000000000..e07ad4495f --- /dev/null +++ b/build/install/install.bat @@ -0,0 +1,12 @@ +@echo off + +PUSHD %~dp0.. + +if %errorlevel% == 0 ( + for /R "run\" %%f in (*.xml) do ( + call TeamLabSvc\WinSW3.0.0.exe install %%f + ) +) + +echo. +pause \ No newline at end of file diff --git a/build/install/rpm/common.spec b/build/install/rpm/common.spec index 90ac68abb4..13881fd0b0 100644 --- a/build/install/rpm/common.spec +++ b/build/install/rpm/common.spec @@ -76,6 +76,11 @@ find "$RPM_BUILD_ROOT/usr/bin/" \ find "$RPM_BUILD_ROOT/var/www/%{package_sysname}/Sql" -depth -type f -exec rename -f -v 's/onlyoffice([^\/]*)$/%{package_sysname}$1/g' {} \; +find \ +"$RPM_BUILD_ROOT/var/www/%{package_sysname}/" \ +"$RPM_BUILD_ROOT/etc/%{package_sysname}/communityserver/" \ +-type f -regex '.*\(json\|config\)' ! -path '*node_modules*' -exec chmod o-rwx {} \; + #list files OLD_IFS="$IFS" IFS=" @@ -90,7 +95,7 @@ for FILE in `find "$RPM_BUILD_ROOT/var/www/%{package_sysname}/"`; do echo "%%attr(-, %{package_sysname}, %{package_sysname}) %%config(noreplace) \"$RELFILE\"" >>onlyoffice.list ;; - */WebStudio/[Ww]eb*.config | */ApiSystem/[Ww]eb*.config | */TeamLabSvc.exe.config | */ASC.Mail.EmlDownloader.exe.config ) + */WebStudio/[Ww]eb*.config | */ApiSystem/[Ww]eb*.config | */TeamLabSvc.exe.config ) echo "%%attr(-, %{package_sysname}, %{package_sysname}) %%config \"$RELFILE\"" >>onlyoffice.list ;; @@ -116,6 +121,13 @@ rm -rf "$RPM_BUILD_ROOT" %attr(-, %{package_sysname}, %{package_sysname}) %config /etc/%{package_sysname}/communityserver/* %pre + +node_version=$(rpm -q --qf '%%{version}' nodejs | awk -F. '{ printf("%%d%%03d%%03d%%03d", $1,$2,$3,$4); }';) +if [[ "$node_version" -lt "14018000000" ]]; then + echo -e "\033[31mFor the %{package_sysname}-communityserver package to work properly, you need to install nodejs version 14.18.0 or higher\033[0m" + exit 1 +fi + getent group %{package_sysname} >/dev/null || groupadd -r %{package_sysname} getent passwd %{package_sysname} >/dev/null || useradd -r -g %{package_sysname} -d /var/www/%{package_sysname}/ -s /sbin/nologin %{package_sysname} @@ -145,9 +157,13 @@ sed '/web\.controlpanel\.url/s/\(value\s*=\s*\"\)[^\"]*\"/\1\/controlpanel\/\"/' CORE_MACHINEKEY="$(sed -n '/"core.machinekey"/s!.*value\s*=\s*"\([^"]*\)".*!\1!p' ${DIR}/WebStudio/web.appsettings.config)"; find "$DIR/controlpanel/www/config" -type f -name "*.json" -exec sed -i "s_\(\"core.machinekey\":\).*,_\1 \"${CORE_MACHINEKEY}\",_" {} \; -if systemctl is-active monoserve | grep -q "active"; then - systemctl restart monoserve -fi +package_services=("monoserve" "%{package_sysname}ControlPanel") + +for SVC in "${package_services[@]}"; do + if systemctl is-active "$SVC" | grep -q ^active; then + systemctl restart "$SVC" + fi +done %triggerin -- python3, python36 @@ -259,7 +275,7 @@ binDirs=("$DIR/ApiSystem/" "$DIR/WebStudio" "$DIR/controlpanel/www/config" "$SER if [ -f $DIR/WebStudio/web.appsettings.config.rpmsave ]; then CORE_MACHINEKEY="$(sed -n '/"core.machinekey"/s!.*value\s*=\s*"\([^"]*\)".*!\1!p' ${DIR}/WebStudio/web.appsettings.config.rpmsave)"; else - CORE_MACHINEKEY="$(sed -n '/"core.machinekey"/s!.*value\s*=\s*"\([^"]*\)".*!\1!p' ${DIR}/WebStudio/web.appsettings.config)"; + CORE_MACHINEKEY="$(cat /dev/urandom | tr -dc A-Za-z0-9 | head -c 12)"; fi sed "s^\(machine_key\)\s*=.*^\1 = ${CORE_MACHINEKEY}^g" -i ${SERVICES_DIR}/TeamLabSvc/radicale.config @@ -369,6 +385,10 @@ if [ -f ${ELASTIC_SEARCH_JAVA_CONF_PATH}.rpmnew ]; then cp -rf ${ELASTIC_SEARCH_JAVA_CONF_PATH}.rpmnew ${ELASTIC_SEARCH_JAVA_CONF_PATH}; fi +if [ -d "${APP_DATA_DIR}/Index" ]; then + find ${APP_DATA_DIR}/Index -maxdepth 1 \! -name "v${ELASTIC_SEARCH_VERSION}" -type d -regex '.*/v[0-9]+\.[0-9]+\.[0-9]+.*' -exec rm -rf {} \; +fi + mkdir -p "$LOG_DIR/Index" mkdir -p "$APP_INDEX_DIR" @@ -413,17 +433,21 @@ TOTAL_MEMORY=$(free -m | grep -oP '\d+' | head -n 1); MEMORY_REQUIREMENTS=12228; #RAM ~4*3Gb if [ ${TOTAL_MEMORY} -gt ${MEMORY_REQUIREMENTS} ]; then - if ! grep -q "[-]Xms1g" ${ELASTIC_SEARCH_JAVA_CONF_PATH}; then - echo "-Xms4g" >> ${ELASTIC_SEARCH_JAVA_CONF_PATH} - else - sed -i "s/-Xms1g/-Xms4g/" ${ELASTIC_SEARCH_JAVA_CONF_PATH} - fi + ELASTICSEATCH_MEMORY="4g" +else + ELASTICSEATCH_MEMORY="1g" +fi - if ! grep -q "[-]Xmx1g" ${ELASTIC_SEARCH_JAVA_CONF_PATH}; then - echo "-Xmx4g" >> ${ELASTIC_SEARCH_JAVA_CONF_PATH} - else - sed -i "s/-Xmx1g/-Xmx4g/" ${ELASTIC_SEARCH_JAVA_CONF_PATH} - fi +if grep -qE "^[^#]*-Xms[0-9]g" "${ELASTIC_SEARCH_JAVA_CONF_PATH}"; then + sed -i "s/-Xms[0-9]g/-Xms${ELASTICSEATCH_MEMORY}/" "${ELASTIC_SEARCH_JAVA_CONF_PATH}" +else + echo "-Xms${ELASTICSEATCH_MEMORY}" >> "${ELASTIC_SEARCH_JAVA_CONF_PATH}" +fi + +if grep -qE "^[^#]*-Xmx[0-9]g" "${ELASTIC_SEARCH_JAVA_CONF_PATH}"; then + sed -i "s/-Xmx[0-9]g/-Xmx${ELASTICSEATCH_MEMORY}/" "${ELASTIC_SEARCH_JAVA_CONF_PATH}" +else + echo "-Xmx${ELASTICSEATCH_MEMORY}" >> "${ELASTIC_SEARCH_JAVA_CONF_PATH}" fi if [ -d /etc/elasticsearch/ ]; then @@ -482,6 +506,10 @@ if [ $1 -ge 2 ]; then systemctl restart $SVC fi done + if systemctl is-active %{package_sysname}AutoCleanUp | grep -q "active"; then + systemctl disable %{package_sysname}AutoCleanUp + systemctl stop %{package_sysname}AutoCleanUp + fi fi if systemctl is-active monoserve | grep -q "active"; then diff --git a/build/install/rpm/onlyoffice-communityserver.spec b/build/install/rpm/onlyoffice-communityserver.spec index 9f275d4bdb..9e3035a2f9 100644 --- a/build/install/rpm/onlyoffice-communityserver.spec +++ b/build/install/rpm/onlyoffice-communityserver.spec @@ -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 -%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, dotnet-sdk-7.0 +%global package_header_tag_requires mono-complete >= 6.8.0, nginx >= 1.9.5, mysql-server >= 5.7.0, wget, mono-webserver-hyperfastcgi, nodejs >= 14.18.0, redis >= 3.0.0, elasticsearch = 7.16.3-1, python3 >= 3.6, ffmpeg, jq, dotnet-sdk-7.0 %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 onlyofficeFilesTrashCleaner onlyofficeRadicale onlyofficeThumbnailBuilder onlyofficeSsoAuth diff --git a/build/install/uninstall.bat b/build/install/uninstall.bat new file mode 100644 index 0000000000..65dc10a173 --- /dev/null +++ b/build/install/uninstall.bat @@ -0,0 +1,13 @@ +@echo off + +PUSHD %~dp0.. + +if %errorlevel% == 0 ( + for /R "run\" %%f in (*.xml) do ( + call TeamLabSvc\WinSW3.0.0.exe stop %%f + call TeamLabSvc\WinSW3.0.0.exe uninstall %%f + ) +) + +echo. +pause \ No newline at end of file diff --git a/build/msbuild/ASC.Web.Core.BuildTask.dll b/build/msbuild/ASC.Web.Core.BuildTask.dll index 1966e5e8b6c6791c559d61b244562ad832fa6b56..1a297ec95426a955c981c2893a3481d27acdd987 100644 GIT binary patch delta 469 zcmZp;!PszvaY6@+#@7ug8++oI>luUuH8dF*xbn4tgs>2hrwwG3N-;1n3JVJg=j#A@ zBLA3$MFd53Y#5*d`MN++4Lu+M6VL~;iw%H;u&5xPppc+wu_2I?Zv-S57%cc085jiF z^O+eK*aU_0je&w<{}_eE1jQ^BE-^4L6ng+AgvA*I#RY{$@=ZV*L9VHlU|?XG+{vQC zCtfWHWUA^)sR5OUPu|U9$PA+2vsf7m35r*P)D_!qr<^{V0Zm9!M8meY< z4C^`tM%m5WYVxecFS#TbUowQVH!*NB6|%Q6ykw{avR^Wo3CS{E1d_^(G7LG)T8t(P zoZ{v{kqR!`&9U0dOhEmKy4{S7=9Ay*nKEi^R@Pt3!f3GhqH(s0z*MV@1%4&Rz2-6B z?{Z6USvc7z!jF?rD3eL3lu1Zo^5Tetld~gL+1V5rWrP|vH&2LM!2ynt$u>z6nlBGj z?(@Gh(`}_`&pUJVQ!K!sV{o>LanCIAC{2nf$S*2M%qdRJFQ}Ycne={hPVy8E04M2a A+5i9m delta 450 zcmZp;!PszvaY6^n(T)Yl8++oI>x(@Y7}$h`7=#2hG#MDU^0k13urQFP4P=x`F)%O+ ziwFt{iiqUvz@%#>7#LUtMe=ol0wVvIg+&ELb!-@*0{MDCQ4M_{0TVC)vWpFYgs_+( zpP;aySg{e1lWzd2(srh1Dzo#oNodY75m31EG{T+xg99OFu9XOg-@tj z5@@BWu9Oqr<^@{@H`oCv4OO!_hIO3+ zqsnG(HF;Lf3N8u8iwrNh$Sq}_wlv%>I)cwUUsvJ fanCIAC{2n9$S*2M%qgB+oAiF70n6r`0 0 1 - 1 1 $(RootDir).nuget\NuGet.exe mono $(RootDir).nuget\NuGet.exe @@ -34,24 +33,6 @@ $(RootDir)packages\dotless.1.5.2\tool\dotless.compiler.exe mono $(RootDir)packages\dotless.1.5.2\tool\dotless.compiler.exe - - - module\ASC.Mail\Services\ASC.Mail.Aggregator.CollectionService\ASC.Mail.Aggregator.CollectionService.csproj - $(OutDir)Services\MailAggregator\ - - - module\ASC.Mail\Services\ASC.Mail.EmlDownloader\ASC.Mail.EmlDownloader.csproj - $(OutDir)Services\MailAggregator\ - - - module\ASC.Mail\Services\ASC.Mail.Watchdog.Service\ASC.Mail.Watchdog.Service.csproj - $(OutDir)Services\MailWatchdog\ - - - module\ASC.Mail\Services\ASC.Mail.StorageCleaner\ASC.Mail.StorageCleaner.Service.csproj - $(OutDir)Services\MailCleaner\ - - ASC.Socket.IO.Svc.Launcher, ASC.Socket.IO.Svc @@ -173,9 +154,6 @@ TargetToInvoke=DeployService - - TargetToInvoke=DeployMail - TargetToInvoke=DeployWeb @@ -204,23 +182,17 @@ - + - + - - - + + + - - - - - - @@ -298,11 +270,6 @@ - - - - - @@ -400,39 +367,6 @@ ..\config\private\UrlShortener.Substitutions.xml - - ..\config\private\Mail.Agg.Substitutions.xml - - - ..\config\private\Mail.Agg.Substitutions.xml - - - ..\config\private\Mail.Agg.Log4net.Substitutions.xml - - - ..\config\private\Mail.Agg.NLog.Substitutions.xml - - - ..\config\private\Mail.Dog.Substitutions.xml - - - ..\config\private\Mail.Dog.NLog.Substitutions.xml - - - ..\config\private\Mail.Dog.Log4net.Substitutions.xml - - - ..\config\private\Mail.Dog.NLog.Substitutions.xml - - - ..\config\private\Mail.Cln.Substitutions.xml - - - ..\config\private\Mail.Cln.Log4net.Substitutions.xml - - - ..\config\private\Mail.Cln.NLog.Substitutions.xml - diff --git a/build/run/Radicale.xml b/build/run/Radicale.xml new file mode 100644 index 0000000000..b131b0a4d3 --- /dev/null +++ b/build/run/Radicale.xml @@ -0,0 +1,11 @@ + + OnlyofficeRadicale + OnlyofficeRadicale + Automatic + %BASE%\..\TeamLabSvc + python + -m radicale --config radicale.config + + true + + \ No newline at end of file diff --git a/build/run/SocketIO.xml b/build/run/SocketIO.xml new file mode 100644 index 0000000000..47ee3a7f58 --- /dev/null +++ b/build/run/SocketIO.xml @@ -0,0 +1,10 @@ + + OnlyofficeSocketIO + OnlyofficeSocketIO + Automatic + node + ../ASC.Socket.IO/app.js + + true + + \ No newline at end of file diff --git a/build/run/SsoAuth.xml b/build/run/SsoAuth.xml new file mode 100644 index 0000000000..fcfe4e18c6 --- /dev/null +++ b/build/run/SsoAuth.xml @@ -0,0 +1,10 @@ + + OnlyofficeSsoAuth + OnlyOfficeSsoAuth + Automatic + node + ../ASC.SSoAuth/app.js + + true + + \ No newline at end of file diff --git a/build/run/Thumb.xml b/build/run/Thumb.xml new file mode 100644 index 0000000000..987147f762 --- /dev/null +++ b/build/run/Thumb.xml @@ -0,0 +1,10 @@ + + OnlyOfficeThumb + OnlyOfficeThumb + Automatic + node + ../ASC.Thumbnails/index.js + + true + + \ No newline at end of file diff --git a/build/run/UrlShortener.xml b/build/run/UrlShortener.xml new file mode 100644 index 0000000000..9442a6c1ca --- /dev/null +++ b/build/run/UrlShortener.xml @@ -0,0 +1,10 @@ + + OnlyofficeUrlShortener + OnlyOfficeUrlShortener + Automatic + node + ../ASC.UrlShortener/index.js + + true + + \ No newline at end of file diff --git a/build/run/WebDav.xml b/build/run/WebDav.xml new file mode 100644 index 0000000000..839ee16db1 --- /dev/null +++ b/build/run/WebDav.xml @@ -0,0 +1,10 @@ + + OnlyofficeWebDav + OnlyOfficeWebDav + Automatic + node + ../ASC.WebDav/server/webDavServer.js + + true + + \ No newline at end of file diff --git a/build/sql/onlyoffice.data.sql b/build/sql/onlyoffice.data.sql index 0c6a92b6e3..25eaf58761 100644 --- a/build/sql/onlyoffice.data.sql +++ b/build/sql/onlyoffice.data.sql @@ -283,7 +283,6 @@ BEGIN insert into files_converts (input, output) values ('.docxf', '.fb2'); insert into files_converts (input, output) values ('.docxf', '.html'); insert into files_converts (input, output) values ('.docxf', '.odt'); - insert into files_converts (input, output) values ('.docxf', '.oform'); insert into files_converts (input, output) values ('.docxf', '.ott'); insert into files_converts (input, output) values ('.docxf', '.pdf'); insert into files_converts (input, output) values ('.docxf', '.rtf'); diff --git a/build/sql/onlyoffice.upgradev126.sql b/build/sql/onlyoffice.upgradev126.sql new file mode 100644 index 0000000000..f315590514 --- /dev/null +++ b/build/sql/onlyoffice.upgradev126.sql @@ -0,0 +1,14 @@ +DELIMITER DLM00 + +DROP PROCEDURE IF EXISTS upgrade126 DLM00 + +CREATE PROCEDURE upgrade126() +BEGIN + + DELETE FROM `files_converts` WHERE `output`='.oform'; + +END DLM00 + +CALL upgrade126() DLM00 + +DELIMITER ; diff --git a/build/start/command.ps1 b/build/start/command.ps1 new file mode 100644 index 0000000000..a4651cecec --- /dev/null +++ b/build/start/command.ps1 @@ -0,0 +1,48 @@ +$PSversionMajor = $PSVersionTable.PSVersion | sort-object major | ForEach-Object {$_.major} +$PSversionMinor = $PSVersionTable.PSVersion | sort-object minor | ForEach-Object {$_.minor} + +if ($PSversionMajor -lt 7 -or $PSversionMinor -lt 2) { + Write-Error "Powershell version must be greater than or equal to 7.2." + exit +} + +$WorkDir = "$(Split-Path -Parent $PSScriptRoot)\run"; +$CommandName = "$($args[0])"; + +if ( $CommandName -eq "increase-service-timeout" ) { + $RegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Control' + $Name = 'ServicesPipeTimeout' + $Value = '90000' + + Write-Output "Changing service start timeout from default value (30000 ms ) to $($Value) ms" + + New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force + + + Write-Warning "Please, restart the computer for the changes to take effect." + exit +} + + + +#Write-Output "Starting $($CommandName) services at time: $(Get-Date -Format HH:mm:ss)" +#Write-Output "" + +Get-ChildItem -Path $WorkDir -File | ForEach-Object -ThrottleLimit 20 -Parallel { + $ServiceName = "Onlyoffice$([System.IO.Path]::GetFileNameWithoutExtension($_))"; + + switch ( $Using:CommandName ) + { + "start" { Start-Service -InputObject $(Get-Service -Name "$ServiceName") } + "stop" { Stop-Service -InputObject $(Get-Service -Name "$ServiceName") } + "restart" { Restart-Service -InputObject $(Get-Service -Name "$ServiceName") } + } + + if( $? ) + { + Write-Output "$ServiceName $($Using:CommandName) service has been done" + } +} + +#Write-Output "" +#Write-Output "End $($CommandName) services at time: $(Get-Date -Format HH:mm:ss)" \ No newline at end of file diff --git a/build/start/start.bat b/build/start/start.bat new file mode 100644 index 0000000000..697420556c --- /dev/null +++ b/build/start/start.bat @@ -0,0 +1,15 @@ +@echo off + +PUSHD %~dp0.. + +POPD + +if %errorlevel% == 0 ( + pwsh %~dp0/command.ps1 "start" +) + +echo. + +if "%1"=="nopause" goto start +pause +:start \ No newline at end of file diff --git a/build/start/stop.bat b/build/start/stop.bat new file mode 100644 index 0000000000..9d326a7314 --- /dev/null +++ b/build/start/stop.bat @@ -0,0 +1,15 @@ +@echo off + +PUSHD %~dp0.. + +POPD + +if %errorlevel% == 0 ( + pwsh %~dp0/command.ps1 "stop" +) + +echo. + +if "%1"=="nopause" goto start +pause +:start \ No newline at end of file diff --git a/common/ASC.Common/Data/MultiRegionalDbManager.cs b/common/ASC.Common/Data/MultiRegionalDbManager.cs index 0998be50d3..a1f27da61e 100644 --- a/common/ASC.Common/Data/MultiRegionalDbManager.cs +++ b/common/ASC.Common/Data/MultiRegionalDbManager.cs @@ -51,17 +51,27 @@ public DbCommand Command } - public MultiRegionalDbManager(string dbId) + public MultiRegionalDbManager(string dbId, bool? docspace) { const StringComparison cmp = StringComparison.InvariantCultureIgnoreCase; DatabaseId = dbId; databases = ConfigurationManager.ConnectionStrings.OfType() .Where(c => c.Name.Equals(dbId, cmp) || c.Name.StartsWith(dbId + ".", cmp)) + .Where(c => FilterDocspace(c, docspace)) .Select(c => new DbManager(c.Name)) .ToList(); localDb = databases.SingleOrDefault(db => db.DatabaseId.Equals(dbId, cmp)); } + private bool FilterDocspace(ConnectionStringSettings connectionString, bool? docspace) + { + if (!docspace.HasValue) return true; + + var isDocspace = connectionString.ConnectionString.Contains("docspace"); + + return docspace.Value ? isDocspace : !isDocspace; + } + public MultiRegionalDbManager(IEnumerable databases) { this.databases = databases.ToList(); @@ -78,11 +88,6 @@ public void Dispose() } } - public static MultiRegionalDbManager FromHttpContext(string databaseId) - { - return new MultiRegionalDbManager(databaseId); - } - public IDbTransaction BeginTransaction(IsolationLevel isolationLevel) { return localDb.BeginTransaction(isolationLevel); diff --git a/common/ASC.Common/Web/MimeMapping.cs b/common/ASC.Common/Web/MimeMapping.cs index 4ce7789e36..2e52b15cfb 100644 --- a/common/ASC.Common/Web/MimeMapping.cs +++ b/common/ASC.Common/Web/MimeMapping.cs @@ -156,6 +156,8 @@ static MimeMapping() AddMimeMapping(".dotm", "application/vnd.ms-word.template.macroEnabled.12"); AddMimeMapping(".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"); AddMimeMapping(".dp", "application/commonground"); + AddMimeMapping(".dps", "application/presentation"); + AddMimeMapping(".dpt", "application/presentation"); AddMimeMapping(".drw", "application/drafting"); AddMimeMapping(".dump", "application/octet-stream"); AddMimeMapping(".dv", "video/x-dv"); @@ -177,6 +179,8 @@ static MimeMapping() AddMimeMapping(".eps", "application/postscript"); AddMimeMapping(".epub", "application/epub+zip"); AddMimeMapping(".es", "application/x-esrehber"); + AddMimeMapping(".et", "application/spreadsheet"); + AddMimeMapping(".ett", "application/spreadsheet"); AddMimeMapping(".etx", "text/x-setext"); AddMimeMapping(".evy", "application/envoy"); AddMimeMapping(".evy", "application/x-envoy"); @@ -612,6 +616,7 @@ static MimeMapping() AddMimeMapping(".stl", "application/vndms-pkistl"); AddMimeMapping(".stm", "text/html"); AddMimeMapping(".stp", "application/step"); + AddMimeMapping(".stw", "application/vnd.sun.xml.writer.template"); AddMimeMapping(".sv4cpio", "application/x-sv4cpio"); AddMimeMapping(".sv4crc", "application/x-sv4crc"); AddMimeMapping(".svf", "image/vnd.dwg"); @@ -621,6 +626,9 @@ static MimeMapping() AddMimeMapping(".svg", "image/svg+xml"); AddMimeMapping(".svgt", "image/svg+xml"); AddMimeMapping(".swf", "application/x-shockwave-flash"); + AddMimeMapping(".sxi", "application/presentation"); + AddMimeMapping(".sxc", "application/vnd.sun.xml.calc"); + AddMimeMapping(".sxw", "application/vnd.sun.xml.writer"); AddMimeMapping(".t", "application/x-troff"); AddMimeMapping(".talk", "text/x-speech"); AddMimeMapping(".tar", "application/x-tar"); @@ -715,7 +723,8 @@ static MimeMapping() AddMimeMapping(".wp6", "application/wordperfect"); AddMimeMapping(".wpd", "application/wordperfect"); AddMimeMapping(".wpd", "application/x-wpwin"); - AddMimeMapping(".wps", "application/vnd.ms-works"); + AddMimeMapping(".wps", "application/document"); + AddMimeMapping(".wpt", "application/document"); AddMimeMapping(".wq1", "application/x-lotus"); AddMimeMapping(".wri", "application/mswrite"); AddMimeMapping(".wri", "application/x-wri"); diff --git a/common/ASC.Core.Common/Billing/ITariffService.cs b/common/ASC.Core.Common/Billing/ITariffService.cs index 0f881f8201..8e7f85e295 100644 --- a/common/ASC.Core.Common/Billing/ITariffService.cs +++ b/common/ASC.Core.Common/Billing/ITariffService.cs @@ -24,6 +24,8 @@ public interface ITariffService { Tariff GetTariff(int tenantId, bool withRequestToPaymentSystem = true); + IEnumerable GetAdditionalTariffs(int tenantId); + void SetTariff(int tenantId, Tariff tariff); void DeleteDefaultBillingInfo(); diff --git a/common/ASC.Core.Common/Billing/TariffService.cs b/common/ASC.Core.Common/Billing/TariffService.cs index 6e5166bb2b..7e391b1b88 100644 --- a/common/ASC.Core.Common/Billing/TariffService.cs +++ b/common/ASC.Core.Common/Billing/TariffService.cs @@ -107,7 +107,7 @@ public Tariff GetTariff(int tenantId, bool withRequestToPaymentSystem = true) tariff = CalculateTariff(tenantId, tariff); cache.Insert(key, tariff, DateTime.UtcNow.Add(GetCacheExpiration())); - if (BillingClient.Configured && withRequestToPaymentSystem) + if (BillingClient.Configured && withRequestToPaymentSystem && !IsDocspace) { Task.Run(() => { @@ -177,6 +177,22 @@ public Tariff GetTariff(int tenantId, bool withRequestToPaymentSystem = true) return tariff; } + public IEnumerable GetAdditionalTariffs(int tenantId) + { + if (CoreContext.Configuration.Standalone || !IsDocspace) + return null; + + var key = GetAdditionalTariffsCacheKey(tenantId); + var tariffs = cache.Get>(key); + if (tariffs == null) + { + tariffs = GetDocspaceTariffs(tenantId, true); + cache.Insert(key, tariffs, DateTime.UtcNow.Add(GetCacheExpiration())); + } + + return tariffs; + } + public void SetTariff(int tenantId, Tariff tariff) { if (tariff == null) @@ -208,6 +224,11 @@ private static string GetTariffCacheKey(int tenantId) return string.Format("{0}:{1}", tenantId, "tariff"); } + private static string GetAdditionalTariffsCacheKey(int tenantId) + { + return string.Format("{0}:{1}", tenantId, "tariff:additional"); + } + private static string GetBillingUrlCacheKey(int tenantId) { return string.Format("{0}:{1}", tenantId, "billing:urls"); @@ -420,11 +441,16 @@ public void SaveButton(int tariffId, string partnerId, string buttonUrl) private Tariff GetBillingInfo(int tenant) { + if (IsDocspace) + { + return GetDocspaceTariffs(tenant, false).FirstOrDefault() ?? Tariff.CreateDefault(); + } + var q = new SqlQuery("tenants_tariff") - .Select("tariff", "stamp", "quantity") - .Where("tenant", tenant) - .OrderBy("id", false) - .SetMaxResults(1); + .Select("tariff", "stamp", "quantity") + .Where("tenant", tenant) + .OrderBy("id", false) + .SetMaxResults(1); return ExecList(q) .ConvertAll(r => @@ -439,8 +465,44 @@ private Tariff GetBillingInfo(int tenant) ?? Tariff.CreateDefault(); } + private List GetDocspaceTariffs(int tenant, bool? additional) + { + var q = new SqlQuery("tenants_tariff tt") + .InnerJoin("tenants_tariffrow ttr", Exp.EqColumns("tt.id", "ttr.tariff_id")) + .Select("ttr.quota", "tt.stamp", "ttr.quantity") + .Where(string.Format("tt.id = (SELECT max(id) FROM tenants_tariff WHERE tenant={0})", tenant)); + + //additional tariffs: disk, admin1 + if (additional.HasValue) + { + if (additional.Value) + { + q.Where(Exp.In("ttr.quota", new[] { -4, -5 })); + } + else + { + q.Where(!Exp.In("ttr.quota", new[] { -4, -5 })); + } + } + + return ExecList(q) + .ConvertAll(r => + { + var tariff = Tariff.CreateDefault(); + tariff.QuotaId = Convert.ToInt32(r[0]); + tariff.DueDate = ((DateTime)r[1]).Year < 9999 ? (DateTime)r[1] : DateTime.MaxValue; + tariff.Quantity = Convert.ToInt32(r[2]); + return tariff; + }); + } + private bool SaveBillingInfo(int tenant, Tariff tariffInfo, bool renewal = true) { + if (IsDocspace) + { + return SaveDocspaceBillingInfo(tenant, tariffInfo); + } + var inserted = false; var currentTariff = GetBillingInfo(tenant); if (!tariffInfo.EqualsByParams(currentTariff)) @@ -483,6 +545,70 @@ private bool SaveBillingInfo(int tenant, Tariff tariffInfo, bool renewal = true) return inserted; } + private bool SaveDocspaceBillingInfo(int tenant, Tariff tariffInfo) + { + var inserted = false; + var currentTariff = GetBillingInfo(tenant); + if (!tariffInfo.EqualsByParams(currentTariff)) + { + var additionalTariffs = GetAdditionalTariffs(tenant); + + using (var db = GetDb()) + using (var tx = db.BeginTransaction()) + { + var q = new SqlInsert("tenants_tariff") + .InColumnValue("id", 0) + .InColumnValue("tenant", tenant) + .InColumnValue("stamp", tariffInfo.DueDate) + .InColumnValue("customer_id", string.Empty) + .InColumnValue("create_on", DateTime.UtcNow) + .Identity(0, 0, true); + + var id = db.ExecuteScalar(q); + + q = new SqlInsert("tenants_tariffrow") + .InColumnValue("tariff_id", id) + .InColumnValue("quota", tariffInfo.QuotaId) + .InColumnValue("tenant", tenant) + .InColumnValue("quantity", tariffInfo.Quantity); + + db.ExecuteNonQuery(q); + + if (additionalTariffs != null) + { + foreach (var additionalTariff in additionalTariffs) + { + q = new SqlInsert("tenants_tariffrow") + .InColumnValue("tariff_id", id) + .InColumnValue("quota", additionalTariff.QuotaId) + .InColumnValue("tenant", tenant) + .InColumnValue("quantity", additionalTariff.Quantity); + + db.ExecuteNonQuery(q); + } + } + + cache.Remove(GetTariffCacheKey(tenant)); + cache.Remove(GetAdditionalTariffsCacheKey(tenant)); + inserted = true; + + tx.Commit(); + } + } + + if (inserted) + { + var t = tenantService.GetTenant(tenant); + if (t != null) + { + // update tenant.LastModified to flush cache in documents + tenantService.SaveTenant(t); + } + } + + return inserted; + } + public void DeleteDefaultBillingInfo() { const int tenant = Tenant.DEFAULT_TENANT; diff --git a/common/ASC.Core.Common/Caching/CachedTenantService.cs b/common/ASC.Core.Common/Caching/CachedTenantService.cs index b63fde1c31..b677a5feef 100644 --- a/common/ASC.Core.Common/Caching/CachedTenantService.cs +++ b/common/ASC.Core.Common/Caching/CachedTenantService.cs @@ -43,6 +43,13 @@ public TimeSpan SettingsExpiration set; } + public bool IsDocspace + { + get + { + return service.IsDocspace; + } + } public CachedTenantService(ITenantService service) { diff --git a/common/ASC.Core.Common/Context/Impl/TenantManager.cs b/common/ASC.Core.Common/Context/Impl/TenantManager.cs index 75f87bb8b3..6d44e5b9af 100644 --- a/common/ASC.Core.Common/Context/Impl/TenantManager.cs +++ b/common/ASC.Core.Common/Context/Impl/TenantManager.cs @@ -24,6 +24,7 @@ using System.Web; using ASC.Core.Billing; +using ASC.Core.Data; using ASC.Core.Tenants; @@ -217,11 +218,35 @@ public TenantQuota GetTenantQuota(int tenant, bool useCache = true) { currentQuota = (TenantQuota)currentQuota.Clone(); - if (currentQuota.ActiveUsers == -1) + if (tenantService.IsDocspace) { - currentQuota.ActiveUsers = tariff.Quantity; - currentQuota.MaxTotalSize *= currentQuota.ActiveUsers; - currentQuota.Price *= currentQuota.ActiveUsers; + currentQuota.ActiveUsers *= tariff.Quantity; + currentQuota.MaxTotalSize *= tariff.Quantity; + currentQuota.Price *= tariff.Quantity; + + var additionalTariffs = tariffService.GetAdditionalTariffs(tenant); + if (additionalTariffs != null) + { + foreach (var additionalTariff in additionalTariffs) + { + var additionalQuota = quotaService.GetTenantQuota(additionalTariff.QuotaId); + if (additionalQuota != null) + { + currentQuota.ActiveUsers += additionalQuota.ActiveUsers * additionalTariff.Quantity; + currentQuota.MaxTotalSize += additionalQuota.MaxTotalSize * additionalTariff.Quantity; + currentQuota.Price += additionalQuota.Price * additionalTariff.Quantity; + } + } + } + } + else + { + if (currentQuota.ActiveUsers == -1) + { + currentQuota.ActiveUsers = tariff.Quantity; + currentQuota.MaxTotalSize *= currentQuota.ActiveUsers; + currentQuota.Price *= currentQuota.ActiveUsers; + } } return currentQuota; diff --git a/common/ASC.Core.Common/Core/ITenantService.cs b/common/ASC.Core.Common/Core/ITenantService.cs index 2ec6774ae6..f8616745f2 100644 --- a/common/ASC.Core.Common/Core/ITenantService.cs +++ b/common/ASC.Core.Common/Core/ITenantService.cs @@ -47,5 +47,7 @@ public interface ITenantService void SetTenantSettings(int tenant, string key, byte[] data); IEnumerable GetTenantVersions(); + + bool IsDocspace { get; } } } diff --git a/common/ASC.Core.Common/Data/DbBaseService.cs b/common/ASC.Core.Common/Data/DbBaseService.cs index 292a8edf44..641d34b7d8 100644 --- a/common/ASC.Core.Common/Data/DbBaseService.cs +++ b/common/ASC.Core.Common/Data/DbBaseService.cs @@ -28,6 +28,8 @@ namespace ASC.Core.Data { public abstract class DbBaseService { + public readonly bool IsDocspace; + private readonly string dbid; protected string TenantColumn @@ -40,6 +42,7 @@ protected DbBaseService(ConnectionStringSettings connectionString, string tenant { dbid = connectionString.Name; TenantColumn = tenantColumn; + IsDocspace = connectionString.ConnectionString.Contains("docspace"); } protected T ExecScalar(ISqlInstruction sql) diff --git a/common/ASC.Core.Common/Data/DbLoginEventsManager.cs b/common/ASC.Core.Common/Data/DbLoginEventsManager.cs index 86b878d8fa..5b17b2b67d 100644 --- a/common/ASC.Core.Common/Data/DbLoginEventsManager.cs +++ b/common/ASC.Core.Common/Data/DbLoginEventsManager.cs @@ -85,6 +85,31 @@ public static bool IsActiveLoginEvent(int tenantId, Guid userId, int loginEventI return isActive; } } + + public static BaseEvent GetLoginEvent(int tenantId, int loginEventId) + { + using (var db = GetDbManager()) + { + var query = new SqlQuery("login_events") + .Select("id", "substring_index(ip, ':', 1) ip", "platform", "browser", "date", "user_id") + .Where("tenant_id", tenantId) + .Where("id", loginEventId) + .Where("active", true); + + var loginEvent = db.ExecuteList(query).Select(row => new BaseEvent + { + TenantId = tenantId, + Id = (int)row[0], + IP = (string)row[1], + Platform = (string)row[2], + Browser = (string)row[3], + Date = TenantUtil.DateTimeFromUtc((DateTime)row[4]), + UserId = Guid.Parse((string)row[5]) + }).FirstOrDefault(); + + return loginEvent; + } + } public static List GetLoginEvents(int tenantId, Guid userId) { diff --git a/common/ASC.Core.Common/Data/DbQuotaService.cs b/common/ASC.Core.Common/Data/DbQuotaService.cs index ec6ce1463d..fe2dc0ca3e 100644 --- a/common/ASC.Core.Common/Data/DbQuotaService.cs +++ b/common/ASC.Core.Common/Data/DbQuotaService.cs @@ -19,6 +19,7 @@ using System.Collections.Generic; using System.Configuration; using System.Linq; +using System.Text.RegularExpressions; using ASC.Common.Data.Sql; using ASC.Common.Data.Sql.Expressions; @@ -31,7 +32,6 @@ public class DbQuotaService : DbBaseService, IQuotaService private const string tenants_quota = "tenants_quota"; public const string tenants_quotarow = "tenants_quotarow"; - public DbQuotaService(ConnectionStringSettings connectionString) : base(connectionString, "tenant") { @@ -51,6 +51,8 @@ public TenantQuota GetTenantQuota(int id, bool useCache = false) private IEnumerable GetTenantQuotas(Exp where) { + if (IsDocspace) return GetDocspaceTenantQuotas(where); + var q = new SqlQuery(tenants_quota) .Select("tenant", "name", "max_file_size", "max_total_size", "active_users", "features", "price", "avangate_id", "visible") .Where(where); @@ -69,9 +71,45 @@ private IEnumerable GetTenantQuotas(Exp where) }); } + private IEnumerable GetDocspaceTenantQuotas(Exp where) + { + var q = new SqlQuery(tenants_quota) + .Select("tenant", "name", "features", "price", "product_id", "visible") + .Where(where); + + return ExecList(q) + .ConvertAll(r => + { + var features = (string)r[2]; + var featuresArray = features.Split(','); + var fileSize = GetQuotaFeatureValue(featuresArray, "file_size"); + var totalSize = GetQuotaFeatureValue(featuresArray, "total_size"); + var managers = GetQuotaFeatureValue(featuresArray, "manager"); + + return new TenantQuota(Convert.ToInt32(r[0])) + { + Name = (string)r[1], + MaxFileSize = fileSize == null ? 0 : GetInBytes(Convert.ToInt64(fileSize)), + MaxTotalSize = totalSize == null ? 0 : GetInBytes(Convert.ToInt64(totalSize)), + ActiveUsers = managers == null ? 0 : Convert.ToInt32(managers), + Features = features, + Price = Convert.ToDecimal(r[3]), + AvangateId = (string)r[4], + Visible = Convert.ToBoolean(r[5]), + }; + }); + } + + private string GetQuotaFeatureValue(string[] featuresArray, string featureName) + { + var featureStr = featuresArray.FirstOrDefault(f => f.StartsWith(featureName + ":")); + return featureStr == null ? null : Regex.Match(featureStr, @"\d+").Value; + } public TenantQuota SaveTenantQuota(TenantQuota quota) { + if (IsDocspace) throw new NotImplementedException(); + if (quota == null) throw new ArgumentNullException("quota"); var i = Insert(tenants_quota, quota.Id) @@ -90,6 +128,8 @@ public TenantQuota SaveTenantQuota(TenantQuota quota) public void RemoveTenantQuota(int id) { + if (IsDocspace) throw new NotImplementedException(); + var d = Delete(tenants_quota, id); ExecNonQuery(d); } diff --git a/common/ASC.Core.Common/Data/DbTenantService.cs b/common/ASC.Core.Common/Data/DbTenantService.cs index 8b921e527a..cba4552ceb 100644 --- a/common/ASC.Core.Common/Data/DbTenantService.cs +++ b/common/ASC.Core.Common/Data/DbTenantService.cs @@ -28,7 +28,6 @@ using ASC.Common.Utils; using ASC.Core.Tenants; using ASC.Core.Users; -using ASC.Security.Cryptography; namespace ASC.Core.Data { @@ -37,6 +36,13 @@ public class DbTenantService : DbBaseService, ITenantService private static TimeZoneInfo defaultTimeZone; private List forbiddenDomains; + public new bool IsDocspace + { + get + { + return base.IsDocspace; + } + } public DbTenantService(ConnectionStringSettings connectionString) : base(connectionString, null) @@ -227,19 +233,22 @@ public Tenant SaveTenant(Tenant t) db.ExecuteNonQuery(u); } - if (string.IsNullOrEmpty(t.PartnerId) && string.IsNullOrEmpty(t.AffiliateId) && string.IsNullOrEmpty(t.Campaign)) - { - var d = new SqlDelete("tenants_partners").Where("tenant_id", t.TenantId); - db.ExecuteNonQuery(d); - } - else + if (!IsDocspace) { - var i = new SqlInsert("tenants_partners", true) - .InColumnValue("tenant_id", t.TenantId) - .InColumnValue("partner_id", t.PartnerId) - .InColumnValue("affiliate_id", t.AffiliateId) - .InColumnValue("campaign", t.Campaign); - db.ExecuteNonQuery(i); + if (string.IsNullOrEmpty(t.PartnerId) && string.IsNullOrEmpty(t.AffiliateId) && string.IsNullOrEmpty(t.Campaign)) + { + var d = new SqlDelete("tenants_partners").Where("tenant_id", t.TenantId); + db.ExecuteNonQuery(d); + } + else + { + var i = new SqlInsert("tenants_partners", true) + .InColumnValue("tenant_id", t.TenantId) + .InColumnValue("partner_id", t.PartnerId) + .InColumnValue("affiliate_id", t.AffiliateId) + .InColumnValue("campaign", t.Campaign); + db.ExecuteNonQuery(i); + } } tx.Commit(); @@ -278,7 +287,6 @@ public IEnumerable GetTenantVersions() .ConvertAll(r => new TenantVersion(Convert.ToInt32(r[0]), (string)r[1])); } - public byte[] GetTenantSettings(int tenant, string key) { return ExecScalar(new SqlQuery("core_settings").Select("value").Where("tenant", tenant).Where("id", key)); @@ -298,8 +306,18 @@ private IEnumerable GetTenants(Exp where) return ExecList(q).ConvertAll(ToTenant); } - private static SqlQuery TenantsQuery(Exp where) + private SqlQuery TenantsQuery(Exp where) { + if (IsDocspace) + { + return new SqlQuery("tenants_tenants t") + .Select("t.id", "t.alias", "t.mappeddomain", "t.version", "t.version_changed", "t.name", "t.language", "t.timezone", "t.owner_id") + .Select("t.trusteddomains", "t.trusteddomainsenabled", "t.creationdatetime", "t.status", "t.statuschanged", "t.payment_id", "t.last_modified") + .Select("NULL", "NULL", "NULL") + .Select("t.industry", "t.spam", "t.calls") + .Where(where); + } + return new SqlQuery("tenants_tenants t") .Select("t.id", "t.alias", "t.mappeddomain", "t.version", "t.version_changed", "t.name", "t.language", "t.timezone", "t.owner_id") .Select("t.trusteddomains", "t.trusteddomainsenabled", "t.creationdatetime", "t.status", "t.statuschanged", "t.payment_id", "t.last_modified") diff --git a/common/ASC.Core.Common/Data/DbUserService.cs b/common/ASC.Core.Common/Data/DbUserService.cs index a9691d9fbe..8c50deac32 100644 --- a/common/ASC.Core.Common/Data/DbUserService.cs +++ b/common/ASC.Core.Common/Data/DbUserService.cs @@ -24,6 +24,7 @@ using ASC.Common.Data.Sql.Expressions; using ASC.Core.Tenants; using ASC.Core.Users; +using ASC.MessagingSystem; namespace ASC.Core.Data { @@ -168,8 +169,11 @@ public UserInfo SaveUser(int tenant, UserInfo user) .InColumnValue("sid", user.Sid) .InColumnValue("sso_name_id", user.SsoNameId) .InColumnValue("sso_session_id", user.SsoSessionId) - .InColumnValue("create_on", user.CreateDate) - .InColumnValue("user_lead", user.Lead); + .InColumnValue("create_on", user.CreateDate); + + if (!IsDocspace) { + i.InColumnValue("user_lead", user.Lead); + } db.ExecuteNonQuery(i); @@ -231,9 +235,26 @@ public byte[] GetUserPhoto(int tenant, Guid id) public DateTime GetUserPasswordStamp(int tenant, Guid id) { - var q = Query("core_usersecurity", tenant).Select("LastModified").Where("userid", id.ToString()); - var stamp = ExecScalar(q); - return !string.IsNullOrEmpty(stamp) ? Convert.ToDateTime(stamp) : DateTime.MinValue; + var userId = id.ToString(); + var auditQuery = new SqlQuery("audit_events") + .Select("date") + .Where("tenant_id", tenant) + .Where("action", (int)MessageAction.UserSentPasswordChangeInstructions) + .Where("target", userId) + .OrderBy("id", false) + .SetMaxResults(1); + + var auditValue = ExecScalar(auditQuery); + var auditDate = string.IsNullOrEmpty(auditValue) ? DateTime.MinValue : Convert.ToDateTime(auditValue); + + var securityQuery = Query("core_usersecurity", tenant) + .Select("LastModified") + .Where("userid", userId); + + var securityValue = ExecScalar(securityQuery); + var securityDate = string.IsNullOrEmpty(securityValue) ? DateTime.MinValue : Convert.ToDateTime(securityValue); + + return auditDate.CompareTo(securityDate) > 0 ? auditDate : securityDate; } public void SetUserPasswordHash(int tenant, Guid id, string passwordHash) @@ -350,15 +371,16 @@ public void RemoveUserGroupRef(int tenant, Guid userId, Guid groupId, UserGroupR ExecBatch(i, u); } - private static SqlQuery GetUserQuery() + private SqlQuery GetUserQuery() { return new SqlQuery("core_user u") .Select("u.id", "u.username", "u.firstname", "u.lastname", "u.sex", "u.bithdate", "u.status", "u.title") .Select("u.workfromdate", "u.terminateddate", "u.contacts", "u.email", "u.location", "u.notes", "u.removed") - .Select("u.last_modified", "u.tenant", "u.activation_status", "u.culture", "u.phone", "u.phone_activation", "u.sid", "u.sso_name_id", "u.sso_session_id", "u.create_on", "u.user_lead"); + .Select("u.last_modified", "u.tenant", "u.activation_status", "u.culture", "u.phone", "u.phone_activation", "u.sid", "u.sso_name_id", "u.sso_session_id", "u.create_on") + .Select(IsDocspace ? "NULL" : "u.user_lead"); } - private static SqlQuery GetUserQuery(int tenant, DateTime from) + private SqlQuery GetUserQuery(int tenant, DateTime from) { var q = GetUserQuery(); var where = Exp.Empty; diff --git a/common/ASC.Core.Common/HostedSolution.cs b/common/ASC.Core.Common/HostedSolution.cs index 5362ae7038..03687420f5 100644 --- a/common/ASC.Core.Common/HostedSolution.cs +++ b/common/ASC.Core.Common/HostedSolution.cs @@ -50,6 +50,10 @@ public string DbId private set; } + public bool IsDocspace + { + get { return tenantService.IsDocspace; } + } public HostedSolution(ConnectionStringSettings connectionString) : this(connectionString, null) @@ -216,7 +220,7 @@ public void SetTariff(int tenant, bool paid) var quota = quotaService.GetTenantQuotas().FirstOrDefault(q => paid ? q.NonProfit : q.Trial); if (quota != null) { - tariffService.SetTariff(tenant, new Tariff { QuotaId = quota.Id, DueDate = DateTime.MaxValue, }); + tariffService.SetTariff(tenant, new Tariff { QuotaId = quota.Id, DueDate = DateTime.MaxValue, Quantity = 1 }); } } @@ -235,6 +239,16 @@ public IEnumerable FindUsers(IEnumerable userIds) return userService.GetUsersAllTenants(userIds); } + public UserInfo GetUser(int tenant, string email) + { + return userService.GetUser(tenant, email); + } + + public DateTime GetUserPasswordStamp(int tenant, Guid userId) + { + return userService.GetUserPasswordStamp(tenant, userId); + } + private Tenant AddRegion(Tenant tenant) { if (tenant != null) diff --git a/common/ASC.Core.Common/MultiRegionHostedSolution.cs b/common/ASC.Core.Common/MultiRegionHostedSolution.cs index 975802d417..a343d5eff1 100644 --- a/common/ASC.Core.Common/MultiRegionHostedSolution.cs +++ b/common/ASC.Core.Common/MultiRegionHostedSolution.cs @@ -43,24 +43,24 @@ public MultiRegionHostedSolution(string dbid) this.dbid = dbid; } - public List GetTenants(DateTime from) + public List GetTenants(DateTime from, bool? docspace = null) { - return GetRegionServices() + return GetRegionServices(docspace) .SelectMany(r => r.GetTenants(from)) .ToList(); } - public List FindTenants(string login) + public List FindTenants(string login, bool? docspace = null) { - return FindTenants(login, null); + return FindTenants(login, null, null, docspace); } - public List FindTenants(string login, string password, string passwordHash = null) + public List FindTenants(string login, string password, string passwordHash = null, bool? docspace = null) { var result = new List(); Exception error = null; - foreach (var service in GetRegionServices()) + foreach (var service in GetRegionServices(docspace)) { try { @@ -88,9 +88,9 @@ public void RegisterTenant(string region, TenantRegistrationInfo ri, out Tenant GetRegionService(region).RegisterTenant(ri, out tenant); } - public Tenant GetTenant(string domain) + public Tenant GetTenant(string domain, bool? docspace = null) { - foreach (var service in GetRegionServices()) + foreach (var service in GetRegionServices(docspace)) { var tenant = service.GetTenant(domain); if (tenant != null) @@ -143,41 +143,46 @@ public TenantQuota GetTenantQuota(string region, int tenant) return GetRegionService(region).GetTenantQuota(tenant); } - public void CheckTenantAddress(string address) + public void CheckTenantAddress(string address, bool? docspace = null) { - foreach (var service in GetRegionServices()) + foreach (var service in GetRegionServices(docspace)) { service.CheckTenantAddress(address); } } - public IEnumerable GetRegions() + public IEnumerable GetRegions(bool? docspace = null) { - return GetRegionServices().Select(s => s.Region).ToList(); + return GetRegionServices(docspace).Select(s => s.Region).ToList(); } - public IDbManager GetRegionDb(string region) + public IDbManager GetRegionDb(string region, out bool docspace) { - return new DbManager(GetRegionService(region).DbId); + var hostedSolution = GetRegionService(region); + docspace = hostedSolution.IsDocspace; + return new DbManager(hostedSolution.DbId); } - public IDbManager GetMultiRegionDb() + public IDbManager GetMultiRegionDb(bool? docspace = null) { - return new MultiRegionalDbManager(GetRegions().Select(r => new DbManager(GetRegionService(r).DbId))); + return new MultiRegionalDbManager(GetRegions(docspace).Select(r => new DbManager(GetRegionService(r).DbId))); } - public ConnectionStringSettings GetRegionConnectionString(string region) + public ConnectionStringSettings GetRegionConnectionString(string region, out bool docspace) { - return DbRegistry.GetConnectionString(GetRegionService(region).DbId); + var hostedSolution = GetRegionService(region); + docspace = hostedSolution.IsDocspace; + return DbRegistry.GetConnectionString(hostedSolution.DbId); } - private IEnumerable GetRegionServices() + private IEnumerable GetRegionServices(bool? docspace = null) { Initialize(); return regions.Where(x => !String.IsNullOrEmpty(x.Key)) - .Select(x => x.Value); + .Select(x => x.Value) + .Where(r => docspace.HasValue ? r.IsDocspace == docspace : true); } private HostedSolution GetRegionService(string region) diff --git a/common/ASC.Core.Common/Notify/Senders/SmtpSender.cs b/common/ASC.Core.Common/Notify/Senders/SmtpSender.cs index 29d1e3caa2..f1b65bcded 100644 --- a/common/ASC.Core.Common/Notify/Senders/SmtpSender.cs +++ b/common/ASC.Core.Common/Notify/Senders/SmtpSender.cs @@ -39,8 +39,19 @@ internal class SmtpSender : INotifySender + + + -{0} +{0} "; protected ILog Log { get; private set; } @@ -279,6 +290,10 @@ private MimeMessage BuildMailMessage(NotifyMessage m) protected string GetHtmlView(string body) { + body = body.StartsWith("{0}", body); + return string.Format(HTML_FORMAT, body); } diff --git a/common/ASC.Core.Common/Tenants/TenantUtil.cs b/common/ASC.Core.Common/Tenants/TenantUtil.cs index 7715244786..4a917a0129 100644 --- a/common/ASC.Core.Common/Tenants/TenantUtil.cs +++ b/common/ASC.Core.Common/Tenants/TenantUtil.cs @@ -16,6 +16,7 @@ using System; +using System.Text.RegularExpressions; namespace ASC.Core.Tenants { @@ -30,7 +31,7 @@ public static String GetBaseDomain(string hostedRegion) return baseHost; } var subdomain = baseHost.Remove(baseHost.IndexOf('.') + 1); - return hostedRegion.StartsWith(subdomain) ? hostedRegion : (subdomain + hostedRegion.TrimStart('.')); + return hostedRegion.StartsWith(subdomain) ? hostedRegion : (subdomain + Regex.Replace(hostedRegion.TrimStart('.'), @"\d", "")); } diff --git a/common/ASC.Data.Backup/ASC.Data.Backup.csproj b/common/ASC.Data.Backup/ASC.Data.Backup.csproj index 2b14b45483..7730dcfc5a 100644 --- a/common/ASC.Data.Backup/ASC.Data.Backup.csproj +++ b/common/ASC.Data.Backup/ASC.Data.Backup.csproj @@ -75,6 +75,7 @@ + @@ -98,6 +99,7 @@ + Code @@ -108,6 +110,7 @@ Code + @@ -197,6 +200,9 @@ 8.0.32.1 + + 2020.0.2 + diff --git a/common/ASC.Data.Backup/Service/BackupConfiguration.cs b/common/ASC.Data.Backup/Service/BackupConfiguration.cs index 488c2ddf8a..6938551248 100644 --- a/common/ASC.Data.Backup/Service/BackupConfiguration.cs +++ b/common/ASC.Data.Backup/Service/BackupConfiguration.cs @@ -44,16 +44,6 @@ public int Limit set { this["limit"] = value; } } - [ConfigurationProperty("chunkSize", DefaultValue = 20971520L)] - public long ChunkSize - { - get - { - return long.Parse(this["chunkSize"].ToString()); - } - set { this["chunkSize"] = value; } - } - [ConfigurationProperty("service")] public ServiceConfigurationElement Service { @@ -82,6 +72,13 @@ public WebConfigCollection WebConfigs set { this["webConfigs"] = value; } } + [ConfigurationProperty("mailServer")] + public MailServerConfigurationElement MailServer + { + get { return (MailServerConfigurationElement)this["mailServer"]; } + set { this["mailServer"] = value; } + } + public static BackupConfigurationSection GetSection() { return (BackupConfigurationSection)ConfigurationManagerExtension.GetSection("backup"); @@ -125,6 +122,44 @@ public int WorkerCount } } + public class MailServerConfigurationElement : ConfigurationElement + { + [ConfigurationProperty("pathToMailFilesOnHost", DefaultValue = "")] + public string PathToMailFilesOnHost + { + get { return (string)this["pathToMailFilesOnHost"]; } + set { this["pathToMailFilesOnHost"] = value; } + } + + [ConfigurationProperty("hostAddress", DefaultValue = "")] + public string HostAddress + { + get { return (string)this["hostAddress"]; } + set { this["hostAddress"] = value; } + } + + [ConfigurationProperty("hostUsername", DefaultValue = "")] + public string HostUsername + { + get { return (string)this["hostUsername"]; } + set { this["hostUsername"] = value; } + } + + [ConfigurationProperty("hostPassword", DefaultValue = "")] + public string HostPassword + { + get { return (string)this["hostPassword"]; } + set { this["hostPassword"] = value; } + } + + [ConfigurationProperty("hostKey", DefaultValue = "")] + public string HostKey + { + get { return (string)this["hostKey"]; } + set { this["hostKey"] = value; } + } + } + public class WebConfigCollection : ConfigurationElementCollection { [ConfigurationProperty("current", DefaultValue = "localhost")] diff --git a/common/ASC.Data.Backup/Service/BackupMailServerFilesService.cs b/common/ASC.Data.Backup/Service/BackupMailServerFilesService.cs new file mode 100644 index 0000000000..2949267450 --- /dev/null +++ b/common/ASC.Data.Backup/Service/BackupMailServerFilesService.cs @@ -0,0 +1,319 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using ASC.Common.Logging; +using ASC.Data.Backup.Exceptions; +using ASC.Data.Storage.ZipOperators; + +using Renci.SshNet; + +namespace ASC.Data.Backup.Service +{ + public class BackupMailServerFilesService + { + ///

+ /// State of the mail server connection + /// + public bool IsConnected { get; private set; } + + private SftpClient _sftpClient; + + public static string mailFilesDirectoryInArchiv = "mailServerFiles"; + + private ILog _logger; + + public string pathToMailFilesOnHost; + + private string host; + private string userName; + private string pathToKey; + private string password; + + public BackupMailServerFilesService(ILog Logger) + { + var config = BackupConfigurationSection.GetSection(); + + _logger = Logger; + + host = config.MailServer.HostAddress; + userName = config.MailServer.HostUsername; + pathToKey = config.MailServer.HostKey; + password = config.MailServer.HostPassword; + pathToMailFilesOnHost = config.MailServer.PathToMailFilesOnHost; + + _logger.Debug($"BackupMailServerFilesService: Host = {host}, UserName={userName}, password={password}, pathToKey={pathToKey}, pathToMailFilesOnHost={pathToMailFilesOnHost}."); + + if (string.IsNullOrEmpty(host) + || string.IsNullOrEmpty(userName)) + { + _logger.Debug("MailServerHostAddress and MailServerHostUsername don't have values."); + + IsConnected = false; + + return; + } + + IsConnected = Connect(); + } + + /// + /// Connect to Mail Server + /// + /// True if connect establish, False if not. + public bool Connect() + { + try + { + var methods = new List(); + + if (!string.IsNullOrEmpty(pathToKey)) + { + PrivateKeyFile keyFile = new PrivateKeyFile(pathToKey); + var keyFiles = new[] { keyFile }; + + methods.Add(new PrivateKeyAuthenticationMethod(userName, keyFiles)); + } + + if (!string.IsNullOrEmpty(password)) + { + methods.Add(new PasswordAuthenticationMethod(userName, password)); + }; + + if (methods.Count == 0) + { + _logger.Debug($"BackupMailServerFilesService didn`t connect, becouse pathToKey and password are empty."); + } + + ConnectionInfo con = new ConnectionInfo(host, 22, userName, methods.ToArray()); + + _sftpClient = new SftpClient(con); + _sftpClient.Connect(); + } + catch (Exception ex) + { + _logger.Debug($"BackupMailServerFilesService didn`t connect, becouse: {ex}"); + } + + return _sftpClient.IsConnected; + } + + /// + /// Download single file from the mail server and return the path to file on the local temp directory + /// + /// + /// + public string GetSingleFile(string pathRemoteFile) + { + if (!IsConnected) return ""; + + string result = TempPath.GetTempFileName(); + + using (Stream fileStream = System.IO.File.OpenWrite(result)) + { + _sftpClient.DownloadFile(pathRemoteFile, fileStream); + } + + return result; + } + + /// + /// Get List of files pathes on the mail server directory, if connection establish + /// + /// + /// + public string[] GetFilesList(string remoteDirectory) + { + if (!IsConnected) return new string[0]; + + var files = _sftpClient.ListDirectory(remoteDirectory); + + return files.Where(x => !x.IsDirectory).Select(f => f.Name).ToArray(); + } + + /// + /// Get List of directories on the mail server directory, if connection establish + /// + /// + /// + /// + public string[] GetDirectoryList(string remoteDirectory) + { + string[] result = new string[0]; + + if (!IsConnected) return result; + + try + { + var files = _sftpClient.ListDirectory(remoteDirectory); + + result = files.Where(x => x.IsDirectory) + .Select(f => f.Name) + .ToArray(); + } + catch (Exception ex) + { + _logger.Debug($"Get Directory List error. Path={remoteDirectory}.{ex.Message}"); + } + + return result; + } + + /// + /// Recursively download and save by fileSaver action the directory from the mail server + /// + /// Directory on the mail server + /// Action for save file + /// Count of saved files + public int SaveDirectory(string path, Action fileSaver) + { + var result = 0; + + if (!IsConnected) return result; + + _logger.Debug($"Save Directory {path} start."); + + var files = GetFilesList(path); + + foreach (var file in files) + { + var filePath = path + '/' + file; + + try + { + _logger.Debug($"Try save file {filePath}."); + + using (Stream fileStream = new MemoryStream()) + { + _sftpClient.DownloadFile(filePath, fileStream); + + fileSaver(mailFilesDirectoryInArchiv + filePath, fileStream); + + result++; + } + + } + catch (Exception ex) + { + _logger.Error($"Save file {filePath} error. {ex.Message}"); + } + } + + var directorys = GetDirectoryList(path); + + foreach (var directory in directorys) + { + if (directory == ".." || directory == ".") continue; + + result += SaveDirectory(path + '/' + directory, fileSaver); + } + + _logger.Debug($"Upload Directory {path} ended. {result} files was saved."); + + return result; + } + + /// + /// Upload the directory to the mail server + /// + /// + /// Count of uploaded files + public int UploadMailDirectory(IDataReadOperator dataReader) + { + _logger.Debug($"Upload Mail Directory started."); + + return UploadDirectory(mailFilesDirectoryInArchiv + pathToMailFilesOnHost, dataReader); + } + /// + /// Upload the directory to the mail server + /// + /// + /// + /// Count of uploaded files + public int UploadDirectory(string path, IDataReadOperator dataReader) + { + var result = 0; + + if (!IsConnected) return result; + + _logger.Debug($"Upload Directory {path} start."); + + try + { + var abloluteFolderName = path.Substring(path.IndexOf(pathToMailFilesOnHost)); + + if(_sftpClient.Exists(abloluteFolderName)) + { + _logger.Debug($"UploadDirectory: directory {abloluteFolderName} existed."); + } + else + { + _sftpClient.CreateDirectory(abloluteFolderName); + _sftpClient.ChangePermissions(abloluteFolderName, 777); + + _logger.Debug($"UploadDirectory: directory {abloluteFolderName} created."); + } + + var directories = dataReader.GetDirectories(path); + + foreach (var directory in directories) + { + try + { + result += UploadDirectory(directory, dataReader); + } + catch (Exception ex) + { + _logger.Error($"Upload Directory: upload directory {directory} exception: {ex.Message}"); + } + } + + var files = dataReader.GetEntries(path); + + foreach (var file in files) + { + try + { + var destinationName = file.Substring(file.IndexOf(pathToMailFilesOnHost)); + + _logger.Debug($"Upload Directory: Begin start copy file {mailFilesDirectoryInArchiv + destinationName}"); + + using (var streamData = dataReader.GetEntry(mailFilesDirectoryInArchiv + destinationName)) + { + if (streamData == null) + { + _logger.Debug($"Upload Directory: File didn't found: {file}"); + + continue; + } + + _logger.Debug($"Upload Directory: place {streamData.Length} bytes file to {destinationName}"); + + using (var remoteFile = _sftpClient.Create(destinationName)) + { + streamData.CopyTo(remoteFile); + } + + _sftpClient.ChangePermissions(destinationName, 777); + } + + result++; + } + catch (Exception ex) + { + _logger.Error($"UploadDirectory: upload file {file} exception: {ex.Message}"); + } + } + } + catch (Exception ex) + { + _logger.Error($"UploadDirectory exception: {ex.Message}"); + } + + _logger.Debug($"Upload Directory {path} stop. {result} files upload."); + + return result; + } + } +} diff --git a/common/ASC.Data.Backup/Service/BackupService.cs b/common/ASC.Data.Backup/Service/BackupService.cs index 0c1da9d43c..365d7eddf4 100644 --- a/common/ASC.Data.Backup/Service/BackupService.cs +++ b/common/ASC.Data.Backup/Service/BackupService.cs @@ -34,6 +34,8 @@ internal class BackupService : IBackupService, IHealthCheckService public BackupProgress StartBackup(StartBackupRequest request) { + BackupStorageFactory.CheckBackupStorage(request); + var progress = BackupWorker.StartBackup(request); if (!string.IsNullOrEmpty(progress.Error)) { @@ -199,6 +201,8 @@ public List GetTransferRegions() public void CreateSchedule(CreateScheduleRequest request) { + BackupStorageFactory.CheckBackupStorage(request); + BackupStorageFactory.GetBackupRepository().SaveBackupSchedule( new Schedule(request.TenantId) { diff --git a/common/ASC.Data.Backup/Service/BackupWorker.cs b/common/ASC.Data.Backup/Service/BackupWorker.cs index ed816622ab..6aa986bd9b 100644 --- a/common/ASC.Data.Backup/Service/BackupWorker.cs +++ b/common/ASC.Data.Backup/Service/BackupWorker.cs @@ -66,8 +66,6 @@ public static void Start(BackupConfigurationSection config) configPaths = config.WebConfigs.Cast().ToDictionary(el => el.Region, el => PathHelper.ToRootedConfigPath(el.Path)); configPaths[currentRegion] = PathHelper.ToRootedConfigPath(config.WebConfigs.CurrentPath); - SetupInfo.ChunkUploadSize = config.ChunkSize; - var invalidConfigPath = configPaths.Values.FirstOrDefault(path => !File.Exists(path)); if (invalidConfigPath != null) { @@ -431,6 +429,9 @@ public void RunJob() Percentage = 10; tenant = CoreContext.TenantManager.GetTenant(TenantId); + + Log.Debug($"RestoreProgressItem, RunJob for Tenant={tenant?.TenantId} "); + tenant.SetStatus(TenantStatus.Restoring); CoreContext.TenantManager.SaveTenant(tenant); @@ -484,7 +485,7 @@ public void RunJob() } catch (Exception error) { - Log.Error(error); + Log.Error(error.Message); Error = error; if (tenant != null) diff --git a/common/ASC.Data.Backup/Storage/BackupStorageFactory.cs b/common/ASC.Data.Backup/Storage/BackupStorageFactory.cs index a203f6e92a..641a21ac4c 100644 --- a/common/ASC.Data.Backup/Storage/BackupStorageFactory.cs +++ b/common/ASC.Data.Backup/Storage/BackupStorageFactory.cs @@ -63,6 +63,37 @@ public static IBackupStorage GetBackupStorage(BackupStorageType type, int tenant } } + public static void CheckBackupStorage(StartBackupRequest backupRequest) + { + if (backupRequest == null) + { + throw new ArgumentNullException("backupRequest"); + } + + if (backupRequest.StorageType != BackupStorageType.Documents && + backupRequest.StorageType != BackupStorageType.ThridpartyDocuments) + { + return; + } + + CoreContext.TenantManager.SetCurrentTenant(backupRequest.TenantId); + + using (var folderDao = Web.Files.Classes.Global.DaoFactory.GetFolderDao()) + { + var folder = folderDao.GetFolder(backupRequest.StorageBasePath); + + if (folder == null) + { + throw new System.IO.DirectoryNotFoundException("Folder not found."); + } + + if (folder.RootFolderType != Files.Core.FolderType.COMMON) + { + throw new NotSupportedException("Root folder type is not supported."); + } + } + } + public static IBackupRepository GetBackupRepository() { return new BackupRepository(); diff --git a/common/ASC.Data.Backup/Tasks/BackupPortalTask.cs b/common/ASC.Data.Backup/Tasks/BackupPortalTask.cs index 0d69b0b8a3..ba36738391 100644 --- a/common/ASC.Data.Backup/Tasks/BackupPortalTask.cs +++ b/common/ASC.Data.Backup/Tasks/BackupPortalTask.cs @@ -34,6 +34,7 @@ using ASC.Core; using ASC.Data.Backup.Exceptions; using ASC.Data.Backup.Extensions; +using ASC.Data.Backup.Service; using ASC.Data.Backup.Tasks.Data; using ASC.Data.Backup.Tasks.Modules; using ASC.Data.Storage; @@ -47,6 +48,7 @@ public class BackupPortalTask : PortalTaskBase { private const int MaxLength = 250; private const int BatchLimit = 5000; + private readonly BackupMailServerFilesService backupMailServerFilesService; public string BackupFilePath { get; private set; } public int Limit { get; private set; } private bool Dump { get; set; } @@ -60,6 +62,8 @@ public BackupPortalTask(ILog logger, int tenantId, string fromConfigPath, string BackupFilePath = toFilePath; Limit = limit; Dump = CoreContext.Configuration.Standalone; + + backupMailServerFilesService = new BackupMailServerFilesService(Logger); } public override void RunJob() @@ -84,6 +88,15 @@ public override void RunJob() { DoBackupModule(WriteOperator, dbFactory, module); } + if (!IgnoredModules.Contains(ModuleName.Mail)) + { + var paths = DoBackupMailTable(WriteOperator); + + if (paths.Count != 0) + { + DoBackupMailFiles(WriteOperator, paths); + } + } if (ProcessStorage) { DoBackupStorage(WriteOperator, fileGroups); @@ -96,27 +109,29 @@ public override void RunJob() private void DoDump(IDataWriteOperator writer) { Dictionary> databases = new Dictionary>(); - using (var dbManager = new DbManager("default", 100000)) + if (!IgnoredModules.Contains(ModuleName.Mail)) { - dbManager.ExecuteList("select id, connection_string from mail_server_server").ForEach(r => + using (var dbManager = new DbManager("default", 100000)) { - var dbName = GetDbName((int)r[0], JsonConvert.DeserializeObject>(Convert.ToString(r[1]))["DbConnection"].ToString()); - using (var dbManager1 = new DbManager(dbName, 100000)) + dbManager.ExecuteList("select id, connection_string from mail_server_server").ForEach(r => { - try + var dbName = GetDbName((int)r[0], JsonConvert.DeserializeObject>(Convert.ToString(r[1]))["DbConnection"].ToString()); + using (var dbManager1 = new DbManager(dbName, 100000)) { - var tables = dbManager1.ExecuteList("show tables;").Select(res => Convert.ToString(res[0])).ToList(); - databases.Add(dbName, tables); - } - catch (Exception e) - { - Logger.Error(e); - DbRegistry.UnRegisterDatabase(dbName); + try + { + var tables = dbManager1.ExecuteList("show tables;").Select(res => Convert.ToString(res[0])).ToList(); + databases.Add(dbName, tables); + } + catch (Exception e) + { + Logger.Error(e); + DbRegistry.UnRegisterDatabase(dbName); + } } - } - }); + }); + } } - using (var dbManager = new DbManager("default", 100000)) { var tables = dbManager.ExecuteList("show tables;").Select(res => Convert.ToString(res[0])).ToList(); @@ -684,6 +699,164 @@ private void DoBackupModule(IDataWriteOperator writer, DbFactory dbFactory, IMod Logger.DebugFormat("end saving data for module {0}", module.ModuleName); } + private List DoBackupMailTable(IDataWriteOperator writer) + { + Logger.DebugFormat("begin saving data for MailTable"); + + List result = new List(); + + string dbconnection = null; + var module = new MailTableSpecifics(); + + using (var dbManager = new DbManager("default", 100000)) + { + dbManager.ExecuteList("select connection_string from mail_server_server").ForEach(r => + { + dbconnection = JsonConvert.DeserializeObject>(Convert.ToString(r[0]))["DbConnection"].ToString() + "; convert zero datetime=True"; + + Logger.Debug($"DoBackupMailTable: dbconnection: {dbconnection}."); + }); + + dbManager.ExecuteList($"SELECT name FROM mail_server_domain WHERE tenant={TenantId} AND is_verified=1").ForEach(r => + { + var findedDomain = Convert.ToString(r[0]); + + var findedReverseDomain = string.Join(".", findedDomain.Split('.').Reverse().ToArray()); + + module.findValues["domain"].Add($"'{findedDomain}'"); + + module.findValues["reversedomain"].Add($"'{findedReverseDomain}'"); + + Logger.Debug($"DoBackupMailTable: find domain: {findedDomain}, findedReverseDomain: {findedReverseDomain}."); + }); + } + + if (dbconnection == null) + { + Logger.Debug("DoBackupMailTable: mail_server_server have not connection_string."); + return result; + } + + if (module.findValues["domain"].Count == 0) + { + Logger.Debug($"DoBackupMailTable: TenantId {TenantId} hasn`t any custom domain."); + return result; + } + + var dbFactory = new DbFactory(ConfigPath) { ConnectionStringSettings = new ConnectionStringSettings("mailTable", dbconnection, "MySql.Data.MySqlClient") }; + + using (var connection = dbFactory.OpenConnection()) + { + foreach (var table in module.Tables) + { + Logger.DebugFormat("begin load table {0}", table.Name); + using (var data = new DataTable(table.Name)) + { + ActionInvoker.Try( + state => + { + data.Clear(); + int counts; + var offset = 0; + do + { + var t = (MailTableInfo)state; + var dataAdapter = dbFactory.CreateDataAdapter(); + dataAdapter.SelectCommand = module.CreateSelectCommand(connection.Fix(), t, Limit, offset).WithTimeout(600); + Logger.Debug($"DoBackupMailTable SelectCommand is {dataAdapter.SelectCommand.CommandText}"); + counts = ((DbDataAdapter)dataAdapter).Fill(data); + offset += Limit; + } while (counts == Limit); + + }, + table, + maxAttempts: 5, + onFailure: error => { throw ThrowHelper.CantBackupTable(table.Name, error); }, + onAttemptFailure: error => Logger.Warn("backup attempt failure: {0}", error)); + + foreach (var col in data.Columns.Cast().Where(col => col.DataType == typeof(DateTime))) + { + col.DateTimeMode = DataSetDateTime.Unspecified; + } + + Logger.DebugFormat("end load table {0}", table.Name); + + Logger.DebugFormat("begin saving table {0}", table.Name); + + if (data.TableName == "maddr") + { + foreach (DataRow row in data.Rows) + { + module.findValues["id"].Add(row["id"]); + + var bytes = row["email"] as byte[]; + + var sb = new StringBuilder(); + sb.Append("0x"); + foreach (var b in bytes) + sb.AppendFormat("{0:x2}", b); + + module.findValues["email"].Add(sb.ToString()); + + Logger.Debug($"DoBackupMailTable: In maddr finded email: {sb}."); + } + } + + if (data.TableName == "mailbox") + { + foreach (DataRow row in data.Rows) + { + var storagenode = Convert.ToString(row["storagenode"]); + var maildir = Convert.ToString(row["maildir"]); + + var sb = new StringBuilder(); + sb.Append(backupMailServerFilesService.pathToMailFilesOnHost); + + sb.Append('/'); + + sb.AppendFormat(storagenode); + + sb.Append('/'); + + sb.AppendFormat(maildir); + + result.Add(sb.ToString()); + + Logger.Debug($"DoBackupMailTable: In mailbox finded path: {sb}."); + } + } + + using (var file = TempStream.Create()) + { + data.WriteXml(file, XmlWriteMode.WriteSchema); + data.Clear(); + + writer.WriteEntry(KeyHelper.GetMailTableZipKey(data.TableName), file); + } + + Logger.DebugFormat("end saving table {0}", table.Name); + } + } + } + Logger.DebugFormat("end saving data for MailTable"); + + return result; + } + + private void DoBackupMailFiles(IDataWriteOperator writer, List paths) + { + Logger.DebugFormat("begin saving files for Mail Server"); + + int filesCount = 0; + + foreach (string path in paths) + { + filesCount += backupMailServerFilesService.SaveDirectory(path, writer.WriteEntry); + } + + Logger.DebugFormat($"end saving {filesCount} files for Mail Server"); + } + private void DoBackupStorage(IDataWriteOperator writer, List> fileGroups) { Logger.Debug("begin backup storage"); @@ -703,7 +876,7 @@ private void DoBackupStorage(IDataWriteOperator writer, List Logger.WarnFormat("can't backup file ({0}:{1}): {2}", file1.Module, file1.Path, error)); - if (fileStream != null) + if (fileStream != null) { writer.WriteEntry(file1.GetZipKey(), fileStream); fileStream.Dispose(); diff --git a/common/ASC.Data.Backup/Tasks/DbFactory.cs b/common/ASC.Data.Backup/Tasks/DbFactory.cs index f942af26ee..65252a4ccc 100644 --- a/common/ASC.Data.Backup/Tasks/DbFactory.cs +++ b/common/ASC.Data.Backup/Tasks/DbFactory.cs @@ -38,7 +38,7 @@ public class DbFactory private ConnectionStringSettings connectionStringSettings; private DbProviderFactory dbProviderFactory; - internal ConnectionStringSettings ConnectionStringSettings + public ConnectionStringSettings ConnectionStringSettings { get { @@ -49,6 +49,10 @@ internal ConnectionStringSettings ConnectionStringSettings } return connectionStringSettings; } + set + { + connectionStringSettings = value; + } } private DbProviderFactory DbProviderFactory diff --git a/common/ASC.Data.Backup/Tasks/KeyHelper.cs b/common/ASC.Data.Backup/Tasks/KeyHelper.cs index fd3c1a7035..62c3d13343 100644 --- a/common/ASC.Data.Backup/Tasks/KeyHelper.cs +++ b/common/ASC.Data.Backup/Tasks/KeyHelper.cs @@ -68,5 +68,10 @@ public static string GetStorageRestoreInfoZipKey() { return string.Format("{0}/restore_info", GetStorage()); } + + public static string GetMailTableZipKey(string tableName) + { + return string.Format("mailtable/{0}", tableName); + } } } diff --git a/common/ASC.Data.Backup/Tasks/Modules/MailModuleSpecifics.cs b/common/ASC.Data.Backup/Tasks/Modules/MailModuleSpecifics.cs index cad4834c81..c2db020fdf 100644 --- a/common/ASC.Data.Backup/Tasks/Modules/MailModuleSpecifics.cs +++ b/common/ASC.Data.Backup/Tasks/Modules/MailModuleSpecifics.cs @@ -50,44 +50,74 @@ internal class MailModuleSpecifics : ModuleSpecificsBase UserIDColumns = new[] {"id_user"}, DateColumns = new Dictionary {{"begin_date", false}} }, + new TableInfo("mail_mailbox_server", idColumn: "id"), + new TableInfo("mail_mailbox_provider", idColumn: "id"), + new TableInfo("mail_mailbox_domain", idColumn: "id"), + + new TableInfo("mail_server_dns", "tenant", "id") {UserIDColumns = new[] {"id_user"}}, + new TableInfo("mail_server_domain", "tenant", "id"), + new TableInfo("mail_server_address", "tenant", "id"), + new TableInfo("mail_server_mail_group", "id_tenant"), + new TableInfo("mail_tag", "tenant", "id") {UserIDColumns = new[] {"id_user"}}, new TableInfo("mail_tag_addresses", "tenant"), new TableInfo("mail_tag_mail", "tenant") {UserIDColumns = new[] {"id_user"}}, new TableInfo("mail_chain_x_crm_entity", "id_tenant"), new TableInfo("mail_mailbox_signature", "tenant"), - new TableInfo("mail_mailbox_autoreply", "tenant"), + new TableInfo("mail_mailbox_autoreply", "tenant") {InsertMethod = InsertMethod.Ignore}, new TableInfo("mail_mailbox_autoreply_history", "tenant"), new TableInfo("mail_contact_info", "tenant", "id") {UserIDColumns = new[] {"id_user"}}, - new TableInfo("mail_mailbox_provider", idColumn: "id"), - new TableInfo("mail_mailbox_domain", idColumn: "id"), - new TableInfo("mail_mailbox_server", idColumn: "id") + + new TableInfo("mail_filter", "tenant", "id") {UserIDColumns = new[] {"id_user"}}, + new TableInfo("mail_folder", "tenant", "id") {UserIDColumns = new[] {"id_user"}}, + new TableInfo("mail_user_folder", "tenant", "id") {UserIDColumns = new[] {"id_user"}}, + new TableInfo("mail_user_folder_x_mail", "tenant") {UserIDColumns = new[] {"id_user"}} }; private readonly RelationInfo[] _tableRelations = new[] { + new RelationInfo("mail_user_folder", "id", "mail_user_folder", "parent_id"), new RelationInfo("mail_mail", "id", "mail_attachment", "id_mail"), + new RelationInfo("mail_mail", "id", "mail_user_folder_x_mail", "id_mail"), + new RelationInfo("mail_mail", "id", "mail_tag_mail", "id_mail"), + new RelationInfo("mail_mailbox", "id", "mail_mail", "id_mailbox"), new RelationInfo("mail_mailbox", "id", "mail_chain", "id_mailbox"), + new RelationInfo("mail_mailbox", "id", "mail_chain_x_crm_entity", "id_mailbox"), + new RelationInfo("mail_mailbox", "id", "mail_mailbox_autoreply", "id_mailbox"), + new RelationInfo("mail_mailbox", "id", "mail_mailbox_autoreply_history", "id_mailbox"), + new RelationInfo("mail_mailbox", "id", "mail_server_address", "id_mailbox"), + new RelationInfo("mail_mailbox", "id", "mail_mailbox_signature", "id_mailbox"), + + new RelationInfo("mail_mailbox_server", "id", "mail_mailbox", "id_smtp_server"), + new RelationInfo("mail_mailbox_server", "id", "mail_mailbox", "id_in_server"), + + new RelationInfo("mail_mailbox_provider", "id", "mail_mailbox_server", "id_provider"), + new RelationInfo("mail_mailbox_provider", "id", "mail_mailbox_domain", "id_provider"), + + new RelationInfo("mail_server_domain", "id", "mail_server_dns", "id_domain"), + new RelationInfo("mail_server_domain", "id", "mail_server_address", "id_domain"), + new RelationInfo("mail_server_address", "id", "mail_server_mail_group", "id_address"), + + //new RelationInfo("mail_user_folder", "id", "mail_user_folder_tree", "folder_id"), + //new RelationInfo("mail_user_folder", "id", "mail_user_folder_tree", "parent_id"), + new RelationInfo("mail_tag", "id", "mail_chain", "tags"), new RelationInfo("crm_tag", "id", "mail_chain", "tags", typeof(CrmModuleSpecifics)), - new RelationInfo("mail_mailbox", "id", "mail_mail", "id_mailbox"), + new RelationInfo("crm_tag", "id", "mail_tag", "crm_id", typeof(CrmModuleSpecifics)), new RelationInfo("mail_tag", "id", "mail_tag_addresses", "id_tag", x => Convert.ToInt32(x["id_tag"]) > 0), new RelationInfo("crm_tag", "id", "mail_tag_addresses", "id_tag", typeof(CrmModuleSpecifics), x => Convert.ToInt32(x["id_tag"]) < 0), - new RelationInfo("mail_mail", "id", "mail_tag_mail", "id_mail"), new RelationInfo("mail_tag", "id", "mail_tag_mail", "id_tag", x => Convert.ToInt32(x["id_tag"]) > 0), new RelationInfo("crm_tag", "id", "mail_tag_mail", "id_tag", typeof(CrmModuleSpecifics), x => Convert.ToInt32(x["id_tag"]) < 0), - new RelationInfo("mail_mailbox", "id", "mail_chain_x_crm_entity", "id_mailbox"), new RelationInfo("crm_contact", "id", "mail_chain_x_crm_entity", "entity_id", typeof(CrmModuleSpecifics), x => Convert.ToInt32(x["entity_type"]) == 1), new RelationInfo("crm_case", "id", "mail_chain_x_crm_entity", "entity_id", typeof(CrmModuleSpecifics), x => Convert.ToInt32(x["entity_type"]) == 2), new RelationInfo("crm_deal", "id", "mail_chain_x_crm_entity", "entity_id", typeof(CrmModuleSpecifics), x => Convert.ToInt32(x["entity_type"]) == 3), - new RelationInfo("mail_mailbox", "id", "mail_mailbox_signature", "id_mailbox"), + new RelationInfo("files_folder", "id", "mail_mailbox", "email_in_folder", typeof(FilesModuleSpecifics)), - new RelationInfo("mail_mailbox", "id", "mail_mailbox_autoreply", "id_mailbox"), - new RelationInfo("mail_mailbox", "id", "mail_mailbox_autoreply_history", "id_mailbox"), + new RelationInfo("mail_contacts", "id", "mail_contact_info", "id_contact"), - new RelationInfo("mail_mailbox_provider", "id", "mail_mailbox_domain", "id_provider"), - new RelationInfo("mail_mailbox_server", "id", "mail_mailbox", "id_smtp_server"), - new RelationInfo("mail_mailbox_server", "id", "mail_mailbox", "id_in_server") + + new RelationInfo("mail_user_folder", "id", "mail_user_folder_x_mail", "id_folder") }; public override ModuleName ModuleName @@ -113,20 +143,20 @@ protected override string GetSelectCommandConditionText(int tenantId, TableInfo case "mail_mailbox_provider": return string.Format("where t.id in " + "(select distinct t2.id_provider from mail_mailbox t1 " + - "inner join mail_mailbox_server t2 on t2.id in (t1.id_in_server, t1.id_smtp_server) and t2.is_user_data = 1 " + + "inner join mail_mailbox_server t2 on t2.id in (t1.id_in_server, t1.id_smtp_server) " + "where t1.tenant = {0} and t1.is_removed = 0)", tenantId); // mail_mailbox_domain.id_provider not in index case "mail_mailbox_domain": return string.Format("where t.id_provider in " + "(select distinct t2.id_provider from mail_mailbox t1 " + - "inner join mail_mailbox_server t2 on t2.id in (t1.id_in_server, t1.id_smtp_server) and t2.is_user_data = 1 " + + "inner join mail_mailbox_server t2 on t2.id in (t1.id_in_server, t1.id_smtp_server) " + "where t1.tenant = {0} and t1.is_removed = 0)", tenantId); case "mail_mailbox_server": return string.Format("where t.id in " + "(select distinct t2.id from mail_mailbox t1 " + - "inner join mail_mailbox_server t2 on t2.id in (t1.id_in_server, t1.id_smtp_server) and t2.is_user_data = 1 " + + "inner join mail_mailbox_server t2 on t2.id in (t1.id_in_server, t1.id_smtp_server) " + "where t1.tenant = {0} and t1.is_removed = 0)", tenantId); case "mail_mailbox": @@ -172,15 +202,15 @@ public override bool TryAdjustFilePath(bool dump, ColumnMapper columnMapper, ref protected override bool TryPrepareRow(bool dump, DbConnection connection, ColumnMapper columnMapper, TableInfo table, DataRowInfo row, out Dictionary preparedRow) { - if (table.Name == "mail_mailbox") - { - var boxType = row["is_server_mailbox"]; - if (boxType != null && Convert.ToBoolean(int.Parse(boxType.ToString()))) - { - preparedRow = null; - return false; - } - } + //if (table.Name == "mail_mailbox") + //{ + // var boxType = row["is_server_mailbox"]; + // if (boxType != null && !Convert.ToBoolean(int.Parse(boxType.ToString()))) + // { + // preparedRow = null; + // return false; + // } + //} return base.TryPrepareRow(dump, connection, columnMapper, table, row, out preparedRow); } diff --git a/common/ASC.Data.Backup/Tasks/Modules/MailTableSpecifics.cs b/common/ASC.Data.Backup/Tasks/Modules/MailTableSpecifics.cs new file mode 100644 index 0000000000..881171ed65 --- /dev/null +++ b/common/ASC.Data.Backup/Tasks/Modules/MailTableSpecifics.cs @@ -0,0 +1,115 @@ +using System.Collections.Generic; +using System.Data.Common; +using System.Linq; + +using ASC.Common.Data; +using ASC.Data.Backup.Tasks.Data; + +namespace ASC.Data.Backup.Tasks.Modules +{ + internal class MailTableSpecifics + { + public Dictionary> findValues = new Dictionary>() + { + { + "domain", new List() + }, + { + "id", new List() + }, + { + "email", new List() + }, + { + "reversedomain", new List() + }, + }; + + private readonly MailTableInfo[] _tables = new[] + { + new MailTableInfo("maddr", "domain", "reversedomain"), + new MailTableInfo("dkim", "domain_name", "domain"), + new MailTableInfo("domain", "domain"), + + new MailTableInfo("mailbox", "username", "email"), + new MailTableInfo("alias", "address", "email"), + new MailTableInfo("used_quota", "username", "email"), + + new MailTableInfo("msgs", "sid", "id"), + new MailTableInfo("msgrcpt", "rid", "id"), + + new MailTableInfo("bayes_seen"), + new MailTableInfo("bayes_token") + }; + + public IEnumerable Tables => _tables; + + public DbCommand CreateSelectCommand(DbConnection connection, MailTableInfo table, int limit, int offset) + { + return connection.CreateCommand(string.Format("select t.* from {0} as t {1} limit {2},{3};", table.Name, GetSelectCommandConditionText(table), offset, limit)); + } + + protected string GetSelectCommandConditionText(MailTableInfo table) + { + return table.existFindColumn ? string.Format("where t.{0} in ({1})", table.FindColumn, string.Join(",", findValues[table.FindColumnKey])) : string.Empty; + } + + + public DbCommand CreateInsertCommand(DbConnection connection, MailTableInfo table, DataRowInfo row) + { + Dictionary valuesForInsert; + if (!TryPrepareRow(connection, table, row, out valuesForInsert)) + return null; + + var columns = valuesForInsert.Keys.Intersect(table.Columns).ToArray(); + + var insertCommantText = string.Format("{0} into {1}({2}) values({3});", + "insert ignore", + table.Name, + string.Join(",", columns.Select(c =>$"`{c}`")), + string.Join(",", columns.Select(c =>$"@{c}".Replace('-','_')))); + + var command = connection.CreateCommand(insertCommantText); + foreach (var parameter in valuesForInsert) + { + command.AddParameter(parameter.Key.Replace('-', '_'), parameter.Value); + } + return command; + } + + protected virtual bool TryPrepareRow(DbConnection connection, MailTableInfo table, DataRowInfo row, out Dictionary preparedRow) + { + preparedRow = new Dictionary(); + + foreach (var columnName in row.ColumnNames) + { + preparedRow.Add(columnName, row[columnName]); + } + + return true; + } + } + + internal class MailTableInfo + { + public string Name { get; private set; } + public string[] Columns { get; set; } + public string FindColumn { get; private set; } + public string FindColumnKey { get; private set; } + public bool existFindColumn { get; private set; } + + public MailTableInfo(string name) + { + Name = name; + existFindColumn = false; + } + + public MailTableInfo(string name, string findColumn, string findColumnKey = null) + { + Name = name; + FindColumn = findColumn; + FindColumnKey = findColumnKey ?? findColumn; + existFindColumn = true; + } + } +} diff --git a/common/ASC.Data.Backup/Tasks/RestoreMailTableTask.cs b/common/ASC.Data.Backup/Tasks/RestoreMailTableTask.cs new file mode 100644 index 0000000000..4a095753cc --- /dev/null +++ b/common/ASC.Data.Backup/Tasks/RestoreMailTableTask.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data.Common; +using System.IO; +using System.Linq; + +using ASC.Common.Data; +using ASC.Common.Logging; +using ASC.Data.Backup.Exceptions; +using ASC.Data.Backup.Extensions; +using ASC.Data.Backup.Service; +using ASC.Data.Backup.Tasks.Data; +using ASC.Data.Backup.Tasks.Modules; +using ASC.Data.Storage.ZipOperators; + +namespace ASC.Data.Backup.Tasks +{ + internal class RestoreMailTableTask + { + private const int TransactionLength = 10000; + + private readonly ILog _logger; + private readonly IDataReadOperator _dataReader; + private readonly MailTableSpecifics _module; + private readonly DbFactory _factory; + + private readonly string[] tableCreateScripts = new string[] { "CREATE TABLE IF NOT EXISTS `dkim` (`id` int unsigned NOT NULL AUTO_INCREMENT, `domain_name` varchar(255) CHARACTER SET latin1 NOT NULL, `selector` varchar(63) NOT NULL, `private_key` text CHARACTER SET latin1, `public_key` text CHARACTER SET latin1, PRIMARY KEY (`id`), KEY `domain_name` (`domain_name`)) ENGINE=InnoDB AUTO_INCREMENT=169 DEFAULT CHARSET=utf8mb3;", + "CREATE TABLE `bayes_seen` ( `id` int NOT NULL DEFAULT '0', `msgid` varchar(200) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '', `flag` char(1) NOT NULL DEFAULT '', PRIMARY KEY (`id`,`msgid`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;", + "CREATE TABLE `bayes_token` ( `id` int NOT NULL DEFAULT '0', `token` char(5) NOT NULL DEFAULT '', `spam_count` int NOT NULL DEFAULT '0', `ham_count` int NOT NULL DEFAULT '0', `atime` int NOT NULL DEFAULT '0', PRIMARY KEY (`id`,`token`), KEY `bayes_token_idx1` (`id`,`atime`)) ENGINE=MyISAM DEFAULT CHARSET=latin1;", + "CREATE TABLE `maddr` ( `partition_tag` int DEFAULT '0', `id` bigint unsigned NOT NULL AUTO_INCREMENT, `email` varbinary(255) NOT NULL, `domain` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `part_email` (`partition_tag`,`email`), KEY `maddr_idx_email` (`email`), KEY `maddr_idx_domain` (`domain`)) ENGINE=InnoDB AUTO_INCREMENT=11498 DEFAULT CHARSET=utf8mb3;", + "CREATE TABLE `msgrcpt` ( `partition_tag` int NOT NULL DEFAULT '0', `mail_id` varbinary(16) NOT NULL, `rseqnum` int NOT NULL DEFAULT '0', `rid` bigint unsigned NOT NULL, `is_local` char(1) NOT NULL DEFAULT '', `content` char(1) NOT NULL DEFAULT '', `ds` char(1) NOT NULL, `rs` char(1) NOT NULL, `bl` char(1) DEFAULT '', `wl` char(1) DEFAULT '', `bspam_level` float DEFAULT NULL, `smtp_resp` varchar(255) DEFAULT '', PRIMARY KEY (`partition_tag`,`mail_id`,`rseqnum`), KEY `msgrcpt_idx_mail_id` (`mail_id`), KEY `msgrcpt_idx_rid` (`rid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;", + "CREATE TABLE `msgs` ( `partition_tag` int NOT NULL DEFAULT '0', `mail_id` varbinary(16) NOT NULL, `secret_id` varbinary(16) DEFAULT '', `am_id` varchar(20) NOT NULL, `time_num` int unsigned NOT NULL, `time_iso` char(16) NOT NULL, `sid` bigint unsigned NOT NULL, `policy` varchar(255) DEFAULT '', `client_addr` varchar(255) DEFAULT '', `size` int unsigned NOT NULL, `originating` char(1) NOT NULL DEFAULT '', `content` char(1) DEFAULT NULL, `quar_type` char(1) DEFAULT NULL, `quar_loc` varbinary(255) DEFAULT '', `dsn_sent` char(1) DEFAULT NULL, `spam_level` float DEFAULT NULL, `message_id` varchar(255) DEFAULT '', `from_addr` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT '', `subject` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT '', `host` varchar(255) NOT NULL, PRIMARY KEY (`partition_tag`,`mail_id`), KEY `msgs_idx_sid` (`sid`), KEY `msgs_idx_mess_id` (`message_id`), KEY `msgs_idx_time_num` (`time_num`), KEY `msgs_idx_mail_id` (`mail_id`), KEY `msgs_idx_content` (`content`), KEY `msgs_idx_quar_type` (`quar_type`), KEY `msgs_idx_content_time_num` (`content`,`time_num`), KEY `msgs_idx_spam_level` (`spam_level`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;" + }; + + public RestoreMailTableTask(ILog logger, IDataReadOperator dataReader, string configPath, string dbconnection) + { + _logger = logger; + _dataReader = dataReader; + _module = new MailTableSpecifics(); + _factory = new DbFactory(configPath) { ConnectionStringSettings = new ConnectionStringSettings("mailTable", dbconnection, "MySql.Data.MySqlClient") }; + } + + internal void RunJob() + { + _logger.DebugFormat("begin restore data for mail table"); + + using (var connection = _factory.OpenConnection()) + { + RestoreMailServerTables(connection); + + foreach (var table in _module.Tables) + { + _logger.DebugFormat("begin restore table {0}", table.Name); + + var transactionsCommited = 0; + var rowsInserted = 0; + ActionInvoker.Try( + state => + RestoreTable(connection.Fix(), (MailTableInfo)state, ref transactionsCommited, + ref rowsInserted), table, 5, + onFailure: error => { throw ThrowHelper.CantRestoreTable(table.Name, error); }); + + _logger.DebugFormat("{0} rows inserted for table {1}", rowsInserted, table.Name); + } + } + + _logger.DebugFormat("end restore data for mail table"); + + RestoreMailServerFiles(); + } + + private void RestoreMailServerFiles() + { + try + { + var backupMailServerFilesService = new BackupMailServerFilesService(_logger); + backupMailServerFilesService.UploadMailDirectory(_dataReader); + } + catch (Exception ex) + { + _logger.DebugFormat($"RestoreMailServerFiles exception: {ex.Message}"); + } + } + + private void RestoreTable(DbConnection connection, MailTableInfo tableInfo, ref int transactionsCommited, ref int rowsInserted) + { + SetColumns(connection, tableInfo); + + using (var stream = _dataReader.GetEntry(KeyHelper.GetMailTableZipKey(tableInfo.Name))) + { + foreach ( + IEnumerable rows in + GetRows(stream) + .Skip(transactionsCommited * TransactionLength) + .MakeParts(TransactionLength)) + { + using (var transaction = connection.BeginTransaction()) + { + int rowsSuccess = 0; + foreach (DataRowInfo row in rows) + { + var insertCommand = _module.CreateInsertCommand(connection, tableInfo, + row); + if (insertCommand == null) + { + _logger.WarnFormat("Can't create command to insert row to {0} with values [{1}]", tableInfo, + row); + continue; + } + insertCommand.WithTimeout(120).ExecuteNonQuery(); + rowsSuccess++; + } + + transaction.Commit(); + transactionsCommited++; + rowsInserted += rowsSuccess; + } + } + } + } + + private void SetColumns(DbConnection connection, MailTableInfo table) + { + var showColumnsCommand = _factory.CreateShowColumnsCommand(table.Name); + showColumnsCommand.Connection = connection; + table.Columns = showColumnsCommand.ExecuteList().Select(x => Convert.ToString(x[0])).ToArray(); + } + + private IEnumerable GetRows(Stream xmlStream) + { + if (xmlStream == null) + return Enumerable.Empty(); + + var rows = DataRowInfoReader.ReadFromStream(xmlStream); + + return rows; + } + + private int RestoreMailServerTables(DbConnection connection) + { + int result = 0; + + using (var transaction = connection.BeginTransaction()) + { + foreach (var script in tableCreateScripts) + { + var insertCommand = connection.CreateCommand(script); + + try + { + result += insertCommand.ExecuteNonQuery(); + } + catch (Exception ex) + { + _logger.Error($"RestoreMailServerTables error: {ex.Message}"); + } + } + + transaction.Commit(); + } + + return result; + } + } +} diff --git a/common/ASC.Data.Backup/Tasks/RestorePortalTask.cs b/common/ASC.Data.Backup/Tasks/RestorePortalTask.cs index 74a4b4e269..e313876a4a 100644 --- a/common/ASC.Data.Backup/Tasks/RestorePortalTask.cs +++ b/common/ASC.Data.Backup/Tasks/RestorePortalTask.cs @@ -73,7 +73,7 @@ public override void RunJob() { Logger.Debug("begin restore portal"); - Logger.Debug("begin restore data"); + Logger.Debug($"begin restore data from {BackupFilePath}"); using (var dataReader = new ZipReadOperator(BackupFilePath)) { @@ -82,13 +82,19 @@ public override void RunJob() Dump = entry != null && CoreContext.Configuration.Standalone; } + Logger.Debug($"restore data dbFactory: {ConfigPath}"); + var dbFactory = new DbFactory(ConfigPath); if (Dump) { + Logger.Debug("begin restore from dump."); + RestoreFromDump(dataReader); } else { + Logger.Debug("begin restore not from dump."); + var modulesToProcess = GetModulesToProcess().ToList(); SetStepsCount(ProcessStorage ? modulesToProcess.Count + 1 : modulesToProcess.Count); @@ -102,7 +108,25 @@ public override void RunJob() } restoreTask.RunJob(); } - var backupRepository = BackupStorageFactory.GetBackupRepository(); + RestoreMailTable(dataReader); + + try + { + using (var dbManager = new DbManager("default", 100000)) + { + //set new domain name in dns record + dbManager.ExecuteNonQuery("update mail_server_dns set mx=(select hostname from mail_mailbox_server where id_provider=-1 limit 1)"); + + dbManager.ExecuteNonQuery("update mail_mailbox set id_smtp_server = (select id from mail_mailbox_server where id_provider = -1 and type = 'smtp' limit 1), id_in_server = (select id from mail_mailbox_server where id_provider = -1 and type = 'imap' limit 1) where is_server_mailbox=1"); + } + + } + catch (Exception ex) + { + Logger.Error(ex); + } + + var backupRepository = BackupStorageFactory.GetBackupRepository(); backupRepository.MigrationBackupRecords(TenantId, _columnMapper.GetTenantMapping(), ConfigPath); } @@ -142,7 +166,44 @@ public override void RunJob() Logger.Debug("end restore portal"); } - private void RestoreFromDump(IDataReadOperator dataReader) + private void RestoreMailTable(IDataReadOperator dataReader) + { + if (!CoreContext.Configuration.Standalone || !dataReader.GetDirectories("").Any(r => r.EndsWith("mailtable"))) + { + Logger.Debug($"RestoreMailTable: Not Standalone, skip restore."); + + return; + } + + try + { + string dbconnection = null; + using (var dbManager = new DbManager("default", 100000)) + { + dbManager.ExecuteList("select connection_string from mail_server_server").ForEach(r => + { + dbconnection = JsonConvert.DeserializeObject>(Convert.ToString(r[0]))["DbConnection"].ToString(); + }); + } + Logger.Debug($"RestoreMailTable connection string: {dbconnection}"); + + if (string.IsNullOrEmpty(dbconnection)) dbconnection = "Server=onlyoffice-mysql-server;Database=onlyoffice_mailserver;User ID=root;Password=my-secret-pw;Pooling=True;Character Set=utf8;AutoEnlist=false;SSL Mode=None;Connection Timeout=30;Maximum Pool Size=300;"; + + Logger.Debug($"RestoreMailTable connection string: {dbconnection}"); + + if (dbconnection != null) + { + var restoreTask = new RestoreMailTableTask(Logger, dataReader, ConfigPath, dbconnection); + restoreTask.RunJob(); + } + } + catch (Exception ex) + { + Logger.Error($"RestoreMailTable error: {ex}"); + } + } + + private void RestoreFromDump(IDataReadOperator dataReader) { var keyBase = KeyHelper.GetDatabaseSchema(); var keys = dataReader.GetEntries(keyBase).Select(r => Path.GetFileName(r)).ToList(); diff --git a/common/ASC.Data.Storage/BaseStorage.cs b/common/ASC.Data.Storage/BaseStorage.cs index 119fb51b88..447253442b 100644 --- a/common/ASC.Data.Storage/BaseStorage.cs +++ b/common/ASC.Data.Storage/BaseStorage.cs @@ -37,6 +37,7 @@ public abstract class BaseStorage : IDataStore internal string _modulename; internal bool _cache; + internal bool _attachment; internal DataList _dataList; internal string _tenant; internal Dictionary _domainsExpires = new Dictionary(); @@ -132,6 +133,11 @@ public virtual bool IsSupportInternalUri get { return true; } } + public virtual bool IsContentDispositionAsAttachment + { + get { return _attachment; } + } + public virtual Uri GetInternalUri(string domain, string path, TimeSpan expire, IEnumerable headers) { return null; @@ -221,6 +227,7 @@ public virtual IDataWriteOperator CreateDataWriteOperator( public abstract void DeleteFiles(string domain, string folderPath, DateTime fromDate, DateTime toDate); public abstract void MoveDirectory(string srcdomain, string srcdir, string newdomain, string newdir); public abstract Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, bool quotaCheckFileSize = true); + public abstract Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, Guid ownerId, bool quotaCheckFileSize = true); public abstract Uri SaveTemp(string domain, out string assignedPath, Stream stream); public abstract string[] ListDirectoriesRelative(string domain, string path, bool recursive); public abstract string[] ListFilesRelative(string domain, string path, string pattern, bool recursive); diff --git a/common/ASC.Data.Storage/ChunkedUploader/CommonChunkedUploadSessionHolder.cs b/common/ASC.Data.Storage/ChunkedUploader/CommonChunkedUploadSessionHolder.cs index 3e3895104a..207d025b3b 100644 --- a/common/ASC.Data.Storage/ChunkedUploader/CommonChunkedUploadSessionHolder.cs +++ b/common/ASC.Data.Storage/ChunkedUploader/CommonChunkedUploadSessionHolder.cs @@ -101,11 +101,15 @@ public virtual string Finalize(CommonChunkedUploadSession uploadSession) DataStore.FinalizeChunkedUpload(Domain, tempPath, uploadId, eTags); return Path.GetFileName(tempPath); - } + } - public void Move(CommonChunkedUploadSession chunkedUploadSession, string newPath, bool quotaCheckFileSize = true) + public void Move(CommonChunkedUploadSession chunkedUploadSession, string newPath, bool quotaCheckFileSize = true) + { + Move(chunkedUploadSession, newPath, Guid.Empty, quotaCheckFileSize); + } + public void Move(CommonChunkedUploadSession chunkedUploadSession, string newPath, Guid ownerId, bool quotaCheckFileSize = true) { - DataStore.Move(Domain, chunkedUploadSession.TempPath, string.Empty, newPath, quotaCheckFileSize); + DataStore.Move(Domain, chunkedUploadSession.TempPath, string.Empty, newPath, ownerId, quotaCheckFileSize); } public void Abort(CommonChunkedUploadSession uploadSession) diff --git a/common/ASC.Data.Storage/Configuration/ModuleConfigurationElement.cs b/common/ASC.Data.Storage/Configuration/ModuleConfigurationElement.cs index 73152c666a..514d4f2889 100644 --- a/common/ASC.Data.Storage/Configuration/ModuleConfigurationElement.cs +++ b/common/ASC.Data.Storage/Configuration/ModuleConfigurationElement.cs @@ -129,5 +129,12 @@ public bool Cache get { return (bool)this[Schema.CACHE]; } set { this[Schema.CACHE] = value; } } + + [ConfigurationProperty(Schema.ATTACHMENT)] + public bool Attachment + { + get { return (bool)this[Schema.ATTACHMENT]; } + set { this[Schema.ATTACHMENT] = value; } + } } } \ No newline at end of file diff --git a/common/ASC.Data.Storage/Configuration/Schema.cs b/common/ASC.Data.Storage/Configuration/Schema.cs index 393e0f6086..7126cc6fe3 100644 --- a/common/ASC.Data.Storage/Configuration/Schema.cs +++ b/common/ASC.Data.Storage/Configuration/Schema.cs @@ -48,5 +48,6 @@ static class Schema public const string DISABLEDMIGRATE = "disableMigrate"; public const string DISABLEDENCRYPTION = "disableEncryption"; public const string CACHE = "cache"; + public const string ATTACHMENT = "attachment"; } } \ No newline at end of file diff --git a/common/ASC.Data.Storage/DiscStorage/DiscDataStore.cs b/common/ASC.Data.Storage/DiscStorage/DiscDataStore.cs index 0b2550172e..7f4383eeb0 100644 --- a/common/ASC.Data.Storage/DiscStorage/DiscDataStore.cs +++ b/common/ASC.Data.Storage/DiscStorage/DiscDataStore.cs @@ -46,6 +46,7 @@ public DiscDataStore(string tenant, HandlerConfigurationElement handlerConfig, M _modulename = moduleConfig.Name; _cache = moduleConfig.Cache; _dataList = new DataList(moduleConfig); + _attachment = moduleConfig.Attachment; foreach (DomainConfigurationElement domain in moduleConfig.Domains) { _mappedPaths.Add(domain.Name, new MappedPath(tenant, moduleConfig.AppendTenant, domain.Path, handlerConfig.GetProperties())); @@ -380,6 +381,10 @@ public override void MoveDirectory(string srcdomain, string srcdir, string newdo } public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, bool quotaCheckFileSize = true) + { + return Move(srcdomain, srcpath, newdomain, newpath, Guid.Empty, quotaCheckFileSize); + } + public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, Guid ownerId, bool quotaCheckFileSize = true) { if (srcpath == null) throw new ArgumentNullException("srcpath"); if (newpath == null) throw new ArgumentNullException("srcpath"); @@ -403,7 +408,7 @@ public override Uri Move(string srcdomain, string srcpath, string newdomain, str File.Move(target, newtarget); QuotaUsedDelete(srcdomain, flength); - QuotaUsedAdd(newdomain, flength, quotaCheckFileSize); + QuotaUsedAdd(newdomain, flength, ownerId, quotaCheckFileSize); } else { diff --git a/common/ASC.Data.Storage/GoogleCloud/GoogleCloudStorage.cs b/common/ASC.Data.Storage/GoogleCloud/GoogleCloudStorage.cs index e9fd4a3080..25226d4964 100644 --- a/common/ASC.Data.Storage/GoogleCloud/GoogleCloudStorage.cs +++ b/common/ASC.Data.Storage/GoogleCloud/GoogleCloudStorage.cs @@ -63,10 +63,11 @@ public GoogleCloudStorage(string tenant) _modulename = string.Empty; _cache = false; _dataList = null; + _attachment = false; _domainsExpires = new Dictionary { { string.Empty, TimeSpan.Zero } }; _domainsAcl = new Dictionary(); - _moduleAcl = PredefinedObjectAcl.PublicRead; + _moduleAcl = PredefinedObjectAcl.BucketOwnerFullControl; } @@ -77,7 +78,7 @@ public GoogleCloudStorage(string tenant, HandlerConfigurationElement handlerConf _modulename = moduleConfig.Name; _cache = moduleConfig.Cache; _dataList = new DataList(moduleConfig); - + _attachment = moduleConfig.Attachment; _domainsExpires = moduleConfig.Domains.Cast().Where(x => x.Expires != TimeSpan.Zero). ToDictionary(x => x.Name, @@ -346,9 +347,9 @@ private PredefinedObjectAcl GetGoogleCloudAcl(ACL acl) switch (acl) { case ACL.Read: - return PredefinedObjectAcl.PublicRead; + return PredefinedObjectAcl.BucketOwnerFullControl; default: - return PredefinedObjectAcl.PublicRead; + return PredefinedObjectAcl.BucketOwnerFullControl; } } @@ -477,8 +478,11 @@ public override void MoveDirectory(string srcdomain, string srcdir, string newdo } } + public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, bool quotaCheckFileSize = true) { + return Move(srcdomain, srcpath, newdomain, newpath, Guid.Empty, quotaCheckFileSize); + } - public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, bool quotaCheckFileSize = true) + public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, Guid ownerId, bool quotaCheckFileSize = true) { var storage = GetStorage(); @@ -494,7 +498,7 @@ public override Uri Move(string srcdomain, string srcpath, string newdomain, str Delete(srcdomain, srcpath); QuotaUsedDelete(srcdomain, size); - QuotaUsedAdd(newdomain, size, quotaCheckFileSize); + QuotaUsedAdd(newdomain, size, ownerId, quotaCheckFileSize); return GetUri(newdomain, newpath); diff --git a/common/ASC.Data.Storage/IDataStore.cs b/common/ASC.Data.Storage/IDataStore.cs index 79e1630b93..98de5cf497 100644 --- a/common/ASC.Data.Storage/IDataStore.cs +++ b/common/ASC.Data.Storage/IDataStore.cs @@ -177,6 +177,8 @@ IDataWriteOperator CreateDataWriteOperator( bool IsSupportedPreSignedUri { get; } + bool IsContentDispositionAsAttachment { get; } + /// /// Deletes file /// @@ -229,6 +231,18 @@ IDataWriteOperator CreateDataWriteOperator( /// Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, bool quotaCheckFileSize = true); + /// + /// Moves file + /// + /// + /// + /// + /// + /// + /// + /// + Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, Guid ownerId, bool quotaCheckFileSize = true); + /// /// Saves the file in the temp. In fact, almost no different from the usual Save except that generates the file name itself. An inconvenient thing. /// diff --git a/common/ASC.Data.Storage/RackspaceCloud/RackspaceCloudStorage.cs b/common/ASC.Data.Storage/RackspaceCloud/RackspaceCloudStorage.cs index 211335424d..e8ab4f24f2 100644 --- a/common/ASC.Data.Storage/RackspaceCloud/RackspaceCloudStorage.cs +++ b/common/ASC.Data.Storage/RackspaceCloud/RackspaceCloudStorage.cs @@ -57,7 +57,7 @@ public RackspaceCloudStorage(string tenant) _modulename = string.Empty; _cache = false; _dataList = null; - + _attachment = false; _domainsExpires = new Dictionary { { string.Empty, TimeSpan.Zero } }; _domainsAcl = new Dictionary(); _moduleAcl = ACL.Auto; @@ -70,7 +70,7 @@ public RackspaceCloudStorage(string tenant, HandlerConfigurationElement handlerC _modulename = moduleConfig.Name; _cache = moduleConfig.Cache; _dataList = new DataList(moduleConfig); - + _attachment = moduleConfig.Attachment; _domains.AddRange( moduleConfig.Domains.Cast().Select(x => string.Format("{0}/", x.Name))); @@ -498,6 +498,10 @@ public override void MoveDirectory(string srcdomain, string srcdir, string newdo } public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, bool quotaCheckFileSize = true) + { + return Move(srcdomain, srcpath, newdomain, newpath, Guid.Empty, quotaCheckFileSize); + } + public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, Guid ownerId, bool quotaCheckFileSize = true) { var srcKey = MakePath(srcdomain, srcpath); var dstKey = MakePath(newdomain, newpath); @@ -510,7 +514,7 @@ public override Uri Move(string srcdomain, string srcpath, string newdomain, str Delete(srcdomain, srcpath); QuotaUsedDelete(srcdomain, size); - QuotaUsedAdd(newdomain, size, quotaCheckFileSize); + QuotaUsedAdd(newdomain, size, ownerId, quotaCheckFileSize); return GetUri(newdomain, newpath); } diff --git a/common/ASC.Data.Storage/S3/S3Storage.cs b/common/ASC.Data.Storage/S3/S3Storage.cs index a7cc0fd116..fb01786c98 100644 --- a/common/ASC.Data.Storage/S3/S3Storage.cs +++ b/common/ASC.Data.Storage/S3/S3Storage.cs @@ -77,7 +77,7 @@ public S3Storage(string tenant) _modulename = string.Empty; _cache = false; _dataList = null; - + _attachment = false; //Make expires _domainsExpires = new Dictionary { { string.Empty, TimeSpan.Zero } }; @@ -91,6 +91,7 @@ public S3Storage(string tenant, HandlerConfigurationElement handlerConfig, Modul _modulename = moduleConfig.Name; _cache = moduleConfig.Cache; _dataList = new DataList(moduleConfig); + _attachment = moduleConfig.Attachment; _domains.AddRange( moduleConfig.Domains.Cast().Select(x => string.Format("{0}/", x.Name))); @@ -717,6 +718,10 @@ public override void MoveDirectory(string srcdomain, string srcdir, string newdo } public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, bool quotaCheckFileSize = true) + { + return Move(srcdomain, srcpath, newdomain, newpath, Guid.Empty, quotaCheckFileSize); + } + public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, Guid ownerId, bool quotaCheckFileSize = true) { var srcKey = MakePath(srcdomain, srcpath); var dstKey = MakePath(newdomain, newpath); @@ -726,7 +731,7 @@ public override Uri Move(string srcdomain, string srcpath, string newdomain, str Delete(srcdomain, srcpath); QuotaUsedDelete(srcdomain, size); - QuotaUsedAdd(newdomain, size, quotaCheckFileSize); + QuotaUsedAdd(newdomain, size, ownerId, quotaCheckFileSize); return GetUri(newdomain, newpath); } @@ -1278,7 +1283,7 @@ private void CopyFile(string sourceKey, string destinationKey, string newdomain, var metadataResponse = client.GetObjectMetadata(metadataRequest); var objectSize = metadataResponse.ContentLength; - if (objectSize >= 100 * 1024 * 1024L) //100 megabytes + if (objectSize >= 1000 * 1024 * 1024L) //1000 megabytes { var copyResponses = new List(); @@ -1306,7 +1311,7 @@ private void CopyFile(string sourceKey, string destinationKey, string newdomain, var uploadId = initResponse.UploadId; - var partSize = GetChunkSize(); + var partSize = 500 * 1024 * 1024L; //500 megabytes long bytePosition = 0; for (int i = 1; bytePosition < objectSize; i++) @@ -1565,18 +1570,6 @@ protected override DateTime GetLastModificationDate(string domain, string path) throw new FileNotFoundException("file not found", path); } - private long GetChunkSize() - { - var configSetting = ConfigurationManagerExtension.AppSettings["files.uploader.chunk-size"]; - if (!string.IsNullOrEmpty(configSetting)) - { - configSetting = configSetting.Trim(); - return long.Parse(configSetting); - } - long defaultValue = 10 * 1024 * 1024; - return defaultValue; - } - private enum EncryptionMethod { None, diff --git a/common/ASC.Data.Storage/Selectel/SelectelStorage.cs b/common/ASC.Data.Storage/Selectel/SelectelStorage.cs index d0a1dbdf9b..fd7a2d63e4 100644 --- a/common/ASC.Data.Storage/Selectel/SelectelStorage.cs +++ b/common/ASC.Data.Storage/Selectel/SelectelStorage.cs @@ -57,7 +57,7 @@ public SelectelStorage(String tenant) _modulename = string.Empty; _cache = false; _dataList = null; - + _attachment = false; _domainsExpires = new Dictionary { { string.Empty, TimeSpan.Zero } }; _domainsAcl = new Dictionary(); _moduleAcl = ACL.Auto; @@ -70,7 +70,7 @@ public SelectelStorage(String tenant, HandlerConfigurationElement handlerConfig, _modulename = moduleConfig.Name; _cache = moduleConfig.Cache; _dataList = new DataList(moduleConfig); - + _attachment = moduleConfig.Attachment; _domainsExpires = moduleConfig.Domains.Cast() .Where(x => x.Expires != TimeSpan.Zero) .ToDictionary(x => x.Name, y => y.Expires); @@ -471,6 +471,10 @@ public override void MoveDirectory(string srcdomain, string srcdir, string newdo } public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, bool quotaCheckFileSize = true) + { + return Move(srcdomain, srcpath, newdomain, newpath, Guid.Empty, quotaCheckFileSize); + } + public override Uri Move(string srcdomain, string srcpath, string newdomain, string newpath, Guid ownerId, bool quotaCheckFileSize = true) { var srcKey = MakePath(srcdomain, srcpath); var dstKey = MakePath(newdomain, newpath); @@ -481,7 +485,7 @@ public override Uri Move(string srcdomain, string srcpath, string newdomain, str Delete(srcdomain, srcpath); QuotaUsedDelete(srcdomain, size); - QuotaUsedAdd(newdomain, size, quotaCheckFileSize); + QuotaUsedAdd(newdomain, size, ownerId, quotaCheckFileSize); return GetUri(newdomain, newpath); } diff --git a/common/ASC.Data.Storage/StorageHandler.cs b/common/ASC.Data.Storage/StorageHandler.cs index f5a861465e..52095646a3 100644 --- a/common/ASC.Data.Storage/StorageHandler.cs +++ b/common/ASC.Data.Storage/StorageHandler.cs @@ -91,7 +91,7 @@ public void ProcessRequest(HttpContext context) { var path = _path; var header = context.Request[Constants.QUERY_HEADER] ?? ""; - var headers = header.Length > 0 ? header.Split('&').Select(HttpUtility.UrlDecode) : new string[] { }; + var headers = header.Length > 0 ? header.Split('&').Select(HttpUtility.UrlDecode).ToList() : new List(); if (_checkAuth && !SecurityContext.IsAuthenticated) { @@ -127,6 +127,14 @@ public void ProcessRequest(HttpContext context) return; } + if (storage.IsContentDispositionAsAttachment) + { + if (!headers.Any(h => h.StartsWith("Content-Disposition"))) + { + headers.Add("Content-Disposition:attachment"); + } + } + const int bigSize = 5 * 1024 * 1024; var fileSize = storage.GetFileSize(_domain, path); diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.Designer.cs b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.Designer.cs index ad710597ba..905823c0a5 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.Designer.cs +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.Designer.cs @@ -85,11 +85,9 @@ public static string FooterOpensourceV121 { } /// - /// Looks up a localized string similar to <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + /// Looks up a localized string similar to <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> ///<div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> - /// <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> - /// <tbody> - /// <tr border="0 [rest of string was truncated]";. + /// <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; e [rest of string was truncated]";. /// public static string HtmlMaster { get { diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.az-Latn-AZ.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.az-Latn-AZ.resx index 203c82d307..d899a53b00 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.az-Latn-AZ.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.az-Latn-AZ.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.bg.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.bg.resx index c8ecf4c42c..a3dee74b6b 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.bg.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.bg.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.cs.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.cs.resx index 6d66db2b10..b8f93b967e 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.cs.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.cs.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.de.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.de.resx index 72a61ddbe1..657b2a438b 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.de.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.de.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.es.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.es.resx index 25281d0c5e..946fd6cf0a 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.es.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.es.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.fr.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.fr.resx index 8e39ee997c..d3d0a7d58b 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.fr.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.fr.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.it.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.it.resx index 0391694f2c..b7da305b63 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.it.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.it.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.lv.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.lv.resx index 780bbe716f..f13937166f 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.lv.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.lv.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.nl.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.nl.resx index 5cdbffba9f..373e8ba442 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.nl.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.nl.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.pl.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.pl.resx index 6cdefff96e..5034ab7e7c 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.pl.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.pl.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.pt-BR.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.pt-BR.resx index 8e1959f5a7..95dddb8bad 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.pt-BR.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.pt-BR.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.resx index a3a8e9c77f..e1c647704f 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.resx @@ -119,7 +119,7 @@ </tr> - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.ru.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.ru.resx index b867f65632..81df49c530 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.ru.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.ru.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.sk.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.sk.resx index 8f73532585..1b6219f2a5 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.sk.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.sk.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.tr.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.tr.resx index 208c94a0a1..faee19648f 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.tr.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.tr.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.uk.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.uk.resx index aec4ce9816..d626ea72c7 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.uk.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.uk.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.vi.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.vi.resx index 52159d7c3f..bafa530cc3 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.vi.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.vi.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.zh-CN.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.zh-CN.resx index fc24e84d31..e1b38827bf 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.zh-CN.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.zh-CN.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.zh-TW.resx b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.zh-TW.resx index 0cf2d66ca2..d34b93a1f1 100644 --- a/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.zh-TW.resx +++ b/common/ASC.Notify.Textile/Resources/NotifyTemplateResource.zh-TW.resx @@ -59,7 +59,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - <body style="margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> + <body style="background: linear-gradient(#ffffff, #ffffff); background-color: #ffffff; margin: 0; padding: 0; text-align: center; width: 100%; font-family: Arial, sans-serif; font-size: 14px; color: #333;"> <div style="background-color: #fff; width: 600px; margin: 0 auto; text-align: left;"> <table cellspacing="0" cellpadding="0" style="font-family: Arial; font-size: 14px; color: #333; background: #fff; text-align: center; width: 600px; margin: 0; padding: 0; border: 0 none; border-collapse: collapse; empty-cells: show; border-spacing: 0;"> <tbody> diff --git a/module/ASC.Api/ASC.Api.CRM/ASC.Api.CRM.csproj b/module/ASC.Api/ASC.Api.CRM/ASC.Api.CRM.csproj index 48adebcf15..0a946a756d 100644 --- a/module/ASC.Api/ASC.Api.CRM/ASC.Api.CRM.csproj +++ b/module/ASC.Api/ASC.Api.CRM/ASC.Api.CRM.csproj @@ -150,10 +150,6 @@ {481B0D9C-B2F8-4DE9-8597-BA8D24585099} ASC.FederatedLogin - - {592eac85-6cfc-4ad7-b653-3eadaa18327e} - ASC.Thrdparty - {988536c1-4b89-4649-8f77-5c16f55d95d1} ASC.VoipService diff --git a/module/ASC.Api/ASC.Api.CRM/CRMApi.Contacts.cs b/module/ASC.Api/ASC.Api.CRM/CRMApi.Contacts.cs index 11a2cd22ba..91bd13d04d 100644 --- a/module/ASC.Api/ASC.Api.CRM/CRMApi.Contacts.cs +++ b/module/ASC.Api/ASC.Api.CRM/CRMApi.Contacts.cs @@ -32,13 +32,9 @@ using ASC.MessagingSystem; using ASC.Projects.Engine; using ASC.Specific; -using ASC.Thrdparty; -using ASC.Thrdparty.Twitter; using ASC.Web.CRM.Classes; -using ASC.Web.CRM.Classes.SocialMedia; using ASC.Web.CRM.Core.Enums; using ASC.Web.CRM.Resources; -using ASC.Web.CRM.SocialMedia; using ASC.Web.Projects.Core; using ASC.Web.Studio.Core; @@ -272,6 +268,7 @@ public OpportunityWrapper DeleteDealFromContact(int contactid, int opportunityid var opportunity = DaoFactory.DealDao.GetByID(opportunityid); if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException(); + if(opportunity.ContactID == contactid) throw new SecurityException("Can't unlink base contact"); DaoFactory.DealDao.RemoveMember(opportunityid, contactid); @@ -1694,106 +1691,6 @@ public IEnumerable GetContactsByContactInfo(ContactInfoType? inf return result; } - /// - /// Returns a certain number of tweets created by a user with the ID specified in the request. - /// - /// Contact ID - /// Number of tweets - /// Get user tweets - /// Contacts - /// List of tweets - /// api/2.0/crm/contact/{contactid}/tweets - /// GET - /// list - [Read(@"contact/{contactid:[0-9]+}/tweets")] - public List GetUserTweets(int contactid, int count) - { - var MessageCount = 10; - var twitterAccounts = DaoFactory.ContactInfoDao.GetList(contactid, ContactInfoType.Twitter, null, null); - - if (twitterAccounts.Count == 0) - throw new ResourceNotFoundException( - Newtonsoft.Json.JsonConvert.SerializeObject( - new - { - message = "", - description = CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter - } - )); - - var apiInfo = TwitterApiHelper.GetTwitterApiInfoForCurrentUser(); - TwitterDataProvider twitterProvider = new TwitterDataProvider(apiInfo); - - List messages = new List(); - - foreach (var twitterAccount in twitterAccounts) - { - try - { - messages.AddRange(twitterProvider.GetUserTweets(twitterAccount.Data, MessageCount)); - } - catch (ResourceNotFoundException ex) - { - throw new ResourceNotFoundException( - Newtonsoft.Json.JsonConvert.SerializeObject( - new - { - message = ex.Message, - description = String.Format("{0}: {1}", CRMSocialMediaResource.ErrorUnknownTwitterAccount, twitterAccount.Data) - } - )); - } - catch (Exception ex) - { - throw new Exception( - Newtonsoft.Json.JsonConvert.SerializeObject( - new - { - message = ex.Message, - description = String.Format("{0}: {1}", CRMSocialMediaResource.ErrorUnknownTwitterAccount, twitterAccount.Data) - } - )); - } - } - - - return messages.OrderByDescending(m => m.PostedOn).Take(MessageCount).ToList(); - - } - - - /// - /// Returns a list of twitter profiles by the search text specified in the request. - /// - /// Search text - /// Get twitter profiles - /// Contacts - /// List of twitter profiles - /// api/2.0/crm/contact/twitterprofile - /// GET - /// list - [Read(@"contact/twitterprofile")] - public List FindTwitterProfiles(string searchText) - { - try - { - TwitterApiInfo apiInfo = TwitterApiHelper.GetTwitterApiInfoForCurrentUser(); - if (apiInfo == null) - throw new SocialMediaAccountNotFound(CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter); - - TwitterDataProvider provider = new TwitterDataProvider(apiInfo); - List users = provider.FindUsers(searchText); - /*List users = new List(); - users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 }); - users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 }); - users.Add(new TwitterUserInfo { Description = "I'm a cool user", SmallImageUrl = "http://localhost/TeamLab/products/crm/data/0/photos/00/00/10/contact_10_50_50.jpg", UserName = "User", ScreenName = "user", UserID = 1 });*/ - return users; - } - catch (Exception ex) - { - throw new SocialMediaUI(DaoFactory).ProcessError(ex, "ASC.Api.CRM.CRMApi.FindTwitterProfiles"); - } - } /// /// Deletes an avatar of the contact with the ID specified in the request. @@ -1833,85 +1730,6 @@ public string DeleteContactAvatar(int contactId, string contactType, bool upload return ""; } - /// - /// Returns a list of the social media images for the contact with the ID specified in the request. - /// - /// Contact ID - /// Get contact social media images by contact ID - /// Contacts - /// List of social media images - /// api/2.0/crm/contact/{contactid}/socialmediaavatar - /// GET - /// list - [Read(@"contact/{contactid:[0-9]+}/socialmediaavatar")] - public List GetContactSMImages(int contactId) - { - return new SocialMediaUI(DaoFactory).GetContactSMImages(contactId); - } - - /// - /// Returns a list of the contact social media images from the social networks specified in the request. - /// - /// List of contact social networks - /// Get contact social media images by networks - /// Contacts - /// List of social media images - /// api/2.0/crm/contact/socialmediaavatar - /// POST - /// list - [Create(@"contact/socialmediaavatar")] - public List GetContactSMImagesByNetworks(List socialNetworks) - { - if (socialNetworks == null || socialNetworks.Count == 0) - { - return new List(); - } - var twitter = new List(); - - foreach (var sn in socialNetworks) - { - if (sn.InfoType == ContactInfoType.Twitter) twitter.Add(sn.Data); - } - - return new SocialMediaUI(DaoFactory).GetContactSMImages(twitter); - } - - /// - /// Uploads an avatar of the contact with the ID specified in the request from the social network. - /// - /// Contact ID - /// Contact social network - /// User identity - /// Defines whether to upload an avatar only or also save it to a folder - /// Temporary directory name - /// Upload an avatar from social network - /// Contacts - /// Avatar - /// api/2.0/crm/contact/{contactid}/avatar - /// PUT - [Update(@"contact/{contactid:[0-9]+}/avatar")] - public ContactPhotoManager.PhotoData UploadUserAvatarFromSocialNetwork(int contactId, SocialNetworks socialNetwork, string userIdentity, bool uploadOnly, string tmpDirName) - { - if (socialNetwork != SocialNetworks.Twitter) - throw new ArgumentException(); - - if (contactId != 0) - { - var contact = DaoFactory.ContactDao.GetByID(contactId); - if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException(); - - if (!CRMSecurity.CanEdit(contact)) throw CRMSecurity.CreateSecurityException(); - } - - if (socialNetwork == SocialNetworks.Twitter) - { - var provider = new TwitterDataProvider(TwitterApiHelper.GetTwitterApiInfoForCurrentUser()); - var imageUrl = provider.GetUrlOfUserImage(userIdentity, TwitterDataProvider.ImageSize.Original); - return UploadAvatar(contactId, imageUrl, uploadOnly, tmpDirName, false); - } - - return null; - } /// /// Sends a mail through SMTP to the contacts with the IDs specified in the request. @@ -2036,17 +1854,6 @@ public void SetContactLastModifedDate(int contactId, ApiDateTime lastModifedDate } - private static ContactPhotoManager.PhotoData UploadAvatar(int contactID, string imageUrl, bool uploadOnly, string tmpDirName, bool checkFormat = true) - { - if (contactID != 0) - { - return ContactPhotoManager.UploadPhoto(imageUrl, contactID, uploadOnly, checkFormat); - } - - if (string.IsNullOrEmpty(tmpDirName) || tmpDirName == "null") tmpDirName = null; - return ContactPhotoManager.UploadPhotoToTemp(imageUrl, tmpDirName, checkFormat); - } - private IEnumerable ToSimpleListContactWrapper(IReadOnlyList itemList) { if (itemList.Count == 0) return new List(); diff --git a/module/ASC.Api/ASC.Api.Calendar/ASC.Api.Calendar.csproj b/module/ASC.Api/ASC.Api.Calendar/ASC.Api.Calendar.csproj index 6c241ff554..c45b01b13b 100644 --- a/module/ASC.Api/ASC.Api.Calendar/ASC.Api.Calendar.csproj +++ b/module/ASC.Api/ASC.Api.Calendar/ASC.Api.Calendar.csproj @@ -343,11 +343,14 @@ - 4.1.11 + 4.2.0 13.0.1 + + 4.3.0 + diff --git a/module/ASC.Api/ASC.Api.Calendar/iCalParser/DDayICalParser.cs b/module/ASC.Api/ASC.Api.Calendar/iCalParser/DDayICalParser.cs index 08971c3586..b9c2e19e4e 100644 --- a/module/ASC.Api/ASC.Api.Calendar/iCalParser/DDayICalParser.cs +++ b/module/ASC.Api/ASC.Api.Calendar/iCalParser/DDayICalParser.cs @@ -66,7 +66,7 @@ public static string SerializeCalendar(Ical.Net.Calendar calendar) { try { - var serializer = new Ical.Net.Serialization.CalendarSerializer(); + var serializer = new Ical.Net.Serialization.ComponentSerializer(); return StringUtils.NormalizeStringForMySql(serializer.SerializeToString(calendar)); } @@ -214,7 +214,7 @@ public static Ical.Net.Calendar ConvertCalendar(BaseCalendar calandarObj) result.Method = Ical.Net.CalendarMethods.Publish; result.Scale = Ical.Net.CalendarScales.Gregorian; result.Version = Ical.Net.LibraryMetadata.Version; - result.ProductId = "-//Ascensio System//OnlyOffice Calendar//EN"; + result.ProductId = "-//Ascensio System//ONLYOFFICE Calendar//EN"; if (!string.IsNullOrEmpty(calandarObj.Name)) { diff --git a/module/ASC.Api/ASC.Api.Community/Events/EventApi.cs b/module/ASC.Api/ASC.Api.Community/Events/EventApi.cs index 70657debad..3e9d3a5dc5 100644 --- a/module/ASC.Api/ASC.Api.Community/Events/EventApi.cs +++ b/module/ASC.Api/ASC.Api.Community/Events/EventApi.cs @@ -336,14 +336,11 @@ public EventCommentWrapper AddEventComments(int feedid, string content, long par [Create("event/{feedid}/vote")] public EventWrapperFull VoteForEvent(int feedid, long[] variants) { - var feed = FeedStorage.GetFeed(feedid).NotFoundIfNull(); - - if (feed.FeedType != FeedType.Poll) throw new ArgumentException("Feed is not a poll"); - if (((FeedPoll)feed).IsUserVote(SecurityContext.CurrentAccount.ID.ToString())) throw new ArgumentException("User already voted"); + var feed = FeedStorage.GetFeed(feedid); //Voting string error; - PollVoteHandler.VoteForPoll(variants.ToList(), FeedStorage, feedid, out error);//this method is from + PollVoteHandler.VoteForPoll(variants.ToList(), FeedStorage, feed, out error);//this method is from if (!string.IsNullOrEmpty(error)) throw new Exception(error); diff --git a/module/ASC.Api/ASC.Api.Documents/DocumentsApi.cs b/module/ASC.Api/ASC.Api.Documents/DocumentsApi.cs index b83e64af68..78cf6700da 100644 --- a/module/ASC.Api/ASC.Api.Documents/DocumentsApi.cs +++ b/module/ASC.Api/ASC.Api.Documents/DocumentsApi.cs @@ -26,6 +26,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Web; +using System.Windows.Controls; using ASC.Api.Attributes; using ASC.Api.Collections; @@ -102,6 +103,7 @@ public DocumentsApi(ApiContext context, IFileStorageService fileStorageService) /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// Specifies whether to return sections with or without trash folder /// Specifies whether to return sections with or without additional folders @@ -111,7 +113,7 @@ public DocumentsApi(ApiContext context, IFileStorageService fileStorageService) /// GET /// list [Read("@root")] - public IEnumerable GetRootFolders(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders, bool withoutTrash, bool withoutAdditionalFolder) + public IEnumerable GetRootFolders(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders, bool withoutTrash, bool withoutAdditionalFolder) { var IsVisitor = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsVisitor(); var IsOutsider = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsOutsider(); @@ -174,7 +176,7 @@ public IEnumerable GetRootFolders(Guid userIdOrGroupId, Fi result.Add((int)Global.FolderTrash); } - return result.Select(r => ToFolderContentWrapper(r, userIdOrGroupId, filterType, searchInContent, withSubfolders)); + return result.Select(r => ToFolderContentWrapper(r, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders)); } /// @@ -185,14 +187,15 @@ public IEnumerable GetRootFolders(Guid userIdOrGroupId, Fi /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// The "My documents" section contents /// api/2.0/files/@my /// GET [Read("@my")] - public FolderContentWrapper GetMyFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetMyFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(Global.FolderMy, userIdOrGroupId, filterType, searchInContent, withSubfolders); + return ToFolderContentWrapper(Global.FolderMy, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders); } /// @@ -203,14 +206,15 @@ public FolderContentWrapper GetMyFolder(Guid userIdOrGroupId, FilterType filterT /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// The "In projects" section contents /// api/2.0/files/@projects /// GET [Read("@projects")] - public FolderContentWrapper GetProjectsFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetProjectsFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(Global.FolderProjects, userIdOrGroupId, filterType, searchInContent, withSubfolders); + return ToFolderContentWrapper(Global.FolderProjects, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders); } @@ -222,14 +226,15 @@ public FolderContentWrapper GetProjectsFolder(Guid userIdOrGroupId, FilterType f /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// The "Common" section contents /// api/2.0/files/@common /// GET [Read("@common")] - public FolderContentWrapper GetCommonFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetCommonFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(Global.FolderCommon, userIdOrGroupId, filterType, searchInContent, withSubfolders); + return ToFolderContentWrapper(Global.FolderCommon, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders); } /// @@ -240,14 +245,15 @@ public FolderContentWrapper GetCommonFolder(Guid userIdOrGroupId, FilterType fil /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// The "Shared with me" section contents /// api/2.0/files/@share /// GET [Read("@share")] - public FolderContentWrapper GetShareFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetShareFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(Global.FolderShare, userIdOrGroupId, filterType, searchInContent, withSubfolders); + return ToFolderContentWrapper(Global.FolderShare, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders); } /// @@ -258,14 +264,15 @@ public FolderContentWrapper GetShareFolder(Guid userIdOrGroupId, FilterType filt /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// The "Recent" section contents /// api/2.0/files/@recent /// GET [Read("@recent")] - public FolderContentWrapper GetRecentFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetRecentFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(Global.FolderRecent, userIdOrGroupId, filterType, searchInContent, withSubfolders); + return ToFolderContentWrapper(Global.FolderRecent, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders); } /// @@ -276,14 +283,15 @@ public FolderContentWrapper GetRecentFolder(Guid userIdOrGroupId, FilterType fil /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// The "Favorites" section contents /// api/2.0/files/@favorites /// GET [Read("@favorites")] - public FolderContentWrapper GetFavoritesFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetFavoritesFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(Global.FolderFavorites, userIdOrGroupId, filterType, searchInContent, withSubfolders); + return ToFolderContentWrapper(Global.FolderFavorites, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders); } /// @@ -294,14 +302,15 @@ public FolderContentWrapper GetFavoritesFolder(Guid userIdOrGroupId, FilterType /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// The "Templates" section contents /// api/2.0/files/@templates /// GET [Read("@templates")] - public FolderContentWrapper GetTemplatesFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetTemplatesFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(Global.FolderTemplates, userIdOrGroupId, filterType, searchInContent, withSubfolders); + return ToFolderContentWrapper(Global.FolderTemplates, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders); } /// @@ -312,14 +321,15 @@ public FolderContentWrapper GetTemplatesFolder(Guid userIdOrGroupId, FilterType /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// The "Trash" section contents /// api/2.0/files/@trash /// GET [Read("@trash")] - public FolderContentWrapper GetTrashFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetTrashFolder(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(Global.FolderTrash, userIdOrGroupId, filterType, searchInContent, withSubfolders); + return ToFolderContentWrapper(Global.FolderTrash, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders); } /// @@ -333,14 +343,15 @@ public FolderContentWrapper GetTrashFolder(Guid userIdOrGroupId, FilterType filt /// User or group ID /// Filter type /// Specifies whether to search within the section contents or not + /// File extension by which files will be searched for if the FilterType.ByExtension parameter is passed /// Specifies whether to return sections with or without subfolders /// Folder contents /// api/2.0/files/{folderId} /// GET [Read("{folderId}")] - public FolderContentWrapper GetFolder(String folderId, Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + public FolderContentWrapper GetFolder(String folderId, Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { - return ToFolderContentWrapper(folderId, userIdOrGroupId, filterType, searchInContent, withSubfolders).NotFoundIfNull(); + return ToFolderContentWrapper(folderId, userIdOrGroupId, filterType, searchInContent, extension, withSubfolders).NotFoundIfNull(); } @@ -1228,7 +1239,7 @@ public IEnumerable MoveOrCopyBatchCheck(String destFolderId, IEnume var ids = _fileStorageService.MoveOrCopyFilesCheck(itemList, destFolderId).Keys.Select(id => "file_" + id); - var entries = _fileStorageService.GetItems(new Web.Files.Services.WCFService.ItemList(ids), FilterType.FilesOnly, false, "", ""); + var entries = _fileStorageService.GetItems(new Web.Files.Services.WCFService.ItemList(ids), FilterType.FilesOnly, false, "", "", null); return entries.Select(x => new FileWrapper((Files.Core.File)x)).ToSmartList(); } @@ -2326,13 +2337,19 @@ public IEnumerable CreateThumbnails(IEnumerable fileIds) } - private FolderContentWrapper ToFolderContentWrapper(object folderId, Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubfolders) + private FolderContentWrapper ToFolderContentWrapper(object folderId, Guid userIdOrGroupId, FilterType filterType, bool searchInContent, string extension, bool withSubfolders) { if (folderId == null) { throw new ItemNotFoundException(Web.Files.Resources.FilesCommonResource.ErrorMassage_FolderNotFound); } + var subjectGroup = false; + var groupInfo = CoreContext.UserManager.GetGroupInfo(userIdOrGroupId); + if(groupInfo.ID != Core.Users.Constants.LostGroupInfo.ID) + { + subjectGroup = true; + } OrderBy orderBy = null; SortedByType sortBy; if (Enum.TryParse(_context.SortBy, true, out sortBy)) @@ -2344,10 +2361,11 @@ private FolderContentWrapper ToFolderContentWrapper(object folderId, Guid userId startIndex, Convert.ToInt32(_context.Count) - 1, //NOTE: in ApiContext +1 filterType, - filterType == FilterType.ByDepartment, + subjectGroup, userIdOrGroupId.ToString(), _context.FilterValue, searchInContent, + extension, withSubfolders, orderBy), startIndex); diff --git a/module/ASC.Api/ASC.Api.Mail/ASC.Api.Mail.csproj b/module/ASC.Api/ASC.Api.Mail/ASC.Api.Mail.csproj index fd39a7cc0c..63f938d850 100644 --- a/module/ASC.Api/ASC.Api.Mail/ASC.Api.Mail.csproj +++ b/module/ASC.Api/ASC.Api.Mail/ASC.Api.Mail.csproj @@ -147,7 +147,7 @@ - 4.1.11 + 4.2.0 diff --git a/module/ASC.Api/ASC.Api.Migration/MigrationApi.cs b/module/ASC.Api/ASC.Api.Migration/MigrationApi.cs index eeb5619e49..a489f1019e 100644 --- a/module/ASC.Api/ASC.Api.Migration/MigrationApi.cs +++ b/module/ASC.Api/ASC.Api.Migration/MigrationApi.cs @@ -57,15 +57,15 @@ public MigrationApi(ApiContext context) } /// - /// Returns the temporary folder where all the created backups are stored. + /// Returns the temporary folder where all the migration files are stored. /// /// - /// Get backup folder + /// Get migration temporary folder /// - /// Path to the backup folder - /// api/2.0/migration/backuptmp + /// Path to the migration temporary folder + /// api/2.0/migration/tmp /// GET - [Read("backuptmp")] + [Read("tmp")] public string GetTmpFolder() { if (!CoreContext.Configuration.Standalone || !CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsAdmin()) throw new System.Security.SecurityException(); diff --git a/module/ASC.Api/ASC.Api.Projects/ProjectApi.Projects.cs b/module/ASC.Api/ASC.Api.Projects/ProjectApi.Projects.cs index 185fad6815..403ed74d52 100644 --- a/module/ASC.Api/ASC.Api.Projects/ProjectApi.Projects.cs +++ b/module/ASC.Api/ASC.Api.Projects/ProjectApi.Projects.cs @@ -574,6 +574,8 @@ public ProjectWrapperFull DeleteProject(int id) [Delete(@"")] public IEnumerable DeleteProjects(int[] projectids) { + projectids = projectids.Distinct().ToArray(); + var result = new List(projectids.Length); foreach (var id in projectids) @@ -1259,7 +1261,7 @@ public FolderContentWrapper GetProjectFiles(int id) var project = EngineFactory.ProjectEngine.GetByID(id).NotFoundIfNull(); if (ProjectSecurity.CanReadFiles(project)) - return documentsApi.GetFolder(EngineFactory.FileEngine.GetRoot(id).ToString(), Guid.Empty, FilterType.None, false, false); + return documentsApi.GetFolder(EngineFactory.FileEngine.GetRoot(id).ToString(), Guid.Empty, FilterType.None, false, null, false); throw new SecurityException("Access to files is denied"); } diff --git a/module/ASC.Api/ASC.Api.Security/SecurityApi.cs b/module/ASC.Api/ASC.Api.Security/SecurityApi.cs index da2087ab7a..668accfe6d 100644 --- a/module/ASC.Api/ASC.Api.Security/SecurityApi.cs +++ b/module/ASC.Api/ASC.Api.Security/SecurityApi.cs @@ -511,8 +511,7 @@ public string LogOutAllActiveConnectionsChangePassword() [Update("/activeconnections/logoutall/{userId}")] public void LogOutAllActiveConnectionsForUser(Guid userId) { - if (!CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsAdmin() - && !WebItemSecurity.IsProductAdministrator(WebItemManager.PeopleProductID, SecurityContext.CurrentAccount.ID)) + if (!WebItemSecurity.IsProductAdministrator(WebItemManager.PeopleProductID, SecurityContext.CurrentAccount.ID)) throw new SecurityException("Method not available"); LogOutAllActiveConnections(userId); @@ -566,6 +565,19 @@ public bool LogOutActiveConnection(int loginEventId) try { var user = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID); + + var loginEvent = DbLoginEventsManager.GetLoginEvent(user.Tenant, loginEventId); + + if (loginEvent == null) + { + return false; + } + + if (loginEvent.UserId != user.ID && !WebItemSecurity.IsProductAdministrator(WebItemManager.PeopleProductID, user.ID)) + { + throw new SecurityException("Method not available"); + } + var userName = user.DisplayUserName(false); DbLoginEventsManager.LogOutEvent(loginEventId); @@ -606,7 +618,7 @@ public LoginSettings UpdateLoginSettings(int attemptsCount, int blockTime, int c { throw new ArgumentOutOfRangeException("checkPeriod"); } - if (blockTime < 0) + if (blockTime < 1) { throw new ArgumentOutOfRangeException("blockTime"); } diff --git a/module/ASC.Api/ASC.Api.Settings/SettingsApi.cs b/module/ASC.Api/ASC.Api.Settings/SettingsApi.cs index 13a9394527..b4f8b0567d 100644 --- a/module/ASC.Api/ASC.Api.Settings/SettingsApi.cs +++ b/module/ASC.Api/ASC.Api.Settings/SettingsApi.cs @@ -1109,6 +1109,7 @@ private void RestoreWhiteLabelLogosForDefaultTenant(List if (restoreLogoText) { settings.LogoText = null; + settings.ClearAppliedTenants(); } RestoreWhiteLabelLogosForTenant(settings, storage, Tenant.DEFAULT_TENANT, logoTypes); @@ -1412,8 +1413,8 @@ public IEnumerable TfaAppRequestNewCodes() [Update("tfaappnewapp")] public string TfaAppNewApp(Guid id) { - var isMe = id.Equals(Guid.Empty); - var user = CoreContext.UserManager.GetUsers(isMe ? SecurityContext.CurrentAccount.ID : id); + var user = CoreContext.UserManager.GetUsers(id.Equals(Guid.Empty) ? SecurityContext.CurrentAccount.ID : id); + var isMe = user.IsMe(); if (!isMe && !SecurityContext.CheckPermissions(new UserSecurityProvider(user.ID), Core.Users.Constants.Action_EditUser)) throw new SecurityAccessDeniedException(Resource.ErrorAccessDenied); diff --git a/module/ASC.Api/ASC.Employee/EmployeeApi.cs b/module/ASC.Api/ASC.Employee/EmployeeApi.cs index 7e015859dd..bfc90dda4b 100644 --- a/module/ASC.Api/ASC.Employee/EmployeeApi.cs +++ b/module/ASC.Api/ASC.Employee/EmployeeApi.cs @@ -1131,6 +1131,8 @@ public EmployeeWraperFull ChangeUserEmail(Guid userid, string email) CoreContext.UserManager.SaveUserInfo(user, syncCardDav: true); MessageService.Send(Request, MessageAction.UserUpdatedEmail, messageTarget, messageDescription); + CookiesManager.ResetUserCookie(user.ID); + StudioNotifyService.Instance.SendEmailActivationInstructions(user, email); MessageService.Send(HttpContext.Current.Request, MessageAction.UserSentActivationInstructions, messageTarget, messageDescription); } diff --git a/module/ASC.Api/ASC.Specific/ASC.Specific.csproj b/module/ASC.Api/ASC.Specific/ASC.Specific.csproj index 5f35e47d8e..73b26d4922 100644 --- a/module/ASC.Api/ASC.Specific/ASC.Specific.csproj +++ b/module/ASC.Api/ASC.Specific/ASC.Specific.csproj @@ -96,11 +96,6 @@ ASC.FederatedLogin False - - {592eac85-6cfc-4ad7-b653-3eadaa18327e} - ASC.Thrdparty - False - {49f07fff-98a5-47d2-a9e9-a46b98c41245} ASC.Api.Core diff --git a/module/ASC.AuditTrail/AuditEventsRepository.cs b/module/ASC.AuditTrail/AuditEventsRepository.cs index 0947523e66..cd6a922e79 100644 --- a/module/ASC.AuditTrail/AuditEventsRepository.cs +++ b/module/ASC.AuditTrail/AuditEventsRepository.cs @@ -89,15 +89,26 @@ public static IEnumerable GetByFilter( var isNeedFindEntry = entry.HasValue && entry.Value != EntryType.None && target != null; + IEnumerable> actions = new List>(); if (action.HasValue && action.Value != MessageAction.None) { - q.Where("a.action", (int)action); + if (isNeedFindEntry) + { + actions = AuditActionMapper.Mappers + .SelectMany(r => r.Mappers) + .SelectMany(r => r.Actions) + .Where(r => r.Key == action); + + FindByEntry(q, entry.Value, target, actions); + } + else + { + q.Where("a.action", (int)action); + } } else { - IEnumerable> actions = new List>(); - var isFindActionType = actionType.HasValue && actionType.Value != ActionType.None; if (productType.HasValue && productType.Value != ProductType.None) @@ -185,11 +196,11 @@ private static void FindByEntry(SqlQuery q, EntryType entry, string target, IEnu { if (action.Value.EntryType1 == entry) { - sb.Append(string.Format("(a.action = {0} AND SUBSTRING_INDEX(SUBSTRING_INDEX(a.target,',',{1}),',',1) = {2}) OR ", (int)action.Key, -2, target)); + sb.Append(string.Format("(a.action = {0} AND SUBSTRING_INDEX(SUBSTRING_INDEX(a.target,',',{1}),',',1) = '{2}') OR ", (int)action.Key, -2, target)); } if (action.Value.EntryType2 == entry) { - sb.Append(string.Format("(a.action = {0} AND SUBSTRING_INDEX(SUBSTRING_INDEX(a.target,',',{1}),',',1) = {2}) OR ", (int)action.Key, -1, target)); + sb.Append(string.Format("(a.action = {0} AND SUBSTRING_INDEX(SUBSTRING_INDEX(a.target,',',{1}),',',1) = '{2}') OR ", (int)action.Key, -1, target)); } } diff --git a/module/ASC.ElasticSearch/Engine/BaseIndexer.cs b/module/ASC.ElasticSearch/Engine/BaseIndexer.cs index 7f54917177..018be079c7 100644 --- a/module/ASC.ElasticSearch/Engine/BaseIndexer.cs +++ b/module/ASC.ElasticSearch/Engine/BaseIndexer.cs @@ -411,7 +411,7 @@ void IIndexer.Check() async Task IIndexer.ReIndex() { - while (Launcher.IsStarted && Launcher.Indexing.Contains(Wrapper.IndexName)) + while (Launcher.IsStarted && Launcher.Indexing.ContainsKey(Wrapper.IndexName)) { await Task.Delay(10000); } diff --git a/module/ASC.ElasticSearch/Service/Launcher.cs b/module/ASC.ElasticSearch/Service/Launcher.cs index dde3c76ff6..950265a02d 100644 --- a/module/ASC.ElasticSearch/Service/Launcher.cs +++ b/module/ASC.ElasticSearch/Service/Launcher.cs @@ -16,6 +16,7 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.ServiceModel; @@ -41,12 +42,12 @@ public class Launcher : IServiceController internal static ServiceHost Searcher { get; private set; } internal static bool IsStarted { get; private set; } - internal static List Indexing { get; private set; } + internal static ConcurrentDictionary Indexing { get; private set; } internal static DateTime? LastIndexed { get; private set; } static Launcher() { - Indexing = new List(); + Indexing = new ConcurrentDictionary(); } public void Start() @@ -106,9 +107,9 @@ private static void CheckIfChange() if (!IsStarted) return; logger.DebugFormat("Product check {0}", product.IndexName); - Indexing.Add(product.IndexName); + Indexing.TryAdd(product.IndexName, null); product.Check(); - Indexing.Remove(product.IndexName); + Indexing.TryRemove(product.IndexName, out _); } catch (Exception e) { @@ -161,9 +162,9 @@ private static void IndexAll(bool reindex = false) if (!IsStarted) return; logger.DebugFormat("Product {0}", product.IndexName); - Indexing.Add(product.IndexName); + Indexing.TryAdd(product.IndexName, null); product.IndexAll(); - Indexing.Remove(product.IndexName); + Indexing.TryRemove(product.IndexName, out _); } catch (Exception e) { diff --git a/module/ASC.ElasticSearch/Service/Service.cs b/module/ASC.ElasticSearch/Service/Service.cs index 67a287ec8c..7836c967ac 100644 --- a/module/ASC.ElasticSearch/Service/Service.cs +++ b/module/ASC.ElasticSearch/Service/Service.cs @@ -61,7 +61,7 @@ public State GetState() { return new State { - Indexing = Launcher.Indexing, + Indexing = Launcher.Indexing.Keys.ToList(), LastIndexed = Launcher.LastIndexed }; } diff --git a/module/ASC.Files.AutoCleanUp/Worker.cs b/module/ASC.Files.AutoCleanUp/Worker.cs index c97407b84b..8c6d2dfe7c 100644 --- a/module/ASC.Files.AutoCleanUp/Worker.cs +++ b/module/ASC.Files.AutoCleanUp/Worker.cs @@ -140,7 +140,7 @@ private void DeleteFilesAndFolders(TenantUserSettings tenantUser) itemList.AddRange(folderDao.GetFolders(trashId) .Where(x => FileDateTime.GetModifiedOnWithAutoCleanUp(x.ModifiedOn, tenantUser.Setting, true) < now) .Select(f => "folder_" + f.ID)); - itemList.AddRange(fileDao.GetFiles(trashId, null, default(FilterType), false, Guid.Empty, string.Empty, false) + itemList.AddRange(fileDao.GetFiles(trashId, null, default(FilterType), false, Guid.Empty, string.Empty, false, null) .Where(x => FileDateTime.GetModifiedOnWithAutoCleanUp(x.ModifiedOn, tenantUser.Setting, true) < now) .Select(y => "file_" + y.ID)); diff --git a/module/ASC.Files.Thirdparty/Box/BoxFileDao.cs b/module/ASC.Files.Thirdparty/Box/BoxFileDao.cs index e46618c7f8..d705440bbc 100644 --- a/module/ASC.Files.Thirdparty/Box/BoxFileDao.cs +++ b/module/ASC.Files.Thirdparty/Box/BoxFileDao.cs @@ -82,7 +82,7 @@ public List GetFiles(IEnumerable fileIds) return fileIds.Select(GetBoxFile).Select(ToFile).ToList(); } - public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { if (fileIds == null || !fileIds.Any() || filterType == FilterType.FoldersOnly) return new List(); @@ -123,10 +123,11 @@ public List GetFilesFiltered(IEnumerable fileIds, FilterType filte }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -142,7 +143,7 @@ public List GetFiles(object parentId) return GetBoxItems(parentId, false).Select(entry => (object)MakeId(entry.Id)).ToList(); } - public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, bool withSubfolders = false) + public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension, bool withSubfolders = false) { if (filterType == FilterType.FoldersOnly) return new List(); @@ -184,10 +185,11 @@ public List GetFiles(object parentId, OrderBy orderBy, FilterType filterTy }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -487,7 +489,7 @@ public void ReassignFiles(IEnumerable fileIds, Guid newOwnerId) { } - public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { return new List(); } diff --git a/module/ASC.Files.Thirdparty/Dropbox/DropboxFileDao.cs b/module/ASC.Files.Thirdparty/Dropbox/DropboxFileDao.cs index 61a57d1b8a..0ed858c457 100644 --- a/module/ASC.Files.Thirdparty/Dropbox/DropboxFileDao.cs +++ b/module/ASC.Files.Thirdparty/Dropbox/DropboxFileDao.cs @@ -85,7 +85,7 @@ public List GetFiles(IEnumerable fileIds) return fileIds.Select(GetDropboxFile).Select(ToFile).ToList(); } - public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { if (fileIds == null || !fileIds.Any() || filterType == FilterType.FoldersOnly) return new List(); @@ -126,10 +126,11 @@ public List GetFilesFiltered(IEnumerable fileIds, FilterType filte }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -145,7 +146,7 @@ public List GetFiles(object parentId) return GetDropboxItems(parentId, false).Select(entry => (object)MakeId(entry)).ToList(); } - public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, bool withSubfolders = false) + public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension, bool withSubfolders = false) { if (filterType == FilterType.FoldersOnly) return new List(); @@ -187,10 +188,11 @@ public List GetFiles(object parentId, OrderBy orderBy, FilterType filterTy }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -534,7 +536,7 @@ public void ReassignFiles(IEnumerable fileIds, Guid newOwnerId) { } - public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { return new List(); } diff --git a/module/ASC.Files.Thirdparty/GoogleDrive/GoogleDriveFileDao.cs b/module/ASC.Files.Thirdparty/GoogleDrive/GoogleDriveFileDao.cs index 65e622cd8d..921b3e7272 100644 --- a/module/ASC.Files.Thirdparty/GoogleDrive/GoogleDriveFileDao.cs +++ b/module/ASC.Files.Thirdparty/GoogleDrive/GoogleDriveFileDao.cs @@ -81,7 +81,7 @@ public List GetFiles(IEnumerable fileIds) return fileIds.Select(GetDriveEntry).Select(ToFile).ToList(); } - public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { if (fileIds == null || !fileIds.Any() || filterType == FilterType.FoldersOnly) return new List(); @@ -122,10 +122,11 @@ public List GetFilesFiltered(IEnumerable fileIds, FilterType filte }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -141,7 +142,7 @@ public List GetFiles(object parentId) return GetDriveEntries(parentId, false).Select(entry => (object)MakeId(entry.Id)).ToList(); } - public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, bool withSubfolders = false) + public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension, bool withSubfolders = false) { if (filterType == FilterType.FoldersOnly) return new List(); @@ -183,10 +184,11 @@ public List GetFiles(object parentId, OrderBy orderBy, FilterType filterTy }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -535,7 +537,7 @@ public void ReassignFiles(IEnumerable fileIds, Guid newOwnerId) { } - public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { return new List(); } diff --git a/module/ASC.Files.Thirdparty/OneDrive/OneDriveFileDao.cs b/module/ASC.Files.Thirdparty/OneDrive/OneDriveFileDao.cs index 32228017d4..ae8a796998 100644 --- a/module/ASC.Files.Thirdparty/OneDrive/OneDriveFileDao.cs +++ b/module/ASC.Files.Thirdparty/OneDrive/OneDriveFileDao.cs @@ -82,7 +82,7 @@ public List GetFiles(IEnumerable fileIds) return fileIds.Select(GetOneDriveItem).Select(ToFile).ToList(); } - public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { if (fileIds == null || !fileIds.Any() || filterType == FilterType.FoldersOnly) return new List(); @@ -123,10 +123,11 @@ public List GetFilesFiltered(IEnumerable fileIds, FilterType filte }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -142,7 +143,7 @@ public List GetFiles(object parentId) return GetOneDriveItems(parentId, false).Select(entry => (object)MakeId(entry.Id)).ToList(); } - public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, bool withSubfolders = false) + public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension, bool withSubfolders = false) { if (filterType == FilterType.FoldersOnly) return new List(); @@ -184,10 +185,11 @@ public List GetFiles(object parentId, OrderBy orderBy, FilterType filterTy }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -539,7 +541,7 @@ public void ReassignFiles(IEnumerable fileIds, Guid newOwnerId) { } - public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { return new List(); } diff --git a/module/ASC.Files.Thirdparty/ProviderDao/ProviderDaoBase.cs b/module/ASC.Files.Thirdparty/ProviderDao/ProviderDaoBase.cs index eaf9dece37..89f42daa9a 100644 --- a/module/ASC.Files.Thirdparty/ProviderDao/ProviderDaoBase.cs +++ b/module/ASC.Files.Thirdparty/ProviderDao/ProviderDaoBase.cs @@ -236,7 +236,7 @@ protected File PerformCrossDaoFileCopy(object fromFileId, object toFolderId, boo } //Delete source file if needed - fromFileDao.DeleteFile(fromSelector.ConvertId(fromFileId)); + fromFileDao.DeleteFile(fromSelector.ConvertId(fromFileId), fromFile.GetFileQuotaOwner()); } return toFile; } diff --git a/module/ASC.Files.Thirdparty/ProviderDao/ProviderFileDao.cs b/module/ASC.Files.Thirdparty/ProviderDao/ProviderFileDao.cs index 8e640a9618..837416b086 100644 --- a/module/ASC.Files.Thirdparty/ProviderDao/ProviderFileDao.cs +++ b/module/ASC.Files.Thirdparty/ProviderDao/ProviderFileDao.cs @@ -136,7 +136,7 @@ public List GetFiles(IEnumerable fileIds) return result.ToList(); } - public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { var result = Enumerable.Empty(); @@ -153,7 +153,7 @@ public List GetFilesFiltered(IEnumerable fileIds, FilterType filte using (var fileDao = selectorLocal.GetFileDao(matchedId.FirstOrDefault())) { return fileDao.GetFilesFiltered(matchedId.Select(selectorLocal.ConvertId).ToList(), - filterType, subjectGroup, subjectID, searchText, searchInContent); + filterType, subjectGroup, subjectID, searchText, searchInContent, extension); } }) .Where(r => r != null)); @@ -171,13 +171,13 @@ public List GetFiles(object parentId) } } - public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, bool withSubfolders = false) + public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension, bool withSubfolders = false) { var selector = GetSelector(parentId); using (var fileDao = selector.GetFileDao(parentId)) { - var result = fileDao.GetFiles(selector.ConvertId(parentId), orderBy, filterType, subjectGroup, subjectID, searchText, searchInContent, withSubfolders) + var result = fileDao.GetFiles(selector.ConvertId(parentId), orderBy, filterType, subjectGroup, subjectID, searchText, searchInContent, extension, withSubfolders) .Where(r => r != null).ToList(); if (!result.Any()) return new List(); @@ -479,7 +479,7 @@ public void ReassignFiles(IEnumerable fileIds, Guid newOwnerId) } } - public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { var result = Enumerable.Empty(); @@ -496,7 +496,7 @@ public List GetFiles(IEnumerable parentIds, FilterType filterType, using (var fileDao = selectorLocal.GetFileDao(matchedId.FirstOrDefault())) { return fileDao.GetFiles(matchedId.Select(selectorLocal.ConvertId).ToList(), - filterType, subjectGroup, subjectID, searchText, searchInContent); + filterType, subjectGroup, subjectID, searchText, searchInContent, extension); } })); } diff --git a/module/ASC.Files.Thirdparty/SharePoint/SharePointFileDao.cs b/module/ASC.Files.Thirdparty/SharePoint/SharePointFileDao.cs index e15253ca16..d1fe65e0b5 100644 --- a/module/ASC.Files.Thirdparty/SharePoint/SharePointFileDao.cs +++ b/module/ASC.Files.Thirdparty/SharePoint/SharePointFileDao.cs @@ -76,7 +76,7 @@ public List GetFiles(IEnumerable fileIds) return fileIds.Select(fileId => ProviderInfo.ToFile(ProviderInfo.GetFileById(fileId))).ToList(); } - public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { if (fileIds == null || !fileIds.Any() || filterType == FilterType.FoldersOnly) return new List(); @@ -117,10 +117,11 @@ public List GetFilesFiltered(IEnumerable fileIds, FilterType filte }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -136,7 +137,7 @@ public List GetFiles(object parentId) return ProviderInfo.GetFolderFiles(parentId).Select(r => ProviderInfo.ToFile(r).ID).ToList(); } - public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, bool withSubfolders = false) + public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension, bool withSubfolders = false) { if (filterType == FilterType.FoldersOnly) return new List(); @@ -178,10 +179,11 @@ public List GetFiles(object parentId, OrderBy orderBy, FilterType filterTy }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -373,7 +375,7 @@ public void ReassignFiles(IEnumerable fileIds, Guid newOwnerId) { } - public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { return new List(); } diff --git a/module/ASC.Files.Thirdparty/Sharpbox/SharpBoxFileDao.cs b/module/ASC.Files.Thirdparty/Sharpbox/SharpBoxFileDao.cs index 9c859bba17..3872c3bc74 100644 --- a/module/ASC.Files.Thirdparty/Sharpbox/SharpBoxFileDao.cs +++ b/module/ASC.Files.Thirdparty/Sharpbox/SharpBoxFileDao.cs @@ -80,7 +80,7 @@ public List GetFiles(IEnumerable fileIds) return fileIds.Select(fileId => ToFile(GetFileById(fileId))).ToList(); } - public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFilesFiltered(IEnumerable fileIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { if (fileIds == null || !fileIds.Any() || filterType == FilterType.FoldersOnly) return new List(); @@ -121,10 +121,11 @@ public List GetFilesFiltered(IEnumerable fileIds, FilterType filte }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -144,7 +145,7 @@ public List GetFiles(object parentId) .Select(x => (object)MakeId(x)).ToList(); } - public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, bool withSubfolders = false) + public List GetFiles(object parentId, OrderBy orderBy, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension, bool withSubfolders = false) { if (filterType == FilterType.FoldersOnly) return new List(); @@ -186,10 +187,11 @@ public List GetFiles(object parentId, OrderBy orderBy, FilterType filterTy }); break; case FilterType.ByExtension: - if (!string.IsNullOrEmpty(searchText)) + case FilterType.ByExtensionIncludeFolders: + if (!string.IsNullOrEmpty(extension)) { - searchText = searchText.Trim().ToLower(); - files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(searchText)); + extension = extension.Trim().ToLower(); + files = files.Where(x => FileUtility.GetFileExtension(x.Title).Equals(extension)); } break; } @@ -595,7 +597,7 @@ public void ReassignFiles(IEnumerable fileIds, Guid newOwnerId) { } - public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent) + public List GetFiles(IEnumerable parentIds, FilterType filterType, bool subjectGroup, Guid subjectID, string searchText, bool searchInContent, string extension) { return new List(); } diff --git a/module/ASC.Files.ThumbnailBuilder/Builder.cs b/module/ASC.Files.ThumbnailBuilder/Builder.cs index 4d3f52d38c..1a8a200720 100644 --- a/module/ASC.Files.ThumbnailBuilder/Builder.cs +++ b/module/ASC.Files.ThumbnailBuilder/Builder.cs @@ -204,8 +204,7 @@ private bool GetThumbnailUrl(File file, string toExtension, out string url) var thumbnailAspect = config.ThumbnailAspect; var thumbnail = GetThumbnailData(thumbnailAspect); var spreadsheetLayout = GetSpreadsheetLayout(thumbnailAspect); - - var operationResultProgress = DocumentServiceConnector.GetConvertedUri(fileUri, fileExtension, toExtension, docKey, null, null, thumbnail, spreadsheetLayout, false, out url); + var operationResultProgress = DocumentServiceConnector.GetConvertedUri(fileUri, fileExtension, toExtension, docKey, null, null, thumbnail, spreadsheetLayout, false, out url, out _); operationResultProgress = Math.Min(operationResultProgress, 100); return operationResultProgress == 100; diff --git a/module/ASC.Files.ThumbnailBuilder/ConfigSection.cs b/module/ASC.Files.ThumbnailBuilder/ConfigSection.cs index fa9b306179..9fa32f3c57 100644 --- a/module/ASC.Files.ThumbnailBuilder/ConfigSection.cs +++ b/module/ASC.Files.ThumbnailBuilder/ConfigSection.cs @@ -47,7 +47,7 @@ public string ConnectionStringName get { return (string)this["connectionStringName"]; } } - [ConfigurationProperty("formats", DefaultValue = ".pptx|.pptm|.ppt|.ppsx|.ppsm|.pps|.potx|.potm|.pot|.odp|.fodp|.otp|.gslides|.xlsx|.xlsm|.xls|.xltx|.xltm|.xlt|.ods|.fods|.ots|.gsheet|.csv|.docx|.docxf|.oform|.docm|.doc|.dotx|.dotm|.dot|.odt|.fodt|.ott|.gdoc|.txt|.rtf|.mht|.html|.htm|.fb2|.epub|.pdf|.djvu|.xps|.oxps|.bmp|.jpeg|.jpg|.png|.gif|.tiff|.tif|.ico")] + [ConfigurationProperty("formats", DefaultValue = ".dps|.dpt|.fodp|.odp|.otp|.pot|.potm|.potx|.pps|.ppsm|.ppsx|.ppt|.pptm|.pptx|.sxi|.csv|.et|.ett|.fods|.ods|.ots|.sxc|.xls|.xlsb|.xlsm|.xlsx|.xlt|.xltm|.xltx|.xml|.djvu|.doc|.docm|.docx|.docxf|.oform|.dot|.dotm|.dotx|.epub|.fb2|.fodt|.htm|.html|.mht|.mhtml|.odt|.ott|.oxps|.pdf|.rtf|.stw|.sxw|.txt|.wps|.wpt|.xml|.xps|.bmp|.jpeg|.jpg|.png|.gif|.tiff|.tif|.ico")] public string Formats { get { return (string)this["formats"]; } diff --git a/module/ASC.Mail/ASC.Mail/ASC.Mail.csproj b/module/ASC.Mail/ASC.Mail/ASC.Mail.csproj index 16eb2a74cf..077dd312c2 100644 --- a/module/ASC.Mail/ASC.Mail/ASC.Mail.csproj +++ b/module/ASC.Mail/ASC.Mail/ASC.Mail.csproj @@ -558,7 +558,7 @@ 1.6.0.1 - 4.1.11 + 4.2.0 2.15.0 @@ -575,6 +575,9 @@ 106.12.0 + + 4.3.0 + 1.1.0 diff --git a/module/ASC.Mail/ASC.Mail/Utils/MailUtil.cs b/module/ASC.Mail/ASC.Mail/Utils/MailUtil.cs index 48330f0fd9..1fe5752813 100644 --- a/module/ASC.Mail/ASC.Mail/Utils/MailUtil.cs +++ b/module/ASC.Mail/ASC.Mail/Utils/MailUtil.cs @@ -225,7 +225,7 @@ public static string SerializeCalendar(Ical.Net.Calendar calendar) { try { - var serializer = new Ical.Net.Serialization.CalendarSerializer(calendar); + var serializer = new Ical.Net.Serialization.ComponentSerializer(); return serializer.SerializeToString(calendar); } catch (Exception) diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/ASC.Mail.Aggregator.CollectionService.csproj b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/ASC.Mail.Aggregator.CollectionService.csproj deleted file mode 100644 index b9be43196f..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/ASC.Mail.Aggregator.CollectionService.csproj +++ /dev/null @@ -1,147 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {2EBFAA3E-AF1D-4A30-B16A-4E8AE053E063} - Exe - Properties - ASC.Mail.Aggregator.CollectionService - ASC.Mail.Aggregator.CollectionService - v4.8 - 512 - - - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - bin\$(Configuration)\ - - - true - full - false - DEBUG;TRACE - prompt - 4 - false - false - bin\Debug\ASC.Mail.Aggregator.CollectionService.xml - CS1591 - - - none - true - TRACE - prompt - 4 - false - false - - - - Component - - - - - - - - - - - - - - - - web.consumers.config - PreserveNewest - Designer - - - web.autofac.config - PreserveNewest - - - Designer - Always - - - PreserveNewest - Designer - - - PreserveNewest - Designer - - - - - {76de7717-3d4b-4a5b-b740-15b8913df0cb} - ASC.Common - - - {a51d0454-4afa-46de-89d4-b03d37e1816c} - ASC.Core.Common - - - {448851d4-e525-4acc-9ae4-7aec289445bc} - ASC.Data.Encryption - - - {3f6b420f-abd3-4b5a-9f4c-5d61ffbb01de} - ASC.Data.Storage - - - {ae1a0e06-6cd4-4e1d-8209-22bbbd6d5652} - ASC.ElasticSearch - - - {7080343d-fbe7-423a-9405-4f883f6e235b} - ASC.Mail - - - - - 2.8.0 - - - 5.0.11 - - - 2.0.9 - - - 2.15.0 - - - 0.8.5 - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/AggregatorService.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/AggregatorService.cs deleted file mode 100644 index 6938acc7f8..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/AggregatorService.cs +++ /dev/null @@ -1,1119 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Configuration; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Net; -using System.ServiceModel; -using System.ServiceProcess; -using System.Threading; -using System.Threading.Tasks; - -using ASC.Core; -using ASC.Mail.Aggregator.CollectionService.Queue; -using ASC.Mail.Aggregator.CollectionService.Queue.Data; -using ASC.Mail.Clients; -using ASC.Mail.Core; -using ASC.Mail.Core.Dao.Expressions.Mailbox; -using ASC.Mail.Core.Engine; -using ASC.Mail.Data.Contracts; -using ASC.Mail.Data.Storage; -using ASC.Mail.Extensions; -using ASC.Mail.Utils; - -using MailKit.Net.Imap; -using MailKit.Net.Pop3; -using MailKit.Security; - -using MimeKit; - -using ILog = ASC.Common.Logging.ILog; -using LogManager = ASC.Common.Logging.LogManager; - -namespace ASC.Mail.Aggregator.CollectionService -{ - public sealed class AggregatorService : ServiceBase - { - public const string ASC_MAIL_COLLECTION_SERVICE_NAME = "ASC Mail Collection Service"; - - private const string S_FAIL = "error"; - private const string S_OK = "success"; - - private const string PROCESS_MESSAGE = "process message"; - private const string PROCESS_MAILBOX = "process mailbox"; - private const string CONNECT_MAILBOX = "connect mailbox"; - - private readonly ILog _log; - private readonly ILog _logStat; - private readonly CancellationTokenSource _cancelTokenSource; - private ManualResetEvent _resetEvent; - private Timer _workTimer; - private readonly TasksConfig _tasksConfig; - private readonly QueueManager _queueManager; - readonly TaskFactory _taskFactory; - private readonly TimeSpan _tsTaskStateCheckInterval; - private bool _isFirstTime = true; - private static SignalrWorker _signalrWorker; - private const int SIGNALR_WAIT_SECONDS = 30; - private readonly TimeSpan _taskSecondsLifetime; - private ServiceHost _healthCheckServiceHost; - - public ConcurrentDictionary> Filters { get; set; } - - public AggregatorService(Options options) - { - ServiceName = ASC_MAIL_COLLECTION_SERVICE_NAME; - EventLog.Log = "Application"; - - // These Flags set whether or not to handle that specific - // type of event. Set to true if you need it, false otherwise. - CanHandlePowerEvent = false; - CanHandleSessionChangeEvent = false; - CanPauseAndContinue = false; - CanShutdown = true; - CanStop = true; - try - { - _log = LogManager.GetLogger("ASC.Mail.MainThread"); - - _logStat = LogManager.GetLogger("ASC.Mail.Stat"); - - _tasksConfig = TasksConfig.FromConfig; - - var mailSettings = new MailQueueItemSettings(); - - _tasksConfig.DefaultFolders = mailSettings.DefaultFolders; - - _tasksConfig.ImapFlags = mailSettings.ImapFlags; - - _tasksConfig.SkipImapFlags = mailSettings.SkipImapFlags; - - _tasksConfig.SpecialDomainFolders = mailSettings.SpecialDomainFolders; - - if (options.OnlyUsers != null) - _tasksConfig.WorkOnUsersOnly.AddRange(options.OnlyUsers.ToList()); - - if (options.NoMessagesLimit) - _tasksConfig.MaxMessagesPerSession = -1; - - _taskSecondsLifetime = - TimeSpan.FromSeconds(ConfigurationManagerExtension.AppSettings["mail.task-process-lifetime-seconds"] != null - ? Convert.ToInt32(ConfigurationManagerExtension.AppSettings["mail.task-process-lifetime-seconds"]) - : 300); - - _queueManager = new QueueManager(_tasksConfig, _log); - - _cancelTokenSource = new CancellationTokenSource(); - - _taskFactory = new TaskFactory(); - - _tsTaskStateCheckInterval = ConfigurationManagerExtension.AppSettings["mail.task-check-state-seconds"] != null - ? TimeSpan.FromSeconds( - Convert.ToInt32(ConfigurationManagerExtension.AppSettings["mail.task-check-state-seconds"])) - : TimeSpan.FromSeconds(30); - - if (_tasksConfig.EnableSignalr) - _signalrWorker = new SignalrWorker(); - - _workTimer = new Timer(workTimer_Elapsed, _cancelTokenSource.Token, Timeout.Infinite, Timeout.Infinite); - - Filters = new ConcurrentDictionary>(); - - _log.Info("Service is ready."); - } - catch (Exception ex) - { - _log.FatalFormat("CollectorService error under construct: {0}", ex.ToString()); - - throw ex; - } - } - - #region - Overrides base - - - /// - /// OnStart(): Put startup code here - /// - Start threads, get inital data, etc. - /// - /// - protected override void OnStart(string[] args) - { - try - { - _log.Info("Start service\r\n"); - - base.OnStart(args); - - _healthCheckServiceHost = new ServiceHost(typeof(HealthCheckService)); - _healthCheckServiceHost.Open(); - - StartTimer(true); - } - catch (Exception ex) - { - _log.Fatal("OnStart", ex); - OnStop(); - } - } - - /// - /// OnStop(): Put your stop code here - /// - Stop threads, set final data, etc. - /// - protected override void OnStop() - { - try - { - _log.Info("Stoping service\r\n"); - - if (_cancelTokenSource != null) - _cancelTokenSource.Cancel(); - - if (_queueManager != null) - _queueManager.CancelHandler.WaitOne(); - - StopTimer(); - - if (_workTimer != null) - { - _workTimer.Dispose(); - _workTimer = null; - } - - if (_queueManager != null) - _queueManager.Dispose(); - - if (_signalrWorker != null) - _signalrWorker.Dispose(); - } - catch (Exception ex) - { - _log.ErrorFormat("Stop service Error: {0}\r\n", ex.ToString()); - } - finally - { - _log.Info("Stop service\r\n"); - - base.OnStop(); - - if (_resetEvent != null) - _resetEvent.Set(); - - if (_healthCheckServiceHost != null) - { - _healthCheckServiceHost.Close(); - _healthCheckServiceHost = null; - } - - } - } - - /// - /// OnShutdown(): Called when the System is shutting down - /// - Put code here when you need special handling - /// of code that deals with a system shutdown, such - /// as saving special data before shutdown. - /// - protected override void OnShutdown() - { - _log.Info("Service shutdown."); - OnStop(); - base.OnShutdown(); - } - - /// - /// OnPowerEvent(): Useful for detecting power status changes, - /// such as going into Suspend mode or Low Battery for laptops. - /// - /// The Power Broadcast Status - /// (BatteryLow, Suspend, etc.) - protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus) - { - _log.InfoFormat("Service power event detected = {0}.", powerStatus.ToString()); - - if (powerStatus == PowerBroadcastStatus.Suspend) - { - OnStop(); - } - return base.OnPowerEvent(powerStatus); - } - - /// - /// Start service in console mode. - /// - public void StartConsole() - { - _log.Info("Service Start in console-daemon mode"); - OnStart(null); - _resetEvent = new ManualResetEvent(false); - Console.CancelKeyPress += (sender, e) => OnStop(); - _resetEvent.WaitOne(); - } - - #endregion - - #region - Timer_Elapsed - - - private void workTimer_Elapsed(object state) - { - _log.Debug("Timer->workTimer_Elapsed"); - - var cancelToken = state as CancellationToken? ?? new CancellationToken(); - - try - { - if (_isFirstTime) - { - _queueManager.LoadMailboxesFromDump(); - - if (_queueManager.ProcessingCount > 0) - { - _log.InfoFormat("Found {0} tasks to release", _queueManager.ProcessingCount); - - _queueManager.ReleaseAllProcessingMailboxes(); - } - - _queueManager.LoadTenantsFromDump(); - - _isFirstTime = false; - } - - if (cancelToken.IsCancellationRequested) - { - _log.Debug("Timer->workTimer_Elapsed: IsCancellationRequested. Quit."); - return; - } - - if (_workTimer == null) - { - _log.Debug("Timer->workTimer_Elapsed: _workTimer == null. Quit."); - OnStop(); - return; - } - - StopTimer(); - - var tasks = CreateTasks(_tasksConfig.MaxTasksAtOnce, cancelToken); - - // ***Add a loop to process the tasks one at a time until none remain. - while (tasks.Any()) - { - // Identify the first task that completes. - var indexTask = Task.WaitAny(tasks.Select(t => t.Task).ToArray(), (int)_tsTaskStateCheckInterval.TotalMilliseconds, cancelToken); - if (indexTask > -1) - { - // ***Remove the selected task from the list so that you don't - // process it more than once. - var outTask = tasks[indexTask]; - - FreeTask(outTask, tasks); - } - else - { - _log.InfoFormat("Task.WaitAny timeout. Tasks count = {0}\r\nTasks:\r\n{1}", tasks.Count, - string.Join("\r\n", - tasks.Select( - t => - string.Format("Id: {0} Status: {1}, MailboxId: {2} Address: '{3}'", - t.Task.Id, t.Task.Status, t.Mailbox.MailBoxId, t.Mailbox.EMail)))); - } - - var tasks2Free = - tasks.Where( - t => - t.Task.Status == TaskStatus.Canceled || t.Task.Status == TaskStatus.Faulted || - t.Task.Status == TaskStatus.RanToCompletion).ToList(); - - if (tasks2Free.Any()) - { - _log.InfoFormat("Need free next tasks = {0}: ({1})", tasks2Free.Count, - string.Join(",", - tasks2Free.Select(t => t.Task.Id.ToString(CultureInfo.InvariantCulture)))); - - tasks2Free.ForEach(task => FreeTask(task, tasks)); - } - - var difference = _tasksConfig.MaxTasksAtOnce - tasks.Count; - - if (difference <= 0) continue; - - var newTasks = CreateTasks(difference, cancelToken); - - tasks.AddRange(newTasks); - - _log.InfoFormat("Total tasks count = {0} ({1}).", tasks.Count, - string.Join(",", tasks.Select(t => t.Task.Id))); - } - - _log.Info("All mailboxes were processed. Go back to timer."); - } - catch (Exception ex) - { - if (ex is AggregateException) - { - ex = ((AggregateException)ex).GetBaseException(); - } - - if (ex is TaskCanceledException || ex is OperationCanceledException) - { - _log.Info("Execution was canceled."); - - _queueManager.ReleaseAllProcessingMailboxes(); - - _queueManager.CancelHandler.Set(); - - return; - } - - _log.ErrorFormat("Timer->workTimer_Elapsed. Exception:\r\n{0}\r\n", ex.ToString()); - - if (_queueManager.ProcessingCount != 0) - { - _queueManager.ReleaseAllProcessingMailboxes(); - } - } - - _queueManager.CancelHandler.Set(); - - StartTimer(); - } - - private void StartTimer(bool immediately = false) - { - if (_workTimer == null) - return; - - _log.DebugFormat("Setup _workTimer to {0} seconds", _tasksConfig.CheckTimerInterval.TotalSeconds); - if (immediately) - { - _workTimer.Change(0, Timeout.Infinite); - } - else - { - _workTimer.Change(_tasksConfig.CheckTimerInterval, _tasksConfig.CheckTimerInterval); - } - } - - private void StopTimer() - { - if (_workTimer == null) - return; - - _log.Debug("Setup _workTimer to Timeout.Infinite"); - _workTimer.Change(Timeout.Infinite, Timeout.Infinite); - } - - private void NotifySignalrIfNeed(MailBoxData mailbox, ILog log) - { - if (!_tasksConfig.EnableSignalr) - { - log.Debug("Skip NotifySignalrIfNeed: EnableSignalr == false"); - - return; - } - - var now = DateTime.UtcNow; - - try - { - if (mailbox.LastSignalrNotify.HasValue && - !((now - mailbox.LastSignalrNotify.Value).TotalSeconds > SIGNALR_WAIT_SECONDS)) - { - mailbox.LastSignalrNotifySkipped = true; - - log.InfoFormat( - "Skip NotifySignalrIfNeed: last notification has occurend less then {0} seconds ago", - SIGNALR_WAIT_SECONDS); - - return; - } - - if (_signalrWorker == null) - throw new NullReferenceException("_signalrWorker"); - - _signalrWorker.AddMailbox(mailbox); - - log.InfoFormat("NotifySignalrIfNeed(UserId = {0} TenantId = {1}) has been succeeded", - mailbox.UserId, mailbox.TenantId); - } - catch (Exception ex) - { - log.ErrorFormat("NotifySignalrIfNeed(UserId = {0} TenantId = {1}) Exception: {2}", mailbox.UserId, - mailbox.TenantId, ex.ToString()); - } - - mailbox.LastSignalrNotify = now; - mailbox.LastSignalrNotifySkipped = false; - } - - private List CreateTasks(int needCount, CancellationToken cancelToken) - { - _log.InfoFormat("CreateTasks(need {0} tasks).", needCount); - - var mailboxes = _queueManager.GetLockedMailboxes(needCount); - - var tasks = new List(); - - foreach (var mailbox in mailboxes) - { - var timeoutCancel = new CancellationTokenSource(_taskSecondsLifetime); - - var commonCancelToken = - CancellationTokenSource.CreateLinkedTokenSource(cancelToken, timeoutCancel.Token).Token; - - var taskLogger = LogManager.GetLogger(string.Format("ASC.Mail Mbox_{0}", mailbox.MailBoxId)); - - taskLogger.InfoFormat("CreateMailClient(Tenant = {0} MailboxId = {1}, Address = '{2}')", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail); - - var client = CreateMailClient(mailbox, taskLogger, commonCancelToken); - - if (client == null || !client.IsConnected || !client.IsAuthenticated) - { - if (client != null) - taskLogger.InfoFormat("Client -> Could not connect: {0} | Not authenticated: {1}.", - !client.IsConnected ? "Yes" : "No", - !client.IsAuthenticated ? "Yes" : "No"); - else taskLogger.InfoFormat("Client was null"); - - taskLogger.InfoFormat("ReleaseMailbox(Tenant = {0} MailboxId = {1}, Address = '{2}')", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail); - ReleaseMailbox(mailbox); - continue; - } - - var task = _taskFactory.StartNew(() => ProcessMailbox(client, _tasksConfig), - commonCancelToken); - - tasks.Add(new TaskData(mailbox, task)); - } - - if (tasks.Any()) - _log.InfoFormat("Created {0} tasks.", tasks.Count); - else - _log.Info("No more mailboxes for processing."); - - return tasks; - } - - private MailClient CreateMailClient(MailBoxData mailbox, ILog log, CancellationToken cancelToken) - { - MailClient client = null; - - var connectError = false; - var stopClient = false; - - Stopwatch watch = null; - - if (_tasksConfig.CollectStatistics) - { - watch = new Stopwatch(); - watch.Start(); - } - - try - { - client = new MailClient(mailbox, cancelToken, _tasksConfig.TcpTimeout, - mailbox.IsTeamlab || _tasksConfig.SslCertificateErrorsPermit, _tasksConfig.ProtocolLogPath, log, true); - - log.DebugFormat("MailClient.LoginImapPop(Tenant = {0}, MailboxId = {1} Address = '{2}')", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail); - - if (!mailbox.Imap) - { - client.FuncGetPop3NewMessagesIDs = - uidls => MessageEngine.GetPop3NewMessagesIDs(mailbox, uidls, _tasksConfig.ChunkOfPop3Uidl); - } - - client.Authenticated += ClientOnAuthenticated; - - client.LoginImapPop(); - } - catch (System.TimeoutException exTimeout) - { - log.WarnFormat( - "[TIMEOUT] CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, exTimeout.ToString()); - - connectError = true; - stopClient = true; - } - catch (OperationCanceledException) - { - log.InfoFormat( - "[CANCEL] CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}')", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail); - stopClient = true; - } - catch (AuthenticationException authEx) - { - log.ErrorFormat( - "CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}')\r\nException: {3}\r\n", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, authEx.ToString()); - - connectError = true; - stopClient = true; - } - catch (WebException webEx) - { - log.ErrorFormat( - "CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}')\r\nException: {3}\r\n", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, webEx.ToString()); - - connectError = true; - stopClient = true; - } - catch (ImapProtocolException protocolEx) - { - log.ErrorFormat( - $"CreateTasks() -> MailClient.LoginImap(Tenant = {mailbox.TenantId}, MailboxId = {mailbox.MailBoxId}, Address = \"{mailbox.EMail}\")\r\nThe box will be disabled.\r\nImap Protocol Exception: {protocolEx}\r\n"); - - connectError = true; - stopClient = true; - } - catch (Exception ex) - { - log.ErrorFormat( - "CreateTasks->client.LoginImapPop(Tenant = {0}, MailboxId = {1}, Address = '{2}')\r\nException: {3}\r\n", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, - ex is ImapProtocolException || ex is Pop3ProtocolException ? ex.Message : ex.ToString()); - - stopClient = true; - } - finally - { - if (connectError) - { - SetMailboxAuthError(mailbox, log); - } - - if (stopClient) - { - CloseMailClient(client, mailbox, log); - } - - if (_tasksConfig.CollectStatistics && watch != null) - { - watch.Stop(); - - LogStat(CONNECT_MAILBOX, mailbox, watch.Elapsed, connectError); - } - } - - return client; - } - - private static void SetMailboxAuthError(MailBoxData mailbox, ILog log) - { - try - { - if (mailbox.AuthErrorDate.HasValue) - return; - - mailbox.AuthErrorDate = DateTime.UtcNow; - - var engine = new EngineFactory(mailbox.TenantId); - engine.MailboxEngine.SetMaiboxAuthError(mailbox.MailBoxId, mailbox.AuthErrorDate.Value); - } - catch (Exception ex) - { - log.ErrorFormat( - "CreateTasks->SetMailboxAuthError(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, ex.Message); - } - } - - private void CloseMailClient(MailClient client, MailBoxData mailbox, ILog log) - { - if (client == null) - return; - - try - { - client.Authenticated -= ClientOnAuthenticated; - client.GetMessage -= ClientOnGetMessage; - - client.Cancel(); - client.Dispose(); - } - catch (Exception ex) - { - log.ErrorFormat( - "CloseMailClient(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, ex.Message); - } - } - - private void ProcessMailbox(MailClient client, TasksConfig tasksConfig) - { - var mailbox = client.Account; - - Stopwatch watch = null; - - if (_tasksConfig.CollectStatistics) - { - watch = new Stopwatch(); - watch.Start(); - } - - var failed = false; - - var taskLogger = LogManager.GetLogger(string.Format("ASC.Mail Mbox_{0}", mailbox.MailBoxId)); - - taskLogger.InfoFormat( - "ProcessMailbox(Tenant = {0}, MailboxId = {1} Address = '{2}') Is {3}", - mailbox.TenantId, mailbox.MailBoxId, - mailbox.EMail, mailbox.Active ? "Active" : "Inactive"); - - try - { - client.Log = taskLogger; - - client.GetMessage += ClientOnGetMessage; - - client.Aggregate(tasksConfig, tasksConfig.MaxMessagesPerSession); - } - catch (OperationCanceledException) - { - taskLogger.InfoFormat( - "[CANCEL] ProcessMailbox(Tenant = {0}, MailboxId = {1}, Address = '{2}')", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail); - - NotifySignalrIfNeed(mailbox, taskLogger); - } - catch (Exception ex) - { - taskLogger.ErrorFormat( - "ProcessMailbox(Tenant = {0}, MailboxId = {1}, Address = '{2}')\r\nException: {3}\r\n", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, - ex is ImapProtocolException || ex is Pop3ProtocolException ? ex.Message : ex.ToString()); - - failed = true; - } - finally - { - CloseMailClient(client, mailbox, _log); - - if (_tasksConfig.CollectStatistics && watch != null) - { - watch.Stop(); - - LogStat(PROCESS_MAILBOX, mailbox, watch.Elapsed, failed); - } - } - - var state = GetMailboxState(mailbox, taskLogger); - - switch (state) - { - case MailboxState.NoChanges: - taskLogger.InfoFormat("MailBox with id={0} not changed.", mailbox.MailBoxId); - break; - case MailboxState.Disabled: - taskLogger.InfoFormat("MailBox with id={0} is deactivated.", mailbox.MailBoxId); - break; - case MailboxState.Deleted: - taskLogger.InfoFormat("MailBox with id={0} is removed.", mailbox.MailBoxId); - - try - { - taskLogger.InfoFormat("RemoveMailBox(id={0}) >> Try clear new data from removed mailbox", mailbox.MailBoxId); - - var engine = new EngineFactory(mailbox.TenantId, mailbox.UserId); - engine.MailboxEngine.RemoveMailBox(mailbox); - } - catch (Exception exRem) - { - taskLogger.InfoFormat( - "[REMOVE] ProcessMailbox->RemoveMailBox(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, exRem.Message); - } - break; - case MailboxState.DateChanged: - taskLogger.InfoFormat("MailBox with id={0}: beginDate was changed.", mailbox.MailBoxId); - break; - default: - throw new ArgumentOutOfRangeException(); - } - - taskLogger.InfoFormat("Mailbox '{0}' has been processed.", mailbox.EMail); - } - - private static void ClientOnAuthenticated(object sender, MailClientEventArgs mailClientEventArgs) - { - if (!mailClientEventArgs.Mailbox.AuthErrorDate.HasValue) - return; - - mailClientEventArgs.Mailbox.AuthErrorDate = null; - - var engine = new EngineFactory(mailClientEventArgs.Mailbox.TenantId); - engine.MailboxEngine.SetMaiboxAuthError(mailClientEventArgs.Mailbox.MailBoxId, mailClientEventArgs.Mailbox.AuthErrorDate); - } - - private void ClientOnGetMessage(object sender, MailClientMessageEventArgs mailClientMessageEventArgs) - { - var log = _log; - - Stopwatch watch = null; - - if (_tasksConfig.CollectStatistics) - { - watch = new Stopwatch(); - watch.Start(); - } - - var failed = false; - - var mailbox = mailClientMessageEventArgs.Mailbox; - - try - { - var mimeMessage = mailClientMessageEventArgs.Message; - var uid = mailClientMessageEventArgs.MessageUid; - var folder = mailClientMessageEventArgs.Folder; - var unread = mailClientMessageEventArgs.Unread; - log = mailClientMessageEventArgs.Logger; - - var uidl = mailbox.Imap ? string.Format("{0}-{1}", uid, (int)folder.Folder) : uid; - - log.InfoFormat("Found message (UIDL: '{0}', MailboxId = {1}, Address = '{2}')", - uidl, mailbox.MailBoxId, mailbox.EMail); - - CoreContext.TenantManager.SetCurrentTenant(mailbox.TenantId); - SecurityContext.CurrentUser = new Guid(mailbox.UserId); - - var message = MessageEngine.Save(mailbox, mimeMessage, uidl, folder, null, unread, log); - - if (message == null || message.Id <= 0) - { - return; - } - - log.InfoFormat("Message saved (id: {0}, From: '{1}', Subject: '{2}', Unread: {3})", - message.Id, message.From, message.Subject, message.IsNew); - - log.Info("DoOptionalOperations->START"); - - DoOptionalOperations(message, mimeMessage, mailbox, folder, log); - - log.Info("DoOptionalOperations->END"); - } - catch (Exception ex) - { - log.ErrorFormat("[ClientOnGetMessage] Exception:\r\n{0}\r\n", ex.ToString()); - - failed = true; - - throw ex; - } - finally - { - if (_tasksConfig.CollectStatistics && watch != null) - { - watch.Stop(); - - LogStat(PROCESS_MESSAGE, mailbox, watch.Elapsed, failed); - } - } - } - - enum MailboxState - { - NoChanges, - Disabled, - Deleted, - DateChanged - } - - private static MailboxState GetMailboxState(MailBoxData mailbox, ILog log) - { - try - { - log.Debug("GetMailBoxState()"); - - var engine = new EngineFactory(-1); - var status = engine.MailboxEngine.GetMailboxStatus(new СoncreteUserMailboxExp(mailbox.MailBoxId, mailbox.TenantId, mailbox.UserId, null)); - - if (mailbox.BeginDate != status.BeginDate) - { - mailbox.BeginDateChanged = true; - mailbox.BeginDate = status.BeginDate; - - return MailboxState.DateChanged; - } - - if (status.IsRemoved) - return MailboxState.Deleted; - - if (!status.Enabled) - return MailboxState.Disabled; - } - catch (Exception exGetMbInfo) - { - log.InfoFormat("GetMailBoxState(Tenant = {0}, MailboxId = {1}, Address = '{2}') Exception: {3}", - mailbox.TenantId, mailbox.MailBoxId, mailbox.EMail, exGetMbInfo.Message); - } - - return MailboxState.NoChanges; - } - - private readonly ConcurrentDictionary _userCrmAvailabeDictionary = new ConcurrentDictionary(); - private readonly object _locker = new object(); - - private bool IsCrmAvailable(MailBoxData mailbox, ILog log) - { - bool crmAvailable; - - lock (_locker) - { - if (_userCrmAvailabeDictionary.TryGetValue(mailbox.UserId, out crmAvailable)) - return crmAvailable; - - crmAvailable = mailbox.IsCrmAvailable(_tasksConfig.DefaultApiSchema, log); - _userCrmAvailabeDictionary.GetOrAdd(mailbox.UserId, crmAvailable); - } - - return crmAvailable; - } - - private List GetFilters(EngineFactory factory, ILog log) - { - var user = factory.UserId; - - if (string.IsNullOrEmpty(user)) - return new List(); - - try - { - if (Filters.ContainsKey(user)) return Filters[user]; - - var filters = factory.FilterEngine.GetList(); - - Filters.TryAdd(user, filters); - - return filters; - } - catch (Exception ex) - { - log.Error("GetFilters failed", ex); - } - - return new List(); - } - - private void DoOptionalOperations(MailMessageData message, MimeMessage mimeMessage, MailBoxData mailbox, MailFolder folder, ILog log) - { - try - { - var factory = new EngineFactory(mailbox.TenantId, mailbox.UserId, log); - - var tagIds = new List(); - - if (folder.Tags.Any()) - { - log.Debug("DoOptionalOperations->GetOrCreateTags()"); - - tagIds = factory.TagEngine.GetOrCreateTags(mailbox.TenantId, mailbox.UserId, folder.Tags); - } - - log.Debug("DoOptionalOperations->IsCrmAvailable()"); - - if (IsCrmAvailable(mailbox, log)) - { - log.Debug("DoOptionalOperations->GetCrmTags()"); - - var crmTagIds = factory.TagEngine.GetCrmTags(message.FromEmail); - - if (crmTagIds.Any()) - { - if (tagIds == null) - tagIds = new List(); - - tagIds.AddRange(crmTagIds.Select(t => t.Id)); - } - } - - if (tagIds.Any()) - { - if (message.TagIds == null || !message.TagIds.Any()) - message.TagIds = tagIds; - else - message.TagIds.AddRange(tagIds); - - message.TagIds = message.TagIds.Distinct().ToList(); - } - - log.Debug("DoOptionalOperations->AddMessageToIndex()"); - - var wrapper = message.ToMailWrapper(mailbox.TenantId, new Guid(mailbox.UserId)); - - factory.IndexEngine.Add(wrapper); - - foreach (var tagId in tagIds) - { - try - { - log.DebugFormat("DoOptionalOperations->SetMessagesTag(tagId: {0})", tagId); - - factory.TagEngine.SetMessagesTag(new List { message.Id }, tagId); - } - catch (Exception e) - { - log.ErrorFormat( - "SetMessagesTag(tenant={0}, userId='{1}', messageId={2}, tagid = {3}) Exception:\r\n{4}\r\n", - mailbox.TenantId, mailbox.UserId, message.Id, e.ToString(), - tagIds != null ? string.Join(",", tagIds) : "null"); - } - } - - log.Debug("DoOptionalOperations->AddRelationshipEventForLinkedAccounts()"); - - factory.CrmLinkEngine.AddRelationshipEventForLinkedAccounts(mailbox, message, _tasksConfig.DefaultApiSchema); - - log.Debug("DoOptionalOperations->SaveEmailInData()"); - - factory.EmailInEngine.SaveEmailInData(mailbox, message, _tasksConfig.DefaultApiSchema); - - log.Debug("DoOptionalOperations->SendAutoreply()"); - - factory.AutoreplyEngine.SendAutoreply(mailbox, message, _tasksConfig.DefaultApiSchema, log); - - log.Debug("DoOptionalOperations->UploadIcsToCalendar()"); - - if (folder.Folder != Enums.FolderType.Spam) - { - factory - .CalendarEngine - .UploadIcsToCalendar(mailbox, message.CalendarId, message.CalendarUid, message.CalendarEventIcs, - message.CalendarEventCharset, message.CalendarEventMimeType, message.Attachments, mimeMessage.Attachments, mailbox.EMail.Address, - _tasksConfig.DefaultApiSchema); - } - - if (_tasksConfig.SaveOriginalMessage) - { - log.Debug("DoOptionalOperations->StoreMailEml()"); - StoreMailEml(mailbox.TenantId, mailbox.UserId, message.StreamId, mimeMessage, log); - } - - log.Debug("DoOptionalOperations->ApplyFilters()"); - - var filters = GetFilters(factory, log); - - factory.FilterEngine.ApplyFilters(message, mailbox, folder, filters); - - log.Debug("DoOptionalOperations->NotifySignalrIfNeed()"); - - NotifySignalrIfNeed(mailbox, log); - } - catch (Exception ex) - { - log.ErrorFormat("DoOptionalOperations() Exception:\r\n{0}\r\n", ex.ToString()); - } - } - - public string StoreMailEml(int tenant, string user, string streamId, MimeMessage message, ILog log) - { - if (message == null) - return string.Empty; - - // Using id_user as domain in S3 Storage - allows not to add quota to tenant. - var savePath = MailStoragePathCombiner.GetEmlKey(user, streamId); - var storage = MailDataStore.GetDataStore(tenant); - - try - { - using (var stream = new MemoryStream()) - { - message.WriteTo(stream); - - var res = storage.Save(savePath, stream, MailStoragePathCombiner.EML_FILE_NAME).ToString(); - - log.InfoFormat("StoreMailEml() tenant='{0}', user_id='{1}', save_eml_path='{2}' Result: {3}", tenant, user, savePath, res); - - return res; - } - } - catch (Exception ex) - { - log.ErrorFormat("StoreMailEml Exception: {0}", ex.ToString()); - } - - return string.Empty; - } - - private void FreeTask(TaskData taskData, ICollection tasks) - { - try - { - _log.DebugFormat("End Task {0} with status = '{1}'.", taskData.Task.Id, taskData.Task.Status); - - if (!tasks.Remove(taskData)) - _log.Error("Task not exists in tasks array."); - - var mailbox = taskData.Mailbox; - - ReleaseMailbox(mailbox); - - taskData.Task.Dispose(); - } - catch (Exception ex) - { - _log.ErrorFormat("FreeTask(id:'{0}', email:'{1}'): Exception:\r\n{2}\r\n", taskData.Mailbox.MailBoxId, taskData.Mailbox.EMail, ex.ToString()); - } - } - - private void ReleaseMailbox(MailBoxData mailbox) - { - if (mailbox == null) - return; - - if (mailbox.LastSignalrNotifySkipped) - NotifySignalrIfNeed(mailbox, _log); - - _queueManager.ReleaseMailbox(mailbox); - - if (!Filters.ContainsKey(mailbox.UserId)) - return; - - List filters; - if (!Filters.TryRemove(mailbox.UserId, out filters)) - { - _log.Error("Try forget Filters for user failed"); - } - } - - private void LogStat(string method, MailBoxData mailBoxData, TimeSpan duration, bool failed) - { - if (!_tasksConfig.CollectStatistics) - return; - - _logStat.DebugWithProps(method, - new KeyValuePair("duration", duration.TotalMilliseconds), - new KeyValuePair("mailboxId", mailBoxData.MailBoxId), - new KeyValuePair("address", mailBoxData.EMail.ToString()), - new KeyValuePair("status", failed ? S_FAIL : S_OK)); - } - - #endregion - } -} \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/App.config b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/App.config deleted file mode 100644 index 1a5cdd77de..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/App.config +++ /dev/null @@ -1,111 +0,0 @@ - - - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/HealthCheckService.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/HealthCheckService.cs deleted file mode 100644 index 4961d76522..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/HealthCheckService.cs +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using ASC.Core.Common.Contracts; - -namespace ASC.Mail.Aggregator.CollectionService -{ - public class HealthCheckService : IHealthCheckService - { - #region - HealthCheck - - - public HealthCheckResponse CheckHealth() - { - return HealthCheckResult.ToResponse(new HealthCheckResult - { - Message = "Service MailAggregator is OK! Warning: Method is not implement. Always return the Healthy status", - Status = HealthStatus.Healthy - }); - } - - #endregion - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Program.Options.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Program.Options.cs deleted file mode 100644 index d0abbe4a72..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Program.Options.cs +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System.Collections.Generic; - -using CommandLine; -using CommandLine.Text; - -namespace ASC.Mail.Aggregator.CollectionService -{ - public class Options - { - [Option('u', "users", MetaValue = "STRING ARRAY", Required = false, HelpText = "An array of users for which the aggregator will take tasks. " + - "Separator = ';' " + - "Example: -u\"{tl_userId_1}\";\"{tl_userId_2}\";\"{tl_userId_3}\"", Separator = ';')] - public IList OnlyUsers { get; set; } - - [Option("console", Required = false, HelpText = "Console state")] - public bool IsConsole { get; set; } - - [Option("unlimit", Required = false, HelpText = "Unlimit messages per mailbox session")] - public bool NoMessagesLimit { get; set; } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Program.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Program.cs deleted file mode 100644 index 8635108bba..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Program.cs +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Linq; -using System.ServiceProcess; - -using ASC.Common.Logging; - -using CommandLine; - -namespace ASC.Mail.Aggregator.CollectionService -{ - internal class Program - { - private static void Main(string[] args) - { - AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; - - var options = new Options(); - - if (args.Any()) - { - - Parser.Default.ParseArguments(args) - .WithNotParsed(x => Console.WriteLine(@"Bad command line parameters.")) - .WithParsed(x => options = x); - } - - if (Environment.UserInteractive || options.IsConsole) - { - var service = new AggregatorService(options); - service.StartConsole(); - } - else - { - ServiceBase.Run(new AggregatorService(options)); - } - } - - - private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) - { - var log = LogManager.GetLogger("ASC.Mail.Aggregator"); - log.FatalFormat("Unhandled exception: {0}", e.ExceptionObject.ToString()); - } - } -} \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Properties/AssemblyInfo.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Properties/AssemblyInfo.cs deleted file mode 100644 index 7a068e63db..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ASC.Mail.Aggregator.CollectionService")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Ascensio System SIA")] -[assembly: AssemblyProduct("ASC.Mail.Aggregator.CollectionService")] -[assembly: AssemblyCopyright("(c) Ascensio System SIA. All rights reserved")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7d2be6c9-b628-4705-bdd1-1d58719b1c1e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.*")] -[assembly: AssemblyFileVersion("2.0.0.1")] diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/Extensions.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/Extensions.cs deleted file mode 100644 index 5dddff673a..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/Extensions.cs +++ /dev/null @@ -1,56 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System.Net.Mail; - -using ASC.Mail.Data.Contracts; - -namespace ASC.Mail.Aggregator.CollectionService.Queue.Data -{ - public static class Extensions - { - public static MailBoxData ToMailbox(this MailboxData mailboxData) - { - return new MailBoxData - { - TenantId = mailboxData.TenantId, - UserId = mailboxData.UserId, - MailBoxId = mailboxData.MailboxId, - EMail = new MailAddress(mailboxData.EMail), - Imap = mailboxData.Imap, - IsTeamlab = mailboxData.IsTeamlab, - Size = mailboxData.Size, - MessagesCount = mailboxData.MessagesCount - }; - } - - public static MailboxData ToMailboxData(this MailBoxData mailbox) - { - return new MailboxData - { - MailboxId = mailbox.MailBoxId, - TenantId = mailbox.TenantId, - UserId = mailbox.UserId, - EMail = mailbox.EMail.Address, - Imap = mailbox.Imap, - IsTeamlab = mailbox.IsTeamlab, - MessagesCount = mailbox.MessagesCount, - Size = mailbox.Size - }; - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/MailboxData.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/MailboxData.cs deleted file mode 100644 index ead907faa9..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/MailboxData.cs +++ /dev/null @@ -1,49 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System.Runtime.Serialization; - -namespace ASC.Mail.Aggregator.CollectionService.Queue.Data -{ - [DataContract] - public class MailboxData - { - [DataMember(Name = "tenant")] - public int TenantId { get; set; } - - [DataMember(Name = "user")] - public string UserId { get; set; } - - [DataMember(Name = "id")] - public int MailboxId { get; set; } - - [DataMember] - public string EMail { get; set; } - - [DataMember(Name = "imap")] - public bool Imap { get; set; } - - [DataMember(Name = "is_teamlab")] - public bool IsTeamlab { get; set; } - - [DataMember(Name = "size")] - public long Size { get; set; } - - [DataMember(Name = "messages_count")] - public int MessagesCount { get; set; } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/TaskData.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/TaskData.cs deleted file mode 100644 index 18344e2473..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/TaskData.cs +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System.Threading.Tasks; - -using ASC.Mail.Data.Contracts; - -namespace ASC.Mail.Aggregator.CollectionService.Queue.Data -{ - public class TaskData - { - public TaskData(MailBoxData mailBoxData, Task task) - { - Mailbox = mailBoxData; - Task = task; - } - - public MailBoxData Mailbox { get; private set; } - - public Task Task { get; private set; } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/TenantData.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/TenantData.cs deleted file mode 100644 index 3952443936..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/Data/TenantData.cs +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Runtime.Serialization; - -namespace ASC.Mail.Aggregator.CollectionService.Queue.Data -{ - [DataContract] - public class TenantData - { - [DataMember(Name = "tenant")] - public int Tenant { get; set; } - - [DataMember(Name = "tariff_type")] - public Defines.TariffType TariffType { get; set; } - - [DataMember(Name = "expired")] - public DateTime Expired { get; set; } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/MailQueueItemSettings.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/MailQueueItemSettings.cs deleted file mode 100644 index 6bcbefff3e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/MailQueueItemSettings.cs +++ /dev/null @@ -1,104 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Linq; - -using ASC.Mail.Core; -using ASC.Mail.Data.Contracts; - -namespace ASC.Mail.Aggregator.CollectionService.Queue -{ - public class MailQueueItemSettings - { - public Dictionary ImapFlags { get; private set; } - - public string[] SkipImapFlags { get; private set; } - - public Dictionary> SpecialDomainFolders { get; private set; } - - public Dictionary DefaultFolders { get; private set; } - - public MailQueueItemSettings() - { - using (var daoFactory = new DaoFactory()) - { - var imapFlags = daoFactory.CreateImapFlagsDao().GetImapFlags(); - - SkipImapFlags = imapFlags.FindAll(i => i.Skip).ConvertAll(i => i.Name).ToArray(); - - ImapFlags = new Dictionary(); - imapFlags.FindAll(i => !i.Skip).ForEach(i => { ImapFlags[i.Name] = i.FolderId; }); - - var imapSpecialMailboxes = daoFactory.CreateImapSpecialMailboxDao().GetImapSpecialMailboxes(); - - SpecialDomainFolders = new Dictionary>(); - imapSpecialMailboxes.ForEach(r => - { - var mb = new MailBoxData.MailboxInfo - { - folder_id = r.FolderId, - skip = r.Skip - }; - if (SpecialDomainFolders.Keys.Contains(r.Server)) - SpecialDomainFolders[r.Server][r.MailboxName] = mb; - else - SpecialDomainFolders[r.Server] = new Dictionary - { - {r.MailboxName, mb} - }; - }); - } - - DefaultFolders = GetDefaultFolders(); - } - - private static Dictionary GetDefaultFolders() - { - var list = new Dictionary - { - {"inbox", 1}, - {"sent", 2}, - {"sent items", 2}, - {"drafts", 3}, - {"trash", 4}, - {"spam", 5}, - {"junk", 5}, - {"bulk", 5} - }; - - try - { - if (!string.IsNullOrEmpty(ConfigurationManagerExtension.AppSettings["mail.folders-mapping"])) - // "sent:2|"drafts:3|trash:4|spam:5|junk:5" - { - list = ConfigurationManagerExtension.AppSettings["mail.folders-mapping"] - .Split('|') - .Select(s => s.Split(':')) - .ToDictionary(s => s[0].ToLower(), s => Convert.ToInt32(s[1])); - } - } - catch - { - //ignore - } - return list; - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/QueueManager.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/QueueManager.cs deleted file mode 100644 index c4eeb84cfe..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/QueueManager.cs +++ /dev/null @@ -1,633 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Runtime.Caching; -using System.Threading; - -using ASC.Common.Logging; -using ASC.Core; -using ASC.Mail.Aggregator.CollectionService.Queue.Data; -using ASC.Mail.Core; -using ASC.Mail.Core.Dao.Expressions.Mailbox; -using ASC.Mail.Data.Contracts; -using ASC.Mail.Extensions; - -using LiteDB; - -namespace ASC.Mail.Aggregator.CollectionService.Queue -{ - public class QueueManager : IDisposable - { - private readonly EngineFactory _engineFactory; - - private readonly int _maxItemsLimit; - private readonly Queue _mailBoxQueue; - private List _lockedMailBoxList; - private readonly TasksConfig _tasksConfig; - private readonly ILog _log; - private DateTime _loadQueueTime; - private MemoryCache _tenantMemCache; - - private const string DBC_MAILBOXES = "mailboxes"; - private const string DBC_TENANTS = "tenants"; - private static string _dbcFile; - private static string _dbcJournalFile; - - private readonly object _locker = new object(); - - private LiteDatabase _db; - private ILiteCollection _mailboxes; - private ILiteCollection _tenants; - - public ManualResetEvent CancelHandler { get; set; } - - public QueueManager(TasksConfig tasksConfig, ILog log) - { - _maxItemsLimit = tasksConfig.MaxTasksAtOnce; - _mailBoxQueue = new Queue(); - _lockedMailBoxList = new List(); - _tasksConfig = tasksConfig; - _log = log; - _loadQueueTime = DateTime.UtcNow; - _tenantMemCache = new MemoryCache("QueueManagerTenantCache"); - - CancelHandler = new ManualResetEvent(false); - - _engineFactory = new EngineFactory(-1); - - if (_tasksConfig.UseDump) - { - _dbcFile = Path.Combine(Environment.CurrentDirectory, "dump.db"); - _dbcJournalFile = Path.Combine(Environment.CurrentDirectory, "dump-journal.db"); - - _log.DebugFormat("Dump file path: {0}", _dbcFile); - - LoadDump(); - } - } - - #region - public methods - - - public IEnumerable GetLockedMailboxes(int needTasks) - { - var mbList = new List(); - do - { - var mailBox = GetLockedMailbox(); - if (mailBox == null) - break; - - mbList.Add(mailBox); - - } while (mbList.Count < needTasks); - - return mbList; - } - - public MailBoxData GetLockedMailbox() - { - MailBoxData mailBoxData; - - do - { - mailBoxData = GetQueuedMailbox(); - - } while (mailBoxData != null && !TryLockMailbox(mailBoxData)); - - if (mailBoxData == null) - return null; - - _lockedMailBoxList.Add(mailBoxData); - - CancelHandler.Reset(); - - AddMailboxToDumpDb(mailBoxData.ToMailboxData()); - - return mailBoxData; - } - - public void ReleaseAllProcessingMailboxes() - { - if (!_lockedMailBoxList.Any()) - return; - - var cloneCollection = new List(_lockedMailBoxList); - - _log.Info("QueueManager->ReleaseAllProcessingMailboxes()"); - - foreach (var mailbox in cloneCollection) - { - ReleaseMailbox(mailbox); - } - } - - public void ReleaseMailbox(MailBoxData mailBoxData) - { - try - { - if (!_lockedMailBoxList.Contains(mailBoxData)) - { - _log.WarnFormat("QueueManager->ReleaseMailbox(Tenant = {0} MailboxId = {1}, Address = '{2}') mailbox not found", - mailBoxData.TenantId, mailBoxData.MailBoxId, mailBoxData.EMail); - return; - } - - _log.InfoFormat("QueueManager->ReleaseMailbox(MailboxId = {0} Address '{1}')", mailBoxData.MailBoxId, mailBoxData.EMail); - - CoreContext.TenantManager.SetCurrentTenant(mailBoxData.TenantId); - - _engineFactory.MailboxEngine.ReleaseMaibox(mailBoxData, _tasksConfig); - - _lockedMailBoxList.Remove(mailBoxData); - - DeleteMailboxFromDumpDb(mailBoxData.MailBoxId); - } - catch (Exception ex) - { - _log.ErrorFormat("QueueManager->ReleaseMailbox(Tenant = {0} MailboxId = {1}, Address = '{2}')\r\nException: {3} \r\n", - mailBoxData.TenantId, mailBoxData.MailBoxId, mailBoxData.Account, ex.ToString()); - } - } - - public int ProcessingCount - { - get { return _lockedMailBoxList.Count; } - } - - public void LoadMailboxesFromDump() - { - if (!_tasksConfig.UseDump) - return; - - if (_lockedMailBoxList.Any()) - return; - - try - { - _log.Debug("LoadMailboxesFromDump()"); - - lock (_locker) - { - var list = _mailboxes.FindAll().ToList(); - - _lockedMailBoxList = list.ConvertAll(m => m.ToMailbox()).ToList(); - } - } - catch (Exception ex) - { - _log.ErrorFormat("LoadMailboxesFromDump: {0}", ex.ToString()); - - ReCreateDump(); - } - } - - public void LoadTenantsFromDump() - { - if (!_tasksConfig.UseDump) - return; - - try - { - _log.Debug("LoadTenantsFromDump()"); - - lock (_locker) - { - var list = _tenants.FindAll().ToList(); - - foreach (var tenantData in list) - { - AddTenantToCache(tenantData, false); - } - } - - } - catch (Exception ex) - { - _log.ErrorFormat("LoadTenantsFromDump: {0}", ex.ToString()); - - ReCreateDump(); - } - } - - #endregion - - #region - private methods - - - private void ReCreateDump() - { - if (!_tasksConfig.UseDump) - return; - - try - { - if (File.Exists(_dbcFile)) - { - _log.DebugFormat("Dump file '{0}' exists, trying delete", _dbcFile); - - File.Delete(_dbcFile); - - _log.DebugFormat("Dump file '{0}' deleted", _dbcFile); - } - - if (File.Exists(_dbcJournalFile)) - { - _log.DebugFormat("Dump journal file '{0}' exists, trying delete", _dbcJournalFile); - - File.Delete(_dbcJournalFile); - - _log.DebugFormat("Dump journal file '{0}' deleted", _dbcJournalFile); - } - - _db = new LiteDatabase(_dbcFile); - - lock (_locker) - { - _mailboxes = _db.GetCollection(DBC_MAILBOXES); - _tenants = _db.GetCollection(DBC_TENANTS); - } - } - catch (Exception ex) - { - _log.ErrorFormat("ReCreateDump() failed Exception: {0}", ex.ToString()); - } - } - - private void AddMailboxToDumpDb(MailboxData mailboxData) - { - if (!_tasksConfig.UseDump) - return; - - try - { - lock (_locker) - { - var mailbox = _mailboxes.FindOne(Query.EQ("MailboxId", mailboxData.MailboxId)); - - if (mailbox != null) - return; - - _mailboxes.Insert(mailboxData); - - // Create, if not exists, new index on Name field - _mailboxes.EnsureIndex(x => x.MailboxId); - } - } - catch (Exception ex) - { - _log.ErrorFormat("AddMailboxToDumpDb(id={0}) Exception: {1}", mailboxData.MailboxId, ex.ToString()); - - ReCreateDump(); - } - } - - private void DeleteMailboxFromDumpDb(int mailBoxId) - { - if (!_tasksConfig.UseDump) - return; - - try - { - lock (_locker) - { - var mailbox = _mailboxes.FindOne(Query.EQ("MailboxId", mailBoxId)); - - if (mailbox == null) - return; - - _mailboxes.DeleteMany(Query.EQ("MailboxId", mailBoxId)); - } - } - catch (Exception ex) - { - _log.ErrorFormat("DeleteMailboxFromDumpDb(mailboxId={0}) Exception: {1}", mailBoxId, ex.ToString()); - - ReCreateDump(); - } - } - - private void LoadDump() - { - if (!_tasksConfig.UseDump) - return; - - try - { - if (File.Exists(_dbcJournalFile)) - throw new Exception(string.Format("temp dump journal file exists in {0}", _dbcJournalFile)); - - _db = new LiteDatabase(_dbcFile); - - lock (_locker) - { - _tenants = _db.GetCollection(DBC_TENANTS); - _mailboxes = _db.GetCollection(DBC_MAILBOXES); - } - } - catch (Exception ex) - { - _log.ErrorFormat("LoadDump() failed Exception: {0}", ex.ToString()); - - ReCreateDump(); - } - } - - private void AddTenantToDumpDb(TenantData tenantData) - { - if (!_tasksConfig.UseDump) - return; - - try - { - lock (_locker) - { - var tenant = _tenants.FindOne(Query.EQ("Tenant", tenantData.Tenant)); - - if (tenant != null) - return; - - _tenants.Insert(tenantData); - - // Create, if not exists, new index on Name field - _tenants.EnsureIndex(x => x.Tenant); - } - } - catch (Exception ex) - { - _log.ErrorFormat("AddTenantToDumpDb(tenantId={0}) Exception: {1}", tenantData.Tenant, ex.ToString()); - - ReCreateDump(); - } - } - - private void DeleteTenantFromDumpDb(int tenantId) - { - if (!_tasksConfig.UseDump) - return; - - try - { - lock (_locker) - { - var tenant = _tenants.FindOne(Query.EQ("Tenant", tenantId)); - - if (tenant == null) - return; - - _tenants.DeleteMany(Query.EQ("Tenant", tenantId)); - } - } - catch (Exception ex) - { - _log.ErrorFormat("DeleteTenantFromDumpDb(tenant={0}) Exception: {1}", tenantId, ex.ToString()); - - ReCreateDump(); - } - } - - private void AddTenantToCache(TenantData tenantData, bool needDump = true) - { - var now = DateTime.UtcNow; - - if (tenantData.Expired < now) - { - DeleteTenantFromDumpDb(tenantData.Tenant); - return; // Skip Expired tenant - } - - var cacheItem = new CacheItem(tenantData.Tenant.ToString(CultureInfo.InvariantCulture), tenantData); - - var nowOffset = tenantData.Expired - now; - - var absoluteExpiration = DateTime.UtcNow.Add(nowOffset); - - var cacheItemPolicy = new CacheItemPolicy - { - RemovedCallback = CacheEntryRemove, - AbsoluteExpiration = absoluteExpiration - }; - - _tenantMemCache.Add(cacheItem, cacheItemPolicy); - - if (!needDump) - return; - - AddTenantToDumpDb(tenantData); - } - - private bool QueueIsEmpty - { - get { return !_mailBoxQueue.Any(); } - } - - private bool QueueLifetimeExpired - { - get { return DateTime.UtcNow - _loadQueueTime >= _tasksConfig.QueueLifetime; } - } - - private void LoadQueue() - { - try - { - var mbList = _engineFactory.MailboxEngine.GetMailboxesForProcessing(_tasksConfig, _maxItemsLimit); - - ReloadQueue(mbList); - } - catch (Exception ex) - { - _log.ErrorFormat("QueueManager->LoadQueue()\r\nException: \r\n {0}", ex.ToString()); - } - } - - private MailBoxData GetQueuedMailbox() - { - if (QueueIsEmpty || QueueLifetimeExpired) - { - _log.DebugFormat("Queue is {0}. Load new queue.", QueueIsEmpty ? "EMPTY" : "EXPIRED"); - - LoadQueue(); - } - - return !QueueIsEmpty ? _mailBoxQueue.Dequeue() : null; - } - - private void RemoveFromQueue(int tenant) - { - var mbList = _mailBoxQueue.Where(mb => mb.TenantId != tenant).Select(mb => mb).ToList(); - ReloadQueue(mbList); - } - - private void RemoveFromQueue(int tenant, string user) - { - var mbList = _mailBoxQueue.Where(mb => mb.TenantId != tenant && mb.UserId != user).Select(mb => mb).ToList(); - ReloadQueue(mbList); - } - - private void ReloadQueue(IEnumerable mbList) - { - _mailBoxQueue.Clear(); - _mailBoxQueue.PushRange(mbList); - _loadQueueTime = DateTime.UtcNow; - } - - private bool TryLockMailbox(MailBoxData mailbox) - { - _log.DebugFormat("TryLockMailbox(MailboxId={0} is {1})", mailbox.MailBoxId, mailbox.Active ? "active" : "inactive"); - - try - { - var contains = _tenantMemCache.Contains(mailbox.TenantId.ToString(CultureInfo.InvariantCulture)); - - if (!contains) - { - _log.DebugFormat("Tenant {0} isn't in cache", mailbox.TenantId); - try - { - var type = mailbox.GetTenantStatus(_tasksConfig.TenantOverdueDays, _tasksConfig.DefaultApiSchema, _log); - - switch (type) - { - case Defines.TariffType.LongDead: - _log.InfoFormat("Tenant {0} is not paid. Disable mailboxes.", mailbox.TenantId); - - _engineFactory.MailboxEngine.DisableMailboxes( - new TenantMailboxExp(mailbox.TenantId)); - - var userIds = - _engineFactory.MailboxEngine.GetMailUsers(new TenantMailboxExp(mailbox.TenantId)) - .ConvertAll(t => t.Item2); - - _engineFactory.AlertEngine.CreateDisableAllMailboxesAlert(mailbox.TenantId, userIds); - - RemoveFromQueue(mailbox.TenantId); - - return false; - - case Defines.TariffType.Overdue: - _log.InfoFormat("Tenant {0} is not paid. Stop processing mailboxes.", mailbox.TenantId); - - _engineFactory.MailboxEngine.SetNextLoginDelay(new TenantMailboxExp(mailbox.TenantId), - _tasksConfig.OverdueAccountDelay); - - RemoveFromQueue(mailbox.TenantId); - - return false; - - default: - _log.InfoFormat("Tenant {0} is paid.", mailbox.TenantId); - - var expired = DateTime.UtcNow.Add(_tasksConfig.TenantCachingPeriod); - - var tenantData = new TenantData - { - Tenant = mailbox.TenantId, - TariffType = type, - Expired = expired - }; - - AddTenantToCache(tenantData); - - break; - } - } - catch (Exception e) - { - _log.ErrorFormat("TryLockMailbox() -> GetTariffType Exception:\r\n{0}\r\n", e.ToString()); - } - } - else - { - _log.DebugFormat("Tenant {0} is in cache", mailbox.TenantId); - } - - if (mailbox.IsUserTerminated() || mailbox.IsUserRemoved()) - { - _log.InfoFormat("User '{0}' was terminated. Tenant = {1}. Disable mailboxes for user.", - mailbox.UserId, - mailbox.TenantId); - - _engineFactory.MailboxEngine.DisableMailboxes( - new UserMailboxExp(mailbox.TenantId, mailbox.UserId)); - - _engineFactory.AlertEngine.CreateDisableAllMailboxesAlert(mailbox.TenantId, - new List { mailbox.UserId }); - - RemoveFromQueue(mailbox.TenantId, mailbox.UserId); - - return false; - } - - if (mailbox.IsTenantQuotaEnded(_tasksConfig.TenantMinQuotaBalance, _log)) - { - _log.InfoFormat("Tenant = {0} User = {1}. Quota is ended.", mailbox.TenantId, mailbox.UserId); - - if (!mailbox.QuotaError) - _engineFactory.AlertEngine.CreateQuotaErrorWarningAlert(mailbox.TenantId, mailbox.UserId); - - _engineFactory.MailboxEngine.SetNextLoginDelay(new UserMailboxExp(mailbox.TenantId, mailbox.UserId), - _tasksConfig.QuotaEndedDelay); - - RemoveFromQueue(mailbox.TenantId, mailbox.UserId); - - return false; - } - - return _engineFactory.MailboxEngine.LockMaibox(mailbox.MailBoxId); - - } - catch (Exception ex) - { - _log.ErrorFormat("TryLockMailbox(MailboxId={0} is {1}) Exception:\r\n{2}\r\n", mailbox.MailBoxId, - mailbox.Active ? "active" : "inactive", ex.ToString()); - - return false; - } - - } - - private void CacheEntryRemove(CacheEntryRemovedArguments arguments) - { - if (arguments.RemovedReason == CacheEntryRemovedReason.CacheSpecificEviction) - return; - - var tenantId = Convert.ToInt32(arguments.CacheItem.Key); - - _log.InfoFormat("Tenant {0} payment cache is expired.", tenantId); - - DeleteTenantFromDumpDb(tenantId); - } - - #endregion - - public void Dispose() - { - _tenantMemCache.Dispose(); - _tenantMemCache = null; - - if (_tasksConfig.UseDump) - { - _db.Dispose(); - _db = null; - } - } - } - -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/SignalrWorker.cs b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/SignalrWorker.cs deleted file mode 100644 index 6c08e0df1d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/Queue/SignalrWorker.cs +++ /dev/null @@ -1,193 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; - -using ASC.Common.Logging; -using ASC.Core; -using ASC.Core.Notify.Signalr; -using ASC.Core.Users; -using ASC.Mail.Core; -using ASC.Mail.Data.Contracts; -using ASC.Mail.Enums; - -namespace ASC.Mail.Aggregator.CollectionService.Queue -{ - public class SignalrWorker : IDisposable - { - private readonly Queue _processingQueue; - private Thread _worker; - private volatile bool _workerTerminateSignal; - private readonly EventWaitHandle _waitHandle; - private readonly ILog _log; - private static SignalrServiceClient _signalrServiceClient; - private readonly TimeSpan _timeSpan; - - public SignalrWorker(bool startImmediately = true) - { - _log = LogManager.GetLogger("ASC.Mail.SignalrWorker"); - _workerTerminateSignal = false; - _signalrServiceClient = new SignalrServiceClient("mail"); - _processingQueue = new Queue(); - _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); - _timeSpan = TimeSpan.FromSeconds(10); - - _worker = new Thread(ProcessQueue); - - if (startImmediately) - _worker.Start(); - } - - private void ProcessQueue() - { - while (!_workerTerminateSignal) - { - if (!HasQueuedMailbox) - { - _log.Debug("No items, waiting."); - _waitHandle.WaitOne(); - _log.Debug("Waking up..."); - } - - var mailbox = NextQueuedMailBoxData; - if (mailbox == null) - continue; - - try - { - _log.DebugFormat("signalrServiceClient.SendUnreadUser(UserId = {0} TenantId = {1})", mailbox.UserId, - mailbox.TenantId); - - SendUnreadUser(mailbox.TenantId, mailbox.UserId); - } - catch (Exception ex) - { - _log.ErrorFormat("signalrServiceClient.SendUnreadUser(UserId = {0} TenantId = {1}) Exception: {2}", mailbox.UserId, - mailbox.TenantId, ex.ToString()); - } - - _waitHandle.Reset(); - } - } - - public int QueueCount - { - get - { - lock (_processingQueue) - { - return _processingQueue.Count; - } - } - } - - public bool HasQueuedMailbox - { - get - { - lock (_processingQueue) - { - return _processingQueue.Any(); - } - } - } - - public MailBoxData NextQueuedMailBoxData - { - get - { - if (!HasQueuedMailbox) - return null; - - lock (_processingQueue) - { - return _processingQueue.Dequeue(); - } - } - } - - public void Start() - { - if (!_worker.IsAlive) - _worker.Start(); - } - - public void AddMailbox(MailBoxData item) - { - lock (_processingQueue) - { - if (!_processingQueue.Contains(item)) - _processingQueue.Enqueue(item); - } - _waitHandle.Set(); - } - - public void Dispose() - { - if (_worker == null) - return; - - _workerTerminateSignal = true; - _waitHandle.Set(); - - if (_worker.IsAlive) - { - _log.Info("Stop SignalrWorker."); - - if (!_worker.Join(_timeSpan)) - { - _log.Info("SignalrWorker busy, aborting the thread."); - _worker.Abort(); - } - } - - _worker = null; - } - - private static void SendUnreadUser(int tenant, string userId) - { - var log = LogManager.GetLogger("ASC.Mail.SignalrWorker"); - try - { - var engineFactory = new EngineFactory(tenant, userId); - - var mailFolderInfos = engineFactory.FolderEngine.GetFolders(); - - var count = (from mailFolderInfo in mailFolderInfos - where mailFolderInfo.id == FolderType.Inbox - select mailFolderInfo.unreadMessages) - .FirstOrDefault(); - - CoreContext.TenantManager.SetCurrentTenant(tenant); - var userInfo = CoreContext.UserManager.GetUsers(Guid.Parse(userId)); - if (userInfo.ID != Constants.LostUser.ID) - { - // sendMailsCount - _signalrServiceClient.SendUnreadUser(tenant, userId, count); - } - } - catch (Exception e) - { - log.ErrorFormat("Unknown Error. {0}, {1}", e.ToString(), - e.InnerException != null ? e.InnerException.Message : string.Empty); - } - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/mail.agg.log4net.config b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/mail.agg.log4net.config deleted file mode 100644 index f13c586c63..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/mail.agg.log4net.config +++ /dev/null @@ -1,137 +0,0 @@ - - - - WINDOWS:LogDirectory - ..\..\..\..\..\..\web\studio\Logs\ - - - UNIX:LogDirectory - /var/log/onlyoffice/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/mail.agg.nlog.config b/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/mail.agg.nlog.config deleted file mode 100644 index 1518993122..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Aggregator.CollectionService/mail.agg.nlog.config +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/ASC.Mail.DomainParser.csproj b/module/ASC.Mail/Services/ASC.Mail.DomainParser/ASC.Mail.DomainParser.csproj deleted file mode 100644 index d96f917871..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/ASC.Mail.DomainParser.csproj +++ /dev/null @@ -1,341 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {9B218E58-4967-4DAC-B427-C2FD2AC50634} - Exe - Properties - ASC.Mail.DomainParser - ASC.Mail.DomainParser - v4.8 - 512 - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - none - true - bin\Release\ - TRACE - prompt - 4 - false - - - - ..\..\..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll - - - ..\..\..\..\packages\MySql.Data.8.0.18\lib\net452\MySql.Data.dll - - - False - ..\..\..\..\packages\NLog.4.5.8\lib\net45\NLog.dll - - - - - 3.5 - - - 3.5 - - - 3.5 - - - - - ..\..\..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - - - {76de7717-3d4b-4a5b-b740-15b8913df0cb} - ASC.Common - - - {a51d0454-4afa-46de-89d4-b03d37e1816c} - ASC.Core.Common - - - {7080343d-fbe7-423a-9405-4f883f6e235b} - ASC.Mail - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/App.config b/module/ASC.Mail/Services/ASC.Mail.DomainParser/App.config deleted file mode 100644 index 74768ca9d3..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/App.config +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/Program.cs b/module/ASC.Mail/Services/ASC.Mail.DomainParser/Program.cs deleted file mode 100644 index ae08fa2307..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/Program.cs +++ /dev/null @@ -1,149 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using ASC.Mail.Core; -using ASC.Mail.Data.Contracts; - -namespace ASC.Mail.DomainParser -{ - internal class Program - { - private static void Main(string[] args) - { - Console.WriteLine(".Begin"); - - var parsePath = @"../../XmlData"; - - try - { - var listOfConfig = new List(); - - if (args != null && args.Any()) - { - parsePath = args[0]; - } - - Console.WriteLine("\r\nParser path: '{0}'", parsePath); - - if (File.GetAttributes(parsePath) == FileAttributes.Directory) - { - var parsePathInfo = new DirectoryInfo(parsePath); - - var files = parsePathInfo.GetFiles(); - - Console.WriteLine("\r\n{0} file(s) found!", files.Count()); - Console.WriteLine(""); - - var index = 0; - var count = files.Count(); - - files - .ToList() - .ForEach(f => - { - if (f.Attributes == FileAttributes.Directory) return; - ClientConfig obj; - if (!ParseXml(f.FullName, out obj)) return; - Console.SetCursorPosition(0, Console.CursorTop); - Console.Write(" "); - Console.SetCursorPosition(0, Console.CursorTop); - Console.Write("{0} from {1}", ++index, count); - listOfConfig.Add(obj); - }); - Console.WriteLine(""); - } - else - { - Console.WriteLine("\r\n1 file found!"); - - ClientConfig obj; - if (ParseXml(parsePath, out obj)) - { - listOfConfig.Add(obj); - } - } - - Console.WriteLine("\r\n{0} config(s) parsed!", listOfConfig.Count); - - var engine = new EngineFactory(-1, ASC.Core.Configuration.Constants.CoreSystem.ToString()); - - if (listOfConfig.Any()) - { - do - { - Console.Write("\r\nDo you want add configs to DB? [y, n]: "); - var info = Console.ReadKey(); - if (info.Key == ConsoleKey.Y) - { - var index = 0; - var count = listOfConfig.Count; - - Console.WriteLine("\r\n"); - - listOfConfig.ForEach(c => - { - Console.Write("{0} from {1}", ++index, count); - - if (!engine.MailBoxSettingEngine.SetMailBoxSettings(c, false)) return; - if (index >= count) return; - Console.SetCursorPosition(0, Console.CursorTop); - Console.Write(" "); - Console.SetCursorPosition(0, Console.CursorTop); - }); - - Console.WriteLine("\r\n"); - Console.WriteLine("{0} config(s) added to DB!", listOfConfig.Count); - Console.WriteLine(""); - break; - } - if (info.Key != ConsoleKey.N) continue; - Console.WriteLine("\r\n"); - break; - } while (true); - } - - } - catch (Exception ex) - { - Console.WriteLine(ex.Message); - } - - Console.WriteLine(".End"); - Console.ReadKey(); - } - - private static bool ParseXml(string filepath, out ClientConfig obj) - { - obj = null; - - try - { - obj = ClientConfig.LoadFromFile(filepath); - } - catch (Exception) - { - return false; - } - - return true; - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/Properties/AssemblyInfo.cs b/module/ASC.Mail/Services/ASC.Mail.DomainParser/Properties/AssemblyInfo.cs deleted file mode 100644 index 05e605da6d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ASC.Mail.DomainParser")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Ascensio System SIA")] -[assembly: AssemblyProduct("ASC.Mail.DomainParser")] -[assembly: AssemblyCopyright("(c) Ascensio System SIA. All rights reserved")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("4c868901-7e6a-4254-a788-41bdc5d0e401")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/1und1.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/1und1.de.xml deleted file mode 100644 index b669e33de4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/1und1.de.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - 1and1.de - - online.de - onlinehome.de - sofortstart.de - sofort-start.de - sofortsurf.de - sofort-surf.de - go4more.de - - kundenserver.de - schlund.de - 1and1.com - 1and1.fr - 1and1.co.uk - 1and1.es - - 1&1 - 1&1 - - imap.1und1.de - 993 - SSL - password-cleartext - %EMAILADDRESS% - - - imap.1und1.de - 143 - STARTTLS - password-cleartext - %EMAILADDRESS% - - - pop.1und1.de - 995 - SSL - password-cleartext - %EMAILADDRESS% - - - pop.1und1.de - 110 - STARTTLS - password-cleartext - %EMAILADDRESS% - - - smtp.1und1.de - 587 - STARTTLS - password-cleartext - %EMAILADDRESS% - - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/abc.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/abc.plala.or.jp.xml deleted file mode 100644 index 549bed6cb3..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/abc.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - abc.plala.or.jp - ぷらら - ぷらら - - abc.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - abc.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/agate.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/agate.plala.or.jp.xml deleted file mode 100644 index 6195f58519..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/agate.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - agate.plala.or.jp - ぷらら - ぷらら - - agate.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - agate.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/alice.it.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/alice.it.xml deleted file mode 100644 index 6bf811d02a..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/alice.it.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - alice.it - Alice Italy - Alice - - in.alice.it - 143 - plain - %EMAILADDRESS% - password-cleartext - - - in.alice.it - 110 - plain - %EMAILADDRESS% - password-cleartext - - - out.alice.it - 587 - plain - %EMAILADDRESS% - password-cleartext - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/amail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/amail.plala.or.jp.xml deleted file mode 100644 index b4bd8af5fc..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/amail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - amail.plala.or.jp - ぷらら - ぷらら - - amail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - amail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/amber.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/amber.plala.or.jp.xml deleted file mode 100644 index ae682933ee..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/amber.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - amber.plala.or.jp - ぷらら - ぷらら - - amber.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - amber.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/aol.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/aol.com.xml deleted file mode 100644 index a967363bf6..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/aol.com.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - aol.com - aim.com - netscape.net - AOL Mail - AOL - - imap.aol.com - 993 - SSL - %EMAILLOCALPART% - password-cleartext - - - imap.aol.com - 143 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - pop.aol.com - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - pop.aol.com - 110 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - smtp.aol.com - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/apost.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/apost.plala.or.jp.xml deleted file mode 100644 index c4f936a7c1..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/apost.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - apost.plala.or.jp - ぷらら - ぷらら - - apost.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - apost.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/aqua.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/aqua.plala.or.jp.xml deleted file mode 100644 index 0c78abc615..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/aqua.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - aqua.plala.or.jp - ぷらら - ぷらら - - aqua.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - aqua.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/arcor.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/arcor.de.xml deleted file mode 100644 index 81ebcdccc1..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/arcor.de.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - arcor.de - Arcor - Arcor - - imap.arcor.de - 993 - SSL - - password-cleartext - %EMAILLOCALPART% - - - imap.arcor.de - 143 - STARTTLS - password-cleartext - %EMAILLOCALPART% - - - pop3.arcor.de - 995 - SSL - - password-cleartext - %EMAILLOCALPART% - - - mail.arcor.de - 465 - SSL - password-cleartext - %EMAILLOCALPART% - - - mail.arcor.de - 587 - STARTTLS - password-cleartext - %EMAILLOCALPART% - - - Generic settings - - - TB 2.0 settings - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/arubapec.it.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/arubapec.it.xml deleted file mode 100644 index 8196ee84b4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/arubapec.it.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - pec.it - arubapec.it - mypec.eu - gigapec.it - ingpec.eu - Aruba PEC - Aruba - - imaps.pec.aruba.it - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - pop3s.pec.aruba.it - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - smtps.pec.aruba.it - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/att.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/att.net.xml deleted file mode 100644 index 0e839a1c11..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/att.net.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - att.net - bellsouth.net - sbcglobal.net - prodigy.net - pacbell.net - swbell.net - nvbell.net - ameritech.net - snet.net - flash.net - wans.net - AT&T - AT&T - - pop.att.yahoo.com - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.att.yahoo.com - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - Configure POP3 for att, sbcglobal, swbell, prodigy etc. - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/avsmedia.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/avsmedia.com.xml deleted file mode 100644 index 2b23f76284..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/avsmedia.com.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - avsmedia.com - avsmedia.com - avsmedia - - mail.avsmedia.com - 110 - plain - %EMAILLOCALPART%@%EMAILHOSTNAME% - password-cleartext - - - mail.avsmedia.com - 25 - plain - %EMAILLOCALPART%@%EMAILHOSTNAME% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/avsmedia.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/avsmedia.net.xml deleted file mode 100644 index ba10084a19..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/avsmedia.net.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - avsmedia.net - avsmedia.net - avsmedia - - 78.40.187.62 - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - 78.40.187.62 - 25 - plain - none - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ballade.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ballade.plala.or.jp.xml deleted file mode 100644 index 913390f9ee..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ballade.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - ballade.plala.or.jp - ぷらら - ぷらら - - ballade.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - ballade.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bay.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bay.wind.ne.jp.xml deleted file mode 100644 index 930cf3ab09..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bay.wind.ne.jp.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - bay.wind.ne.jp - bay.wind.jp - bay.wind.co.jp - bay.gunmanet.or.jp - bay.gunmanet.ne.jp - 群馬インターネット - wind - - bay.wind.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - bay.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bb-niigata.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bb-niigata.jp.xml deleted file mode 100644 index 96f4fb7bac..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bb-niigata.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - bb-niigata.jp - BBにいがた - BB-NIIGATA - - pop.bb-niigata.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - pop.bb-niigata.jp - 25 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/beige.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/beige.plala.or.jp.xml deleted file mode 100644 index 1da18eb675..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/beige.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - beige.plala.or.jp - ぷらら - ぷらら - - beige.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - beige.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/biglobe.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/biglobe.ne.jp.xml deleted file mode 100644 index a55728a11a..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/biglobe.ne.jp.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - biglobe.ne.jp - Biglobe - Biglobe - - mail.biglobe.ne.jp - 110 - plain - %EMAILADDRESS% - password-cleartext - - - mail.biglobe.ne.jp - 587 - plain - %EMAILADDRESS% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bigpond.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bigpond.com.xml deleted file mode 100644 index b3bb498369..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bigpond.com.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - bigpond.com - bigpond.net.au - telstra.com - bigpond.net - Telstra Bigpond - Bigpond - - mail.bigpond.com - 995 - SSL - %EMAILADDRESS% - plain - - - mail.bigpond.com - 25 - plain - %EMAILADDRESS% - plain - - - - Generic email settings - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/blue.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/blue.plala.or.jp.xml deleted file mode 100644 index 510042ee9e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/blue.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - blue.plala.or.jp - ぷらら - ぷらら - - blue.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - blue.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bluemail.ch.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bluemail.ch.xml deleted file mode 100644 index 8a4062a5fb..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bluemail.ch.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - bluemail.ch - - bluewin.ch - bluewin.ch - - imaps.bluewin.ch - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - pop3s.bluewin.ch - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - smtpauths.bluewin.ch - 465 - SSL - %EMAILADDRESS% - password-encrypted - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bluewin.ch.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bluewin.ch.xml deleted file mode 100644 index 64488a04ba..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bluewin.ch.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - bluewin.ch - bluewin.ch - bluewin.ch - - imaps.bluewin.ch - 993 - SSL - %EMAILLOCALPART% - password-cleartext - - - pop3s.bluewin.ch - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - smtpauths.bluewin.ch - 465 - SSL - %EMAILLOCALPART% - password-encrypted - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bmail.plala.or.jp.xml deleted file mode 100644 index f849e6e4b6..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - bmail.plala.or.jp - ぷらら - ぷらら - - bmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - bmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bolero.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bolero.plala.or.jp.xml deleted file mode 100644 index 171776a28b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bolero.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - bolero.plala.or.jp - ぷらら - ぷらら - - bolero.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - bolero.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bpost.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bpost.plala.or.jp.xml deleted file mode 100644 index 24c8ebd843..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/bpost.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - bpost.plala.or.jp - ぷらら - ぷらら - - bpost.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - bpost.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/broba.cc.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/broba.cc.xml deleted file mode 100644 index 75e6ebcf72..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/broba.cc.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - garnet.broba.cc - amethyst.broba.cc - coral.broba.ccv - diamond.broba.cc - ぷらら - ぷらら - - mail.broba.cc - 110 - plain - %EMAILADDRESS% - password-cleartext - - - mail.broba.cc - 587 - plain - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/brown.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/brown.plala.or.jp.xml deleted file mode 100644 index 3bd4be2168..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/brown.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - brown.plala.or.jp - ぷらら - ぷらら - - brown.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - brown.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/camel.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/camel.plala.or.jp.xml deleted file mode 100644 index c55faa8270..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/camel.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - camel.plala.or.jp - ぷらら - ぷらら - - camel.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - camel.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cameo.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cameo.plala.or.jp.xml deleted file mode 100644 index 7376c1fffe..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cameo.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - cameo.plala.or.jp - ぷらら - ぷらら - - cameo.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - cameo.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cc9.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cc9.ne.jp.xml deleted file mode 100644 index 9f6c11e517..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cc9.ne.jp.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - cc9.ne.jp - CC9インターネットサービス - CC9 - - pop.cc9.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.cc9.ne.jp - 25 - plain - none - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cek.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cek.ne.jp.xml deleted file mode 100644 index a1bce9e139..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cek.ne.jp.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - cek.ne.jp - エコーシティー・駒ケ岳 - CEK-Net - - mail.cek.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.cek.ne.jp - 25 - plain - none - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cgl.ucsf.edu.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cgl.ucsf.edu.xml deleted file mode 100644 index ca545ebf59..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cgl.ucsf.edu.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - cgl.ucsf.edu - UCSF CGL email - CGL email - - plato.cgl.ucsf.edu - 993 - SSL - %EMAILLOCALPART% - password-cleartext - - - plato.cgl.ucsf.edu - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/charter.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/charter.com.xml deleted file mode 100644 index ee5dd0285d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/charter.com.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - charter.net - charter.com - Charter Commuications - Charter - - mobile.charter.net - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - imap.charter.net - 143 - plain - %EMAILADDRESS% - password-cleartext - - - - - mobile.charter.net - - 587 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.charter.net - 25 - plain - %EMAILADDRESS% - password-cleartext - client-IP-address - - - POP/IMAP and SMTP settings for Charter, including mobile - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/clio.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/clio.ne.jp.xml deleted file mode 100644 index e1cb7552ec..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/clio.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - clio.ne.jp - CLIO-Net移管サービス - CLIO-Net - - mail.clio.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - mail.clio.ne.jp - 587 - plain - %EMAILLOCALPART% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cmail.plala.or.jp.xml deleted file mode 100644 index eb2558272b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - cmail.plala.or.jp - ぷらら - ぷらら - - cmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - cmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co1.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co1.wind.ne.jp.xml deleted file mode 100644 index e086cd7785..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co1.wind.ne.jp.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - co1.wind.ne.jp - co1.wind.jp - 群馬インターネット - wind - - co1.wind.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - co1.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co2.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co2.wind.ne.jp.xml deleted file mode 100644 index 010477274d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co2.wind.ne.jp.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - co2.wind.ne.jp - co2.wind.jp - 群馬インターネット - wind - - co2.wind.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - co2.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co3.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co3.wind.ne.jp.xml deleted file mode 100644 index 498384cb09..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/co3.wind.ne.jp.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - co3.wind.ne.jp - co3.wind.jp - 群馬インターネット - wind - - co3.wind.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - co3.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cocoa.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cocoa.plala.or.jp.xml deleted file mode 100644 index 5387cd368d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cocoa.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - cocoa.plala.or.jp - ぷらら - ぷらら - - cocoa.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - cocoa.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/coda.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/coda.plala.or.jp.xml deleted file mode 100644 index f668775d84..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/coda.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - coda.plala.or.jp - ぷらら - ぷらら - - coda.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - coda.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/comcast.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/comcast.net.xml deleted file mode 100644 index a78656b58b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/comcast.net.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - comcast.net - Comcast - Comcast - - mail.comcast.net - 110 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - smtp.comcast.net - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/concerto.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/concerto.plala.or.jp.xml deleted file mode 100644 index 1c190b5d70..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/concerto.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - concerto.plala.or.jp - ぷらら - ぷらら - - concerto.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - concerto.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/coral.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/coral.plala.or.jp.xml deleted file mode 100644 index 1c52fcee37..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/coral.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - coral.plala.or.jp - ぷらら - ぷらら - - coral.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - coral.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/courante.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/courante.plala.or.jp.xml deleted file mode 100644 index 05976ef0b3..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/courante.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - courante.plala.or.jp - ぷらら - ぷらら - - courante.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - courante.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cpost.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cpost.plala.or.jp.xml deleted file mode 100644 index 613d3774b9..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cpost.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - cpost.plala.or.jp - ぷらら - ぷらら - - cpost.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - cpost.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cream.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cream.plala.or.jp.xml deleted file mode 100644 index 16e232591b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/cream.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - cream.plala.or.jp - ぷらら - ぷらら - - cream.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - cream.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dan.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dan.wind.ne.jp.xml deleted file mode 100644 index b027d98d04..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dan.wind.ne.jp.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - dan.wind.ne.jp - dan.wind.jp - dan.wind.co.jp - dan.gunmanet.or.jp - dan.gunmanet.ne.jp - 群馬インターネット - wind - - dan.wind.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - dan.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dance.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dance.plala.or.jp.xml deleted file mode 100644 index 74f90c8fbc..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dance.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - dance.plala.or.jp - ぷらら - ぷらら - - dance.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - dance.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dd.iij4u.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dd.iij4u.or.jp.xml deleted file mode 100644 index 5d4221816d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dd.iij4u.or.jp.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - dd.iij4u.or.jp - ff.iij4u.or.jp - hh.iij4u.or.jp - kk.iij4u.or.jp - nn.iij4u.or.jp - pp.iij4u.or.jp - rr.iij4u.or.jp - ss.iij4u.or.jp - bc.iij4u.or.jp - bk.iij4u.or.jp - bp.iij4u.or.jp - bu.iij4u.or.jp - IIJ4U - IIJ4U - - mbox.iij4u.or.jp - 110 - STARTTLS - %EMAILLOCALPART%.%EMAILDOMAIN% - password-encrypted - - - mbox.iij4u.or.jp - 587 - STARTTLS - %EMAILLOCALPART%.%EMAILDOMAIN% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/df.eu.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/df.eu.xml deleted file mode 100644 index 9d54fd2d58..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/df.eu.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - ispgateway.de - domainFACTORY - domainFACTORY - - sslmailpool.ispgateway.de - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - sslmailpool.ispgateway.de - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - smtprelaypool.ispgateway.de - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - Configuration of Thunderbird (2, 3, 3.1) and others - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dmail.plala.or.jp.xml deleted file mode 100644 index f742605b4f..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/dmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - dmail.plala.or.jp - ぷらら - ぷらら - - dmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - dmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/earthlink.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/earthlink.net.xml deleted file mode 100644 index 6807e32cc2..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/earthlink.net.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - earthlink.net - mindspring.com - ix.netcom.com - - EarthLink - EarthLink - - imap.earthlink.net - 143 - plain - %EMAILADDRESS% - password-encrypted - - - pop.earthlink.net - 110 - plain - %EMAILADDRESS% - password-encrypted - - - smtpauth.earthlink.net - 587 - STARTTLS - %EMAILADDRESS% - password-encrypted - - - POP settings, domains - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ebony.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ebony.plala.or.jp.xml deleted file mode 100644 index 11a275e990..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ebony.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - ebony.plala.or.jp - ぷらら - ぷらら - - ebony.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - ebony.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/email.it.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/email.it.xml deleted file mode 100644 index 22ec45629f..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/email.it.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - email.it - email.it - email.it - - imapmail.email.it - 993 - SSL - %EMAILADDRESS% - password-encrypted - - - popmail.email.it - 995 - SSL - %EMAILADDRESS% - password-encrypted - - - smtp.email.it - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/email.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/email.plala.or.jp.xml deleted file mode 100644 index 45a8e0d500..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/email.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - email.plala.or.jp - ぷらら - ぷらら - - email.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - email.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ewetel.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ewetel.de.xml deleted file mode 100644 index b61ac4c6de..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ewetel.de.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - ewetel.de - ewetel.net - EWE Tel - EWE Tel - - pop3s-1.ewetel.net - 995 - SSL - password-cleartext - %EMAILLOCALPART% - - - smtps-1.ewetel.net - 25 - STARTTLS - password-cleartext - %EMAILLOCALPART% - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fantasy.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fantasy.plala.or.jp.xml deleted file mode 100644 index 5774cc239a..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fantasy.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - fantasy.plala.or.jp - ぷらら - ぷらら - - fantasy.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - fantasy.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/flamenco.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/flamenco.plala.or.jp.xml deleted file mode 100644 index 3a8ade7488..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/flamenco.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - flamenco.plala.or.jp - ぷらら - ぷらら - - flamenco.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - flamenco.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fmail.plala.or.jp.xml deleted file mode 100644 index c4a4dbc14b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - fmail.plala.or.jp - ぷらら - ぷらら - - fmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - fmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/francetelecom.fr.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/francetelecom.fr.xml deleted file mode 100644 index 32d67bfc00..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/francetelecom.fr.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - wanadoo.fr - orange.fr - France Telecom / Orange - Orange - - pop.orange.fr - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - imap.orange.fr - 143 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.orange.fr - 587 - plain - %EMAILLOCALPART% - password-cleartext - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/free.fr.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/free.fr.xml deleted file mode 100644 index a3fac4d29f..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/free.fr.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - free.fr - Free Telecom - free.fr - - - imap.free.fr - 993 - SSL - %EMAILLOCALPART% - password-cleartext - - - - pop.free.fr - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - - smtp.free.fr - 25 - plain - %EMAILLOCALPART% - password-cleartext - client-IP-address - - - - - How to set up Thunderbird with Free.fr - Configurer Thunderbird avec Free - - - How to setup a secure IMAP account - Serveur de réception IMAP sécurisé SSL - - - How to enable authenticated SMTP - Comment activer le serveur d'envoi SMTP authentifié - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/freenet.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/freenet.de.xml deleted file mode 100644 index e2cb788723..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/freenet.de.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - freenet.de - Freenet Mail - Freenet - - mx.freenet.de - 993 - SSL - password-encrypted - %EMAILADDRESS% - - - mx.freenet.de - 143 - STARTTLS - password-encrypted - %EMAILADDRESS% - - - mx.freenet.de - 995 - SSL - password-cleartext - %EMAILADDRESS% - - - mx.freenet.de - 110 - STARTTLS - password-cleartext - %EMAILADDRESS% - - - mx.freenet.de - 465 - SSL - password-encrypted - %EMAILADDRESS% - - - mx.freenet.de - 587 - STARTTLS - password-encrypted - %EMAILADDRESS% - - - Generic settings page - - - TB 2.0 IMAP settings - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fuga.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fuga.plala.or.jp.xml deleted file mode 100644 index f41116addd..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/fuga.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - fuga.plala.or.jp - ぷらら - ぷらら - - fuga.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - fuga.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gandi.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gandi.net.xml deleted file mode 100644 index b71cdbb18d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gandi.net.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - gandi.net - Gandi Mail - Gandi - - mail.gandi.net - 993 - SSL - password-cleartext - %EMAILADDRESS% - - - mail.gandi.net - 143 - STARTTLS - password-cleartext - %EMAILADDRESS% - - - mail.gandi.net - 995 - SSL - password-cleartext - %EMAILADDRESS% - - - mail.gandi.net - 110 - STARTTLS - password-cleartext - %EMAILADDRESS% - - - mail.gandi.net - 465 - SSL - password-cleartext - %EMAILADDRESS% - - - mail.gandi.net - 587 - STARTTLS - password-cleartext - %EMAILADDRESS% - - - Generic settings page - - - Create new mailbox, including MX servers to use in DNS - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmail.plala.or.jp.xml deleted file mode 100644 index d369859a43..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - gmail.plala.or.jp - ぷらら - ぷらら - - gmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - gmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmx.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmx.com.xml deleted file mode 100644 index 6c2809feb1..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmx.com.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - gmx.com - gmx.tm - gmx.us - gmx.co.uk - gmx.es - gmx.fr - gmx.ca - gmx.cn - gmx.co.in - gmx.com.br - gmx.com.my - gmx.hk - gmx.ie - gmx.ph - gmx.pt - gmx.ru - gmx.se - gmx.sg - gmx.tw - gmx.com.tr - gmx.it - gmx.li - - GMX Freemail - GMX - - imap.gmx.com - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - imap.gmx.com - 143 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - pop.gmx.com - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - pop.gmx.com - 110 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - mail.gmx.com - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - mail.gmx.com - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmx.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmx.net.xml deleted file mode 100644 index 5a33fb0450..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gmx.net.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - gmx.net - gmx.de - gmx.at - gmx.ch - gmx.eu - gmx.biz - gmx.org - gmx.info - - - GMX Freemail - GMX - - - imap.gmx.net - 993 - SSL - - %EMAILADDRESS% - password-cleartext - - - imap.gmx.net - 143 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - pop.gmx.net - 995 - SSL - - %EMAILADDRESS% - password-cleartext - - - pop.gmx.net - 110 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - mail.gmx.net - 465 - SSL - - %EMAILADDRESS% - password-cleartext - - - mail.gmx.net - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/go.tvm.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/go.tvm.ne.jp.xml deleted file mode 100644 index e8e5570c42..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/go.tvm.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - go.tvm.ne.jp - テレビ松本ケーブルインターネットサービス - TVM-Net - - go.tvm.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - go.tvm.ne.jp - 25 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/goo.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/goo.jp.xml deleted file mode 100644 index ef4d5f78eb..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/goo.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - goo.jp - goo メールアドバンス - goo - - pop.mail.goo.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.mail.goo.ne.jp - 587 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/googlemail.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/googlemail.com.xml deleted file mode 100644 index ea2a63e25c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/googlemail.com.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - gmail.com - googlemail.com - - google.com - - jazztel.es - Google Mail - GMail - - imap.googlemail.com - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - pop.googlemail.com - 995 - SSL - %EMAILADDRESS% - password-cleartext - - true - - - - smtp.googlemail.com - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - You need to enable IMAP access - - - How to enable IMAP/POP3 in GMail - - - How to configure email clients for IMAP - - - How to configure email clients for POP3 - - - How to configure TB 2.0 for POP3 - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/grape.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/grape.plala.or.jp.xml deleted file mode 100644 index 09fb378504..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/grape.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - grape.plala.or.jp - ぷらら - ぷらら - - grape.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - grape.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gray.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gray.plala.or.jp.xml deleted file mode 100644 index efeb3547f0..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/gray.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - gray.plala.or.jp - ぷらら - ぷらら - - gray.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - gray.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hal.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hal.ne.jp.xml deleted file mode 100644 index 0653877103..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hal.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - hal.ne.jp - ハルインターネット - HAL - - mail.hal.ne.jp - 110 - plain - %EMAILADDRESS% - password-cleartext - - - mail.hal.ne.jp - 587 - plain - %EMAILLOCALPART% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hana.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hana.or.jp.xml deleted file mode 100644 index e2e7d7fe96..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hana.or.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - hana.or.jp - きたうら花ねっと - 花ねっと - - mail.hana.or.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - mail.hana.or.jp - 587 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hotmail.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hotmail.com.xml deleted file mode 100644 index 1474ece5f0..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/hotmail.com.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - hotmail.com - hotmail.co.uk - hotmail.co.jp - hotmail.com.br - hotmail.de - hotmail.fr - hotmail.it - hotmail.es - live.com - live.co.uk - live.co.jp - live.de - live.fr - live.it - live.jp - msn.com - Microsoft Live Hotmail - Hotmail - - pop3.live.com - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.live.com - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/i.softbank.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/i.softbank.jp.xml deleted file mode 100644 index 965d5e8343..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/i.softbank.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - i.softbank.jp - SoftBank - SoftBank - - imap.softbank.jp - 993 - SSL - password-cleartext - %EMAILLOCALPART% - - - smtp.softbank.jp - 465 - SSL - password-cleartext - %EMAILLOCALPART% - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ic-net.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ic-net.or.jp.xml deleted file mode 100644 index 8a8e995022..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ic-net.or.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - ic-net.or.jp - IC-NET - IC-NET - - mail.ic-net.or.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.ic-net.or.jp - 587 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iijmio-mail.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iijmio-mail.jp.xml deleted file mode 100644 index 00a385ed26..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iijmio-mail.jp.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - iijmio-mail.jp - miomio.jp - miobox.jp - e23.jp - x-il.jp - IIJmio セーフティメール - IIJmio - - mbox.iijmio-mail.jp - 110 - STARTTLS - %EMAILLOCALPART%.%EMAILDOMAIN% - password-encrypted - - - mbox.iijmio-mail.jp - 587 - STARTTLS - %EMAILLOCALPART%.%EMAILDOMAIN% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iiyama-catv.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iiyama-catv.ne.jp.xml deleted file mode 100644 index 96477d0a07..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iiyama-catv.ne.jp.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - iiyama-catv.ne.jp - ケーブルテレビiネット飯山 - iネット飯山 - - mail.iiyama-catv.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.iiyama-catv.ne.jp - 25 - plain - none - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/imail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/imail.plala.or.jp.xml deleted file mode 100644 index d4c8897d22..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/imail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - imail.plala.or.jp - ぷらら - ぷらら - - imail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - imail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inbox.lt.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inbox.lt.xml deleted file mode 100644 index 336c817249..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inbox.lt.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - inbox.lt - - Inbox.lt - Inbox.lt - - mail.inbox.lt - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - true - - - - mail.inbox.lt - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inbox.lv.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inbox.lv.xml deleted file mode 100644 index 13786265af..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inbox.lv.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - inbox.lv - - Inbox.lv - Inbox.lv - - mail.inbox.lv - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - true - - - - mail.inbox.lv - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/indigo.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/indigo.plala.or.jp.xml deleted file mode 100644 index 2d21e2d69e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/indigo.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - indigo.plala.or.jp - ぷらら - ぷらら - - indigo.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - indigo.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inet-shibata.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inet-shibata.or.jp.xml deleted file mode 100644 index f12c85bc3e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/inet-shibata.or.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - inet-shibata.or.jp - インターネット新発田 - INET-SHIBATA - - po.inet-shibata.or.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - po.inet-shibata.or.jp - 25 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/internode.on.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/internode.on.net.xml deleted file mode 100644 index ee7dab1037..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/internode.on.net.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - internode.on.net - Internode - Internode - - mail.internode.on.net - 993 - SSL - password-cleartext - %EMAILADDRESS% - - - mail.internode.on.net - 995 - SSL - password-cleartext - %EMAILADDRESS% - - - mail.internode.on.net - 465 - SSL - password-cleartext - %EMAILADDRESS% - - - Secure settings, generic - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ipax.at.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ipax.at.xml deleted file mode 100644 index 3d6d3b4450..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ipax.at.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - ipax.at - IPAX Internet Services - IPAX - - mail.ipax.at - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - - mail.ipax.at - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - - Configure Thunderbird 3 for IMAP - Thunderbird 3 mit IMAP konfigurieren - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ivory.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ivory.plala.or.jp.xml deleted file mode 100644 index a3a0b40c79..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ivory.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - ivory.plala.or.jp - ぷらら - ぷらら - - ivory.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - ivory.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iwafune.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iwafune.ne.jp.xml deleted file mode 100644 index f7cf4cd705..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/iwafune.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - iwafune.ne.jp - インターネットいわふね - IWAFUNE - - po.iwafune.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - po.iwafune.ne.jp - 25 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jade.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jade.plala.or.jp.xml deleted file mode 100644 index 998ff0ce43..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jade.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - jade.plala.or.jp - ぷらら - ぷらら - - jade.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - jade.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/janis.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/janis.or.jp.xml deleted file mode 100644 index d23012b016..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/janis.or.jp.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - janis.or.jp - Janis - Janis - - mail.%EMAILDOMAIN% - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.%EMAILDOMAIN% - 25 - plain - none - client-IP-address - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jet.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jet.ne.jp.xml deleted file mode 100644 index 13e49f02a8..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jet.ne.jp.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - jet.ne.jp - JETINTERNET - JET - - pop.jet.ne.jp - 110 - plain - %EMAILLOCALPART% - password-encrypted - - - imap.jet.ne.jp - 993 - SSL - %EMAILLOCALPART% - password-encrypted - - - smtp.jet.ne.jp - 587 - plain - %EMAILLOCALPART% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ji.jet.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ji.jet.ne.jp.xml deleted file mode 100644 index ecc22eb8dd..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ji.jet.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - ji.jet.ne.jp - JETINTERNET - JET - - pop02.jet.ne.jp - 110 - plain - %EMAILLOCALPART% - password-encrypted - - - smtp02.jet.ne.jp - 587 - plain - %EMAILLOCALPART% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jmail.plala.or.jp.xml deleted file mode 100644 index a8c80b2026..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/jmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - jmail.plala.or.jp - ぷらら - ぷらら - - jmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - jmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kabelmail.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kabelmail.de.xml deleted file mode 100644 index 6f58d3e1a3..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kabelmail.de.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - kabelmail.de - Kabel Deutschland - Kabel D - - pop3.kabelmail.de - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.kabelmail.de - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.kabelmail.de - 25 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kelcom.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kelcom.net.xml deleted file mode 100644 index a3e211afc0..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kelcom.net.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - kelcom.net - KELCOM Internet - KELCOM - - pop1.kelcom.net - 110 - plain - %EMAILADDRESS% - password-cleartext - - - smtp.kelcom.net - 25 - plain - %EMAILADDRESS% - password-cleartext - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/khaki.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/khaki.plala.or.jp.xml deleted file mode 100644 index 09b562ce68..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/khaki.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - khaki.plala.or.jp - ぷらら - ぷらら - - khaki.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - khaki.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kl.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kl.wind.ne.jp.xml deleted file mode 100644 index 80bd91ee82..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kl.wind.ne.jp.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - kl.wind.ne.jp - kl.wind.jp - kl.wind.co.jp - kl.gunmanet.or.jp - kl.gunmanet.ne.jp - k1.wind.ne.jp - k1.wind.jp - k1.gunmanet.or.jp - k1.gunmanet.ne.jp - 群馬インターネット - wind - - kl.wind.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - kl.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kmail.plala.or.jp.xml deleted file mode 100644 index 7e88d5f88d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - kmail.plala.or.jp - ぷらら - ぷらら - - kmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - kmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kokuyou.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kokuyou.ne.jp.xml deleted file mode 100644 index 5e6d65702d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/kokuyou.ne.jp.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - kokuyou.ne.jp - 長和町黒耀の里ゆいねっと - ゆいねっと - - mail.kokuyou.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.kokuyou.ne.jp - 25 - plain - none - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lapis.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lapis.plala.or.jp.xml deleted file mode 100644 index eb54651cb0..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lapis.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - lapis.plala.or.jp - ぷらら - ぷらら - - lapis.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - lapis.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/laposte.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/laposte.net.xml deleted file mode 100644 index 18a7257cf1..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/laposte.net.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - laposte.net - LaPoste - LaPoste - - imap.laposte.net - 993 - SSL - %EMAILLOCALPART% - password-cleartext - - - pop.laposte.net - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - smtp.laposte.net - 465 - SSL - %EMAILLOCALPART% - password-cleartext - - - Annonce sur le site de Geckozone (non-officiel) - News on the Geckozone website (unofficial) - - - Aide officielle (non-SSL) - Official support (no SSL) - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lemon.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lemon.plala.or.jp.xml deleted file mode 100644 index 26846d8f5c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lemon.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - lemon.plala.or.jp - ぷらら - ぷらら - - lemon.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - lemon.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/libero.it.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/libero.it.xml deleted file mode 100644 index 172e2a00ad..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/libero.it.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - libero.it - iol.it - blu.it - inwind.it - Libero Mail - Libero - - imapmail.libero.it - 143 - plain - %EMAILADDRESS% - password-encrypted - - - popmail.libero.it - 110 - plain - %EMAILADDRESS% - password-encrypted - - - smtp.libero.it - 25 - plain - %EMAILADDRESS% - password-encrypted - - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lilac.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lilac.plala.or.jp.xml deleted file mode 100644 index 1283c0246e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lilac.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - lilac.plala.or.jp - ぷらら - ぷらら - - lilac.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - lilac.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lime.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lime.plala.or.jp.xml deleted file mode 100644 index 94e092548b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/lime.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - lime.plala.or.jp - ぷらら - ぷらら - - lime.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - lime.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mahoroba.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mahoroba.ne.jp.xml deleted file mode 100644 index 7365039ff7..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mahoroba.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - mahoroba.ne.jp - インターネットまほろば - まほろば - - mail.mahoroba.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - mail.mahoroba.ne.jp - 587 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.com.xml deleted file mode 100644 index de1c346914..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.com.xml +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - mail.com - mail.org - email.com - post.com - usa.com - accountant.com - consultant.com - dr.com - engineer.com - cheerful.com - techie.com - linuxmail.org - europe.com - london.com - uymail.com - myself.com - iname.com - writeme.com - - 2die4.com - activist.com - adexec.com - africamail.com - aircraftmail.com - alabama.usa.com - alaska.usa.com - allergist.com - alumni.com - alumnidirector.com - americamail.com - amorous.com - angelic.com - archaeologist.com - arizona.usa.com - artlover.com - asia-mail.com - atheist.com - australiamail.com - bartender.net - berlin.com - bigger.com - bikerider.com - birdlover.com - blader.com - boardermail.com - brazilmail.com - brew-master.com - california.usa.com - californiamail.com - caress.com - catlover.com - chef.net - chemist.com - chinamail.com - clerk.com - cliffhanger.com - collector.org - columnist.com - comic.com - computer4u.com - contractor.net - coolsite.net - counsellor.com - count.com - couple.com - cutey.com - cyberdude.com - cybergal.com - cyber-wizard.com - dallasmail.com - dbzmail.com - deliveryman.com - diplomats.com - disciples.com - doctor.com - doglover.com - doramail.com - dublin.com - earthling.net - elvisfan.com - englandmail.com - europemail.com - execs.com - fan.com - feelings.com - financier.com - fireman.net - florida.usa.com - footballer.com - gardener.com - geologist.com - germanymail.com - graduate.org - graphic-designer.com - hackermail.com - hairdresser.net - hilarious.com - hockeymail.com - homemail.com - hot-shot.com - hour.com - humanoid.net - illinois.usa.com - innocent.com - inorbit.com - instruction.com - instructor.net - insurer.com - irelandmail.com - italymail.com - japan.com - journalist.com - keromail.com - kittymail.com - koreamail.com - lawyer.com - legislator.com - loveable.com - lovecat.com - mad.scientist.com - madonnafan.com - madrid.com - marchmail.com - mexicomail.com - mindless.com - minister.com - mobsters.com - monarchy.com - moscowmail.com - munich.com - musician.org - muslim.com - newyork.usa.com - null.net - nycmail.com - oath.com - optician.com - pacificwest.com - petlover.com - photographer.net - playful.com - poetic.com - politician.com - popstar.com - presidency.com - priest.com - programmer.net - publicist.com - realtyagent.com - reborn.com - reggaefan.com - religious.com - repairman.com - representative.com - rescueteam.com - revenue.com - rocketship.com - rockfan.com - rome.com - royal.net - saintly.com - salesperson.net - sanfranmail.com - scientist.com - scotlandmail.com - secretary.net - seductive.com - singapore.com - snakebite.com - songwriter.net - soon.com - spainmail.com - teachers.org - technologist.com - texas.usa.com - thegame.com - therapist.net - toke.com - tokyo.com - toothfairy.com - tvstar.com - umpire.com - wallet.com - webname.com - weirdness.com - who.net - whoever.com - winning.com - witty.com - worker.com - workmail.com - yours.com - - mail.com - mail.com - - imap.mail.com - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - imap.mail.com - 143 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - pop.mail.com - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - pop.mail.com - 110 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - smtp.mail.com - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.mail.com - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.dk.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.dk.xml deleted file mode 100644 index 2a16f8995b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.dk.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - mail.dk - TDC (DK) - TDC - - pop3.mail.dk - 110 - plain - %EMAILADDRESS% - password-cleartext - - - asmtp.mail.dk - 587 - plain - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.iwafune.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.iwafune.ne.jp.xml deleted file mode 100644 index 38123dc5cf..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.iwafune.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - mail.iwafune.ne.jp - インターネットいわふね - IWAFUNE - - mail.iwafune.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - mail.iwafune.ne.jp - 25 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.ru.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.ru.xml deleted file mode 100644 index bc86f1fcc7..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.ru.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - mail.ru - inbox.ru - list.ru - bk.ru - mail.ru - mail.ru - - pop.mail.ru - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - pop.mail.ru - 110 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - smtp.mail.ru - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.mail.ru - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - - POP, Thunderbird, with screenshots - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.telenor.dk.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.telenor.dk.xml deleted file mode 100644 index 74dc63dcc7..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.telenor.dk.xml +++ /dev/null @@ -1,121 +0,0 @@ - - - - - mail.telenor.dk - vip.cybercity.dk - post.cybercity.dk - - email.dk - mobil.dk - privatmail.dk - info.dk - io.dk - it.dk - film.dk - worldonline.dk - wol.dk - - 1031.inord.dk - 123mail.dk - 12fuel.dk - 12mail.dk - 12move.dk - 2senior.dk - anarki.dk - anderledes.dk - begavet.dk - bitnisse.dk - city.dk - cool.dk - cyberdude.dk - cyberjunkie.dk - dk2net.dk - dk-online.dk - elinstallatoer.dk - elsker.dk - elvis.dk - fald.dk - fedt.dk - feminin.dk - forening.dk - gadefejer.dk - gason.dk - grin.dk - grov.dk - hardworking.dk - heaven.dk - hemmelig.dk - huleboer.dk - image.dk - inbound.dk - indbakke.dk - infile.dk - jyde.dk - klog.dk - knus.dk - krudt.dk - kulturel.dk - larsen.dk - lazy.dk - lystig.dk - mail.dia.dk - maskulin.dk - min-postkasse.dk - musling.dk - natteliv.dk - netbruger.dk - pedal.dk - pengemand.dk - pokerface.dk - post.dia.dk - postman.dk - privat.dia.dk - quake.dk - ready.dk - secret.dk - sleepy.dk - sporty.dk - superbruger.dk - talent.dk - tanke.dk - taxidriver.dk - teens.dk - teknik.dk - tjekket.dk - traceroute.dk - tv.dk - ugenstilbud.dk - ungdom.dk - video.dk - vittig.dk - Telenor Danmark - Telenor - - mail.telenor.dk - 143 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - mail.telenor.dk - 110 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - mail.telenor.dk - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - - - - Domain list source (requires login) - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.wind.ne.jp.xml deleted file mode 100644 index 90bdf8ecf8..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mail.wind.ne.jp.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - mail.wind.ne.jp - mail.wind.jp - mail.wind.co.jp - mail.gunmanet.or.jp - mail.gunmanet.ne.jp - mail.gunmanet.jp - 群馬インターネット - wind - - mail.wind.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - mail.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/maroon.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/maroon.plala.or.jp.xml deleted file mode 100644 index d2e00e2d0d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/maroon.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - maroon.plala.or.jp - ぷらら - ぷらら - - maroon.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - maroon.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/me.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/me.com.xml deleted file mode 100644 index 9c7d7311dc..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/me.com.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - mac.com - me.com - Apple iCloud - Apple - - imap.mail.me.com - 993 - SSL - %EMAILLOCALPART% - plain - - - - smtp.mail.me.com - 587 - STARTTLS - %EMAILLOCALPART% - plain - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/minuet.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/minuet.plala.or.jp.xml deleted file mode 100644 index af72bf2644..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/minuet.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - minuet.plala.or.jp - ぷらら - ぷらら - - minuet.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - minuet.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ml.murakami.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ml.murakami.ne.jp.xml deleted file mode 100644 index c563dba3df..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ml.murakami.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - ml.murakami.ne.jp - インターネットいわふね - IWAFUNE - - ml.murakami.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - ml.murakami.ne.jp - 25 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mnet.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mnet.ne.jp.xml deleted file mode 100644 index 0965552fbe..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mnet.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - mnet.ne.jp - Mnet メール サービス - Mnetメール - - mail.mnet.ne.jp - 110 - plain - %EMAILADDRESS% - password-encrypted - - - mail.mnet.ne.jp - 587 - plain - %EMAILADDRESS% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mopera.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mopera.net.xml deleted file mode 100644 index 26f6037f92..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mopera.net.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - mopera.net - mopera U - mopera U - - mail.mopera.net - 993 - SSL - %EMAILLOCALPART% - password-cleartext - - - mail.mopera.net - 143 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - mail.mopera.net - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - mail.mopera.net - 110 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - mail.mopera.net - 465 - SSL - %EMAILLOCALPART% - password-encrypted - - - mail.mopera.net - 587 - STARTTLS - %EMAILLOCALPART% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mozilla.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mozilla.com.xml deleted file mode 100644 index 3275fcf8d6..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mozilla.com.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - mozilla.com - mozillafoundation.org - Mozilla Corporation and Mozilla Foundation internal email addresses - mozilla.com - - mail.mozilla.com - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.mozilla.org - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mx1.tiki.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mx1.tiki.ne.jp.xml deleted file mode 100644 index d87f89eda9..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/mx1.tiki.ne.jp.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - mx1.tiki.ne.jp - mx2.et.tiki.ne.jp - mx2.tiki.ne.jp - mx2.wt.tiki.ne.jp - mx3.et.tiki.ne.jp - mx3.tiki.ne.jp - mx4.et.tiki.ne.jp - mx4.tiki.ne.jp - mx5.et.tiki.ne.jp - mx5.tiki.ne.jp - mx6.et.tiki.ne.jp - mx6.tiki.ne.jp - mx7.tiki.ne.jp - mx8.tiki.ne.jp - mx9.tiki.ne.jp - mx21.tiki.ne.jp - mx22.tiki.ne.jp - mx31.tiki.ne.jp - mx32.tiki.ne.jp - mx35.tiki.ne.jp - mx36.tiki.ne.jp - mx41.tiki.ne.jp - mx51.et.tiki.ne.jp - mx51.tiki.ne.jp - mx52.tiki.ne.jp - mx61.tiki.ne.jp - mx71.tiki.ne.jp - mx81.tiki.ne.jp - mx82.tiki.ne.jp - mx91.tiki.ne.jp - ma100.tiki.ne.jp - TikiTikiインターネット - TikiTiki - - %EMAILDOMAIN% - 110 - plain - %EMAILLOCALPART% - plain - - - smtp-auth.tiki.ne.jp - 587 - plain - %EMAILADDRESS% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/navy.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/navy.plala.or.jp.xml deleted file mode 100644 index 3935216659..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/navy.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - navy.plala.or.jp - ぷらら - ぷらら - - navy.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - navy.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nctsoft.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nctsoft.com.xml deleted file mode 100644 index 0299065241..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nctsoft.com.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - nctsoft.com - nctsoft - nct - - mail.nctsoft.com - 110 - plain - %EMAILLOCALPART%@%EMAILHOSTNAME% - password-cleartext - - - mail.nctsoft.com - 25 - plain - %EMAILLOCALPART%@%EMAILHOSTNAME% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nifty.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nifty.com.xml deleted file mode 100644 index 12217d4d71..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nifty.com.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - nifty.com - @nifty - @nifty - - pop.nifty.com - 110 - plain - %EMAILLOCALPART% - password-encrypted - - - smtp.nifty.com - 587 - plain - %EMAILLOCALPART% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nsat.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nsat.jp.xml deleted file mode 100644 index a8a32062ac..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/nsat.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - nsat.jp - BBにいがた - NSAT - - mail.nsat.jp - 110 - plain - %EMAILADDRESS% - password-encrypted - - - mail.nsat.jp - 587 - plain - %EMAILADDRESS% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/o2.pl.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/o2.pl.xml deleted file mode 100644 index 7a9671f85f..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/o2.pl.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - o2.pl - go2.pl - tlen.pl - prokonto.pl - o2 Poczta - o2 - - poczta.o2.pl - 995 - SSL - password-cleartext - %EMAILLOCALPART% - - - poczta.o2.pl - 465 - SSL - password-cleartext - %EMAILLOCALPART% - client-IP-address - - - poczta.o2.pl - 587 - STARTTLS - password-cleartext - %EMAILLOCALPART% - client-IP-address - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/olive.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/olive.plala.or.jp.xml deleted file mode 100644 index f85b0232ea..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/olive.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - olive.plala.or.jp - ぷらら - ぷらら - - olive.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - olive.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/onet.pl.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/onet.pl.xml deleted file mode 100644 index 8a25934cfa..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/onet.pl.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - onet.pl - onet.eu - poczta.onet.pl - poczta.onet.eu - op.pl - vp.pl - autograf.pl - buziaczek.pl - amorki.pl - republika.pl - Poczta Onet - Onet - - pop3.poczta.onet.pl - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.poczta.onet.pl - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.poczta.onet.pl - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/opal.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/opal.plala.or.jp.xml deleted file mode 100644 index 168f59fd01..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/opal.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - opal.plala.or.jp - ぷらら - ぷらら - - opal.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - opal.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/orange.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/orange.plala.or.jp.xml deleted file mode 100644 index 7baa803144..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/orange.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - orange.plala.or.jp - ぷらら - ぷらら - - orange.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - orange.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/orchid.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/orchid.plala.or.jp.xml deleted file mode 100644 index b5c8bc2130..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/orchid.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - orchid.plala.or.jp - ぷらら - ぷらら - - orchid.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - orchid.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ovh.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ovh.net.xml deleted file mode 100644 index f469126cbb..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ovh.net.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - ovh.net - - OVH - OVH - - ssl0.ovh.net - 993 - SSL - password-cleartext - %EMAILADDRESS% - - - ssl0.ovh.net - 995 - SSL - password-cleartext - %EMAILADDRESS% - - - ssl0.ovh.net - 465 - SSL - password-cleartext - %EMAILADDRESS% - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pal.kijimadaira.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pal.kijimadaira.jp.xml deleted file mode 100644 index 5652a2c7e2..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pal.kijimadaira.jp.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - pal.kijimadaira.jp - 木島平村FTTH - 木島平村FTTH - - mail.pal.kijimadaira.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.pal.kijimadaira.jp - 25 - plain - none - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/palette.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/palette.plala.or.jp.xml deleted file mode 100644 index 1a64ad6643..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/palette.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - palette.plala.or.jp - ぷらら - ぷらら - - palette.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - palette.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/parabox.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/parabox.or.jp.xml deleted file mode 100644 index bda1e22461..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/parabox.or.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - parabox.or.jp - パラボックス - PARABOX - - pop3.parabox.or.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.parabox.or.jp - 25 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pdx.edu.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pdx.edu.xml deleted file mode 100644 index e0370caeae..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pdx.edu.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - pdx.edu - Portland State University Mail - PSU Mail - - psumail.pdx.edu - 993 - SSL - password-encrypted - %EMAILADDRESS% - - - psumail.pdx.edu - 587 - STARTTLS - password-encrypted - %EMAILADDRESS% - - - mailhost.pdx.edu - 465 - SSL - password-encrypted - %EMAILADDRESS% - - - mailhost.pdx.edu - 587 - STARTTLS - password-encrypted - %EMAILADDRESS% - - - Portland State University Email Settings for Advanced Users - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/peach.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/peach.plala.or.jp.xml deleted file mode 100644 index 34c7a3df41..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/peach.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - peach.plala.or.jp - ぷらら - ぷらら - - peach.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - peach.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/peoplepc.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/peoplepc.com.xml deleted file mode 100644 index 01429db957..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/peoplepc.com.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - peoplepc.com - PeoplePC - PeoplePC - - imap.peoplepc.com - 143 - plain - %EMAILADDRESS% - password-encrypted - - - pop.peoplepc.com - 110 - plain - %EMAILADDRESS% - password-encrypted - - - smtpauth.peoplepc.com - 587 - STARTTLS - %EMAILADDRESS% - password-encrypted - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/plum.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/plum.plala.or.jp.xml deleted file mode 100644 index 5696afd5ba..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/plum.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - plum.plala.or.jp - ぷらら - ぷらら - - plum.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - plum.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/po.dcn.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/po.dcn.ne.jp.xml deleted file mode 100644 index efa044e03f..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/po.dcn.ne.jp.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - po.dcn.ne.jp - DCNインターネットサービス - DCN - - po.dcn.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - po.dcn.ne.jp - 25 - plain - none - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/po.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/po.wind.ne.jp.xml deleted file mode 100644 index 96b2d0f81b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/po.wind.ne.jp.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - po.wind.ne.jp - po.wind.jp - po.wind.co.jp - po.gunmanet.or.jp - po.gunmanet.ne.jp - 群馬インターネット - wind - - po.wind.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - po.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/polka.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/polka.plala.or.jp.xml deleted file mode 100644 index 087065eb7f..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/polka.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - polka.plala.or.jp - ぷらら - ぷらら - - polka.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - polka.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pop.shibata.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pop.shibata.ne.jp.xml deleted file mode 100644 index 6f2e8df7b2..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/pop.shibata.ne.jp.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - pop.shibata.ne.jp - ml.shibata.ne.jp - インターネット新発田 - INET-SHIBATA - - %EMAILDOMAIN% - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - %EMAILDOMAIN% - 25 - plain - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/posteo.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/posteo.de.xml deleted file mode 100644 index 3720753d66..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/posteo.de.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - posteo.de - posteo.at - posteo.ch - posteo.org - posteo.eu - Posteo - Posteo - - posteo.de - 143 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - posteo.de - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/purple.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/purple.plala.or.jp.xml deleted file mode 100644 index 393d2ac841..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/purple.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - purple.plala.or.jp - ぷらら - ぷらら - - purple.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - purple.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/qip.ru.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/qip.ru.xml deleted file mode 100644 index 01cfd5ee8d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/qip.ru.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - qip.ru - pochta.ru - fromru.com - front.ru - hotbox.ru - hotmail.ru - krovatka.su - land.ru - mail15.com - mail333.com - newmail.ru - nightmail.ru - nm.ru - pisem.net - pochtamt.ru - pop3.ru - rbcmail.ru - smtp.ru - 5ballov.ru - aeterna.ru - ziza.ru - memori.ru - photofile.ru - fotoplenka.ru - qip.ru - qip.ru - - pop.qip.ru - 110 - plain - %EMAILADDRESS% - password-cleartext - - - imap.qip.ru - 143 - plain - %EMAILADDRESS% - password-cleartext - - - smtp.qip.ru - 25 - plain - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rainbow.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rainbow.plala.or.jp.xml deleted file mode 100644 index 3718ed4868..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rainbow.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - rainbow.plala.or.jp - ぷらら - ぷらら - - rainbow.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - rainbow.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rambler.ru.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rambler.ru.xml deleted file mode 100644 index 10a92c3d03..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rambler.ru.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - rambler.ru - lenta.ru - myrambler.ru - autorambler.ru - ro.ru - r0.ru - Rambler Mail - Rambler - - mail.rambler.ru - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - mail.rambler.ru - 995 - SSL - %EMAILADDRESS% - password-encrypted - - - mail.rambler.ru - 465 - SSL - %EMAILADDRESS% - password-encrypted - - - - POP, Thunderbird, with screenshots - - - IMAP, all clients - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/red.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/red.plala.or.jp.xml deleted file mode 100644 index a42e8893ff..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/red.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - red.plala.or.jp - ぷらら - ぷらら - - red.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - red.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rmail.plala.or.jp.xml deleted file mode 100644 index 7ecc703e01..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - rmail.plala.or.jp - ぷらら - ぷらら - - rmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - rmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rondo.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rondo.plala.or.jp.xml deleted file mode 100644 index 13616d3e41..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rondo.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - rondo.plala.or.jp - ぷらら - ぷらら - - rondo.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - rondo.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rose.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rose.plala.or.jp.xml deleted file mode 100644 index 034f32cab4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rose.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - rose.plala.or.jp - ぷらら - ぷらら - - rose.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - rose.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rouge.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rouge.plala.or.jp.xml deleted file mode 100644 index cbbb43ce4d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rouge.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - rouge.plala.or.jp - ぷらら - ぷらら - - rouge.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - rouge.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rr.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rr.com.xml deleted file mode 100644 index 93346f9560..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/rr.com.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - rr.com - RoadRunner - RR - - pop-server.%EMAILDOMAIN% - 110 - plain - %EMAILADDRESS% - password-cleartext - - - smtp-server.%EMAILDOMAIN% - 25 - plain - %EMAILADDRESS% - password-cleartext - - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ruby.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ruby.plala.or.jp.xml deleted file mode 100644 index 427be4b3cf..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ruby.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - ruby.plala.or.jp - ぷらら - ぷらら - - ruby.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - ruby.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sakunet.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sakunet.ne.jp.xml deleted file mode 100644 index 80d5f24d99..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sakunet.ne.jp.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - sakunet.ne.jp - 佐久ケーブルテレビ - Saku-Net - - mail.sakunet.ne.jp - 110 - plain - %EMAILLOCALPART% - password-cleartext - - - smtp.sakunet.ne.jp - 25 - plain - none - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sea.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sea.plala.or.jp.xml deleted file mode 100644 index ddde2c1767..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sea.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - sea.plala.or.jp - ぷらら - ぷらら - - sea.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - sea.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sepia.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sepia.plala.or.jp.xml deleted file mode 100644 index 1dce9e1cf4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sepia.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - sepia.plala.or.jp - ぷらら - ぷらら - - sepia.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - sepia.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/serenade.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/serenade.plala.or.jp.xml deleted file mode 100644 index 83bf35b7ba..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/serenade.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - serenade.plala.or.jp - ぷらら - ぷらら - - serenade.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - serenade.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/seznam.cz.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/seznam.cz.xml deleted file mode 100644 index 7dacb0cba4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/seznam.cz.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - seznam.cz - email.cz - post.cz - spoluzaci.cz - Seznam - Seznam - - pop3.seznam.cz - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.seznam.cz - 25 - plain - %EMAILADDRESS% - password-cleartext - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sfr.fr.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sfr.fr.xml deleted file mode 100644 index 845c27cce9..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sfr.fr.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - sfr.fr - neuf.fr - SFR / Neuf - SFR - - imap.sfr.fr - 143 - plain - %EMAILADDRESS% - password-cleartext - - - pop.sfr.fr - 110 - plain - %EMAILADDRESS% - password-cleartext - - - smtp.sfr.fr - 587 - plain - %EMAILADDRESS% - password-cleartext - - - TB2, unclear - - - Apple Mail - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/silk.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/silk.plala.or.jp.xml deleted file mode 100644 index 1aa4b81964..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/silk.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - silk.plala.or.jp - ぷらら - ぷらら - - silk.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - silk.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/silver.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/silver.plala.or.jp.xml deleted file mode 100644 index 8ff9fd9ec8..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/silver.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - silver.plala.or.jp - ぷらら - ぷらら - - silver.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - silver.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sky.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sky.plala.or.jp.xml deleted file mode 100644 index 9da6383b8c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sky.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - sky.plala.or.jp - ぷらら - ぷらら - - sky.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - sky.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/skynet.be.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/skynet.be.xml deleted file mode 100644 index 66442b02b0..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/skynet.be.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - skynet.be - skynet - skynet - - imap.skynet.be - 993 - SSL - password-cleartext - %EMAILADDRESS% - - - pop.skynet.be - 110 - plain - password-encrypted - %EMAILADDRESS% - - - relay.skynet.be - 587 - STARTTLS - password-cleartext - %EMAILADDRESS% - - - Thunderbird settings - - - SMTP works outside their network - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/smail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/smail.plala.or.jp.xml deleted file mode 100644 index 1768bfd9bc..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/smail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - smail.plala.or.jp - ぷらら - ぷらら - - smail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - smail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/snow.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/snow.plala.or.jp.xml deleted file mode 100644 index 44267b99b1..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/snow.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - snow.plala.or.jp - ぷらら - ぷらら - - snow.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - snow.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/so.wind.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/so.wind.ne.jp.xml deleted file mode 100644 index 50fd47ef1c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/so.wind.ne.jp.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - so.wind.ne.jp - so.wind.jp - 群馬インターネット - wind - - so.wind.ne.jp - 143 - plain - %EMAILLOCALPART% - plain - - - so.wind.ne.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sonata.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sonata.plala.or.jp.xml deleted file mode 100644 index 3834428fbd..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sonata.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - sonata.plala.or.jp - ぷらら - ぷらら - - sonata.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - sonata.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/strato.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/strato.de.xml deleted file mode 100644 index a143e6f90e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/strato.de.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - strato.de - - rzone.de - - Strato - Strato - - - imap.strato.de - 993 - SSL - password-encrypted - %EMAILADDRESS% - - - pop3.strato.de - 995 - SSL - password-encrypted - %EMAILADDRESS% - - - smtp.strato.de - 465 - SSL - password-encrypted - %EMAILADDRESS% - - - smtp.strato.de - 587 - STARTTLS - password-encrypted - %EMAILADDRESS% - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/studenti.univr.it.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/studenti.univr.it.xml deleted file mode 100644 index 6eb5bf9fa7..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/studenti.univr.it.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - studenti.univr.it - Università degli Studi di Verona - UniVR - - mail.studenti.univr.it - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - mail.studenti.univr.it - 465 - SSL - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/suite.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/suite.plala.or.jp.xml deleted file mode 100644 index c8beac6b9c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/suite.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - suite.plala.or.jp - ぷらら - ぷらら - - suite.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - suite.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sympatico.ca.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sympatico.ca.xml deleted file mode 100644 index 2830faf076..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/sympatico.ca.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - sympatico.ca - - Sympatico Email - Sympatico - - - pophm.sympatico.ca - 995 - SSL - %EMAILADDRESS% - plain - - - - smtphm.sympatico.ca - 587 - STARTTLS - %EMAILADDRESS% - plain - true - false - - - POP settings, domains - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/symphony.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/symphony.plala.or.jp.xml deleted file mode 100644 index 311aa184ac..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/symphony.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - symphony.plala.or.jp - ぷらら - ぷらら - - symphony.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - symphony.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/t-online.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/t-online.de.xml deleted file mode 100644 index 0d3014b027..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/t-online.de.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - t-online.de - T-Online - T-Online - - secureimap.t-online.de - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - securepop.t-online.de - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - securesmtp.t-online.de - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - You need to set up an E-Mail-Password. Attention: The normal password for the T-Online-Website and Webmail does *not* work for email aplications. - Sie müssen ein E-Mail-Passwort einrichten. Achtung: Das Passwort für die T-Online-Website und Webmail funktioniert *nicht* für E-Mail-Programme! - - - Set up your email address - Richten Sie Ihre Email-Adresse ein - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/taupe.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/taupe.plala.or.jp.xml deleted file mode 100644 index cec35b2df5..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/taupe.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - taupe.plala.or.jp - ぷらら - ぷらら - - taupe.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - taupe.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/terra.es.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/terra.es.xml deleted file mode 100644 index f6e8a33bc7..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/terra.es.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - terra.es - Correo Terra - Terra - - imap4.terra.es - 143 - plain - %EMAILADDRESS% - password-cleartext - - - pop3.terra.es - 110 - plain - %EMAILADDRESS% - password-cleartext - - - mailhost.terra.es - 25 - plain - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiki.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiki.ne.jp.xml deleted file mode 100644 index 9e54488ead..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiki.ne.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - tiki.ne.jp - TikiTikiインターネット - TikiTiki - - mx.tiki.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - smtp-auth.tiki.ne.jp - 587 - plain - %EMAILADDRESS% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiscali.cz.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiscali.cz.xml deleted file mode 100644 index 552eb8a43d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiscali.cz.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - tiscali.cz - wo.cz - worldonline.cz - worldmail.cz - Tiscali - Tiscali - - pop3.mail.tiscali.cz - 110 - plain - %EMAILADDRESS% - password-cleartext - - - smtp.mail.tiscali.cz - 25 - plain - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiscali.it.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiscali.it.xml deleted file mode 100644 index 98f22a7578..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tiscali.it.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - tiscali.it - Tiscali Italy - Tiscali - - imap.tiscali.it - 993 - SSL - %EMAILADDRESS% - password-encrypted - - - pop.tiscali.it - 995 - SSL - %EMAILADDRESS% - password-encrypted - - - smtp.tiscali.it - 465 - SSL - %EMAILADDRESS% - password-encrypted - client-IP-address - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tmail.plala.or.jp.xml deleted file mode 100644 index d138304dc9..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/tmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - tmail.plala.or.jp - ぷらら - ぷらら - - tmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - tmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/toccata.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/toccata.plala.or.jp.xml deleted file mode 100644 index 41281a7d6c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/toccata.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - toccata.plala.or.jp - ぷらら - ぷらら - - toccata.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - toccata.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/topaz.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/topaz.plala.or.jp.xml deleted file mode 100644 index 185f1796de..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/topaz.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - topaz.plala.or.jp - ぷらら - ぷらら - - topaz.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - topaz.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/trio.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/trio.plala.or.jp.xml deleted file mode 100644 index 6d15fc17b4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/trio.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - trio.plala.or.jp - ぷらら - ぷらら - - trio.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - trio.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/umail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/umail.plala.or.jp.xml deleted file mode 100644 index 2b4a0694a0..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/umail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - umail.plala.or.jp - ぷらら - ぷらら - - umail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - umail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/umich.edu.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/umich.edu.xml deleted file mode 100644 index c19dd74c87..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/umich.edu.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - umich.edu - UM ITCS Email - UM ITCS - - mail.umich.edu - 993 - SSL - %EMAILLOCALPART% - password-cleartext - - - smtp.mail.umich.edu - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/upcmail.nl.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/upcmail.nl.xml deleted file mode 100644 index 48db41aaf9..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/upcmail.nl.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - upcmail.nl - chello.nl - UPC Nederland - UPC - - pop3.upcmail.nl - 110 - plain - %EMAILADDRESS% - password-cleartext - - - smtp.upcmail.nl - 25 - plain - %EMAILADDRESS% - client-IP-address - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/verizon.net.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/verizon.net.xml deleted file mode 100644 index a72d5d57c1..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/verizon.net.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - verizon.net - Verizon Online - Verizon - - incoming.verizon.net - 995 - SSL - %EMAILLOCALPART% - password-encrypted - - - outgoing.verizon.net - 465 - SSL - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/versatel.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/versatel.de.xml deleted file mode 100644 index 1945a19dbd..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/versatel.de.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - versatel.de - versanet.de - foni.net - gelsennet.de - - telebel.de - telelev.de - cneweb.de - ruhrnet-online.de - Versatel - Versatel - - mx.versatel.de - 143 - plain - password-cleartext - %EMAILADDRESS% - - - mx.versatel.de - 143 - plain - password-cleartext - %EMAILADDRESS% - - - smtp.versatel.de - 25 - plain - password-cleartext - %EMAILADDRESS% - - - Email settings - - - IMAP server - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/violet.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/violet.plala.or.jp.xml deleted file mode 100644 index a1ce58b326..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/violet.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - violet.plala.or.jp - ぷらら - ぷらら - - violet.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - violet.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vm.aikis.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vm.aikis.or.jp.xml deleted file mode 100644 index f650476be4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vm.aikis.or.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - vm.aikis.or.jp - aikis - aikis - - mail.aikis.or.jp - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - mail.aikis.or.jp - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vmail.plala.or.jp.xml deleted file mode 100644 index 66358ef6a8..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - vmail.plala.or.jp - ぷらら - ぷらら - - vmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - vmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vp.tiki.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vp.tiki.ne.jp.xml deleted file mode 100644 index 378a9d3b24..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/vp.tiki.ne.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - vp.tiki.ne.jp - TikiTikiインターネット - TikiTiki - - vp.tiki.ne.jp - 110 - plain - %EMAILLOCALPART% - plain - - - vs.tiki.ne.jp - 587 - plain - %EMAILADDRESS% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/waltz.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/waltz.plala.or.jp.xml deleted file mode 100644 index e7814cd235..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/waltz.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - waltz.plala.or.jp - ぷらら - ぷらら - - waltz.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - waltz.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wave.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wave.plala.or.jp.xml deleted file mode 100644 index 611ab2a6b8..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wave.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - wave.plala.or.jp - ぷらら - ぷらら - - wave.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - wave.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/web.de.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/web.de.xml deleted file mode 100644 index 606848a396..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/web.de.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - web.de - WEB.DE Freemail - Web.de - - - imap.web.de - 993 - SSL - %EMAILLOCALPART% - password-cleartext - - - imap.web.de - 143 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - pop3.web.de - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - - - - - pop3.web.de - 110 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - - - - - smtp.web.de - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - Configure POP3 in Thunderbird (currently describing TB 3.0) - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/white.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/white.plala.or.jp.xml deleted file mode 100644 index 34f9a8af3f..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/white.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - white.plala.or.jp - ぷらら - ぷらら - - white.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - white.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wildwestdomains.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wildwestdomains.com.xml deleted file mode 100644 index 2f47caa261..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wildwestdomains.com.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - secureserver.net - - Your WildWest domain - WildWest - - pop.secureserver.net - 995 - SSL - password-cleartext - %EMAILADDRESS% - - - - imap.secureserver.net - 993 - SSL - password-cleartext - %EMAILADDRESS% - - - smtpout.secureserver.net - 465 - SSL - password-cleartext - %EMAILADDRESS% - - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wine.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wine.plala.or.jp.xml deleted file mode 100644 index 62f66db872..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wine.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - wine.plala.or.jp - ぷらら - ぷらら - - wine.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - wine.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wmail.plala.or.jp.xml deleted file mode 100644 index 375c3010eb..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - wmail.plala.or.jp - ぷらら - ぷらら - - wmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - wmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wp.pl.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wp.pl.xml deleted file mode 100644 index 0d801c0b11..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/wp.pl.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - wp.pl - Poczta Wirtualna Polska - Poczta WP - - pop3.wp.pl - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - smtp.wp.pl - 587 - STARTTLS - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xmail.plala.or.jp.xml deleted file mode 100644 index b8d7187ff5..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - xmail.plala.or.jp - ぷらら - ぷらら - - xmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - xmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xp.wind.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xp.wind.jp.xml deleted file mode 100644 index bed7569308..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xp.wind.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - xp.wind.jp - 群馬インターネット - wind - - xp.wind.jp - 110 - plain - %EMAILLOCALPART% - plain - - - xp.wind.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xpost.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xpost.plala.or.jp.xml deleted file mode 100644 index 7d175fd750..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xpost.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - xpost.plala.or.jp - ぷらら - ぷらら - - xpost.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - xpost.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xs4all.nl.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xs4all.nl.xml deleted file mode 100644 index 60c19131c8..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xs4all.nl.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - xs4all.nl - XS4All - XS4All - - pops.xs4all.nl - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - smtps.xs4all.nl - 465 - SSL - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xtra.co.nz.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xtra.co.nz.xml deleted file mode 100644 index 3fe9e7b90b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/xtra.co.nz.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - xtra.co.nz - Yahoo! Mail - Yahoo - - pop3.xtra.co.nz - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - send.xtra.co.nz - 465 - SSL - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yahoo.co.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yahoo.co.jp.xml deleted file mode 100644 index f8fadde8fd..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yahoo.co.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - yahoo.co.jp - Yahoo! メール - Yahoo! メール - - pop.mail.yahoo.co.jp - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - smtp.mail.yahoo.co.jp - 465 - SSL - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yahoo.com.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yahoo.com.xml deleted file mode 100644 index cb818a9467..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yahoo.com.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - yahoo.com - yahoo.de - yahoo.it - yahoo.fr - yahoo.es - yahoo.co.uk - yahoo.co.nz - yahoo.com.au - yahoo.com.ar - yahoo.com.br - yahoo.com.mx - ymail.com - rocketmail.com - Yahoo! Mail - Yahoo - - pop.mail.yahoo.com - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - imap.mail.yahoo.com - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.mail.yahoo.com - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yandex.ru.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yandex.ru.xml deleted file mode 100644 index b9b4538477..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yandex.ru.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - yandex.ru - yandex.com - yandex.net - yandex.by - yandex.kz - yandex.ua - ya.ru - narod.ru - Yandex Mail - Yandex - - imap.yandex.ru - 993 - SSL - %EMAILADDRESS% - password-cleartext - - - pop.yandex.ru - 995 - SSL - %EMAILADDRESS% - password-cleartext - - - smtp.yandex.ru - 465 - SSL - %EMAILADDRESS% - password-cleartext - - - Check 'Enable IMAP' on Yandex.Mail setup page - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ybb.ne.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ybb.ne.jp.xml deleted file mode 100644 index ab91e94262..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ybb.ne.jp.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - ybb.ne.jp - Yahoo! BB - Yahoo! BB - - ybbpop.mail.yahoo.co.jp - 995 - SSL - %EMAILLOCALPART% - password-cleartext - - - ybbsmtp.mail.yahoo.co.jp - 465 - SSL - %EMAILLOCALPART% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yellow.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yellow.plala.or.jp.xml deleted file mode 100644 index 4b71b37f72..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/yellow.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - yellow.plala.or.jp - ぷらら - ぷらら - - yellow.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - yellow.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ymail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ymail.plala.or.jp.xml deleted file mode 100644 index 0f367d6b4e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ymail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - ymail.plala.or.jp - ぷらら - ぷらら - - ymail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - ymail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ypost.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ypost.plala.or.jp.xml deleted file mode 100644 index 9149c8d496..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ypost.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - ypost.plala.or.jp - ぷらら - ぷらら - - ypost.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - ypost.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ziggo.nl.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ziggo.nl.xml deleted file mode 100644 index 5827ab56b6..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/ziggo.nl.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - ziggo.nl - casema.nl - quicknet.nl - home.nl - Ziggo - Ziggo - - pop.ziggo.nl - 110 - plain - %EMAILADDRESS% - password-cleartext - - - smtp.ziggo.nl - 587 - STARTTLS - %EMAILADDRESS% - password-cleartext - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/zmail.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/zmail.plala.or.jp.xml deleted file mode 100644 index 02e73a9842..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/zmail.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - zmail.plala.or.jp - ぷらら - ぷらら - - zmail.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - zmail.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/zpost.plala.or.jp.xml b/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/zpost.plala.or.jp.xml deleted file mode 100644 index 9844a443eb..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.DomainParser/XmlData/zpost.plala.or.jp.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - zpost.plala.or.jp - ぷらら - ぷらら - - zpost.mail.plala.or.jp - 110 - plain - %EMAILLOCALPART% - plain - - - zpost.mail.plala.or.jp - 587 - plain - %EMAILLOCALPART% - plain - true - false - - - diff --git a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/ASC.Mail.EmlDownloader.csproj b/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/ASC.Mail.EmlDownloader.csproj deleted file mode 100644 index 986b038aea..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/ASC.Mail.EmlDownloader.csproj +++ /dev/null @@ -1,103 +0,0 @@ - - - - - Debug - AnyCPU - {0C0B3474-9991-4ADC-BF4B-7A4F35EB5A7C} - Exe - Properties - ASC.Mail.EmlDownloader - ASC.Mail.EmlDownloader - v4.8 - 512 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - bin\Debug\ASC.Mail.EmlDownloader.xml - CS1591 - - - AnyCPU - none - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - - - - - Designer - - - web.consumers.config - PreserveNewest - - - web.autofac.config - PreserveNewest - - - mail.agg.nlog.config - PreserveNewest - - - mail.agg.log4net.config - PreserveNewest - - - - - {76de7717-3d4b-4a5b-b740-15b8913df0cb} - ASC.Common - - - {a51d0454-4afa-46de-89d4-b03d37e1816c} - ASC.Core.Common - - - {7080343d-fbe7-423a-9405-4f883f6e235b} - ASC.Mail - - - - - 2.8.0 - - - 2.0.9 - - - 2.15.0 - - - 8.0.32.1 - - - 5.1.2 - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/App.config b/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/App.config deleted file mode 100644 index 9c798d54a2..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/App.config +++ /dev/null @@ -1,58 +0,0 @@ - - - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Program.Options.cs b/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Program.Options.cs deleted file mode 100644 index 7f84e61212..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Program.Options.cs +++ /dev/null @@ -1,34 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using CommandLine; -using CommandLine.Text; - -namespace ASC.Mail.EmlDownloader -{ - partial class Program - { - private sealed class Options - { - [Option('i', "id", Required = true, HelpText = "Id mailbox from MySQL DB.")] - public int MailboxId { get; set; } - - [Option('u', "uid", Required = false, HelpText = "Message uid for download.")] - public string MessageUid { get; set; } - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Program.cs b/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Program.cs deleted file mode 100644 index 6dfd110c83..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Program.cs +++ /dev/null @@ -1,168 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Configuration; -using System.IO; -using System.Reflection; -using System.Threading; - -using ASC.Mail.Clients; -using ASC.Mail.Core; -using ASC.Mail.Core.Dao.Expressions.Mailbox; -using ASC.Mail.Data.Contracts; -using ASC.Mail.Enums; - -using CommandLine; - -namespace ASC.Mail.EmlDownloader -{ - internal partial class Program - { - private static void Main(string[] args) - { - CommandLine.Parser.Default.ParseArguments(args) - .WithNotParsed(options => Console.WriteLine(@"Bad command line parameters.")) - .WithParsed(options => { - try - { - Console.WriteLine(@"Searching account with id {0}", options.MailboxId); - - if (string.IsNullOrEmpty(options.MessageUid)) - { - Console.WriteLine(@"MessageUid not setup."); - ShowAnyKey(); - return; - } - - var mailbox = GetMailBox(options.MailboxId); - - if (mailbox == null) - { - Console.WriteLine(@"Account not found."); - ShowAnyKey(); - return; - } - - if (mailbox.Imap) - { - var uidlStucture = ParserImapUidl(options.MessageUid); - if (uidlStucture.folderId != FolderType.Inbox) - throw new FormatException("Only inbox messages are supported for downloading."); - - } - - var certificatePermit = ConfigurationManagerExtension.AppSettings["mail.certificate-permit"] != null && - Convert.ToBoolean( - ConfigurationManagerExtension.AppSettings["mail.certificate-permit"]); - - string messageEml; - using (var client = new MailClient(mailbox, CancellationToken.None, certificatePermit: mailbox.IsTeamlab || certificatePermit)) - { - var message = client.GetInboxMessage(options.MessageUid); - messageEml = message.ToString(); - } - - Console.WriteLine(@"Try StoreToFile"); - - var now = DateTime.UtcNow; - - var path = Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Downloads"), - string.Format("uid_{0}_{1}.eml", options.MessageUid, - now.ToString("dd_MM_yyyy_hh_mm"))); - - - var pathFile = StoreToFile(messageEml, path, true); - - Console.WriteLine(@"[SUCCESS] File was stored into path ""{0}""", pathFile); - - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - - - }); - } - - private static void ShowAnyKey() - { - Console.WriteLine(); - Console.WriteLine(@"Any key to exit..."); - Console.ReadKey(); - } - - static string StoreToFile(string emlString, string fileName, bool useTemp) - { - var tempPath = useTemp ? TempPath.GetTempFileName() : fileName; - var sw = File.CreateText(tempPath); - sw.Write(emlString); - sw.Close(); - - if (useTemp) - { - if (!string.IsNullOrEmpty(fileName)) - { - var directory = Path.GetDirectoryName(fileName); - // Create the traget path iof it does not exist - if (directory != null && !Directory.Exists(directory)) - Directory.CreateDirectory(directory); - - if (string.IsNullOrEmpty(Path.GetFileName(fileName))) - { - string savePath = Path.Combine(fileName, Path.GetFileNameWithoutExtension(tempPath) + ".eml"); - File.Move(tempPath, savePath); - File.Delete(tempPath); - return savePath; - } - - File.Move(tempPath, fileName); - File.Delete(tempPath); - - return fileName; - } - - return tempPath; - } - return tempPath; - } - - private struct ImapUidl - { - public FolderType folderId; - public int uid; - } - - private static ImapUidl ParserImapUidl(string uidl) - { - var elements = uidl.Split('-'); - - return new ImapUidl - { - uid = Convert.ToInt32(elements[0]), - folderId = (FolderType)Convert.ToInt32(elements[1]) - }; - } - - private static MailBoxData GetMailBox(int mailboxId) - { - var engine = new EngineFactory(-1); - return engine.MailboxEngine.GetMailboxData(new ConcreteSimpleMailboxExp(mailboxId)); - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Properties/AssemblyInfo.cs b/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Properties/AssemblyInfo.cs deleted file mode 100644 index e3c63e133e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.EmlDownloader/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ASC.Mail.EmlDownloader")] -[assembly: AssemblyDescription("Download message from mailbox.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Ascensio System SIA")] -[assembly: AssemblyProduct("ASC.Mail.EmlDownloader")] -[assembly: AssemblyCopyright("(c) Ascensio System SIA. All rights reserved")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7a6f0fc6-c562-4bf8-a3a5-737f9a79b1e2")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.0.1")] diff --git a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/ASC.Mail.PasswordFinder.csproj b/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/ASC.Mail.PasswordFinder.csproj deleted file mode 100644 index 643148ff48..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/ASC.Mail.PasswordFinder.csproj +++ /dev/null @@ -1,119 +0,0 @@ - - - - - Debug - AnyCPU - {10F8632E-A59F-4009-A211-5AE043622538} - Exe - Properties - ASC.Mail.PasswordFinder - ASC.Mail.PasswordFinder - v4.8 - 512 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - none - true - bin\Release\ - TRACE - prompt - 4 - false - - - - ..\..\..\..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll - - - False - ..\..\..\..\packages\DotNetOpenAuth.Ultimate.4.1.0.12182\lib\net45-full\DotNetOpenAuth.dll - - - False - ..\..\..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll - - - False - ..\..\..\..\packages\MySql.Data.8.0.18\lib\net452\MySql.Data.dll - - - ..\..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - - - False - ..\..\..\..\packages\NLog.4.5.8\lib\net45\NLog.dll - - - - - - - - - - - ..\..\..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll - - - - - - - - - - Designer - - - web.consumers.config - PreserveNewest - - - web.autofac.config - PreserveNewest - - - mail.agg.nlog.config - PreserveNewest - - - mail.agg.log4net.config - PreserveNewest - - - - - {76de7717-3d4b-4a5b-b740-15b8913df0cb} - ASC.Common - - - {a51d0454-4afa-46de-89d4-b03d37e1816c} - ASC.Core.Common - - - {7080343d-fbe7-423a-9405-4f883f6e235b} - ASC.Mail - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/App.config b/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/App.config deleted file mode 100644 index 03d39ea88d..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/App.config +++ /dev/null @@ -1,64 +0,0 @@ - - - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Program.Options.cs b/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Program.Options.cs deleted file mode 100644 index 74ed54eee4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Program.Options.cs +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using CommandLine; -using CommandLine.Text; - -namespace ASC.Mail.PasswordFinder -{ - partial class Program - { - private sealed class Options - { - [Option('j', "json", Required = false, HelpText = "Save settings to mailbox.json")] - public bool NeedJson { get; set; } - - [Option('e', "exit", Required = false, HelpText = "Exit on end of any operations")] - public bool ExitOnEnd { get; set; } - - [ParserState] - public IParserState LastParserState { get; set; } - - [HelpOption] - public string GetUsage() - { - return HelpText.AutoBuild(this, current => HelpText.DefaultParsingErrorsHandler(this, current)); - } - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Program.cs b/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Program.cs deleted file mode 100644 index e3439a6f3b..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Program.cs +++ /dev/null @@ -1,314 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using ASC.Core.Users; -using ASC.Mail.Enums; -using ASC.Mail.Extensions; -using ASC.Mail.Iterators; -using Newtonsoft.Json; - -namespace ASC.Mail.PasswordFinder -{ - internal partial class Program - { - const string IMAP = "IMAP"; - const string POP3 = "POP3"; - const string SMTP = "SMTP"; - - private static void Main(string[] args) - { - var options = new Options(); - - if (!CommandLine.Parser.Default.ParseArgumentsStrict(args, options, - () => Console.WriteLine(@"Bad command line parameters."))) - { - return; - } - - try - { - var mailboxIterator = new MailboxIterator(); - - var mailbox = mailboxIterator.First(); - - if (mailbox == null) - { - Console.WriteLine(@"Accounts not found."); - ShowAnyKey(options); - return; - } - - StringBuilder sbuilder = null; - List accounts = null; - - if (!options.NeedJson) - { - sbuilder = new StringBuilder(); - } - else - { - accounts = new List(); - } - - var i = 0; - - while (!mailboxIterator.IsDone) - { - if (mailbox.IsRemoved || !mailbox.IsTeamlab) - { - mailbox = mailboxIterator.Next(); - continue; - } - - var current = new StringBuilder(); - - var userInfo = mailbox.GetUserInfo(); - - var isUserRemoved = userInfo == null || userInfo.Equals(Constants.LostUser); - - var user = isUserRemoved ? "user is removed" : userInfo.UserName; - - current.AppendFormat("#{0}. Id: {1} MailBox: {2}, Tenant: {3}, User: '{4}' ID: {5}\r\n", - ++i, mailbox.MailBoxId, mailbox.EMail, mailbox.TenantId, user, - mailbox.UserId); - - current.AppendLine(); - - var inType = mailbox.Imap ? IMAP : POP3; - - current.AppendFormat("\t\t{0} settings:\r\n", inType); - current.AppendFormat("\t\tLogin:\t\t{0}\r\n", mailbox.Account); - - string inPassword; - - if (!mailbox.IsOAuth) - { - inPassword = - string.IsNullOrEmpty(mailbox.Password) - ? "[-=! ERROR: Invalid Decription !=-]" - : mailbox.Password; - } - else - { - inPassword = "[-=! OAuth: no password stored !=-]"; - } - - current.AppendFormat("\t\tPassword:\t{0}\r\n", inPassword); - - current.AppendFormat("\t\tHost:\t\t{0}\r\n", mailbox.Server); - current.AppendFormat("\t\tPort:\t\t{0}\r\n", mailbox.Port); - - var inAuthentication = Enum.GetName(typeof(SaslMechanism), mailbox.Authentication); - - current.AppendFormat("\t\tAuthType:\t{0}\r\n", inAuthentication); - - var inEncryption = Enum.GetName(typeof(EncryptionType), mailbox.Encryption); - - current.AppendFormat("\t\tEncryptType:\t{0}\r\n", inEncryption); - - current.AppendLine(); - - current.AppendFormat("\t\t{0} settings:\r\n", SMTP); - current.AppendFormat("\t\tSmtpAuth:\t{0}\r\n", mailbox.SmtpAuth); - if (mailbox.SmtpAuth) - { - current.AppendFormat("\t\tSmtpLogin:\t{0}\r\n", mailbox.SmtpAccount); - if (!mailbox.IsOAuth) - { - current.AppendFormat("\t\tSmtPassword:\t{0}\r\n", - string.IsNullOrEmpty(mailbox.SmtpPassword) - ? "[-=! ERROR: Invalid Decription !=-]" - : mailbox.SmtpPassword); - } - else - { - current.AppendFormat("\t\tSmtPassword:\t[-=! OAuth: no password stored !=-]\r\n"); - } - } - current.AppendFormat("\t\tHost:\t\t{0}\r\n", mailbox.SmtpServer); - current.AppendFormat("\t\tPort:\t\t{0}\r\n", mailbox.SmtpPort); - - var outAuthentication = Enum.GetName(typeof(SaslMechanism), mailbox.SmtpAuthentication); - - current.AppendFormat("\t\tAuthType:\t{0}\r\n", outAuthentication); - - var outEncryption = Enum.GetName(typeof(EncryptionType), mailbox.SmtpEncryption); - - current.AppendFormat("\t\tEncryptType:\t{0}\r\n", outEncryption); - - current.AppendLine(); - - Console.WriteLine(current.ToString()); - - if (!options.NeedJson) - { - if (sbuilder != null) - sbuilder.Append(current); - } - else - { - if (accounts != null) - { - accounts.Add(new MailAccount - { - email = mailbox.EMail.Address, - tenantId = mailbox.TenantId, - user = user, - userId = mailbox.UserId, - settings = new List - { - new MailAccountSetting - { - type = inType, - host = mailbox.Server, - port = mailbox.Port.ToString(), - authentication = inAuthentication, - encryption = inEncryption, - login = mailbox.Account, - password = inPassword - }, - new MailAccountSetting - { - type = SMTP, - host = mailbox.SmtpServer, - port = mailbox.SmtpPort.ToString(), - authentication = outAuthentication, - encryption = outEncryption, - login = mailbox.SmtpAccount, - password = inPassword - } - } - }); - } - } - - mailbox = mailboxIterator.Next(); - } - - string text = null; - - if (!options.NeedJson) - { - if (sbuilder != null) - { - text = sbuilder.ToString(); - } - } - else - { - text = JsonConvert.SerializeObject(accounts, Formatting.Indented); - } - - if (!string.IsNullOrEmpty(text)) - { - Console.WriteLine(@"Try StoreToFile"); - - var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, - options.NeedJson ? "mailboxes.json" : "mailboxes.txt"); - - var pathFile = StoreToFile(text, path, true); - - Console.WriteLine(@"[SUCCESS] File was stored into path ""{0}""", pathFile); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - - ShowAnyKey(options); - } - - private static void ShowAnyKey(Options options) - { - Console.WriteLine(); - - if (options.ExitOnEnd) - return; - - Console.WriteLine(@"Any key to exit..."); - Console.Read(); - } - - private static string StoreToFile(string text, string fileName, bool useTemp) - { - var tempPath = useTemp ? Path.GetTempFileName() : fileName; - var sw = File.CreateText(tempPath); - sw.Write(text); - sw.Close(); - - if (!useTemp) - return tempPath; - - if (string.IsNullOrEmpty(fileName)) - return tempPath; - - var directory = Path.GetDirectoryName(fileName); - // Create the traget path iof it does not exist - if (directory != null && !Directory.Exists(directory)) - Directory.CreateDirectory(directory); - - if (string.IsNullOrEmpty(Path.GetFileName(fileName))) - { - var savePath = Path.Combine(fileName, Path.GetFileNameWithoutExtension(tempPath) + ".txt"); - File.Move(tempPath, savePath); - File.Delete(tempPath); - return savePath; - } - - File.Delete(fileName); - File.Move(tempPath, fileName); - File.Delete(tempPath); - - return fileName; - } - } - - internal class MailAccount - { - public string email; - - public string user; - - public int tenantId; - - public string userId; - - public List settings; - } - - internal class MailAccountSetting - { - public string type; - - public string host; - - public string port; - - public string authentication; - - public string encryption; - - public string login; - - public string password; - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Properties/AssemblyInfo.cs b/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Properties/AssemblyInfo.cs deleted file mode 100644 index 1dd61200ee..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.PasswordFinder/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ASC.Mail.PasswordFinder")] -[assembly: AssemblyDescription("Get connection settings for mailboxes on Onlyoffice MailServer.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Ascensio System SIA")] -[assembly: AssemblyProduct("OnlyOffice")] -[assembly: AssemblyCopyright("(c) Ascensio System SIA. All rights reserved")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7a6f0fc6-c562-4bf8-a3a5-737f9a79b1e2")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.0.2")] diff --git a/module/ASC.Mail/Services/ASC.Mail.Reloader/ASC.Mail.Reloader.csproj b/module/ASC.Mail/Services/ASC.Mail.Reloader/ASC.Mail.Reloader.csproj deleted file mode 100644 index f56068b68a..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Reloader/ASC.Mail.Reloader.csproj +++ /dev/null @@ -1,132 +0,0 @@ - - - - - Debug - AnyCPU - {594BF643-0EBA-49E8-BAA5-BC433DD7601F} - Exe - Properties - ASC.Mail.Reloader - ASC.Mail.Reloader - v4.8 - 512 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - none - true - bin\Release\ - TRACE - prompt - 4 - false - - - ASC.Mail.Reloader.Program - - - - ..\..\..\..\packages\BouncyCastle.1.8.2\lib\BouncyCastle.Crypto.dll - - - False - ..\..\..\..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll - - - False - ..\..\..\..\packages\DotNetOpenAuth.Ultimate.4.1.0.12182\lib\net45-full\DotNetOpenAuth.dll - - - False - ..\..\..\..\packages\log4net.2.0.8\lib\net45-full\log4net.dll - - - ..\..\..\..\packages\MailKit.2.0.4\lib\net45\MailKit.dll - - - ..\..\..\..\packages\MimeKit.2.0.4\lib\net45\MimeKit.dll - - - False - ..\..\..\..\packages\MySql.Data.8.0.18\lib\net452\MySql.Data.dll - - - ..\..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - - - False - ..\..\..\..\packages\NLog.4.5.8\lib\net45\NLog.dll - - - - - - - - - - - ..\..\..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll - - - - - - - - - - Designer - - - web.consumers.config - PreserveNewest - - - web.autofac.config - PreserveNewest - - - mail.agg.nlog.config - PreserveNewest - - - mail.agg.log4net.config - PreserveNewest - - - - - {76de7717-3d4b-4a5b-b740-15b8913df0cb} - ASC.Common - - - {a51d0454-4afa-46de-89d4-b03d37e1816c} - ASC.Core.Common - - - {7080343d-fbe7-423a-9405-4f883f6e235b} - ASC.Mail - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Reloader/App.config b/module/ASC.Mail/Services/ASC.Mail.Reloader/App.config deleted file mode 100644 index 6017e12685..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Reloader/App.config +++ /dev/null @@ -1,73 +0,0 @@ - - - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Reloader/Program.Options.cs b/module/ASC.Mail/Services/ASC.Mail.Reloader/Program.Options.cs deleted file mode 100644 index b091134454..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Reloader/Program.Options.cs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using CommandLine; -using CommandLine.Text; - -namespace ASC.Mail.Reloader -{ - internal partial class Program - { - private sealed class Options - { - [Option('i', "id", Required = false, DefaultValue = -1, HelpText = "Id mailbox from MySQL DB.")] - public int MailboxId { get; set; } - - [Option('m', "mid", Required = false, DefaultValue = -1, HelpText = "Message id for reload.")] - public int MessageId { get; set; } - - [Option('j', "json_path", Required = false, DefaultValue = null, HelpText = "Path to json file (ex. { \"data\": [ { \"id_mailbox\": 2649,\"id\": 27325207 } ] } ).")] - public string PathToJson { get; set; } - - [ParserState] - public IParserState LastParserState { get; set; } - - [HelpOption] - public string GetUsage() - { - return HelpText.AutoBuild(this, current => HelpText.DefaultParsingErrorsHandler(this, current)); - } - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Reloader/Program.cs b/module/ASC.Mail/Services/ASC.Mail.Reloader/Program.cs deleted file mode 100644 index 607950f06c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Reloader/Program.cs +++ /dev/null @@ -1,332 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Generic; -using System.Configuration; -using System.IO; -using System.Linq; -using System.Threading; - -using ASC.Common.Logging; -using ASC.Common.Utils; -using ASC.Mail.Clients; -using ASC.Mail.Core; -using ASC.Mail.Core.Dao.Expressions.Mailbox; -using ASC.Mail.Core.Engine; -using ASC.Mail.Data.Contracts; -using ASC.Mail.Enums; -using ASC.Mail.Utils; -using MimeKit; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; - -namespace ASC.Mail.Reloader -{ - internal partial class Program - { - private static void Main(string[] args) - { - var options = new Options(); - - if (!CommandLine.Parser.Default.ParseArgumentsStrict(args, options, - () => Console.WriteLine(@"Bad command line parameters."))) - { - ShowAnyKey(); - return; - } - - try - { - var reloadList = new Dictionary>(); - - if (!string.IsNullOrEmpty(options.PathToJson) && File.Exists(options.PathToJson)) - { - using (var streamReader = new StreamReader(options.PathToJson)) - { - using (var reader = new JsonTextReader(streamReader)) - { - var jObject = JObject.Load(reader); - - if (jObject["data"] == null || !jObject["data"].Any()) - { - Console.WriteLine(@"[ERROR] json tasks not found. Array is empty."); - - ShowAnyKey(); - return; - } - - var results = jObject["data"].ToList().GroupBy( - p => Convert.ToInt32(p["id_mailbox"]), - p => Convert.ToInt32(p["id"]), - (key, g) => new {MailboxId = key, Ids = g.ToList()}); - - foreach (var result in results) - { - if(reloadList.ContainsKey(result.MailboxId)) - continue; - - reloadList.Add(result.MailboxId, result.Ids); - } - } - } - } - else - { - if (options.MailboxId < 0) - { - Console.WriteLine(@"[ERROR] MailboxId invalid."); - - ShowAnyKey(); - return; - } - - if (options.MessageId < 0) - { - Console.WriteLine(@"[ERROR] MailboxId invalid."); - - ShowAnyKey(); - return; - } - - - reloadList.Add(options.MailboxId, new List {options.MessageId}); - } - - foreach (var reloadItem in reloadList) - { - MailClient client = null; - - try - { - var mailboxId = reloadItem.Key; - - Console.WriteLine(@"Searching account with id {0}", mailboxId); - - var mailbox = GetMailBox(mailboxId); - - if (mailbox == null) - { - Console.WriteLine(@"[ERROR] Account not found."); - ShowAnyKey(); - return; - } - - var messageIds = reloadItem.Value; - - foreach (var messageId in messageIds) - { - Console.WriteLine(@"Searching message with id {0}", messageId); - - if (messageId < 0) - { - Console.WriteLine(@"[ERROR] MessageId not setup."); - continue; - } - - var storedMessage = GetMail(mailbox, messageId); - - if (storedMessage == null) - { - Console.WriteLine(@"[ERROR] Message not found."); - continue; - } - - var messageUid = storedMessage.Uidl; - - if (mailbox.Imap) - { - var uidlStucture = ParserImapUidl(messageUid); - if (uidlStucture.folderId != FolderType.Inbox) - { - Console.WriteLine(@"Only inbox messages are supported for downloading."); - continue; - } - } - - var certificatePermit = ConfigurationManager.AppSettings["mail.certificate-permit"] != - null && - Convert.ToBoolean( - ConfigurationManager.AppSettings["mail.certificate-permit"]); - - var log = new NullLog(); - - if (client == null) - client = new MailClient(mailbox, CancellationToken.None, - certificatePermit: certificatePermit); - - MimeMessage mimeMessage; - - try - { - mimeMessage = client.GetInboxMessage(messageUid); - } - catch (Exception e) - { - Console.WriteLine(@"[ERROR] Failed GetInboxMessage(""{0}"") Exception: {1}", messageUid, e); - continue; - } - - MailMessageData message; - - try - { - message = mimeMessage.ConvertToMailMessage(new MailFolder(FolderType.Inbox, ""), - storedMessage.IsNew, storedMessage.ChainId, storedMessage.ChainDate, - storedMessage.StreamId, mailboxId, false, log); - } - catch (Exception ex) - { - Console.WriteLine(@"[ERROR] Failed ConvertToMailMessage(""{0}"") Exception: {1}", - messageUid, ex); - continue; - } - - if (!storedMessage.From.Equals(StringUtils.NormalizeStringForMySql(message.From)) || - !storedMessage.To.Equals(StringUtils.NormalizeStringForMySql(message.To)) || - !storedMessage.Subject.Equals(StringUtils.NormalizeStringForMySql(message.Subject))) - { - Console.WriteLine(@"storedMessage.From = '{0}'", storedMessage.From); - Console.WriteLine(@"message.From = '{0}'", - StringUtils.NormalizeStringForMySql(message.From)); - - Console.WriteLine(@"storedMessage.To = '{0}'", storedMessage.To); - Console.WriteLine(@"message.To = '{0}'", - StringUtils.NormalizeStringForMySql(message.To)); - - Console.WriteLine(@"storedMessage.Subject = '{0}'", storedMessage.Subject); - Console.WriteLine(@"message.Subject = '{0}'", - StringUtils.NormalizeStringForMySql(message.Subject)); - - Console.WriteLine(@"[ERROR] Stored message not equals to server message"); - continue; - } - - if (storedMessage.Attachments.Any() && message.Attachments.Any()) - { - var newAttachments = new List(); - - foreach (var attachment in message.Attachments) - { - var storedAttachment = - storedMessage.Attachments.FirstOrDefault( - a => - (!string.IsNullOrEmpty(a.fileName) && - a.fileName.Equals(attachment.fileName, - StringComparison.InvariantCultureIgnoreCase)) || - !string.IsNullOrEmpty(a.contentId) && - a.contentId.Equals(attachment.contentId, - StringComparison.InvariantCultureIgnoreCase) || - !string.IsNullOrEmpty(a.contentLocation) && - a.contentLocation.Equals(attachment.contentLocation, - StringComparison.InvariantCultureIgnoreCase)); - - if (storedAttachment == null) - continue; - - attachment.fileName = storedAttachment.fileName; - attachment.storedName = storedAttachment.storedName; - attachment.fileNumber = storedAttachment.fileNumber; - attachment.streamId = storedAttachment.streamId; - attachment.mailboxId = storedAttachment.mailboxId; - attachment.tenant = storedAttachment.tenant; - attachment.user = storedAttachment.user; - - newAttachments.Add(attachment); - } - - message.Attachments = newAttachments; - } - - if (!MessageEngine.TryStoreMailData(message, mailbox, log)) - { - Console.WriteLine(@"[ERROR] Failed to store mail data"); - continue; - } - - Console.WriteLine(@"[SUCCESS] Mail ""{0}"" data was reloaded", messageId); - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - finally - { - if (client != null) - { - client.Dispose(); - } - } - } - } - catch (Exception ex) - { - Console.WriteLine(ex.ToString()); - } - - ShowAnyKey(); - } - - private static void ShowAnyKey() - { - Console.WriteLine(); - Console.WriteLine(@"Any key to exit..."); - Console.ReadKey(); - } - - private struct ImapUidl - { - public FolderType folderId; -#pragma warning disable 414 - public int uid; -#pragma warning restore 414 - } - - private static ImapUidl ParserImapUidl(string uidl) - { - var elements = uidl.Split('-'); - - return new ImapUidl - { - uid = Convert.ToInt32(elements[0]), - folderId = (FolderType) Convert.ToInt32(elements[1]) - }; - } - - private static MailMessageData GetMail(MailBoxData mailbox, int mailId) - { - var engine = new EngineFactory(mailbox.TenantId, mailbox.UserId); - - return engine.MessageEngine.GetMessage(mailId, new MailMessageData.Options - { - LoadBody = false, - LoadImages = false, - NeedProxyHttp = false, - NeedSanitizer = false, - OnlyUnremoved = true, - LoadEmebbedAttachements = true - }); - } - - private static MailBoxData GetMailBox(int mailboxId) - { - var engine = new EngineFactory(-1); - return engine.MailboxEngine.GetMailboxData(new ConcreteSimpleMailboxExp(mailboxId)); - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Reloader/Properties/AssemblyInfo.cs b/module/ASC.Mail/Services/ASC.Mail.Reloader/Properties/AssemblyInfo.cs deleted file mode 100644 index 0a8b39a2a4..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Reloader/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Restore message data in storage.")] -[assembly: AssemblyDescription("Restore message data in storage.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Ascensio System SIA")] -[assembly: AssemblyProduct("ASC.Mail.Reloader")] -[assembly: AssemblyCopyright("(c) Ascensio System SIA. All rights reserved")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("7a6f0fc6-c562-4bf8-a3a5-737f9a79b1e5")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.0.1")] diff --git a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/ASC.Mail.StorageCleaner.Service.csproj b/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/ASC.Mail.StorageCleaner.Service.csproj deleted file mode 100644 index eedbefd5b6..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/ASC.Mail.StorageCleaner.Service.csproj +++ /dev/null @@ -1,140 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {2559E5C4-4803-4A11-B9EC-33ECAD06C935} - Exe - Properties - ASC.Mail.StorageCleaner - ASC.Mail.StorageCleaner - v4.8 - 512 - - - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - false - bin\Debug\ASC.Mail.StorageCleaner.xml - CS1591 - - - none - true - bin\Release\ - TRACE - prompt - 4 - false - - - - - - - Component - - - - - web.autofac.config - PreserveNewest - - - Designer - - - Designer - PreserveNewest - - - Designer - PreserveNewest - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - - - {76de7717-3d4b-4a5b-b740-15b8913df0cb} - ASC.Common - - - {a51d0454-4afa-46de-89d4-b03d37e1816c} - ASC.Core.Common - - - {3f6b420f-abd3-4b5a-9f4c-5d61ffbb01de} - ASC.Data.Storage - - - {7080343d-fbe7-423a-9405-4f883f6e235b} - ASC.Mail - - - - - 2.0.9 - - - 8.0.32.1 - - - 5.1.2 - - - 0.8.5 - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/App.config b/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/App.config deleted file mode 100644 index ac67345d9e..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/App.config +++ /dev/null @@ -1,85 +0,0 @@ - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/HealthCheckService.cs b/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/HealthCheckService.cs deleted file mode 100644 index df7bbdbf8a..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/HealthCheckService.cs +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using ASC.Core.Common.Contracts; - -namespace ASC.Mail.StorageCleaner -{ - public class HealthCheckService : IHealthCheckService - { - public HealthCheckResponse CheckHealth() - { - return HealthCheckResult.ToResponse(new HealthCheckResult - { - Message = "Service MailCleaner is OK! Warning: Method is not implement. Always return the Healthy status", - Status = HealthStatus.Healthy - }); - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/Program.cs b/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/Program.cs deleted file mode 100644 index dda1f7c7de..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/Program.cs +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Linq; -using System.ServiceProcess; - -using ASC.Common.Logging; - -namespace ASC.Mail.StorageCleaner -{ - class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - private static void Main(params string[] args) - { - AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; - - if (Environment.UserInteractive || (args.Any() && args[0].Equals("-console"))) - { - var service = new StorageCleanerService(); - service.StartConsole(); - } - else - { - ServiceBase.Run(new StorageCleanerService()); - } - } - - private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) - { - var log = LogManager.GetLogger("ASC.Mail.StorageCleaner"); - log.FatalFormat("Unhandled exception: {0}", e.ExceptionObject.ToString()); - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/Properties/AssemblyInfo.cs b/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/Properties/AssemblyInfo.cs deleted file mode 100644 index 9dcd43c228..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ASC.Mail.StorageCleaner")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Ascensio System SIA")] -[assembly: AssemblyProduct("ASC.Mail.StorageCleaner")] -[assembly: AssemblyCopyright("(c) Ascensio System SIA. All rights reserved")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("771bfbb8-de8a-47ba-9fcf-af85bf79c2fc")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.0.5")] diff --git a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/StorageCleanerService.cs b/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/StorageCleanerService.cs deleted file mode 100644 index 7c01a38f53..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/StorageCleanerService.cs +++ /dev/null @@ -1,257 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Configuration; -using System.ServiceModel; -using System.ServiceProcess; -using System.Threading; -using System.Threading.Tasks; - -using ASC.Common.Logging; -using ASC.Mail.Core.Engine; - -namespace ASC.Mail.StorageCleaner -{ - internal class StorageCleanerService : ServiceBase - { - #region - Declaration - - - private readonly ILog _log; - private Timer _intervalTimer; - private readonly ManualResetEvent _resetEvent; - private MailGarbageEngine _eraser; - private readonly TimeSpan _tsInterval; - private readonly CancellationTokenSource _cancelTokenSource; - private ServiceHost _healthCheckServiceHost; - - #endregion - - #region - Constructor - - - public StorageCleanerService() - { - CanStop = true; - - AutoLog = true; - - _log = LogManager.GetLogger("ASC.Mail.Cleaner"); - - _resetEvent = new ManualResetEvent(false); - - _cancelTokenSource = new CancellationTokenSource(); - - _tsInterval = TimeSpan.FromMinutes(Convert.ToInt32(ConfigurationManagerExtension.AppSettings["cleaner.timer-wait-minutes"])); - - _log.InfoFormat("Service will clear mail storage every {0} minutes\r\n", _tsInterval.TotalMinutes); - - _eraser = new MailGarbageEngine(_log); - - _intervalTimer = new Timer(IntervalTimer_Elapsed, _cancelTokenSource.Token, Timeout.Infinite, Timeout.Infinite); - } - - #endregion - - #region - Start / Stop - - - /// - /// OnStart(): Put startup code here - /// - Start threads, get inital data, etc. - /// - /// - protected override void OnStart(string[] args) - { - try - { - _log.Info("Start service\r\n"); - - base.OnStart(args); - - _healthCheckServiceHost = new ServiceHost(typeof(HealthCheckService)); - _healthCheckServiceHost.Open(); - - StartTimer(true); - } - catch (Exception) - { - OnStop(); - } - } - - /// - /// OnStop(): Put your stop code here - /// - Stop threads, set final data, etc. - /// - protected override void OnStop() - { - try - { - _log.Info("Stoping service\r\n"); - - if (_cancelTokenSource != null) - _cancelTokenSource.Cancel(); - - StopTimer(); - - if (_intervalTimer != null) - { - _intervalTimer.Dispose(); - _intervalTimer = null; - } - - if (_resetEvent != null) - _resetEvent.Set(); - - if (_eraser != null) - { - _eraser.Dispose(); - _eraser = null; - } - - } - catch (Exception ex) - { - _log.ErrorFormat("Stop service Error: {0}\r\n", ex.ToString()); - } - finally - { - base.OnStop(); - - if (_healthCheckServiceHost != null) - { - _healthCheckServiceHost.Close(); - _healthCheckServiceHost = null; - } - } - - _log.Info("Stop service\r\n"); - } - - /// - /// OnShutdown(): Called when the System is shutting down - /// - Put code here when you need special handling - /// of code that deals with a system shutdown, such - /// as saving special data before shutdown. - /// - protected override void OnShutdown() - { - _log.Info("Service shutdown."); - OnStop(); - base.OnShutdown(); - } - - /// - /// OnPowerEvent(): Useful for detecting power status changes, - /// such as going into Suspend mode or Low Battery for laptops. - /// - /// The Power Broadcast Status - /// (BatteryLow, Suspend, etc.) - protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus) - { - _log.InfoFormat("Service power event detected = {0}.", powerStatus.ToString()); - - if (powerStatus == PowerBroadcastStatus.Suspend) - { - OnStop(); - } - return base.OnPowerEvent(powerStatus); - } - - /// - /// Start service in console mode. - /// - public void StartConsole() - { - _log.Info("Service Start in console-daemon mode"); - - OnStart(null); - - Console.CancelKeyPress += (sender, e) => OnStop(); - - _resetEvent.WaitOne(); - } - - private void StartTimer(bool immediately = false) - { - if (_intervalTimer == null) - return; - - if (immediately) - { - _log.Debug("Setup _workTimer to start immediately"); - - _intervalTimer.Change(0, Timeout.Infinite); - } - else - { - _log.DebugFormat("Setup _workTimer to {0} minutes", _tsInterval.TotalMinutes); - - _intervalTimer.Change(_tsInterval, _tsInterval); - } - } - - private void StopTimer() - { - if (_intervalTimer == null) - return; - - _log.Debug("Setup _workTimer to Timeout.Infinite"); - - _intervalTimer.Change(Timeout.Infinite, Timeout.Infinite); - } - - #endregion - - #region - Timer_Elapsed - - - private void IntervalTimer_Elapsed(object state) - { - _log.Debug("Timer->workTimer_Elapsed"); - - var cancelToken = state as CancellationToken? ?? new CancellationToken(); - - try - { - _eraser.ClearMailGarbage(cancelToken); - - _log.InfoFormat("All mailboxes were processed. Go back to timer. Next start after {0} minutes.\r\n", - _tsInterval.TotalMinutes); - - } - catch (Exception ex) - { - if (ex is AggregateException) - { - ex = ((AggregateException)ex).GetBaseException(); - } - - if (ex is TaskCanceledException || ex is OperationCanceledException) - { - _log.Info("Execution was canceled."); - - return; - } - - _log.ErrorFormat("Timer->workTimer_Elapsed. Exception:\r\n{0}\r\n", ex.ToString()); - } - - StartTimer(); - } - - #endregion - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/mail.cln.log4net.config b/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/mail.cln.log4net.config deleted file mode 100644 index 8ad021be50..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/mail.cln.log4net.config +++ /dev/null @@ -1,113 +0,0 @@ - - - - WINDOWS:LogDirectory - ..\..\..\..\..\..\web\studio\Logs\ - - - UNIX:LogDirectory - /var/log/onlyoffice/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/mail.cln.nlog.config b/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/mail.cln.nlog.config deleted file mode 100644 index 5c09494628..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.StorageCleaner/mail.cln.nlog.config +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/ASC.Mail.Watchdog.Service.csproj b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/ASC.Mail.Watchdog.Service.csproj deleted file mode 100644 index ebf73ca906..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/ASC.Mail.Watchdog.Service.csproj +++ /dev/null @@ -1,148 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {F72B7F19-9A9B-41F1-AEA9-ADE70D3D8D19} - Exe - Properties - ASC.Mail.Watchdog.Service - ASC.Mail.Watchdog.Service - v4.8 - 512 - - - - - 3.5 - - false - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - true - bin\$(Configuration)\ - - - true - full - false - DEBUG;TRACE - prompt - 4 - false - false - bin\Debug\ASC.Mail.Watchdog.Service.xml - CS1591 - - - none - true - TRACE - prompt - 4 - false - false - - - - - - Component - - - WatchdogService.cs - - - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - Designer - - - web.autofac.config - PreserveNewest - - - Designer - PreserveNewest - - - Designer - PreserveNewest - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - - - {76de7717-3d4b-4a5b-b740-15b8913df0cb} - ASC.Common - - - {a51d0454-4afa-46de-89d4-b03d37e1816c} - ASC.Core.Common - - - {7080343d-fbe7-423a-9405-4f883f6e235b} - ASC.Mail - - - - - 2.8.0 - - - 2.0.9 - - - 8.0.32.1 - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/App.config b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/App.config deleted file mode 100644 index 5e1d2ab536..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/App.config +++ /dev/null @@ -1,59 +0,0 @@ - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/HealthCheckService.cs b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/HealthCheckService.cs deleted file mode 100644 index c9004cab60..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/HealthCheckService.cs +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using ASC.Core.Common.Contracts; - -namespace ASC.Mail.Watchdog -{ - public class HealthCheckService : IHealthCheckService - { - public HealthCheckResponse CheckHealth() - { - return HealthCheckResult.ToResponse(new HealthCheckResult - { - Message = "Service MailWatchdog is OK! Warning: Method is not implement. Always return the Healthy status", - Status = HealthStatus.Healthy - }); - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Program.Options.cs b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Program.Options.cs deleted file mode 100644 index 67e92a6ed0..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Program.Options.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using CommandLine; -using CommandLine.Text; - -namespace ASC.Mail.Watchdog.Service -{ - partial class Program - { - private class Options - { - [Option("console", Required = false, HelpText = "Console state")] - public bool IsConsole { get; set; } - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Program.cs b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Program.cs deleted file mode 100644 index 95b02e48b6..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Program.cs +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Linq; -using System.ServiceProcess; - -using ASC.Common.Logging; - -namespace ASC.Mail.Watchdog.Service -{ - partial class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - private static void Main(params string[] args) - { - AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; - - if (Environment.UserInteractive || (args.Any())) - { - var service = new Watchdog(); - service.StartConsole(); - } - else - { - ServiceBase.Run(new Watchdog()); - } - } - - private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e) - { - var log = LogManager.GetLogger("ASC.Mail.Watchdog"); - log.FatalFormat("Unhandled exception: {0}", e.ExceptionObject.ToString()); - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/AssemblyInfo.cs b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/AssemblyInfo.cs deleted file mode 100644 index e63805d365..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("WindowsService")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Ascensio System SIA")] -[assembly: AssemblyProduct("WindowsService")] -[assembly: AssemblyCopyright("(c) Ascensio System SIA. All rights reserved")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("a412ce2e-067e-4c2a-83b6-a90fead0762d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.0.1")] diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Resources.Designer.cs b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Resources.Designer.cs deleted file mode 100644 index deb7aa5fe3..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17929 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ASC.Mail.Watchdog.Service.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.Mail.Watchdog.Service.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Resources.resx b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Resources.resx deleted file mode 100644 index ffecec851a..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Settings.Designer.cs b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Settings.Designer.cs deleted file mode 100644 index b40200bf41..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.17929 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ASC.Mail.Watchdog.Service.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Settings.settings b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Settings.settings deleted file mode 100644 index 2bd17f050c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/Properties/Settings.settings +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/WatchdogService.Designer.cs b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/WatchdogService.Designer.cs deleted file mode 100644 index e8d09ebe1c..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/WatchdogService.Designer.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace ASC.Mail.Watchdog.Service -{ - partial class Watchdog - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Component Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - components = new System.ComponentModel.Container(); - this.ServiceName = "ASC.Mail.Watchdog.Service"; - } - - #endregion - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/WatchdogService.cs b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/WatchdogService.cs deleted file mode 100644 index 005759c5db..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/WatchdogService.cs +++ /dev/null @@ -1,158 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Configuration; -using System.Linq; -using System.ServiceModel; -using System.ServiceProcess; -using System.Threading; - -using ASC.Common.Logging; -using ASC.Mail.Core; - -namespace ASC.Mail.Watchdog.Service -{ - partial class Watchdog : ServiceBase - { - #region - Declaration - - - private readonly ILog _log; - private readonly EngineFactory _engineFactory; - - private Timer _intervalTimer; - readonly TimeSpan _tsInterval; - readonly TimeSpan _tsTasksTimeoutInterval; - - private readonly ManualResetEvent _mreStop; - - private ServiceHost _healthCheckServiceHost; - - #endregion - - #region - Constructor - - - public Watchdog() - { - InitializeComponent(); - CanStop = true; - AutoLog = true; - - _log = LogManager.GetLogger("ASC.Mail.Watchdog"); - _mreStop = new ManualResetEvent(false); - _tsInterval = - TimeSpan.FromMinutes( - Convert.ToInt32(ConfigurationManagerExtension.AppSettings["mailwatchdog.timer-interval-in-minutes"])); - _tsTasksTimeoutInterval = - TimeSpan.FromMinutes( - Convert.ToInt32(ConfigurationManagerExtension.AppSettings["mailwatchdog.tasks-timeout-in-minutes"])); - - _log.InfoFormat("\r\nConfiguration:\r\n" + - "\t- check locked mailboxes in every {0} minutes;\r\n" + - "\t- locked mailboxes timeout {1} minutes;\r\n", - _tsInterval.TotalMinutes, - _tsTasksTimeoutInterval.TotalMinutes); - - _engineFactory = new EngineFactory(-1, log: _log); - } - - #endregion - - #region - Start / Stop - - - public void StartConsole() - { - OnStart(null); - Console.CancelKeyPress += (sender, e) => OnStop(); - _mreStop.WaitOne(); - } - - protected override void OnStart(string[] args) - { - try - { - _log.Info("Start service\r\n"); - _intervalTimer = new Timer(IntervalTimer_Elapsed, _mreStop, 0, Timeout.Infinite); - - _healthCheckServiceHost = new ServiceHost(typeof(HealthCheckService)); - _healthCheckServiceHost.Open(); - } - catch (Exception) - { - OnStop(); - } - } - - protected override void OnStop() - { - //Service will be stoped in future 30 seconds! - // signal to tell the worker process to stop - _mreStop.Set(); - - _log.Info("Stop service\r\n"); - - if (_intervalTimer == null) return; - - _intervalTimer.Change(Timeout.Infinite, Timeout.Infinite); - _intervalTimer.Dispose(); - _intervalTimer = null; - - if (_healthCheckServiceHost != null) - { - _healthCheckServiceHost.Close(); - _healthCheckServiceHost = null; - } - } - - #endregion - - #region - OnTimer - - - private void IntervalTimer_Elapsed(object state) - { - try - { - _intervalTimer.Change(Timeout.Infinite, Timeout.Infinite); - - _log.InfoFormat("ReleaseLockedMailboxes(timeout is {0} minutes)", _tsTasksTimeoutInterval.TotalMinutes); - - var freeMailboxIds = _engineFactory.MailboxEngine.ReleaseMailboxes((int)_tsTasksTimeoutInterval.TotalMinutes); - - if (freeMailboxIds.Any()) - { - _log.InfoFormat("Released next locked mailbox's ids: {0}", string.Join(",", freeMailboxIds)); - } - else - { - _log.Info("Nothing to do!"); - } - - } - catch (Exception ex) - { - _log.ErrorFormat("IntervalTimer_Elapsed() Exception:\r\n{0}", ex.ToString()); - } - finally - { - _log.InfoFormat("Waiting for {0} minutes for next check...", _tsInterval.TotalMinutes); - _intervalTimer.Change(_tsInterval, _tsInterval); - } - } - - #endregion - } -} diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/mail.dog.log4net.config b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/mail.dog.log4net.config deleted file mode 100644 index b501150403..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/mail.dog.log4net.config +++ /dev/null @@ -1,112 +0,0 @@ - - - - WINDOWS:LogDirectory - ..\..\..\..\..\..\web\studio\Logs\ - - - UNIX:LogDirectory - /var/log/onlyoffice/ - - - CleanPeriod - 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/mail.dog.nlog.config b/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/mail.dog.nlog.config deleted file mode 100644 index 10be53f092..0000000000 --- a/module/ASC.Mail/Services/ASC.Mail.Watchdog.Service/mail.dog.nlog.config +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/module/ASC.Thrdparty/ASC.FederatedLogin/LoginProviders/TwitterLoginProvider.cs b/module/ASC.Thrdparty/ASC.FederatedLogin/LoginProviders/TwitterLoginProvider.cs index ab55a3bedf..30a5dfe09b 100644 --- a/module/ASC.Thrdparty/ASC.FederatedLogin/LoginProviders/TwitterLoginProvider.cs +++ b/module/ASC.Thrdparty/ASC.FederatedLogin/LoginProviders/TwitterLoginProvider.cs @@ -35,8 +35,6 @@ public class TwitterLoginProvider : BaseLoginProvider { public static string TwitterKey { get { return Instance.ClientID; } } public static string TwitterSecret { get { return Instance.ClientSecret; } } - public static string TwitterDefaultAccessToken { get { return Instance["twitterAccessToken_Default"]; } } - public static string TwitterAccessTokenSecret { get { return Instance["twitterAccessTokenSecret_Default"]; } } public override string AccessTokenUrl { get { return "https://api.twitter.com/oauth/access_token"; } } public override string RedirectUri { get { return this["twitterRedirectUrl"]; } } diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/ASC.Thrdparty.csproj b/module/ASC.Thrdparty/ASC.Thrdparty/ASC.Thrdparty.csproj deleted file mode 100644 index e57fc06412..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/ASC.Thrdparty.csproj +++ /dev/null @@ -1,93 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {592EAC85-6CFC-4AD7-B653-3EADAA18327E} - Library - Properties - ASC.Thrdparty - ASC.Thrdparty - v4.8 - 512 - - - - - 3.5 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - ..\..\..\web\studio\ASC.Web.Studio\bin\ - - - true - full - false - DEBUG;TRACE - prompt - 4 - false - ..\..\..\web\studio\ASC.Web.Studio\bin\ASC.Thrdparty.xml - CS1591 - - - none - true - TRACE - prompt - 4 - false - - - - - - - - - - - - - - - - - - 13.0.1 - - - 5.0.4 - - - - - {76de7717-3d4b-4a5b-b740-15b8913df0cb} - ASC.Common - - - {a51d0454-4afa-46de-89d4-b03d37e1816c} - ASC.Core.Common - - - - - - - \ No newline at end of file diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/Message.cs b/module/ASC.Thrdparty/ASC.Thrdparty/Message.cs deleted file mode 100644 index 7ee2656edd..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/Message.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; - -namespace ASC.Thrdparty -{ - /// - /// Represents an user activity message - /// - public class Message - { - /// - /// User name - /// - /// Name user - public string UserName { get; set; } - - /// - /// Message text - /// - /// text - public string Text { get; set; } - - /// - /// The date of message post - /// - /// 2008-04-10T06-30-00.000Z - public DateTime PostedOn { get; set; } - - /// - /// Social network - /// - /// 0 - public SocialNetworks Source { get; set; } - } -} diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/Properties/AssemblyInfo.cs b/module/ASC.Thrdparty/ASC.Thrdparty/Properties/AssemblyInfo.cs deleted file mode 100644 index 6f57c8ac00..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("ASC.Thrdparty")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Ascensio System SIA")] -[assembly: AssemblyProduct("ASC.Thrdparty")] -[assembly: AssemblyCopyright("(c) Ascensio System SIA. All rights reserved")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("c17fa4af-6a20-4de1-a9d7-f5a43f128687")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/SocialMediaException.cs b/module/ASC.Thrdparty/ASC.Thrdparty/SocialMediaException.cs deleted file mode 100644 index abdc8e8558..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/SocialMediaException.cs +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Runtime.Serialization; - -namespace ASC.Thrdparty -{ - public class SocialMediaException : Exception - { - public SocialMediaException() - { - } - - public SocialMediaException(string message) - : base(message) - { - } - - public SocialMediaException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected SocialMediaException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - } -} \ No newline at end of file diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/Exceptions.cs b/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/Exceptions.cs deleted file mode 100644 index d938df373e..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/Exceptions.cs +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -namespace ASC.Thrdparty.Twitter -{ - public class TwitterException : SocialMediaException - { - public TwitterException(string message) - : base(message) - { - } - } - - public class ConnectionFailureException : TwitterException - { - public ConnectionFailureException(string message) - : base(message) - { - } - } - - public class RateLimitException : TwitterException - { - public RateLimitException(string message) - : base(message) - { - } - } - - public class ResourceNotFoundException : TwitterException - { - public ResourceNotFoundException(string message) - : base(message) - { - } - } - - public class UnauthorizedException : TwitterException - { - public UnauthorizedException(string message) - : base(message) - { - } - } -} diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterApiInfo.cs b/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterApiInfo.cs deleted file mode 100644 index bd6cd250f1..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterApiInfo.cs +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -namespace ASC.Thrdparty.Twitter -{ - public class TwitterApiInfo - { - public string AccessToken { get; set; } - public string AccessTokenSecret { get; set; } - public string ConsumerKey { get; set; } - public string ConsumerSecret { get; set; } - } -} diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterDataProvider.cs b/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterDataProvider.cs deleted file mode 100644 index b2301acd1c..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterDataProvider.cs +++ /dev/null @@ -1,139 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text.RegularExpressions; - -using Tweetinvi; -using Tweetinvi.Models; -using Tweetinvi.Parameters; - -namespace ASC.Thrdparty.Twitter -{ - /// - /// Contains methods for getting data from Twitter - /// - public class TwitterDataProvider - { - public enum ImageSize - { - Small, - Original - } - - private TwitterClient _twitterClient; - - - /// - /// Costructor - /// - /// TwitterApiInfo object - public TwitterDataProvider(TwitterApiInfo apiInfo) - { - if (apiInfo == null) - throw new ArgumentNullException("apiInfo"); - - _twitterClient = new TwitterClient(apiInfo.ConsumerKey, apiInfo.ConsumerSecret, apiInfo.AccessToken, apiInfo.AccessTokenSecret); - } - - private static String ParseTweetTextIntoHtml(String text) - { - text = Regex.Replace(text, "(https?://([-\\w\\.]+)+(/([\\w/_\\.]*(\\?\\S+)?(#\\S+)?)?)?)", "$1"); - text = Regex.Replace(text, "@(\\w+)", "@$1"); - text = Regex.Replace(text, "\\s#(\\w+)", "#$1"); - - return text; - } - - /// - /// Gets tweets posted by specified user - /// - /// Message list - public List GetUserTweets(string screenName, int messageCount) - { - - var tweets = _twitterClient.Timelines.GetUserTimelineAsync(new GetUserTimelineParameters(screenName) - { - PageSize = messageCount - }).Result; - - return tweets.Select(x => (Message)new TwitterMessage - { - UserName = x.CreatedBy.Name, - PostedOn = x.CreatedAt.DateTime, - Source = SocialNetworks.Twitter, - Text = ParseTweetTextIntoHtml(x.Text), - UserImageUrl = x.CreatedBy.ProfileImageUrl, - UserId = x.Id.ToString() - }).Take(20).ToList(); - } - - /// - /// Gets last 20 users - /// - /// Search string - /// TwitterUserInfo list - public List FindUsers(string search) - { - var findedUsers = _twitterClient.Search.SearchUsersAsync(search).Result; - - return findedUsers.Select(x => new TwitterUserInfo - { - UserID = x.Id, - Description = x.Description, - ScreenName = x.ScreenName, - SmallImageUrl = x.ProfileImageUrl, - UserName = x.Name - }).Take(20).ToList(); - } - - /// - /// Gets url of User image - /// - /// Url of image or null if resource does not exist - public string GetUrlOfUserImage(string userScreenName, ImageSize imageSize) - { - var userInfo = _twitterClient.Users.GetUserAsync(userScreenName).Result; - - if (userInfo == null) return null; - - var profileImageUrl = userInfo.ProfileImageUrl; - - var size = GetTwitterImageSizeText(imageSize); - - if (size == "original") - profileImageUrl = profileImageUrl.Replace("_normal", String.Empty); - - return profileImageUrl; - } - - private static string GetTwitterImageSizeText(ImageSize imageSize) - { - var result = "original"; - - if (imageSize == ImageSize.Small) - { - result = "normal"; - } - - return result; - } - } -} \ No newline at end of file diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterUserInfo.cs b/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterUserInfo.cs deleted file mode 100644 index 333442ec06..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/Twitter/TwitterUserInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -namespace ASC.Thrdparty.Twitter -{ - public class TwitterUserInfo - { - ///1,1 - public decimal UserID { get; set; } - - ///Screen name - public string ScreenName { get; set; } - - ///User Name - public string UserName { get; set; } - - ///url to img - public string SmallImageUrl { get; set; } - - ///Description - public string Description { get; set; } - } -} diff --git a/module/ASC.Thrdparty/ASC.Thrdparty/app.config b/module/ASC.Thrdparty/ASC.Thrdparty/app.config deleted file mode 100644 index dc12e2573d..0000000000 --- a/module/ASC.Thrdparty/ASC.Thrdparty/app.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/module/ASC.WebDav/helper/logger.js b/module/ASC.WebDav/helper/logger.js index be55c5a9ca..2f061763d5 100644 --- a/module/ASC.WebDav/helper/logger.js +++ b/module/ASC.WebDav/helper/logger.js @@ -20,7 +20,7 @@ const { format } = require("winston"); require("winston-daily-rotate-file"); const path = require("path"); -const config = require(`../server/config.${process.argv[2]}.js`); +const config = require(`../server/config.js`); const fs = require("fs"); const logLevel = process.env.logLevel || config.logLevel || "info"; const fileName = config.logPath || path.join(__dirname, "..", "logs", "web.webdav.%DATE%.log"); diff --git a/module/ASC.WebDav/resource/customVirtualResource.js b/module/ASC.WebDav/resource/customVirtualResource.js index 047480a0d4..54aaf90963 100644 --- a/module/ASC.WebDav/resource/customVirtualResource.js +++ b/module/ASC.WebDav/resource/customVirtualResource.js @@ -38,15 +38,13 @@ const { } = require('../server/requestAPI.js'); const { method, - maxChunkSize, + maxChunkSize, + maxExecutionTime, virtualPath } = require('../server/config.js'); const streamWrite = require('../helper/writable.js'); const SimpleStruct = require('./simpleStruct.js'); const parse = require('../helper/propertyParser.js'); -const { - maxExecutionTime -} = require('../server/config'); const { logMessage } = require('../helper/helper.js'); class CustomVirtualResources { diff --git a/module/ASC.WebDav/server/config.js b/module/ASC.WebDav/server/config.js index 83ae1f0d9f..19802aaf9e 100644 --- a/module/ASC.WebDav/server/config.js +++ b/module/ASC.WebDav/server/config.js @@ -17,7 +17,12 @@ /* Config */ -module.exports = { +const fs = require("fs"); +const path = require("path"); +const fileName = `config.${process.argv[2]}.js`; +const config = fs.existsSync(path.join(__dirname, fileName)) + ? require(`./${fileName}`) + : { // Port listener WebDav Server port: 1900, // Path to pfx key @@ -81,4 +86,6 @@ module.exports = { // Method to create session to edit existing file with multiple chunks editSession: "/edit_session" } -}; \ No newline at end of file +}; + +module.exports = config; \ No newline at end of file diff --git a/module/ASC.WebDav/server/webDavServer.js b/module/ASC.WebDav/server/webDavServer.js index c34fae2d7d..898ec4be3d 100644 --- a/module/ASC.WebDav/server/webDavServer.js +++ b/module/ASC.WebDav/server/webDavServer.js @@ -31,7 +31,7 @@ const { keyPath, isHttps, virtualPath -} = require(`./config.${process.argv[2]}.js`); +} = require(`./config.js`); const { logContext, logMessage } = require('../helper/helper.js'); diff --git a/web/core/ASC.Web.Core/Client/Bundling/GoogleCloudStorageTransform.cs b/web/core/ASC.Web.Core/Client/Bundling/GoogleCloudStorageTransform.cs index adabc2f50d..5000d8ca12 100644 --- a/web/core/ASC.Web.Core/Client/Bundling/GoogleCloudStorageTransform.cs +++ b/web/core/ASC.Web.Core/Client/Bundling/GoogleCloudStorageTransform.cs @@ -206,7 +206,7 @@ private void UploadToCdn() UploadObjectOptions uploadObjectOptions = new UploadObjectOptions { - PredefinedAcl = PredefinedObjectAcl.PublicRead + PredefinedAcl = PredefinedObjectAcl.BucketOwnerFullControl }; inputStream.Position = 0; diff --git a/web/core/ASC.Web.Core/CookiesManager.cs b/web/core/ASC.Web.Core/CookiesManager.cs index 187a785eeb..7361e2eefe 100644 --- a/web/core/ASC.Web.Core/CookiesManager.cs +++ b/web/core/ASC.Web.Core/CookiesManager.cs @@ -123,11 +123,21 @@ public static void SetCookies(CookiesType type, string itemId, string value, str if (ClientSettings.SameSiteCookieEnabled) { + // SameSite is not support by Mono yet (https://github.com/mono/mono/issues/18711) + // HttpContext.Current.Response.Cookies[cookieName].SameSite = SameSiteMode.None; + var cookies = HttpContext.Current.Response.Cookies[cookieName]; - cookies.GetType() - .GetProperty("SameSite") - .SetValue(cookies, 0); + var property = cookies.GetType().GetProperty("SameSite"); + + if (property != null) + { + property.SetValue(cookies, 0); + } + else + { + cookies.Path = "/; SameSite=None"; + } } } } @@ -236,17 +246,17 @@ public static int GetLifeTime() public static void ResetUserCookie(Guid? userId = null) { - var currentUserId = SecurityContext.CurrentAccount.ID; + var targetUserId = userId ?? SecurityContext.CurrentAccount.ID; var tenant = TenantProvider.CurrentTenantID; - var settings = TenantCookieSettings.GetForUser(userId ?? currentUserId); + var settings = TenantCookieSettings.GetForUser(targetUserId); settings.Index = settings.Index + 1; - TenantCookieSettings.SetForUser(userId ?? currentUserId, settings); + TenantCookieSettings.SetForUser(targetUserId, settings); - DbLoginEventsManager.LogOutAllActiveConnections(tenant, userId ?? currentUserId); + DbLoginEventsManager.LogOutAllActiveConnections(tenant, targetUserId); - if (!userId.HasValue) + if (targetUserId == SecurityContext.CurrentAccount.ID) { - AuthenticateMeAndSetCookies(tenant, currentUserId, MessageAction.LoginSuccess); + AuthenticateMeAndSetCookies(tenant, targetUserId, MessageAction.LoginSuccess); } } diff --git a/web/core/ASC.Web.Core/Extensions/WebItemExtension.cs b/web/core/ASC.Web.Core/Extensions/WebItemExtension.cs index 7479b8ba90..c058caed4f 100644 --- a/web/core/ASC.Web.Core/Extensions/WebItemExtension.cs +++ b/web/core/ASC.Web.Core/Extensions/WebItemExtension.cs @@ -20,6 +20,7 @@ using System.Linq; using ASC.Core; +using ASC.Web.Core.Utility; using ASC.Web.Core.Utility.Skins; namespace ASC.Web.Core @@ -78,8 +79,12 @@ public static string GetIconAbsoluteURL(this IWebItem item) public static string GetLargeIconAbsoluteURL(this IWebItem item) { - if (item == null || item.Context == null || String.IsNullOrEmpty(item.Context.LargeIconFileName)) return string.Empty; - return WebImageSupplier.GetAbsoluteWebPath(item.Context.LargeIconFileName, item.ID); + var theme = ModeThemeSettings.GetModeThemesSettings().ModeThemeName; + var fileName = theme == ModeTheme.dark ? item.Context.LargeIconFileNameDark : item.Context.LargeIconFileName; + + if (item == null || item.Context == null || string.IsNullOrEmpty(fileName)) return string.Empty; + + return WebImageSupplier.GetAbsoluteWebPath(fileName, item.ID); } public static List GetUserOpportunities(this IWebItem item) diff --git a/web/core/ASC.Web.Core/Files/DocumentService.cs b/web/core/ASC.Web.Core/Files/DocumentService.cs index 7f6044afab..a24efcfc54 100644 --- a/web/core/ASC.Web.Core/Files/DocumentService.cs +++ b/web/core/ASC.Web.Core/Files/DocumentService.cs @@ -88,6 +88,7 @@ public static string GenerateRevisionId(string expectedKey) /// Perform conversions asynchronously /// Secret key to generate the token /// Uri to the converted document + /// Extension of the converted file /// The percentage of completion of conversion /// /// string convertedDocumentUri; @@ -107,7 +108,8 @@ public static int GetConvertedUri( SpreadsheetLayout spreadsheetLayout, bool isAsync, string signatureSecret, - out string convertedDocumentUri) + out string convertedDocumentUri, + out string convertedFileType) { fromExtension = string.IsNullOrEmpty(fromExtension) ? Path.GetExtension(documentUri) : fromExtension; if (string.IsNullOrEmpty(fromExtension)) throw new ArgumentNullException("fromExtension", "Document's extension for conversion is not known"); @@ -222,7 +224,7 @@ public static int GetConvertedUri( response.Dispose(); } - return GetResponseUri(dataResponse, out convertedDocumentUri); + return GetResponseUri(dataResponse, out convertedDocumentUri, out convertedFileType); } /// @@ -858,8 +860,9 @@ public enum ErrorCode /// /// The resulting json from editing service /// Uri to the converted document + /// Extension of the converted file /// The percentage of completion of conversion - private static int GetResponseUri(string jsonDocumentResponse, out string responseUri) + private static int GetResponseUri(string jsonDocumentResponse, out string responseUri, out string responseType) { if (string.IsNullOrEmpty(jsonDocumentResponse)) throw new ArgumentException("Invalid param", "jsonDocumentResponse"); @@ -873,9 +876,11 @@ private static int GetResponseUri(string jsonDocumentResponse, out string respon int resultPercent; responseUri = string.Empty; + responseType = string.Empty; if (isEndConvert) { responseUri = responseFromService.Value("fileUrl"); + responseType = responseFromService.Value("fileType"); resultPercent = 100; } else diff --git a/web/core/ASC.Web.Core/Files/FileUtility.cs b/web/core/ASC.Web.Core/Files/FileUtility.cs index b65332dc6d..ea8336080e 100644 --- a/web/core/ASC.Web.Core/Files/FileUtility.cs +++ b/web/core/ASC.Web.Core/Files/FileUtility.cs @@ -57,6 +57,11 @@ public static string GetInternalExtension(string fileName) : extension; } + public static string GetInternalConvertExtension(string fileName) + { + return "ooxml"; + } + public static string GetGoogleDownloadableExtension(string googleExtension) { googleExtension = GetFileExtension(googleExtension); @@ -67,7 +72,8 @@ public static string GetGoogleDownloadableExtension(string googleExtension) public static string ReplaceFileExtension(string fileName, string newExtension) { newExtension = string.IsNullOrEmpty(newExtension) ? string.Empty : newExtension; - return Path.GetFileNameWithoutExtension(fileName) + newExtension; + return Path.GetFileNameWithoutExtension(fileName) + + "." + newExtension.TrimStart('.'); } public static FileType GetFileTypeByFileName(string fileName) @@ -315,6 +321,7 @@ public static List ExtsCoAuthoring ".xls", ".xlsx", ".xlsm", ".xlt", ".xltx", ".xltm", ".ods", ".fods", ".ots", ".csv", + ".sxc", ".et", ".ett", ".xlst", ".xlsy", ".xlsb", ".gsheet" }; @@ -325,6 +332,7 @@ public static List ExtsCoAuthoring ".ppt", ".pptx", ".pptm", ".pot", ".potx", ".potm", ".odp", ".fodp", ".otp", + ".dps", ".dpt", ".sxi", ".pptt", ".ppty", ".gslides" }; @@ -334,8 +342,9 @@ public static List ExtsCoAuthoring ".doc", ".docx", ".docm", ".dot", ".dotx", ".dotm", ".odt", ".fodt", ".ott", ".rtf", ".txt", - ".html", ".htm", ".mht", ".xml", + ".html", ".htm", ".mht", ".mhtml", ".xml", ".pdf", ".djvu", ".fb2", ".epub", ".xps", ".oxps", + ".sxw", ".stw", ".wps", ".wpt", ".doct", ".docy", ".gdoc", ".docxf", ".oform" diff --git a/web/core/ASC.Web.Core/Utility/ModeThemeSettings.cs b/web/core/ASC.Web.Core/Utility/ModeThemeSettings.cs index b6fd0daa19..712ecbd17b 100644 --- a/web/core/ASC.Web.Core/Utility/ModeThemeSettings.cs +++ b/web/core/ASC.Web.Core/Utility/ModeThemeSettings.cs @@ -44,7 +44,7 @@ public override ISettings GetDefault() return new ModeThemeSettings { ModeThemeName = ModeTheme.light, - AutoDetect = false + AutoDetect = true }; } diff --git a/web/core/ASC.Web.Core/WebItemContext.cs b/web/core/ASC.Web.Core/WebItemContext.cs index 79b5a4f13e..6cb1831218 100644 --- a/web/core/ASC.Web.Core/WebItemContext.cs +++ b/web/core/ASC.Web.Core/WebItemContext.cs @@ -41,6 +41,7 @@ public class WebItemContext public string IconFileName { get; set; } public string LargeIconFileName { get; set; } + public string LargeIconFileNameDark { get; set; } public int DefaultSortOrder { get; set; } diff --git a/web/core/ASC.Web.Core/WhiteLabel/TenantWhiteLabelSettings.cs b/web/core/ASC.Web.Core/WhiteLabel/TenantWhiteLabelSettings.cs index bc844e0696..49b2895b60 100644 --- a/web/core/ASC.Web.Core/WhiteLabel/TenantWhiteLabelSettings.cs +++ b/web/core/ASC.Web.Core/WhiteLabel/TenantWhiteLabelSettings.cs @@ -663,13 +663,18 @@ public static void Apply(int tenantId) if (!AppliedTenants.Contains(tenantId)) AppliedTenants.Add(tenantId); } + public void ClearAppliedTenants() + { + AppliedTenants.Clear(); + } + public void Save(int tenantId, bool restore = false) { SaveForTenant(tenantId); if (tenantId == Tenant.DEFAULT_TENANT) { - AppliedTenants.Clear(); + ClearAppliedTenants(); } else { diff --git a/web/studio/ASC.Web.Studio/ASC.Web.Studio.csproj b/web/studio/ASC.Web.Studio/ASC.Web.Studio.csproj index 900bcd6415..8eccb17210 100644 --- a/web/studio/ASC.Web.Studio/ASC.Web.Studio.csproj +++ b/web/studio/ASC.Web.Studio/ASC.Web.Studio.csproj @@ -1283,8 +1283,13 @@ + + + + + @@ -1293,18 +1298,31 @@ + + + + + + + + + + + + + @@ -1316,14 +1334,22 @@ + + + + + + + + @@ -1335,12 +1361,17 @@ + + + + + @@ -1356,6 +1387,7 @@ + @@ -1363,6 +1395,7 @@ + @@ -1380,10 +1413,16 @@ + + + + + + @@ -1394,6 +1433,7 @@ + @@ -1531,12 +1571,25 @@ + + + + + + + + + + + + + @@ -1544,20 +1597,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1917,6 +1995,7 @@ + @@ -2214,6 +2293,8 @@ + + @@ -2221,6 +2302,7 @@ + @@ -2641,7 +2723,6 @@ - @@ -2678,6 +2759,7 @@ + Designer @@ -4169,7 +4251,6 @@ - @@ -4401,10 +4482,6 @@ {481b0d9c-b2f8-4de9-8597-ba8d24585099} ASC.FederatedLogin - - {592eac85-6cfc-4ad7-b653-3eadaa18327e} - ASC.Thrdparty - {988536c1-4b89-4649-8f77-5c16f55d95d1} ASC.VoipService diff --git a/web/studio/ASC.Web.Studio/Core/EmailOperationService.cs b/web/studio/ASC.Web.Studio/Core/EmailOperationService.cs index c740cd613c..5766333a8d 100644 --- a/web/studio/ASC.Web.Studio/Core/EmailOperationService.cs +++ b/web/studio/ASC.Web.Studio/Core/EmailOperationService.cs @@ -23,6 +23,7 @@ using ASC.Core; using ASC.Core.Users; using ASC.MessagingSystem; +using ASC.Web.Core; using ASC.Web.Studio.Core.Notify; using ASC.Web.Studio.Core.Users; using ASC.Web.Studio.PublicResources; @@ -87,38 +88,45 @@ public string SendEmailActivationInstructions(Guid userID, string email) if (userID == Guid.Empty) throw new ArgumentNullException("userID"); email = (email ?? "").Trim(); - if (String.IsNullOrEmpty(email)) throw new ArgumentNullException(Resource.ErrorEmailEmpty); + if (string.IsNullOrEmpty(email)) throw new ArgumentNullException(Resource.ErrorEmailEmpty); if (!email.TestEmailRegex()) throw new InvalidEmailException(Resource.ErrorNotCorrectEmail); try { var viewer = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID); + var viewerIsAdmin = WebItemSecurity.IsProductAdministrator(WebItemManager.PeopleProductID, SecurityContext.CurrentAccount.ID); + var user = CoreContext.UserManager.GetUsers(userID); - if (user == null) throw new UserNotFoundException(Resource.ErrorUserNotFound); + if (CoreContext.UserManager.IsSystemUser(user.ID)) + throw new UserNotFoundException(Resource.ErrorUserNotFound); - if (viewer == null) throw new AccessDeniedException(Resource.ErrorAccessDenied); + if (!viewerIsAdmin && viewer.ID != user.ID) + throw new AccessDeniedException(Resource.ErrorAccessDenied); - if (viewer.IsAdmin() || viewer.ID == user.ID) - { - var existentUser = CoreContext.UserManager.GetUserByEmail(email); - if (existentUser.ID != ASC.Core.Users.Constants.LostUser.ID && existentUser.ID != userID) - throw new InputException(CustomNamingPeople.Substitute("ErrorEmailAlreadyExists")); + if (user.IsOwner() && viewer.ID != user.ID && email != user.Email) + throw new AccessDeniedException(Resource.ErrorAccessDenied); - user.Email = email; - if (user.ActivationStatus == EmployeeActivationStatus.Activated) - { - user.ActivationStatus = EmployeeActivationStatus.NotActivated; - } - if (user.ActivationStatus == (EmployeeActivationStatus.AutoGenerated | EmployeeActivationStatus.Activated)) - { - user.ActivationStatus = EmployeeActivationStatus.AutoGenerated; - } - CoreContext.UserManager.SaveUserInfo(user, syncCardDav: true); + var existentUser = CoreContext.UserManager.GetUserByEmail(email); + if (existentUser.ID != Constants.LostUser.ID && existentUser.ID != user.ID) + throw new InputException(CustomNamingPeople.Substitute("ErrorEmailAlreadyExists")); + + var emailChanged = email != user.Email; + + user.Email = email; + if (user.ActivationStatus == EmployeeActivationStatus.Activated) + { + user.ActivationStatus = EmployeeActivationStatus.NotActivated; } - else + if (user.ActivationStatus == (EmployeeActivationStatus.AutoGenerated | EmployeeActivationStatus.Activated)) { - email = user.Email; + user.ActivationStatus = EmployeeActivationStatus.AutoGenerated; + } + CoreContext.UserManager.SaveUserInfo(user, syncCardDav: true); + + if (emailChanged) + { + CookiesManager.ResetUserCookie(user.ID); } if (user.ActivationStatus == EmployeeActivationStatus.Pending && !user.IsLDAP()) @@ -176,19 +184,24 @@ public string SendEmailChangeInstructions(Guid userID, string email) try { var viewer = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID); + var viewerIsAdmin = WebItemSecurity.IsProductAdministrator(WebItemManager.PeopleProductID, SecurityContext.CurrentAccount.ID); + var user = CoreContext.UserManager.GetUsers(userID); - if (user == null) + if (CoreContext.UserManager.IsSystemUser(user.ID)) throw new UserNotFoundException(Resource.ErrorUserNotFound); - if (viewer == null || (user.IsOwner() && viewer.ID != user.ID)) + if (!viewerIsAdmin && viewer.ID != user.ID) + throw new AccessDeniedException(Resource.ErrorAccessDenied); + + if (user.IsOwner() && viewer.ID != user.ID) throw new AccessDeniedException(Resource.ErrorAccessDenied); var existentUser = CoreContext.UserManager.GetUserByEmail(email); - if (existentUser.ID != ASC.Core.Users.Constants.LostUser.ID) + if (existentUser.ID != Constants.LostUser.ID) throw new InputException(CustomNamingPeople.Substitute("ErrorEmailAlreadyExists")); - if (!viewer.IsAdmin()) + if (!viewerIsAdmin) { StudioNotifyService.Instance.SendEmailChangeInstructions(user, email); MessageService.Send(HttpContext.Current.Request, MessageAction.UserSentEmailChangeInstructions, user.DisplayUserName(false)); @@ -209,6 +222,9 @@ public string SendEmailChangeInstructions(Guid userID, string email) } CoreContext.UserManager.SaveUserInfo(user, syncCardDav: true); + + CookiesManager.ResetUserCookie(user.ID); + StudioNotifyService.Instance.SendEmailActivationInstructions(user, email); MessageService.Send(HttpContext.Current.Request, MessageAction.UserSentActivationInstructions, user.DisplayUserName(false)); } diff --git a/web/studio/ASC.Web.Studio/Default.aspx b/web/studio/ASC.Web.Studio/Default.aspx index d5e5daa3b7..cf8f6ac432 100644 --- a/web/studio/ASC.Web.Studio/Default.aspx +++ b/web/studio/ASC.Web.Studio/Default.aspx @@ -39,7 +39,7 @@ <% if (TenantExtra.EnableControlPanel) { %> - <%= Resource.ControlPanelLabel %>" /> + <%= Resource.ControlPanelLabel %>" /> <%= Resource.ControlPanelLabel %> diff --git a/web/studio/ASC.Web.Studio/Default.aspx.cs b/web/studio/ASC.Web.Studio/Default.aspx.cs index b29a955258..3b54ff694e 100644 --- a/web/studio/ASC.Web.Studio/Default.aspx.cs +++ b/web/studio/ASC.Web.Studio/Default.aspx.cs @@ -25,6 +25,8 @@ using ASC.Core.Users; using ASC.Web.Core; using ASC.Web.Core.Files; +using ASC.Web.Core.Utility; +using ASC.Web.Core.Utility.Skins; using ASC.Web.Studio.Core; using ASC.Web.Studio.PublicResources; using ASC.Web.Studio.UserControls.EmptyScreens; @@ -56,13 +58,23 @@ protected override void OnPreInit(EventArgs e) protected int ProductsCount { get; set; } protected string ResetCacheKey; + protected string ControlPanelImg; protected void Page_Load(object sender, EventArgs e) { CurrentUser = CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID); - Page.RegisterStyle("~/skins/page_default.less"); - + if (ModeThemeSettings.GetModeThemesSettings().ModeThemeName == ModeTheme.dark) + { + Page.RegisterStyle("~/skins/page_default_dark.less"); + ControlPanelImg = WebImageSupplier.GetAbsoluteWebPath("icon-controlpanel-dark.svg"); + } + else + { + Page.RegisterStyle("~/skins/page_default.less"); + ControlPanelImg = WebImageSupplier.GetAbsoluteWebPath("icon-controlpanel.svg"); + } + var defaultPageSettings = StudioDefaultPageSettings.Load() ?? (StudioDefaultPageSettings)new StudioDefaultPageSettings().GetDefault(); var isDesktop = Request.DesktopApp(); var defaultProductID = isDesktop ? WebItemManager.DocumentsProductID : defaultPageSettings.DefaultProductID; diff --git a/web/studio/ASC.Web.Studio/Global.asax.cs b/web/studio/ASC.Web.Studio/Global.asax.cs index f91a0832bc..fd0417a571 100644 --- a/web/studio/ASC.Web.Studio/Global.asax.cs +++ b/web/studio/ASC.Web.Studio/Global.asax.cs @@ -191,8 +191,19 @@ public static bool Authenticate() if (!authenticated) { - Auth.ProcessLogout(); - return false; + var comebackAuthCookies = CookiesManager.GetCookies(CookiesType.ComebackAuthKey); + + if (!string.IsNullOrEmpty(comebackAuthCookies) && SecurityContext.AuthenticateMe(comebackAuthCookies)) + { + CookiesManager.SetCookies(CookiesType.AuthKey, comebackAuthCookies); + CookiesManager.ClearCookies(CookiesType.ComebackAuthKey); + authenticated = true; + } + else + { + Auth.ProcessLogout(); + return false; + } } } } diff --git a/web/studio/ASC.Web.Studio/HttpHandlers/FCKEditorFileUploadHandler.cs b/web/studio/ASC.Web.Studio/HttpHandlers/FCKEditorFileUploadHandler.cs index 050109ae7a..3d8367281b 100644 --- a/web/studio/ASC.Web.Studio/HttpHandlers/FCKEditorFileUploadHandler.cs +++ b/web/studio/ASC.Web.Studio/HttpHandlers/FCKEditorFileUploadHandler.cs @@ -16,10 +16,10 @@ using System; -using System.Text.RegularExpressions; using System.Web; using ASC.Common.Web; +using ASC.Core; using ASC.Data.Storage; using ASC.Web.Core.Files; using ASC.Web.Studio.Core; @@ -34,6 +34,11 @@ public override void OnProcessRequest(HttpContext context) { try { + if (!SecurityContext.IsAuthenticated) + { + throw new HttpException(403, "Access denied."); + } + var storeDomain = context.Request["esid"]; var itemID = context.Request["iid"] ?? ""; var file = context.Request.Files["upload"]; diff --git a/web/studio/ASC.Web.Studio/HttpHandlers/UrlProxyHandler.cs b/web/studio/ASC.Web.Studio/HttpHandlers/UrlProxyHandler.cs index 86b50d1a3f..d690b42f63 100644 --- a/web/studio/ASC.Web.Studio/HttpHandlers/UrlProxyHandler.cs +++ b/web/studio/ASC.Web.Studio/HttpHandlers/UrlProxyHandler.cs @@ -23,7 +23,8 @@ using ASC.Common.Logging; using ASC.Core; - +using ASC.Web.Studio.Core; + namespace ASC.Web.Studio.HttpHandlers { public class UrlProxyHandler : IHttpHandler @@ -42,7 +43,7 @@ public void ProcessRequest(HttpContext context) try { - if (!SecurityContext.IsAuthenticated) + if (!SecurityContext.IsAuthenticated || !SetupInfo.IsVisibleSettings("ProxyHttpContent")) throw new HttpException(403, "Access denied."); var url = context.Request.QueryString["url"]; diff --git a/web/studio/ASC.Web.Studio/Products/CRM/ASC.Web.CRM.csproj b/web/studio/ASC.Web.Studio/Products/CRM/ASC.Web.CRM.csproj index 3e3ff72f72..2e671d1f43 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/ASC.Web.CRM.csproj +++ b/web/studio/ASC.Web.Studio/Products/CRM/ASC.Web.CRM.csproj @@ -64,7 +64,6 @@ - @@ -369,9 +368,6 @@ - - - @@ -597,17 +593,18 @@ + - + @@ -623,9 +620,10 @@ + + - @@ -1232,85 +1230,6 @@ True CRMSettingResource.resx - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - Designer - PublicResXFileCodeGenerator - CRMSocialMediaResource.Designer.cs - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - True - True - CRMSocialMediaResource.resx - CRMTaskResource.resx @@ -1668,48 +1587,6 @@ CRMDealResource.resx - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - - - CRMSocialMediaResource.resx - CRMSettingResource.resx @@ -2245,7 +2122,6 @@ - @@ -2272,9 +2148,6 @@ - - - @@ -2322,10 +2195,6 @@ {481B0D9C-B2F8-4DE9-8597-BA8D24585099} ASC.FederatedLogin - - {592eac85-6cfc-4ad7-b653-3eadaa18327e} - ASC.Thrdparty - {988536c1-4b89-4649-8f77-5c16f55d95d1} ASC.VoipService diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/dark/dark-params.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/dark/dark-params.less index 4c211ff636..b5ac7dd223 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/dark/dark-params.less +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/dark/dark-params.less @@ -53,6 +53,7 @@ @ui-autocomplete-a-col: rgba(255, 255, 255, 0.92); @invoice-icon-search-bg: #292929; @option-button-col: #BDBDBD; -@option-button-bor: #BDBDBD; -@contact-photo-bor: #474747; -@change-status-button-bg: #474747; \ No newline at end of file +@option-button-bor: #BDBDBD; +@contact-photo-bor: #474747; +@change-status-button-bg: #474747; +@icons-png: "icons-dark.svg"; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/common.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/common.less index 6d2e0cec80..f1260f8fe8 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/common.less +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/common.less @@ -76,12 +76,12 @@ textarea { } -.crm-deleteLink{ - background: url("../images/icons.png") 0 -263px no-repeat transparent; +.crm-deleteLink { + background: url("../images/@{icons-png}") 0 -263px no-repeat transparent; .crm-actionLinkBase; } .crm-editLink{ - background: url("../images/icons.png") 0 -240px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -240px no-repeat transparent; .crm-actionLinkBase; } .crm-addNewLink { @@ -105,13 +105,13 @@ textarea { } } -.crm-acceptLink{ - background: url("../images/icons.png") 0 -43px no-repeat transparent; +.crm-acceptLink { + background: url("../images/@{icons-png}") 0 -43px no-repeat transparent; .crm-actionLinkBase; } -.crm-rejectLink{ - background: url("../images/icons.png") 0 -21px no-repeat transparent; +.crm-rejectLink { + background: url("../images/@{icons-png}") 0 -21px no-repeat transparent; .crm-actionLinkBase; } .crm-removeLink{ @@ -141,15 +141,15 @@ textarea { position: relative; } .crm-email:after { - background: url("../images/icons.png") 0 -476px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -476px no-repeat transparent; .crm-img-pseudo-base(2px); } .crm-phone:after { - background: url("../images/icons.png") 0 -458px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -458px no-repeat transparent; .crm-img-pseudo-base(2px); } .crm-address:after { - background: url("../images/icons.png") 0 -438px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -438px no-repeat transparent; .crm-img-pseudo-base; } .crm-email a { @@ -209,8 +209,8 @@ select.disabled { background-color: #EFEFEF; color: #666562; } -.crm-private-lock{ - background: url("../images/icons.png") 1px -159px no-repeat transparent; +.crm-private-lock { + background: url("../images/@{icons-png}") 1px -159px no-repeat transparent; display: inline-block; height: 16px; margin-top: -4px; @@ -362,7 +362,7 @@ a.attachLink, a.attachLink:active, a.attachLink:hover, a.attachLink:visited{ position: relative; margin: 3px 4px 3px 20px; &:after { - background: url( "../images/icons.png" ) 0 -415px no-repeat; + background: url( "../images/@{icons-png}" ) 0 -415px no-repeat; margin-top: -8px; margin-left: -30px; .crm-img-pseudo-base(50%, 10px); @@ -412,7 +412,7 @@ a.attachLink, a.attachLink:active, a.attachLink:hover, a.attachLink:visited{ float:left; } .mainContainerClass .containerHeaderBlock .privateMark { - background: url("../images/icons.png") 0 -183px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -183px no-repeat transparent; width: 24px; height: 24px; } @@ -645,7 +645,7 @@ Navigation panel with page navigator File Uploader css style *******************************************************************************/ .pm_deleteLinkCSSClass { - background:url("../images/icons.png") 0 -603px no-repeat transparent; + background:url("../images/@{icons-png}") 0 -603px no-repeat transparent; .crm-actionLinkBase; text-decoration:none !important; } @@ -656,7 +656,7 @@ File Uploader css style text-decoration:none !important; } .pm_completeCSSClass { - background:url("../images/icons.png") 0 -63px no-repeat transparent; + background:url("../images/@{icons-png}") 0 -63px no-repeat transparent; .crm-actionLinkBase(16px); cursor:default; margin-top:2px; @@ -671,10 +671,10 @@ File Uploader css style } .pm_overAllProcessBarCssClass div { height:8px; - background:url("../images/icons.png") 0 -698px repeat-x !important; + background:url("../images/@{icons-png}") 0 -698px repeat-x !important; } .pm_uploadIcon { - background: url(../images/icons.png) 0 -653px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -653px no-repeat transparent; height: 32px; width: 32px; } @@ -863,7 +863,7 @@ label.event_category { } label.event_attached_file { - background: url("../images/icons.png") no-repeat scroll 0 -415px rgba(0, 0, 0, 0); + background: url("../images/@{icons-png}") no-repeat scroll 0 -415px rgba(0, 0, 0, 0); content: " "; display: inline-block; height: 16px; @@ -1020,7 +1020,7 @@ ContactSelector.ascx } label.crossButton { - background: url("../images/icons.png") 0 -718px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -718px no-repeat transparent; .crm-actionLinkBase; } @@ -1351,7 +1351,7 @@ Import From CSV position: relative; &:after { - background: url("../images/icons.png") 0 -288px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -288px no-repeat transparent; .crm-img-pseudo-base(50%, -16px, 14px, 14px); margin-top: -7px; } diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/contacts.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/contacts.less index 022f486462..eb78ac79bb 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/contacts.less +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/contacts.less @@ -45,7 +45,7 @@ sliders } .ui-slider .ui-slider-handle{ background-color: #dedede; - background: url( "../images/icons.png" ) -1px -500px no-repeat transparent; + background: url( "../images/@{icons-png}" ) -1px -500px no-repeat transparent; border: 1px solid #aaaaaa; cursor: pointer; margin-left: -0.4em; @@ -218,7 +218,7 @@ ListContactView.ascx margin-left: 4px; &.sharedContact:after { - background: url( "../images/icons.png") 0 -768px no-repeat transparent; + background: url( "../images/@{icons-png}") 0 -768px no-repeat transparent; .crm-img-pseudo-base(auto, -2px, 12px, 12px); bottom: -2px; } @@ -284,7 +284,7 @@ body.media-width-min { } } #previewAttachments label.previewAttachment{ - background: url( "../images/icons.png" ) 0 -415px no-repeat; + background: url( "../images/@{icons-png}" ) 0 -415px no-repeat; display: inline-block; height: 16px; width: 16px; @@ -510,7 +510,7 @@ ContactActionView.ascx } .is_primary { - background-image: url( "../images/icons.png"); + background-image: url( "../images/@{icons-png}"); background-repeat: no-repeat; background-color: transparent; cursor: pointer; @@ -600,7 +600,7 @@ ContactActionView.ascx position: relative; &.sharedContact:after { - background: url( "../images/icons.png") 0 -783px no-repeat transparent; + background: url( "../images/@{icons-png}") 0 -783px no-repeat transparent; .crm-img-pseudo-base(auto, 8px, 22px, 22px); bottom: 8px; } @@ -656,7 +656,7 @@ body.media-width-min { #companySelectorsContainer { .delete_company_for_person { - background: url("../images/icons.png") 0 -263px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -263px no-repeat transparent; cursor: pointer; display: inline-block; height: 16px; @@ -820,25 +820,57 @@ HistoryView.ascx } /******************************************************************************** -SocialMedia +Page Navigation +********************************************************************************/ +#contactsFilterContainer, #tableForContactNavigation { + display: none; +} + +/******************************************************************************** +Contact Photo (ContactDetailsView, ContactActionView) ********************************************************************************/ +#divLoadPhotoWindow h4 { + margin-bottom: 5px; +} + +#divLoadPhotoFromPC { + .fileUploadDscr { + margin-left: 12px; + } -.sm_UserSearchView_ErrorDescription{ - margin-left: 0px !important; - margin-right: 0px !important; + .fileUploadError { + color: #CC0000; + display: none; + font: 12px Tahoma; + margin-left: 12px; + } } -.select-container{ - position:relative; + +#divLoadPhotoDefault { + margin-top: 10px; } -.select-container.type-select-container{ - min-width:180px; + +.ImageHolderOuter { + display: inline-block; + width: 54px; + height: 54px; + margin-right: 10px; + margin-bottom: 10px; + vertical-align: top; + cursor: pointer; + border: 1px solid @text-color; + + img { + padding: 2px; + + &:hover { + border: 2px solid #1A6DB3 !important; + padding: 0px; + } + } } -.select-container.tags-select-container{ - min-width:160px; + +.AvatarImage { + width: 50px; + height: 50px; } -/******************************************************************************** -Page Navigation -********************************************************************************/ -#contactsFilterContainer, #tableForContactNavigation { - display: none; -} \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/crm.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/crm.less index 024e5c35a6..58a25d053a 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/crm.less +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/crm.less @@ -22,7 +22,6 @@ @import "contacts.less"; @import "deals.less"; @import "invoices.less"; -@import "socialmedia.less"; @import "settings.less"; @import "voip.common.less"; @import "voip.quick.less"; diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/invoices.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/invoices.less index b41666c332..f0332d13a5 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/invoices.less +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/invoices.less @@ -620,7 +620,7 @@ ListActionView.ascx } &.serch { - background: url("../images/icons.png") no-repeat scroll -1px -390px @invoice-icon-search-bg; + background: url("../images/@{icons-png}") no-repeat scroll -1px -390px @invoice-icon-search-bg; } } } diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/params.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/params.less index 0768caf5e7..0960d8346e 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/params.less +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/params.less @@ -53,6 +53,7 @@ @ui-autocomplete-a-col: black; @invoice-icon-search-bg: #FFFFFF; @option-button-col: #272727; -@option-button-bor: #8E908F; -@contact-photo-bor: #BFBFBF; -@change-status-button-bg: #eaeaea; \ No newline at end of file +@option-button-bor: #8E908F; +@contact-photo-bor: #BFBFBF; +@change-status-button-bg: #eaeaea; +@icons-png: "icons.png"; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/settings.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/settings.less index a2ac5aade3..efdf1816b6 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/settings.less +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/settings.less @@ -243,7 +243,7 @@ margin: 10px 0 0 0; label.deleteBtn { - background: url("../images/icons.png") 0 -263px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -263px no-repeat transparent; cursor: pointer; display: inline-block; height: 16px; @@ -415,11 +415,11 @@ } .headerCollapse { - background: url("../images/icons.png") 0 -103px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -103px no-repeat transparent; } .headerExpand { - background: url("../images/icons.png") 0 -131px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -131px no-repeat transparent; } li, li:hover { @@ -523,7 +523,7 @@ td.digits { background-color: #FEECD6; } #properties_webFormKey .refreshBtn { - background: url("../images/icons.png") 0 -743px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -743px no-repeat transparent; cursor: pointer; display: inline-block; margin-left: 5px; diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/socialmedia.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/socialmedia.less deleted file mode 100644 index 7712f000e3..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/socialmedia.less +++ /dev/null @@ -1,193 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -@import "params.less"; -@import "base.less"; -/* List Facebook UserInfo, List Twitter UserInfo */ -#sm_tbl_UserList { - border-collapse: collapse; - padding: 0px; - width: 100%; - - .sm_tbl_UserList_clmnAvatar { - width: 50px; - text-align: center; - padding: 5px 0; - } - - .sm_tbl_UserList_clmnUserName { - padding: 5px 0 5px 10px; - } - - .sm_tbl_UserList_clmnBtRelate { - width: 80px; - padding: 5px 5px 5px 10px; - } - - .sm_tbl_UserList_NotFound { - text-align: center; - margin: 10px; - } -} - - - - - -.sm_message_line { - border-top: 1px solid @border-color; - padding: 5px 0; -} -.sn_userName { - color: Black !important; -} -.sn_user_icon { - float: left; - margin: 0 15px; - width: 34px; -} -.sn_message_icon { - float: left; - text-align: center; - width: 30px; -} -.sn_message_block { - float: left; - width: 90%; -} -.sn_message_text { - margin: 2px 0; -} -.sn_small_img { - float: left; - margin-right: 10px; -} -.sm_messagesList_ErrorDescription { - margin-left: 0 !important; - margin-right: 0 !important; -} - - -/* ContactDetailsView - Window with user avatars*/ -#divLoadPhotoFromSocialMedia { - width: 100%; - height: 50px; - margin-top: -16px; -} -#divLoadPhotoWindow h4 { - margin-bottom: 5px; -} - -#divLoadPhotoFromPC { - .fileUploadDscr { - margin-left: 12px; - } - - .fileUploadError { - color: #CC0000; - display: none; - font: 12px Tahoma; - margin-left: 12px; - } -} - -#divImagesHolder { - width: 100%; - height: 70px; - overflow: auto; - display: none; - - > div.describe-text { - margin-top: 4px; - } -} - -#divLoadPhotoDefault { - margin-top: 10px; -} - -#divAjaxImageContainerPhotoLoad { - margin-left: 220px; - display: none; - position: absolute; - top: 185px; -} - -.ImageHolderOuter { - display: inline-block; - width: 54px; - height: 54px; - margin-right: 10px; - margin-bottom: 10px; - vertical-align: top; - cursor: pointer; - border: 1px solid @text-color; - - img { - padding: 2px; - - &:hover { - border: 2px solid #1A6DB3 !important; - padding: 0px; - } - } -} - -.AvatarImage { - width: 50px; - height: 50px; -} -/* ContactActionView */ - -#divSMProfilesWindow { - display: none; - width: 420px; - background-color: @defaultBgColor; - .borderRadius(10px); - - .cancel_cross { - background: url("../images/icons.png") 0 -718px no-repeat transparent; - cursor: pointer; - display: inline-block; - height: 16px; - right: -5px; - top: -5px; - width: 16px; - position: absolute; - } - .divNoProfiles { - display: none; - text-align: center; - vertical-align: middle; - } - .divWait { - text-align: center; - display: none; - } - .divHeader { - margin: 15px; - text-align: center; - position: relative; - } - - .divSMProfilesWindowBody { - margin: 10px; - max-height: 200px; - min-height: 30px; - overflow: auto; - } -} \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/tasks.less b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/tasks.less index 7defae4fa4..138288e65a 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/tasks.less +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/css/tasks.less @@ -90,7 +90,7 @@ taskStatusesMenu *******************************************************************************/ #taskStatusListContainer li .dropdown-item { - background-image: url("../images/icons.png"); + background-image: url("../images/@{icons-png}"); background-repeat: no-repeat; padding-left: 30px; } @@ -102,10 +102,10 @@ taskStatusesMenu } #taskTable .changeStatusCombobox .open, #taskTable .changeStatusCombobox .overdue { - background: url("../images/icons.png") 0 -518px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -518px no-repeat transparent; } #taskTable .changeStatusCombobox .closed { - background: url("../images/icons.png") 0 -536px no-repeat transparent; + background: url("../images/@{icons-png}") 0 -536px no-repeat transparent; } #taskTable { diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/empty_screen_twitter.svg b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/empty_screen_twitter.svg deleted file mode 100644 index c747c24e38..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/empty_screen_twitter.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/icons-dark.svg b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/icons-dark.svg new file mode 100644 index 0000000000..a454d78c6b --- /dev/null +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/icons-dark.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/product_logolarge_dark.svg b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/product_logolarge_dark.svg new file mode 100644 index 0000000000..a07acefc5b --- /dev/null +++ b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/product_logolarge_dark.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/twitter.png b/web/studio/ASC.Web.Studio/Products/CRM/App_Themes/default/images/twitter.png deleted file mode 100644 index 0fb7f615e77bbed34cd0674a9f91e1ceec4ccd67..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 606 zcmV-k0-^nhP)X~Ds4hLu!fY`1DApPjO}0AD)$?DY$3iQ(?zJT4fVR1p*>7B9l@6U`4#UE7Li zK9@!s2EKRqX@!DUOIOL$$a?pHnuXN-8`eOUSb}P9gDMRRPL#cV!SkhSEHAcrc`xV0 z3r@76ta#Px9svlVq#}wFgI7gjWND!Zz|GkP+r2(s6w!#ph-f5BELWNhf@)cy6v^O4 zQ7tPE(SCS`Nvv+{^7U7r`RRpMKTwLq(${@01OTL&1!nF~inz=@J27F*AF{O%j88@uOz zAG!cAC_F(F^XS9o)>J~CB?b!=q8tr8+lT#f0;>qsB*qvqQ8^tH3 SelectedUsers) { var ids = SelectedUsers != null && SelectedUsers.Count > 0 ? SelectedUsers.Select(i => i.Key).ToArray() : new List().ToArray(); @@ -233,8 +218,7 @@ public static void DataContactActionView(BasePage page, Contact targetContact, L var contactAvailableTypes = {4}; var presetCompanyForPersonJson = '{5}'; var presetPersonsForCompanyJson = '{6}'; - var twitterSearchEnabled = {7}; - var contactActionCurrencies = {8};", + var contactActionCurrencies = {7};", json, JsonConvert.SerializeObject(networks), JsonConvert.SerializeObject(tags.ToList().ConvertAll(t => t.HtmlEncode())), @@ -247,7 +231,6 @@ public static void DataContactActionView(BasePage page, Contact targetContact, L })), presetCompanyForPersonJson, presetPersonsForCompanyJson, - IsTwitterSearchEnabled.ToString().ToLower(), JsonConvert.SerializeObject(CurrencyProvider.GetAll()) ); diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaAccountNotFound.cs b/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaAccountNotFound.cs deleted file mode 100644 index 5a65f449d5..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaAccountNotFound.cs +++ /dev/null @@ -1,26 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; - -namespace ASC.Web.CRM.SocialMedia -{ - public class SocialMediaAccountNotFound : Exception - { - public SocialMediaAccountNotFound(string message) : base(message) { } - } -} diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaImageDescription.cs b/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaImageDescription.cs deleted file mode 100644 index d72c78bbab..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaImageDescription.cs +++ /dev/null @@ -1,33 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using ASC.Thrdparty; - -namespace ASC.Web.CRM.Classes.SocialMedia -{ - public class SocialMediaImageDescription - { - ///0 - public SocialNetworks SocialNetwork { get; set; } - - ///url to img - public string ImageUrl { get; set; } - - ///Identity - public string Identity { get; set; } - } -} diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaUI.cs b/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaUI.cs deleted file mode 100644 index b3147a8714..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/SocialMediaUI.cs +++ /dev/null @@ -1,154 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; - -using ASC.Common.Logging; -using ASC.Core; -using ASC.Core.Tenants; -using ASC.CRM.Core; -using ASC.CRM.Core.Dao; -using ASC.Thrdparty; -using ASC.Thrdparty.Twitter; -using ASC.Web.CRM.Classes.SocialMedia; -using ASC.Web.CRM.Resources; - - -namespace ASC.Web.CRM.SocialMedia -{ - public class SocialMediaUI - { - private readonly ILog _logger = LogManager.GetLogger("ASC"); - private DaoFactory DaoFactory { get; set; } - - public SocialMediaUI(DaoFactory factory) - { - DaoFactory = factory; - } - - public List GetContactSMImages(int contactID) - { - var contact = DaoFactory.ContactDao.GetByID(contactID); - - var images = new List(); - - - var socialNetworks = DaoFactory.ContactInfoDao.GetList(contact.ID, null, null, null); - - var twitterAccounts = socialNetworks.Where(sn => sn.InfoType == ContactInfoType.Twitter).Select(sn => sn.Data.Trim()).ToList(); - - Func, Tenant, List> dlgGetTwitterImageDescriptionList = GetTwitterImageDescriptionList; - - // Parallelizing - - var waitHandles = new List(); - - var currentTenant = CoreContext.TenantManager.GetCurrentTenant(); - - var arGetAvatarsFromTwitter = dlgGetTwitterImageDescriptionList.BeginInvoke(twitterAccounts, currentTenant, null, null); - waitHandles.Add(arGetAvatarsFromTwitter.AsyncWaitHandle); - - WaitHandle.WaitAll(waitHandles.ToArray()); - - images.AddRange(dlgGetTwitterImageDescriptionList.EndInvoke(arGetAvatarsFromTwitter)); - - return images; - } - - public List GetContactSMImages(List twitter) - { - var images = new List(); - - Func, Tenant, List> dlgGetTwitterImageDescriptionList = GetTwitterImageDescriptionList; - - // Parallelizing - - var waitHandles = new List(); - - var currentTenant = CoreContext.TenantManager.GetCurrentTenant(); - - var arGetAvatarsFromTwitter = dlgGetTwitterImageDescriptionList.BeginInvoke(twitter, currentTenant, null, null); - waitHandles.Add(arGetAvatarsFromTwitter.AsyncWaitHandle); - - WaitHandle.WaitAll(waitHandles.ToArray()); - - images.AddRange(dlgGetTwitterImageDescriptionList.EndInvoke(arGetAvatarsFromTwitter)); - - return images; - } - - private List GetTwitterImageDescriptionList(List twitterAccounts, Tenant tenant) - { - var images = new List(); - - if (twitterAccounts.Count == 0) - return images; - - try - { - CoreContext.TenantManager.SetCurrentTenant(tenant); - - var provider = new TwitterDataProvider(TwitterApiHelper.GetTwitterApiInfoForCurrentUser()); - - twitterAccounts = twitterAccounts.Distinct().ToList(); - images.AddRange(from twitterAccount in twitterAccounts - let imageUrl = provider.GetUrlOfUserImage(twitterAccount, TwitterDataProvider.ImageSize.Small) - where imageUrl != null - select new SocialMediaImageDescription - { - Identity = twitterAccount, - ImageUrl = imageUrl, - SocialNetwork = SocialNetworks.Twitter - }); - } - catch (Exception ex) - { - _logger.Error(ex); - } - - return images; - } - - public Exception ProcessError(Exception exception, string methodName) - { - if (exception is ConnectionFailureException) - return new Exception(CRMSocialMediaResource.ErrorTwitterConnectionFailure); - - if (exception is RateLimitException) - return new Exception(CRMSocialMediaResource.ErrorTwitterRateLimit); - - if (exception is ResourceNotFoundException) - return new Exception(CRMSocialMediaResource.ErrorTwitterAccountNotFound); - - if (exception is UnauthorizedException) - return new Exception(CRMSocialMediaResource.ErrorTwitterUnauthorized); - - if (exception is SocialMediaException) - return new Exception(CRMSocialMediaResource.ErrorInternalServer); - - if (exception is SocialMediaAccountNotFound) - return exception; - - var unknownErrorText = String.Format("{0} error: Unknown exception:", methodName); - _logger.Error(unknownErrorText, exception); - return new Exception(CRMSocialMediaResource.ErrorInternalServer); - } - } -} \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/TwitterApiHelper.cs b/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/TwitterApiHelper.cs deleted file mode 100644 index 410f6cb5d5..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Classes/SocialMedia/TwitterApiHelper.cs +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -using ASC.FederatedLogin.LoginProviders; -using ASC.Thrdparty.Twitter; - -namespace ASC.Web.CRM.Classes.SocialMedia -{ - public static class TwitterApiHelper - { - public static TwitterApiInfo GetTwitterApiInfoForCurrentUser() - { - TwitterApiInfo apiInfo = new TwitterApiInfo - { - ConsumerKey = TwitterLoginProvider.TwitterKey, - ConsumerSecret = TwitterLoginProvider.TwitterSecret - }; - - SetDefaultTokens(apiInfo); - - return apiInfo; - } - - private static void SetDefaultTokens(TwitterApiInfo apiInfo) - { - apiInfo.AccessToken = TwitterLoginProvider.TwitterDefaultAccessToken; - apiInfo.AccessTokenSecret = TwitterLoginProvider.TwitterAccessTokenSecret; - } - } -} diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Configuration/ProductEntryPoint.cs b/web/studio/ASC.Web.Studio/Products/CRM/Configuration/ProductEntryPoint.cs index ae3a88c94f..96d102101a 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Configuration/ProductEntryPoint.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Configuration/ProductEntryPoint.cs @@ -87,6 +87,7 @@ public override void Init() DisabledIconFileName = "product_disabled_logo.png", IconFileName = "product_logo.png", LargeIconFileName = "product_logolarge.svg", + LargeIconFileNameDark = "product_logolarge_dark.svg", DefaultSortOrder = 30, SubscriptionManager = new ProductSubscriptionManager(), SpaceUsageStatManager = new CRMSpaceUsageStatManager(), diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactActionView.ascx b/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactActionView.ascx index d19bd86ef5..dca7c43df1 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactActionView.ascx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactActionView.ascx @@ -329,7 +329,7 @@ @@ -394,21 +394,4 @@ <% } %> - - -
-
- - -
-
- -
-
- <%= CRMSocialMediaResource.PleaseWait%> -
-
- <%= UrlParameters.Type == "people" ? CRMSocialMediaResource.NoAccountsHasBeenFound : CRMSocialMediaResource.NoCompaniesHasBeenFound%> -
-
\ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactDetailsView.ascx b/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactDetailsView.ascx index 271d183af2..d1325cd9e3 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactDetailsView.ascx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactDetailsView.ascx @@ -109,32 +109,6 @@ - - <% if (CRMSecurity.CanEdit(TargetContact)) %> <% { %>
diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactDetailsView.ascx.cs b/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactDetailsView.ascx.cs index 6bc92d6b4b..c7afa08388 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactDetailsView.ascx.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactDetailsView.ascx.cs @@ -126,13 +126,12 @@ private void RegisterScript() var sb = new StringBuilder(); sb.AppendFormat(@" - ASC.CRM.ContactDetailsView.init({0},{1},{2},{3},{4},{5}); - {6}", + ASC.CRM.ContactDetailsView.init({0},{1},{2},{3},{4}); + {5}", TargetContact.ID, (TargetContact is Company).ToString().ToLower(), WebItemSecurity.IsAvailableForMe(WebItemManager.ProjectsProductID).ToString().ToLower(), - (!string.IsNullOrEmpty(TwitterLoginProvider.TwitterDefaultAccessToken)).ToString().ToLower(), (int)TargetContact.ShareType, CRMSecurity.CanEdit(TargetContact).ToString().ToLower(), ShowEventLinkToPanel ? "" : "jq('#eventLinkToPanel').hide();" diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactFullCardView.ascx b/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactFullCardView.ascx index 9c86b5ade3..2dda4093df 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactFullCardView.ascx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Controls/Contacts/ContactFullCardView.ascx @@ -28,7 +28,7 @@ <% if (CRMSecurity.CanEdit(TargetContact)) %> <% { %> diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Masters/BasicTemplate.Master.cs b/web/studio/ASC.Web.Studio/Products/CRM/Masters/BasicTemplate.Master.cs index e2db4d430e..cfc17997e6 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Masters/BasicTemplate.Master.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Masters/BasicTemplate.Master.cs @@ -83,7 +83,6 @@ public ScriptBundleData GetStaticJavaScript() "cases.js", "deals.js", "invoices.js", - "socialmedia.js", "sender.js", "reports.js") .AddSource(ResolveUrl, diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Masters/ClientScripts/CRMSettingsResources.cs b/web/studio/ASC.Web.Studio/Products/CRM/Masters/ClientScripts/CRMSettingsResources.cs index e4b64f11be..8595f85bfa 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Masters/ClientScripts/CRMSettingsResources.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Masters/ClientScripts/CRMSettingsResources.cs @@ -56,8 +56,7 @@ protected override IEnumerable> GetClientVariables( {"empty_screen_case_participants", WebImageSupplier.GetAbsoluteWebPath("empty_screen_case_participants.svg", ProductEntryPoint.ID)}, {"empty_screen_projects", WebImageSupplier.GetAbsoluteWebPath("empty_screen_projects.svg", ProductEntryPoint.ID)}, {"empty_screen_userfields", WebImageSupplier.GetAbsoluteWebPath("empty_screen_userfields.svg", ProductEntryPoint.ID)}, - {"empty_screen_tags", WebImageSupplier.GetAbsoluteWebPath("empty_screen_tags.svg", ProductEntryPoint.ID)}, - {"empty_screen_twitter", WebImageSupplier.GetAbsoluteWebPath("empty_screen_twitter.svg", ProductEntryPoint.ID)} + {"empty_screen_tags", WebImageSupplier.GetAbsoluteWebPath("empty_screen_tags.svg", ProductEntryPoint.ID)} }; return new List>(1) diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Masters/ClientScripts/ClientLocalizationResources.cs b/web/studio/ASC.Web.Studio/Products/CRM/Masters/ClientScripts/ClientLocalizationResources.cs index 213de6705f..355c7e03db 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Masters/ClientScripts/ClientLocalizationResources.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Masters/ClientScripts/ClientLocalizationResources.cs @@ -47,7 +47,6 @@ protected override IEnumerable> GetClientVariables( RegisterResourceSet("CRMCasesResource", CRMCasesResource.ResourceManager), RegisterResourceSet("CRMEnumResource", CRMEnumResource.ResourceManager), RegisterResourceSet("CRMSettingResource", CRMSettingResource.ResourceManager), - RegisterResourceSet("CRMSocialMediaResource", CRMSocialMediaResource.ResourceManager), RegisterResourceSet("CRMVoipResource", CRMVoipResource.ResourceManager), RegisterResourceSet("CRMReportResource", CRMReportResource.ResourceManager), RegisterObject(new @@ -95,7 +94,6 @@ protected override IEnumerable> GetClientVariables( CurrentUser = CustomNamingPeople.Substitute("CurrentUser").HtmlEncode(), PrivatePanelAccessListLable = CustomNamingPeople.Substitute("PrivatePanelAccessListLable").HtmlEncode(), PrivatePanelDescription = CustomNamingPeople.Substitute("PrivatePanelDescription").HtmlEncode(), - SocialMediaAccountNotFoundTwitter = CRMSocialMediaResource.SocialMediaAccountNotFoundTwitter.HtmlEncode(), DisabledEmployeeTitle = Resource.DisabledEmployeeTitle.HtmlEncode() }) }; diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.Designer.cs b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.Designer.cs index 81a4825e5e..d79028cf16 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.Designer.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.Designer.cs @@ -2130,15 +2130,6 @@ public static string NextSample { } } - /// - /// Looks up a localized string similar to No records. - /// - public static string NoLoadedMessages { - get { - return ResourceManager.GetString("NoLoadedMessages", resourceCulture); - } - } - /// /// Looks up a localized string similar to No mail accounts available. /// diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ar-AE.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ar-AE.resx index 6ae50f4af3..9f69a5378c 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ar-AE.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ar-AE.resx @@ -370,9 +370,6 @@ السجل التالي - - لا توجد سجلات - لا يوجد تطابق diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.az-Latn-AZ.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.az-Latn-AZ.resx index 7aa0f397ad..16bbe75a96 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.az-Latn-AZ.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.az-Latn-AZ.resx @@ -742,9 +742,6 @@ Sonrakı qeyd - - Qeyd yoxdur - Poçt hesabı mövcud deyil diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.bg.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.bg.resx index 54c9252480..24bc326dce 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.bg.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.bg.resx @@ -478,9 +478,6 @@ Следващ запис - - Няма записи - Няма налични пощенски акаунти diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.bs-BA.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.bs-BA.resx index d02703caad..c4dca14af0 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.bs-BA.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.bs-BA.resx @@ -478,9 +478,6 @@ Slijedeći zapis - - Nema zapisa - Nisu dostupni računi pošte diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ca.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ca.resx index da728930e6..f83d398811 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ca.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ca.resx @@ -373,9 +373,6 @@ Següent - - No hi ha registres - No hi ha cap coincidència diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.cs.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.cs.resx index f161887e56..8d8a3824a0 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.cs.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.cs.resx @@ -469,9 +469,6 @@ Další záznam - - Žádné záznamy - Žádné poštovní účty nejsou k dispozici diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.de.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.de.resx index 1084e80128..0525c67c8c 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.de.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.de.resx @@ -526,9 +526,6 @@ Nächster Eintrag - - Keine Einträge - Keine verfügbaren Konten diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.el.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.el.resx index 10364d8929..49c1f0e870 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.el.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.el.resx @@ -283,9 +283,6 @@ Τα συμβάντα μου - - Καμία εγγραφή - Ειδοποίηση diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.es.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.es.resx index 885965c8e4..ff879e5131 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.es.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.es.resx @@ -526,9 +526,6 @@ Apunte próximo - - No hay apuntes - No hay cuentas disponibles diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.et.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.et.resx index 51e3a0f542..3e7b044f9b 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.et.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.et.resx @@ -289,9 +289,6 @@ Järgmine kirje - - Kirjeid pole - vastet ei leitud diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.fi.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.fi.resx index beea66ff6d..8e51188630 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.fi.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.fi.resx @@ -457,9 +457,6 @@ Seuraava tietue - - Ei tietueita - Ei sähköpostitilejä. diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.fr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.fr.resx index 465c553078..0f8d84c981 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.fr.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.fr.resx @@ -526,9 +526,6 @@ Suivant - - Aucun enregistrement - Pas de comptes disponibles diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.hr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.hr.resx index 6e1cf21e15..6cecc4d83b 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.hr.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.hr.resx @@ -328,9 +328,6 @@ Sljedeći zapis - - Nema zapisa - Nema podudaranja diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.id.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.id.resx index 85061c2d9c..cd9a5d8258 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.id.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.id.resx @@ -448,9 +448,6 @@ Rekaman berikutnya - - Tidak ada rekaman - Tidak tersedia akun surat diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.it.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.it.resx index 5f7ea30af9..359d6768bb 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.it.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.it.resx @@ -526,9 +526,6 @@ Registrazione successiva - - Nessuna registrazione - Nessun account disponibile diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ja.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ja.resx index e29a626bcf..55472e71e3 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ja.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ja.resx @@ -449,9 +449,6 @@ 次のレコード - - レコードなしません - 利用可能なメールアカウントはありません diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ka.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ka.resx index 95a3c76d6c..d604911b96 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ka.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ka.resx @@ -199,9 +199,6 @@ შემდეგი ჩანაწერი - - ჩანაწერები არ არის - დამთხვევები არ არის diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ko.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ko.resx index ec9a3be30e..51cc7f3c24 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ko.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ko.resx @@ -370,9 +370,6 @@ 다음 레코드 - - 레코드 없음 - 일치 하는 항목 없음 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.lt.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.lt.resx index 4de7782b9c..f8547a724c 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.lt.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.lt.resx @@ -460,9 +460,6 @@ Kitas įrašas - - Nėra įrašų - Nėra elektroninio pašto paskyrų diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.lv.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.lv.resx index 7decdd8953..5541353dc4 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.lv.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.lv.resx @@ -469,9 +469,6 @@ Nākamais ieraksts - - Nav ierakstu - Nav pieejami pasta konti diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.nb-NO.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.nb-NO.resx index 0549434eb7..8d92cc3a68 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.nb-NO.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.nb-NO.resx @@ -325,9 +325,6 @@ Neste - - Ingen elementer - Ingen treff diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.nl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.nl.resx index 09b0bb908e..33228687d5 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.nl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.nl.resx @@ -460,9 +460,6 @@ Volgende record - - Geen records - Geen mailaccounts beschikbaar diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pl.resx index ea89a97c56..f0595d9845 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pl.resx @@ -471,9 +471,6 @@ Następny wpis - - Wpisów nie ma - Brak dostępnych kont pocztowych diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pt-BR.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pt-BR.resx index 44aa353436..7590916ed9 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pt-BR.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pt-BR.resx @@ -528,9 +528,6 @@ Próximo regristro - - Nenum registro - Nenhuma conta de e-mail disponível diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pt.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pt.resx index 3c5d5f5cae..88e875653b 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pt.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.pt.resx @@ -361,9 +361,6 @@ Próximo registo - - Não há registos - Sem correspondência diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.resx index 149c82bc11..4352fbce8a 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.resx @@ -739,9 +739,6 @@ Next record - - No records - No mail accounts available diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ru.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ru.resx index 0ebde378ea..3c46540b6f 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ru.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.ru.resx @@ -526,9 +526,6 @@ Следующая запись - - Записей нет - Нет доступных учетных записей diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sk.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sk.resx index 6988e7478e..4b9aa46fd8 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sk.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sk.resx @@ -548,9 +548,6 @@ Ďalší záznam - - Žiadne záznamy - Nie sú k dispozícii žiadne poštové účty diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sl.resx index 0881f19efd..cd987dd54f 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sl.resx @@ -448,9 +448,6 @@ Naslednji zapis - - Ni zapisov - Na voljo ni noben mail račun diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sr-Latn-CS.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sr-Latn-CS.resx index e1fc76b23c..a0dcb24fd0 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sr-Latn-CS.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sr-Latn-CS.resx @@ -313,9 +313,6 @@ Sledeći zapis - - Nema zapisa - Nema podudaranja diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sv.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sv.resx index b67f187687..30e5d55d41 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sv.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.sv.resx @@ -478,9 +478,6 @@ Nästa register - - Inga register - Inga mejlkonto tillgängliga diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.tr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.tr.resx index 4ee5d64a5f..bb6f93d8fa 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.tr.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.tr.resx @@ -469,9 +469,6 @@ Sonraki kayıt - - Kayıt yok - Mevcut posta hesabı yok diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.uk.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.uk.resx index d3e194b97b..ed9c4cae37 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.uk.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.uk.resx @@ -461,9 +461,6 @@ Наступний запис - - Записів немає - Немає доступних облікових записів електронної пошти diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.vi.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.vi.resx index ba40419bbd..7bfed841b0 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.vi.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.vi.resx @@ -470,9 +470,6 @@ Hồ sơ tiếp theo - - Không có hồ sơ - Không có tài khoản mail khả dụng diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.zh-CN.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.zh-CN.resx index 6723f9e29b..1b943641df 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.zh-CN.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.zh-CN.resx @@ -478,9 +478,6 @@ 下一条纪录 - - 暂无纪录 - 无可用邮件账户 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.zh-TW.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.zh-TW.resx index 3ead280705..09d35b9d62 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.zh-TW.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMCommonResource.zh-TW.resx @@ -527,9 +527,6 @@ 下一則紀錄 - - 沒有記錄 - 沒有可用的郵件帳戶 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.Designer.cs b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.Designer.cs index 5a6cef1052..d75339de48 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.Designer.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.Designer.cs @@ -1171,15 +1171,6 @@ public static string LoadPhotoFromPC { } } - /// - /// Looks up a localized string similar to Select from social networks. - /// - public static string LoadPhotoFromSocialMedia { - get { - return ResourceManager.GetString("LoadPhotoFromSocialMedia", resourceCulture); - } - } - /// /// Looks up a localized string similar to Allow access to the company for all CRM users. /// @@ -1342,15 +1333,6 @@ public static string NoMatchSelect { } } - /// - /// Looks up a localized string similar to There are no available photos corresponding to the profile. - /// - public static string NoPhotoFromSocialMedia { - get { - return ResourceManager.GetString("NoPhotoFromSocialMedia", resourceCulture); - } - } - /// /// Looks up a localized string similar to Notify contact manager by email. /// diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.az-Latn-AZ.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.az-Latn-AZ.resx index 7cd8cd3b8e..7075948c68 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.az-Latn-AZ.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.az-Latn-AZ.resx @@ -431,9 +431,6 @@ Siz etiketi bu şirkətdən və onunla əlaqəli bütün şəxslərdən silmək Kompüterdən fotoşəkil yüklə - - və ya sosial şəbəkələrdən seçin: - Bütün CRM istifadəçiləri üçün şirkətə giriş icazəsi verin @@ -488,9 +485,6 @@ Siz etiketi bu şirkətdən və onunla əlaqəli bütün şəxslərdən silmək ONLYOFFICE™ CRM ilə üst-üstə düşən heç nə yoxdur, siyahıdan seçim edin - - Bu profilə uyğun fotolar yoxdur. - Kontakt menecerini e-poçt vasitəsilə xəbərdar edin diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.bg.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.bg.resx index fe28b37961..b97dd1a7e6 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.bg.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.bg.resx @@ -427,9 +427,6 @@ Качване на снимка от компютър - - Изберете от социалните мрежи - Разрешаване на достъпа до компанията за всички CRM потребители @@ -484,9 +481,6 @@ Няма съвпадения в ONLYOFFICE™ CRM, изберете от списъка - - Няма налични снимки, съответстващи на профила - Уведомете мениджъра на контактите по имейл diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.bs-BA.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.bs-BA.resx index 676a265295..3b25971cc7 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.bs-BA.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.bs-BA.resx @@ -431,9 +431,6 @@ Pošaljite fotografiju sa računara - - Odaberite s društvenih mreža - Omogućite pristup kompaniji svim CRM korisnicima @@ -488,9 +485,6 @@ Nema podudaranja u CRM, odaberite s popisa - - Nema dostupnih fotografija koje odgovaraju profilu - Obavijestite menadžera kontakata putem e-pošte diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.cs.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.cs.resx index 9ca492d8e2..bc95ac89bc 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.cs.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.cs.resx @@ -434,9 +434,6 @@ Chcete tuto značku smazat také od společnosti a od všech jejích osob? Nahrát foto z Počítače - - Vyberte ze sociálních sítí - Povolit přístup ke společnosti pro všechny uživatele CRM @@ -492,9 +489,6 @@ Chcete tuto značku smazat také od společnosti a od všech jejích osob? V ONLYOFFICE™ CRM nejsou žádné shody, vyberte ze seznamu - - Nejsou k dispozici žádné fotky odpovídající profilu - Upozorněte správce kontaktů e-mailem diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.de.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.de.resx index a63df509c3..e45cad98f8 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.de.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.de.resx @@ -429,9 +429,6 @@ Möchten Sie dieses Tag auch aus dem Unternehmen und allen darauf bezogenen Pers Foto vom PC hochladen - - Aus den sozialen Netzwerken wählen - Den Zugriff auf das Unternehmen für alle CRM-Benutzer erteilen @@ -486,9 +483,6 @@ Möchten Sie dieses Tag auch aus dem Unternehmen und allen darauf bezogenen Pers Keine Treffer in ONLYOFFICE™-CRM. Wählen Sie aus der Liste - - Keine verfügbaren Bilder, die diesem Profil entsprechen - den Kontaktleiter per E-Mail benachrichtigen diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.es.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.es.resx index cf956117f7..59ac968cea 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.es.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.es.resx @@ -431,9 +431,6 @@ Subir fotos de la PC - - Seleccione de las redes sociales - Permitir a todos los usuarios de CRM el acceso a la empresa @@ -488,9 +485,6 @@ No hay coincidencias en ONLYOFFICE™ CRM, seleccione de la lista - - No hay fotos disponibles que corresponden al perfil - Notificar gerente de contacto por correo electrónico diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.fi.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.fi.resx index d187a2e7f2..5ee5fe307b 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.fi.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.fi.resx @@ -427,9 +427,6 @@ Lisää valokuva tietokoneelta - - Valitse sosiaalisista palveluista - Salli Pääsyoikeudet yritykseen kaikille Asiakkuudenhallinnan käyttäjille @@ -484,9 +481,6 @@ Ei vastaavia tuloksia ONLYOFFICE™ Asiakkuudenhallinnassa, valitse luettelosta - - Ei käytettävissä olevia valokuvia tälle profiilille. - Ilmoita kontaktin hallintaan sähköpostilla. diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.fr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.fr.resx index cdadefec8f..2e6abfad33 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.fr.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.fr.resx @@ -431,9 +431,6 @@ Voulez-vous aussi supprimer ce tag de cette entreprise et toutes ses personnes l Chargez la photo à partir de l'ordinateur - - Choisissez parmi les réseaux sociaux - Autoriser l'accès à l'entreprise à tous les utilisateurs @@ -488,9 +485,6 @@ Voulez-vous aussi supprimer ce tag de cette entreprise et toutes ses personnes l Rien n'a été trouvé pour CRM ONLYOFFICE™, sélectionnez dans la liste - - Pas de photos disponibles qui correspondent à ce profil - Informer le responsable du contact par courrier électronique diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.id.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.id.resx index 20182c3105..88d3e1972d 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.id.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.id.resx @@ -425,9 +425,6 @@ Apakah Anda juga ingin menghapus tag ini dari perusahaan tersebut dan semua oran Unggah foto dari komputer PC - - Pilih dari jejaring sosial - Ijinkan akses ke perusahaan untuk semua pengguna CRM @@ -482,9 +479,6 @@ Apakah Anda juga ingin menghapus tag ini dari perusahaan tersebut dan semua oran Tidak ditemukan dalam ONLYOFFICE™ CRM, pilihlah dari daftar - - Tidak ada foto yang sesuai dengan profil - Beritahukan pengelola kontak melalui email diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.it.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.it.resx index 0bdc5be464..86315c32e6 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.it.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.it.resx @@ -431,9 +431,6 @@ Desideri eliminare questa etichetta anche dall'azienda e dalle sue persone? Carica foto dal PC - - Seleziona una dalle reti sociali: - Consenti l'accesso a questa azienda a tutti gli utenti di CRM @@ -488,9 +485,6 @@ Desideri eliminare questa etichetta anche dall'azienda e dalle sue persone? Nessuna corrispondenza con ONLYOFFICE™ CRM, seleziona dall'elenco - - Nessuna foto disponibile corrispondente a questo profilo - Notifica il responsabile per email diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ja.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ja.resx index 965cab2193..d1e743982d 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ja.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ja.resx @@ -345,9 +345,6 @@ PCから写真をアップロード - - またはソーシャルネットワークから選択します。 - すでに送信 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ka.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ka.resx index 126baeb012..abfbbc3b9f 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ka.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ka.resx @@ -235,9 +235,6 @@ სურათის კომპიუტერიდან ატვირთვა - - ან აირჩიეთ სოციალური ქსელიდან - ეს ასლია diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ko.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ko.resx index 2b09a431ce..aa753102c6 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ko.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ko.resx @@ -334,9 +334,6 @@ PC에서 사진을 업로드 - - 또는 소셜 네트워크에서 선택 : - 이미 전송 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.lt.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.lt.resx index 3b709a3507..3a07bcdd80 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.lt.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.lt.resx @@ -431,9 +431,6 @@ Ar norite šią žymą taip pat panaikinti nuo bendrovės ir kitų jos asmenų?< Įkelti nuotrauką iš kompiuterio - - Pasirinkite iš socialinių tinklų: - Suteikti prieigą prie bendrovės visiems CRM naudotojams @@ -488,9 +485,6 @@ Ar norite šią žymą taip pat panaikinti nuo bendrovės ir kitų jos asmenų?< Nėra atitikmenų ONLYOFFICE™ CRM. Pasirinkite iš sąrašo. - - Nėra šiam profiliui nurodytų paveikslėlių - Informuoti kontakto vadovą el.paštu diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.lv.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.lv.resx index 8b3c358ea5..50bd5c5d75 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.lv.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.lv.resx @@ -431,9 +431,6 @@ Vai vēlaties dzēst šo birku arī no uzņēmuma un visām tā personām? Augšupielādēt foto no datora - - Izvēlēties no sociālajiem tīkliem - Atļaut piekļuvi uzņēmumam visiem CRM lietotājiem @@ -488,9 +485,6 @@ Vai vēlaties dzēst šo birku arī no uzņēmuma un visām tā personām? Nav atbilstības ONLYOFFICE™ CRM, izvēlieties no saraksta - - Nav pieejamu foto, kas atbilstu profilam - Paziņot kontaktu pārvaldniekam pa e-pastu diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.nl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.nl.resx index 13ac069e46..dcb15892f7 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.nl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.nl.resx @@ -431,9 +431,6 @@ Wilt u deze tag ook van het bedrijf en al zijn personen verwijderen? Foto van PC uploaden - - Selecteer uit sociale netwerken - Toegang toestaan tot het bedrijf voor alle CRM-gebruikers @@ -488,9 +485,6 @@ Wilt u deze tag ook van het bedrijf en al zijn personen verwijderen? Geen overeenkomsten in ONLYOFFICE™ CRM, selecteer uit lijst - - Er zijn geen beschikbare foto's die overeenkomen met het profiel - Contactmanager informeren per e-mail diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pl.resx index 0da7b7e82c..9798c57d22 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pl.resx @@ -432,9 +432,6 @@ Czy chcesz usunąć ten tag również ze spółki i ze wszystkich jej osób? Załaduj zdjęcie z komputera - - Wybierz z sieci społecznościowych - Zezwalaj na dostęp do firmy wszystkim użytkownikom CRM @@ -489,9 +486,6 @@ Czy chcesz usunąć ten tag również ze spółki i ze wszystkich jej osób? Brak dopasowań z ONLYOFFICE™ CRM, wybierz z listy - - Brak zdjęć odpowiadających profilowi - Powiadom menedżera kontaktów e-mailem diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pt-BR.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pt-BR.resx index cbb8a88fce..21421c54b6 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pt-BR.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pt-BR.resx @@ -432,9 +432,6 @@ Você deseja excluir esta etiqueta também da empresa e de todas as suas pessoas Carregar foto do PC - - Selecionar a partir das redes sociais - Permitir acesso à empresa para todos os usuários do CRM @@ -489,9 +486,6 @@ Você deseja excluir esta etiqueta também da empresa e de todas as suas pessoas Nenhuma correspondência no CRM do ONLYOFFICE™, selecione da lista - - Não há fotos disponíveis correspondentes ao perfil - Notificar gerente de contato por e-mail diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pt.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pt.resx index e600ad18a8..abc14ded01 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pt.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.pt.resx @@ -334,9 +334,6 @@ Carregar foto do PC - - ou selecione das redes sociais: - Já enviado diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.resx index 7e27ee569f..e00508d635 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.resx @@ -431,9 +431,6 @@ Do you want to delete this tag also from the company and from all its persons? Upload photo from PC - - Select from social networks - Allow access to the company for all CRM users @@ -488,9 +485,6 @@ Do you want to delete this tag also from the company and from all its persons? No matches in ONLYOFFICE™ CRM, select from list - - There are no available photos corresponding to the profile - Notify contact manager by email diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ru.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ru.resx index d18934d9c8..6d12eb69c0 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ru.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.ru.resx @@ -431,9 +431,6 @@ Загрузить фото с компьютера - - Выбрать из социальных сетей - Разрешить доступ к компании для всех пользователей CRM @@ -488,9 +485,6 @@ Совпадений с ONLYOFFICE™ CRM нет, выберите из списка - - Нет доступных фотографий, соответствующих этому профилю - Оповестить менеджера контакта по email diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sk.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sk.resx index 35d295f64f..e776679b9d 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sk.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sk.resx @@ -562,11 +562,6 @@ Nahrať fotografiu z počítača - - Vybrať zo sociálnych sietí - - - Umožniť prístup k spoločnosti všetkým používateľom CRM @@ -650,11 +645,6 @@ Žiadne zhody v ONLYOFFICE™ CRM, vyberte zo zoznamu - - - - Nie sú k dispozícii žiadne fotografie zodpovedajúce profilu - diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sl.resx index 6517cf586b..4cb3125cbe 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sl.resx @@ -425,9 +425,6 @@ Ali želite izbrisati to oznako tudi pri podjetju in vseh osebah? Naloži sliko iz PC-ja - - Izberi iz družbenih omrežij - Dovoli dostop k podjetju za vse CRM uporabnike @@ -482,9 +479,6 @@ Ali želite izbrisati to oznako tudi pri podjetju in vseh osebah? Ni ujemanj v ONLYOFFICE™ CRM, izberite s seznama - - Slik, ki ustrezajo tem profilu, ni na voljo - Vodjo kontakta obvesti preko emaila diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sv.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sv.resx index b46d38f920..6d8c6685e4 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sv.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.sv.resx @@ -431,9 +431,6 @@ Vill du radera denna etikett även från företaget och från alla dess personer Ladda upp bild från PC - - Välj från sociala nätverk - Tillåta tillgång till företaget för alla CRM-användare @@ -488,9 +485,6 @@ Vill du radera denna etikett även från företaget och från alla dess personer Inga matchningar i ONLYOFFICE™ CRM, välj från listan - - Inga tillgängliga bilder matchar profilen - Avisera kontaktansvarig via mejl diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.tr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.tr.resx index ce3e7aea7f..dcce2a99cc 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.tr.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.tr.resx @@ -431,9 +431,6 @@ Bu etiketi şirketten ve tüm kişilerinden silmek istiyor musunuz? PC'den fotoğraf yükle - - Sosyal ağlardan seç - Tüm CRM kullanıcıları için şirkete erişime izin ver @@ -488,9 +485,6 @@ Bu etiketi şirketten ve tüm kişilerinden silmek istiyor musunuz? ONLYOFFICE™ CRM'de eşleşme yok, listeden seçiniz - - Profille eşleşen mevcut resim yok - Kontak yöneticisini epostayla haberdar et diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.uk.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.uk.resx index 719c037f66..54937e6a23 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.uk.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.uk.resx @@ -467,9 +467,6 @@ Завантажити фото з ​​комп'ютера - - Виберіть з соціальних мереж: - Дозволити доступ до компанії для всіх користувачів CRM @@ -531,9 +528,6 @@ Співпадінь з ONLYOFFICE™ CRM немає, виберіть зі списку - - Немає доступних фотографій, що відповідають профілю - Повідомити диспетчера контактів електронною поштою diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.vi.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.vi.resx index 8a19c21292..353a868471 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.vi.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.vi.resx @@ -427,9 +427,6 @@ Tải ảnh từ PC - - Chọn từ mạng xã hội - Cho phép tất cả người dùng CRM truy cập vào công ty này @@ -484,9 +481,6 @@ Không khớp trong ONLYOFFICE™ CRM, chọn từ danh sách - - Không có ảnh tương ứng với hồ sơ này - Thông báo cho quản lý liên hệ qua email diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.zh-CN.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.zh-CN.resx index dec6994323..d54e7dca95 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.zh-CN.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.zh-CN.resx @@ -434,9 +434,6 @@ 从电脑上传图片 - - 或从社交网中选择: - 允许所有CRM用户访问公司 @@ -491,9 +488,6 @@ 在ONLYOFFICE™中找不到与此项对应的联系人格式,请从列表中选择 - - 没有与档案对应的可用照片 - 通过电子邮件通知联系人经理 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.zh-TW.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.zh-TW.resx index a21036a9c2..c81308fab0 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.zh-TW.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMContactResource.zh-TW.resx @@ -433,9 +433,6 @@ 從PC上傳照片 - - 從社交網絡中選擇 - 允許所有CRM用戶存取公司 @@ -490,9 +487,6 @@ 在ONLYOFFICE™CRM中沒有匹配項,請從列表中選擇 - - 沒有與該個人資料相對應的照片 - 通過電子郵件通知聯繫人經理 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.Designer.cs b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.Designer.cs index 7f460a749e..37637464af 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.Designer.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.Designer.cs @@ -331,15 +331,6 @@ public static string ConfirmGoToCustomFieldPage { } } - /// - /// Looks up a localized string similar to Please enter the name of your Twitter account. For example, teamlabdotcom. - /// - public static string ContactTwitterDescription { - get { - return ResourceManager.GetString("ContactTwitterDescription", resourceCulture); - } - } - /// /// Looks up a localized string similar to Country. /// @@ -736,15 +727,6 @@ public static string ExpectedCloseDate { } } - /// - /// Looks up a localized string similar to Find account in Twitter. - /// - public static string FindTwitter { - get { - return ResourceManager.GetString("FindTwitter", resourceCulture); - } - } - /// /// Looks up a localized string similar to Your recipient list has been generated. {0} Click the links below to pass your email addresses over to the email program.. /// @@ -1087,15 +1069,6 @@ public static string PleaseWait { } } - /// - /// Looks up a localized string similar to Possible profiles for {0}. - /// - public static string PossibleSocialMediaAccounts { - get { - return ResourceManager.GetString("PossibleSocialMediaAccounts", resourceCulture); - } - } - /// /// Looks up a localized string similar to Previous. /// diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ar-AE.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ar-AE.resx index e269d939cc..9cdf8b8211 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ar-AE.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ar-AE.resx @@ -140,9 +140,6 @@ جميع البيانات المدخله سيتم فقدها. هل انت متأكد من انك تريد الإكمال على ايه حال؟ - - الرجاء ادخال اسم المستخدم الخاص بك على تويتر - فرصه @@ -248,9 +245,6 @@ الموعد النهائي المتوقع لإتمام الصفقه - - ابحث عن الحساب في تويتر - تم انشاء قائمه المستلمين. {0} اضغط الرابط ادناه لترحيل عناوين المستلمين الى برنامج البريد. @@ -353,9 +347,6 @@ الرجاء اعاده تحميل هذه الصفحه - - ملفات شخصيه متوقعه لـ {0} - رئيسي diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.az-Latn-AZ.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.az-Latn-AZ.resx index d8f24ce48d..ece0d09707 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.az-Latn-AZ.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.az-Latn-AZ.resx @@ -149,9 +149,6 @@ Bütün daxil edilmiş məlumat itiriləcək. Siz istənilən halda davam etmək istədiyinizə əminsiniz mi? - - Twitter hesabınızın adını daxil edin. Örnək olaraq, teamlabdotcom - Ölkə @@ -281,9 +278,6 @@ Siz istənilən halda davam etmək istədiyinizə əminsiniz mi? Təxmini qapadılma tarixi - - Twitter'də hesabı tap - Alıcıların siyahısı yaradıldı.{0}Aşağıdakı keçidlərə basın ki, elektron poçt ünvanlarını elektron poçt proqramına keçirəsiniz. @@ -398,9 +392,6 @@ Siz istənilən halda davam etmək istədiyinizə əminsiniz mi? Gözləyin... - - {0} üçün mümkün profillər - Əvvəlki diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.bg.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.bg.resx index dc4f0fc757..274fd987bc 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.bg.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.bg.resx @@ -148,9 +148,6 @@ Всички въведени данни ще бъдат загубени. Наистина ли искате да продължите? - - Моля, въведете името на профила си в Twitter. Например, teamlabdotcom - Държава @@ -280,9 +277,6 @@ Приблизителна дата на сделката - - Намерете профил в Twitter - Списъкът с получатели е генериран. {0} Кликнете върху връзките по-долу, за да препратите имейл адресите си към програмата за електронна поща. @@ -394,9 +388,6 @@ Моля Изчакай... - - Възможни профили за {0} - Предишен diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.bs-BA.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.bs-BA.resx index 43ebb313e9..6e77feb72e 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.bs-BA.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.bs-BA.resx @@ -149,9 +149,6 @@ Sve unesene informacije će biti izgubljene. Jeste li sigurni da ionako želite nastaviti? - - Unesite ime svog Twitter naloga. Na primjer, teamlabdotcom - Država @@ -281,9 +278,6 @@ Jeste li sigurni da ionako želite nastaviti? Procenjeni rok dospijeća posla - - Pronađi račun na Twitteru - Lista primatelja je generirana. {0} Kliknite dole navedene veze kako biste proslijedili adrese e-pošte programu e-pošte. @@ -395,9 +389,6 @@ Jeste li sigurni da ionako želite nastaviti? Molimo sačekajte... - - Mogući profili za {0} - Prethodno diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.cs.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.cs.resx index 258347d88c..68bba5bcf0 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.cs.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.cs.resx @@ -149,9 +149,6 @@ Všechny zadané informace budou ztraceny. Opravdu chcete pokračovat? - - Zadejte název účtu Twitter. Například teamlabdotcom - země @@ -282,9 +279,6 @@ Opravdu chcete pokračovat? Předpokládaný termín realizace - - Najít účet na Twitteru - Seznam příjemců byl vygenerován. {0} Klepnutím na níže uvedené odkazy předáte e-mailové adresy do e-mailového programu. @@ -398,9 +392,6 @@ Opravdu chcete pokračovat? Čekejte prosím ... - - Možné profily pro {0} - Předchozí diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.de.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.de.resx index d277288ee3..6296463fa3 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.de.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.de.resx @@ -149,9 +149,6 @@ Alle eingegebenen Daten werden verloren gehen. Möchten Sie wirklich trotzdem fortsetzen? - - Bitte geben Sie den Namen Ihres Twitter-Kontos ein. Zum Beispiel, teamlabdotcom - Land @@ -281,9 +278,6 @@ Möchten Sie wirklich trotzdem fortsetzen? Geschätzte Fälligkeit der Verkaufschance - - Twitter-Konto finden - Ihre Empfängerliste wurde erstellt. {0}Klicken Sie auf die Links unten, um Ihre E-Mail-Adressen ins E-Mail-Programm zu richten. @@ -398,9 +392,6 @@ Möchten Sie wirklich trotzdem fortsetzen? Bitte warten... - - Mögliche Profile für {0} - Zurück diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.es.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.es.resx index bb04f83c3b..f6b5c2df7b 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.es.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.es.resx @@ -149,9 +149,6 @@ Toda la información introducida se perderá. ¿Está seguro(a) de que quiere continuar? - - Por favor, introduzca el nombre de su cuenta de Twitter. Por ejemplo, teamlabdotcom - País @@ -283,9 +280,6 @@ Fecha limite de acuerdo estimada - - Buscar cuenta de Twitter - La lista de destinatarios se ha generado. {0} Haga clic en los enlaces siguientes para pasar las direcciones de email para al programa de correo electrónico. @@ -400,9 +394,6 @@ Espere, por favor... - - Perfiles posibles para{0} - Anterior diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.fi.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.fi.resx index 12bb1c7005..462059a8be 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.fi.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.fi.resx @@ -149,9 +149,6 @@ Kaikki syötetyt tiedot menetetään. Oletko varma että haluat jatkaa? - - Anna Twitter tilisi nimi. - Nykyinen kuukausi @@ -278,9 +275,6 @@ Oletko varma että haluat jatkaa? Arvioitu sopimuksen määräpäivä - - Etsi Twitter-tili - Vastaanottajaluettelo on luotu. {0}Klikkaa allaolevia linkkejä siirtääksesi osoitteet sähköpostiohjelmaan. @@ -392,9 +386,6 @@ Oletko varma että haluat jatkaa? Ole hyvä ja odota... - - Mahdolliset profiilit - Edellinen diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.fr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.fr.resx index 33d3d5831a..6b878fe919 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.fr.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.fr.resx @@ -149,9 +149,6 @@ Toute information saisie sera perdue. Continuer ? - - Veuillez entrer le nom de votre compte Twitter. Par exemple, teamlabdotcom - pays @@ -281,9 +278,6 @@ Continuer ? Date limite supposée - - Trouver le compte dans Twitter - Votre liste des destinataires a été générée. {0} Cliquez sur les liens ci-dessous pour passer vos adresses email dans le programme de messagerie. @@ -398,9 +392,6 @@ Continuer ? Veuillez patienter... - - Les profils possibles pour {0} - Précédent diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.id.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.id.resx index 5ff10b7a90..ffa480b2e1 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.id.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.id.resx @@ -145,9 +145,6 @@ Semua informasi yang dimasukkan akan hilang. Apakah Anda yakin ingin melanjutkan? - - Silakan masukkan nama akun Twitter Anda. Sebagai contoh, teamlabdotcom - Kesempatan @@ -262,9 +259,6 @@ Perkiraan kesepakatan tanggal jatuh tempo - - Temukan akun di Twitter - Daftar penerima Anda telah dihasilkan. {0} Klik tautan di bawah untuk melewati alamat email Anda ke program email. @@ -376,9 +370,6 @@ Silakan tunggu... - - Kemungkinan profil untuk {0} - Sebelumnya diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.it.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.it.resx index 5f9b376e0f..23d834d091 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.it.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.it.resx @@ -149,9 +149,6 @@ Tutte le informazioni inserite saranno perse. Continuare comunque? - - Inserisci il nome del tuo account Twitter. Per esempio, teamlabdotcom - Paese @@ -281,9 +278,6 @@ Continuare comunque? Scadenza stimata - - Cerca account in Twitter - E' stato generato l'elenco dei destinatari.{0}Clicca sui collegamenti qui sotto per far passare gl indirizzi email nel programa di posta elettronica. @@ -398,9 +392,6 @@ Continuare comunque? Per favore, attendi... - - Profili possibili per {0} - Precedente diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ja.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ja.resx index 81cda4370e..04d6701b1f 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ja.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ja.resx @@ -140,9 +140,6 @@ 入力したすべての情報は失われます。 あなたは、このまま続行してもよろしいですか? - - あなたのTwitterアカウントの名前を入力してください。たとえば、teamlabdotcom - 機会 @@ -248,9 +245,6 @@ 推定契約期日 - - Twitterでアカウントを検索 - あなたの受信者リストが生成されました。 {0}はあなたの電子メールは電子メールプログラムに引き継がアドレス渡すには、以下のリンクをクリックしてください。 @@ -353,9 +347,6 @@ ページを再読み込みしてください - - のための可能なプロファイル{0} - プライマリー diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ka.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ka.resx index 8ea4fa66e0..8890a4919b 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ka.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ka.resx @@ -91,9 +91,6 @@ დარწმუნებული ხართ, რომ გსურთ ამ დავალების წაშლა? - - შეიყვანეთ თქვენი Twitter ანგარიში. მაგალითად, teamlabdotcom - დარწმუნებული ხართ, რომ გსურთ '{0}' კომპანიის წაშლა? @@ -160,9 +157,6 @@ გარიგების დასრულების სავარაუდი თარიღი - - მოძებნე ანგარიში Twitter ზე - კონტაქტები @@ -211,9 +205,6 @@ გთხოვთ განაახლოთ გვერდი. - - შესაძლებელი პროფილები {0} -თვის - ძირითადი diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ko.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ko.resx index 702361d0dc..22b1ee4ff5 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ko.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ko.resx @@ -139,9 +139,6 @@ 모든 입력 된 정보가 손실됩니다. 당신은 어쨌든 계속 하시겠습니까? - - 귀하의 트위터 계정의 이름을 입력하십시오. 예를 들어, teamlabdotcom - 영업기회 @@ -247,9 +244,6 @@ 예상 거래 기한 - - 트위터에 계정을 찾기 - 받는 사람 목록이 생성되었습니다. {0} 이메일 이메일 프로그램으로 주소를 전달하려면 아래의 링크를 클릭하십시오. @@ -352,9 +346,6 @@ 페이지를 새로 고침하세요 - - 에 대한 가능성이 프로필 {0} - 예비 선거 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.lt.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.lt.resx index 6602590c99..2a95e573fc 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.lt.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.lt.resx @@ -149,9 +149,6 @@ Visa įvesta informacija bus prarasta. Ar tikrai norite tęsti? - - Nurodykite savo Twitter paskyros pavadinimą. Pavyzdžiui, teamlabdotcom - Einamasis mėnuo @@ -278,9 +275,6 @@ Ar tikrai norite tęsti? Numatoma sandorio užbaigimo data - - Rasti Twitter paskyrą - Adresatų sąrašas sugeneruotas. {0} Spauskite žemiau esančias nuorodas adresų persiuntimui į el. pašto programą. @@ -392,9 +386,6 @@ Ar tikrai norite tęsti? Prašome palaukti - - galimi profiliai {0} - Ankstesnis diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.lv.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.lv.resx index 38f1276166..2e22b6b125 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.lv.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.lv.resx @@ -149,9 +149,6 @@ Ievadītā informācija būs zaudēta. Vai tiešām vēlaties turpināt? - - Lūdzu, ievadiet jūsu Twitter konta nosaukumu. Piemēram, teamlabdotcom - Valsts @@ -281,9 +278,6 @@ Vai tiešām vēlaties turpināt? Paredzams darījuma izpildes datums - - Atrast Twitter kontu - Jūsu adresātu saraksts ir ģenerēts. {0}Noklikšķiniet uz saites zemāk, lai pāriet jūsu e-pasta adreses e-pasta programmu. @@ -395,9 +389,6 @@ Vai tiešām vēlaties turpināt? Lūdzu, uzgaidiet... - - Iespējamie profili {0} - Atpakaļ diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.nl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.nl.resx index 34f9642dff..2d8b619182 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.nl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.nl.resx @@ -149,9 +149,6 @@ Alle ingevoerde informatie zal verloren gaan. Weet u zeker dat u toch wilt doorgaan? - - Geef de naam van je Twitter-account. Bijvoorbeeld, teamlabdotcom - Land @@ -281,9 +278,6 @@ Weet u zeker dat u toch wilt doorgaan? Geschatte vervaldatum deal - - Account zoeken in Twitter - Uw ontvangerslijst is gegenereerd. {0} Klik op de links hieronder om uw e-mailadres in het e-mailprogramma te zetten. @@ -395,9 +389,6 @@ Weet u zeker dat u toch wilt doorgaan? Een ogenblik geduld... - - Mogelijke profielen voor {0} - Vorige diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pl.resx index 9cea7687e7..44c2db25ec 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pl.resx @@ -149,9 +149,6 @@ Wszystkie wprowadzone informacje zostaną utracone. Czy na pewno chcesz dalej? - - Podaj nazwę Twojego konta w Twitter. Na przykład teamlabdotcom - Kraj @@ -281,9 +278,6 @@ Czy na pewno chcesz dalej? Prawdopodobna data finalizacji umowy - - Znajdź konto na Twitter - Twoja lista odbiorców została wygenerowana. {0} Kliknij poniższe linki, aby przesłać adresy e-mail do programu pocztowego. @@ -397,9 +391,6 @@ Czy na pewno chcesz dalej? Proszę czekać... - - Możliwe profile dla {0} - Poprzedni diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pt-BR.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pt-BR.resx index 5f1c5f70f5..f08f39c8c6 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pt-BR.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pt-BR.resx @@ -149,9 +149,6 @@ Todas as informações inseridas serão perdidas. Você tem certeza de que deseja continuar de qualquer forma? - - Por favor, insira o nome da sua conta no Twitter. Por exemplo, teamlabdotcom - País @@ -281,9 +278,6 @@ Você tem certeza de que deseja continuar de qualquer forma? Data de conclusão de negócio estimada - - Encontrar conta no Twitter - Sua lista de destinatários foi gerada. {0} Clique nos links abaixo para enviar o seu endereço de e-mail para o programa de e-mail. @@ -398,9 +392,6 @@ Você tem certeza de que deseja continuar de qualquer forma? Aguarde... - - Perfis possíveis para {0} - Anterior diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pt.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pt.resx index 1f1998f715..b5a19270c3 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pt.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.pt.resx @@ -140,9 +140,6 @@ Todas as informações inseridas serão perdidas. Continuar mesmo assim? - - Por favor, digite o nome da sua conta do Twitter. Por exemplo, teamlabdotcom - Oportunidade @@ -248,9 +245,6 @@ Continuar mesmo assim? Data de vencimento estimada do negócio - - Localizar conta no Twitter - A sua lista de destinatários foi gerada. {0} Clique nos links abaixo para passar o seu endereço de email para o programa de e-mail. @@ -353,9 +347,6 @@ Continuar mesmo assim? Por favor carregue a página - - Perfis possíveis para {0} - Primário diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.resx index da9c0b9cea..011a8bc74f 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.resx @@ -149,9 +149,6 @@ All the entered information will be lost. Are you sure you want to continue anyway? - - Please enter the name of your Twitter account. For example, teamlabdotcom - Country @@ -284,9 +281,6 @@ Are you sure you want to continue anyway? Estimated deal due date - - Find account in Twitter - Your recipient list has been generated. {0} Click the links below to pass your email addresses over to the email program. @@ -401,9 +395,6 @@ Are you sure you want to continue anyway? Please wait... - - Possible profiles for {0} - Previous diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ru.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ru.resx index a2aa5187c2..e9aa55880f 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ru.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.ru.resx @@ -149,9 +149,6 @@ Вся введенная информация будет потеряна. Вы уверены, что хотите продолжить? - - Введите название вашего Twitter аккаунта. Например, teamlabdotcom - Страна @@ -281,9 +278,6 @@ Предполагаемая дата закрытия - - Найти аккаунт в Twitter - Список получателей был сгенерирован. {0} Щелкните по ссылкам ниже, чтобы перенести адреса email в почтовую программу. @@ -398,9 +392,6 @@ Пожалуйста, подождите... - - Возможные профили для {0} - Назад diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sk.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sk.resx index 9aeaba8228..88b6f85bc5 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sk.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sk.resx @@ -160,11 +160,6 @@ Všetky zadané informácie sa stratia. Určite chcete pokračovať? - - - - Zadajte prosím názov svojho Twitter účtu. Napríklad teamlabdotcom - @@ -343,11 +338,6 @@ Odhadované dátumy splatnosti obchodu - - - - Nájsť účet na Twitteri - @@ -490,11 +480,6 @@ Čakajte prosím... - - Možné profily pre {0} - - - Predchádzajúce diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sl.resx index e5b15baac3..a69fc9aee8 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sl.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sl.resx @@ -146,9 +146,6 @@ Vse vnešene informacije bodo izgubljene. Ali ste prepričani, da želite vseeno nadaljevati? - - Prosim vnesi ime svojega Twitter računa. Na primer teamlabdotcom - Priložnost @@ -263,9 +260,6 @@ Ali ste prepričani, da želite vseeno nadaljevati? Ocenjen datum zapadlosti ponudbe - - Poišči račun v Twitteju - Vaš seznam prejemnikov je bil ustvarjen. {0} Pritisnite spodnje povezave in svoj e-poštni naslov predajte na email program. @@ -377,9 +371,6 @@ Ali ste prepričani, da želite vseeno nadaljevati? Prosim počakajte... - - Možni profili za {0} - Prejšnji diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sv.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sv.resx index db76dbd58b..ac73623ad6 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sv.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.sv.resx @@ -149,9 +149,6 @@ All angett data kommer förloras. Är du säker på att du vill fortsätta ändå? - - Vänligen ange namen på ditt TWitter-konto. Till exempel, teamlabdotcom - Land @@ -281,9 +278,6 @@ Beräknad förfallodatum för avtalet - - Hitta konto på Twitter - Din mottagareslista har genereras. {0} Klicka länkarna nedan för att skicka dina mejladresser över till mejlprogrammet. @@ -395,9 +389,6 @@ Vänligen vänta... - - Möjliga profiler för {0} - Föregående diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.tr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.tr.resx index ada5147d3b..5ccc2774e0 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.tr.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.tr.resx @@ -149,9 +149,6 @@ Tüm girilen bilgiler kaybolacaktır. Devam etmek istediğinizden emin misiniz? - - Lütfen Twitter hesabınızın ismini girin. Ör. teamlabdotcom - Ülke @@ -281,9 +278,6 @@ Devam etmek istediğinizden emin misiniz? Öngörülen anlaşma bitiş tarihi - - Twitter'dan hesap bul - Alıcı listeniz oluşturuldu. {0} Aşağıdaki bağlantılara tıklayarak eposta programına eposta adreslerini geçirebilirsiniz. @@ -395,9 +389,6 @@ Devam etmek istediğinizden emin misiniz? Lütfen bekleyin... - - {0} için olası profiller - Önceki diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.uk.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.uk.resx index 8a01d4effc..3d67383b3b 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.uk.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.uk.resx @@ -148,9 +148,6 @@ Уся введена інформація буде загублена. Ви упевнені, що хочете продовжити? - - Введіть назву вашого Twitter аккаунта. Наприклад, teamlabdotcom - Країна @@ -280,9 +277,6 @@ Передбачувана дата закриття угоди - - Знайти акаунт на Twitter - Ваш список одержувачів був створений. {0} Клацніть на посилання нижче, щоб передати свої електронні адреси в програму електронної пошти. @@ -394,9 +388,6 @@ Будь ласка, зачекайте.... - - Можливі профілі для {0} - Попередній diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.vi.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.vi.resx index a4900c9d6f..6dcaf93cf4 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.vi.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.vi.resx @@ -148,9 +148,6 @@ Tất cả các thông tin đã nhập sẽ bị mất. Bạn có chắc là muốn tiếp tục? - - Vui lòng nhập tên tài khoản Twitter của bạn. Ví dụ, teamlabdotcom - Quốc gia @@ -280,9 +277,6 @@ Ngày kết thúc dự kiến - - Tìm tài khoản trong Twitter - Danh sách người nhận đã được tạo. {0} Nhấp vào liên kết dưới đây để chuyển các địa chỉ email của bạn qua chương trình email. @@ -394,9 +388,6 @@ Vui lòng chờ... - - Hồ sơ có thể có cho {0} - Trước diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.zh-CN.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.zh-CN.resx index 90c1e46048..fcdb50ee6d 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.zh-CN.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.zh-CN.resx @@ -149,9 +149,6 @@ 所有已输入的信息将会丢失。 您确定要继续吗? - - 请输入你的Twitter帐户。例如“teamlabdotcom” - 国家 @@ -281,9 +278,6 @@ 预计成交日期 - - 在Twitter上搜索帐户 - 已为您的收件人列表。{0}请单击下面的链接以传送到您的电邮软件。 @@ -395,9 +389,6 @@ 请稍候... - - 最接近 {0} 的账户 - 上一个 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.zh-TW.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.zh-TW.resx index 3b6fd23ca9..b518764a98 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.zh-TW.resx +++ b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMJSResource.zh-TW.resx @@ -150,9 +150,6 @@ 所有輸入的信息將丟失。 您確定要繼續嗎? - - 請輸入您的Twitter帳戶的名稱。例如,teamlabdotcom - 國家 @@ -282,9 +279,6 @@ 預計交易截止日期 - - 在Twitter中查找帳戶 - 您的收件人列表已生成。 {0}單擊下面的連結將您的電子郵件地址傳遞到電子郵件程序。 @@ -399,9 +393,6 @@ 請稍候... - - {0}的可能配置總則 - 前一個 diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.Designer.cs b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.Designer.cs deleted file mode 100644 index 4ac0e664e2..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.Designer.cs +++ /dev/null @@ -1,180 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ASC.Web.CRM.Resources { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - public class CRMSocialMediaResource { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal CRMSocialMediaResource() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASC.Web.CRM.Resources.CRMSocialMediaResource", typeof(CRMSocialMediaResource).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - public static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Be aware of what your clients think about your produce and brand in the social network. Simply link the twitter account with the contact and follow the tweet news feed right on your portal.. - /// - public static string EmptyContentTwitterAccountsDescribe { - get { - return ResourceManager.GetString("EmptyContentTwitterAccountsDescribe", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No linked Twitter accounts. - /// - public static string EmptyContentTwitterAccountsHeader { - get { - return ResourceManager.GetString("EmptyContentTwitterAccountsHeader", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Internal error. - /// - public static string ErrorInternalServer { - get { - return ResourceManager.GetString("ErrorInternalServer", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Twitter account could not be found. - /// - public static string ErrorTwitterAccountNotFound { - get { - return ResourceManager.GetString("ErrorTwitterAccountNotFound", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Could not connect to Twitter. - /// - public static string ErrorTwitterConnectionFailure { - get { - return ResourceManager.GetString("ErrorTwitterConnectionFailure", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Maximal allowed number of requests to Twitter is exceeded. Try again later.. - /// - public static string ErrorTwitterRateLimit { - get { - return ResourceManager.GetString("ErrorTwitterRateLimit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The application has no Twitter access. Please reconnect the Twitter account.. - /// - public static string ErrorTwitterUnauthorized { - get { - return ResourceManager.GetString("ErrorTwitterUnauthorized", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unknown Twitter account. - /// - public static string ErrorUnknownTwitterAccount { - get { - return ResourceManager.GetString("ErrorUnknownTwitterAccount", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Link Twitter account. - /// - public static string LinkTwitterAccount { - get { - return ResourceManager.GetString("LinkTwitterAccount", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No accounts could be found. - /// - public static string NoAccountsHasBeenFound { - get { - return ResourceManager.GetString("NoAccountsHasBeenFound", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No companies could be found. - /// - public static string NoCompaniesHasBeenFound { - get { - return ResourceManager.GetString("NoCompaniesHasBeenFound", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Please wait.... - /// - public static string PleaseWait { - get { - return ResourceManager.GetString("PleaseWait", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Twitter account is not connected. - /// - public static string SocialMediaAccountNotFoundTwitter { - get { - return ResourceManager.GetString("SocialMediaAccountNotFoundTwitter", resourceCulture); - } - } - } -} diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ar-AE.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ar-AE.resx deleted file mode 100644 index 9800c8bedc..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ar-AE.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - كل على اطلاع بما يعتقدة عملائك عن منتجاتك او اسمك التجاري فقط قم بربط حسابات تويتر مع جهة الاتصال وتابع الاخبار والاحداث التي يتحدث عنها العميل - - - لا يوجد اي حساب تويتر مرتبط - - - اربط حساب تويتر - - - لا يمكن ايجاد اي حساب - - - لا يوجد اي شركات - - - الرجاء الانتظار ... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.az-Latn-AZ.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.az-Latn-AZ.resx deleted file mode 100644 index e6bbfd1c7f..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.az-Latn-AZ.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Müştərilərinizin məhsul və brendiniz haqqında düşüncələrindən xəbərdar olun. Sadəcə müştərinizin Twitter hesabı ilə bağlantı qurun və sağ portalınızda lent xəbərlərini izləyin. - - - Bağlantılı Twitter hesabı yoxdur - - - Daxili xəta - - - Twitter hesabı tapılmadı - - - Twitter'ə qoşulmaq mümkün olmadı - - - Twitter-ə edilən sorğuların maksimum sayı keçilib. Biraz sonra yenidən cəhd edin. - - - Proqramın Twitter-ə girişi yoxdur. Twitter hesabını yenidən əlaqələndirin. - - - Naməlum Twitter hesabı - - - Twitter hesabına bağla - - - Heç bir hesab tapılmadı - - - Heç bir şirkət tapılmadı - - - Lütfən gözləyin... - - - Twitter hesabı əlaqələndirilməyib - - diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.bg.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.bg.resx deleted file mode 100644 index ef79289b03..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.bg.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Бъдете наясно с това, което вашите клиенти мислят за вашата продукция и марка в социалната мрежа. Просто свържете профила в Twitter с контакта и следвайте подаването на чужди новини направо на портала си. - - - Няма свързани профили в Twitter - - - Вътрешна грешка - - - Профилът в Twitter не може да бъде намерен - - - Не може да се свърже с Twitter - - - Превишен е максималният допустим брой заявки за Twitter. Опитайте отново по-късно. - - - Приложението няма достъп до Twitter. Моля, свържете отново профила в Twitter. - - - Неизвестен профил в Twitter - - - Линк към профила в Twitter - - - Не бяха намерени профили - - - Не могат да бъдат намерени фирми - - - Моля Изчакай... - - - Профилът в Twitter не е свързан - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.bs-BA.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.bs-BA.resx deleted file mode 100644 index 427bac21bd..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.bs-BA.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Budite svjesni što vaši klijenti misle o vašem proizvodu i brendu na društvenoj mreži. Jednostavno povežite twitter račun sa kontaktom i pratite tweet news feed pravo na svom portalu. - - - Nema povezanih Twitter računa - - - Interna greška - - - Nije bilo moguće pronaći račun na Twitteru - - - Nije moguće povezivanje s Twitterom - - - Premašen je maksimalno dozvoljeni broj zahtjeva za Twitter. Pokušajte ponovo kasnije. - - - Aplikacija nema pristup Twitteru. Ponovo povežite Twitter račun. - - - Nepoznati Twitter račun - - - Povežite Twitter račun - - - Nije moguće pronaći nijedan račun - - - Nijedna kompanija nije moguća - - - Molimo pričekajte... - - - Twitter račun nije povezan - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ca.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ca.resx deleted file mode 100644 index c9b84f36fe..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ca.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Estigueu al corrent del que pensen els vostres clients sobre els vostres productes i la vostra marca a les xarxes socials. Simplement, vinculeu el vostre compte de twitter amb el contacte i seguiu els tuits directament des del vostre portal. - - - No hi ha cap compte de Twitter vinculat - - - Vincular el compte de twitter - - - No s'han trobat comptes - - - No s'han trobat empreses - - - Espereu, si us plau... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.cs.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.cs.resx deleted file mode 100644 index 0ce680709a..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.cs.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Uvědomte si, co si zákazníci myslí o vaší produkci a značce na sociální síti. Jednoduše propojte účet twitter s kontaktem a postupujte podle tweet news feed přímo na váš portál. - - - Bez propojení s Twitter účty - - - Interní chyba - - - Twitter účet nebyl nalezen - - - Nelze se připojit ke službě Twitter - - - Maximální povolený počet požadavků na službu Twitter je překročen. Zkuste to později. - - - Aplikace nemá přístup ke službě Twitter. Znovu připojte účet Twitter. - - - Neznámý účet Twitter - - - Link Twitter účet - - - Žádné účty lze nalézt - - - Nepodařilo se najít firmu - - - Čekejte prosím ... - - - Twitter účet není připojen - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.da.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.da.resx deleted file mode 100644 index 1a16d87704..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.da.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Vær opmærksom på hvad dine klienter tænker om dine produkter og dit varemærke i de sociale netværk. Link din twitter konto til kontakten og følg tweet nyheds strømmen direkte her i din portal. - - - Ingen linkede twitter konti - - - Link med twitter konto - - - Kunne ikke finde nogen konti - - - Kunne ikke finde nogen firmaer - - - Vent venligst... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.de.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.de.resx deleted file mode 100644 index d3026e5cbb..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.de.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Erfahren Sie, was Ihre Kunden zu Ihren Produkten und der Marke in den sozialen Netzwerken meinen. Verknüpfen Sie einfach das Twitter-Konto mit dem Kontakt und verfolgen Sie den Newsfeed direkt auf Ihrem Portal. - - - Keine verknüpften Twitter-Konten - - - Interner Fehler - - - Twitter-Konto ist nicht gefunden - - - Es konnte keine Verbindung zu Twitter hergestellt werden. - - - Die maximal zulässige Anzahl der Anfragen an Twitter wurde überschritten. Versuchen Sie es später noch einmal. - - - Die Anwendung hat keinen Zugriff auf Twitter. Bitte verknüpfen Sie das Twitter-Konto erneut. - - - Unbekanntes Twitter-Konto - - - Twitter-Konto verknüpfen - - - Keine Konten gefunden - - - Keine Unternehmen gefunden - - - Bitte warten... - - - Twitter-Konto ist nicht verknüpft. - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.el.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.el.resx deleted file mode 100644 index 0e8f38701e..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.el.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Να γνωρίζετε τι σκέφτονται οι πελάτες σας για τα προϊόντα και την επωνυμία σας στα κοινωνικά δίκτυα. Απλώς συνδέστε το λογαριασμό twitter με την επαφή και ακολουθήστε τη ροή ειδήσεων tweet απευθείας στο πόρταλ σας. - - - Δεν υπάρχουν συνδεδεμένοι λογαριασμοί Twitter - - - Εσωτερικό σφάλμα - - - Δεν ήταν δυνατή η εύρεση λογαριασμού Twitter - - - Αδυναμία σύνδεσης στο Twitter - - - Υπέρβαση του μέγιστου επιτρεπόμενου αριθμού αιτημάτων στο Twitter. Προσπαθήστε ξανά αργότερα. - - - Η εφαρμογή δεν έχει πρόσβαση στο Twitter. Παρακαλούμε συνδέστε ξανά το λογαριασμό Twitter. - - - Άγνωστος λογαριασμός Twitter - - - Σύνδεση λογαριασμού Twitter - - - Δεν βρέθηκαν λογαριασμοί - - - Δεν βρέθηκαν εταιρείες - - - Παρακαλούμε περιμένετε... - - - Ο λογαριασμός Twitter δεν είναι συνδεδεμένος - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.es.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.es.resx deleted file mode 100644 index f61145fb10..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.es.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Sea consciente de lo que opinan sus clientes sobre sus productos y marca en la red social. Simplemente vincule la cuenta de Twitter con el contacto y siga las noticias Tweet directo en su portal. - - - Ningunas cuentas de Twitter vinculadas - - - Error interno - - - No puedo encontrarse la cuenta de Twitter - - - No pudo conectar a Twitter - - - Máximo número de peticiones a Twitter excedido. Por favor intente más tarde. - - - La aplicación no tiene acceso a Twitter. Por favor vuelva a conectar la cuenta de Twitter. - - - Cuenta de Twitter desconocida - - - Vincular cuenta de twitter - - - No se puede encontrar ningunas cuentas - - - No se puede encontrar ningunas empresas - - - Por favor espere... - - - La cuenta de Twitter no está conectada - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.et.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.et.resx deleted file mode 100644 index 36f7c92dbe..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.et.resx +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Seotud twitter'i konto puudub - - - Seo twitter'i konto - - - Kontot ei leitud - - - Ettevõttet ei leitud - - - Palun oota... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fa.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fa.resx deleted file mode 100644 index d0875c00e4..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fa.resx +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - هیچ حساب Twitter ای لینک نشده است - - - لینک کردن حساب تویتر - - - هیچ حسابی یافت نشد - - - هیچ شرکتی یافت نشد - - - لطفاً منتظر بمانید... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fi.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fi.resx deleted file mode 100644 index b28bf5907c..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fi.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Pysy ajan tasalla siitä, mitä kontaktisi ajattelevat tuotteistasi ja yrityskuvastasi sosiaalisessa mediassa. Linkitä kontakti Twitter-tiliin ja seuraa tweet uutissyötettä suoraan portaalissasi. - - - Ei linkitettyjä Twitter-tilejä - - - Linkitä Twitter-tiliin - - - Tilejä ei löytynyt - - - Yrityksiä ei löytynyt - - - Ole hyvä ja odota... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fr.resx deleted file mode 100644 index de01848c0b..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.fr.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Soyez au courant de ce que vos clients disent au sujet de vos produits et votre marque dans le réseau social. Tout simplement liez le compte Twitter avec le contact et suivez le fil de nouvelles directement sur le portail. - - - Aucun compte Twitter lié - - - Erreur interne - - - Le compte Twitter ne peut pas être trouvé - - - Impossible de se connecter à Twitter - - - Le nombre maximal de demandes à Twitter est dépassé. Essayez encore une fois plus tard. - - - L'application n'a pas d'accès à Twitter. Reconnectez le compte Twitter. - - - Un compte Twitter inconnu - - - Lier le compte Twitter - - - Aucun compte trouvé - - - Aucune entreprise trouvé - - - Veuillez patienter... - - - Le compte Twitter n'est pas connecté - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.hr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.hr.resx deleted file mode 100644 index 1ecf116564..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.hr.resx +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Korisnički račun nije pronađen - - - Tražena tvrtka nije pronađena - - - Molimo pričekajte... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.hu.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.hu.resx deleted file mode 100644 index 2c66f95b57..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.hu.resx +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.id.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.id.resx deleted file mode 100644 index 85e57906cc..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.id.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - waspasda apa yang klien Anda pikirkan tentang produk dan merek di jaringan sosial. Cukup menghubungkan akun twitter dengan kontak dan mengikuti berita langsung di portal Anda. - - - tidak ada akun twitter terkait - - - tautkan akun Twitter - - - tidak ada akun dapat ditemukan - - - tidak ada perusahaan dapat ditemukan - - - Silakan tunggu... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.it.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.it.resx deleted file mode 100644 index 6cfd6ba55c..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.it.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Scopri cosa pensano i tuoi clienti dei tuoi prodotti e della tua marca nelle reti sociali. Basta collegare l'account Twitter al contatto e seguire le ultime notizie twittate direttamente nel tuo portale. - - - Nessun account Twitter collegato - - - Errore interno - - - Nessun account Twitter trovato - - - Impossibile connettersi a Twitter - - - E stato superato il numero di richieste a Twitter massimo autorizzato. Riprova più tardi. - - - L'applicazione non ha accesso a Twitter. Connetti l'account Twitter di nuovo. - - - Account Twitter sconosciuto - - - Collega account Twitter - - - Nessun account trovato - - - Nessun azienda trovata - - - Per favore, aspetta... - - - L'account Twitter non è connesso - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ja.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ja.resx deleted file mode 100644 index 7afbacf8e2..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ja.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - あなたのクライアントはソーシャルネットワークでの食材やブランドについてどう思っているかに注意する必要があります。単に連絡先とTwitterのアカウントをリンクして、右のポータルにつぶやきニュースフィードに従ってください。 - - - リンクされたTwitterアカウントません - - - リンクtwitterアカウント - - - 該当するアカウントが見つかりませんでした - - - いいえ会社が見つかりませんでした - - - しばらくお待ちください... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ka.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ka.resx deleted file mode 100644 index 8abb75b3a3..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ka.resx +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ანგარიში არ მოიძებნა - - - კომპანიები არ მოიძებნა - - - გტხოვთ დაიცადოთ... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ko.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ko.resx deleted file mode 100644 index 2ecc0497f1..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ko.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 고객이 제품과 브랜드에 대하여 소셜네트웨그에서 어떻게 생각하는지 알고자 한다면, 트위터 계정을 연락처와 연결하고 팔로우하여 포털에서 트윗 뉴스를 구독합니다. - - - 연결 된 twitter 계정이 없습니다. - - - twitter 계정 연결 - - - 계정을 찾을 수 없습니다. - - - 회사를 찾을 수 없습니다. - - - 잠시만 기다려 주십시오... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.lt.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.lt.resx deleted file mode 100644 index 83a9125059..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.lt.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Sužinokite, ką Jūsų klientai galvoja apie Jūsų produkciją ir prekinį ženklą socialiniuose tinkluose. Tiesiog susiekite twitter paskyrą su kontaktu ir sekite įrašų srautą savo portale. - - - Nėra susietų twitter paskyrų - - - Susieti su twitter paskyra - - - Nerasta jokių paskirų - - - Nerasta jokių kompanijų - - - Prašome palaukti... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.lv.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.lv.resx deleted file mode 100644 index f50f13f7ce..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.lv.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Esi informēts par to ko jūsu klienti doma par produkcijam un zīmolu sociālos tīklos. Vienkārši saistiet twitter kontu ar kontaktpersonu un sekojiet ziņam no twittera tieši jūsu portālā. - - - Nav saistīta twitter konta - - - Iekšējā kļūda - - - Nav atrasts Twitter konts - - - Neizdevās pieslēgties Twitter - - - Ir pārsniegts maksimālais atļautais Twitter pieprasījumu skaits. Mēģiniet vēlāk vēlreiz. - - - Lietotnei nav piekļuves Twitter. Lūdzu, atkārtoti pieslēdzieties Twitter kontam. - - - Nezināms Twitter konts - - - Saistīt twitter kontu - - - Nevar atrast nevienu kontu - - - Nevar atrast nevienu uzņēmumu - - - Lūdzu, uzgaidiet ... - - - Twitter konts nav pieslēgts - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.nl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.nl.resx deleted file mode 100644 index 12a4543b13..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.nl.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Ben je bewust van de mening van je klanten over je producten en merken in de sociale netwerken! Koppel het twitter account aan de contactpersoon en volg de tweets direct in je portal. - - - Geen gekoppelde twitter accounts - - - Interne fout - - - Twitter-account kon niet worden gevonden - - - Kon geen verbinding maken met Twitter - - - Maximaal aantal toegestane verzoeken voor Twitter is overschreden. Probeer het later nog eens. - - - De applicatie heeft geen toegang tot Twitter. Maak alstublieft opnieuw verbinding met het Twitter-account. - - - Onbekend Twitter-account - - - Link twitter-account - - - Geen accounts gevonden - - - Geen bedrijven gevonden - - - Een ogenblik geduld... - - - Twitter-account is niet verbonden - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pl.resx deleted file mode 100644 index ad8b52b85d..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pl.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Pamiętaj, co Twoi klienci myślą o swoich produktach i marce w sieci społecznościowej. Wystarczy połączyć konto Twitter z kontaktem i śledzić za tweet wiadomościami bezpośrednio na portalu. - - - Brak powiązanych kont Twitter - - - Błąd wewnętrzny - - - Nie można znaleźć konta Twitter - - - Nie można połączyć się z Twitterem - - - Maksymalna dozwolona liczba zgłoszeń do serwisu Twitter jest przekroczona. Spróbuj ponownie później. - - - Aplikacja nie ma dostępu do serwisu Twitter. Proszę ponownie podłączyć konto Twitter. - - - Nieznane konto Twitter - - - Połącz konto Twitter - - - Nie można znaleźć konta - - - Nie można znaleźć firmy - - - Proszę czekać... - - - Konto Twitter nie jest połączone - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pt-BR.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pt-BR.resx deleted file mode 100644 index bfee85d26a..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pt-BR.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Fique ciente do que seus clientes pensam sobre seu produto e marca na rede social. Basta vincular a conta do twitter com o contato e seguir os feed de notícia tweet diretamente em seu portal. - - - Não há contas de Twitter vinculadas - - - Erro interno - - - Conta do Twitter não foi encontrada - - - Não foi possível conectar com Twitter - - - Número máximo de solicitações para Twitter permitido foi excedido. Tente novamente depois. - - - O aplicativo não tem acesso ao Twitter. Reconecte a conta do Twitter. - - - Conta do Twitter desconhecida - - - Vincule uma conta do Twitter - - - Nenhuma conta foi encontrada - - - Nenhuma empresa foi encontrada - - - Aguarde... - - - A conta do Twitter não está conectada - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pt.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pt.resx deleted file mode 100644 index d7a57de993..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.pt.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Informe-se do que seus clientes pensam sobre o seu produto e marca na rede social. Ligue simplesmente a conta do twitter com o contato e siga as notícias no seu portal. - - - Não há contas de twitter associadas - - - Ligar conta do twitter - - - Não foi encontrada nenhuma conta - - - Não foi encontrada nenhuma empresa - - - Por favor aguarde ... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.resx deleted file mode 100644 index b3dc130d06..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Be aware of what your clients think about your produce and brand in the social network. Simply link the twitter account with the contact and follow the tweet news feed right on your portal. - - - No linked Twitter accounts - - - Internal error - - - Twitter account could not be found - - - Could not connect to Twitter - - - Maximal allowed number of requests to Twitter is exceeded. Try again later. - - - The application has no Twitter access. Please reconnect the Twitter account. - - - Unknown Twitter account - - - Link Twitter account - - - No accounts could be found - - - No companies could be found - - - Please wait... - - - Twitter account is not connected - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ro.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ro.resx deleted file mode 100644 index 40f52a4dda..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ro.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Fiți conștienți de ce cred clienții dvs. despre produsele și marca dvs. pe rețeaua de socializare. Pur și simplu conectați contul de twitter cu contactul și urmați fluxul de știri de pe tweet chiar pe portalul dvs. - - - Nu există conturi Twitter atașate - - - Eroare internă - - - Contul Twitter nu a fost găsit - - - Nu s-a putut conecta la Twitter - - - Numărul maxim de solicitări către Twitter este depășit. Încercați mai târziu. - - - Aplicația nu are acces pe Twitter. Vă rugăm să reconectați contul de Twitter. - - - Cont Twitter necunoscut - - - Atașează contul de Twitter - - - Nu s-au găsit conturi - - - Nu a fost găsită nicio companie - - - Vă rugăm așteptați... - - - Contul Twitter nu este conectat - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ru.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ru.resx deleted file mode 100644 index da3c4411c6..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.ru.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Будьте в курсе того, что думают о вашей продукции и бренде ваши клиенты в социальной сети. Просто привяжите к контакту аккаунт Twitter и следите за лентой новостей прямо на своем портале. - - - Нет связанных аккаунтов Twitter - - - Внутренняя ошибка - - - Аккаунт Twitter не найден - - - Не удалось подключиться к Twitter - - - Превышено максимально допустимое количество запросов к Twitter. Повторите попытку позже. - - - У приложения нет доступа к Twitter. Пожалуйста, подключите аккаунт Twitter повторно. - - - Неизвестный аккаунт Twitter - - - Привязать аккаунт Twitter - - - Аккаунты не найдены - - - Компании не найдены - - - Пожалуйста, подождите... - - - Аккаунт Twitter не подключен - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sk.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sk.resx deleted file mode 100644 index 0f88aadd49..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sk.resx +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Buďte si vedomí toho, čo si klienti myslia o vašej produkcii a značke na sociálnej sieti. Jednoducho prepojte účet twitter s kontaktom a postupujte podľa tweet news feed priamo na vašom portáli. - - - - Bez prepojenia s twitter účtami - - - Interná chyba - - - Účet Twitter nebol nájdený - - - - - Nepodarilo sa pripojiť k službe Twitter - - - - - Maximálny povolený počet žiadostí na Twitter je prekročený. Skúste to neskôr. - - - - Aplikácia nemá prístup k službe Twitter. Znova pripojte účet služby Twitter. - - - - - Neznámy Twitter účet - - - Prepojiť účet Twitter - - - - - Neboli nájdené žiadne účty - - - - - Neboli nájdené žiadne spoločnosti - - - - - Čakajte prosím - - - Účet Twitter nie je pripojený - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sl.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sl.resx deleted file mode 100644 index a9f741a979..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sl.resx +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Zavedajte se kaj vaše stranke menijo o postopku in znamki na družbenih omrežjih. Preprosto povežite twitter račun z kontaktom in sledite tweetom neposredno na svojem portalu. - - - ni povezanih twitter računov - - - Poveži Twitter račun - - - Nobenega računa ni bilo mogoče najti - - - Nobenega podjetja ni bilo mogoče najti - - - Prosim počakajte... - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sv.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sv.resx deleted file mode 100644 index 791b724fa2..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.sv.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Få kännedom om vad dina kunder säger om din produkt och ditt märke i sociala nätverk. Bara länka twitter-kontot med kontakten och följ tweet nyhetsflödets direkt på din portal. - - - Inga länkade Twitter-konton - - - Intern fel - - - Twitter-kontot hittades ej - - - Kunde inte ansluta till Twitter - - - Det maximala antalet förfrågningar till Twitter har överskridits. Försök igen senare. - - - Applikationen kan inte nå Twitter. Vänligen återansluta Twitter-kontot. - - - Okänt Twitter-konto - - - Länka Twitter konto - - - Inga konton hittades - - - Inga företag hittades - - - Vänligen vänta... - - - Twitter-kontot är inte anslutet - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.tr.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.tr.resx deleted file mode 100644 index 05cf7b5951..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.tr.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Müşterilerinizin ürün ve markanız hakkında düşüncelerinin farkında olun. Basitçe, müşterinizin Twitter hesabı ile bağlantı kurun ve sağ portalınızda besleme haberleri izleyin. - - - Bağlantılı Twitter hesabı yok - - - İçsel bir hata - - - Twitter hesabı bulunamadı - - - Twitter'a bağlanılamıyor - - - İzin verilen maksimum Twitter talep sayısı aşıldı. Daha sonra tekrar deneyin. - - - Uygulamanın Twitter erişimi yok. Lütfen Twitter hesabını tekrar bağlayın. - - - Bilinmeyen Twitter hesabı - - - Twitter hesabı ile bağla - - - Hiçbir hesap bulunamadı - - - Hiçbir şirket bulunamadı - - - Lütfen bekleyin... - - - Twitter hesabı bağlı değil - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.uk.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.uk.resx deleted file mode 100644 index 8d9fe7de85..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.uk.resx +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Дізнайтеся думку ваших клієнтів про ваші продукти та бренд у соціальній мережі. Просто зв'яжіть обліковий запис Twitter із контактом і слідуйте за каналом новин Twitter безпосередньо на порталі. - - - - Немає підключених акаунтів Twitter - - - Внутрішня помилка - - - Акаунт Twitter не знайдено - - - Неможливо підключитися до Twitter - - - Максимально дозволене число запитів до Twitter перевищено. Спробуйте ще раз пізніше. - - - Додаток не має доступу до Twitter. Будь ласка, знову підключіть обліковий запис Twitter. - - - Невідомий акаунт Twitter - - - Прив'язати аккаунт Twitter - - - Акаунти не знайдені - - - Компанії не знайдені - - - Будь ласка, зачекайте... - - - Акаунт Twitter не підключено - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.vi.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.vi.resx deleted file mode 100644 index 327c011ef1..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.vi.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Để khách hàng nhận biết sản phẩm và thương hiệu của bạn trên mạng xã hội. Đơn giản chỉ cần liên kết tài khoản twitter với địa chỉ liên hệ và theo dõi các tweet ngay trên cổng thông tin của bạn. - - - Không có tài khoản Twitter được liên kết - - - Lỗi máy chủ nội bộ - - - Không thể tìm thấy tài khoản Twitter - - - Không thể kết nối Twitter - - - Vượt quá số lượng tối đa yêu cầu cho phép của Twitter. Thử lại sau. - - - Ứng dụng không có quyền truy cập Twitter. Vui lòng kết nối lại tài khoản Twitter. - - - Tài khoản Twitter không xác định - - - Liên kết với tài khoản Twitter - - - Không tìm thấy tài khoản nào - - - Không tìm thấy công ty nào - - - Vui lòng chờ... - - - Tài khoản Twitter không được kết nối - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.zh-CN.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.zh-CN.resx deleted file mode 100644 index 728a4fc4fc..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.zh-CN.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 将客户的Twitter账户加入联系信息后,系统就会自动为您读取TA的最新动态并实时显示在联系页中。 - - - 没有链接Twitter帐号 - - - 内部错误 - - - 找不到Twitter账户 - - - 无法连接到Twitter - - - 超出允许的Twitter请求的最大数量。请稍后再试。 - - - 该应用程序无Twitter访问权限。请重新连接Twitter账户。 - - - 未知的Twitter账户 - - - 链接Twitter账号 - - - 找不到符合条件的账户 - - - 找不到符合条件的企业 - - - 请稍候…… - - - Twitter账户未连接 - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.zh-TW.resx b/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.zh-TW.resx deleted file mode 100644 index 5584d8dc3c..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/Resources/CRMSocialMediaResource.zh-TW.resx +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=5.0.6.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 注意您的客戶在社交網絡中對您的產品和品牌的看法。只需將Twitter帳戶與聯繫人連接,然後按照門戶網站上的tweet新聞提要。 - - - 沒有關聯的Twitter 帳戶 - - - 內部錯誤 - - - 找不到Twitter帳戶 - - - 無法連接到Twitter - - - 超過了允許的最大Twitter請求數。稍後再試。 - - - 該應用程序沒有Twitter存取權限。請重新連接Twitter帳戶。 - - - 未知的Twitter帳戶 - - - 連結Twitter帳戶 - - - 找不到帳戶 - - - 找不到公司 - - - 請稍候... - - - Twitter帳戶未連接 - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Templates/ContactsTemplates.html b/web/studio/ASC.Web.Studio/Products/CRM/Templates/ContactsTemplates.html index 6b5aa9c4a8..9618cf21c5 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Templates/ContactsTemplates.html +++ b/web/studio/ASC.Web.Studio/Products/CRM/Templates/ContactsTemplates.html @@ -224,54 +224,6 @@ - - - - -F - - - - - \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Utils/ExportToCSV.cs b/web/studio/ASC.Web.Studio/Products/CRM/Utils/ExportToCSV.cs index 11a01c33f7..0880273fa2 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Utils/ExportToCSV.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Utils/ExportToCSV.cs @@ -115,8 +115,10 @@ public ExportDataOperation(FilterObject filterObject, string fileName) FileUrl = null; } + /// + /// Constructor for serialization/deserialization public properties (redis cache) + /// public ExportDataOperation() - : this(null, null) { } diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Utils/Import/CSV/ImportDataOperation.cs b/web/studio/ASC.Web.Studio/Products/CRM/Utils/Import/CSV/ImportDataOperation.cs index ff6cdee04f..0e79df9d88 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Utils/Import/CSV/ImportDataOperation.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Utils/Import/CSV/ImportDataOperation.cs @@ -97,8 +97,10 @@ public partial class ImportDataOperation : IProgressItem { #region Constructor + /// + /// Constructor for serialization/deserialization public properties (redis cache) + /// public ImportDataOperation() - : this(EntityType.Contact, String.Empty, String.Empty) { } diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Utils/MailSender.cs b/web/studio/ASC.Web.Studio/Products/CRM/Utils/MailSender.cs index 9992d648e9..5bfa427abf 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Utils/MailSender.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Utils/MailSender.cs @@ -79,8 +79,10 @@ class SendBatchEmailsOperation : IProgressItem, IDisposable public bool IsCompleted { get; set; } + /// + /// Constructor for serialization/deserialization public properties (redis cache) + /// private SendBatchEmailsOperation() - : this(new List(), new List(), String.Empty, String.Empty, false) { } diff --git a/web/studio/ASC.Web.Studio/Products/CRM/Utils/PdfCreator.cs b/web/studio/ASC.Web.Studio/Products/CRM/Utils/PdfCreator.cs index 574b4472c5..22d147827c 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/Utils/PdfCreator.cs +++ b/web/studio/ASC.Web.Studio/Products/CRM/Utils/PdfCreator.cs @@ -144,7 +144,7 @@ private static string GetUrlToFile(Stream docxStream) var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); string urlToFile; - DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, null, null, null, false, out urlToFile); + DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, null, null, null, false, out urlToFile, out _); Log.DebugFormat("PdfCreator. GetUrlToFile. urlToFile = {0}", urlToFile); return urlToFile; @@ -159,7 +159,7 @@ public static ConverterData StartCreationFileAsync(Invoice data) var revisionId = DocumentServiceConnector.GenerateRevisionId(Guid.NewGuid().ToString()); string urlToFile; - DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, null, null, null, true, out urlToFile); + DocumentServiceConnector.GetConvertedUri(externalUri, FormatDocx, FormatPdf, revisionId, null, null, null, null, true, out urlToFile, out _); return new ConverterData { @@ -178,7 +178,7 @@ public static File GetConvertedFile(ConverterData data, DaoFactory daoFactory) } string urlToFile; - DocumentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, null, null, null, true, out urlToFile); + DocumentServiceConnector.GetConvertedUri(data.StorageUrl, FormatDocx, FormatPdf, data.RevisionId, null, null, null, null, true, out urlToFile, out _); if (string.IsNullOrEmpty(urlToFile)) { diff --git a/web/studio/ASC.Web.Studio/Products/CRM/js/contacts.js b/web/studio/ASC.Web.Studio/Products/CRM/js/contacts.js index 228adc9f27..c7fad8ddae 100644 --- a/web/studio/ASC.Web.Studio/Products/CRM/js/contacts.js +++ b/web/studio/ASC.Web.Studio/Products/CRM/js/contacts.js @@ -1009,7 +1009,19 @@ ASC.CRM.ListContactView = (function() { if (typeof (ASC.CRM.ListContactView.basePathMail) == "undefined") { ASC.CRM.ListContactView.basePathMail = ASC.CRM.Common.getMailModuleBasePath(); } - + if (window.contactForInitTaskActionPanel != null && contactID == window.contactForInitTaskActionPanel.id) { + if (email == "") { + jq("#simpleContactActionMenu").addClass("display-none"); + jq("#simpleContactMenu_" + contactID).hide(); + } + else { + jq("#simpleContactActionMenu .unlinkContact").addClass("display-none"); + } + } + else { + jq("#simpleContactActionMenu").removeClass("display-none"); + jq("#simpleContactActionMenu .unlinkContact").removeClass("display-none"); + } if (email != "") { var pathCreateEmail = [ ASC.CRM.ListContactView.basePathMail, @@ -1025,7 +1037,7 @@ ASC.CRM.ListContactView = (function() { "/sortorder=descending/" ].join(''); - jq("#simpleContactActionMenu .writeEmail").attr("href", pathCreateEmail); + jq("#simpleContactActionMenu .writeEmail").attr("href", pathCreateEmail).removeClass("display-none"); jq("#simpleContactActionMenu .viewMailingHistory").attr("href", pathSortEmails).removeClass("display-none"); } else { jq("#simpleContactActionMenu .writeEmail").addClass("display-none"); @@ -1640,8 +1652,10 @@ ASC.CRM.ListContactView = (function() { }, render_simple_content: function(params, contacts) { + var parentContactId = window.contactForInitTaskActionPanel && window.contactForInitTaskActionPanel.id; for (var i = 0, n = contacts.length; i < n; i++) { ASC.CRM.Common.contactItemFactory(contacts[i], params); + contacts[i].showActionMenu = contacts[i].showActionMenu && (contacts[i].primaryEmail != null || contacts[i].id != parentContactId) } jq(window).trigger("getContactsFromApi", [contacts]); jq.tmpl("simpleContactTmpl", contacts).prependTo("#contactTable tbody"); @@ -2350,6 +2364,10 @@ ASC.CRM.ListContactView = (function() { ASC.CRM.ContactPhotoUploader = (function() { return { + init: function (defaultAvatarSrc) { + ASC.CRM.ContactPhotoUploader.defaultAvatarSrc = defaultAvatarSrc; + }, + initPhotoUploader: function(parentDialog, photoImg, data) { var a = new AjaxUpload('changeLogo', { action: 'ajaxupload.ashx?type=ASC.Web.CRM.Classes.ContactPhotoHandler,ASC.Web.CRM', @@ -2401,6 +2419,63 @@ ASC.CRM.ContactPhotoUploader = (function() { isInPopup: true, name: "changeLogo" }); + }, + + openLoadPhotoWindow: function () { + + var $link = jq(".linkChangePhoto"); + + if (!$link.length || $link.hasClass("disable")) { + return; + } + + var curAvatarSrc = jq("img.contact_photo").attr("src"); + + var isDefaultAvatar = curAvatarSrc.indexOf(ASC.CRM.ContactPhotoUploader.defaultAvatarSrc + '?') == 0; + + jq("#divLoadPhotoDefault").toggleClass("display-none", isDefaultAvatar); + + PopupKeyUpActionProvider.EnableEsc = false; + + StudioBlockUIManager.blockUI("#divLoadPhotoWindow", 520); + }, + + deleteContactAvatar: function () { + LoadingBanner.displayLoading(); + jq(".under_logo .linkChangePhoto").addClass("disable"); + var contactId = jq("[id$='_ctrlContactID']").val(); + if (contactId == "") { + contactId = 0; + } + var contactType = jq.getURLParam("type"), + uploadOnly = jq("#divDefaultImagesHolder").attr("data-uploadOnly") == "true", + data = { contactId: contactId, uploadOnly: uploadOnly, contactType: contactType }; + + Teamlab.removeCrmContactAvatar({}, contactId, data, { + success: function (params, response) { + PopupKeyUpActionProvider.CloseDialog(); + jq(".under_logo .linkChangePhoto").removeClass("disable"); + LoadingBanner.hideLoading(); + + var now = new Date(); + jq("img.contact_photo").attr("src", + [ + ASC.CRM.ContactPhotoUploader.defaultAvatarSrc, + '?', + now.getTime()] + .join('')); + if (jq("#uploadPhotoPath").length == 1) { + jq("#uploadPhotoPath").val(""); + } + }, + error: function (params, errors) { + PopupKeyUpActionProvider.CloseDialog(); + jq(".under_logo .linkChangePhoto").removeClass("disable"); + LoadingBanner.hideLoading(); + + toastr.error(ASC.CRM.Resources.CRMJSResource.ErrorMessage_SaveImageError); + } + }); } }; })(); @@ -2758,23 +2833,12 @@ ASC.CRM.ContactFullCardView = (function () { ASC.CRM.Resources.CRMContactResource.ChangePhotoToDefault, "", "
", - "
", + "
", "\"\"", "
", "
", - "
", - "
", - "

", - ASC.CRM.Resources.CRMContactResource.LoadPhotoFromSocialMedia, - "

", - "
", - "
", - "
", - "
", - "
", - "
", "
"].join(''), OKBtn: "", CancelBtn: "", @@ -2846,7 +2910,6 @@ ASC.CRM.ContactFullCardView = (function () { } else { item.href = item.data; } - ASC.CRM.SocialMedia.socialNetworks.push(item); } if (item.infoType == 5) { //LinkedIn if (item.data.indexOf("://") == -1) { @@ -2854,13 +2917,11 @@ ASC.CRM.ContactFullCardView = (function () { } else { item.href = item.data; } - ASC.CRM.SocialMedia.socialNetworks.push(item); } if (item.infoType == 6) { //Facebook if (item.data.indexOf("://") == -1) { item.href = "http://facebook.com/" + item.data; } - ASC.CRM.SocialMedia.socialNetworks.push(item); } if (item.infoType == 8) { //LiveJournal if (item.data.indexOf("://") == -1) { @@ -3402,7 +3463,7 @@ ASC.CRM.ContactDetailsView = (function() { return anch; }; - var _initTabs = function (contactID, contactsTabVisible, currentTabAnch, projectsTabVisible, socialMediaTabVisible) { + var _initTabs = function (contactID, contactsTabVisible, currentTabAnch, projectsTabVisible) { window.ASC.Controls.ClientTabsNavigator.init("ContactTabs", { tabs: [ { @@ -3455,14 +3516,6 @@ ASC.CRM.ContactDetailsView = (function() { divID: "projectsTab", visible: projectsTabVisible, onclick: "ASC.CRM.ContactDetailsView.activateCurrentTab('" + contactID + "','projects');" - }, - { - title: "Twitter", - selected: currentTabAnch == "twitter", - anchor: "twitter", - divID: "socialMediaTab", - visible: socialMediaTabVisible, - onclick: "ASC.CRM.ContactDetailsView.activateCurrentTab('" + contactID + "','twitter');" } ] }); @@ -3809,7 +3862,6 @@ ASC.CRM.ContactDetailsView = (function() { init: function (contactID, isCompany, projectsTabVisible, - socialMediaTabVisible, shareType, canEdit) { _canCreateProjects = ASC.CRM.Data.CanCreateProjects; @@ -3817,16 +3869,14 @@ ASC.CRM.ContactDetailsView = (function() { _availableTabs = ["profile", "tasks", "deals", "invoices", "files"]; if (isCompany === true) { _availableTabs.push("contacts"); } if (projectsTabVisible) { _availableTabs.push("projects"); } - if (socialMediaTabVisible) { _availableTabs.push("twitter"); } var currentTabAnch = _getCurrentTabAnch(); - _initTabs(contactID, isCompany === true, currentTabAnch, projectsTabVisible, socialMediaTabVisible); + _initTabs(contactID, isCompany === true, currentTabAnch, projectsTabVisible); ASC.CRM.HistoryView.init(contactID, "contact", 0); ASC.CRM.DealTabView.initTab(contactID); ASC.CRM.ListTaskView.initTab(contactID, "contact", 0); ASC.CRM.ListInvoiceView.initTab(contactID, "contact"); - ASC.CRM.SocialMedia.initTab(isCompany, canEdit); ASC.CRM.ListContactView.isContentRendered = false; ASC.CRM.ListInvoiceView.isContentRendered = false; @@ -3842,8 +3892,7 @@ ASC.CRM.ContactDetailsView = (function() { initContactDetailsMenuPanel(); initOtherActionMenu(shareType); - ASC.CRM.SocialMedia.init(ASC.CRM.Data.DefaultContactPhoto[isCompany === true ? "CompanyBigSizePhoto" : "PersonBigSizePhoto"]); - ASC.CRM.ContactDetailsView.checkSocialMediaError(); + ASC.CRM.ContactPhotoUploader.init(ASC.CRM.Data.DefaultContactPhoto[isCompany === true ? "CompanyBigSizePhoto" : "PersonBigSizePhoto"]); ASC.CRM.ContactDetailsView.activateCurrentTab(contactID, currentTabAnch); }, @@ -3859,18 +3908,6 @@ ASC.CRM.ContactDetailsView = (function() { ASC.CRM.ListContactView.renderSimpleContent(false, true); } } - if (anchor == "twitter") { - var hasTwitter = false - if (typeof (window.contactNetworks) !== "undefined" && window.contactNetworks.length != 0) { - for (var i = 0, n = window.contactNetworks.length; i < n; i++) { - if (window.contactNetworks[i].infoType == 4) { - hasTwitter = true; - break; - } - } - } - ASC.CRM.SocialMedia.activate(hasTwitter); - } if (anchor == "deals") { ASC.CRM.DealTabView.activate(); } @@ -3949,13 +3986,6 @@ ASC.CRM.ContactDetailsView = (function() { ASC.CRM.HistoryView.isTabActive = false; } }); - }, - - checkSocialMediaError: function () { - var smErrorMessage = jq("input[id$='_ctrlSMErrorMessage']").val(); - if (smErrorMessage != "" && smErrorMessage !== undefined) { - ASC.CRM.SocialMedia.ShowErrorMessage(smErrorMessage); - } } }; })(); @@ -4226,28 +4256,17 @@ ASC.CRM.ContactActionView = (function () { ASC.CRM.Resources.CRMContactResource.ChangePhotoToDefault, "", "
", - "
", + "
", "\"\"", "
", "
", - "
", - "
", - "

", - ASC.CRM.Resources.CRMContactResource.LoadPhotoFromSocialMedia, - "

", - "
", - "
", - "
", - "
", - "
", - "
", "
"].join(''), OKBtn: "", CancelBtn: "", progressText: "" - }).insertAfter("#divSMProfilesWindow"); + }).insertAfter("#socialProfileCategoriesPanel"); }; var createNewAddress = function($contact, is_primary, category, street, city, state, zip, country) { @@ -4370,9 +4389,9 @@ ASC.CRM.ContactActionView = (function () { } ASC.CRM.ContactSelector.Cache = {}; } else { - for (var i = 0, n = ASC.CRM.SocialMedia.selectedPersons.length; i < n; i++) { - if (ASC.CRM.SocialMedia.selectedPersons[i].id == id) { - ASC.CRM.SocialMedia.selectedPersons.splice(i, 1); + for (var i = 0, n = ASC.CRM.ContactActionView.selectedPersons.length; i < n; i++) { + if (ASC.CRM.ContactActionView.selectedPersons[i].id == id) { + ASC.CRM.ContactActionView.selectedPersons.splice(i, 1); break; } } @@ -4409,7 +4428,7 @@ ASC.CRM.ContactActionView = (function () { jq("#contactListBox").parent().removeClass('hiddenFields'); ASC.CRM.Common.RegisterContactInfoCard(); - ASC.CRM.SocialMedia.selectedPersons.push(person); + ASC.CRM.ContactActionView.selectedPersons.push(person); } else { Teamlab.getCrmContact({}, obj.id, { @@ -4765,7 +4784,9 @@ ASC.CRM.ContactActionView = (function () { }); } - ASC.CRM.SocialMedia.init(ASC.CRM.Data.DefaultContactPhoto[isCompany === true ? "CompanyBigSizePhoto" : "PersonBigSizePhoto"]); + ASC.CRM.ContactPhotoUploader.init(ASC.CRM.Data.DefaultContactPhoto[isCompany === true ? "CompanyBigSizePhoto" : "PersonBigSizePhoto"]); + + ASC.CRM.ContactActionView.selectedPersons = new Array(); jq(".cancelSbmtFormBtn:first").on("click", function () { ASC.CRM.Common.unbindOnbeforeUnloadEvent(); @@ -4883,35 +4904,12 @@ ASC.CRM.ContactActionView = (function () { }, changeSocialProfileCategory: function(Obj, category, text, categoryName) { - var $divObj = jq(Obj).parents('table:first').parent(); - jq(Obj).text(text); - $inputObj = jq(Obj).parents('tr:first').find('input'); + var $divObj = jq(Obj).text(text).parents('table:first').parent(); + var $inputObj = jq(Obj).parents('tr:first').find('input'); var parts = $inputObj.attr('name').split('_'); parts[1] = categoryName; $inputObj.attr('name', parts.join('_')); - - var $findProfileObj = $divObj.find('.find_profile'), - isShown = false, - func = "", - title = "", - description = " "; - switch (category) { // Enum ContactInfoType - case 4: // twitter - isShown = window.twitterSearchEnabled; - title = ASC.CRM.Resources.CRMJSResource.FindTwitter; - description = ASC.CRM.Resources.CRMJSResource.ContactTwitterDescription; - func = (function(p1, p2) { return function() { ASC.CRM.SocialMedia.FindTwitterProfiles(jq(this), jq("#typeAddedContact").val(), p1, p2); } })(-3, 5) - break; - } - - if (isShown) { - $findProfileObj.off('click').on("click", func); - $findProfileObj.attr('title', title).show(); - } else { - $findProfileObj.hide(); - } - - $divObj.children(".text-medium-describe").text(description); + $divObj.find('.find_profile').hide(); jq("#socialProfileCategoriesPanel").hide(); }, @@ -4986,16 +4984,16 @@ ASC.CRM.ContactActionView = (function () { if (jq("#typeAddedContact").val() == "people") { ASC.CRM.Common.unbindOnbeforeUnloadEvent(); return true; - } else if (ASC.CRM.SocialMedia.selectedPersons.length == 0) { + } else if (ASC.CRM.ContactActionView.selectedPersons.length == 0) { jq("#assignedContactsListEdit input[name='baseInfo_assignedContactsIDs']").val(window.assignedContactSelector.SelectedContacts); ASC.CRM.Common.unbindOnbeforeUnloadEvent(); return true; } else { var data = []; - for (var i = 0, n = ASC.CRM.SocialMedia.selectedPersons.length; i < n; i++) { + for (var i = 0, n = ASC.CRM.ContactActionView.selectedPersons.length; i < n; i++) { data.push({ - FirstName: ASC.CRM.SocialMedia.selectedPersons[i].Key, - LastName: ASC.CRM.SocialMedia.selectedPersons[i].Value + FirstName: ASC.CRM.ContactActionView.selectedPersons[i].Key, + LastName: ASC.CRM.ContactActionView.selectedPersons[i].Value }); } @@ -5053,37 +5051,6 @@ ASC.CRM.ContactActionView = (function () { PopupKeyUpActionProvider.EnableEsc = false; StudioBlockUIManager.blockUI("#confirmationGotoSettingsPanel", 500); } - }, - - prepareSocialNetworks: function () { - - jq("#divImagesHolder").html(""); - var $networks = jq("#websiteAndSocialProfilesContainer").find("input"); - - ASC.CRM.SocialMedia.socialNetworks = []; - for (var i = 0, n = $networks.length; i < n; i++) { - var $el = jq($networks[i]), - text = $el.val().trim(); - - if (text == "") continue; - if ($el.attr("name").indexOf("contactInfo_Twitter_") == 0) { - ASC.CRM.SocialMedia.socialNetworks.push({ - data: text, - infoType: 4 - }); - } else if ($el.attr("name").indexOf("contactInfo_LinkedIn_") == 0) { - ASC.CRM.SocialMedia.socialNetworks.push({ - data: text, - infoType: 5 - }); - } else if ($el.attr("name").indexOf("contactInfo_Facebook_") == 0) { - ASC.CRM.SocialMedia.socialNetworks.push({ - data: text, - infoType: 6 - }); - } - } - ASC.CRM.SocialMedia.ContactImageListLoaded = false; } }; })(); diff --git a/web/studio/ASC.Web.Studio/Products/CRM/js/socialmedia.js b/web/studio/ASC.Web.Studio/Products/CRM/js/socialmedia.js deleted file mode 100644 index a43ead859b..0000000000 --- a/web/studio/ASC.Web.Studio/Products/CRM/js/socialmedia.js +++ /dev/null @@ -1,448 +0,0 @@ -/* - * - * (c) Copyright Ascensio System Limited 2010-2023 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0 - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -*/ - - -if (typeof ASC === "undefined") { - ASC = {}; -} -if (typeof ASC.CRM === "undefined") { - ASC.CRM = function() { return {} }; -} - - -ASC.CRM.SocialMedia = (function() { - var CallbackMethods = { - addAndSaveTwitter: function(params, twitter) { - ASC.CRM.SocialMedia.LoadContactActivity(); - - var tagsContainer = jq("#contactTagsTR"); - - if (tagsContainer.length) { - $currentPrimaryContainer = jq.tmpl("collectionContainerTmpl", - { Type: twitter.infoTypeName }) - .insertBefore("#contactTagsTR") - .children(".collectionItemsTD"); - - jq.tmpl("collectionTmpl", twitter).appendTo($currentPrimaryContainer); - } - }, - - getContactTweets: function (params, response) { - LoadingBanner.hideLoading(); - if (response.length != 0) { - jq("#tweetsEmptyScreen:not(.display-none)").addClass("display-none"); - jq.tmpl("twitterMessageListTmpl", response).appendTo("#divSocialMediaContent"); - } else { - ASC.CRM.SocialMedia.ShowErrorMessage(ASC.CRM.Resources.CRMCommonResource.NoLoadedMessages); - } - } - }; - - _GetContactSMImagesResponse = function (response) { - var imageCount = response.length; - if (imageCount > 0) { - for (var i = 0; i < imageCount; i++) { - jq.tmpl("socialMediaAvatarTmpl", response[i]).appendTo("#divImagesHolder"); - jq("#linkSaveAvatar").css("display", "inline"); - } - _FinishGettingContactImages(true); - } else { - jq("#divImagesHolder").html( - ["
", - ASC.CRM.Resources.CRMContactResource.NoPhotoFromSocialMedia, - "
"].join('')); - _FinishGettingContactImages(false); - } - }; - - _FinishGettingContactImages = function(hasPhotos) { - ASC.CRM.SocialMedia.ContactImageListLoaded = true; - jq("#divAjaxImageContainerPhotoLoad [id$='_ctrlImgAjaxLoader']").remove(); - if (hasPhotos) { - jq("#divLoadPhotoFromSocialMedia").css("height", "100px"); - } - jq("#divImagesHolder").css("display", "block"); - - LoadingBanner.hideLoading(); - PopupKeyUpActionProvider.EnableEsc = false; - StudioBlockUIManager.blockUI("#divLoadPhotoWindow", 520); - }; - - _FindTwitterProfilesResponse = function (target, addTop, addLeft, response) { - var tmplID = "TwitterProfileTmpl"; - if (target.parent().is(".emptyScrBttnPnl")) { - tmplID = "TwitterProfileTabTmpl"; - } - - _RenderSMProfiles(response, tmplID); - - jq("#divSMProfilesWindow .divWait").hide(); - _CalculateProfilesWindowHeight(); - - ASC.CRM.SocialMedia.TwitterTargetTextbox = jq(target).parent().parent().children('table').find('input'); - _ShowProfilesWindow(); - }; - - _CalculateProfilesWindowHeight = function() { - var height = jq("#sm_tbl_UserList").outerHeight(); - if (height > 200) { - return 270; - } - if (height == 0) { - return 100; - } - return height + 65; - }; - - _CalculateProfilesWindowPosition = function(targetElement, addTop, addLeft) { - var top = addTop == null ? 0 : addTop, - left = addLeft == null ? 0 : addLeft, - dropdownItem = jq("#divSMProfilesWindow"), - targetPos = targetElement.offset(); - elemPosTop = targetPos.top - 23 + top; - elemPosLeft = targetPos.left + targetElement.outerWidth() + 3 + left; - - dropdownItem.css( - { - 'position': 'absolute', - 'top': elemPosTop, - 'left': elemPosLeft - }); - }; - - _RenderSMProfiles = function(profiles, templateID) { - var profileCount = profiles.length; - if (profileCount > 0) { - for (var i = 0; i < profileCount; i++) { - jq.tmpl(templateID, profiles[i]).appendTo("#sm_tbl_UserList"); - } - } else { - jq("#divSMProfilesWindow .divNoProfiles").css("display", "block"); - } - }; - - _AddTwitterProfileToContactResponse = function(response) { - if (response.error != null) toastr.error("Error"); - _HideProfilesWindow(); - }; - - _ShowProfilesWindow = function() { - jq("#divSMProfilesWindow").show(); - var windowHeight = _CalculateProfilesWindowHeight(); - jq("#divSMProfilesWindow").css("height", windowHeight); - - jq("#divSMProfilesWindow").off("mouseenter").on("mouseenter", function() { - ASC.CRM.SocialMedia.MouseInProfilesWindow = true; - }); - jq("#divSMProfilesWindow").off("mouseleave").on("mouseleave", function() { - ASC.CRM.SocialMedia.MouseInProfilesWindow = false; - }); - jq(document).on("click", _CheckProfilesWindow); - }; - - _ShowWaitProfilesWindow = function(name) { - jq("#divSMProfilesWindow .divWait").show(); - jq("#divSMProfilesWindow .divHeader span").text(jq.format(ASC.CRM.Resources.CRMJSResource.PossibleSocialMediaAccounts, name)); - - var windowHeight = _CalculateProfilesWindowHeight(); - jq("#divSMProfilesWindow").css("height", windowHeight); - jq("#divSMProfilesWindow").show(); - }; - - _CheckProfilesWindow = function() { - if (ASC.CRM.SocialMedia.MouseInProfilesWindow == false) { - _HideProfilesWindow(); - } - }; - - _HideProfilesWindow = function() { - jq("#divSMProfilesWindow").hide(); - jq(document).off("click", _CheckProfilesWindow); - }; - - - return { - init: function (defaultAvatarSrc) { - ASC.CRM.SocialMedia.SocialMediaLoaded = false; - ASC.CRM.SocialMedia.ContactImageListLoaded = false; - ASC.CRM.SocialMedia.MouseInProfilesWindow = false; - ASC.CRM.SocialMedia.selectedPersons = new Array(); - ASC.CRM.SocialMedia.defaultAvatarSrc = defaultAvatarSrc; - - ASC.CRM.SocialMedia.socialNetworks = new Array(); - }, - - initTab: function (isCompany, canEdit) { - - jq.tmpl("twitterMessageListPanelTmpl").appendTo("#divSocialMediaContent"); - - jq.tmpl("template-emptyScreen", - { - ID: "tweetsEmptyScreen", - ImgSrc: ASC.CRM.Data.EmptyScrImgs["empty_screen_twitter"], - Header: ASC.CRM.Resources.CRMSocialMediaResource.EmptyContentTwitterAccountsHeader, - Describe: ASC.CRM.Resources.CRMSocialMediaResource.EmptyContentTwitterAccountsDescribe, - ButtonHTML: canEdit ? ["", - ASC.CRM.Resources.CRMSocialMediaResource.LinkTwitterAccount, - ""] - .join('') : "", - CssClass: "display-none" - }).appendTo("#divSocialMediaContent"); - }, - - activate: function (hasTwitter) { - if (ASC.CRM.SocialMedia.SocialMediaLoaded == false) { - ASC.CRM.SocialMedia.SocialMediaLoaded = true; - if (hasTwitter) { - ASC.CRM.SocialMedia.LoadContactActivity(); - } else { - jq("#tweetsEmptyScreen.display-none").removeClass("display-none"); - } - } - }, - - switchCheckedPersonsInCompany: function(checked) { - jq("#chbPersonsRelationship input[type='checkbox']").prop("checked", checked); - }, - - ShowErrorMessage: function(text) { - jq("#smErrorDescriptionContainer").css("display", "block"); - jq("#smErrorDescription").text(text); - }, - - LoadContactActivity: function() { - jq("#smErrorDescriptionContainer").css("display", "none"); - jq("#smErrorDescription").text(""); - - LoadingBanner.displayLoading(); - var contactID = jq("[id$='_ctrlContactID']").val(), - number = jq.cookies.get("sm_msg_count"); - if (number == null || number === undefined || isNaN(number)) { - number = 10; - } - - Teamlab.getCrmContactTweets({}, contactID, number, - { - max_request_attempts: 1, - success: CallbackMethods.getContactTweets, - error: function (params, errors) { - var err = errors[0]; - LoadingBanner.hideLoading(); - try { - var json = JSON.parse(err); - err = json.description; - } catch (e) { } - - if (err === ASC.CRM.Resources.SocialMediaAccountNotFoundTwitter) { - jq("#tweetsEmptyScreen.display-none").removeClass("display-none"); - } else { - ASC.CRM.SocialMedia.ShowErrorMessage(err); - } - } - }); - }, - - GetContactImageList: function() { - if (ASC.CRM.SocialMedia.socialNetworks != null && ASC.CRM.SocialMedia.socialNetworks.length != 0) { - Teamlab.getCrmContactSocialMediaAvatar({}, ASC.CRM.SocialMedia.socialNetworks, - { - max_request_attempts: 1, - success: function (params, response) { - _GetContactSMImagesResponse(response); - }, - error: function (params, errors) { - _GetContactSMImagesResponse([]); - } - }); - - } else { - _GetContactSMImagesResponse([]); - } - }, - - OpenLoadPhotoWindow: function () { - var $link = jq(".linkChangePhoto"); - if (!$link || ($link && !$link.hasClass("disable"))) { - - jq("[name='chbSocialNetwork']").prop("checked", false); - - var curAvatarSrc = jq("img.contact_photo").attr("src"); - if (curAvatarSrc.indexOf(ASC.CRM.SocialMedia.defaultAvatarSrc + '?') == 0) { - jq("#divLoadPhotoDefault").addClass("display-none"); - jq("#divLoadPhotoFromSocialMedia").css("margin-top", "10px"); - } else { - jq("#divLoadPhotoDefault").removeClass("display-none"); - jq("#divLoadPhotoFromSocialMedia").css("margin-top", "-16px"); - } - - if (ASC.CRM.SocialMedia.ContactImageListLoaded == false) { - LoadingBanner.displayLoading(); - ASC.CRM.SocialMedia.GetContactImageList(); - } else { - PopupKeyUpActionProvider.EnableEsc = false; - StudioBlockUIManager.blockUI("#divLoadPhotoWindow", 520); - } - } - }, - - SelectUserAvatar: function(event, socialNetwork, identity) { - if (!event.target) { - event.target = event.srcElement; - } - var imageChecked = jq(event.target).is(":checked"); - if (imageChecked == false) { return; } - jq("[name='chbSocialNetwork']").not(jq(event.target)).prop("checked", false); - }, - - UploadUserAvatar: function (event, socialNetwork, userIdentity) { - LoadingBanner.displayLoading(); - jq(".under_logo .linkChangePhoto").addClass("disable"); - var contactId = jq("[id$='_ctrlContactID']").val(); - if (contactId == "") { - contactId = 0; - } - var uploadOnly = jq("#divImagesHolder").attr("data-uploadOnly") == "true", - data = { contactId: contactId, socialNetwork: socialNetwork, userIdentity: userIdentity, uploadOnly: uploadOnly }; - - if (jq("#uploadPhotoPath").length == 1) { - data.tmpDirName = jq("#uploadPhotoPath").val(); - } - - Teamlab.updateCrmContactAvatar({}, contactId, data, { - success: function (params, response) { - PopupKeyUpActionProvider.CloseDialog(); - jq(".under_logo .linkChangePhoto").removeClass("disable"); - LoadingBanner.hideLoading(); - - var now = new Date(); - jq("img.contact_photo").attr("src", response.url + '?' + now.getTime()); - if (jq("#uploadPhotoPath").length == 1) { - jq("#uploadPhotoPath").val(response.path); - } - }, - error: function (params, errors) { - PopupKeyUpActionProvider.CloseDialog(); - jq(".under_logo .linkChangePhoto").removeClass("disable"); - LoadingBanner.hideLoading(); - - toastr.error(ASC.CRM.Resources.CRMJSResource.ErrorMessage_SaveImageError); - } - }); - }, - - DeleteContactAvatar: function () { - LoadingBanner.displayLoading(); - jq(".under_logo .linkChangePhoto").addClass("disable"); - var contactId = jq("[id$='_ctrlContactID']").val(); - if (contactId == "") { - contactId = 0; - } - var contactType = jq.getURLParam("type"), - uploadOnly = jq("#divImagesHolder").attr("data-uploadOnly") == "true", - data = { contactId: contactId, uploadOnly: uploadOnly, contactType: contactType }; - - Teamlab.removeCrmContactAvatar({}, contactId, data, { - success: function (params, response) { - PopupKeyUpActionProvider.CloseDialog(); - jq(".under_logo .linkChangePhoto").removeClass("disable"); - LoadingBanner.hideLoading(); - - var now = new Date(); - jq("img.contact_photo").attr("src", - [ - ASC.CRM.SocialMedia.defaultAvatarSrc, - '?', - now.getTime()] - .join('')); - if (jq("#uploadPhotoPath").length == 1) { - jq("#uploadPhotoPath").val(""); - } - }, - error: function (params, errors) { - PopupKeyUpActionProvider.CloseDialog(); - jq(".under_logo .linkChangePhoto").removeClass("disable"); - LoadingBanner.hideLoading(); - - toastr.error(ASC.CRM.Resources.CRMJSResource.ErrorMessage_SaveImageError); - } - }); - }, - - FindTwitterProfiles: function(target, contactType, addTop, addLeft) { - _HideProfilesWindow(); - jq("#divSMProfilesWindow .divNoProfiles").css("display", "none"); - jq("#sm_tbl_UserList").html(""); - jq("#divSMProfilesWindow .divSMProfilesWindowBody .errorBox").remove(); - - var searchText; - - //contact type can be "company" or "people" - if (jq("#baseInfo_Title").length == 1) { - searchText = jq("#baseInfo_Title").val().trim(); - } else { - if (contactType == "company") { - searchText = jq("[name='baseInfo_companyName']").val(); - } - if (contactType == "people") { - searchText = jq("[name='baseInfo_firstName']").val() + " " + jq("[name='baseInfo_lastName']").val(); - } - } - - if (searchText === undefined || searchText.trim().length == 0) { - return; - } - - _CalculateProfilesWindowPosition(jq(target), addTop, addLeft); - _ShowWaitProfilesWindow(searchText); - - Teamlab.getCrmContactTwitterProfiles({}, searchText, { - max_request_attempts: 1, - success: function (params, response) { - _FindTwitterProfilesResponse(target, addTop, addLeft, response); - }, - error: function (params, errors) { - var err = errors[0]; - jq("#divSMProfilesWindow .divWait").hide(); - jq("#divSMProfilesWindow .divSMProfilesWindowBody").prepend(jq("
").addClass("errorBox").text(err)); - } - }); - }, - - AddAndSaveTwitterProfileToContact: function(twitterScreenName, contactID) { - var params = {}, - data = { - data: twitterScreenName, - isPrimary: true, - infoType: "Twitter", - category: "Work" - }; - Teamlab.addCrmContactTwitter(params, contactID, data, - { - success: CallbackMethods.addAndSaveTwitter, - before: function(params) { }, - after: function(params) { _HideProfilesWindow(); } - }); - }, - - AddTwitterProfileToContact: function(twitterScreenName) { - jq(ASC.CRM.SocialMedia.TwitterTargetTextbox).val(twitterScreenName); - _HideProfilesWindow(); - } - }; -})(); \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Community/ASC.Web.Community.csproj b/web/studio/ASC.Web.Studio/Products/Community/ASC.Web.Community.csproj index 3b6c39419d..17bde47391 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/ASC.Web.Community.csproj +++ b/web/studio/ASC.Web.Studio/Products/Community/ASC.Web.Community.csproj @@ -2380,6 +2380,8 @@ + + ASPXCodeBehind diff --git a/web/studio/ASC.Web.Studio/Products/Community/App_Themes/dark/dark-params.less b/web/studio/ASC.Web.Studio/Products/Community/App_Themes/dark/dark-params.less index 4a645a32db..417ad8a7a3 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/App_Themes/dark/dark-params.less +++ b/web/studio/ASC.Web.Studio/Products/Community/App_Themes/dark/dark-params.less @@ -23,4 +23,11 @@ @body-color-hover: #474747; @dark-text-color: #fff; @dark-middle-text-color: #555555; -@body-color-bg: #333; \ No newline at end of file +@body-color-bg: #333; +@wiki-link-color: #3DB8EC; +@wiki-example-bc: #292929; +@wiki-example-bor: #666666; +@wiki-h2-bor: #505050; +@wiki-pre-bc: #292929; +@wiki-pre-bor: #666666; +@wiki-pre-col: rgba(255, 255, 255, 0.92); \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Community/App_Themes/default/images/product_logolarge_dark.svg b/web/studio/ASC.Web.Studio/Products/Community/App_Themes/default/images/product_logolarge_dark.svg new file mode 100644 index 0000000000..3f80984957 --- /dev/null +++ b/web/studio/ASC.Web.Studio/Products/Community/App_Themes/default/images/product_logolarge_dark.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/studio/ASC.Web.Studio/Products/Community/App_Themes/default/params.less b/web/studio/ASC.Web.Studio/Products/Community/App_Themes/default/params.less index 11cf021772..ea8f36e03e 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/App_Themes/default/params.less +++ b/web/studio/ASC.Web.Studio/Products/Community/App_Themes/default/params.less @@ -23,4 +23,11 @@ @body-color-hover: #E6E6E6; @dark-text-color: #000000; @dark-middle-text-color: #555555; -@body-color-bg: white; \ No newline at end of file +@body-color-bg: white; +@wiki-link-color: #002bb8; +@wiki-example-bc: #EEEEEE; +@wiki-example-bor: #CCCCCC; +@wiki-h2-bor: #000000; +@wiki-pre-bc:#F9F9F9; +@wiki-pre-bor: #2F6FAB; +@wiki-pre-col: black; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Community/Modules/Bookmarking/UserControls/BookmarkingUserControl.ascx.cs b/web/studio/ASC.Web.Studio/Products/Community/Modules/Bookmarking/UserControls/BookmarkingUserControl.ascx.cs index 76a89fad3f..48f7a09bdd 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/Modules/Bookmarking/UserControls/BookmarkingUserControl.ascx.cs +++ b/web/studio/ASC.Web.Studio/Products/Community/Modules/Bookmarking/UserControls/BookmarkingUserControl.ascx.cs @@ -34,6 +34,7 @@ using ASC.Core; using ASC.Core.Users; using ASC.Web.Community.Modules.Bookmarking.UserControls.Resources; +using ASC.Web.Core; using ASC.Web.Core.Utility.Skins; using ASC.Web.Studio.Controls.Common; using ASC.Web.Studio.UserControls.Common.ViewSwitcher; @@ -188,6 +189,8 @@ private void AddBookmarksListToPlaceHolder(IList bookmarks, HtmlGeneri [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public object RemoveBookmarkFromFavouriteInFavouriteMode(int userBookmarkID) { + CheckPermission(); + _serviceHelper.RemoveBookmarkFromFavourite(userBookmarkID); return null; } @@ -205,6 +208,8 @@ public object RemoveBookmarkFromFavouriteInFavouriteMode(int userBookmarkID) [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public object RemoveBookmarkFromFavourite(int userBookmarkID, string uniqueID) { + CheckPermission(); + var b = _serviceHelper.RemoveBookmarkFromFavourite(userBookmarkID); var displayMode = BookmarkingBusinessFactory.GetDisplayMode(); @@ -252,6 +257,8 @@ private object GetBookmarkAsString(Bookmark b, Guid uniqueID) [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public object SaveBookmark(string BookmarkUrl, string BookmarkName, string BookmarkDescription, string BookmarkTags) { + CheckPermission(); + var url = UpdateURL(BookmarkUrl); var b = _serviceHelper.AddBookmark(url, BookmarkName, BookmarkDescription, BookmarkTags); return GetBookmarkAsString(b, Guid.NewGuid()); @@ -260,6 +267,8 @@ public object SaveBookmark(string BookmarkUrl, string BookmarkName, string Bookm [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public object SaveBookmarkAjax(string BookmarkUrl, string BookmarkName, string BookmarkDescription, string BookmarkTags, string uniqueID) { + CheckPermission(); + var url = UpdateURL(BookmarkUrl); var b = _serviceHelper.AddBookmark(url, BookmarkName, BookmarkDescription, BookmarkTags); @@ -288,6 +297,8 @@ public object SaveBookmarkAjax(string BookmarkUrl, string BookmarkName, string B [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public void RemoveBookmark(int userBookmarkID) { + CheckPermission(); + _serviceHelper.RemoveBookmark(userBookmarkID); } @@ -353,6 +364,8 @@ public AjaxResponse GetSuggest(string text, string varName, int limit) [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public object GetBookmarkByUrl(string url) { + CheckPermission(); + //Create thumbnail if it doesn't exists ThumbnailHelper.Instance.MakeThumbnail(url, true, true, HttpContext.Current, TenantProvider.CurrentTenantID); @@ -376,6 +389,8 @@ private static object GetBookmarkByUrl(Bookmark b, string url) [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public object GetUserBookmarkByUrl(string url) { + CheckPermission(); + //Create bookmark thumbnail ThumbnailHelper.Instance.MakeThumbnail(url, true, true, HttpContext.Current, TenantProvider.CurrentTenantID); @@ -522,6 +537,8 @@ private static string GetXpathArgumentIgnoreCase(string argName) [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public object UpdateThumbnailImageSrc() { + CheckPermission(); + try { var displayMode = BookmarkingBusinessFactory.GetDisplayMode(); @@ -556,18 +573,24 @@ public object UpdateThumbnailImageSrc() [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public void MakeThumbnail(string url) { + CheckPermission(); + ThumbnailHelper.Instance.MakeThumbnail(url, true, true, HttpContext.Current, TenantProvider.CurrentTenantID); } [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public void GenerateAllThumbnails(bool overrideFlag) { + CheckPermission(); + BookmarkingServiceHelper.GenerateAllThumbnails(overrideFlag); } [AjaxMethod(HttpSessionStateRequirement.ReadWrite)] public void UpdateBookmarkThumbnail(int bookmarkID) { + CheckPermission(); + BookmarkingServiceHelper.UpdateBookmarkThumbnail(bookmarkID); } @@ -653,5 +676,20 @@ private void InitScripts() jsResource.Append("jq('#tableForNavigation select').val(" + BookmarkPageCounter + ").on('change', function(evt) {changeBookmarksCountOfRows(this.value);}).tlCombobox();"); Page.RegisterInlineScript(jsResource.ToString(), true); } + + private void CheckPermission() + { + var product = WebItemManager.Instance[WebItemManager.CommunityProductID]; + if (product == null || product.IsDisabled()) + { + throw new System.Security.SecurityException(); + } + + var module = WebItemManager.Instance[BookmarkingSettings.ModuleId]; + if (module == null || module.IsDisabled()) + { + throw new System.Security.SecurityException(); + } + } } } \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Community/Modules/Bookmarking/UserControls/CreateBookmarkUserControl.ascx b/web/studio/ASC.Web.Studio/Products/Community/Modules/Bookmarking/UserControls/CreateBookmarkUserControl.ascx index f639402f2b..615cd415ea 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/Modules/Bookmarking/UserControls/CreateBookmarkUserControl.ascx +++ b/web/studio/ASC.Web.Studio/Products/Community/Modules/Bookmarking/UserControls/CreateBookmarkUserControl.ascx @@ -37,7 +37,7 @@
<% } %>
diff --git a/web/studio/ASC.Web.Studio/Products/Community/Modules/Forum/UserControls/PostListControl.ascx.cs b/web/studio/ASC.Web.Studio/Products/Community/Modules/Forum/UserControls/PostListControl.ascx.cs index 86c6e64482..90d0c96040 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/Modules/Forum/UserControls/PostListControl.ascx.cs +++ b/web/studio/ASC.Web.Studio/Products/Community/Modules/Forum/UserControls/PostListControl.ascx.cs @@ -56,7 +56,8 @@ public bool VoteCallback(string pollID, List selectedVariantIDs, string var q = ForumDataProvider.GetPollByID(TenantProvider.CurrentTenantID, idQuestion); if (q == null || !_forumManager.ValidateAccessSecurityAction(ForumAction.PollVote, q) - || ForumDataProvider.IsUserVote(TenantProvider.CurrentTenantID, idQuestion, SecurityContext.CurrentAccount.ID)) + || ForumDataProvider.IsUserVote(TenantProvider.CurrentTenantID, idQuestion, SecurityContext.CurrentAccount.ID) + || (q.Type == QuestionType.OneAnswer && variantIDs.Count > 1)) { errorMessage = ForumUCResource.ErrorAccessDenied; return false; diff --git a/web/studio/ASC.Web.Studio/Products/Community/Modules/News/Code/PollVoteHandler.cs b/web/studio/ASC.Web.Studio/Products/Community/Modules/News/Code/PollVoteHandler.cs index 2e970375d0..fb5831f970 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/Modules/News/Code/PollVoteHandler.cs +++ b/web/studio/ASC.Web.Studio/Products/Community/Modules/News/Code/PollVoteHandler.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; +using System.Linq; using ASC.Core; using ASC.Web.Community.Modules.News.Resources; @@ -36,20 +37,43 @@ public bool VoteCallback(string pollID, List selectedVariantIDs, string selectedVariantIDs.ForEach(strId => { if (!string.IsNullOrEmpty(strId)) userAnswersIDs.Add(Convert.ToInt64(strId)); }); long pollId = Convert.ToInt64(additionalParams); var storage = FeedStorageFactory.Create(); + var feed = storage.GetFeed(pollId); - return VoteForPoll(userAnswersIDs, storage, pollId, out errorMessage); + return VoteForPoll(userAnswersIDs, storage, feed, out errorMessage); } - public static bool VoteForPoll(List userAnswersIDs, IFeedStorage storage, long pollId, out string errorMessage) + public static bool VoteForPoll(List userAnswersIDs, IFeedStorage storage, Feed feed, out string errorMessage) { errorMessage = string.Empty; - storage.PollVote(SecurityContext.CurrentAccount.ID.ToString(), userAnswersIDs); - var pollFeed = storage.GetFeed(pollId); - if (pollFeed == null) + + if (feed == null) + { + errorMessage = "Item not found"; + return false; + } + + if (feed.FeedType != FeedType.Poll) { - errorMessage = NewsResource.ErrorAccessDenied; + errorMessage = "Feed is not a poll"; return false; } + + var poll = feed as FeedPoll; + var currentAccountId = SecurityContext.CurrentAccount.ID.ToString(); + + if (poll.IsUserVote(currentAccountId)) + { + errorMessage = "User already voted"; + return false; + } + + if (!userAnswersIDs.Any() || (poll.PollType == FeedPollType.SimpleAnswer && userAnswersIDs.Count > 1)) + { + errorMessage = "Invalid number of answers"; + return false; + } + + storage.PollVote(currentAccountId, userAnswersIDs); return true; } diff --git a/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/Handlers/WikiFileHandler.cs b/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/Handlers/WikiFileHandler.cs index a9b776022e..867b11e3b4 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/Handlers/WikiFileHandler.cs +++ b/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/Handlers/WikiFileHandler.cs @@ -41,12 +41,28 @@ public void ProcessRequest(HttpContext context) { if (!SecurityContext.AuthenticateMe(CookiesManager.GetCookies(CookiesType.AuthKey))) { - context.Response.StatusCode = (int)HttpStatusCode.Forbidden; + context.Response.StatusCode = (int)HttpStatusCode.Unauthorized; context.Response.End(); return; } } + var product = WebItemManager.Instance[WebItemManager.CommunityProductID]; + if (product == null || product.IsDisabled()) + { + context.Response.StatusCode = (int)HttpStatusCode.Forbidden; + context.Response.End(); + return; + } + + var module = WebItemManager.Instance[WikiManager.ModuleId]; + if (module == null || module.IsDisabled()) + { + context.Response.StatusCode = (int)HttpStatusCode.Forbidden; + context.Response.End(); + return; + } + context.Response.Clear(); if (string.IsNullOrEmpty(context.Request["file"])) { diff --git a/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/ListFiles.aspx b/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/ListFiles.aspx index 92ab0ef742..68964ee9db 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/ListFiles.aspx +++ b/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/ListFiles.aspx @@ -72,7 +72,7 @@ + NavigateUrl='<%#GetFileViewLink(Container.DataItem as File)%>' Target="_blank" /> <%#GetAuthor(Container.DataItem as File)%> diff --git a/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/content/main.less b/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/content/main.less index f12f0eb9f9..6590493684 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/content/main.less +++ b/web/studio/ASC.Web.Studio/Products/Community/Modules/Wiki/content/main.less @@ -41,14 +41,14 @@ div.wiki { font-size: 12px; color: @dark-text-color; background-color: @body-color; -} -.wiki h1 { - font-size: 24px; - border-bottom: solid 1px @dark-text-color; -} -.wiki h2 { - font-size: 21px; - border-bottom: solid 1px @dark-text-color; +} +.wiki h1 { + font-size: 24px; + border-bottom: solid 1px @wiki-h2-bor; +} +.wiki h2 { + font-size: 21px; + border-bottom: solid 1px @wiki-h2-bor; } .wiki h3 { font-size: 18px; } .wiki h4 { font-size: 14px; font-weight:bold; } @@ -124,7 +124,7 @@ div.wiki { .wiki a.mail { background: url(mail_icon.gif) center right no-repeat; padding-right: 18px; padding-bottom: 2px; } .wiki a.internalNotExists { color:Red !important; } .wiki a.ftp { background: url(file_icon.gif) center right no-repeat; padding-right: 16px; } -.wiki a:link { color: #002bb8; text-decoration: none; } +.wiki a:link { color: @wiki-link-color; text-decoration: none; } .wiki a:visited { color: #5a3696; text-decoration: none; } .wiki a:active { text-decoration: none; } .wiki a:hover { text-decoration: underline; } @@ -132,9 +132,9 @@ div.wiki { .wiki dt { font-weight: bold; margin-top: 1pt; margin-bottom: 1pt; } .wiki pre { - background-color:#F9F9F9; - border:1px dashed #2F6FAB; - color:black; + background-color:@wiki-pre-bc; + border:1px dashed @wiki-pre-bor; + color:@wiki-pre-col; line-height:1.1em; padding:1em; margin:1em; @@ -164,7 +164,7 @@ div.wiki { .wiki ol li li li { list-style-type: lower-roman } .wiki ol li li li li { list-style-type: none } -div.TOC { background-color:#EEEEEE; border:1px solid #CCCCCC; margin-bottom:15px; padding:15px 10px 20px 0; width:266px; overflow:hidden;} +div.TOC { background-color:@wiki-example-bc; border:1px solid @wiki-example-bor; margin-bottom:15px; padding:15px 10px 20px 0; width:266px; overflow:hidden;} div.TOC div.TOC1 { } div.TOC div.TOC2 { margin-left: 20px; } div.TOC div.TOC3 { margin-left: 40px; } diff --git a/web/studio/ASC.Web.Studio/Products/Community/Product/CommunityProduct.cs b/web/studio/ASC.Web.Studio/Products/Community/Product/CommunityProduct.cs index e87c85facc..43f38be8b9 100644 --- a/web/studio/ASC.Web.Studio/Products/Community/Product/CommunityProduct.cs +++ b/web/studio/ASC.Web.Studio/Products/Community/Product/CommunityProduct.cs @@ -91,6 +91,7 @@ public override void Init() DisabledIconFileName = "product_disabled_logo.png", IconFileName = "product_logo.png", LargeIconFileName = "product_logolarge.svg", + LargeIconFileNameDark = "product_logolarge_dark.svg", DefaultSortOrder = 40, SubscriptionManager = new CommunitySubscriptionManager(), diff --git a/web/studio/ASC.Web.Studio/Products/Files/ASC.Web.Files.csproj b/web/studio/ASC.Web.Studio/Products/Files/ASC.Web.Files.csproj index 955b36cc09..4cb1767f76 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/ASC.Web.Files.csproj +++ b/web/studio/ASC.Web.Studio/Products/Files/ASC.Web.Files.csproj @@ -291,6 +291,7 @@ + @@ -298,6 +299,8 @@ + + @@ -348,7 +351,7 @@ - + @@ -373,9 +376,13 @@ + + + + diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/bright-blue/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/bright-blue/params.less index ab14dd44d6..6c62d3df03 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/bright-blue/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/bright-blue/params.less @@ -34,4 +34,5 @@ @textColor: #333; @borderColor: #D1D1D1; @filesHover: #f2f2f2; -@hover: #e5e5e5; \ No newline at end of file +@hover: #e5e5e5; +@thumbnails-bc-selected: #e5e5e5; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-bright-blue/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-bright-blue/params.less index 77158f3bea..c615dbd07e 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-bright-blue/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-bright-blue/params.less @@ -37,4 +37,5 @@ @textColor: #fff; @borderColor: #474747; @filesHover: #505050; -@hover: #555555; +@hover: #555555; +@thumbnails-bc-selected: #3d3d3d; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-dark-green/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-dark-green/params.less index 189cdcb1fd..c615dbd07e 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-dark-green/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-dark-green/params.less @@ -37,4 +37,5 @@ @textColor: #fff; @borderColor: #474747; @filesHover: #505050; -@hover: #555555; \ No newline at end of file +@hover: #555555; +@thumbnails-bc-selected: #3d3d3d; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-deep-blue/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-deep-blue/params.less index 189cdcb1fd..c615dbd07e 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-deep-blue/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-deep-blue/params.less @@ -37,4 +37,5 @@ @textColor: #fff; @borderColor: #474747; @filesHover: #505050; -@hover: #555555; \ No newline at end of file +@hover: #555555; +@thumbnails-bc-selected: #3d3d3d; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-default/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-default/params.less index 8b48432740..5b80f48227 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-default/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-default/params.less @@ -59,4 +59,16 @@ @sharing-dialog-bor: #474747; @uploadsvg: "uploadlight.svg"; @loader-12-gif: "loader-dark-12.svg"; -@loader-12-gray-gif: "loader-dark-12.svg"; \ No newline at end of file +@loader-12-gray-gif: "loader-dark-12.svg"; +@jstree-expander: #D6D6D6; +@thumbnails-row-selected-bor: #EEEEEE; +@thumbnails-bc-not-selected: #292929; +@thumbnails-bc-selected: #3d3d3d; +@user-svg: "user-dark.svg"; +@link-svg: "link-dark.svg"; +@settings-svg: "settings-dark.svg"; +@version-operations-col: #bdbdbd; +@version-operations-col-close: #bdbdbd; +@dropdown-folder-parent: #bdbdbd; +@dropdown-folder-parent-col: #fff; +@sharingDialogButtonArrowPart: #333; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-green/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-green/params.less index e570ba934a..93db681ee7 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-green/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-green/params.less @@ -36,4 +36,5 @@ @hover: #e5e5e5; @item-menu-selected: #333; -@item-menu-style: bold; +@item-menu-style: bold; +@thumbnails-bc-selected: #e5e5e5; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-pure-orange/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-pure-orange/params.less index 189cdcb1fd..c615dbd07e 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-pure-orange/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-pure-orange/params.less @@ -37,4 +37,5 @@ @textColor: #fff; @borderColor: #474747; @filesHover: #505050; -@hover: #555555; \ No newline at end of file +@hover: #555555; +@thumbnails-bc-selected: #3d3d3d; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-wild-pink/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-wild-pink/params.less index 189cdcb1fd..c615dbd07e 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-wild-pink/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/dark-wild-pink/params.less @@ -37,4 +37,5 @@ @textColor: #fff; @borderColor: #474747; @filesHover: #505050; -@hover: #555555; \ No newline at end of file +@hover: #555555; +@thumbnails-bc-selected: #3d3d3d; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/deep-blue/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/deep-blue/params.less index 5efcf655b4..1883686a77 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/deep-blue/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/deep-blue/params.less @@ -35,4 +35,5 @@ @textColor: #333; @borderColor: #D1D1D1; @filesHover: #f2f2f2; -@hover: #e5e5e5; \ No newline at end of file +@hover: #e5e5e5; +@thumbnails-bc-selected: #e5e5e5; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/common.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/common.less index c52315a7b6..4246e7c881 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/common.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/common.less @@ -32,11 +32,11 @@ label .checkbox { } body .may-row-to, body .may-drop-to { - background-color: @drag-and-drop; + background: @drag-and-drop !important; } .may-row-to.row-to, .may-drop-to.drop-to { - background-color: @drag-and-drop-hover; + background: @drag-and-drop-hover !important; } .stick-panel { position: fixed; diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/images/product_logolarge.svg b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/images/product_logolarge.svg index 4a115a3eb3..4f084f240d 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/images/product_logolarge.svg +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/images/product_logolarge.svg @@ -1,35 +1,35 @@ - - - - - + + + + + - + - + - + - - + + - - + + - + - + - + diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/images/product_logolarge_dark.svg b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/images/product_logolarge_dark.svg new file mode 100644 index 0000000000..b08298acf8 --- /dev/null +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/images/product_logolarge_dark.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/params.less index 7007fb9114..94f31c3540 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/default/params.less @@ -75,4 +75,16 @@ @sharing-dialog-bor: #ECECEC; @uploadsvg: "uploadblack.svg"; @loader-12-gif: "loader_12.gif"; -@loader-12-gray-gif: "loader_12_gray.gif"; \ No newline at end of file +@loader-12-gray-gif: "loader_12_gray.gif"; +@jstree-expander: #696969; +@thumbnails-row-selected-bor: #0075ff; +@thumbnails-bc-not-selected: #fff; +@thumbnails-bc-selected: #e5e5e5; +@user-svg: "user.svg"; +@link-svg: "link.svg"; +@settings-svg: "settings.svg"; +@version-operations-col: #83888d; +@version-operations-col-close: #cecece; +@dropdown-folder-parent: #92979B; +@dropdown-folder-parent-col: #83888D; +@sharingDialogButtonArrowPart: rgba(255, 255, 255, 0.3); \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/pure-orange/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/pure-orange/params.less index 12fc595991..c76e23e0f8 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/pure-orange/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/pure-orange/params.less @@ -37,4 +37,5 @@ @textColor: #333; @borderColor: #D1D1D1; @filesHover: #f2f2f2; -@hover: #e5e5e5; \ No newline at end of file +@hover: #e5e5e5; +@thumbnails-bc-selected: #e5e5e5; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/wild-pink/params.less b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/wild-pink/params.less index 40c77dc58b..afbb31dd5b 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/App_Themes/wild-pink/params.less +++ b/web/studio/ASC.Web.Studio/Products/Files/App_Themes/wild-pink/params.less @@ -34,4 +34,5 @@ @filesHover: #f2f2f2; @hover: #e5e5e5; @item-menu-selected: #e1007a; -@item-menu-style: normal; \ No newline at end of file +@item-menu-style: normal; +@thumbnails-bc-selected: #e5e5e5; \ No newline at end of file diff --git a/web/studio/ASC.Web.Studio/Products/Files/Configuration/ProductEntryPoint.cs b/web/studio/ASC.Web.Studio/Products/Files/Configuration/ProductEntryPoint.cs index 760e4bb347..9ef05caedf 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/Configuration/ProductEntryPoint.cs +++ b/web/studio/ASC.Web.Studio/Products/Files/Configuration/ProductEntryPoint.cs @@ -68,6 +68,7 @@ public override void Init() DisabledIconFileName = "product_disabled_logo.png", IconFileName = "product_logo.png", LargeIconFileName = "product_logolarge.svg", + LargeIconFileNameDark = "product_logolarge_dark.svg", DefaultSortOrder = 10, SubscriptionManager = new SubscriptionManager(), SpaceUsageStatManager = new FilesSpaceUsageStatManager(), diff --git a/web/studio/ASC.Web.Studio/Products/Files/Controls/ChunkUploadDialog/chunkuploaddialog.less b/web/studio/ASC.Web.Studio/Products/Files/Controls/ChunkUploadDialog/chunkuploaddialog.less index 203f96bcb1..430e42c8e2 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/Controls/ChunkUploadDialog/chunkuploaddialog.less +++ b/web/studio/ASC.Web.Studio/Products/Files/Controls/ChunkUploadDialog/chunkuploaddialog.less @@ -100,7 +100,7 @@ body.bright-blue .upload-svg { background: url("images/uploader_progress.gif") no-repeat scroll 0 0 @border-color; } .fu-row .progress-label { - color: @body-color; + color: #fff; float: left; font-size: 10px; margin-left: -100px; diff --git a/web/studio/ASC.Web.Studio/Products/Files/Controls/ChunkUploadDialog/chunkuploadmanager.js b/web/studio/ASC.Web.Studio/Products/Files/Controls/ChunkUploadDialog/chunkuploadmanager.js index bd3d0993e2..ab35cc0eed 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/Controls/ChunkUploadDialog/chunkuploadmanager.js +++ b/web/studio/ASC.Web.Studio/Products/Files/Controls/ChunkUploadDialog/chunkuploadmanager.js @@ -50,7 +50,6 @@ window.ASC.Files.ChunkUploads = (function () { WAITCONFIRM: 5 }; - //init chunk upload dialog var init = function (quota) { if (isInit === false) { @@ -146,12 +145,18 @@ window.ASC.Files.ChunkUploads = (function () { inputObj.appendTo(jq("#buttonUpload").parent()); - jq("#buttonUpload").on("click", function (e) { + jq("#buttonUpload, #createMesterFormFromLocalFile").on("click", function (e) { e.preventDefault(); - jq("#" + id) + var input = jq("#" + id) .removeAttr("webkitdirectory") .removeAttr("mozdirectory") - .removeAttr("directory"); + .removeAttr("directory") + .removeAttr("accept") + .removeAttr("createform"); + + if (e.target.id == "createMesterFormFromLocalFile") { + input.attr("accept", ASC.Files.Utility.Resource.InternalFormats.Document).attr("createform", true); + } if (ASC.Files.Folders.folderContainer == "privacy" && ASC.Desktop && ASC.Desktop.encryptionUploadDialog) { @@ -162,7 +167,7 @@ window.ASC.Files.ChunkUploads = (function () { ASC.Desktop.encryptionUploadDialog(uploadEncryptedFile); } else { - jq("#" + id).trigger("click"); + input.trigger("click"); } }); @@ -171,8 +176,10 @@ window.ASC.Files.ChunkUploads = (function () { jq("#" + id) .attr("webkitdirectory", true) .attr("mozdirectory", true) - .attr("directory", true); - jq("#" + id).trigger("click"); + .attr("directory", true) + .removeAttr("accept") + .removeAttr("createform") + .trigger("click"); }); }; @@ -290,6 +297,7 @@ window.ASC.Files.ChunkUploads = (function () { file.id = createNewGuid(); file.percent = 0; file.loaded = 0; + file.createform = e.target.hasAttribute("createform"); var errorMessage; if ((errorMessage = correctFile(file, folderId)) === true) { @@ -434,6 +442,9 @@ window.ASC.Files.ChunkUploads = (function () { } } else { updateFileRow(file); + if (file.createform) { + checkConvertToDocxf(file); + } } } else { @@ -534,24 +545,25 @@ window.ASC.Files.ChunkUploads = (function () { function createFolders(relativePaths) { if (relativePaths && relativePaths.length) { - var folderId = ASC.Files.Folders.currentFolder.id; + var folderId = uploadFolderId == null ? ASC.Files.Folders.currentFolder.id : uploadFolderId; window.Teamlab.createFolders({}, folderId, relativePaths, { success: function (params, data) { - var folderJsonData = { folder: data }; - var stringData = ASC.Files.Common.jsonToXml(folderJsonData); - var htmlXML = ASC.Files.TemplateManager.translateFromString(stringData); + if (folderId == ASC.Files.Folders.currentFolder.id) { + var folderJsonData = { folder: data }; + var stringData = ASC.Files.Common.jsonToXml(folderJsonData); + var htmlXML = ASC.Files.TemplateManager.translateFromString(stringData); - var folderNewObj = ASC.Files.UI.getEntryObject("folder", "0"); - var folderObj = ASC.Files.EventHandler.insertFolderItems(htmlXML, folderNewObj); + var folderNewObj = ASC.Files.UI.getEntryObject("folder", "0"); + var folderObj = ASC.Files.EventHandler.insertFolderItems(htmlXML, folderNewObj); - folderObj.yellowFade().removeClass("new-folder"); + folderObj.yellowFade().removeClass("new-folder"); - if (ASC.Files.Tree) { - ASC.Files.Tree.reloadFolder(folderId); + if (ASC.Files.Tree) { + ASC.Files.Tree.reloadFolder(folderId); + } } - - var folderTitle = ASC.Files.UI.getObjectData(folderObj).title; + var folderTitle = data.title; ASC.Files.UI.displayInfoPanel(ASC.Files.FilesJSResource.InfoCrateFolder.format(folderTitle)); }, processUrl: function (url) { @@ -583,6 +595,11 @@ window.ASC.Files.ChunkUploads = (function () { var posExt = ASC.Files.Utility.GetFileExtension(file.name); var errorMessage; + if (file.createform && posExt != ASC.Files.Utility.Resource.InternalFormats.Document) { + errorMessage = ASC.Files.FilesJSResource.ErrorMessage_WrongExtension; + ASC.Files.UI.displayInfoPanel(errorMessage, true); + return errorMessage; + } if (ASC.Files.Constants.UPLOAD_FILTER && jq.inArray(posExt, ASC.Files.Utility.Resource.ExtsUploadable) == -1) { errorMessage = ASC.Files.FilesJSResource.ErrorMassage_NotSupportedFormat; ASC.Files.UI.displayInfoPanel(errorMessage, true); @@ -1194,6 +1211,53 @@ window.ASC.Files.ChunkUploads = (function () { } }; + var checkConvertToDocxf = function (file) { + var title = file.name; + var lenExt = ASC.Files.Utility.GetFileExtension(title).length; + title = title.substring(0, title.length - lenExt); + + ASC.Files.Folders.createNewDoc({ + title: title + ASC.Files.Utility.Resource.MasterFormExtension, + entryId: file.data.id + }, false, copyFileAs); + } + var copyFileAs = function (params) { + Teamlab.copyDocFileAs(null, params.templateId, + { + destFolderId: params.folderID, + destTitle: params.fileTitle + }, + { + success: function (_, data) { + ASC.Files.ServiceManager.getFile(ASC.Files.ServiceManager.events.CreateNewFile, + { + fileId: data.id, + show: true, + isStringXml: false, + folderID: params.folderID, + winEditor: params.winEditor + }); + }, + error: function (_, error) { + var fileNewObj = ASC.Files.UI.getEntryObject("file", "0"); + ASC.Files.UI.blockObject(fileNewObj); + ASC.Files.UI.removeEntryObject(fileNewObj); + if (jq("#filesMainContent .file-row").length == 0) { + ASC.Files.EmptyScreen.displayEmptyScreen(); + } + + if (params.winEditor) { + params.winEditor.close(); + } + + ASC.Files.UI.displayInfoPanel(error[0], true); + }, + processUrl: function (url) { + return ASC.Files.Utility.AddExternalShareKey(url); + } + }); + }; + var onCheckConvertStatus = function (obj, params, errorMessage) { if (typeof obj !== "object" && typeof errorMessage != "undefined" || obj == null) { errorMessage = errorMessage || ASC.Files.FilesJSResource.ErrorMassage_ErrorConvert; diff --git a/web/studio/ASC.Web.Studio/Products/Files/Controls/ContentList/ContentList.ascx b/web/studio/ASC.Web.Studio/Products/Files/Controls/ContentList/ContentList.ascx index 64963397f7..9d141abc0c 100644 --- a/web/studio/ASC.Web.Studio/Products/Files/Controls/ContentList/ContentList.ascx +++ b/web/studio/ASC.Web.Studio/Products/Files/Controls/ContentList/ContentList.ascx @@ -7,9 +7,14 @@ <%-- Link To Parent --%>
-   - ... +   + + + + + + <%= FilesUCResource.TitleSearchIn %> @@ -21,6 +26,9 @@ <%-- Main Content --%>
+ <% if (AddFilterContainer) { %> +
+ <% } %>
    +