Merge branch 'develop' into bugfix/room-logo

This commit is contained in:
Alexey Safronov 2022-12-12 18:07:59 +03:00
commit be698591d2
104 changed files with 1765 additions and 1919 deletions

View File

@ -45,7 +45,6 @@ public class LdapUserManager
private readonly UserFormatter _userFormatter;
private readonly IServiceProvider _serviceProvider;
private readonly NovellLdapUserImporter _novellLdapUserImporter;
private readonly CountRoomAdminChecker _countRoomAdminChecker;
private LdapLocalization _resource;
public LdapUserManager(
@ -59,8 +58,7 @@ public class LdapUserManager
SettingsManager settingsManager,
DisplayUserSettingsHelper displayUserSettingsHelper,
UserFormatter userFormatter,
NovellLdapUserImporter novellLdapUserImporter,
CountRoomAdminChecker countRoomAdminChecker)
NovellLdapUserImporter novellLdapUserImporter)
{
_logger = logger;
_userManager = userManager;
@ -73,7 +71,6 @@ public class LdapUserManager
_userFormatter = userFormatter;
_serviceProvider = serviceProvider;
_novellLdapUserImporter = novellLdapUserImporter;
_countRoomAdminChecker = countRoomAdminChecker;
}
public void Init(LdapLocalization resource = null)

View File

@ -33,14 +33,11 @@ public class WhiteLabelHelper
private readonly ConcurrentDictionary<int, string> _whiteLabelDictionary;
public string DefaultLogoText { get; set; }
private readonly IConfiguration _configuration;
public WhiteLabelHelper(IConfiguration configuration, ILoggerProvider option)
public WhiteLabelHelper(ILoggerProvider option)
{
_logger = option.CreateLogger("ASC.Resources");
_whiteLabelDictionary = new ConcurrentDictionary<int, string>();
DefaultLogoText = string.Empty;
_configuration = configuration;
}
public void SetNewText(int tenantId, string newText)

View File

@ -24,15 +24,12 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
using System.ComponentModel;
namespace ASC.Core.Data;
[Scope]
public class DbLoginEventsManager
{
private const string GuidLoginEvent = "F4D8BBF6-EB63-4781-B55E-5885EAB3D759";
private static readonly TimeSpan _expirationTimeout = TimeSpan.FromMinutes(5);
private static readonly List<int> _loginActions = new List<int>
{
(int)MessageAction.LoginSuccess,
@ -69,7 +66,7 @@ public class DbLoginEventsManager
if (id < 0) return null;
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
return await loginEventContext.LoginEvents.FindAsync(id);
}
@ -126,7 +123,7 @@ public class DbLoginEventsManager
public async Task LogOutAllActiveConnectionsForTenant(int tenantId)
{
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
var events = await loginEventContext.LoginEvents
.Where(r => r.TenantId == tenantId && r.Active)
.ToListAsync();
@ -142,7 +139,7 @@ public class DbLoginEventsManager
public async Task LogOutAllActiveConnectionsExceptThis(int loginEventId, int tenantId, Guid userId)
{
using var loginEventContext = await _dbContextFactory.CreateDbContextAsync();
var events = await loginEventContext.LoginEvents
.Where(r => r.TenantId == tenantId && r.UserId == userId && r.Id != loginEventId && r.Active)
.ToListAsync();

View File

@ -30,12 +30,10 @@ namespace ASC.MessagingSystem.EF.Model;
public class MessageTarget
{
private IEnumerable<string> _items;
private readonly ILogger _logger;
private readonly ILoggerProvider _option;
public MessageTarget(ILoggerProvider option)
{
_logger = option.CreateLogger("ASC.Messaging");
_option = option;
}

View File

@ -36,10 +36,8 @@ public class BackupAjaxHandler
private readonly PermissionContext _permissionContext;
private readonly SecurityContext _securityContext;
private readonly UserManager _userManager;
private readonly TenantExtra _tenantExtra;
private readonly ConsumerFactory _consumerFactory;
private readonly BackupService _backupService;
private readonly TempPath _tempPath;
private readonly StorageFactory _storageFactory;
private const string BackupTempModule = "backup_temp";
@ -56,9 +54,7 @@ public class BackupAjaxHandler
PermissionContext permissionContext,
SecurityContext securityContext,
UserManager userManager,
TenantExtra tenantExtra,
ConsumerFactory consumerFactory,
TempPath tempPath,
StorageFactory storageFactory)
{
_tenantManager = tenantManager;
@ -68,10 +64,8 @@ public class BackupAjaxHandler
_permissionContext = permissionContext;
_securityContext = securityContext;
_userManager = userManager;
_tenantExtra = tenantExtra;
_consumerFactory = consumerFactory;
_backupService = backupService;
_tempPath = tempPath;
_storageFactory = storageFactory;
}

View File

@ -195,7 +195,7 @@ public class NotifyHelper
{
args.Add(new TagValue(CommonTags.VirtualRootPath, url));
args.Add(new TagValue(CommonTags.ProfileUrl, url + _commonLinkUtility.GetMyStaff()));
args.Add(new TagValue(CommonTags.LetterLogo, _tenantLogoManager.GetLogoDark(true)));
args.Add(new TagValue(CommonTags.LetterLogo, _tenantLogoManager.GetLogoDark(false)));
}
return args;

View File

@ -65,8 +65,6 @@ public class DbFactory
private DbProviderFactory _dbProviderFactory;
private readonly IConfiguration _configuration;
private readonly ConfigurationExtension _configurationExtension;
private string _connectionString;
private string _path;
public DbFactory(IConfiguration configuration, ConfigurationExtension configurationExtension)
{
@ -76,8 +74,6 @@ public class DbFactory
public DbConnection OpenConnection(string path = "default", string connectionString = null)
{
_connectionString = connectionString;
_path = path;
var connection = DbProviderFactory.CreateConnection();
if (connection != null)
{

View File

@ -32,25 +32,6 @@ public class CoreModuleSpecifics : ModuleSpecificsBase
public override IEnumerable<TableInfo> Tables => _tables;
public override IEnumerable<RelationInfo> TableRelations => _tableRelations;
private const string ForumsNewPostInTopicActionID = "new post in topic";
private const string ForumsNewPostInThreadActionID = "new post in thread";
private const string NewsNewCommentActionID = "new feed comment";
private const string BlogsNewCommentActionID = "new comment";
private const string CrmCompanyAclObjectStart = "ASC.CRM.Core.Entities.Company|";
private const string CrmPersonAclObjectStart = "ASC.CRM.Core.Entities.Person|";
private const string CrmDealAclObjectStart = "ASC.CRM.Core.Entities.Deal|";
private const string CrmCasesAclObjectStart = "ASC.CRM.Core.Entities.Cases|";
private const string CrmRelationshipEventAclObjectStart = "ASC.CRM.Core.Entities.RelationshipEvent|";
private const string CalendarCalendarAclObjectStart = "ASC.Api.Calendar.BusinessObjects.Calendar|";
private const string CalendarEventAclObjectStart = "ASC.Api.Calendar.BusinessObjects.Event|";
private static readonly Guid _projectsSourceID = new Guid("6045B68C-2C2E-42db-9E53-C272E814C4AD");
private static readonly Guid _bookmarksSourceID = new Guid("28B10049-DD20-4f54-B986-873BC14CCFC7");
private static readonly Guid _forumsSourceID = new Guid("853B6EB9-73EE-438d-9B09-8FFEEDF36234");
private static readonly Guid _newsSourceID = new Guid("6504977C-75AF-4691-9099-084D3DDEEA04");
private static readonly Guid _blogsSourceID = new Guid("6A598C74-91AE-437d-A5F4-AD339BD11BB2");
private readonly RelationInfo[] _tableRelations;
private readonly Helpers _helpers;
private readonly TableInfo[] _tables = new[]

View File

@ -32,8 +32,6 @@ public class WebStudioModuleSpecifics : ModuleSpecificsBase
public override IEnumerable<TableInfo> Tables => _tables;
public override IEnumerable<RelationInfo> TableRelations => _relations;
private static readonly Guid _crmSettingsId = new Guid("fdf39b9a-ec96-4eb7-aeab-63f2c608eada");
private readonly TableInfo[] _tables = new[]
{
new TableInfo("webstudio_fckuploads", "TenantID") {InsertMethod = InsertMethod.None},

View File

@ -125,12 +125,9 @@ public class CdnStorageSettings : BaseStorageSettings<CdnStorageSettings>, ISett
public class StorageSettingsHelper
{
private readonly StorageFactoryConfig _storageFactoryConfig;
private readonly PathUtils _pathUtils;
private readonly ICacheNotify<DataStoreCacheItem> _cache;
private readonly ILogger _options;
private readonly TenantManager _tenantManager;
private readonly SettingsManager _settingsManager;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly ConsumerFactory _consumerFactory;
private readonly IServiceProvider _serviceProvider;
private IDataStore _dataStore;
@ -138,9 +135,7 @@ public class StorageSettingsHelper
public StorageSettingsHelper(
BaseStorageSettingsListener baseStorageSettingsListener,
StorageFactoryConfig storageFactoryConfig,
PathUtils pathUtils,
ICacheNotify<DataStoreCacheItem> cache,
ILogger<StorageSettingsHelper> options,
TenantManager tenantManager,
SettingsManager settingsManager,
ConsumerFactory consumerFactory,
@ -148,31 +143,13 @@ public class StorageSettingsHelper
{
baseStorageSettingsListener.Subscribe();
_storageFactoryConfig = storageFactoryConfig;
_pathUtils = pathUtils;
_cache = cache;
_options = options;
_tenantManager = tenantManager;
_settingsManager = settingsManager;
_consumerFactory = consumerFactory;
_serviceProvider = serviceProvider;
}
public StorageSettingsHelper(
BaseStorageSettingsListener baseStorageSettingsListener,
StorageFactoryConfig storageFactoryConfig,
PathUtils pathUtils,
ICacheNotify<DataStoreCacheItem> cache,
ILogger<StorageSettingsHelper> options,
TenantManager tenantManager,
SettingsManager settingsManager,
IHttpContextAccessor httpContextAccessor,
ConsumerFactory consumerFactory,
IServiceProvider serviceProvider)
: this(baseStorageSettingsListener, storageFactoryConfig, pathUtils, cache, options, tenantManager, settingsManager, consumerFactory, serviceProvider)
{
_httpContextAccessor = httpContextAccessor;
}
public bool Save<T>(BaseStorageSettings<T> baseStorageSettings) where T : class, ISettings<T>, new()
{
ClearDataStoreCache();

View File

@ -1,136 +0,0 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Data.Storage.DiscStorage;
public class DiscDataHandler
{
private readonly string _physPath;
private readonly bool _checkAuth;
public DiscDataHandler(string physPath, bool checkAuth = true)
{
_physPath = physPath;
_checkAuth = checkAuth;
}
public async Task Invoke(HttpContext context)
{
//TODO
//if (_checkAuth && !Core.SecurityContext.IsAuthenticated)
//{
// context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
// return;
//}
var path = CombinePath(_physPath, context);
if (File.Exists(path))
{
var lastwrite = File.GetLastWriteTime(path);
var etag = '"' + lastwrite.Ticks.ToString("X8", CultureInfo.InvariantCulture) + '"';
var notmodified = context.Request.Headers["If-None-Match"] == etag ||
context.Request.Headers["If-Modified-Since"] == lastwrite.ToString("R");
if (notmodified)
{
context.Response.StatusCode = (int)HttpStatusCode.NotModified;
}
else
{
if (File.Exists(path + ".gz"))
{
await context.Response.SendFileAsync(path + ".gz");
context.Response.Headers["Content-Encoding"] = "gzip";
}
else
{
await context.Response.SendFileAsync(path);
}
context.Response.ContentType = MimeMapping.GetMimeMapping(path);
//TODO
//context.Response.Cache.SetVaryByCustom("*");
//context.Response.Cache.SetAllowResponseInBrowserHistory(true);
//context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(1));
//context.Response.Cache.SetLastModified(lastwrite);
//context.Response.Cache.SetETag(etag);
//context.Response.Cache.SetCacheability(HttpCacheability.Public);
}
}
else
{
context.Response.StatusCode = (int)HttpStatusCode.NotFound;
}
}
private static string CombinePath(string physPath, HttpContext requestContext)
{
var pathInfo = GetRouteValue("pathInfo").Replace('/', Path.DirectorySeparatorChar);
var path = CrossPlatform.PathCombine(physPath, pathInfo);
var tenant = GetRouteValue("0");
if (string.IsNullOrEmpty(tenant))
{
tenant = CrossPlatform.PathCombine(GetRouteValue("t1"), GetRouteValue("t2"), GetRouteValue("t3"));
}
path = path.Replace("{0}", tenant);
return path;
string GetRouteValue(string name)
{
return (requestContext.GetRouteValue(name) ?? "").ToString();
}
}
}
public static class DiscDataHandlerExtensions
{
public static IEndpointRouteBuilder RegisterDiscDataHandler(this IEndpointRouteBuilder builder, string virtPath, string physPath, bool publicRoute = false)
{
if (virtPath != "/")
{
var handler = new DiscDataHandler(physPath, !publicRoute);
var url = virtPath + "{*pathInfo}";
if (!builder.DataSources.Any(r => r.Endpoints.Any(e => e.DisplayName == url)))
{
builder.Map(url, handler.Invoke);
var newUrl = url.Replace("{0}", "{t1}/{t2}/{t3}");
if (newUrl != url)
{
builder.Map(url, handler.Invoke);
}
}
}
return builder;
}
}

View File

@ -84,8 +84,10 @@ public class NotifyHelper
Method = method,
Tenant = tenantId
};
notifyInvoke.Parameters = new List<string>();
notifyInvoke.Parameters.Add(_serverRootPath);
notifyInvoke.Parameters = new List<string>
{
_serverRootPath
};
try
{

View File

@ -72,34 +72,6 @@ public static class StorageFactoryExtenstion
var pathUtils = builder.ServiceProvider.GetService<PathUtils>();
if (section != null)
{
//old scheme
var discHandler = section.GetHandler("disc");
if (discHandler != null && section.Module != null)
{
var props = discHandler.Property != null ? discHandler.Property.ToDictionary(r => r.Name, r => r.Value) : new Dictionary<string, string>();
foreach (var m in section.Module.Where(m => m.Type == "disc"))
{
if (m.Path.Contains(Constants.StorageRootParam))
{
builder.RegisterDiscDataHandler(
pathUtils.ResolveVirtualPath(m.VirtualPath),
pathUtils.ResolvePhysicalPath(m.Path, props),
m.Public);
}
if (m.Domain != null)
{
foreach (var d in m.Domain.Where(d => (d.Type == "disc" || string.IsNullOrEmpty(d.Type)) && d.Path.Contains(Constants.StorageRootParam)))
{
builder.RegisterDiscDataHandler(
pathUtils.ResolveVirtualPath(d.VirtualPath),
pathUtils.ResolvePhysicalPath(d.Path, props));
}
}
}
}
//new scheme
if (section.Module != null)
{
foreach (var m in section.Module)

View File

@ -56,7 +56,8 @@ internal class UsersActionMapper : IModuleActionMapper
Actions = new MessageMapsDictionary(ProductType.People, Module)
{
{
EntryType.User, new Dictionary<ActionType, MessageAction[]>()
EntryType.User,
new Dictionary<ActionType, MessageAction[]>()
{
{ ActionType.Create, new[] { MessageAction.UserCreated, MessageAction.GuestCreated, MessageAction.UserCreatedViaInvite, MessageAction.GuestCreatedViaInvite } },
{
@ -80,15 +81,15 @@ internal class UsersActionMapper : IModuleActionMapper
{ MessageAction.UserLinkedSocialAccount, ActionType.Link },
{ MessageAction.UserUnlinkedSocialAccount, ActionType.Unlink },
{
ActionType.Send, new[] { MessageAction.UserSentActivationInstructions, MessageAction.UserSentDeleteInstructions, MessageAction.SentInviteInstructions }
ActionType.Send,
new[] { MessageAction.UserSentActivationInstructions, MessageAction.UserSentDeleteInstructions, MessageAction.SentInviteInstructions }
},
{ MessageAction.UserUpdatedPassword, ActionType.Update }
{ MessageAction.UserUpdatedPassword, ActionType.Update },
{ MessageAction.UserSentEmailChangeInstructions, new MessageMaps("UserSentEmailInstructions", ActionType.Send, ProductType.People, Module, EntryType.User) },
{ MessageAction.UserSentPasswordChangeInstructions, new MessageMaps("UserSentPasswordInstructions", ActionType.Send, ProductType.People, Module, EntryType.User) },
{ MessageAction.UserConnectedTfaApp, new MessageMaps("UserTfaGenerateCodes", ActionType.Link, ProductType.People, Module, EntryType.User) },
{ MessageAction.UserDisconnectedTfaApp, new MessageMaps("UserTfaDisconnected", ActionType.Delete, ProductType.People, Module, EntryType.User) }
};
Actions.Add(MessageAction.UserSentEmailChangeInstructions, new MessageMaps("UserSentEmailInstructions", ActionType.Send, ProductType.People, Module, EntryType.User));
Actions.Add(MessageAction.UserSentPasswordChangeInstructions, new MessageMaps("UserSentPasswordInstructions", ActionType.Send, ProductType.People, Module, EntryType.User));
Actions.Add(MessageAction.UserConnectedTfaApp, new MessageMaps("UserTfaGenerateCodes", ActionType.Link, ProductType.People, Module, EntryType.User));
Actions.Add(MessageAction.UserDisconnectedTfaApp, new MessageMaps("UserTfaDisconnected", ActionType.Delete, ProductType.People, Module, EntryType.User));
}
}

View File

@ -32,25 +32,19 @@ namespace ASC.Data.Backup.Controllers;
public class BackupController : ControllerBase
{
private readonly BackupAjaxHandler _backupHandler;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly TenantExtra _tenantExtra;
private readonly IEventBus _eventBus;
private readonly Guid _currentUserId;
private readonly int _tenantId;
public BackupController(
BackupAjaxHandler backupAjaxHandler,
CoreBaseSettings coreBaseSettings,
TenantManager tenantManager,
SecurityContext securityContext,
TenantExtra tenantExtra,
IEventBus eventBus)
{
_currentUserId = securityContext.CurrentAccount.ID;
_tenantId = tenantManager.GetCurrentTenant().Id;
_backupHandler = backupAjaxHandler;
_coreBaseSettings = coreBaseSettings;
_tenantExtra = tenantExtra;
_eventBus = eventBus;
}
/// <summary>

View File

@ -244,6 +244,11 @@ server {
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
}
location /logoUploader.ashx {
proxy_pass http://127.0.0.1:5000;
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;
}
location /ThirdPartyApp {
proxy_pass http://127.0.0.1:5007;
proxy_set_header X-REWRITER-URL $X_REWRITER_URL;

View File

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -0,0 +1,5 @@
<svg width="26" height="24" viewBox="0 0 26 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.411 23.7059L0.685256 18.7649C-0.228419 18.3335 -0.228419 17.6669 0.685256 17.2748L4.4194 15.5493L11.3713 18.7649C12.285 19.1963 13.7548 19.1963 14.6287 18.7649L21.5806 15.5493L25.3147 17.2748C26.2284 17.7061 26.2284 18.3728 25.3147 18.7649L14.589 23.7059C13.7548 24.0981 12.285 24.0981 11.411 23.7059Z" fill="#FF6F3D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3762 17.5917L0.683168 12.6449C-0.227723 12.213 -0.227723 11.5456 0.683168 11.153L4.32673 9.46484L11.3762 12.7234C12.2871 13.1553 13.7525 13.1553 14.6238 12.7234L21.6733 9.46484L25.3168 11.153C26.2277 11.5849 26.2277 12.2523 25.3168 12.6449L14.6238 17.5917C13.7129 18.0235 12.2475 18.0235 11.3762 17.5917Z" fill="#95C038"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3762 11.5408L0.683168 6.66521C-0.227723 6.23956 -0.227723 5.58175 0.683168 5.1948L11.3762 0.319234C12.2871 -0.106411 13.7525 -0.106411 14.6238 0.319234L25.3168 5.1948C26.2277 5.62044 26.2277 6.27826 25.3168 6.66521L14.6238 11.5408C13.7129 11.9277 12.2475 11.9277 11.3762 11.5408Z" fill="#5DC0E8"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@ -0,0 +1,27 @@
<svg width="154" height="27" viewBox="0 0 154 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_33388_366500)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6983 26.6691L0.702507 21.1155C-0.234169 20.6306 -0.234169 19.8813 0.702507 19.4406L4.53066 17.5012L11.6576 21.1155C12.5942 21.6003 14.1011 21.6003 14.997 21.1155L22.1239 17.5012L25.9521 19.4406C26.8887 19.9254 26.8887 20.6747 25.9521 21.1155L14.9563 26.6691C14.1011 27.1098 12.5942 27.1098 11.6983 26.6691Z" fill="white" fill-opacity="0.5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6983 19.8372L0.702507 14.2836C-0.234169 13.7987 -0.234169 13.0494 0.702507 12.6087L4.44921 10.7134L11.6983 14.3717C12.635 14.8565 14.1418 14.8565 15.0377 14.3717L22.2868 10.7134L26.0335 12.6087C26.9702 13.0935 26.9702 13.8428 26.0335 14.2836L15.0377 19.8372C14.1011 20.322 12.5942 20.322 11.6983 19.8372Z" fill="white" fill-opacity="0.75"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6983 13.1457L0.702507 7.59212C-0.234169 7.10729 -0.234169 6.35799 0.702507 5.91723L11.6983 0.363629C12.635 -0.12121 14.1418 -0.12121 15.0377 0.363629L26.0335 5.91723C26.9702 6.40207 26.9702 7.15136 26.0335 7.59212L15.0377 13.1457C14.1011 13.5865 12.5942 13.5865 11.6983 13.1457Z" fill="white"/>
</g>
<g clip-path="url(#clip1_33388_366500)">
<path d="M35.8789 13.4761C35.8789 10.964 36.5872 9.06815 38.051 7.83582C39.4676 6.5561 41.1675 5.93994 43.1035 5.93994C45.0395 5.93994 46.6922 6.5561 48.1088 7.83582C49.5254 9.11555 50.2337 10.964 50.2337 13.5235C50.2337 16.0355 49.5254 17.9314 48.1088 19.1637C46.6922 20.4434 44.9923 21.0596 43.1035 21.0596C41.1675 21.0596 39.5148 20.4434 38.051 19.1637C36.5872 17.884 35.8789 15.9881 35.8789 13.4761ZM38.9954 13.4761C38.9954 15.2298 39.3259 16.4621 39.9398 17.2678C40.6009 18.0736 41.3092 18.595 42.0647 18.7846C42.2536 18.8319 42.3952 18.8793 42.5841 18.8793C42.7258 18.8793 42.9146 18.9267 43.0563 18.9267C43.2452 18.9267 43.3868 18.9267 43.5757 18.8793C43.7646 18.8793 43.9063 18.8319 44.0951 18.7846C44.8507 18.595 45.559 18.0736 46.1728 17.2678C46.7867 16.4621 47.1172 15.1824 47.1172 13.5235C47.1172 11.8172 46.7867 10.5849 46.1728 9.7791C45.559 8.97335 44.8507 8.45199 44.0951 8.2624C43.9063 8.215 43.7174 8.1676 43.5757 8.1676C43.3868 8.1676 43.2452 8.12021 43.0563 8.12021C42.8674 8.12021 42.7258 8.12021 42.5841 8.1676C42.4425 8.1676 42.2536 8.215 42.0647 8.2624C41.3092 8.45199 40.6009 8.97335 39.9398 9.7791C39.3259 10.4901 38.9954 11.7698 38.9954 13.4761Z" fill="white"/>
<path d="M52.3984 5.93994H56.3087L61.4589 15.4382L62.2219 17.522H62.2696L62.2219 14.8082V5.93994H65.2261V21.0596H61.3158L56.1657 11.1737L55.4027 9.47756H55.355L55.4027 12.1429V21.0596H52.3984V5.93994Z" fill="white"/>
<path d="M68.0078 5.93994H70.9918V18.4912H76.865V21.0596H68.0078V5.93994Z" fill="white"/>
<path d="M75.5859 5.93994H79.0337L82.0565 11.1121L82.5288 12.156H82.6232L83.0955 11.1121L86.1655 5.93994H89.3299L83.9929 14.7184V20.7446H81.0174V14.6709L75.5859 5.93994Z" fill="white"/>
<path d="M89.0215 13.4761C89.0215 10.964 89.7298 9.06815 91.1936 7.83582C92.6102 6.5561 94.3101 5.93994 96.2461 5.93994C98.1821 5.93994 99.8348 6.5561 101.251 7.83582C102.668 9.11555 103.376 10.964 103.376 13.5235C103.376 16.0355 102.668 17.9314 101.251 19.1637C99.8348 20.4434 98.1349 21.0596 96.2461 21.0596C94.3101 21.0596 92.6574 20.4434 91.1936 19.1637C89.777 17.884 89.0215 15.9881 89.0215 13.4761ZM92.138 13.4761C92.138 15.2298 92.4685 16.4621 93.0824 17.2678C93.7435 18.0736 94.4045 18.595 95.2073 18.7846C95.3961 18.8319 95.5378 18.8793 95.7267 18.8793C95.8683 18.8793 96.0572 18.9267 96.1989 18.9267C96.3878 18.9267 96.5294 18.9267 96.7183 18.8793C96.9072 18.8793 97.0488 18.8319 97.2377 18.7846C97.9932 18.595 98.7015 18.0736 99.3154 17.2678C99.9292 16.4621 100.26 15.1824 100.26 13.5235C100.26 11.8172 99.9292 10.5849 99.3154 9.7791C98.7015 8.97335 97.9932 8.45199 97.2377 8.2624C97.0488 8.215 96.86 8.1676 96.7183 8.1676C96.5294 8.1676 96.3878 8.12021 96.1989 8.12021C96.01 8.12021 95.8683 8.12021 95.7267 8.1676C95.585 8.1676 95.3961 8.215 95.2073 8.2624C94.4518 8.45199 93.7435 8.97335 93.0824 9.7791C92.4685 10.4901 92.138 11.7698 92.138 13.4761Z" fill="white"/>
<path d="M105.539 5.93994H113.785V8.40739H108.525V12.0137H113.548V14.5286H108.525V20.7446H105.539V5.93994Z" fill="white"/>
<path d="M115.895 5.93994H124.141V8.40739H118.88V12.0137H123.904V14.5286H118.88V20.7446H115.895V5.93994Z" fill="white"/>
<path d="M126.32 20.7446V5.93994H129.375V20.7446H126.32Z" fill="white"/>
<path d="M143.11 6.32151V8.8971C142.585 8.70632 142.059 8.56323 141.486 8.46784C140.913 8.37244 140.244 8.32475 139.576 8.32475C137.999 8.32475 136.805 8.80171 135.946 9.80333C135.086 10.7572 134.656 11.9973 134.656 13.4759C134.656 14.9068 135.038 16.0992 135.85 17.0531C136.662 18.0071 137.808 18.5317 139.289 18.5317C139.814 18.5317 140.34 18.484 140.961 18.4363C141.582 18.3409 142.202 18.1978 142.871 17.9117L143.062 20.4396C142.967 20.4873 142.823 20.535 142.68 20.5826C142.489 20.6303 142.298 20.678 142.059 20.7257C141.677 20.8211 141.199 20.8688 140.626 20.9642C140.053 21.0119 139.48 21.0596 138.859 21.0596C138.764 21.0596 138.668 21.0596 138.62 21.0596C138.525 21.0596 138.429 21.0596 138.382 21.0596C136.662 20.9642 135.086 20.2965 133.653 19.1518C132.22 17.9594 131.504 16.0992 131.504 13.619C131.504 11.1865 132.22 9.27867 133.605 7.94318C134.99 6.60769 136.901 5.93994 139.241 5.93994C139.862 5.93994 140.435 5.93994 140.913 5.98764C141.438 6.03533 141.916 6.13073 142.441 6.22612C142.537 6.27381 142.68 6.27381 142.776 6.32151C142.871 6.27381 142.967 6.32151 143.11 6.32151Z" fill="white"/>
<path d="M145.234 5.93994H153.786V8.26503H148.161V11.9662H153.237V14.2438H148.161V18.4195H153.786V20.7446H145.234V5.93994Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_33388_366500">
<rect width="26.7367" height="26.9996" fill="white"/>
</clipPath>
<clipPath id="clip1_33388_366500">
<rect width="117.906" height="15.1197" fill="white" transform="translate(35.8789 5.93994)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -0,0 +1,27 @@
<svg width="154" height="27" viewBox="0 0 154 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_33388_366509)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6983 26.6691L0.702507 21.1155C-0.234169 20.6306 -0.234169 19.8813 0.702507 19.4406L4.53066 17.5012L11.6576 21.1155C12.5942 21.6003 14.1011 21.6003 14.997 21.1155L22.1239 17.5012L25.9521 19.4406C26.8887 19.9254 26.8887 20.6747 25.9521 21.1155L14.9563 26.6691C14.1011 27.1098 12.5942 27.1098 11.6983 26.6691Z" fill="#333333" fill-opacity="0.5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6983 19.8372L0.702507 14.2836C-0.234169 13.7987 -0.234169 13.0494 0.702507 12.6087L4.44921 10.7134L11.6983 14.3717C12.635 14.8565 14.1418 14.8565 15.0377 14.3717L22.2868 10.7134L26.0335 12.6087C26.9702 13.0935 26.9702 13.8428 26.0335 14.2836L15.0377 19.8372C14.1011 20.322 12.5942 20.322 11.6983 19.8372Z" fill="#333333" fill-opacity="0.75"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.6983 13.1457L0.702507 7.59212C-0.234169 7.10729 -0.234169 6.35799 0.702507 5.91723L11.6983 0.363629C12.635 -0.12121 14.1418 -0.12121 15.0377 0.363629L26.0335 5.91723C26.9702 6.40207 26.9702 7.15136 26.0335 7.59212L15.0377 13.1457C14.1011 13.5865 12.5942 13.5865 11.6983 13.1457Z" fill="#333333"/>
</g>
<g clip-path="url(#clip1_33388_366509)">
<path d="M35.8789 13.4761C35.8789 10.964 36.5872 9.06815 38.051 7.83582C39.4676 6.5561 41.1675 5.93994 43.1035 5.93994C45.0395 5.93994 46.6922 6.5561 48.1088 7.83582C49.5254 9.11555 50.2337 10.964 50.2337 13.5235C50.2337 16.0355 49.5254 17.9314 48.1088 19.1637C46.6922 20.4434 44.9923 21.0596 43.1035 21.0596C41.1675 21.0596 39.5148 20.4434 38.051 19.1637C36.5872 17.884 35.8789 15.9881 35.8789 13.4761ZM38.9954 13.4761C38.9954 15.2298 39.3259 16.4621 39.9398 17.2678C40.6009 18.0736 41.3092 18.595 42.0647 18.7846C42.2536 18.8319 42.3952 18.8793 42.5841 18.8793C42.7258 18.8793 42.9146 18.9267 43.0563 18.9267C43.2452 18.9267 43.3868 18.9267 43.5757 18.8793C43.7646 18.8793 43.9063 18.8319 44.0951 18.7846C44.8507 18.595 45.559 18.0736 46.1728 17.2678C46.7867 16.4621 47.1172 15.1824 47.1172 13.5235C47.1172 11.8172 46.7867 10.5849 46.1728 9.7791C45.559 8.97335 44.8507 8.45199 44.0951 8.2624C43.9063 8.215 43.7174 8.1676 43.5757 8.1676C43.3868 8.1676 43.2452 8.12021 43.0563 8.12021C42.8674 8.12021 42.7258 8.12021 42.5841 8.1676C42.4425 8.1676 42.2536 8.215 42.0647 8.2624C41.3092 8.45199 40.6009 8.97335 39.9398 9.7791C39.3259 10.4901 38.9954 11.7698 38.9954 13.4761Z" fill="#333333"/>
<path d="M52.3984 5.93994H56.3087L61.4589 15.4382L62.2219 17.522H62.2696L62.2219 14.8082V5.93994H65.2261V21.0596H61.3158L56.1657 11.1737L55.4027 9.47756H55.355L55.4027 12.1429V21.0596H52.3984V5.93994Z" fill="#333333"/>
<path d="M68.0078 5.93994H70.9918V18.4912H76.865V21.0596H68.0078V5.93994Z" fill="#333333"/>
<path d="M75.5859 5.93994H79.0337L82.0565 11.1121L82.5288 12.156H82.6232L83.0955 11.1121L86.1655 5.93994H89.3299L83.9929 14.7184V20.7446H81.0174V14.6709L75.5859 5.93994Z" fill="#333333"/>
<path d="M89.0215 13.4761C89.0215 10.964 89.7298 9.06815 91.1936 7.83582C92.6102 6.5561 94.3101 5.93994 96.2461 5.93994C98.1821 5.93994 99.8348 6.5561 101.251 7.83582C102.668 9.11555 103.376 10.964 103.376 13.5235C103.376 16.0355 102.668 17.9314 101.251 19.1637C99.8348 20.4434 98.1349 21.0596 96.2461 21.0596C94.3101 21.0596 92.6574 20.4434 91.1936 19.1637C89.777 17.884 89.0215 15.9881 89.0215 13.4761ZM92.138 13.4761C92.138 15.2298 92.4685 16.4621 93.0824 17.2678C93.7435 18.0736 94.4045 18.595 95.2073 18.7846C95.3961 18.8319 95.5378 18.8793 95.7267 18.8793C95.8683 18.8793 96.0572 18.9267 96.1989 18.9267C96.3878 18.9267 96.5294 18.9267 96.7183 18.8793C96.9072 18.8793 97.0488 18.8319 97.2377 18.7846C97.9932 18.595 98.7015 18.0736 99.3154 17.2678C99.9292 16.4621 100.26 15.1824 100.26 13.5235C100.26 11.8172 99.9292 10.5849 99.3154 9.7791C98.7015 8.97335 97.9932 8.45199 97.2377 8.2624C97.0488 8.215 96.86 8.1676 96.7183 8.1676C96.5294 8.1676 96.3878 8.12021 96.1989 8.12021C96.01 8.12021 95.8683 8.12021 95.7267 8.1676C95.585 8.1676 95.3961 8.215 95.2073 8.2624C94.4518 8.45199 93.7435 8.97335 93.0824 9.7791C92.4685 10.4901 92.138 11.7698 92.138 13.4761Z" fill="#333333"/>
<path d="M105.539 5.93994H113.785V8.40739H108.525V12.0137H113.548V14.5286H108.525V20.7446H105.539V5.93994Z" fill="#333333"/>
<path d="M115.895 5.93994H124.141V8.40739H118.88V12.0137H123.904V14.5286H118.88V20.7446H115.895V5.93994Z" fill="#333333"/>
<path d="M126.32 20.7446V5.93994H129.375V20.7446H126.32Z" fill="#333333"/>
<path d="M143.11 6.32151V8.8971C142.585 8.70632 142.059 8.56323 141.486 8.46784C140.913 8.37244 140.244 8.32475 139.576 8.32475C137.999 8.32475 136.805 8.80171 135.946 9.80333C135.086 10.7572 134.656 11.9973 134.656 13.4759C134.656 14.9068 135.038 16.0992 135.85 17.0531C136.662 18.0071 137.808 18.5317 139.289 18.5317C139.814 18.5317 140.34 18.484 140.961 18.4363C141.582 18.3409 142.202 18.1978 142.871 17.9117L143.062 20.4396C142.967 20.4873 142.823 20.535 142.68 20.5826C142.489 20.6303 142.298 20.678 142.059 20.7257C141.677 20.8211 141.199 20.8688 140.626 20.9642C140.053 21.0119 139.48 21.0596 138.859 21.0596C138.764 21.0596 138.668 21.0596 138.62 21.0596C138.525 21.0596 138.429 21.0596 138.382 21.0596C136.662 20.9642 135.086 20.2965 133.653 19.1518C132.22 17.9594 131.504 16.0992 131.504 13.619C131.504 11.1865 132.22 9.27867 133.605 7.94318C134.99 6.60769 136.901 5.93994 139.241 5.93994C139.862 5.93994 140.435 5.93994 140.913 5.98764C141.438 6.03533 141.916 6.13073 142.441 6.22612C142.537 6.27381 142.68 6.27381 142.776 6.32151C142.871 6.27381 142.967 6.32151 143.11 6.32151Z" fill="#333333"/>
<path d="M145.234 5.93994H153.786V8.26503H148.161V11.9662H153.237V14.2438H148.161V18.4195H153.786V20.7446H145.234V5.93994Z" fill="#333333"/>
</g>
<defs>
<clipPath id="clip0_33388_366509">
<rect width="26.7367" height="26.9996" fill="white"/>
</clipPath>
<clipPath id="clip1_33388_366509">
<rect width="117.906" height="15.1197" fill="white" transform="translate(35.8789 5.93994)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 144 KiB

View File

@ -1,5 +0,0 @@
<svg width="56" height="54" viewBox="0 0 56 54" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.5775 52.6067L1.47594 41.7982C-0.491979 40.8546 -0.491979 39.3964 1.47594 38.5385L9.51872 34.7642L24.492 41.7982C26.4599 42.7418 29.6257 42.7418 31.508 41.7982L46.4813 34.7642L54.5241 38.5385C56.492 39.4821 56.492 40.9404 54.5241 41.7982L31.4225 52.6067C29.6257 53.4645 26.4599 53.4645 24.5775 52.6067Z" fill="#FF6F3D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.5027 39.2315L1.47144 28.4105C-0.49048 27.4658 -0.49048 26.0058 1.47144 25.147L9.31912 21.4541L24.5027 28.5822C26.4646 29.5269 29.6207 29.5269 31.4973 28.5822L46.6809 21.4541L54.5286 25.147C56.4905 26.0917 56.4905 27.5517 54.5286 28.4105L31.4973 39.2315C29.5354 40.1762 26.3793 40.1762 24.5027 39.2315Z" fill="#95C038"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.5027 25.9954L1.47144 15.3301C-0.49048 14.399 -0.49048 12.9601 1.47144 12.1136L24.5027 1.44832C26.4646 0.517226 29.6207 0.517226 31.4973 1.44832L54.5286 12.1136C56.4905 13.0447 56.4905 14.4837 54.5286 15.3301L31.4973 25.9954C29.5354 26.8419 26.3793 26.8419 24.5027 25.9954Z" fill="#5DC0E8"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,5 @@
<svg width="26" height="24" viewBox="0 0 26 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.411 23.7059L0.685256 18.7649C-0.228419 18.3335 -0.228419 17.6669 0.685256 17.2748L4.4194 15.5493L11.3713 18.7649C12.285 19.1963 13.7548 19.1963 14.6287 18.7649L21.5806 15.5493L25.3147 17.2748C26.2284 17.7061 26.2284 18.3728 25.3147 18.7649L14.589 23.7059C13.7548 24.0981 12.285 24.0981 11.411 23.7059Z" fill="#FF6F3D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3762 17.5917L0.683168 12.6449C-0.227723 12.213 -0.227723 11.5456 0.683168 11.153L4.32673 9.46484L11.3762 12.7234C12.2871 13.1553 13.7525 13.1553 14.6238 12.7234L21.6733 9.46484L25.3168 11.153C26.2277 11.5849 26.2277 12.2523 25.3168 12.6449L14.6238 17.5917C13.7129 18.0235 12.2475 18.0235 11.3762 17.5917Z" fill="#95C038"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3762 11.5408L0.683168 6.66521C-0.227723 6.23956 -0.227723 5.58175 0.683168 5.1948L11.3762 0.319234C12.2871 -0.106411 13.7525 -0.106411 14.6238 0.319234L25.3168 5.1948C26.2277 5.62044 26.2277 6.27826 25.3168 6.66521L14.6238 11.5408C13.7129 11.9277 12.2475 11.9277 11.3762 11.5408Z" fill="#5DC0E8"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,34 +0,0 @@
<svg width="142" height="23" viewBox="0 0 142 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M31 12.0026C31 9.62504 31.6829 7.83068 33.0943 6.66435C34.4602 5.45316 36.0993 4.87 37.966 4.87C39.8326 4.87 41.4262 5.45316 42.792 6.66435C44.1579 7.87554 44.8409 9.62504 44.8409 12.0474C44.8409 14.4249 44.1579 16.2193 42.792 17.3856C41.4262 18.5968 39.7871 19.18 37.966 19.18C36.0993 19.18 34.5057 18.5968 33.0943 17.3856C31.6829 16.1744 31 14.3801 31 12.0026ZM34.0049 12.0026C34.0049 13.6623 34.3236 14.8287 34.9155 15.5913C35.5529 16.3539 36.2358 16.8473 36.9643 17.0268C37.1464 17.0716 37.283 17.1165 37.4651 17.1165C37.6017 17.1165 37.7838 17.1613 37.9204 17.1613C38.1025 17.1613 38.2391 17.1613 38.4212 17.1165C38.6034 17.1165 38.74 17.0716 38.9221 17.0268C39.6505 16.8473 40.3335 16.3539 40.9253 15.5913C41.5172 14.8287 41.8359 13.6175 41.8359 12.0474C41.8359 10.4774 41.5172 9.26617 40.9253 8.50357C40.3335 7.74097 39.6505 7.24752 38.9221 7.06808C38.74 7.02322 38.5578 6.97836 38.4212 6.97836C38.2391 6.97836 38.1025 6.93351 37.9204 6.93351C37.7383 6.93351 37.6017 6.9335 37.4651 6.97836C37.3285 6.97836 37.1464 7.02322 36.9643 7.06808C36.2358 7.24752 35.5529 7.74097 34.9155 8.50357C34.3236 9.22131 34.0049 10.3876 34.0049 12.0026Z" fill="white"/>
<path d="M46.3433 5.00449H50.0767L54.9938 13.8417L55.7223 15.7258H55.7678L55.7223 13.2585V5.00449H58.5906V19.0005H54.8573L49.9401 9.84925L49.2116 8.27919H49.1661L49.2116 10.7464V19.0005H46.3433V5.00449Z" fill="white"/>
<path d="M61.0948 5.00449H63.9631V16.6229H69.6087V19.0005H61.0948V5.00449Z" fill="white"/>
<path d="M67.8331 5.00449H71.1567L74.0705 9.93897L74.5258 10.881H74.6169L75.0722 9.93897L78.0316 5.00449H81.082L75.9372 13.3034V19.0005H73.0689V13.3034L67.8331 5.00449Z" fill="white"/>
<path d="M81.1731 12.0026C81.1731 9.62504 81.856 7.83068 83.2674 6.66435C84.6333 5.45316 86.2723 4.87 88.139 4.87C90.0057 4.87 91.5993 5.45316 92.9651 6.66435C94.331 7.87554 95.0139 9.62504 95.0139 12.0474C95.0139 14.4249 94.331 16.2193 92.9651 17.3856C91.5993 18.5968 89.9602 19.18 88.139 19.18C86.2723 19.18 84.6788 18.5968 83.2674 17.3856C81.9016 16.1744 81.1731 14.3801 81.1731 12.0026ZM84.178 12.0026C84.178 13.6623 84.4967 14.8287 85.0886 15.5913C85.726 16.3539 86.3634 16.8473 87.1374 17.0268C87.3195 17.0716 87.5016 17.1165 87.6382 17.1165C87.7748 17.1165 87.9569 17.1613 88.0935 17.1613C88.2756 17.1613 88.4122 17.1613 88.5943 17.1165C88.7764 17.1165 88.913 17.0716 89.0952 17.0268C89.8236 16.8473 90.5066 16.3539 91.0984 15.5913C91.6903 14.8287 92.009 13.6175 92.009 12.0474C92.009 10.4774 91.6903 9.26617 91.0984 8.50357C90.5066 7.74097 89.8236 7.24752 89.0952 7.06808C88.913 7.02322 88.7309 6.97836 88.5943 6.97836C88.4122 6.97836 88.2756 6.93351 88.0935 6.93351C87.9114 6.93351 87.7748 6.9335 87.6382 6.97836C87.5016 6.97836 87.3195 7.02322 87.1374 7.06808C86.4089 7.24752 85.726 7.74097 85.0886 8.50357C84.4967 9.22131 84.178 10.3876 84.178 12.0026Z" fill="#D7E4EA"/>
<path d="M96.5619 5.00449H104.484V7.38201H99.4303V10.7464H104.256V13.1239H99.4303V19.0005H96.5619V5.00449Z" fill="#D7E4EA"/>
<path d="M106.169 5.00449H114.091V7.38201H109.037V10.7464H113.863V13.1239H109.037V19.0005H106.169V5.00449Z" fill="#D7E4EA"/>
<path d="M115.775 19.0005V5.00449H118.644V19.0005H115.775Z" fill="#D7E4EA"/>
<path d="M131.665 5.3185V7.74088C131.164 7.56144 130.663 7.42687 130.117 7.33715C129.571 7.24743 128.979 7.20257 128.341 7.20257C126.839 7.20257 125.701 7.65116 124.881 8.5932C124.062 9.49038 123.652 10.6567 123.652 12.0473C123.652 13.3931 124.016 14.5146 124.79 15.4118C125.564 16.3089 126.657 16.8024 128.068 16.8024C128.569 16.8024 129.07 16.7575 129.662 16.7127C130.253 16.6229 130.845 16.4884 131.483 16.2192L131.665 18.5967C131.574 18.6416 131.437 18.6865 131.301 18.7313C131.119 18.7762 130.936 18.821 130.709 18.8659C130.345 18.9556 129.889 19.0005 129.343 19.0902C128.797 19.135 128.25 19.1799 127.658 19.1799C127.567 19.1799 127.476 19.1799 127.431 19.1799C127.34 19.1799 127.249 19.1799 127.203 19.1799C125.564 19.0902 124.062 18.4622 122.696 17.3855C121.33 16.2641 120.647 14.5146 120.647 12.1819C120.647 9.89411 121.33 8.09975 122.65 6.8437C123.97 5.58765 125.792 4.95963 128.023 4.95963C128.614 4.95963 129.161 4.95963 129.616 5.00448C130.117 5.04934 130.572 5.13906 131.073 5.22878C131.164 5.27364 131.301 5.27364 131.392 5.3185C131.437 5.27364 131.528 5.3185 131.665 5.3185Z" fill="#D7E4EA"/>
<path d="M133.486 5.00449H142V7.20257H136.4V10.7016H141.454V12.8997H136.4V16.8024H142V19.0005H133.486V5.00449Z" fill="#D7E4EA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.9389 22.718L0.657327 17.9809C-0.218514 17.5673 -0.218514 16.9282 0.657327 16.5522L4.23685 14.898L10.9009 17.9809C11.7767 18.3944 13.1857 18.3944 14.0234 17.9809L20.6874 14.898L24.267 16.5522C25.1428 16.9658 25.1428 17.6049 24.267 17.9809L13.9853 22.718C13.1857 23.094 11.7767 23.094 10.9389 22.718Z" fill="url(#paint0_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.9389 16.8906L0.657327 12.1535C-0.218514 11.7399 -0.218514 11.1008 0.657327 10.7248L4.16069 9.10815L10.9389 12.2287C11.8148 12.6422 13.2237 12.6422 14.0615 12.2287L20.8398 9.10815L24.3431 10.7248C25.219 11.1384 25.219 11.7775 24.3431 12.1535L14.0615 16.8906C13.1857 17.3042 11.7767 17.3042 10.9389 16.8906Z" fill="url(#paint1_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.9385 11.2131L0.656881 6.47597C-0.21896 6.06241 -0.21896 5.42327 0.656881 5.04731L10.9385 0.31017C11.8143 -0.10339 13.2233 -0.10339 14.0611 0.31017L24.3427 5.04731C25.2185 5.46087 25.2185 6.10001 24.3427 6.47597L14.0611 11.2131C13.1852 11.5891 11.7763 11.5891 10.9385 11.2131Z" fill="url(#paint2_linear)"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="12.4914" y1="27.2083" x2="12.4914" y2="9.91349" gradientUnits="userSpaceOnUse">
<stop stop-color="#FCC2B1"/>
<stop offset="0.8848" stop-color="#D9420B"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="12.4914" y1="19.7202" x2="12.4914" y2="8.34589" gradientUnits="userSpaceOnUse">
<stop stop-color="#DEEDC9"/>
<stop offset="0.6606" stop-color="#8BBA25"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="12.4909" y1="15.114" x2="12.4909" y2="-0.363895" gradientUnits="userSpaceOnUse">
<stop stop-color="#C2EBFA"/>
<stop offset="1" stop-color="#26A8DE"/>
</linearGradient>
<clipPath id="clip0">
<rect width="142" height="23" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,34 +0,0 @@
<svg width="142" height="23" viewBox="0 0 142 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M31 12.0026C31 9.62504 31.6829 7.83068 33.0943 6.66435C34.4602 5.45316 36.0993 4.87 37.966 4.87C39.8326 4.87 41.4262 5.45316 42.792 6.66435C44.1579 7.87554 44.8409 9.62504 44.8409 12.0474C44.8409 14.4249 44.1579 16.2193 42.792 17.3856C41.4262 18.5968 39.7871 19.18 37.966 19.18C36.0993 19.18 34.5057 18.5968 33.0943 17.3856C31.6829 16.1744 31 14.3801 31 12.0026ZM34.0049 12.0026C34.0049 13.6623 34.3236 14.8287 34.9155 15.5913C35.5529 16.3539 36.2358 16.8473 36.9643 17.0268C37.1464 17.0716 37.283 17.1165 37.4651 17.1165C37.6017 17.1165 37.7838 17.1613 37.9204 17.1613C38.1025 17.1613 38.2391 17.1613 38.4212 17.1165C38.6034 17.1165 38.74 17.0716 38.9221 17.0268C39.6505 16.8473 40.3335 16.3539 40.9253 15.5913C41.5172 14.8287 41.8359 13.6175 41.8359 12.0474C41.8359 10.4774 41.5172 9.26617 40.9253 8.50357C40.3335 7.74097 39.6505 7.24752 38.9221 7.06808C38.74 7.02322 38.5578 6.97836 38.4212 6.97836C38.2391 6.97836 38.1025 6.93351 37.9204 6.93351C37.7383 6.93351 37.6017 6.9335 37.4651 6.97836C37.3285 6.97836 37.1464 7.02322 36.9643 7.06808C36.2358 7.24752 35.5529 7.74097 34.9155 8.50357C34.3236 9.22131 34.0049 10.3876 34.0049 12.0026Z" fill="white"/>
<path d="M46.3433 5.00449H50.0767L54.9938 13.8417L55.7223 15.7258H55.7678L55.7223 13.2585V5.00449H58.5906V19.0005H54.8573L49.9401 9.84925L49.2116 8.27919H49.1661L49.2116 10.7464V19.0005H46.3433V5.00449Z" fill="white"/>
<path d="M61.0948 5.00449H63.9631V16.6229H69.6087V19.0005H61.0948V5.00449Z" fill="white"/>
<path d="M67.8331 5.00449H71.1567L74.0705 9.93897L74.5258 10.881H74.6169L75.0722 9.93897L78.0316 5.00449H81.082L75.9372 13.3034V19.0005H73.0689V13.3034L67.8331 5.00449Z" fill="white"/>
<path d="M81.1731 12.0026C81.1731 9.62504 81.856 7.83068 83.2674 6.66435C84.6333 5.45316 86.2723 4.87 88.139 4.87C90.0057 4.87 91.5993 5.45316 92.9651 6.66435C94.331 7.87554 95.0139 9.62504 95.0139 12.0474C95.0139 14.4249 94.331 16.2193 92.9651 17.3856C91.5993 18.5968 89.9602 19.18 88.139 19.18C86.2723 19.18 84.6788 18.5968 83.2674 17.3856C81.9016 16.1744 81.1731 14.3801 81.1731 12.0026ZM84.178 12.0026C84.178 13.6623 84.4967 14.8287 85.0886 15.5913C85.726 16.3539 86.3634 16.8473 87.1374 17.0268C87.3195 17.0716 87.5016 17.1165 87.6382 17.1165C87.7748 17.1165 87.9569 17.1613 88.0935 17.1613C88.2756 17.1613 88.4122 17.1613 88.5943 17.1165C88.7764 17.1165 88.913 17.0716 89.0952 17.0268C89.8236 16.8473 90.5066 16.3539 91.0984 15.5913C91.6903 14.8287 92.009 13.6175 92.009 12.0474C92.009 10.4774 91.6903 9.26617 91.0984 8.50357C90.5066 7.74097 89.8236 7.24752 89.0952 7.06808C88.913 7.02322 88.7309 6.97836 88.5943 6.97836C88.4122 6.97836 88.2756 6.93351 88.0935 6.93351C87.9114 6.93351 87.7748 6.9335 87.6382 6.97836C87.5016 6.97836 87.3195 7.02322 87.1374 7.06808C86.4089 7.24752 85.726 7.74097 85.0886 8.50357C84.4967 9.22131 84.178 10.3876 84.178 12.0026Z" fill="#D7E4EA"/>
<path d="M96.5619 5.00449H104.484V7.38201H99.4303V10.7464H104.256V13.1239H99.4303V19.0005H96.5619V5.00449Z" fill="#D7E4EA"/>
<path d="M106.169 5.00449H114.091V7.38201H109.037V10.7464H113.863V13.1239H109.037V19.0005H106.169V5.00449Z" fill="#D7E4EA"/>
<path d="M115.775 19.0005V5.00449H118.644V19.0005H115.775Z" fill="#D7E4EA"/>
<path d="M131.665 5.3185V7.74088C131.164 7.56144 130.663 7.42687 130.117 7.33715C129.571 7.24743 128.979 7.20257 128.341 7.20257C126.839 7.20257 125.701 7.65116 124.881 8.5932C124.062 9.49038 123.652 10.6567 123.652 12.0473C123.652 13.3931 124.016 14.5146 124.79 15.4118C125.564 16.3089 126.657 16.8024 128.068 16.8024C128.569 16.8024 129.07 16.7575 129.662 16.7127C130.253 16.6229 130.845 16.4884 131.483 16.2192L131.665 18.5967C131.574 18.6416 131.437 18.6865 131.301 18.7313C131.119 18.7762 130.936 18.821 130.709 18.8659C130.345 18.9556 129.889 19.0005 129.343 19.0902C128.797 19.135 128.25 19.1799 127.658 19.1799C127.567 19.1799 127.476 19.1799 127.431 19.1799C127.34 19.1799 127.249 19.1799 127.203 19.1799C125.564 19.0902 124.062 18.4622 122.696 17.3855C121.33 16.2641 120.647 14.5146 120.647 12.1819C120.647 9.89411 121.33 8.09975 122.65 6.8437C123.97 5.58765 125.792 4.95963 128.023 4.95963C128.614 4.95963 129.161 4.95963 129.616 5.00448C130.117 5.04934 130.572 5.13906 131.073 5.22878C131.164 5.27364 131.301 5.27364 131.392 5.3185C131.437 5.27364 131.528 5.3185 131.665 5.3185Z" fill="#D7E4EA"/>
<path d="M133.486 5.00449H142V7.20257H136.4V10.7016H141.454V12.8997H136.4V16.8024H142V19.0005H133.486V5.00449Z" fill="#D7E4EA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.9389 22.718L0.657327 17.9809C-0.218514 17.5673 -0.218514 16.9282 0.657327 16.5522L4.23685 14.898L10.9009 17.9809C11.7767 18.3944 13.1857 18.3944 14.0234 17.9809L20.6874 14.898L24.267 16.5522C25.1428 16.9658 25.1428 17.6049 24.267 17.9809L13.9853 22.718C13.1857 23.094 11.7767 23.094 10.9389 22.718Z" fill="url(#paint0_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.9389 16.8906L0.657327 12.1535C-0.218514 11.7399 -0.218514 11.1008 0.657327 10.7248L4.16069 9.10815L10.9389 12.2287C11.8148 12.6422 13.2237 12.6422 14.0615 12.2287L20.8398 9.10815L24.3431 10.7248C25.219 11.1384 25.219 11.7775 24.3431 12.1535L14.0615 16.8906C13.1857 17.3042 11.7767 17.3042 10.9389 16.8906Z" fill="url(#paint1_linear)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.9385 11.2131L0.656881 6.47597C-0.21896 6.06241 -0.21896 5.42327 0.656881 5.04731L10.9385 0.31017C11.8143 -0.10339 13.2233 -0.10339 14.0611 0.31017L24.3427 5.04731C25.2185 5.46087 25.2185 6.10001 24.3427 6.47597L14.0611 11.2131C13.1852 11.5891 11.7763 11.5891 10.9385 11.2131Z" fill="url(#paint2_linear)"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="12.4914" y1="27.2083" x2="12.4914" y2="9.91349" gradientUnits="userSpaceOnUse">
<stop stop-color="#FCC2B1"/>
<stop offset="0.8848" stop-color="#D9420B"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="12.4914" y1="19.7202" x2="12.4914" y2="8.34589" gradientUnits="userSpaceOnUse">
<stop stop-color="#DEEDC9"/>
<stop offset="0.6606" stop-color="#8BBA25"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="12.4909" y1="15.114" x2="12.4909" y2="-0.363895" gradientUnits="userSpaceOnUse">
<stop stop-color="#C2EBFA"/>
<stop offset="1" stop-color="#26A8DE"/>
</linearGradient>
<clipPath id="clip0">
<rect width="142" height="23" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@ -1,221 +1,221 @@
{
"Accent": "Accent",
"AccessRightsAccessToProduct": "Access to {{product}} module is given to",
"AccessRightsAllUsers": "All {{users}}",
"AccessRightsChangeOwnerConfirmText": "Changes will be applied after the confirmation via email.",
"AccessRightsProductUsersCan": "{{category}} users can",
"AccessRightsUsersFromList": "{{users}} from the list",
"AddAllowedIP": "Add allowed IP address",
"AddName": "Add Name",
"AddTrustedDomain": "Add trusted domain",
"AdditionalResources": "Additional resources",
"AdditionalResourcesDescription": "Choose whether you want to display links to additional resources in DocSpace menu.",
"Admins": "Admins",
"AdminsMessage": "Administrator Message Settings",
"AdminsMessageDescription": "Administrator Message Settings is a way to contact the portal administrator.",
"AdminsMessageHelper": "Enable this option to display the contact form on the Sign In page so that people could send the message to the portal administrator in case they have troubles accessing the portal.",
"AllDomains": "Any domains",
"AmazonBucketTip": "Enter the unique name of the Amazon S3 bucket where you want to store your backups",
"AmazonCSE": "Client-Side Encryption",
"AmazonForcePathStyleTip": "When true, requests will always use path style addressing",
"AmazonHTTPTip": "If this property is set to true, the client attempts to use HTTP protocol, if the target endpoint supports it. By default, this property is set to false",
"AmazonRegionTip": "Enter the AWS region where your Amazon bucket resides",
"AmazonSSE": "Server-Side Encryption",
"AmazonSSETip": "The Server-side encryption algorithm used when storing this object in S3",
"AmazonServiceTip": "This is an optional property; change it only if you want to try a different service endpoint",
"Appearance": "Appearance",
"AuditDownloadText": "You can download the report for the data available during the selected storage period to view the detailed statistics. Please note, that the logging is currently enabled for the Documents, Projects, CRM and People modules, as well as for portal settings.",
"AuditSubheader": "The subsection allows you to browse through the list of the latest changes (creation, modification, deletion etc.) made by users to the entities (rooms, opportunities, files etc.) on your portal.",
"AuditTrailNav": "Audit Trail",
"AutoBackup": "Automatic backup",
"AutoBackupDescription": "Use this option for automatic backup of the portal data.",
"AutoBackupHelp": "The <strong>Automatic backup</strong> option is used to automate the portal data backup process to be able to restore it later to a local server.",
"AutoBackupHelpNote": "Choose the data storage, automatic backup period and maximal number of saved copies.<br/><strong>Note:</strong> before you can save the backup data to a third-party account (DropBox, Box.com, OneDrive or Google Drive), you will need to connect this account to {{organizationName}} Common folder.",
"AutoSavePeriod": "Autosave period",
"AutoSavePeriodHelp": "The time shown below corresponds to the time zone set in the portal.",
"Backup": "Backup",
"BackupCreatedError": "An error has been encountered. Please contact your administrator.",
"BackupCreatedSuccess": "The backup copy has been successfully created.",
"BackupList": "Backup List",
"BackupListWarningText": "If you delete any items from the list, their corresponding files will also be deleted. This action cannot be undone. To delete all the files use the link:",
"Branding": "Branding",
"BrandingSectionDescription": "Specify your company information, add links to external resources, and email addresses displayed within the online office interface.",
"BrandingSubtitle": "Use this option to provide on-brand experience to your users. These settings will be effective for all of your portals.",
"BreakpointWarningText": "This section is only available in desktop version",
"BreakpointWarningTextPrompt": "Please use the desktop site to access <1>{{content}}</1>",
"BrowserNoCanvasSupport": "Your browser does not support the HTML5 canvas tag.",
"Buttons": "Buttons",
"ByApp": "By authenticator app",
"BySms": "By sms",
"ChangeLogoButton": "Change Logo",
"Characters": "{{length}} characters",
"ClearBackupList": "Delete all backups",
"CompanyInfoSettings": "Company info settings",
"CompanyInfoSettingsDescription": "This information will be displayed in the <1>{{link}}</1> window.",
"CompanyNameForCanvasLogo": "Company name",
"ConfirmEmailSended": "Confirmation e-mail has been sent to {{ownerName}}",
"Custom": "Custom",
"CustomDomains": "Custom domains",
"CustomTitles": "Custom titles",
"CustomTitlesFrom": "From",
"CustomTitlesSettingsDescription": "Welcome Page Settings is a way to change the default portal title to be displayed on the Welcome Page of your portal. The same name is also used for the From field of your portal email notifications.",
"CustomTitlesSettingsTooltip": "<0>{{ welcomeText }}</0> is a way to change the default portal title to be displayed on the <2>{{ text }}</2> of your portal. The same name is also used for the <4>{{ from }}</4> field of your portal email notifications.",
"CustomTitlesSettingsTooltipDescription": "Enter the name you like in the <1>{{ header }}</1> field.",
"CustomTitlesText": "Welcome Page",
"CustomTitlesWelcome": "Welcome Page Settings",
"Customization": "Customization",
"CustomizationDescription": "This subsection allows you to change the look and feel of your portal. You can use your own company logo, name and text to match your organization brand.",
"DNSSettings": "DNS Settings",
"DNSSettingsDescription": "DNS Settings is a way to set an alternative URL for your portal.",
"DNSSettingsMobile": "Send your request to our support team, and our specialists will help you with the settings.",
"DNSSettingsTooltip": "DNS Settings allow you to set an alternative URL address for your {{ organizationName }} portal. Send your request to our support team, and our specialists will help you with the settings.<2>{{learnMore}}</2>",
"DataBackup": "Data backup",
"Deactivate": "Deactivate",
"DeactivateOrDeletePortal": "Deactivate or delete portal.",
"DeleteDocSpace": "Delete DocSpace",
"DeleteDocSpaceInfo": "Before you delete the portal, please make sure that automatic billing is turned off. You may check the status of automatic billing in <1>on your Stripe customer portal.</1>",
"DeleteTheme": "Delete theme",
"DeleteThemeForever": "Delete theme forever?",
"DeleteThemeNotice": "The theme will be deleted permanently. You will not be able to undo this action.",
"Disabled": "Disabled",
"DownloadCopy": "Download the copy",
"DownloadReportBtn": "Download and open report",
"EditColorScheme": "Edit color scheme",
"EditCurrentTheme": "Edit current theme",
"Employees": "users",
"EmptyBackupList": "No backups have been created yet. Create one or more backups for them to appear in this list.",
"EnableAutomaticBackup": "Enable automatic backup.",
"EnableAutomaticBackupDescription": "Use this option to back up the portal data.",
"EnterTitle": "Enter title",
"EveryDay": "Every day",
"EveryMonth": "Every month",
"EveryWeek": "Every week",
"ForbiddenPageDescription": "To make changes to this section, go to the desktop version.",
"ForbiddenPageHeader": "Section unavailable.",
"ForcePathStyle": "Force Path Style",
"Group": "Group",
"GroupLead": "Group Lead",
"Groups": "Groups",
"Guests": "Guests",
"IPSecurity": "IP Security",
"IPSecurityDescription": "IP Security is used to restrict login to the portal from all IP addresses except certain addresses.",
"IPSecurityHelper": "You can set the allowed IP addresses using either exact IP addresses in the IPv4 format (#.#.#.#, where # is a numeric value from 0 to 255) or IP range (in the #.#.#.#-#.#.#.# format).",
"IPSecurityWarningHelper": "First you need to specify your current IP or the IP range your current IP address belongs to, otherwise your portal access will be blocked right after you save the settings. The portal owner will have the portal access from any IP address.",
"Job/Title": "Job/Title",
"LanguageAndTimeZoneSettingsDescription": "Language and Time Zone Settings is a way to change the language of the whole portal for all portal users and to configure the time zone so that all the events of the portal will be shown with the correct date and time.",
"LanguageTimeSettingsTooltip": "<0>{{text}}</0> is a way to change the language of the whole portal for all portal users and to configure the time zone so that all the events of the {{ organizationName }} portal will be shown with the correct date and time.",
"LanguageTimeSettingsTooltipDescription": "To make the parameters you set take effect click the <1>{{save}}</1> button at the bottom of the section.<3>{{learnMore}}</3>",
"Lifetime": "Lifetime (min)",
"LimitThemesTooltip": "You can only create 3 custom themes. To create a new one, you must delete one of the previous themes.",
"LocalFile": "Local file",
"LoginDownloadText": "You can download the report for the data available during the selected storage period to view the detailed statistics.",
"LoginHistoryTitle": "Login History",
"LoginLatestText": "Only the latest activity is shown on this page. The data itself is stored during the period specified in the field below (max 180 days).",
"LoginSubheaderTitle": "This subsection is used to monitor the latest user login activity including successful logins and failed attempts with an indication of reasons.",
"LogoAbout": "Logo for the About page",
"LogoCompact": "Logo for the compact left menu",
"LogoDocsEditor": "Logo for the editors header",
"LogoDocsEditorEmbedded": "Logo for the editors header - embedded mode",
"LogoFavicon": "Favicon",
"LogoLightSmall": "Logo for the portal header",
"LogoLogin": "Logo for the Login page",
"ManagementCategoryDataManagement": "Data Management",
"ManagementCategoryIntegration": "Integration",
"ManagementCategorySecurity": "Security",
"ManualBackupDescription": "Use this option if you want to get all data contained on the portal as a file.",
"ManualBackupHelp": "<strong>Data Backup</strong> option is used to back up the portal data to be able to restore it later to your local server.",
"ManualBackupHelpNote": "Select the storage for the data (do not forget to enter your third-party storage details to be able to access it).<br/><strong>Note:</strong> you need to connect your third-party account (DropBox, Box.com, OneDrive or Google Drive) to {{organizationName}} Common folder before you will be able to save your backup there.",
"MaxCopies": "{{copiesCount}} - maximum number of backup copies",
"Migration": "Migration",
"NewColorScheme": "New color scheme",
"PasswordMinLenght": "Minimal password length",
"Path": "Path",
"Payments": "Plans & payments",
"Plugins": "Plugins",
"PleaseNote": "Please note",
"PleaseNoteDescription": "<0>{{pleaseNote}}</0>: your old portal address will become available to new users once you click the <2>{{save}}</2> button.",
"PortalAccess": "Portal access",
"PortalAccessSubTitle": "This section allows you to provide users with safe and convenient ways to access the portal.",
"PortalDeactivation": "Deactivate DocSpace",
"PortalDeactivationDescription": "Use this option to deactivate your portal temporarily.",
"PortalDeactivationHelper": "If you wish to deactivate the portal, your portal and all information associated with it will be blocked so that no one has access to it for a particular period. To do that click the Deactivate button. A link to confirm the operation will be sent to the email address of the portal owner.\n In case you want to come back to the portal and resume using it you will need to use the second link provided in the confirmation email. So, please, keep this email in a safe place.",
"PortalDeletion": "Portal Deletion",
"PortalDeletionDescription": "Use this option to delete your portal permanently.",
"PortalDeletionEmailSended": "A link to confirm the operation has been sent to {{ownerEmail}} (the email address of the portal owner).",
"PortalDeletionHelper": "If you do not think you will use the portal and would like to delete your portal permanently submit your request using the Delete button. Please, keep in mind that you will not be able to reactivate your portal or recover any information associated with it.",
"PortalIntegration": "Portal integration",
"PortalNameEmpty": "Account name is empty",
"PortalNameIncorrect": "Incorrect account name",
"PortalNameLength": "The account name must be between 6 and 50 characters long",
"PortalRenaming": "Portal Renaming",
"PortalRenamingDescription": "Here you can change your portal address.",
"PortalRenamingLabelText": "New portal name",
"PortalRenamingMobile": "Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address. Please note: your old portal address will become available to new users once you click the Save button.",
"PortalRenamingSettingsTooltip": "<0>{{text}}</0> Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address.",
"ProductUserOpportunities": "View profiles and groups",
"RecoveryFileNotSelected": "Recovery error. Recovery file not selected",
"RegistrationDate": "Registration date",
"RestoreBackup": "Restore",
"RestoreBackupDescription": "Use this option to restore your portal from the previously saved backup file.",
"RestoreBackupResetInfoWarningText": "All current passwords will be reset. Portal users will get an email with the access restoration link.",
"RestoreBackupWarningText": "The portal will become unavailable during the restore process. After the restore is complete all the changes made after the date of the selected restore point will be lost.",
"RestoreDefaultButton": "Restore to default",
"RoomsModule": "Backup room",
"RoomsModuleDescription": "You may create a new room specifically for the backup, choose one of the existing rooms, or save the copy in their {{roomName}} room.",
"SelectFileInGZFormat": "Select the file in .GZ format",
"SendNotificationAboutRestoring": "Send notification about portal restoring to users",
"ServerSideEncryptionMethod": "Server Side Encryption Method",
"ServiceUrl": "Service Url",
"SessionLifetime": "Session Lifetime",
"SessionLifetimeDescription": "Session Lifetime allows to set time (in minutes) before the portal users will need to enter the portal credentials again in order to access the portal.",
"SessionLifetimeHelper": "After save all the users will be logged out from portal.",
"SettingPasswordStrength": "Setting password strength",
"SettingPasswordStrengthDescription": "Password Strength Settings is a way to determine the effectiveness of a password in resisting guessing and brute-force attacks.",
"SettingPasswordStrengthHelper": "Use the Minimum Password Length bar to determine how long the password should be. Check the appropriate boxes below to determine the character set that must be used in the password.",
"ShowFeedbackAndSupport": "Show Feedback & Support link",
"ShowHelpCenter": "Show link to Help Center",
"ShowVideoGuides": "Show link to Video Guides",
"SingleSignOn": "Single Sign-On",
"StoragePeriod": "Storage period",
"StudioTimeLanguageSettings": "Language and Time Zone Settings",
"SuccessfullySaveGreetingSettingsMessage": "Welcome Page settings have been successfully saved",
"SuccessfullySavePortalNameMessage": "Portal has been renamed successfully",
"SuccessfullySaveSettingsMessage": "Settings have been successfully updated",
"TeamTemplate": "Team template",
"TeamTemplateSettingsDescription": "Team Template is a customizable way to name the organization (or group), its members and their activities. Drop down the Template list to choose one of the available presets or enter the names yourselves selecting the custom option from the list.",
"Template": "Template",
"TemporaryStorage": "Temporary storage",
"TemporaryStorageDescription": "Backup is stored in the 'Backup' section, you will be able to download it within 24 hours after creating.",
"ThirdPartyAuthorization": "Third-party Authorization",
"ThirdPartyBodyDescription": "Detailed instructions in our <2>Help Center</2>.",
"ThirdPartyBottomDescription": "Need help? Contact our <2>Support Team.</2>",
"ThirdPartyHowItWorks": "How It Works?",
"ThirdPartyPropsActivated": "Updated successfully",
"ThirdPartyPropsDeactivated": "Deactivated successfully",
"ThirdPartyResource": "Third-party resource",
"ThirdPartyResourceDescription": "Backup can be saved to your third-party account (Dropbox, Box.com, OneDrive or Google Drive). You need to connect your third-party account (Dropbox, Box.com, OneDrive or Google Drive) before you will be able to save your backup there.",
"ThirdPartyStorage": "Third-party storage",
"ThirdPartyStorageDescription": "Backup can be saved to a third-party storage. Before, you need to connect the corresponding service in the 'Integration' section. Otherwise, the following settings will be inactive.",
"ThirdPartyTitle": "Third-party services",
"ThirdPartyTitleDescription": "With Authorization keys, you can connect third-party services to your portal. Sign in easily with Facebook, Twitter, or LinkedIn; add Dropbox, OneDrive, etc. to work with files stored there from the Documents module.",
"TimeZone": "Time zone",
"TrustedMail": "Trusted mail domain settings",
"TrustedMailDescription": "Trusted Mail Domain Settings is a way to specify the mail servers used for user self-registration.",
"TrustedMailHelper": "You can either check the Custom domains option and enter the trusted mail server in the field below so that a person who has an account at it will be able to register him(her)self by clicking the Join link on the Sign In page or disable this option.",
"TwoFactorAuth": "Two-factor authentication",
"TwoFactorAuthDescription": "Two-factor authentication provides a more secure way to log in. After entering the credentials, the user will have to enter a code from an SMS or the authentication app.",
"TwoFactorAuthHelper": "Note: SMS messages can be sent if you have a positive balance only. You can always check your current balance in your SMS provider account. Do not forget to replenish your balance in good time.",
"UseAsLogoButton": "Use as logo",
"UseDigits": "Use digits",
"UseHttp": "Use Http",
"UseSpecialChar": "Use special characters",
"UseUpperCase": "Use capital letters",
"UserAgreement": "I confirm and want to proceed",
"Users": "Users",
"WhiteLabel": "White label",
"WhiteLabelHelper": "Use PNG images with a transparent background",
"WhiteLabelSubtitle": "Enter your company name, upload the logo, and customize the styling to match your branding.",
"WhiteLabelTooltip": "The sizes are shown for the Retina displays. For the displays with standard resolutions the logo width and height will be resized accordingly upon upload.",
"YouHaveUnsavedChanges": "You have unsaved changes",
"YourCurrentDomain": "Your current domain"
}
{
"Accent": "Accent",
"AccessRightsAccessToProduct": "Access to {{product}} module is given to",
"AccessRightsAllUsers": "All {{users}}",
"AccessRightsChangeOwnerConfirmText": "Changes will be applied after the confirmation via email.",
"AccessRightsProductUsersCan": "{{category}} users can",
"AccessRightsUsersFromList": "{{users}} from the list",
"AddAllowedIP": "Add allowed IP address",
"AddName": "Add Name",
"AddTrustedDomain": "Add trusted domain",
"AdditionalResources": "Additional resources",
"AdditionalResourcesDescription": "Choose whether you want to display links to additional resources in DocSpace menu.",
"Admins": "Admins",
"AdminsMessage": "Administrator Message Settings",
"AdminsMessageDescription": "Administrator Message Settings is a way to contact the portal administrator.",
"AdminsMessageHelper": "Enable this option to display the contact form on the Sign In page so that people could send the message to the portal administrator in case they have troubles accessing the portal.",
"AllDomains": "Any domains",
"AmazonBucketTip": "Enter the unique name of the Amazon S3 bucket where you want to store your backups",
"AmazonCSE": "Client-Side Encryption",
"AmazonForcePathStyleTip": "When true, requests will always use path style addressing",
"AmazonHTTPTip": "If this property is set to true, the client attempts to use HTTP protocol, if the target endpoint supports it. By default, this property is set to false",
"AmazonRegionTip": "Enter the AWS region where your Amazon bucket resides",
"AmazonSSE": "Server-Side Encryption",
"AmazonSSETip": "The Server-side encryption algorithm used when storing this object in S3",
"AmazonServiceTip": "This is an optional property; change it only if you want to try a different service endpoint",
"Appearance": "Appearance",
"AuditDownloadText": "You can download the report for the data available during the selected storage period to view the detailed statistics. Please note, that the logging is currently enabled for the Documents, Projects, CRM and People modules, as well as for portal settings.",
"AuditSubheader": "The subsection allows you to browse through the list of the latest changes (creation, modification, deletion etc.) made by users to the entities (rooms, opportunities, files etc.) on your portal.",
"AuditTrailNav": "Audit Trail",
"AutoBackup": "Automatic backup",
"AutoBackupDescription": "Use this option for automatic backup of the portal data.",
"AutoBackupHelp": "The <strong>Automatic backup</strong> option is used to automate the portal data backup process to be able to restore it later to a local server.",
"AutoBackupHelpNote": "Choose the data storage, automatic backup period and maximal number of saved copies.<br/><strong>Note:</strong> before you can save the backup data to a third-party account (DropBox, Box.com, OneDrive or Google Drive), you will need to connect this account to {{organizationName}} Common folder.",
"AutoSavePeriod": "Autosave period",
"AutoSavePeriodHelp": "The time shown below corresponds to the time zone set in the portal.",
"Backup": "Backup",
"BackupCreatedError": "An error has been encountered. Please contact your administrator.",
"BackupCreatedSuccess": "The backup copy has been successfully created.",
"BackupList": "Backup List",
"BackupListWarningText": "If you delete any items from the list, their corresponding files will also be deleted. This action cannot be undone. To delete all the files use the link:",
"Branding": "Branding",
"BrandingSectionDescription": "Specify your company information, add links to external resources, and email addresses displayed within the online office interface.",
"BrandingSubtitle": "Use this option to provide on-brand experience to your users. These settings will be effective for all of your portals.",
"BreakpointWarningText": "This section is only available in desktop version",
"BreakpointWarningTextPrompt": "Please use the desktop site to access <1>{{content}}</1>",
"BrowserNoCanvasSupport": "Your browser does not support the HTML5 canvas tag.",
"Buttons": "Buttons",
"ByApp": "By authenticator app",
"BySms": "By sms",
"ChangeLogoButton": "Change Logo",
"Characters": "{{length}} characters",
"ClearBackupList": "Delete all backups",
"CompanyInfoSettings": "Company info settings",
"CompanyInfoSettingsDescription": "This information will be displayed in the <1>{{link}}</1> window.",
"CompanyNameForCanvasLogo": "Company name",
"ConfirmEmailSended": "Confirmation e-mail has been sent to {{ownerName}}",
"Custom": "Custom",
"CustomDomains": "Custom domains",
"CustomTitles": "Custom titles",
"CustomTitlesFrom": "From",
"CustomTitlesSettingsDescription": "Welcome Page Settings is a way to change the default portal title to be displayed on the Welcome Page of your portal. The same name is also used for the From field of your portal email notifications.",
"CustomTitlesSettingsTooltip": "<0>{{ welcomeText }}</0> is a way to change the default portal title to be displayed on the <2>{{ text }}</2> of your portal. The same name is also used for the <4>{{ from }}</4> field of your portal email notifications.",
"CustomTitlesSettingsTooltipDescription": "Enter the name you like in the <1>{{ header }}</1> field.",
"CustomTitlesText": "Welcome Page",
"CustomTitlesWelcome": "Welcome Page Settings",
"Customization": "Customization",
"CustomizationDescription": "This subsection allows you to change the look and feel of your portal. You can use your own company logo, name and text to match your organization brand.",
"DNSSettings": "DNS Settings",
"DNSSettingsDescription": "DNS Settings is a way to set an alternative URL for your portal.",
"DNSSettingsMobile": "Send your request to our support team, and our specialists will help you with the settings.",
"DNSSettingsTooltip": "DNS Settings allow you to set an alternative URL address for your {{ organizationName }} portal. Send your request to our support team, and our specialists will help you with the settings.<2>{{learnMore}}</2>",
"DataBackup": "Data backup",
"Deactivate": "Deactivate",
"DeactivateOrDeletePortal": "Deactivate or delete portal.",
"DeleteDocSpace": "Delete DocSpace",
"DeleteDocSpaceInfo": "Before you delete the portal, please make sure that automatic billing is turned off. You may check the status of automatic billing in <1>on your Stripe customer portal.</1>",
"DeleteTheme": "Delete theme",
"DeleteThemeForever": "Delete theme forever?",
"DeleteThemeNotice": "The theme will be deleted permanently. You will not be able to undo this action.",
"Disabled": "Disabled",
"DownloadCopy": "Download the copy",
"DownloadReportBtn": "Download and open report",
"EditColorScheme": "Edit color scheme",
"EditCurrentTheme": "Edit current theme",
"Employees": "users",
"EmptyBackupList": "No backups have been created yet. Create one or more backups for them to appear in this list.",
"EnableAutomaticBackup": "Enable automatic backup.",
"EnableAutomaticBackupDescription": "Use this option to back up the portal data.",
"EnterTitle": "Enter title",
"EveryDay": "Every day",
"EveryMonth": "Every month",
"EveryWeek": "Every week",
"ForbiddenPageDescription": "To make changes to this section, go to the desktop version.",
"ForbiddenPageHeader": "Section unavailable.",
"ForcePathStyle": "Force Path Style",
"Group": "Group",
"GroupLead": "Group Lead",
"Groups": "Groups",
"Guests": "Guests",
"IPSecurity": "IP Security",
"IPSecurityDescription": "IP Security is used to restrict login to the portal from all IP addresses except certain addresses.",
"IPSecurityHelper": "You can set the allowed IP addresses using either exact IP addresses in the IPv4 format (#.#.#.#, where # is a numeric value from 0 to 255) or IP range (in the #.#.#.#-#.#.#.# format).",
"IPSecurityWarningHelper": "First you need to specify your current IP or the IP range your current IP address belongs to, otherwise your portal access will be blocked right after you save the settings. The portal owner will have the portal access from any IP address.",
"Job/Title": "Job/Title",
"LanguageAndTimeZoneSettingsDescription": "Language and Time Zone Settings is a way to change the language of the whole portal for all portal users and to configure the time zone so that all the events of the portal will be shown with the correct date and time.",
"LanguageTimeSettingsTooltip": "<0>{{text}}</0> is a way to change the language of the whole portal for all portal users and to configure the time zone so that all the events of the {{ organizationName }} portal will be shown with the correct date and time.",
"LanguageTimeSettingsTooltipDescription": "To make the parameters you set take effect click the <1>{{save}}</1> button at the bottom of the section.<3>{{learnMore}}</3>",
"Lifetime": "Lifetime (min)",
"LimitThemesTooltip": "You can only create 3 custom themes. To create a new one, you must delete one of the previous themes.",
"LocalFile": "Local file",
"LoginDownloadText": "You can download the report for the data available during the selected storage period to view the detailed statistics.",
"LoginHistoryTitle": "Login History",
"LoginLatestText": "Only the latest activity is shown on this page. The data itself is stored during the period specified in the field below (max 180 days).",
"LoginSubheaderTitle": "This subsection is used to monitor the latest user login activity including successful logins and failed attempts with an indication of reasons.",
"LogoAbout": "Logo for the About page",
"LogoCompact": "Logo for the compact left menu",
"LogoDocsEditor": "Logo for the editors header",
"LogoDocsEditorEmbedded": "Logo for the editors header - embedded mode",
"LogoFavicon": "Favicon",
"LogoLightSmall": "Logo for the portal header",
"LogoLogin": "Logo for the Login page",
"ManagementCategoryDataManagement": "Data Management",
"ManagementCategoryIntegration": "Integration",
"ManagementCategorySecurity": "Security",
"ManualBackupDescription": "Use this option if you want to get all data contained on the portal as a file.",
"ManualBackupHelp": "<strong>Data Backup</strong> option is used to back up the portal data to be able to restore it later to your local server.",
"ManualBackupHelpNote": "Select the storage for the data (do not forget to enter your third-party storage details to be able to access it).<br/><strong>Note:</strong> you need to connect your third-party account (DropBox, Box.com, OneDrive or Google Drive) to {{organizationName}} Common folder before you will be able to save your backup there.",
"MaxCopies": "{{copiesCount}} - maximum number of backup copies",
"Migration": "Migration",
"NewColorScheme": "New color scheme",
"PasswordMinLenght": "Minimal password length",
"Path": "Path",
"Payments": "Plans & payments",
"Plugins": "Plugins",
"PleaseNote": "Please note",
"PleaseNoteDescription": "<0>{{pleaseNote}}</0>: your old portal address will become available to new users once you click the <2>{{save}}</2> button.",
"PortalAccess": "Portal access",
"PortalAccessSubTitle": "This section allows you to provide users with safe and convenient ways to access the portal.",
"PortalDeactivation": "Deactivate DocSpace",
"PortalDeactivationDescription": "Use this option to deactivate your portal temporarily.",
"PortalDeactivationHelper": "If you wish to deactivate the portal, your portal and all information associated with it will be blocked so that no one has access to it for a particular period. To do that click the Deactivate button. A link to confirm the operation will be sent to the email address of the portal owner.\n In case you want to come back to the portal and resume using it you will need to use the second link provided in the confirmation email. So, please, keep this email in a safe place.",
"PortalDeletion": "Portal Deletion",
"PortalDeletionDescription": "Use this option to delete your portal permanently.",
"PortalDeletionEmailSended": "A link to confirm the operation has been sent to {{ownerEmail}} (the email address of the portal owner).",
"PortalDeletionHelper": "If you do not think you will use the portal and would like to delete your portal permanently submit your request using the Delete button. Please, keep in mind that you will not be able to reactivate your portal or recover any information associated with it.",
"PortalIntegration": "Portal integration",
"PortalNameEmpty": "Account name is empty",
"PortalNameIncorrect": "Incorrect account name",
"PortalNameLength": "The account name must be between 6 and 50 characters long",
"PortalRenaming": "Portal Renaming",
"PortalRenamingDescription": "Here you can change your portal address.",
"PortalRenamingLabelText": "New portal name",
"PortalRenamingMobile": "Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address. Please note: your old portal address will become available to new users once you click the Save button.",
"PortalRenamingSettingsTooltip": "<0>{{text}}</0> Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address.",
"ProductUserOpportunities": "View profiles and groups",
"RecoveryFileNotSelected": "Recovery error. Recovery file not selected",
"RegistrationDate": "Registration date",
"RestoreBackup": "Restore",
"RestoreBackupDescription": "Use this option to restore your portal from the previously saved backup file.",
"RestoreBackupResetInfoWarningText": "All current passwords will be reset. Portal users will get an email with the access restoration link.",
"RestoreBackupWarningText": "The portal will become unavailable during the restore process. After the restore is complete all the changes made after the date of the selected restore point will be lost.",
"RestoreDefaultButton": "Restore to default",
"RoomsModule": "Backup room",
"RoomsModuleDescription": "You may create a new room specifically for the backup, choose one of the existing rooms, or save the copy in their {{roomName}} room.",
"SelectFileInGZFormat": "Select the file in .GZ format",
"SendNotificationAboutRestoring": "Send notification about portal restoring to users",
"ServerSideEncryptionMethod": "Server Side Encryption Method",
"ServiceUrl": "Service Url",
"SessionLifetime": "Session Lifetime",
"SessionLifetimeDescription": "Session Lifetime allows to set time (in minutes) before the portal users will need to enter the portal credentials again in order to access the portal.",
"SessionLifetimeHelper": "After save all the users will be logged out from portal.",
"SettingPasswordStrength": "Setting password strength",
"SettingPasswordStrengthDescription": "Password Strength Settings is a way to determine the effectiveness of a password in resisting guessing and brute-force attacks.",
"SettingPasswordStrengthHelper": "Use the Minimum Password Length bar to determine how long the password should be. Check the appropriate boxes below to determine the character set that must be used in the password.",
"ShowFeedbackAndSupport": "Show Feedback & Support link",
"ShowHelpCenter": "Show link to Help Center",
"ShowVideoGuides": "Show link to Video Guides",
"SingleSignOn": "Single Sign-On",
"StoragePeriod": "Storage period",
"StudioTimeLanguageSettings": "Language and Time Zone Settings",
"SuccessfullySaveGreetingSettingsMessage": "Welcome Page settings have been successfully saved",
"SuccessfullySavePortalNameMessage": "Portal has been renamed successfully",
"SuccessfullySaveSettingsMessage": "Settings have been successfully updated",
"TeamTemplate": "Team template",
"TeamTemplateSettingsDescription": "Team Template is a customizable way to name the organization (or group), its members and their activities. Drop down the Template list to choose one of the available presets or enter the names yourselves selecting the custom option from the list.",
"Template": "Template",
"TemporaryStorage": "Temporary storage",
"TemporaryStorageDescription": "Backup is stored in the 'Backup' section, you will be able to download it within 24 hours after creating.",
"ThirdPartyAuthorization": "Third-party Authorization",
"ThirdPartyBodyDescription": "Detailed instructions in our <2>Help Center</2>.",
"ThirdPartyBottomDescription": "Need help? Contact our <2>Support Team.</2>",
"ThirdPartyHowItWorks": "How It Works?",
"ThirdPartyPropsActivated": "Updated successfully",
"ThirdPartyPropsDeactivated": "Deactivated successfully",
"ThirdPartyResource": "Third-party resource",
"ThirdPartyResourceDescription": "Backup can be saved to your third-party account (Dropbox, Box.com, OneDrive or Google Drive). You need to connect your third-party account (Dropbox, Box.com, OneDrive or Google Drive) before you will be able to save your backup there.",
"ThirdPartyStorage": "Third-party storage",
"ThirdPartyStorageDescription": "Backup can be saved to a third-party storage. Before, you need to connect the corresponding service in the 'Integration' section. Otherwise, the following settings will be inactive.",
"ThirdPartyTitle": "Third-party services",
"ThirdPartyTitleDescription": "With Authorization keys, you can connect third-party services to your portal. Sign in easily with Facebook, Twitter, or LinkedIn; add Dropbox, OneDrive, etc. to work with files stored there from the Documents module.",
"TimeZone": "Time zone",
"TrustedMail": "Trusted mail domain settings",
"TrustedMailDescription": "Trusted Mail Domain Settings is a way to specify the mail servers used for user self-registration.",
"TrustedMailHelper": "You can either check the Custom domains option and enter the trusted mail server in the field below so that a person who has an account at it will be able to register him(her)self by clicking the Join link on the Sign In page or disable this option.",
"TwoFactorAuth": "Two-factor authentication",
"TwoFactorAuthDescription": "Two-factor authentication provides a more secure way to log in. After entering the credentials, the user will have to enter a code from an SMS or the authentication app.",
"TwoFactorAuthHelper": "Note: SMS messages can be sent if you have a positive balance only. You can always check your current balance in your SMS provider account. Do not forget to replenish your balance in good time.",
"UseAsLogoButton": "Use as logo",
"UseDigits": "Use digits",
"UseHttp": "Use Http",
"UseSpecialChar": "Use special characters",
"UseUpperCase": "Use capital letters",
"UserAgreement": "I confirm and want to proceed",
"Users": "Users",
"WhiteLabel": "White label",
"WhiteLabelHelper": "Use images with a transparent background. (PNG, SVG, JPG)",
"WhiteLabelSubtitle": "Enter your company name, upload the logo, and customize the styling to match your branding.",
"WhiteLabelTooltip": "The sizes are shown for the Retina displays. For the displays with standard resolutions the logo width and height will be resized accordingly upon upload.",
"YouHaveUnsavedChanges": "You have unsaved changes",
"YourCurrentDomain": "Your current domain"
}

View File

@ -2,36 +2,41 @@ import React from "react";
import styled from "styled-components";
import { ReactSVG } from "react-svg";
import { hugeMobile } from "@docspace/components/utils/device";
import { isMobileOnly } from "react-device-detect";
import { inject, observer } from "mobx-react";
const StyledWrapper = styled.div`
.logo-wrapper {
width: 100%;
height: 46px;
width: 386px;
height: 44px;
}
svg {
path:last-child {
fill: ${(props) => props.theme.client.home.logoColor};
}
}
@media ${hugeMobile} {
display: none;
}
@media ${hugeMobile} {
display: none;
}
`;
const DocspaceLogo = (props) => {
const { className } = props;
if (isMobileOnly) return <></>;
const { className, whiteLabelLogoUrls, userTheme } = props;
const logo =
userTheme === "Dark"
? whiteLabelLogoUrls[1]?.path?.dark
: whiteLabelLogoUrls[1]?.path?.light;
return (
<StyledWrapper>
<ReactSVG
src="/static/images/docspace.big.react.svg"
className={`logo-wrapper ${className}`}
/>
<ReactSVG src={logo} className={`logo-wrapper ${className}`} />
</StyledWrapper>
);
};
export default DocspaceLogo;
export default inject(({ auth }) => {
const { settingsStore, userStore } = auth;
const { whiteLabelLogoUrls } = settingsStore;
const { userTheme } = userStore;
return {
whiteLabelLogoUrls,
userTheme,
};
})(observer(DocspaceLogo));

View File

@ -27,7 +27,7 @@ import NoUserSelect from "@docspace/components/utils/commonStyles";
import { getLink, checkIfModuleOld, onItemClick } from "SRC_DIR/helpers/utils";
import StyledExternalLinkIcon from "@docspace/client/src/components/StyledExternalLinkIcon";
import HeaderCatalogBurger from "./header-catalog-burger";
import { Base } from "@docspace/components/themes";
import { Base, Dark } from "@docspace/components/themes";
import { ReactSVG } from "react-svg";
const { proxyURL } = AppServerConfig;
@ -138,6 +138,8 @@ const HeaderComponent = ({
isPreparationPortal,
theme,
toggleArticleOpen,
logoUrl,
userTheme,
...props
}) => {
const { t } = useTranslation("Common");
@ -215,6 +217,9 @@ const HeaderComponent = ({
});
}, [history]);
const logo =
userTheme === "Dark" ? logoUrl?.path?.dark : logoUrl?.path?.light;
return (
<>
<Header
@ -232,15 +237,7 @@ const HeaderComponent = ({
!isFormGallery && <HeaderCatalogBurger onClick={toggleArticleOpen} />}
<LinkWithoutRedirect className="header-logo-wrapper" to={defaultPage}>
{!isPersonal ? (
props.logoUrl.includes(".svg") ? (
<ReactSVG src={props.logoUrl} className="header-logo-icon" />
) : (
<img
alt="logo"
src={props.logoUrl}
className="header-logo-icon"
/>
)
<img alt="logo" src={logo} className="header-logo-icon" />
) : (
<img
alt="logo"
@ -337,7 +334,7 @@ HeaderComponent.propTypes = {
onNavMouseEnter: PropTypes.func,
onNavMouseLeave: PropTypes.func,
toggleAside: PropTypes.func,
logoUrl: PropTypes.string,
logoUrl: PropTypes.object,
isLoaded: PropTypes.bool,
version: PropTypes.string,
isAuthenticated: PropTypes.bool,
@ -348,6 +345,7 @@ HeaderComponent.propTypes = {
export default inject(({ auth }) => {
const {
settingsStore,
userStore,
isLoaded,
isAuthenticated,
@ -365,6 +363,7 @@ export default inject(({ auth }) => {
} = settingsStore;
//TODO: restore when chat will complete -> const mainModules = availableModules.filter((m) => !m.isolateMode);
const { user } = userStore;
return {
theme,
@ -380,5 +379,6 @@ export default inject(({ auth }) => {
currentProductId,
toggleArticleOpen,
//currentProductName: (product && product.title) || "",
userTheme: user.theme,
};
})(observer(HeaderComponent));

View File

@ -49,7 +49,7 @@ const StyledDropDown = styled(DropDown)`
`;
const StyledControlContainer = styled.div`
background: ${(props) => props.theme.catalog.control.background};
background: transparent;
width: 24px;
height: 24px;
position: absolute;
@ -70,8 +70,8 @@ const StyledControlContainer = styled.div`
StyledControlContainer.defaultProps = { theme: Base };
const StyledCrossIcon = styled(CrossIcon)`
width: 12px;
height: 12px;
width: 17px;
height: 17px;
path {
fill: ${(props) => props.theme.catalog.control.fill};
}

View File

@ -1,7 +1,6 @@
import React from "react";
import { inject, observer } from "mobx-react";
import Text from "@docspace/components/text";
import Link from "@docspace/components/link";
import NoUserSelect from "@docspace/components/utils/commonStyles";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
@ -75,7 +74,8 @@ const AboutContent = (props) => {
theme,
companyInfoSettingsData,
previewData,
docSpaceLogo,
whiteLabelLogoUrls,
userTheme,
} = props;
const { t } = useTranslation("About");
const license = "AGPL-3.0";
@ -100,6 +100,11 @@ const AboutContent = (props) => {
? previewData.address
: companyInfoSettingsData?.address;
const logo =
userTheme === "Dark"
? whiteLabelLogoUrls[6]?.path.dark
: whiteLabelLogoUrls[6]?.path.light;
return (
companyInfoSettingsData && (
<StyledAboutBody>
@ -111,7 +116,7 @@ const AboutContent = (props) => {
/>
) : (
<img
src={docSpaceLogo}
src={logo}
alt="Logo"
className="logo-docspace-theme no-select"
/>
@ -234,9 +239,15 @@ const AboutContent = (props) => {
};
export default inject(({ auth }) => {
const { settingsStore } = auth;
const { settingsStore, userStore } = auth;
const { theme, companyInfoSettingsData, docSpaceLogo } = settingsStore;
const { theme, companyInfoSettingsData, whiteLabelLogoUrls } = settingsStore;
const { userTheme } = userStore;
return { theme, companyInfoSettingsData, docSpaceLogo };
return {
theme,
companyInfoSettingsData,
whiteLabelLogoUrls,
userTheme,
};
})(observer(AboutContent));

View File

@ -0,0 +1,163 @@
import styled from "styled-components";
import { Base } from "@docspace/components/themes";
const WhiteLabelWrapper = styled.div`
.subtitle {
margin-top: 5px;
margin-bottom: 20px;
}
.header-container {
display: flex;
align-items: center;
gap: 8px;
}
.wl-subtitle {
margin-top: 8px;
margin-bottom: 20px;
}
.wl-helper {
display: flex;
gap: 4px;
align-items: center;
margin-bottom: 16px;
}
.use-as-logo {
margin-top: 12px;
margin-bottom: 24px;
}
.input {
max-width: 350px;
}
.logos-container {
display: flex;
flex-direction: column;
gap: 40px;
}
.logo-wrapper {
display: flex;
flex-direction: column;
gap: 16px;
}
.logos-wrapper {
display: flex;
gap: 20px;
}
.logos-login-wrapper {
display: flex;
flex-direction: column;
gap: 20px;
}
.logos-editor-wrapper {
display: flex;
gap: 8px;
margin-bottom: 8px;
}
.logo-item {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 10px;
}
.border-img {
border: ${(props) =>
props.theme.client.settings.common.whiteLabel.borderImg};
box-sizing: content-box;
}
.logo-header {
width: 211px;
height: 24px;
padding: 22px 20px;
}
.logo-compact {
width: 26px;
height: 26px;
padding: 16px;
}
.logo-big {
width: 384px;
height: 42px;
padding: 12px 20px;
}
.logo-about {
width: 211px;
height: 24px;
padding: 12px 20px;
}
.logo-favicon {
width: 30px;
height: 30px;
margin-bottom: 8px;
}
.logo-docs-editor {
width: 154px;
height: 27px;
padding: 6px 9px 7px 9px;
}
.logo-embedded-editor {
width: 154px;
height: 27px;
padding: 5px 8px 6px 8px;
margin-bottom: 8px;
}
.background-green {
background-color: ${(props) =>
props.theme.client.settings.common.whiteLabel.greenBackgroundColor};
}
.background-blue {
background-color: ${(props) =>
props.theme.client.settings.common.whiteLabel.blueBackgroundColor};
}
.background-orange {
background-color: ${(props) =>
props.theme.client.settings.common.whiteLabel.orangeBackgroundColor};
}
.background-light {
background-color: ${(props) =>
props.theme.client.settings.common.whiteLabel.backgroundColorLight};
}
.background-dark {
background-color: ${(props) =>
props.theme.client.settings.common.whiteLabel.backgroundColorDark};
}
.background-white {
background-color: ${(props) =>
props.theme.client.settings.common.whiteLabel.backgroundColorWhite};
}
.hidden {
display: none;
}
.save-cancel-buttons {
margin-top: 24px;
}
`;
WhiteLabelWrapper.defaultProps = { theme: Base };
export default WhiteLabelWrapper;

View File

@ -0,0 +1,56 @@
import React from "react";
import Text from "@docspace/components/text";
import Link from "@docspace/components/link";
const Logo = (props) => {
const {
title,
src,
onChange,
isSettingPaid,
onChangeText,
inputId,
imageClass,
isEditor,
} = props;
return (
<div>
<div className="logo-item">
{title && (
<Text fontSize="13px" fontWeight="600">
{title}
</Text>
)}
{isEditor ? (
<div className="logos-editor-wrapper">
<img className="logo-docs-editor background-green" src={src} />
<img className="logo-docs-editor background-blue" src={src} />
<img className="logo-docs-editor background-orange" src={src} />
</div>
) : (
<img className={imageClass} src={src} />
)}
</div>
<label>
<input
id={inputId}
type="file"
className="hidden"
onChange={onChange}
disabled={!isSettingPaid}
/>
<Link
fontWeight="600"
isHovered
type="action"
className="settings_unavailable"
>
{onChangeText}
</Link>
</label>
</div>
);
};
export default Logo;

View File

@ -38,7 +38,8 @@ const StyledComponent = styled.div`
}
.section-description {
color: #657077;
color: ${(props) =>
props.theme.client.settings.common.brandingDescriptionColor};
line-height: 20px;
padding-bottom: 20px;
}
@ -46,7 +47,7 @@ const StyledComponent = styled.div`
hr {
margin: 24px 0;
border: none;
border-top: 1px solid #eceef1;
border-top: ${(props) => props.theme.client.settings.separatorBorder};
}
${(props) => !props.isSettingPaid && UnavailableStyles}

View File

@ -0,0 +1,43 @@
export const generateLogo = (
width,
height,
text,
fontSize = 18,
fontColor = "#000",
isEditorLogo = false
) => {
const canvas = document.createElement("canvas");
canvas.width = isEditorLogo ? "154" : width;
canvas.height = isEditorLogo ? "27" : height;
const ctx = canvas.getContext("2d");
ctx.fillStyle = "transparent";
ctx.clearRect(0, 0, width, height);
ctx.fillStyle = fontColor;
ctx.textAlign = "start";
ctx.textBaseline = "top";
ctx.font = `${fontSize}px Arial`;
ctx.fillText(text, 0, height / 2 - fontSize / 2);
return canvas.toDataURL();
};
export const getLogoOptions = (index, text) => {
switch (index) {
case 0:
return { fontSize: 18, text: text };
case 1:
return { fontSize: 44, text: text };
case 2:
return { fontSize: 16, text: text.trim().charAt(0) };
case 3:
return { fontSize: 16, text: text, isEditorLogo: true };
case 4:
return { fontSize: 16, text: text, isEditorLogo: true };
case 5:
return { fontSize: 30, text: text.trim().charAt(0) };
case 6:
return { fontSize: 32, text: text };
default:
return { fontSize: 18, text: text };
}
};

View File

@ -4,7 +4,6 @@ import api from "@docspace/common/api";
class CommonStore {
whiteLabelLogoUrls = [];
whiteLabelLogoSizes = [];
whiteLabelLogoText = null;
isInit = false;
@ -38,7 +37,6 @@ class CommonStore {
authStore.settingsStore.getPortalCultures(),
this.getWhiteLabelLogoUrls(),
this.getWhiteLabelLogoText(),
this.getWhiteLabelLogoSizes(),
this.getGreetingSettingsIsDefault()
);
@ -53,10 +51,6 @@ class CommonStore {
this.whiteLabelLogoText = text;
};
setLogoSizes = (sizes) => {
this.whiteLabelLogoSizes = sizes;
};
restoreWhiteLabelSettings = async (isDefault) => {
const res = await api.settings.restoreWhiteLabelSettings(isDefault);
this.getWhiteLabelLogoUrls();
@ -76,11 +70,6 @@ class CommonStore {
this.setLogoText(res);
};
getWhiteLabelLogoSizes = async () => {
const res = await api.settings.getLogoSizes();
this.setLogoSizes(res);
};
setIsLoadedArticleBody = (isLoadedArticleBody) => {
this.isLoadedArticleBody = isLoadedArticleBody;
};

View File

@ -199,12 +199,6 @@ export function getLogoText() {
url: `/settings/whitelabel/logotext.json`,
});
}
export function getLogoSizes() {
return request({
method: "get",
url: `/settings/whitelabel/sizes.json`,
});
}
export function getLogoUrls() {
return request({

View File

@ -6,7 +6,6 @@ import { isTablet as isTabletUtils } from "@docspace/components/utils/device";
import { Link } from "react-router-dom";
import { isTablet, isMobileOnly } from "react-device-detect";
import { inject, observer } from "mobx-react";
import { ReactSVG } from "react-svg";
import {
StyledArticleHeader,
StyledHeading,
@ -19,6 +18,7 @@ const ArticleHeader = ({
onClick,
isBurgerLoading,
whiteLabelLogoUrls,
userTheme,
...rest
}) => {
const history = useHistory();
@ -26,7 +26,14 @@ const ArticleHeader = ({
const isTabletView = (isTabletUtils() || isTablet) && !isMobileOnly;
const onLogoClick = () => history.push("/");
const isSvgLogo = whiteLabelLogoUrls[0].includes(".svg");
const burgerLogo =
userTheme === "Dark"
? whiteLabelLogoUrls[5].path.dark
: whiteLabelLogoUrls[5].path.light;
const logo =
userTheme === "Dark"
? whiteLabelLogoUrls[0].path.dark
: whiteLabelLogoUrls[0].path.light;
if (isMobileOnly) return <></>;
return (
@ -35,7 +42,7 @@ const ArticleHeader = ({
<Loaders.ArticleHeader height="28px" width="28px" />
) : (
<StyledIconBox name="article-burger" showText={showText}>
<img src={whiteLabelLogoUrls[5]} onClick={onLogoClick} />
<img src={burgerLogo} onClick={onLogoClick} />
</StyledIconBox>
)}
@ -44,29 +51,10 @@ const ArticleHeader = ({
) : (
<StyledHeading showText={showText} size="large">
{isTabletView ? (
isSvgLogo ? (
<ReactSVG
className="logo-icon_svg"
src={whiteLabelLogoUrls[0]}
onClick={onLogoClick}
/>
) : (
<img
className="logo-icon_svg"
src={whiteLabelLogoUrls[0]}
onClick={onLogoClick}
/>
)
<img className="logo-icon_svg" src={logo} onClick={onLogoClick} />
) : (
<Link to="/">
{isSvgLogo ? (
<ReactSVG
className="logo-icon_svg"
src={whiteLabelLogoUrls[0]}
/>
) : (
<img className="logo-icon_svg" src={whiteLabelLogoUrls[0]} />
)}
<img className="logo-icon_svg" src={logo} />
</Link>
)}
</StyledHeading>
@ -84,10 +72,13 @@ ArticleHeader.propTypes = {
ArticleHeader.displayName = "Header";
export default inject(({ auth }) => {
const { settingsStore } = auth;
const { settingsStore, userStore } = auth;
const { isBurgerLoading, whiteLabelLogoUrls } = settingsStore;
const { userTheme } = userStore;
return {
isBurgerLoading,
whiteLabelLogoUrls,
userTheme,
};
})(observer(ArticleHeader));

View File

@ -151,7 +151,6 @@ class SettingsStore {
companyInfoSettingsIsDefault = true;
whiteLabelLogoUrls = [];
docSpaceLogo = "";
constructor() {
makeAutoObservable(this);
@ -288,7 +287,11 @@ class SettingsStore {
this.setIsLoading(true);
const requests = [];
requests.push(this.getPortalSettings(), this.getAppearanceTheme());
requests.push(
this.getPortalSettings(),
this.getAppearanceTheme(),
this.getWhiteLabelLogoUrls()
);
this.tenantStatus !== TenantStatus.PortalRestore &&
requests.push(this.getBuildVersionInfo());
@ -387,10 +390,6 @@ class SettingsStore {
);
};
setDocSpaceLogo = (urls) => {
this.docSpaceLogo = urls[6];
};
setLogoUrl = (url) => {
this.logoUrl = url[0];
};
@ -410,7 +409,6 @@ class SettingsStore {
const res = await api.settings.getLogoUrls();
this.setLogoUrls(Object.values(res));
this.setDocSpaceLogo(Object.values(res));
this.setLogoUrl(Object.values(res));
};

View File

@ -112,6 +112,20 @@ class UserStore {
get isAuthenticated() {
return !!this.user;
}
get userTheme() {
const systemTheme =
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
? "Dark"
: "Light";
const theme = this.user?.theme || systemTheme;
if (theme === "System") {
return systemTheme;
}
return theme;
}
}
export default UserStore;

View File

@ -2891,14 +2891,17 @@ const Base = {
tooltipLinkColor: black,
arrowColor: black,
descriptionColor: cyanBlueDarkShade,
brandingDescriptionColor: "#657077",
whiteLabel: {
borderImg: "1px solid #d1d1d1",
backgroundColor: "#ECEEF1",
greenBackgroundColor: "#7e983f",
blueBackgroundColor: "#5170b5",
orangeBackgroundColor: "#e86e2e",
backgroundColorWhite: white,
backgroundColorLight: "#F8F9F9",
backgroundColorDark: "#282828",
greenBackgroundColor: "#40865C",
blueBackgroundColor: "#446995",
orangeBackgroundColor: "#AA5252",
dataFontColor: white,
dataFontColorBlack: black,

View File

@ -2893,14 +2893,17 @@ const Dark = {
tooltipLinkColor: "#e06a1b",
arrowColor: white,
descriptionColor: "#858585",
brandingDescriptionColor: "#858585",
whiteLabel: {
borderImg: "1px solid #d1d1d1",
borderImg: "1px solid #474747",
backgroundColor: "#282828",
greenBackgroundColor: "#7e983f",
blueBackgroundColor: "#5170b5",
orangeBackgroundColor: "#e86e2e",
backgroundColorWhite: white,
backgroundColorLight: "#F8F9F9",
backgroundColorDark: "#282828",
greenBackgroundColor: "#40865C",
blueBackgroundColor: "#446995",
orangeBackgroundColor: "#AA5252",
dataFontColor: white,
dataFontColorBlack: white,

View File

@ -14,7 +14,7 @@ const App: React.FC<ILoginProps> = (props) => {
const loginStore = initLoginStore(props.currentColorScheme);
return (
<MobxProvider {...loginStore}>
<SimpleNav />
<SimpleNav {...props} />
<Switch>
<Route path="/login/error">
<InvalidRoute />

View File

@ -62,17 +62,12 @@ const Form: React.FC = ({ theme, setTheme, logoUrls }) => {
setInvalidCode(false);
};
const loginLogo = Object.values(logoUrls)[1];
const isSvgLogo = loginLogo.includes(".svg");
const logo = Object.values(logoUrls)[1];
const logoUrl = !theme.isBase ? logo.path.dark : logo.path.light;
return (
<LoginContainer id="code-page" theme={theme}>
{isSvgLogo ? (
<ReactSVG src={loginLogo} className="logo-wrapper" />
) : (
<img src={loginLogo} className="logo-wrapper" />
)}
<img src={logoUrl} className="logo-wrapper" />
<Text
id="workspace-title"
fontSize="23px"

View File

@ -23,7 +23,6 @@ import SSOIcon from "../../../../../public/images/sso.react.svg";
import { Dark, Base } from "@docspace/components/themes";
import { useMounted } from "../helpers/useMounted";
import { getBgPattern } from "@docspace/common/utils";
import { ReactSVG } from "react-svg";
interface ILoginProps extends IInitialState {
isDesktopEditor?: boolean;
@ -175,8 +174,8 @@ const Login: React.FC<ILoginProps> = ({
const bgPattern = getBgPattern(currentColorScheme.id);
const loginLogo = Object.values(logoUrls)[1];
const isSvgLogo = loginLogo.includes(".svg");
const logo = Object.values(logoUrls)[1];
const logoUrl = !theme.isBase ? logo.path.dark : logo.path.light;
if (!mounted) return <></>;
@ -189,11 +188,7 @@ const Login: React.FC<ILoginProps> = ({
bgPattern={bgPattern}
>
<ColorTheme themeId={ThemeType.LinkForgotPassword} theme={theme}>
{isSvgLogo ? (
<ReactSVG src={loginLogo} className="logo-wrapper" />
) : (
<img src={loginLogo} className="logo-wrapper" />
)}
<img src={logoUrl} className="logo-wrapper" />
<Text
fontSize="23px"
fontWeight={700}

View File

@ -2,7 +2,7 @@ import React from "react";
import styled from "styled-components";
import { inject, observer } from "mobx-react";
import { hugeMobile } from "@docspace/components/utils/device";
import { ReactSVG } from "react-svg";
import { Dark } from "@docspace/components/themes";
const StyledNav = styled.div`
display: none;
@ -21,10 +21,13 @@ const StyledNav = styled.div`
}
`;
const SimpleNav = ({ theme }) => {
const SimpleNav = ({ theme, logoUrls }) => {
const logo = Object.values(logoUrls)[0];
const logoUrl = !theme.isBase ? logo.path.dark : logo.path.light;
return (
<StyledNav id="login-header" theme={theme}>
<ReactSVG src="/static/images/logo.docspace.react.svg" />
<img src={logoUrl} />
</StyledNav>
);
};

View File

@ -34,22 +34,19 @@ public class AuditReportUploader
private readonly FilesLinkUtility _filesLinkUtility;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly ILogger<AuditReportUploader> _logger;
private readonly AuditReportCreator _auditReportCreator;
public AuditReportUploader(
GlobalFolderHelper globalFolderHelper,
ILogger<AuditReportUploader> logger,
FileUploader fileUploader,
FilesLinkUtility filesLinkUtility,
CommonLinkUtility commonLinkUtility,
AuditReportCreator auditReportCreator)
CommonLinkUtility commonLinkUtility)
{
_globalFolderHelper = globalFolderHelper;
_logger = logger;
_fileUploader = fileUploader;
_filesLinkUtility = filesLinkUtility;
_commonLinkUtility = commonLinkUtility;
_auditReportCreator = auditReportCreator;
}
public async Task<string> UploadCsvReport(Stream stream, string reportName)

View File

@ -58,9 +58,8 @@ public class File<T> : FileEntry<T>, IFileEntry<T>
FileHelper fileHelper,
Global global,
GlobalFolderHelper globalFolderHelper,
SettingsManager settingsManager,
FilesSettingsHelper filesSettingsHelper,
FileDateTime fileDateTime) : base(fileHelper, global, globalFolderHelper, settingsManager, filesSettingsHelper, fileDateTime)
FileDateTime fileDateTime) : base(fileHelper, global, globalFolderHelper, filesSettingsHelper, fileDateTime)
{
Version = 1;
VersionGroup = 1;

View File

@ -112,7 +112,6 @@ public abstract class FileEntry<T> : FileEntry, ICloneable, IFileEntry<T>
public T ParentId { get; set; }
private T _folderIdDisplay;
private readonly GlobalFolderHelper _globalFolderHelper;
private readonly SettingsManager _settingsManager;
private readonly FilesSettingsHelper _filesSettingsHelper;
private readonly FileDateTime _fileDateTime;
@ -122,12 +121,10 @@ public abstract class FileEntry<T> : FileEntry, ICloneable, IFileEntry<T>
FileHelper fileHelper,
Global global,
GlobalFolderHelper globalFolderHelper,
SettingsManager settingsManager,
FilesSettingsHelper filesSettingsHelper,
FileDateTime fileDateTime) : base(fileHelper, global)
{
_globalFolderHelper = globalFolderHelper;
_settingsManager = settingsManager;
_filesSettingsHelper = filesSettingsHelper;
_fileDateTime = fileDateTime;
}

View File

@ -91,9 +91,8 @@ public class Folder<T> : FileEntry<T>, IFolder
FileHelper fileHelper,
Global global,
GlobalFolderHelper globalFolderHelper,
SettingsManager settingsManager,
FilesSettingsHelper filesSettingsHelper,
FileDateTime fileDateTime) : base(fileHelper, global, globalFolderHelper, settingsManager, filesSettingsHelper, fileDateTime)
FileDateTime fileDateTime) : base(fileHelper, global, globalFolderHelper, filesSettingsHelper, fileDateTime)
{
Title = string.Empty;
FileEntryType = FileEntryType.Folder;

View File

@ -82,7 +82,6 @@ public class FileStorageService<T> //: IFileStorageService
private readonly FileShareParamsHelper _fileShareParamsHelper;
private readonly EncryptionLoginProvider _encryptionLoginProvider;
private readonly CountRoomChecker _countRoomChecker;
private readonly CountRoomCheckerStatistic _countRoomCheckerStatistic;
private readonly RoomLinkService _roomLinkService;
private readonly DocSpaceLinkHelper _docSpaceLinkHelper;
private readonly StudioNotifyService _studioNotifyService;
@ -138,7 +137,6 @@ public class FileStorageService<T> //: IFileStorageService
FileShareParamsHelper fileShareParamsHelper,
EncryptionLoginProvider encryptionLoginProvider,
CountRoomChecker countRoomChecker,
CountRoomCheckerStatistic countRoomCheckerStatistic,
RoomLinkService roomLinkService,
DocSpaceLinkHelper docSpaceLinkHelper,
StudioNotifyService studioNotifyService)
@ -194,7 +192,6 @@ public class FileStorageService<T> //: IFileStorageService
_fileShareParamsHelper = fileShareParamsHelper;
_encryptionLoginProvider = encryptionLoginProvider;
_countRoomChecker = countRoomChecker;
_countRoomCheckerStatistic = countRoomCheckerStatistic;
_roomLinkService = roomLinkService;
_docSpaceLinkHelper = docSpaceLinkHelper;
_studioNotifyService = studioNotifyService;
@ -3216,7 +3213,7 @@ public class FileStorageService<T> //: IFileStorageService
private IDictionary<string, StringValues> GetHttpHeaders()
{
return _httpContextAccessor?.HttpContext?.Request?.Headers;
return _httpContextAccessor?.HttpContext?.Request?.Headers?.ToDictionary(k => k.Key, v => v.Value);
}
private static string GetAccessString(FileShare fileShare)

View File

@ -145,14 +145,12 @@ internal class DropboxProviderInfo : IProviderInfo
internal class DropboxStorageDisposableWrapper : IDisposable
{
public DropboxStorage Storage { get; private set; }
private readonly TempStream _tempStream;
private readonly IServiceProvider _serviceProvider;
private readonly OAuth20TokenHelper _oAuth20TokenHelper;
private readonly ConsumerFactory _consumerFactory;
public DropboxStorageDisposableWrapper(TempStream tempStream, IServiceProvider serviceProvider, OAuth20TokenHelper oAuth20TokenHelper, ConsumerFactory consumerFactory)
public DropboxStorageDisposableWrapper(IServiceProvider serviceProvider, OAuth20TokenHelper oAuth20TokenHelper, ConsumerFactory consumerFactory)
{
_tempStream = tempStream;
_serviceProvider = serviceProvider;
_oAuth20TokenHelper = oAuth20TokenHelper;
_consumerFactory = consumerFactory;

View File

@ -32,18 +32,21 @@ public class CustomTagsService<T>
private readonly IDaoFactory _daoFactory;
private readonly FileSecurity _fileSecurity;
private readonly AuthContext _authContext;
private readonly FileSecurityCommon _fileSecurityCommon;
private readonly FilesMessageService _filesMessageService;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly UserManager _userManager;
public CustomTagsService(IDaoFactory daoFactory, FileSecurity fileSecurity, AuthContext authContext, FileSecurityCommon fileSecurityCommon,
FilesMessageService filesMessageService, IHttpContextAccessor httpContextAccessor, UserManager userManager)
public CustomTagsService(
IDaoFactory daoFactory,
FileSecurity fileSecurity,
AuthContext authContext,
FilesMessageService filesMessageService,
IHttpContextAccessor httpContextAccessor,
UserManager userManager)
{
_daoFactory = daoFactory;
_fileSecurity = fileSecurity;
_authContext = authContext;
_fileSecurityCommon = fileSecurityCommon;
_filesMessageService = filesMessageService;
_httpContextAccessor = httpContextAccessor;
_userManager = userManager;

View File

@ -76,7 +76,7 @@ public class FilesMessageService
return;
}
SendHeadersMessage(headers, action, _messageTarget.Create(new[] { entry1.Id.ToString(), entry2.Id.ToString() }), description);
SendHeadersMessage(headers, action, _messageTarget.CreateFromGroupValues(new[] { entry1.Id.ToString(), entry2.Id.ToString() }), description);
}
private void SendHeadersMessage(IDictionary<string, StringValues> headers, MessageAction action, MessageTarget target, params string[] description)

View File

@ -282,7 +282,6 @@ public class GlobalFolder
private readonly SettingsManager _settingsManager;
private readonly GlobalStore _globalStore;
private readonly IServiceProvider _serviceProvider;
private readonly Global _global;
private readonly ILogger _logger;
public GlobalFolder(
@ -295,9 +294,7 @@ public class GlobalFolder
SettingsManager settingsManager,
GlobalStore globalStore,
ILoggerProvider options,
IServiceProvider serviceProvider,
Global global,
ThumbnailSettings thumbnailSettings
IServiceProvider serviceProvider
)
{
_coreBaseSettings = coreBaseSettings;
@ -309,9 +306,7 @@ public class GlobalFolder
_settingsManager = settingsManager;
_globalStore = globalStore;
_serviceProvider = serviceProvider;
_global = global;
_logger = options.CreateLogger("ASC.Files");
_thumbnailSettings = thumbnailSettings;
_logger = options.CreateLogger("ASC.Files");
}
internal static readonly IDictionary<int, int> ProjectsRootFolderCache =
@ -623,7 +618,6 @@ public class GlobalFolder
internal static readonly IDictionary<string, object> TrashFolderCache =
new ConcurrentDictionary<string, object>(); /*Use SYNCHRONIZED for cross thread blocks*/
private readonly ThumbnailSettings _thumbnailSettings;
public async Task<T> GetFolderTrashAsync<T>(IDaoFactory daoFactory)
{

View File

@ -38,7 +38,6 @@ public class PathProvider
private readonly FilesLinkUtility _filesLinkUtility;
private readonly EmailValidationKeyProvider _emailValidationKeyProvider;
private readonly GlobalStore _globalStore;
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
public PathProvider(
WebImageSupplier webImageSupplier,
@ -46,8 +45,7 @@ public class PathProvider
CommonLinkUtility commonLinkUtility,
FilesLinkUtility filesLinkUtility,
EmailValidationKeyProvider emailValidationKeyProvider,
GlobalStore globalStore,
BaseCommonLinkUtility baseCommonLinkUtility)
GlobalStore globalStore)
{
_webImageSupplier = webImageSupplier;
_daoFactory = daoFactory;
@ -55,7 +53,6 @@ public class PathProvider
_filesLinkUtility = filesLinkUtility;
_emailValidationKeyProvider = emailValidationKeyProvider;
_globalStore = globalStore;
_baseCommonLinkUtility = baseCommonLinkUtility;
}
public string GetImagePath(string imgFileName)

View File

@ -617,7 +617,7 @@ public class CustomerConfig<T>
public string Address => _settingsManager.LoadForDefaultTenant<CompanyWhiteLabelSettings>().Address;
public string Logo => _baseCommonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteDefaultLogoPath(WhiteLabelLogoTypeEnum.Dark, !_configuration.EditorConfig.Customization.IsRetina));
public string Logo => _baseCommonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteDefaultLogoPath(WhiteLabelLogoTypeEnum.LoginPage, false).Result);
public string Mail => _settingsManager.LoadForDefaultTenant<CompanyWhiteLabelSettings>().Email;
@ -768,8 +768,6 @@ public class CustomizationConfig<T>
}
}
public bool IsRetina { get; set; }
public LogoConfig<T> Logo { get; set; }
public bool MentionShare
@ -933,16 +931,15 @@ public class LogoConfig<T>
return _configuration.EditorType == EditorType.Embedded
|| fillingForm
? _commonLinkUtility.GetFullAbsolutePath(_tenantLogoHelper.GetLogo(WhiteLabelLogoTypeEnum.DocsEditorEmbed, !_configuration.EditorConfig.Customization.IsRetina))
: _commonLinkUtility.GetFullAbsolutePath(_tenantLogoHelper.GetLogo(WhiteLabelLogoTypeEnum.DocsEditor, !_configuration.EditorConfig.Customization.IsRetina));
? _commonLinkUtility.GetFullAbsolutePath(_tenantLogoHelper.GetLogo(WhiteLabelLogoTypeEnum.DocsEditorEmbed).Result)
: _commonLinkUtility.GetFullAbsolutePath(_tenantLogoHelper.GetLogo(WhiteLabelLogoTypeEnum.DocsEditor).Result);
}
}
public string ImageDark
{
set { }
get => _commonLinkUtility.GetFullAbsolutePath(
_tenantLogoHelper.GetLogo(WhiteLabelLogoTypeEnum.DocsEditor, !_configuration.EditorConfig.Customization.IsRetina));
get => _commonLinkUtility.GetFullAbsolutePath(_tenantLogoHelper.GetLogo(WhiteLabelLogoTypeEnum.DocsEditor).Result);
}
public string ImageEmbedded
@ -951,7 +948,7 @@ public class LogoConfig<T>
{
return _configuration.EditorType != EditorType.Embedded
? null
: _commonLinkUtility.GetFullAbsolutePath(_tenantLogoHelper.GetLogo(WhiteLabelLogoTypeEnum.DocsEditorEmbed, !_configuration.EditorConfig.Customization.IsRetina));
: _commonLinkUtility.GetFullAbsolutePath(_tenantLogoHelper.GetLogo(WhiteLabelLogoTypeEnum.DocsEditorEmbed).Result);
}
}

View File

@ -43,7 +43,6 @@ public class NotifyClient
private readonly UserManager _userManager;
private readonly TenantManager _tenantManager;
private readonly StudioNotifyHelper _studioNotifyHelper;
private readonly IServiceScopeFactory _scope;
private readonly Context _notifyContext;
private readonly NotifyEngineQueue _notifyEngineQueue;
@ -59,8 +58,7 @@ public class NotifyClient
PathProvider pathProvider,
UserManager userManager,
TenantManager tenantManager,
StudioNotifyHelper studioNotifyHelper,
IServiceScopeFactory serviceScope)
StudioNotifyHelper studioNotifyHelper)
{
_notifyContext = notifyContext;
_notifyEngineQueue = notifyEngineQueue;
@ -74,7 +72,6 @@ public class NotifyClient
_userManager = userManager;
_tenantManager = tenantManager;
_studioNotifyHelper = studioNotifyHelper;
_scope = serviceScope;
}
public void SendDocuSignComplete<T>(File<T> file, string sourceTitle)

View File

@ -27,7 +27,7 @@
namespace ASC.Web.Files.ThirdPartyApp;
[Scope]
[Scope]
public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
{
public const string AppAttr = "box";
@ -51,7 +51,6 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
private readonly UserManager _userManager;
private readonly UserManagerWrapper _userManagerWrapper;
private readonly CookiesManager _cookiesManager;
private readonly MessageService _messageService;
private readonly Global _global;
private readonly EmailValidationKeyProvider _emailValidationKeyProvider;
private readonly FilesLinkUtility _filesLinkUtility;
@ -79,7 +78,6 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
UserManager userManager,
UserManagerWrapper userManagerWrapper,
CookiesManager cookiesManager,
MessageService messageService,
Global global,
EmailValidationKeyProvider emailValidationKeyProvider,
FilesLinkUtility filesLinkUtility,
@ -111,7 +109,6 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
_userManager = userManager;
_userManagerWrapper = userManagerWrapper;
_cookiesManager = cookiesManager;
_messageService = messageService;
_global = global;
_emailValidationKeyProvider = emailValidationKeyProvider;
_filesLinkUtility = filesLinkUtility;
@ -284,36 +281,36 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
{
RequestUri = new Uri(_boxUrlUpload.Replace("{fileId}", fileId))
};
StreamContent streamContent;
using var multipartFormContent = new MultipartFormDataContent();
if (stream != null)
{
streamContent = new StreamContent(stream);
}
else
{
var downloadRequest = new HttpRequestMessage
{
RequestUri = new Uri(downloadUrl)
};
var response = await httpClient.SendAsync(downloadRequest);
var downloadStream = new ResponseStream(response);
streamContent = new StreamContent(downloadStream);
}
streamContent.Headers.TryAddWithoutValidation("Content-Type", MimeMapping.GetMimeMapping(title));
multipartFormContent.Add(streamContent, name: "filename", fileName: title);
request.Content = multipartFormContent;
request.Method = HttpMethod.Post;
request.Headers.Add("Authorization", "Bearer " + token);
//request.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data; boundary=" + boundary);
//_logger.DebugBoxAppSaveFileTotalSize(tmpStream.Length);
StreamContent streamContent;
using var multipartFormContent = new MultipartFormDataContent();
if (stream != null)
{
streamContent = new StreamContent(stream);
}
else
{
var downloadRequest = new HttpRequestMessage
{
RequestUri = new Uri(downloadUrl)
};
var response = await httpClient.SendAsync(downloadRequest);
var downloadStream = new ResponseStream(response);
streamContent = new StreamContent(downloadStream);
}
streamContent.Headers.TryAddWithoutValidation("Content-Type", MimeMapping.GetMimeMapping(title));
multipartFormContent.Add(streamContent, name: "filename", fileName: title);
request.Content = multipartFormContent;
request.Method = HttpMethod.Post;
request.Headers.Add("Authorization", "Bearer " + token);
//request.Content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data; boundary=" + boundary);
//_logger.DebugBoxAppSaveFileTotalSize(tmpStream.Length);
try
{
using var response = await httpClient.SendAsync(request);

View File

@ -49,7 +49,6 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
private readonly UserManager _userManager;
private readonly UserManagerWrapper _userManagerWrapper;
private readonly CookiesManager _cookiesManager;
private readonly MessageService _messageService;
private readonly Global _global;
private readonly GlobalStore _globalStore;
private readonly EmailValidationKeyProvider _emailValidationKeyProvider;
@ -82,7 +81,6 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
UserManager userManager,
UserManagerWrapper userManagerWrapper,
CookiesManager cookiesManager,
MessageService messageService,
Global global,
GlobalStore globalStore,
EmailValidationKeyProvider emailValidationKeyProvider,
@ -121,7 +119,6 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
_userManager = userManager;
_userManagerWrapper = userManagerWrapper;
_cookiesManager = cookiesManager;
_messageService = messageService;
_global = global;
_globalStore = globalStore;
_emailValidationKeyProvider = emailValidationKeyProvider;

View File

@ -324,7 +324,6 @@ public class EntryManager
private readonly ILogger<EntryManager> _logger;
private readonly IHttpClientFactory _clientFactory;
private readonly FilesMessageService _filesMessageService;
private readonly Global _global;
public EntryManager(
IDaoFactory daoFactory,
@ -353,8 +352,7 @@ public class EntryManager
ThirdPartySelector thirdPartySelector,
IHttpClientFactory clientFactory,
FilesMessageService filesMessageService,
ThumbnailSettings thumbnailSettings,
Global global)
ThumbnailSettings thumbnailSettings)
{
_daoFactory = daoFactory;
_fileSecurity = fileSecurity;
@ -380,7 +378,6 @@ public class EntryManager
_fileTracker = fileTracker;
_entryStatusManager = entryStatusManager;
_clientFactory = clientFactory;
_global = global;
_filesMessageService = filesMessageService;
_thirdPartySelector = thirdPartySelector;
_thumbnailSettings = thumbnailSettings;

View File

@ -39,7 +39,6 @@ public class FilesModule : FeedModule
private const string SharedFileItem = Constants.SharedFileItem;
private readonly FileSecurity _fileSecurity;
private readonly FilesLinkUtility _filesLinkUtility;
private readonly IFileDao<int> _fileDao;
private readonly IFolderDao<int> _folderDao;
private readonly UserManager _userManager;
@ -48,7 +47,6 @@ public class FilesModule : FeedModule
TenantManager tenantManager,
UserManager userManager,
WebItemSecurity webItemSecurity,
FilesLinkUtility filesLinkUtility,
FileSecurity fileSecurity,
IDaoFactory daoFactory)
: base(tenantManager, webItemSecurity)
@ -56,7 +54,6 @@ public class FilesModule : FeedModule
_fileDao = daoFactory.GetFileDao<int>();
_folderDao = daoFactory.GetFolderDao<int>();
_userManager = userManager;
_filesLinkUtility = filesLinkUtility;
_fileSecurity = fileSecurity;
}

View File

@ -39,7 +39,6 @@ public class FoldersModule : FeedModule
private const string SharedFolderItem = Constants.SharedFolderItem;
private readonly FileSecurity _fileSecurity;
private readonly FilesLinkUtility _filesLinkUtility;
private readonly IFolderDao<int> _folderDao;
private readonly UserManager _userManager;
@ -47,13 +46,11 @@ public class FoldersModule : FeedModule
TenantManager tenantManager,
UserManager userManager,
WebItemSecurity webItemSecurity,
FilesLinkUtility filesLinkUtility,
FileSecurity fileSecurity,
IDaoFactory daoFactory)
: base(tenantManager, webItemSecurity)
{
_userManager = userManager;
_filesLinkUtility = filesLinkUtility;
_fileSecurity = fileSecurity;
_folderDao = daoFactory.GetFolderDao<int>();
}
@ -109,7 +106,7 @@ public class FoldersModule : FeedModule
var parentFolders = await _folderDao.GetFoldersAsync(parentFolderIDs, checkShare: false).ToListAsync();
var roomsIds = await _folderDao.GetParentRoomsAsync(parentFolderIDs).ToDictionaryAsync(k => k.FolderId, v => v.ParentRoomId);
return folders.Select(f => new Tuple<Feed.Aggregator.Feed, object>(ToFeed(f, parentFolders.FirstOrDefault(r => r.Id.Equals(f.Folder.ParentId)),
return folders.Select(f => new Tuple<Feed.Aggregator.Feed, object>(ToFeed(f, parentFolders.FirstOrDefault(r => r.Id.Equals(f.Folder.ParentId)),
roomsIds.GetValueOrDefault(f.Folder.ParentId)), f));
}

View File

@ -33,7 +33,6 @@ public class RoomsModule : FeedModule
public const string RoomItem = Constants.RoomItem;
public const string SharedRoomItem = Constants.SharedRoomItem;
private readonly FilesLinkUtility _filesLinkUtility;
private readonly IFolderDao<int> _folderDao;
private readonly UserManager _userManager;
private readonly FileSecurity _fileSecurity;
@ -42,13 +41,11 @@ public class RoomsModule : FeedModule
TenantManager tenantManager,
UserManager userManager,
WebItemSecurity webItemSecurity,
FilesLinkUtility filesLinkUtility,
FileSecurity fileSecurity,
IDaoFactory daoFactory)
: base(tenantManager, webItemSecurity)
{
_userManager = userManager;
_filesLinkUtility = filesLinkUtility;
_fileSecurity = fileSecurity;
_folderDao = daoFactory.GetFolderDao<int>();
}

View File

@ -76,7 +76,7 @@ public class PhotoController : PeopleControllerBase
if (!string.IsNullOrEmpty(inDto.TmpFile))
{
var fileName = Path.GetFileName(inDto.TmpFile);
var data = _userPhotoManager.GetTempPhotoData(fileName);
var data = await _userPhotoManager.GetTempPhotoData(fileName);
var settings = new UserPhotoThumbnailSettings(inDto.X, inDto.Y, inDto.Width, inDto.Height);
@ -149,7 +149,7 @@ public class PhotoController : PeopleControllerBase
}
[HttpPost("{userid}/photo")]
public FileUploadResultDto UploadMemberPhoto(string userid, IFormCollection formCollection)
public async Task<FileUploadResultDto> UploadMemberPhoto(string userid, IFormCollection formCollection)
{
var result = new FileUploadResultDto();
var autosave = bool.Parse(formCollection["Autosave"]);
@ -211,7 +211,7 @@ public class PhotoController : PeopleControllerBase
}
else
{
result.Data = _userPhotoManager.SaveTempPhoto(data, _setupInfo.MaxImageUploadSize, UserPhotoManager.OriginalFotoSize.Width, UserPhotoManager.OriginalFotoSize.Height);
result.Data = await _userPhotoManager.SaveTempPhoto(data, _setupInfo.MaxImageUploadSize, UserPhotoManager.OriginalFotoSize.Width, UserPhotoManager.OriginalFotoSize.Height);
}
result.Success = true;

View File

@ -41,8 +41,7 @@ public class AuthenticationController : ControllerBase
private readonly TenantCookieSettingsHelper _tenantCookieSettingsHelper;
private readonly CookiesManager _cookiesManager;
private readonly PasswordHasher _passwordHasher;
private readonly EmailValidationKeyModelHelper _emailValidationKeyModelHelper;
private readonly ICache _cache;
private readonly EmailValidationKeyModelHelper _emailValidationKeyModelHelper;
private readonly SetupInfo _setupInfo;
private readonly MessageService _messageService;
private readonly ProviderManager _providerManager;
@ -79,7 +78,6 @@ public class AuthenticationController : ControllerBase
CookiesManager cookiesManager,
PasswordHasher passwordHasher,
EmailValidationKeyModelHelper emailValidationKeyModelHelper,
ICache cache,
SetupInfo setupInfo,
MessageService messageService,
ProviderManager providerManager,
@ -114,8 +112,7 @@ public class AuthenticationController : ControllerBase
_tenantCookieSettingsHelper = tenantCookieSettingsHelper;
_cookiesManager = cookiesManager;
_passwordHasher = passwordHasher;
_emailValidationKeyModelHelper = emailValidationKeyModelHelper;
_cache = cache;
_emailValidationKeyModelHelper = emailValidationKeyModelHelper;
_setupInfo = setupInfo;
_messageService = messageService;
_providerManager = providerManager;

View File

@ -34,9 +34,7 @@ public class CapabilitiesController : ControllerBase
private readonly CoreBaseSettings _coreBaseSettings;
private readonly TenantManager _tenantManager;
private readonly ProviderManager _providerManager;
private readonly SettingsManager _settingsManager;
private readonly IConfiguration _configuration;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly SettingsManager _settingsManager;
private readonly ILogger _log;
@ -45,16 +43,12 @@ public class CapabilitiesController : ControllerBase
TenantManager tenantManager,
ProviderManager providerManager,
SettingsManager settingsManager,
IConfiguration configuration,
IHttpContextAccessor httpContextAccessor,
ILogger<CapabilitiesController> logger)
{
_coreBaseSettings = coreBaseSettings;
_tenantManager = tenantManager;
_providerManager = providerManager;
_settingsManager = settingsManager;
_configuration = configuration;
_httpContextAccessor = httpContextAccessor;
_settingsManager = settingsManager;
_log = logger;
}

View File

@ -34,7 +34,6 @@ public class GreetingSettingsController : BaseSettingsController
private readonly TenantManager _tenantManager;
private readonly PermissionContext _permissionContext;
private readonly TenantInfoSettingsHelper _tenantInfoSettingsHelper;
private readonly IConfiguration _configuration;
public GreetingSettingsController(
TenantInfoSettingsHelper tenantInfoSettingsHelper,
@ -44,14 +43,12 @@ public class GreetingSettingsController : BaseSettingsController
PermissionContext permissionContext,
WebItemManager webItemManager,
IMemoryCache memoryCache,
IHttpContextAccessor httpContextAccessor,
IConfiguration configuration) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
IHttpContextAccessor httpContextAccessor) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
{
_tenantInfoSettingsHelper = tenantInfoSettingsHelper;
_messageService = messageService;
_tenantManager = tenantManager;
_permissionContext = permissionContext;
_configuration = configuration;
}
[HttpGet("greetingsettings")]

View File

@ -30,8 +30,7 @@ public class SettingsController : BaseSettingsController
{
private static readonly object locked = new object();
private Tenant Tenant { get { return ApiContext.Tenant; } }
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly MessageService _messageService;
private readonly ConsumerFactory _consumerFactory;
private readonly TimeZoneConverter _timeZoneConverter;
@ -62,8 +61,7 @@ public class SettingsController : BaseSettingsController
private readonly QuotaUsageManager _quotaUsageManager;
private readonly QuotaSyncOperation _quotaSyncOperation;
public SettingsController(
IServiceScopeFactory serviceScopeFactory,
public SettingsController(
ILoggerProvider option,
MessageService messageService,
ApiContext apiContext,
@ -105,7 +103,6 @@ public class SettingsController : BaseSettingsController
_customNamingPeople = customNamingPeople;
_providerManager = providerManager;
_firstTimeTenantSettings = firstTimeTenantSettings;
_serviceScopeFactory = serviceScopeFactory;
_messageService = messageService;
_userManager = userManager;
_tenantManager = tenantManager;

View File

@ -38,7 +38,6 @@ public class StorageController : BaseSettingsController
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly ConsumerFactory _consumerFactory;
private readonly TenantManager _tenantManager;
private readonly TenantExtra _tenantExtra;
private readonly PermissionContext _permissionContext;
private readonly SettingsManager _settingsManager;
private readonly CoreBaseSettings _coreBaseSettings;
@ -61,7 +60,6 @@ public class StorageController : BaseSettingsController
StudioNotifyService studioNotifyService,
ApiContext apiContext,
TenantManager tenantManager,
TenantExtra tenantExtra,
PermissionContext permissionContext,
SettingsManager settingsManager,
WebItemManager webItemManager,
@ -86,7 +84,6 @@ public class StorageController : BaseSettingsController
_messageService = messageService;
_studioNotifyService = studioNotifyService;
_tenantManager = tenantManager;
_tenantExtra = tenantExtra;
_permissionContext = permissionContext;
_settingsManager = settingsManager;
_coreBaseSettings = coreBaseSettings;

View File

@ -38,8 +38,7 @@ public class WhitelabelController : BaseSettingsController
private readonly CoreBaseSettings _coreBaseSettings;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly IMapper _mapper;
private readonly CompanyWhiteLabelSettingsHelper _companyWhiteLabelSettingsHelper;
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
private readonly CompanyWhiteLabelSettingsHelper _companyWhiteLabelSettingsHelper;
public WhitelabelController(
ApiContext apiContext,
@ -54,7 +53,7 @@ public class WhitelabelController : BaseSettingsController
IMemoryCache memoryCache,
IHttpContextAccessor httpContextAccessor,
IMapper mapper,
CompanyWhiteLabelSettingsHelper companyWhiteLabelSettingsHelper, AdditionalWhiteLabelSettingsHelper additionalWhiteLabelSettingsHelper) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
CompanyWhiteLabelSettingsHelper companyWhiteLabelSettingsHelper) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
{
_permissionContext = permissionContext;
_settingsManager = settingsManager;
@ -65,7 +64,6 @@ public class WhitelabelController : BaseSettingsController
_commonLinkUtility = commonLinkUtility;
_mapper = mapper;
_companyWhiteLabelSettingsHelper = companyWhiteLabelSettingsHelper;
_additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
}
///<visible>false</visible>
@ -80,11 +78,11 @@ public class WhitelabelController : BaseSettingsController
if (inDto.Logo != null)
{
var logoDict = new Dictionary<int, string>();
var logoDict = new Dictionary<int, KeyValuePair<string, string>>();
foreach (var l in inDto.Logo)
{
logoDict.Add(Int32.Parse(l.Key), l.Value);
logoDict.Add(Int32.Parse(l.Key), new KeyValuePair<string, string>(l.Value.Light, l.Value.Dark));
}
await _tenantWhiteLabelSettingsHelper.SetLogo(settings, logoDict, null);
@ -112,61 +110,102 @@ public class WhitelabelController : BaseSettingsController
var settings = _settingsManager.Load<TenantWhiteLabelSettings>();
foreach (var f in HttpContext.Request.Form.Files)
{
var parts = f.FileName.Split('.');
var logoType = (WhiteLabelLogoTypeEnum)Convert.ToInt32(parts[0]);
var fileExt = parts[1];
await _tenantWhiteLabelSettingsHelper.SetLogoFromStream(settings, logoType, fileExt, f.OpenReadStream(), null);
{
if (f.FileName.Contains("dark"))
{
GetParts(f.FileName, out var logoType, out var fileExt);
if (HttpContext.Request.Form.Files.Any(f => f.FileName.Contains($"{logoType}")))
{
continue;
}
await _tenantWhiteLabelSettingsHelper.SetLogoFromStream(settings, logoType, fileExt, null, f.OpenReadStream(), null);
}
else
{
GetParts(f.FileName, out var logoType, out var fileExt);
IFormFile darkFile;
if (HttpContext.Request.Form.Files.Any(f => f.FileName.Contains($"{logoType}.dark.")))
{
darkFile = HttpContext.Request.Form.Files.Single(f => f.FileName.Contains($"{logoType}.dark."));
}
else
{
darkFile = null;
}
if (darkFile != null && darkFile.FileName != f.FileName)
{
throw new InvalidOperationException("logo light and logo dark have different extention");
}
await _tenantWhiteLabelSettingsHelper.SetLogoFromStream(settings, logoType, fileExt, f.OpenReadStream(), darkFile?.OpenReadStream(), null);
}
}
_settingsManager.SaveForTenant(settings, Tenant.Id);
return true;
}
private void GetParts(string fileName, out WhiteLabelLogoTypeEnum logoType, out string fileExt)
{
var parts = fileName.Split('.');
logoType = (WhiteLabelLogoTypeEnum)Convert.ToInt32(parts[0]);
fileExt = parts.Last();
}
///<visible>false</visible>
[AllowNotPayment]
[HttpGet("whitelabel/sizes")]
public object GetWhiteLabelSizes()
{
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
return
new[]
{
new {type = (int)WhiteLabelLogoTypeEnum.LightSmall, name = nameof(WhiteLabelLogoTypeEnum.LightSmall), height = TenantWhiteLabelSettings.LogoLightSmallSize.Height, width = TenantWhiteLabelSettings.LogoLightSmallSize.Width},
new {type = (int)WhiteLabelLogoTypeEnum.Dark, name = nameof(WhiteLabelLogoTypeEnum.Dark), height = TenantWhiteLabelSettings.LogoDarkSize.Height, width = TenantWhiteLabelSettings.LogoDarkSize.Width},
new {type = (int)WhiteLabelLogoTypeEnum.Favicon, name = nameof(WhiteLabelLogoTypeEnum.Favicon), height = TenantWhiteLabelSettings.LogoFaviconSize.Height, width = TenantWhiteLabelSettings.LogoFaviconSize.Width},
new {type = (int)WhiteLabelLogoTypeEnum.DocsEditor, name = nameof(WhiteLabelLogoTypeEnum.DocsEditor), height = TenantWhiteLabelSettings.LogoDocsEditorSize.Height, width = TenantWhiteLabelSettings.LogoDocsEditorSize.Width},
new {type = (int)WhiteLabelLogoTypeEnum.DocsEditorEmbed, name = nameof(WhiteLabelLogoTypeEnum.DocsEditorEmbed), height = TenantWhiteLabelSettings.LogoDocsEditorEmbedSize.Height, width = TenantWhiteLabelSettings.LogoDocsEditorEmbedSize.Width},
new {type = (int)WhiteLabelLogoTypeEnum.LeftMenu, name = nameof(WhiteLabelLogoTypeEnum.LeftMenu), height = TenantWhiteLabelSettings.LogoLeftMenuSize.Height, width = TenantWhiteLabelSettings.LogoLeftMenuSize.Width},
new {type = (int)WhiteLabelLogoTypeEnum.AboutPage, name = nameof(WhiteLabelLogoTypeEnum.AboutPage), height = TenantWhiteLabelSettings.LogoAboutPageSize.Height, width = TenantWhiteLabelSettings.LogoAboutPageSize.Width}
};
}
///<visible>false</visible>
[AllowNotPayment, AllowAnonymous]
[HttpGet("whitelabel/logos")]
public Dictionary<string, string> GetWhiteLabelLogos([FromQuery] WhiteLabelQueryRequestsDto inDto)
public async IAsyncEnumerable<WhiteLabelItemDto> GetWhiteLabelLogos([FromQuery] WhiteLabelQueryRequestsDto inDto)
{
Dictionary<string, string> result;
var _tenantWhiteLabelSettings = _settingsManager.Load<TenantWhiteLabelSettings>();
result = new Dictionary<string, string>
{
{ ((int)WhiteLabelLogoTypeEnum.LightSmall).ToString(), _commonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, WhiteLabelLogoTypeEnum.LightSmall, !inDto.IsRetina)) },
{ ((int)WhiteLabelLogoTypeEnum.Dark).ToString(), _commonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, WhiteLabelLogoTypeEnum.Dark, !inDto.IsRetina)) },
{ ((int)WhiteLabelLogoTypeEnum.Favicon).ToString(), _commonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, WhiteLabelLogoTypeEnum.Favicon, !inDto.IsRetina)) },
{ ((int)WhiteLabelLogoTypeEnum.DocsEditor).ToString(), _commonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, WhiteLabelLogoTypeEnum.DocsEditor, !inDto.IsRetina)) },
{ ((int)WhiteLabelLogoTypeEnum.DocsEditorEmbed).ToString(), _commonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings,WhiteLabelLogoTypeEnum.DocsEditorEmbed, !inDto.IsRetina)) },
{ ((int)WhiteLabelLogoTypeEnum.LeftMenu).ToString(), _commonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings,WhiteLabelLogoTypeEnum.LeftMenu, !inDto.IsRetina)) },
{ ((int)WhiteLabelLogoTypeEnum.AboutPage).ToString(), _commonLinkUtility.GetFullAbsolutePath(_tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings,WhiteLabelLogoTypeEnum.AboutPage, !inDto.IsRetina)) }
};
return result;
foreach (var logoType in (WhiteLabelLogoTypeEnum[])Enum.GetValues(typeof(WhiteLabelLogoTypeEnum)))
{
var result = new WhiteLabelItemDto
{
Name = logoType.ToString(),
Size = TenantWhiteLabelSettings.GetSize(logoType)
};
if (inDto.IsDark.HasValue)
{
var path = _commonLinkUtility.GetFullAbsolutePath(await _tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, logoType, inDto.IsDark.Value));
if (inDto.IsDark.Value)
{
result.Path = new WhiteLabelItemPathDto
{
Dark = path
};
}
else
{
result.Path = new WhiteLabelItemPathDto
{
Light = path
};
}
}
else
{
var lightPath = _commonLinkUtility.GetFullAbsolutePath(await _tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, logoType, false));
var darkPath = _commonLinkUtility.GetFullAbsolutePath(await _tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, logoType, true));
if (lightPath == darkPath)
{
darkPath = null;
}
result.Path = new WhiteLabelItemPathDto
{
Light = lightPath,
Dark = darkPath
};
}
yield return result;
}
}
///<visible>false</visible>

View File

@ -29,11 +29,16 @@ namespace ASC.Web.Api.ApiModel.RequestsDto;
public class WhiteLabelRequestsDto
{
public string LogoText { get; set; }
public IEnumerable<ItemKeyValuePair<string, string>> Logo { get; set; }
public IEnumerable<ItemKeyValuePair<string, LogoRequestsDto>> Logo { get; set; }
}
public class LogoRequestsDto
{
public string Light { get; set; }
public string Dark { get; set; }
}
public class WhiteLabelQueryRequestsDto
{
public bool IsDefault { get; set; }
public bool IsRetina { get; set; }
public bool? IsDark { get; set; }
}

View File

@ -0,0 +1,40 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Web.Api.ApiModels.ResponseDto;
public class WhiteLabelItemDto
{
public string Name { get; set; }
public SixLabors.ImageSharp.Size Size { get; set; }
public WhiteLabelItemPathDto Path { get; set; }
}
public class WhiteLabelItemPathDto
{
public string Light { get; set; }
public string Dark { get; set; }
}

View File

@ -37,7 +37,6 @@ public class DnsSettings
private readonly StudioNotifyService _studioNotifyService;
private readonly CommonLinkUtility _commonLinkUtility;
private readonly MessageService _messageService;
private readonly TenantExtra _tenantExtra;
public DnsSettings(
PermissionContext permissionContext,
@ -47,8 +46,7 @@ public class DnsSettings
CoreSettings coreSettings,
StudioNotifyService studioNotifyService,
CommonLinkUtility commonLinkUtility,
MessageService messageService,
TenantExtra tenantExtra)
MessageService messageService)
{
_permissionContext = permissionContext;
_tenantManager = tenantManager;
@ -58,7 +56,6 @@ public class DnsSettings
_studioNotifyService = studioNotifyService;
_commonLinkUtility = commonLinkUtility;
_messageService = messageService;
_tenantExtra = tenantExtra;
}
public string SaveDnsSettings(string dnsName, bool enableDns)

View File

@ -32,14 +32,14 @@ public class Startup : BaseStartup
public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) : base(configuration, hostEnvironment)
{
}
public override void ConfigureServices(IServiceCollection services)
{
base.ConfigureServices(services);
if (!_configuration.GetValue<bool>("disableLdapNotifyService"))
if (!_configuration.GetValue<bool>("disableLdapNotifyService"))
{
services.AddHostedService<LdapNotifyService>();
DIHelper.TryAdd<LdapNotifyService>();
@ -52,5 +52,19 @@ public class Startup : BaseStartup
services.AddScoped<ITenantQuotaFeatureStat<CountRoomFeature, int>, CountRoomCheckerStatistic>();
services.AddScoped<CountRoomCheckerStatistic>();
}
}
DIHelper.TryAdd<AdditionalWhiteLabelSettingsConverter>();
}
public override void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
base.Configure(app, env);
app.MapWhen(
context => context.Request.Path.ToString().EndsWith("logoUploader.ashx"),
appBranch =>
{
appBranch.UseLogoUploader();
});
}
}

View File

@ -25,7 +25,7 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.Web.Core.Log;
internal static partial class LogoUploaderLogger
internal static partial class StorageHelperLogger
{
[LoggerMessage(Level = LogLevel.Error, Message = "SaveTmpLogo")]
public static partial void ErrorSaveTmpLogo(this ILogger<StorageHelper> logger, Exception exception);

View File

@ -26,88 +26,93 @@
namespace ASC.Web.Studio.UserControls.CustomNavigation;
[Scope]
public class StorageHelper
public class LogoUploader
{
private const string StorageName = "customnavigation";
private const string Base64Start = "data:image/png;base64,";
private readonly UserPhotoManager _userPhotoManager;
private readonly StorageFactory _storageFactory;
private readonly TenantManager _tenantManager;
private readonly ILogger<StorageHelper> _logger;
public StorageHelper(UserPhotoManager userPhotoManager, StorageFactory storageFactory, TenantManager tenantManager, ILogger<StorageHelper> logger)
public LogoUploader(RequestDelegate next)
{
_userPhotoManager = userPhotoManager;
_storageFactory = storageFactory;
_tenantManager = tenantManager;
_logger = logger;
}
public async Task<string> SaveTmpLogo(string tmpLogoPath)
public async Task Invoke
(HttpContext context,
PermissionContext permissionContext,
SetupInfo setupInfo,
UserPhotoManager userPhotoManager)
{
if (string.IsNullOrEmpty(tmpLogoPath))
{
return null;
}
var result = new FileUploadResult();
try
{
byte[] data;
permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
if (tmpLogoPath.StartsWith(Base64Start))
var width = Convert.ToInt32(context.Request.Form["width"]);
var height = Convert.ToInt32(context.Request.Form["height"]);
var size = new Size(width, height);
if (context.Request.Form.Files.Count != 0)
{
data = Convert.FromBase64String(tmpLogoPath.Substring(Base64Start.Length));
const string imgContentType = @"image";
return SaveLogo(Guid.NewGuid() + ".png", data);
var logo = context.Request.Form.Files[0];
if (!logo.ContentType.StartsWith(imgContentType))
{
throw new Exception(Resource.ErrorFileNotImage);
}
var data = new byte[logo.Length];
var reader = new BinaryReader(logo.OpenReadStream());
reader.Read(data, 0, (int)logo.Length);
reader.Close();
if (logo.ContentType.Contains("svg"))
{
result.Success = true;
result.Message = await userPhotoManager.SaveTempSvg(data, setupInfo.MaxImageUploadSize);
}
else
{
using (var stream = new MemoryStream(data))
using (var image = Image.Load(stream))
{
var actualSize = image.Size();
if (actualSize.Height != size.Height && actualSize.Width != size.Width)
{
throw new ImageSizeLimitException();
}
}
result.Success = true;
result.Message = await userPhotoManager.SaveTempPhoto(data, setupInfo.MaxImageUploadSize, size.Width, size.Height);
}
}
var fileName = Path.GetFileName(tmpLogoPath);
data = _userPhotoManager.GetTempPhotoData(fileName);
await _userPhotoManager.RemoveTempPhoto(fileName);
return SaveLogo(fileName, data);
else
{
result.Success = false;
result.Message = Resource.ErrorEmptyUploadFileSelected;
}
}
catch (ImageWeightLimitException)
{
result.Success = false;
result.Message = Resource.ErrorImageWeightLimit;
}
catch (ImageSizeLimitException)
{
result.Success = false;
result.Message = Resource.ErrorImageSize;
}
catch (Exception ex)
{
_logger.ErrorSaveTmpLogo(ex);
return null;
result.Success = false;
result.Message = ex.Message.HtmlEncode();
}
await context.Response.WriteAsync(System.Text.Json.JsonSerializer.Serialize(result));
}
public async Task DeleteLogo(string logoPath)
}
public static class LogoUploaderExtensions
{
public static IApplicationBuilder UseLogoUploader(this IApplicationBuilder builder)
{
if (string.IsNullOrEmpty(logoPath))
{
return;
}
try
{
var store = _storageFactory.GetStorage(_tenantManager.GetCurrentTenant().Id, StorageName);
var fileName = Path.GetFileName(logoPath);
if (await store.IsFileAsync(fileName))
{
await store.DeleteAsync(fileName);
}
}
catch (Exception e)
{
_logger.ErrorDeleteLogo(e);
}
return builder.UseMiddleware<LogoUploader>();
}
private string SaveLogo(string fileName, byte[] data)
{
var store = _storageFactory.GetStorage(_tenantManager.GetCurrentTenant().Id, StorageName);
using var stream = new MemoryStream(data);
stream.Seek(0, SeekOrigin.Begin);
return store.SaveAsync(fileName, stream).Result.ToString();
}
}
}

View File

@ -375,7 +375,7 @@ public class NotifyTransferRequest : INotifyEngineAction
if (logoData == null)
{
var logoStream = _tenantLogoManager.GetWhitelabelMailLogo();
var logoStream = _tenantLogoManager.GetWhitelabelMailLogo().Result;
logoData = ReadStreamToByteArray(logoStream) ?? GetDefaultMailLogo();
if (logoData != null)
@ -404,7 +404,7 @@ public class NotifyTransferRequest : INotifyEngineAction
}
}
var logoUrl = _commonLinkUtility.GetFullAbsolutePath(_tenantLogoManager.GetLogoDark(true));
var logoUrl = _commonLinkUtility.GetFullAbsolutePath(_tenantLogoManager.GetLogoDark(false).Result);
request.Arguments.Add(new TagValue(CommonTags.LetterLogo, logoUrl));
}

View File

@ -40,7 +40,6 @@ public class StudioPeriodicNotify
private readonly CommonLinkUtility _commonLinkUtility;
private readonly ApiSystemHelper _apiSystemHelper;
private readonly SetupInfo _setupInfo;
private readonly IDbContextFactory<FeedDbContext> _dbContextFactory;
private readonly SettingsManager _settingsManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
@ -61,7 +60,6 @@ public class StudioPeriodicNotify
CommonLinkUtility commonLinkUtility,
ApiSystemHelper apiSystemHelper,
SetupInfo setupInfo,
IDbContextFactory<FeedDbContext> dbContextFactory,
SettingsManager settingsManager,
CoreBaseSettings coreBaseSettings,
DisplayUserSettingsHelper displayUserSettingsHelper,
@ -79,7 +77,6 @@ public class StudioPeriodicNotify
_commonLinkUtility = commonLinkUtility;
_apiSystemHelper = apiSystemHelper;
_setupInfo = setupInfo;
_dbContextFactory = dbContextFactory;
_settingsManager = settingsManager;
_coreBaseSettings = coreBaseSettings;
_displayUserSettingsHelper = displayUserSettingsHelper;

View File

@ -1680,6 +1680,24 @@ namespace ASC.Web.Core.PublicResources {
}
}
/// <summary>
/// Looks up a localized string similar to Unknown image file type.
/// </summary>
public static string ErrorFileNotImage {
get {
return ResourceManager.GetString("ErrorFileNotImage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Image size exceed the allowed parameters.
/// </summary>
public static string ErrorImageSize {
get {
return ResourceManager.GetString("ErrorImageSize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Image file size is too large.
/// </summary>

View File

@ -909,6 +909,12 @@
<data name="ErrorIpSecurity" xml:space="preserve">
<value>The access to the portal is restricted</value>
</data>
<data name="ErrorFileNotImage" xml:space="preserve">
<value>Unknown image file type</value>
</data>
<data name="ErrorImageSize" xml:space="preserve">
<value>Image size exceed the allowed parameters</value>
</data>
<data name="ConsumersTelegram" xml:space="preserve">
<value>Telegram</value>
</data>
@ -924,4 +930,4 @@
<data name="ConsumersTelegramInstructionV11" xml:space="preserve">
<value>To receive portal notifications via Telegram, enable Telegram bot. You can create a new bot using BotFather in Telegram Desktop. To use this bot, portal users need to enable Telegram notifications on their Profile Page. {0}Paste bots username and the token you received in the fields below.</value>
</data>
</root>
</root>

View File

@ -0,0 +1,112 @@
// (c) Copyright Ascensio System SIA 2010-2022
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
[Scope]
public class StorageHelper
{
private const string StorageName = "customnavigation";
private const string Base64Start = "data:image/png;base64,";
private readonly UserPhotoManager _userPhotoManager;
private readonly StorageFactory _storageFactory;
private readonly TenantManager _tenantManager;
private readonly ILogger<StorageHelper> _logger;
public StorageHelper(UserPhotoManager userPhotoManager, StorageFactory storageFactory, TenantManager tenantManager, ILogger<StorageHelper> logger)
{
_userPhotoManager = userPhotoManager;
_storageFactory = storageFactory;
_tenantManager = tenantManager;
_logger = logger;
}
public async Task<string> SaveTmpLogo(string tmpLogoPath)
{
if (string.IsNullOrEmpty(tmpLogoPath))
{
return null;
}
try
{
byte[] data;
if (tmpLogoPath.StartsWith(Base64Start))
{
data = Convert.FromBase64String(tmpLogoPath.Substring(Base64Start.Length));
return await SaveLogo(Guid.NewGuid() + ".png", data);
}
var fileName = Path.GetFileName(tmpLogoPath);
data = await _userPhotoManager.GetTempPhotoData(fileName);
await _userPhotoManager.RemoveTempPhoto(fileName);
return await SaveLogo(fileName, data);
}
catch (Exception ex)
{
_logger.ErrorSaveTmpLogo(ex);
return null;
}
}
public async Task DeleteLogo(string logoPath)
{
if (string.IsNullOrEmpty(logoPath))
{
return;
}
try
{
var store = _storageFactory.GetStorage(_tenantManager.GetCurrentTenant().Id, StorageName);
var fileName = Path.GetFileName(logoPath);
if (await store.IsFileAsync(fileName))
{
await store.DeleteAsync(fileName);
}
}
catch (Exception e)
{
_logger.ErrorDeleteLogo(e);
}
}
private async Task<string> SaveLogo(string fileName, byte[] data)
{
var store = _storageFactory.GetStorage(_tenantManager.GetCurrentTenant().Id, StorageName);
using var stream = new MemoryStream(data);
stream.Seek(0, SeekOrigin.Begin);
return (await store.SaveAsync(fileName, stream)).ToString();
}
}

View File

@ -40,12 +40,10 @@ public sealed class UserManagerWrapper
private readonly StudioNotifyService _studioNotifyService;
private readonly UserManager _userManager;
private readonly SecurityContext _securityContext;
private readonly MessageService _messageService;
private readonly CustomNamingPeople _customNamingPeople;
private readonly TenantUtil _tenantUtil;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly IPSecurity.IPSecurity _iPSecurity;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
private readonly SettingsManager _settingsManager;
private readonly UserFormatter _userFormatter;
private readonly CountRoomAdminChecker _countManagerChecker;
@ -54,12 +52,10 @@ public sealed class UserManagerWrapper
StudioNotifyService studioNotifyService,
UserManager userManager,
SecurityContext securityContext,
MessageService messageService,
CustomNamingPeople customNamingPeople,
TenantUtil tenantUtil,
CoreBaseSettings coreBaseSettings,
IPSecurity.IPSecurity iPSecurity,
DisplayUserSettingsHelper displayUserSettingsHelper,
SettingsManager settingsManager,
UserFormatter userFormatter,
CountRoomAdminChecker countManagerChecker)
@ -67,12 +63,10 @@ public sealed class UserManagerWrapper
_studioNotifyService = studioNotifyService;
_userManager = userManager;
_securityContext = securityContext;
_messageService = messageService;
_customNamingPeople = customNamingPeople;
_tenantUtil = tenantUtil;
_coreBaseSettings = coreBaseSettings;
_iPSecurity = iPSecurity;
_displayUserSettingsHelper = displayUserSettingsHelper;
_settingsManager = settingsManager;
_userFormatter = userFormatter;
_countManagerChecker = countManagerChecker;

View File

@ -437,7 +437,6 @@ public class UserPhotoManager
};
}
private static readonly HashSet<int> _tenantDiskCache = new HashSet<int>();
private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1);
@ -458,7 +457,7 @@ public class UserPhotoManager
if (!string.IsNullOrEmpty(fileName))
{
var store = GetDataStore();
return store.GetUriAsync(fileName).Result.ToString();
return (await store.GetUriAsync(fileName)).ToString();
}
return null;
@ -566,7 +565,7 @@ public class UserPhotoManager
{
using (var stream = new MemoryStream(data))
{
photoUrl = store.SaveAsync(fileName, stream).Result.ToString();
photoUrl = (await store.SaveAsync(fileName, stream)).ToString();
}
//Queue resizing
var t1 = SizePhoto(userID, data, -1, SmallFotoSize, true);
@ -753,12 +752,12 @@ public class UserPhotoManager
}
}
public string GetTempPhotoAbsoluteWebPath(string fileName)
public async Task<string> GetTempPhotoAbsoluteWebPath(string fileName)
{
return GetDataStore().GetUriAsync(_tempDomainName, fileName).Result.ToString();
return (await GetDataStore().GetUriAsync(_tempDomainName, fileName)).ToString();
}
public string SaveTempPhoto(byte[] data, long maxFileSize, int maxWidth, int maxHeight)
public async Task<string> SaveTempPhoto(byte[] data, long maxFileSize, int maxWidth, int maxHeight)
{
data = TryParseImage(data, maxFileSize, new Size(maxWidth, maxHeight), out var imgFormat, out _, out _);
@ -766,33 +765,48 @@ public class UserPhotoManager
var store = GetDataStore();
using var stream = new MemoryStream(data);
return store.SaveAsync(_tempDomainName, fileName, stream).Result.ToString();
return (await store.SaveAsync(_tempDomainName, fileName, stream)).ToString();
}
public byte[] GetTempPhotoData(string fileName)
public async Task<string> SaveTempSvg(byte[] data, long maxFileSize)
{
using var s = GetDataStore().GetReadStreamAsync(_tempDomainName, fileName).Result;
if (maxFileSize != -1 && data.Length > maxFileSize)
{
throw new ImageSizeLimitException();
}
using var stream = new MemoryStream(data);
var fileName = Guid.NewGuid() + ".svg";
var store = GetDataStore();
return (await store.SaveAsync(_tempDomainName, fileName, stream)).ToString();
}
public async Task<byte[]> GetTempPhotoData(string fileName)
{
using var s = await GetDataStore().GetReadStreamAsync(_tempDomainName, fileName);
var data = new MemoryStream();
var buffer = new byte[1024 * 10];
while (true)
{
var count = s.Read(buffer, 0, buffer.Length);
var count = await s.ReadAsync(buffer, 0, buffer.Length);
if (count == 0)
{
break;
}
data.Write(buffer, 0, count);
await data.WriteAsync(buffer, 0, count);
}
return data.ToArray();
}
public string GetSizedTempPhotoAbsoluteWebPath(string fileName, int newWidth, int newHeight)
public async Task<string> GetSizedTempPhotoAbsoluteWebPath(string fileName, int newWidth, int newHeight)
{
var store = GetDataStore();
if (store.IsFileAsync(_tempDomainName, fileName).Result)
if (await store.IsFileAsync(_tempDomainName, fileName))
{
using var s = store.GetReadStreamAsync(_tempDomainName, fileName).Result;
using var s = await store.GetReadStreamAsync(_tempDomainName, fileName);
using var img = Image.Load(s, out var format);
var imgFormat = format;
byte[] data;
@ -812,8 +826,9 @@ public class UserPhotoManager
var trueFileName = fileNameWithoutExt + "_size_" + newWidth.ToString() + "-" + newHeight.ToString() + "." + widening;
using var stream = new MemoryStream(data);
return store.SaveAsync(_tempDomainName, trueFileName, stream).Result.ToString();
return (await store.SaveAsync(_tempDomainName, trueFileName, stream)).ToString();
}
return GetDefaultPhotoAbsoluteWebPath(new Size(newWidth, newHeight));
}
@ -847,7 +862,7 @@ public class UserPhotoManager
return null;
}
public string SaveThumbnail(Guid userID, Image img, IImageFormat format)
public async Task<string> SaveThumbnail(Guid userID, Image img, IImageFormat format)
{
var moduleID = Guid.Empty;
var widening = CommonPhotoManager.GetImgFormatName(format);
@ -859,7 +874,7 @@ public class UserPhotoManager
using (var s = new MemoryStream(CommonPhotoManager.SaveToBytes(img)))
{
img.Dispose();
photoUrl = store.SaveAsync(fileName, s).Result.ToString();
photoUrl = (await store.SaveAsync(fileName, s)).ToString();
}
_userPhotoManagerCache.AddToCache(userID, size, fileName, _tenant.Id);
@ -872,14 +887,14 @@ public class UserPhotoManager
{
var pattern = string.Format("{0}_size_{1}-{2}.*", userId, size.Width, size.Height);
var fileName = (await GetDataStore().ListFilesRelativeAsync("", "", pattern, false).ToArrayAsync()).FirstOrDefault();
var fileName = await GetDataStore().ListFilesRelativeAsync("", "", pattern, false).FirstOrDefaultAsync();
if (string.IsNullOrEmpty(fileName))
{
return null;
}
using var s = GetDataStore().GetReadStreamAsync("", fileName).Result;
using var s = await GetDataStore().GetReadStreamAsync("", fileName);
var data = new MemoryStream();
var buffer = new byte[1024 * 10];
while (true)

View File

@ -63,7 +63,7 @@ public static class UserPhotoThumbnailManager
resultBitmaps.Add(thumbnail);
}
thumbnailsData.Save(resultBitmaps);
await thumbnailsData.Save(resultBitmaps);
settingsManager.SaveForUser(thumbnailSettings, userId);
@ -248,12 +248,12 @@ public class ThumbnailsData
};
}
public void Save(List<ThumbnailItem> bitmaps)
public async Task Save(List<ThumbnailItem> bitmaps)
{
foreach (var item in bitmaps)
{
using var mainImgBitmap = MainImgBitmap(out var format);
_userPhotoManager.SaveThumbnail(_userId, item.Image, format);
await _userPhotoManager.SaveThumbnail(_userId, item.Image, format);
}
}
}

View File

@ -46,23 +46,23 @@ public class TenantLogoHelper
_tenantInfoSettingsHelper = tenantInfoSettingsHelper;
}
public string GetLogo(WhiteLabelLogoTypeEnum type, bool general = true, bool isDefIfNoWhiteLabel = false)
public async Task<string> GetLogo(WhiteLabelLogoTypeEnum type, bool isDefIfNoWhiteLabel = false, bool dark = false)
{
string imgUrl;
if (_tenantLogoManager.WhiteLabelEnabled)
{
var _tenantWhiteLabelSettings = _settingsManager.Load<TenantWhiteLabelSettings>();
return _tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, type, general);
return await _tenantWhiteLabelSettingsHelper.GetAbsoluteLogoPath(_tenantWhiteLabelSettings, type, dark);
}
else
{
if (isDefIfNoWhiteLabel)
{
imgUrl = _tenantWhiteLabelSettingsHelper.GetAbsoluteDefaultLogoPath(type, general);
imgUrl = await _tenantWhiteLabelSettingsHelper.GetAbsoluteDefaultLogoPath(type, dark);
}
else
{
if (type == WhiteLabelLogoTypeEnum.Dark)
if (type == WhiteLabelLogoTypeEnum.LoginPage)
{
/*** simple scheme ***/
var _tenantInfoSettings = _settingsManager.Load<TenantInfoSettings>();
@ -71,7 +71,7 @@ public class TenantLogoHelper
}
else
{
imgUrl = _tenantWhiteLabelSettingsHelper.GetAbsoluteDefaultLogoPath(type, general);
imgUrl = await _tenantWhiteLabelSettingsHelper.GetAbsoluteDefaultLogoPath(type, dark);
}
}
}

Some files were not shown because too many files have changed in this diff Show More