Merge branch 'develop' of github.com:ONLYOFFICE/AppServer into feature/sso
# Conflicts: # web/ASC.Web.Client/public/locales/en/Settings.json
This commit is contained in:
commit
9e68c29d4f
22
.gitignore
vendored
22
.gitignore
vendored
@ -17,3 +17,25 @@ Logs/
|
||||
build/deploy/
|
||||
/public/debuginfo.md
|
||||
TestsResults/
|
||||
/Data.Test
|
||||
/build/install/RadicalePlugins/app_auth_plugin/app_auth_plugin.egg-info/PKG-INFO
|
||||
/build/install/RadicalePlugins/app_auth_plugin/app_auth_plugin.egg-info/SOURCES.txt
|
||||
/build/install/RadicalePlugins/app_auth_plugin/app_auth_plugin.egg-info/dependency_links.txt
|
||||
/build/install/RadicalePlugins/app_auth_plugin/app_auth_plugin.egg-info/top_level.txt
|
||||
/build/install/RadicalePlugins/app_auth_plugin/build/lib/app_auth_plugin/__init__.py
|
||||
/build/install/RadicalePlugins/app_rights_plugin/app_rights_plugin.egg-info/PKG-INFO
|
||||
/build/install/RadicalePlugins/app_rights_plugin/app_rights_plugin.egg-info/SOURCES.txt
|
||||
/build/install/RadicalePlugins/app_rights_plugin/app_rights_plugin.egg-info/dependency_links.txt
|
||||
/build/install/RadicalePlugins/app_rights_plugin/app_rights_plugin.egg-info/top_level.txt
|
||||
/build/install/RadicalePlugins/app_rights_plugin/build/lib/app_rights_plugin/__init__.py
|
||||
/build/install/RadicalePlugins/app_store_plugin/app_store_plugin.egg-info/PKG-INFO
|
||||
/build/install/RadicalePlugins/app_store_plugin/app_store_plugin.egg-info/SOURCES.txt
|
||||
/build/install/RadicalePlugins/app_store_plugin/app_store_plugin.egg-info/dependency_links.txt
|
||||
/build/install/RadicalePlugins/app_store_plugin/app_store_plugin.egg-info/top_level.txt
|
||||
/build/install/RadicalePlugins/app_store_plugin/build/lib/app_store_plugin/__init__.py
|
||||
/build/install/RadicalePlugins/app_store_plugin/build/lib/app_store_plugin/cache.py
|
||||
/build/install/RadicalePlugins/app_store_plugin/build/lib/app_store_plugin/delete.py
|
||||
/build/install/RadicalePlugins/app_store_plugin/build/lib/app_store_plugin/history.py
|
||||
/build/install/RadicalePlugins/app_store_plugin/build/lib/app_store_plugin/log.py
|
||||
/build/install/RadicalePlugins/app_store_plugin/build/lib/app_store_plugin/sync.py
|
||||
/build/install/RadicalePlugins/app_store_plugin/build/lib/app_store_plugin/upload.py
|
||||
|
12
ASC.Web.sln
12
ASC.Web.sln
@ -24,8 +24,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.FederatedLogin", "commo
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Web.Core", "web\ASC.Web.Core\ASC.Web.Core.csproj", "{02C40A64-FE22-41D0-9037-69F0D6F787A9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.VoipService", "common\ASC.VoipService\ASC.VoipService.csproj", "{988536C1-4B89-4649-8F77-5C16F55D95D1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.MessagingSystem", "common\ASC.MessagingSystem\ASC.MessagingSystem.csproj", "{BD8A18A5-60C5-4411-9719-0AA11B4BE0E9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.IPSecurity", "common\ASC.IPSecurity\ASC.IPSecurity.csproj", "{2FF2177F-2D1A-4396-84EB-51F14FD99385}"
|
||||
@ -54,8 +52,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.ApiSystem", "common\ser
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Feed.Aggregator", "common\services\ASC.Feed.Aggregator\ASC.Feed.Aggregator.csproj", "{07CCC11F-76CB-448E-B15A-72E09FBB348B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Thumbnails.Svc", "common\services\ASC.Thumbnails.Svc\ASC.Thumbnails.Svc.csproj", "{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Files.Core", "products\ASC.Files\Core\ASC.Files.Core.csproj", "{F0A39728-940D-4DBE-A37A-05D4EB57F342}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Data.Storage.Migration", "common\services\ASC.Data.Storage.Migration\ASC.Data.Storage.Migration.csproj", "{02356BD7-7E99-457B-BEFF-090CE4DF067D}"
|
||||
@ -147,10 +143,6 @@ Global
|
||||
{02C40A64-FE22-41D0-9037-69F0D6F787A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{02C40A64-FE22-41D0-9037-69F0D6F787A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{02C40A64-FE22-41D0-9037-69F0D6F787A9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{988536C1-4B89-4649-8F77-5C16F55D95D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{988536C1-4B89-4649-8F77-5C16F55D95D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{988536C1-4B89-4649-8F77-5C16F55D95D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{988536C1-4B89-4649-8F77-5C16F55D95D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BD8A18A5-60C5-4411-9719-0AA11B4BE0E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BD8A18A5-60C5-4411-9719-0AA11B4BE0E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BD8A18A5-60C5-4411-9719-0AA11B4BE0E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -207,10 +199,6 @@ Global
|
||||
{07CCC11F-76CB-448E-B15A-72E09FBB348B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{07CCC11F-76CB-448E-B15A-72E09FBB348B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{07CCC11F-76CB-448E-B15A-72E09FBB348B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1D2F61B2-B1F4-45F0-83CA-03370FD6E62C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F0A39728-940D-4DBE-A37A-05D4EB57F342}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F0A39728-940D-4DBE-A37A-05D4EB57F342}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F0A39728-940D-4DBE-A37A-05D4EB57F342}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
|
@ -20,7 +20,6 @@
|
||||
"common\\ASC.Migration\\ASC.Migration.csproj",
|
||||
"common\\ASC.Notify.Textile\\ASC.Notify.Textile.csproj",
|
||||
"common\\ASC.Textile\\ASC.Textile.csproj",
|
||||
"common\\ASC.VoipService\\ASC.VoipService.csproj",
|
||||
"common\\ASC.Webhooks.Core\\ASC.Webhooks.Core.csproj",
|
||||
"common\\services\\ASC.AuditTrail\\ASC.AuditTrail.csproj",
|
||||
"common\\services\\ASC.ClearEvents\\ASC.ClearEvents.csproj",
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
using static ASC.Security.Cryptography.EmailValidationKeyProvider;
|
||||
|
||||
using Constants = ASC.Core.Users.Constants;
|
||||
|
||||
namespace ASC.Api.Core.Security;
|
||||
|
||||
[Transient]
|
||||
@ -58,7 +60,7 @@ public class EmailValidationKeyModelHelper
|
||||
{
|
||||
var request = QueryHelpers.ParseQuery(_httpContextAccessor.HttpContext.Request.Headers["confirm"]);
|
||||
|
||||
request.TryGetValue("type", out var type);
|
||||
var type = request.ContainsKey("type") ? request["type"].FirstOrDefault() : null;
|
||||
|
||||
ConfirmType? cType = null;
|
||||
if (ConfirmTypeExtensions.TryParse(type, out var confirmType))
|
||||
@ -141,7 +143,7 @@ public class EmailValidationKeyModelHelper
|
||||
case ConfirmType.ProfileRemove:
|
||||
// validate UiD
|
||||
var user = _userManager.GetUsers(uiD.GetValueOrDefault());
|
||||
if (user == null || user.Status == EmployeeStatus.Terminated || _authContext.IsAuthenticated && _authContext.CurrentAccount.ID != uiD)
|
||||
if (user == null || user == Constants.LostUser || user.Status == EmployeeStatus.Terminated || _authContext.IsAuthenticated && _authContext.CurrentAccount.ID != uiD)
|
||||
{
|
||||
return ValidationResult.Invalid;
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ public class AscCacheNotify
|
||||
public void OnClearCache()
|
||||
{
|
||||
_cache.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Singletone]
|
||||
public class AscCache : ICache
|
||||
@ -67,27 +67,14 @@ public class AscCache : ICache
|
||||
return _memoryCache.Get<T>(key);
|
||||
}
|
||||
|
||||
public void Insert(string key, object value, TimeSpan sligingExpiration)
|
||||
public void Insert(string key, object value, TimeSpan sligingExpiration, Action<object, object, EvictionReason, object> evictionCallback = null)
|
||||
{
|
||||
var options = new MemoryCacheEntryOptions()
|
||||
.SetSlidingExpiration(sligingExpiration)
|
||||
.RegisterPostEvictionCallback(EvictionCallback)
|
||||
.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token));
|
||||
|
||||
_memoryCache.Set(key, value, options);
|
||||
_memoryCacheKeys.TryAdd(key, null);
|
||||
Insert(key, value, sligingExpiration, null, evictionCallback);
|
||||
}
|
||||
|
||||
public void Insert(string key, object value, DateTime absolutExpiration)
|
||||
public void Insert(string key, object value, DateTime absolutExpiration, Action<object, object, EvictionReason, object> evictionCallback = null)
|
||||
{
|
||||
var options = new MemoryCacheEntryOptions()
|
||||
.SetAbsoluteExpiration(absolutExpiration == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration))
|
||||
.RegisterPostEvictionCallback(EvictionCallback)
|
||||
.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token));
|
||||
|
||||
|
||||
_memoryCache.Set(key, value, options);
|
||||
_memoryCacheKeys.TryAdd(key, null);
|
||||
Insert(key, value, null, absolutExpiration, evictionCallback);
|
||||
}
|
||||
|
||||
public void Remove(string key)
|
||||
@ -160,6 +147,31 @@ public class AscCache : ICache
|
||||
}
|
||||
}
|
||||
|
||||
private void Insert(string key, object value, TimeSpan? sligingExpiration = null, DateTime? absolutExpiration = null, Action<object, object, EvictionReason, object> evictionCallback = null)
|
||||
{
|
||||
var options = new MemoryCacheEntryOptions()
|
||||
.RegisterPostEvictionCallback(EvictionCallback)
|
||||
.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token));
|
||||
|
||||
if (sligingExpiration.HasValue)
|
||||
{
|
||||
options = options.SetSlidingExpiration(sligingExpiration.Value);
|
||||
}
|
||||
|
||||
if (absolutExpiration.HasValue)
|
||||
{
|
||||
options = options.SetAbsoluteExpiration(absolutExpiration.Value == DateTime.MaxValue ? DateTimeOffset.MaxValue : new DateTimeOffset(absolutExpiration.Value));
|
||||
}
|
||||
|
||||
if (evictionCallback != null)
|
||||
{
|
||||
options = options.RegisterPostEvictionCallback(new PostEvictionDelegate(evictionCallback));
|
||||
}
|
||||
|
||||
_memoryCache.Set(key, value, options);
|
||||
_memoryCacheKeys.TryAdd(key, null);
|
||||
}
|
||||
|
||||
private void EvictionCallback(object key, object value, EvictionReason reason, object state)
|
||||
{
|
||||
_memoryCacheKeys.TryRemove(key.ToString(), out _);
|
||||
|
@ -31,9 +31,9 @@ public interface ICache
|
||||
{
|
||||
T Get<T>(string key) where T : class;
|
||||
|
||||
void Insert(string key, object value, TimeSpan sligingExpiration);
|
||||
void Insert(string key, object value, TimeSpan sligingExpiration, Action<object, object, EvictionReason, object> evictionCallback = null);
|
||||
|
||||
void Insert(string key, object value, DateTime absolutExpiration);
|
||||
void Insert(string key, object value, DateTime absolutExpiration, Action<object, object, EvictionReason, object> evictionCallback = null);
|
||||
|
||||
void Remove(string key);
|
||||
|
||||
@ -44,6 +44,6 @@ public interface ICache
|
||||
T HashGet<T>(string key, string field);
|
||||
|
||||
void HashSet<T>(string key, string field, T value);
|
||||
|
||||
|
||||
void Reset();
|
||||
}
|
@ -50,6 +50,11 @@ public class AzRecord : IMapFrom<Acl>
|
||||
Object = fullId;
|
||||
}
|
||||
|
||||
public AzRecord(Guid subjectId, Guid actionId, AceType reaction, ISecurityObjectId objectId)
|
||||
: this(subjectId, actionId, reaction, AzObjectIdHelper.GetFullObjectId(objectId))
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator AzRecord(AzRecordCache cache)
|
||||
{
|
||||
var result = new AzRecord()
|
||||
|
@ -45,7 +45,6 @@ public class DbLoginEventsManager
|
||||
(int)MessageAction.LoginSuccessViaApiTfa
|
||||
};
|
||||
|
||||
private readonly ICache _cache;
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly AuthContext _authContext;
|
||||
private readonly IMapper _mapper;
|
||||
@ -54,14 +53,11 @@ public class DbLoginEventsManager
|
||||
private readonly Lazy<MessagesContext> _lazyLoginEventContext;
|
||||
|
||||
public DbLoginEventsManager(
|
||||
ICache cache,
|
||||
TenantManager tenantManager,
|
||||
AuthContext authContext,
|
||||
DbContextManager<MessagesContext> dbContextManager,
|
||||
TenantUtil tenantUtil,
|
||||
IMapper mapper)
|
||||
{
|
||||
_cache = cache;
|
||||
_tenantManager = tenantManager;
|
||||
_authContext = authContext;
|
||||
_mapper = mapper;
|
||||
@ -69,25 +65,13 @@ public class DbLoginEventsManager
|
||||
}
|
||||
|
||||
public async Task<List<int>> GetLoginEventIds(int tenantId, Guid userId)
|
||||
{
|
||||
var commonKey = GetCacheKey(tenantId, userId);
|
||||
var cacheKeys = _cache.Get<List<int>>(commonKey);
|
||||
if (cacheKeys != null)
|
||||
{
|
||||
return cacheKeys;
|
||||
}
|
||||
|
||||
{
|
||||
var date = DateTime.UtcNow.AddYears(-1);
|
||||
var resultList = await LoginEventContext.LoginEvents
|
||||
.Where(r => r.TenantId == tenantId && r.UserId == userId && _loginActions.Contains(r.Action) && r.Date >= date && r.Active)
|
||||
.Select(r => r.Id)
|
||||
.ToListAsync();
|
||||
|
||||
if (resultList != null)
|
||||
{
|
||||
_cache.Insert(commonKey, resultList, _expirationTimeout);
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@ -174,7 +158,6 @@ public class DbLoginEventsManager
|
||||
public void ResetCache(int tenantId, Guid userId)
|
||||
{
|
||||
var key = GetCacheKey(tenantId, userId);
|
||||
_cache.Remove(key);
|
||||
}
|
||||
|
||||
private string GetCacheKey(int tenantId, Guid userId)
|
||||
|
@ -1,65 +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.Core.Common.EF.Context;
|
||||
|
||||
public class MySqlVoipDbContext : VoipDbContext { }
|
||||
public class PostgreSqlVoipDbContext : VoipDbContext { }
|
||||
public class VoipDbContext : BaseDbContext
|
||||
{
|
||||
public DbSet<VoipNumber> VoipNumbers { get; set; }
|
||||
public DbSet<DbVoipCall> VoipCalls { get; set; }
|
||||
public DbSet<CrmContact> CrmContact { get; set; }
|
||||
|
||||
protected override Dictionary<Provider, Func<BaseDbContext>> ProviderContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Dictionary<Provider, Func<BaseDbContext>>()
|
||||
{
|
||||
{ Provider.MySql, () => new MySqlVoipDbContext() } ,
|
||||
{ Provider.PostgreSql, () => new PostgreSqlVoipDbContext() } ,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
ModelBuilderWrapper
|
||||
.From(modelBuilder, _provider)
|
||||
.AddVoipNumber()
|
||||
.AddDbVoipCall()
|
||||
.AddCrmContact();
|
||||
}
|
||||
}
|
||||
|
||||
public static class VoipDbExtension
|
||||
{
|
||||
public static DIHelper AddVoipDbContextService(this DIHelper services)
|
||||
{
|
||||
return services.AddDbContextManagerService<VoipDbContext>();
|
||||
}
|
||||
}
|
@ -1,208 +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.Core.Common.EF.Model;
|
||||
|
||||
public class DbVoipCall
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string ParentCallId { get; set; }
|
||||
public string NumberFrom { get; set; }
|
||||
public string NumberTo { get; set; }
|
||||
public int Status { get; set; }
|
||||
public Guid AnsweredBy { get; set; }
|
||||
public DateTime DialDate { get; set; }
|
||||
public int DialDuration { get; set; }
|
||||
public string Sid { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public int Duration { get; set; }
|
||||
public decimal RecordPrice { get; set; }
|
||||
public int ContactId { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
|
||||
public CrmContact CrmContact { get; set; }
|
||||
}
|
||||
public static class DbVoipCallExtension
|
||||
{
|
||||
public static ModelBuilderWrapper AddDbVoipCall(this ModelBuilderWrapper modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Add(MySqlAddDbVoipCall, Provider.MySql)
|
||||
.Add(PgSqlAddDbVoipCall, Provider.PostgreSql);
|
||||
|
||||
return modelBuilder;
|
||||
}
|
||||
|
||||
public static void MySqlAddDbVoipCall(this ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<DbVoipCall>(entity =>
|
||||
{
|
||||
entity.ToTable("crm_voip_calls");
|
||||
|
||||
entity.HasIndex(e => e.TenantId)
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
entity.HasIndex(e => new { e.ParentCallId, e.TenantId })
|
||||
.HasDatabaseName("parent_call_id");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnName("id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.AnsweredBy)
|
||||
.IsRequired()
|
||||
.HasColumnName("answered_by")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.ContactId).HasColumnName("contact_id");
|
||||
|
||||
entity.Property(e => e.DialDate)
|
||||
.HasColumnName("dial_date")
|
||||
.HasColumnType("datetime");
|
||||
|
||||
entity.Property(e => e.DialDuration).HasColumnName("dial_duration");
|
||||
|
||||
entity.Property(e => e.NumberFrom)
|
||||
.IsRequired()
|
||||
.HasColumnName("number_from")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.NumberTo)
|
||||
.IsRequired()
|
||||
.HasColumnName("number_to")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.ParentCallId)
|
||||
.IsRequired()
|
||||
.HasColumnName("parent_call_id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Price)
|
||||
.HasColumnName("price")
|
||||
.HasColumnType("decimal(10,4)");
|
||||
|
||||
entity.Property(e => e.Duration).HasColumnName("record_duration");
|
||||
|
||||
entity.Property(e => e.RecordPrice)
|
||||
.HasColumnName("record_price")
|
||||
.HasColumnType("decimal(10,4)");
|
||||
|
||||
entity.Property(e => e.Sid)
|
||||
.HasColumnName("record_sid")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Uri)
|
||||
.HasColumnName("record_url")
|
||||
.HasColumnType("text")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Status).HasColumnName("status");
|
||||
|
||||
entity.Property(e => e.TenantId).HasColumnName("tenant_id");
|
||||
});
|
||||
}
|
||||
public static void PgSqlAddDbVoipCall(this ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<DbVoipCall>(entity =>
|
||||
{
|
||||
entity.ToTable("crm_voip_calls", "onlyoffice");
|
||||
|
||||
entity.HasIndex(e => e.TenantId)
|
||||
.HasDatabaseName("tenant_id_crm_voip_calls");
|
||||
|
||||
entity.HasIndex(e => new { e.ParentCallId, e.TenantId })
|
||||
.HasDatabaseName("parent_call_id");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnName("id")
|
||||
.HasMaxLength(50);
|
||||
|
||||
entity.Property(e => e.AnsweredBy)
|
||||
.IsRequired()
|
||||
.HasColumnName("answered_by")
|
||||
.HasMaxLength(50)
|
||||
.HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'");
|
||||
|
||||
entity.Property(e => e.ContactId).HasColumnName("contact_id");
|
||||
|
||||
entity.Property(e => e.DialDate).HasColumnName("dial_date");
|
||||
|
||||
entity.Property(e => e.DialDuration).HasColumnName("dial_duration");
|
||||
|
||||
entity.Property(e => e.NumberFrom)
|
||||
.IsRequired()
|
||||
.HasColumnName("number_from")
|
||||
.HasMaxLength(50);
|
||||
|
||||
entity.Property(e => e.NumberTo)
|
||||
.IsRequired()
|
||||
.HasColumnName("number_to")
|
||||
.HasMaxLength(50);
|
||||
|
||||
entity.Property(e => e.ParentCallId)
|
||||
.IsRequired()
|
||||
.HasColumnName("parent_call_id")
|
||||
.HasMaxLength(50);
|
||||
|
||||
entity.Property(e => e.Price)
|
||||
.HasColumnName("price")
|
||||
.HasColumnType("numeric(10,4)")
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.Duration).HasColumnName("record_duration");
|
||||
|
||||
entity.Property(e => e.RecordPrice)
|
||||
.HasColumnName("record_price")
|
||||
.HasColumnType("numeric(10,4)");
|
||||
|
||||
entity.Property(e => e.Sid)
|
||||
.HasColumnName("record_sid")
|
||||
.HasMaxLength(50)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.Uri).HasColumnName("record_url");
|
||||
|
||||
entity.Property(e => e.Status).HasColumnName("status");
|
||||
|
||||
entity.Property(e => e.TenantId).HasColumnName("tenant_id");
|
||||
});
|
||||
}
|
||||
}
|
@ -1,112 +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.Core.Common.EF.Model;
|
||||
|
||||
public class VoipNumber
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Number { get; set; }
|
||||
public string Alias { get; set; }
|
||||
public string Settings { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
}
|
||||
public static class VoipNumberExtension
|
||||
{
|
||||
public static ModelBuilderWrapper AddVoipNumber(this ModelBuilderWrapper modelBuilder)
|
||||
{
|
||||
modelBuilder
|
||||
.Add(MySqlAddVoipNumber, Provider.MySql)
|
||||
.Add(PgSqlAddVoipNumber, Provider.PostgreSql);
|
||||
|
||||
return modelBuilder;
|
||||
}
|
||||
public static void MySqlAddVoipNumber(this ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<VoipNumber>(entity =>
|
||||
{
|
||||
entity.ToTable("crm_voip_number");
|
||||
|
||||
entity.HasIndex(e => e.TenantId)
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnName("id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Alias)
|
||||
.HasColumnName("alias")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Number)
|
||||
.IsRequired()
|
||||
.HasColumnName("number")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.Settings)
|
||||
.HasColumnName("settings")
|
||||
.HasColumnType("text")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.TenantId).HasColumnName("tenant_id");
|
||||
});
|
||||
}
|
||||
public static void PgSqlAddVoipNumber(this ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<VoipNumber>(entity =>
|
||||
{
|
||||
entity.ToTable("crm_voip_number", "onlyoffice");
|
||||
|
||||
entity.HasIndex(e => e.TenantId)
|
||||
.HasDatabaseName("tenant_id_crm_voip_number");
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnName("id")
|
||||
.HasMaxLength(50);
|
||||
|
||||
entity.Property(e => e.Alias)
|
||||
.HasColumnName("alias")
|
||||
.HasMaxLength(255)
|
||||
.HasDefaultValueSql("NULL");
|
||||
|
||||
entity.Property(e => e.Number)
|
||||
.IsRequired()
|
||||
.HasColumnName("number")
|
||||
.HasMaxLength(50);
|
||||
|
||||
entity.Property(e => e.Settings).HasColumnName("settings");
|
||||
|
||||
entity.Property(e => e.TenantId).HasColumnName("tenant_id");
|
||||
});
|
||||
}
|
||||
}
|
@ -65,6 +65,7 @@ public class DbTenant : IMapFrom<Tenant>
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<Tenant, DbTenant>()
|
||||
.ForMember(dest => dest.TrustedDomainsEnabled, opt => opt.MapFrom(dest => dest.TrustedDomainsType))
|
||||
.ForMember(dest => dest.TrustedDomainsRaw, opt => opt.MapFrom(dest => dest.GetTrustedDomains()))
|
||||
.ForMember(dest => dest.Alias, opt => opt.MapFrom(dest => dest.Alias.ToLowerInvariant()))
|
||||
.ForMember(dest => dest.LastModified, opt => opt.MapFrom(dest => DateTime.UtcNow))
|
||||
|
@ -160,3 +160,5 @@ global using ProtoBuf;
|
||||
global using Telegram.Bot;
|
||||
|
||||
global using static ASC.Security.Cryptography.EmailValidationKeyProvider;
|
||||
|
||||
global using JsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;
|
@ -34,7 +34,8 @@ public class EventTypeConverter : ITypeConverter<EventMessage, LoginEvent>, ITyp
|
||||
var messageEvent = context.Mapper.Map<EventMessage, MessageEvent>(source);
|
||||
var loginEvent = context.Mapper.Map<MessageEvent, LoginEvent>(messageEvent);
|
||||
|
||||
loginEvent.Login = source.Initiator;
|
||||
loginEvent.Login = source.Initiator;
|
||||
loginEvent.Active = source.Active;
|
||||
|
||||
if (source.Description != null && source.Description.Count > 0)
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ public class LoginEvent : MessageEvent, IMapFrom<EventMessage>
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<MessageEvent, LoginEvent>();
|
||||
profile.CreateMap<EventMessage, LoginEvent>()
|
||||
.ConvertUsing<EventTypeConverter>();
|
||||
}
|
||||
|
@ -1,282 +0,0 @@
|
||||
// <auto-generated />
|
||||
|
||||
namespace ASC.Core.Common.Migrations.MySql.VoipDbContextMySql
|
||||
{
|
||||
[DbContext(typeof(MySqlVoipDbContext))]
|
||||
[Migration("20211012145344_VoipDbContextMySql")]
|
||||
partial class VoipDbContextMySql
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64)
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.CrmContact", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("CompanyId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("company_id");
|
||||
|
||||
b.Property<string>("CompanyName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("company_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("ContactTypeId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("contact_type_id");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<string>("Currency")
|
||||
.HasColumnType("varchar(3)")
|
||||
.HasColumnName("currency")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("DisplayName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("display_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("first_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Industry")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("industry")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("IsCompany")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("is_company");
|
||||
|
||||
b.Property<bool>("IsShared")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("is_shared");
|
||||
|
||||
b.Property<string>("LastModifedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("last_modifed_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("LastModifedOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("last_modifed_on");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("last_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("notes")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("StatusId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status_id");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreateOn")
|
||||
.HasDatabaseName("create_on");
|
||||
|
||||
b.HasIndex("LastModifedOn", "TenantId")
|
||||
.HasDatabaseName("last_modifed_on");
|
||||
|
||||
b.HasIndex("TenantId", "CompanyId")
|
||||
.HasDatabaseName("company_id");
|
||||
|
||||
b.HasIndex("TenantId", "DisplayName")
|
||||
.HasDatabaseName("display_name");
|
||||
|
||||
b.ToTable("crm_contact");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbVoipCall", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("AnsweredBy")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("answered_by")
|
||||
.HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("ContactId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("contact_id");
|
||||
|
||||
b.Property<int?>("CrmContactId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("DialDate")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("dial_date");
|
||||
|
||||
b.Property<int>("DialDuration")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("dial_duration");
|
||||
|
||||
b.Property<string>("NumberFrom")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number_from")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("NumberTo")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number_to")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("ParentCallId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("parent_call_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("decimal(10,4)")
|
||||
.HasColumnName("price");
|
||||
|
||||
b.Property<int>("RecordDuration")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("record_duration");
|
||||
|
||||
b.Property<decimal>("RecordPrice")
|
||||
.HasColumnType("decimal(10,4)")
|
||||
.HasColumnName("record_price");
|
||||
|
||||
b.Property<string>("RecordSid")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("record_sid")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("RecordUrl")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("record_url")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CrmContactId");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.HasIndex("ParentCallId", "TenantId")
|
||||
.HasDatabaseName("parent_call_id");
|
||||
|
||||
b.ToTable("crm_voip_calls");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.VoipNumber", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("alias")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Number")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Settings")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("settings")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("crm_voip_number");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbVoipCall", b =>
|
||||
{
|
||||
b.HasOne("ASC.Core.Common.EF.Model.CrmContact", "CrmContact")
|
||||
.WithMany()
|
||||
.HasForeignKey("CrmContactId");
|
||||
|
||||
b.Navigation("CrmContact");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,189 +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.Core.Common.Migrations.MySql.VoipDbContextMySql;
|
||||
|
||||
public partial class VoipDbContextMySql : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterDatabase()
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "crm_contact",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
tenant_id = table.Column<int>(type: "int", nullable: false),
|
||||
is_company = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
notes = table.Column<string>(type: "text", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
title = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
first_name = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
last_name = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
company_name = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
industry = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
status_id = table.Column<int>(type: "int", nullable: false),
|
||||
company_id = table.Column<int>(type: "int", nullable: false),
|
||||
contact_type_id = table.Column<int>(type: "int", nullable: false),
|
||||
create_by = table.Column<string>(type: "char(38)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
create_on = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
last_modifed_by = table.Column<string>(type: "char(38)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
last_modifed_on = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
display_name = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
is_shared = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
currency = table.Column<string>(type: "varchar(3)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_crm_contact", x => x.id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "crm_voip_number",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
number = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
alias = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
settings = table.Column<string>(type: "text", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
tenant_id = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_crm_voip_number", x => x.id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "crm_voip_calls",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
parent_call_id = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
number_from = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
number_to = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
status = table.Column<int>(type: "int", nullable: false),
|
||||
answered_by = table.Column<string>(type: "varchar(50)", nullable: false, defaultValueSql: "'00000000-0000-0000-0000-000000000000'", collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
dial_date = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
dial_duration = table.Column<int>(type: "int", nullable: false),
|
||||
record_sid = table.Column<string>(type: "varchar(50)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
record_url = table.Column<string>(type: "text", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
record_duration = table.Column<int>(type: "int", nullable: false),
|
||||
record_price = table.Column<decimal>(type: "decimal(10,4)", nullable: false),
|
||||
contact_id = table.Column<int>(type: "int", nullable: false),
|
||||
price = table.Column<decimal>(type: "decimal(10,4)", nullable: false),
|
||||
tenant_id = table.Column<int>(type: "int", nullable: false),
|
||||
CrmContactId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_crm_voip_calls", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_crm_voip_calls_crm_contact_CrmContactId",
|
||||
column: x => x.CrmContactId,
|
||||
principalTable: "crm_contact",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "company_id",
|
||||
table: "crm_contact",
|
||||
columns: new[] { "tenant_id", "company_id" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "create_on",
|
||||
table: "crm_contact",
|
||||
column: "create_on");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "display_name",
|
||||
table: "crm_contact",
|
||||
columns: new[] { "tenant_id", "display_name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "last_modifed_on",
|
||||
table: "crm_contact",
|
||||
columns: new[] { "last_modifed_on", "tenant_id" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_crm_voip_calls_CrmContactId",
|
||||
table: "crm_voip_calls",
|
||||
column: "CrmContactId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "parent_call_id",
|
||||
table: "crm_voip_calls",
|
||||
columns: new[] { "parent_call_id", "tenant_id" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "tenant_id",
|
||||
table: "crm_voip_calls",
|
||||
column: "tenant_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "tenant_id",
|
||||
table: "crm_voip_number",
|
||||
column: "tenant_id");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "crm_voip_calls");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "crm_voip_number");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "crm_contact");
|
||||
}
|
||||
}
|
@ -1,281 +0,0 @@
|
||||
// <auto-generated />
|
||||
|
||||
namespace ASC.Core.Common.Migrations.MySql.VoipDbContextMySql
|
||||
{
|
||||
[DbContext(typeof(MySqlVoipDbContext))]
|
||||
partial class MySqlVoipDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64)
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.CrmContact", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("CompanyId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("company_id");
|
||||
|
||||
b.Property<string>("CompanyName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("company_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("ContactTypeId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("contact_type_id");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<string>("Currency")
|
||||
.HasColumnType("varchar(3)")
|
||||
.HasColumnName("currency")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("DisplayName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("display_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("first_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Industry")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("industry")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("IsCompany")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("is_company");
|
||||
|
||||
b.Property<bool>("IsShared")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("is_shared");
|
||||
|
||||
b.Property<string>("LastModifedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("last_modifed_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("LastModifedOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("last_modifed_on");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("last_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("notes")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("StatusId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status_id");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreateOn")
|
||||
.HasDatabaseName("create_on");
|
||||
|
||||
b.HasIndex("LastModifedOn", "TenantId")
|
||||
.HasDatabaseName("last_modifed_on");
|
||||
|
||||
b.HasIndex("TenantId", "CompanyId")
|
||||
.HasDatabaseName("company_id");
|
||||
|
||||
b.HasIndex("TenantId", "DisplayName")
|
||||
.HasDatabaseName("display_name");
|
||||
|
||||
b.ToTable("crm_contact");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbVoipCall", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("AnsweredBy")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("answered_by")
|
||||
.HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("ContactId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("contact_id");
|
||||
|
||||
b.Property<int?>("CrmContactId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("DialDate")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("dial_date");
|
||||
|
||||
b.Property<int>("DialDuration")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("dial_duration");
|
||||
|
||||
b.Property<string>("NumberFrom")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number_from")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("NumberTo")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number_to")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("ParentCallId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("parent_call_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("decimal(10,4)")
|
||||
.HasColumnName("price");
|
||||
|
||||
b.Property<int>("RecordDuration")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("record_duration");
|
||||
|
||||
b.Property<decimal>("RecordPrice")
|
||||
.HasColumnType("decimal(10,4)")
|
||||
.HasColumnName("record_price");
|
||||
|
||||
b.Property<string>("RecordSid")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("record_sid")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("RecordUrl")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("record_url")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CrmContactId");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.HasIndex("ParentCallId", "TenantId")
|
||||
.HasDatabaseName("parent_call_id");
|
||||
|
||||
b.ToTable("crm_voip_calls");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.VoipNumber", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("alias")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Number")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Settings")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("settings")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("crm_voip_number");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbVoipCall", b =>
|
||||
{
|
||||
b.HasOne("ASC.Core.Common.EF.Model.CrmContact", "CrmContact")
|
||||
.WithMany()
|
||||
.HasForeignKey("CrmContactId");
|
||||
|
||||
b.Navigation("CrmContact");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,282 +0,0 @@
|
||||
// <auto-generated />
|
||||
|
||||
namespace ASC.Core.Common.Migrations.PostgreSql.VoipDbContextPostgreSql
|
||||
{
|
||||
[DbContext(typeof(PostgreSqlVoipDbContext))]
|
||||
[Migration("20211012145345_VoipDbContextPostgreSql")]
|
||||
partial class VoipDbContextPostgreSql
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64)
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.CrmContact", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("CompanyId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("company_id");
|
||||
|
||||
b.Property<string>("CompanyName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("company_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("ContactTypeId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("contact_type_id");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<string>("Currency")
|
||||
.HasColumnType("varchar(3)")
|
||||
.HasColumnName("currency")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("DisplayName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("display_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("first_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Industry")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("industry")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("IsCompany")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("is_company");
|
||||
|
||||
b.Property<bool>("IsShared")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("is_shared");
|
||||
|
||||
b.Property<string>("LastModifedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("last_modifed_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("LastModifedOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("last_modifed_on");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("last_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("notes")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("StatusId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status_id");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreateOn")
|
||||
.HasDatabaseName("create_on");
|
||||
|
||||
b.HasIndex("LastModifedOn", "TenantId")
|
||||
.HasDatabaseName("last_modifed_on");
|
||||
|
||||
b.HasIndex("TenantId", "CompanyId")
|
||||
.HasDatabaseName("company_id");
|
||||
|
||||
b.HasIndex("TenantId", "DisplayName")
|
||||
.HasDatabaseName("display_name");
|
||||
|
||||
b.ToTable("crm_contact");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbVoipCall", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("AnsweredBy")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("answered_by")
|
||||
.HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("ContactId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("contact_id");
|
||||
|
||||
b.Property<int?>("CrmContactId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("DialDate")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("dial_date");
|
||||
|
||||
b.Property<int>("DialDuration")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("dial_duration");
|
||||
|
||||
b.Property<string>("NumberFrom")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number_from")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("NumberTo")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number_to")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("ParentCallId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("parent_call_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("decimal(10,4)")
|
||||
.HasColumnName("price");
|
||||
|
||||
b.Property<int>("RecordDuration")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("record_duration");
|
||||
|
||||
b.Property<decimal>("RecordPrice")
|
||||
.HasColumnType("decimal(10,4)")
|
||||
.HasColumnName("record_price");
|
||||
|
||||
b.Property<string>("RecordSid")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("record_sid")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("RecordUrl")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("record_url")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CrmContactId");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.HasIndex("ParentCallId", "TenantId")
|
||||
.HasDatabaseName("parent_call_id");
|
||||
|
||||
b.ToTable("crm_voip_calls");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.VoipNumber", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("alias")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Number")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Settings")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("settings")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("crm_voip_number");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbVoipCall", b =>
|
||||
{
|
||||
b.HasOne("ASC.Core.Common.EF.Model.CrmContact", "CrmContact")
|
||||
.WithMany()
|
||||
.HasForeignKey("CrmContactId");
|
||||
|
||||
b.Navigation("CrmContact");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -1,189 +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.Core.Common.Migrations.PostgreSql.VoipDbContextPostgreSql;
|
||||
|
||||
public partial class VoipDbContextPostgreSql : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterDatabase()
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "crm_contact",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
tenant_id = table.Column<int>(type: "int", nullable: false),
|
||||
is_company = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
notes = table.Column<string>(type: "text", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
title = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
first_name = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
last_name = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
company_name = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
industry = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
status_id = table.Column<int>(type: "int", nullable: false),
|
||||
company_id = table.Column<int>(type: "int", nullable: false),
|
||||
contact_type_id = table.Column<int>(type: "int", nullable: false),
|
||||
create_by = table.Column<string>(type: "char(38)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
create_on = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
last_modifed_by = table.Column<string>(type: "char(38)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
last_modifed_on = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
display_name = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
is_shared = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
currency = table.Column<string>(type: "varchar(3)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_crm_contact", x => x.id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "crm_voip_number",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
number = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
alias = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
settings = table.Column<string>(type: "text", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
tenant_id = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_crm_voip_number", x => x.id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "crm_voip_calls",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
parent_call_id = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
number_from = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
number_to = table.Column<string>(type: "varchar(50)", nullable: false, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
status = table.Column<int>(type: "int", nullable: false),
|
||||
answered_by = table.Column<string>(type: "varchar(50)", nullable: false, defaultValueSql: "'00000000-0000-0000-0000-000000000000'", collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
dial_date = table.Column<DateTime>(type: "datetime", nullable: false),
|
||||
dial_duration = table.Column<int>(type: "int", nullable: false),
|
||||
record_sid = table.Column<string>(type: "varchar(50)", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
record_url = table.Column<string>(type: "text", nullable: true, collation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8"),
|
||||
record_duration = table.Column<int>(type: "int", nullable: false),
|
||||
record_price = table.Column<decimal>(type: "decimal(10,4)", nullable: false),
|
||||
contact_id = table.Column<int>(type: "int", nullable: false),
|
||||
price = table.Column<decimal>(type: "decimal(10,4)", nullable: false),
|
||||
tenant_id = table.Column<int>(type: "int", nullable: false),
|
||||
CrmContactId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_crm_voip_calls", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_crm_voip_calls_crm_contact_CrmContactId",
|
||||
column: x => x.CrmContactId,
|
||||
principalTable: "crm_contact",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "company_id",
|
||||
table: "crm_contact",
|
||||
columns: new[] { "tenant_id", "company_id" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "create_on",
|
||||
table: "crm_contact",
|
||||
column: "create_on");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "display_name",
|
||||
table: "crm_contact",
|
||||
columns: new[] { "tenant_id", "display_name" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "last_modifed_on",
|
||||
table: "crm_contact",
|
||||
columns: new[] { "last_modifed_on", "tenant_id" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_crm_voip_calls_CrmContactId",
|
||||
table: "crm_voip_calls",
|
||||
column: "CrmContactId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "parent_call_id",
|
||||
table: "crm_voip_calls",
|
||||
columns: new[] { "parent_call_id", "tenant_id" });
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "tenant_id",
|
||||
table: "crm_voip_calls",
|
||||
column: "tenant_id");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "tenant_id",
|
||||
table: "crm_voip_number",
|
||||
column: "tenant_id");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "crm_voip_calls");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "crm_voip_number");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "crm_contact");
|
||||
}
|
||||
}
|
@ -1,281 +0,0 @@
|
||||
// <auto-generated />
|
||||
|
||||
namespace ASC.Core.Common.Migrations.PostgreSql.VoipDbContextPostgreSql
|
||||
{
|
||||
[DbContext(typeof(PostgreSqlVoipDbContext))]
|
||||
partial class PostgreSqlVoipDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64)
|
||||
.HasAnnotation("ProductVersion", "5.0.10");
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.CrmContact", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("CompanyId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("company_id");
|
||||
|
||||
b.Property<string>("CompanyName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("company_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("ContactTypeId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("contact_type_id");
|
||||
|
||||
b.Property<string>("CreateBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("create_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("CreateOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("create_on");
|
||||
|
||||
b.Property<string>("Currency")
|
||||
.HasColumnType("varchar(3)")
|
||||
.HasColumnName("currency")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("DisplayName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("display_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("first_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Industry")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("industry")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<bool>("IsCompany")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("is_company");
|
||||
|
||||
b.Property<bool>("IsShared")
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("is_shared");
|
||||
|
||||
b.Property<string>("LastModifedBy")
|
||||
.IsRequired()
|
||||
.HasColumnType("char(38)")
|
||||
.HasColumnName("last_modifed_by")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<DateTime>("LastModifedOn")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("last_modifed_on");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("last_name")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Notes")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("notes")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("StatusId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status_id");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("title")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CreateOn")
|
||||
.HasDatabaseName("create_on");
|
||||
|
||||
b.HasIndex("LastModifedOn", "TenantId")
|
||||
.HasDatabaseName("last_modifed_on");
|
||||
|
||||
b.HasIndex("TenantId", "CompanyId")
|
||||
.HasDatabaseName("company_id");
|
||||
|
||||
b.HasIndex("TenantId", "DisplayName")
|
||||
.HasDatabaseName("display_name");
|
||||
|
||||
b.ToTable("crm_contact");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbVoipCall", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("AnsweredBy")
|
||||
.IsRequired()
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("answered_by")
|
||||
.HasDefaultValueSql("'00000000-0000-0000-0000-000000000000'")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("ContactId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("contact_id");
|
||||
|
||||
b.Property<int?>("CrmContactId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("DialDate")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("dial_date");
|
||||
|
||||
b.Property<int>("DialDuration")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("dial_duration");
|
||||
|
||||
b.Property<string>("NumberFrom")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number_from")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("NumberTo")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number_to")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("ParentCallId")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("parent_call_id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("decimal(10,4)")
|
||||
.HasColumnName("price");
|
||||
|
||||
b.Property<int>("RecordDuration")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("record_duration");
|
||||
|
||||
b.Property<decimal>("RecordPrice")
|
||||
.HasColumnType("decimal(10,4)")
|
||||
.HasColumnName("record_price");
|
||||
|
||||
b.Property<string>("RecordSid")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("record_sid")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("RecordUrl")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("record_url")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CrmContactId");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.HasIndex("ParentCallId", "TenantId")
|
||||
.HasDatabaseName("parent_call_id");
|
||||
|
||||
b.ToTable("crm_voip_calls");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.VoipNumber", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("id")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Alias")
|
||||
.HasColumnType("varchar(255)")
|
||||
.HasColumnName("alias")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Number")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("number")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Settings")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("settings")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("crm_voip_number");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Core.Common.EF.Model.DbVoipCall", b =>
|
||||
{
|
||||
b.HasOne("ASC.Core.Common.EF.Model.CrmContact", "CrmContact")
|
||||
.WithMany()
|
||||
.HasForeignKey("CrmContactId");
|
||||
|
||||
b.Navigation("CrmContact");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -321,17 +321,17 @@ public class SignalrServiceClient
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateFile<T>(T fileId, string room, string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
MakeRequest("update-file", new { room, fileId, data });
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
ProcessError(error);
|
||||
}
|
||||
public void UpdateFile<T>(T fileId, string room, string data)
|
||||
{
|
||||
try
|
||||
{
|
||||
MakeRequest("update-file", new { room, fileId, data });
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
ProcessError(error);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteFile<T>(T fileId, string room)
|
||||
{
|
||||
|
@ -149,7 +149,8 @@ public class Tenant : IMapFrom<DbTenant>
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<DbTenant, Tenant>();
|
||||
profile.CreateMap<DbTenant, Tenant>()
|
||||
.ForMember(r => r.TrustedDomainsType, opt => opt.MapFrom(src => src.TrustedDomainsEnabled));
|
||||
|
||||
profile.CreateMap<TenantUserSecurity, Tenant>()
|
||||
.IncludeMembers(src => src.DbTenant);
|
||||
|
@ -35,6 +35,8 @@ public class TenantAuditSettings : ISettings<TenantAuditSettings>
|
||||
public int AuditTrailLifeTime { get; set; }
|
||||
|
||||
public static readonly Guid Guid = new Guid("{8337D0FB-AD67-4552-8297-802312E7F503}");
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid ID => Guid;
|
||||
|
||||
public TenantAuditSettings GetDefault()
|
||||
|
@ -31,8 +31,9 @@ namespace ASC.Core.Tenants;
|
||||
public class TenantControlPanelSettings : ISettings<TenantControlPanelSettings>
|
||||
{
|
||||
[DataMember(Name = "LimitedAccess")]
|
||||
public bool LimitedAccess { get; set; }
|
||||
|
||||
public bool LimitedAccess { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid ID => new Guid("{880585C4-52CD-4AE2-8DA4-3B8E2772753B}");
|
||||
|
||||
public TenantControlPanelSettings GetDefault()
|
||||
|
@ -49,6 +49,7 @@ public class TenantCookieSettings : ISettings<TenantCookieSettings>
|
||||
return new TenantCookieSettings();
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid ID => new Guid("{16FB8E67-E96D-4B22-B217-C80F25C5DE1B}");
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ namespace ASC.Web.Core.Users;
|
||||
[Serializable]
|
||||
public class DarkThemeSettings : ISettings<DarkThemeSettings>
|
||||
{
|
||||
[System.Text.Json.Serialization.JsonIgnore]
|
||||
[JsonIgnore]
|
||||
public Guid ID
|
||||
{
|
||||
get { return new Guid("{38362061-066D-4C57-A23E-8953CF34EFC3}"); }
|
||||
|
@ -29,6 +29,7 @@ namespace ASC.Web.Core.Users;
|
||||
[Serializable]
|
||||
public class DisplayUserSettings : ISettings<DisplayUserSettings>
|
||||
{
|
||||
[JsonIgnore]
|
||||
public Guid ID => new Guid("2EF59652-E1A7-4814-BF71-FEB990149428");
|
||||
|
||||
public bool IsDisableGettingStarted { get; set; }
|
||||
|
@ -31,6 +31,7 @@ public class PersonalQuotaSettings : ISettings<PersonalQuotaSettings>
|
||||
{
|
||||
public long MaxSpace { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid ID => new Guid("{C634A747-C39B-4517-8698-B3B39BF2BD8E}");
|
||||
|
||||
public PersonalQuotaSettings GetDefault()
|
||||
|
@ -40,6 +40,7 @@ public class MailWhiteLabelSettings : ISettings<MailWhiteLabelSettings>
|
||||
public string DemoUrl { get; set; }
|
||||
public string SiteUrl { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid ID => new Guid("{C3602052-5BA2-452A-BD2A-ADD0FAF8EB88}");
|
||||
|
||||
public MailWhiteLabelSettings(IConfiguration configuration)
|
||||
|
@ -97,6 +97,7 @@ public abstract class BaseStorageSettings<T> : ISettings<BaseStorageSettings<T>>
|
||||
[Serializable]
|
||||
public class StorageSettings : BaseStorageSettings<StorageSettings>, ISettings<StorageSettings>
|
||||
{
|
||||
[JsonIgnore]
|
||||
public override Guid ID => new Guid("F13EAF2D-FA53-44F1-A6D6-A5AEDA46FA2B");
|
||||
|
||||
StorageSettings ISettings<StorageSettings>.GetDefault()
|
||||
@ -109,6 +110,7 @@ public class StorageSettings : BaseStorageSettings<StorageSettings>, ISettings<S
|
||||
[Serializable]
|
||||
public class CdnStorageSettings : BaseStorageSettings<CdnStorageSettings>, ISettings<CdnStorageSettings>
|
||||
{
|
||||
[JsonIgnore]
|
||||
public override Guid ID => new Guid("0E9AE034-F398-42FE-B5EE-F86D954E9FB2");
|
||||
|
||||
public override Func<DataStoreConsumer, DataStoreConsumer> Switch => d => d.Cdn;
|
||||
|
@ -59,7 +59,8 @@ public class IPRestrictionsRepository
|
||||
using var tx = TenantDbContext.Database.BeginTransaction();
|
||||
|
||||
var restrictions = TenantDbContext.TenantIpRestrictions.Where(r => r.Tenant == tenant).ToList();
|
||||
TenantDbContext.TenantIpRestrictions.RemoveRange(restrictions);
|
||||
TenantDbContext.TenantIpRestrictions.RemoveRange(restrictions);
|
||||
TenantDbContext.SaveChanges();
|
||||
|
||||
var ipsList = ips.Select(r => new TenantIpRestrictions
|
||||
{
|
||||
@ -67,7 +68,8 @@ public class IPRestrictionsRepository
|
||||
Ip = r
|
||||
});
|
||||
|
||||
TenantDbContext.TenantIpRestrictions.AddRange(ipsList);
|
||||
TenantDbContext.TenantIpRestrictions.AddRange(ipsList);
|
||||
TenantDbContext.SaveChanges();
|
||||
|
||||
tx.Commit();
|
||||
});
|
||||
|
@ -24,6 +24,8 @@
|
||||
// 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.Text.Json.Serialization;
|
||||
|
||||
namespace ASC.IPSecurity;
|
||||
|
||||
[Serializable]
|
||||
@ -31,6 +33,7 @@ public class IPRestrictionsSettings : ISettings<IPRestrictionsSettings>
|
||||
{
|
||||
public bool Enable { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid ID => new Guid("{2EDDDF64-F792-4498-A638-2E3E6EBB13C9}");
|
||||
|
||||
public IPRestrictionsSettings GetDefault()
|
||||
|
@ -1,40 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ApplicationIcon />
|
||||
<OutputType>Library</OutputType>
|
||||
<StartupObject />
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Properties\**" />
|
||||
<Compile Remove="VoxImplant\**" />
|
||||
<EmbeddedResource Remove="Properties\**" />
|
||||
<EmbeddedResource Remove="VoxImplant\**" />
|
||||
<None Remove="Properties\**" />
|
||||
<None Remove="VoxImplant\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Grpc.Tools" Version="2.45.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Twilio" Version="5.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ASC.Core.Common\ASC.Core.Common.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="protos\cached_voip_item.proto" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,64 +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.VoipService.Dao;
|
||||
|
||||
public class AbstractDao
|
||||
{
|
||||
private readonly string _dbid = "default";
|
||||
private readonly Lazy<VoipDbContext> _lazyVoipDbContext;
|
||||
|
||||
protected VoipDbContext VoipDbContext { get => _lazyVoipDbContext.Value; }
|
||||
protected int TenantID
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
protected AbstractDao(DbContextManager<VoipDbContext> dbOptions, TenantManager tenantManager)
|
||||
{
|
||||
_lazyVoipDbContext = new Lazy<VoipDbContext>(() => dbOptions.Get(_dbid));
|
||||
TenantID = tenantManager.GetCurrentTenant().Id;
|
||||
}
|
||||
|
||||
protected string GetTenantColumnName(string table)
|
||||
{
|
||||
const string tenant = "tenant_id";
|
||||
if (!table.Contains(' '))
|
||||
{
|
||||
return tenant;
|
||||
}
|
||||
|
||||
return table.Substring(table.IndexOf(" ", StringComparison.Ordinal)).Trim() + "." + tenant;
|
||||
}
|
||||
|
||||
|
||||
protected static Guid ToGuid(object guid)
|
||||
{
|
||||
var str = guid as string;
|
||||
return !string.IsNullOrEmpty(str) ? new Guid(str) : Guid.Empty;
|
||||
}
|
||||
}
|
@ -1,113 +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.VoipService.Dao;
|
||||
|
||||
public class VoipCallFilter
|
||||
{
|
||||
public string Type { get; set; }
|
||||
public DateTime? FromDate { get; set; }
|
||||
public DateTime? ToDate { get; set; }
|
||||
public Guid? Agent { get; set; }
|
||||
public int? Client { get; set; }
|
||||
public int? ContactID { get; set; }
|
||||
public string Id { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
public string SortBy { get; set; }
|
||||
public bool SortOrder { get; set; }
|
||||
public string SearchText { get; set; }
|
||||
public long Offset { get; set; }
|
||||
public long Max { get; set; }
|
||||
|
||||
public int? TypeStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Type))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (TypeStatuses.TryGetValue(Type, out var status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string SortByColumn
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(SortBy))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return SortColumns.ContainsKey(SortBy) ? SortColumns[SortBy] : null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, int> TypeStatuses
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Dictionary<string, int>
|
||||
{
|
||||
{
|
||||
"answered", (int)VoipCallStatus.Answered
|
||||
},
|
||||
{
|
||||
"missed", (int)VoipCallStatus.Missed
|
||||
},
|
||||
{
|
||||
"outgoing", (int)VoipCallStatus.Outcoming
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> SortColumns
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Dictionary<string, string>
|
||||
{
|
||||
{
|
||||
"date", "dial_date"
|
||||
},
|
||||
{
|
||||
"duration", "dial_duration"
|
||||
},
|
||||
{
|
||||
"price", "price"
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -1,326 +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.VoipService.Dao;
|
||||
|
||||
[Scope(Additional = typeof(EventTypeConverterExtension))]
|
||||
public class VoipDao : AbstractDao
|
||||
{
|
||||
private readonly AuthContext _authContext;
|
||||
private readonly TenantUtil _tenantUtil;
|
||||
private readonly SecurityContext _securityContext;
|
||||
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
|
||||
private readonly ConsumerFactory _consumerFactory;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public VoipDao(
|
||||
TenantManager tenantManager,
|
||||
DbContextManager<VoipDbContext> dbOptions,
|
||||
AuthContext authContext,
|
||||
TenantUtil tenantUtil,
|
||||
SecurityContext securityContext,
|
||||
BaseCommonLinkUtility baseCommonLinkUtility,
|
||||
ConsumerFactory consumerFactory,
|
||||
IMapper mapper)
|
||||
: base(dbOptions, tenantManager)
|
||||
{
|
||||
_authContext = authContext;
|
||||
_tenantUtil = tenantUtil;
|
||||
_securityContext = securityContext;
|
||||
_baseCommonLinkUtility = baseCommonLinkUtility;
|
||||
_consumerFactory = consumerFactory;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public virtual VoipPhone SaveOrUpdateNumber(VoipPhone phone)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(phone.Number))
|
||||
{
|
||||
phone.Number = phone.Number.TrimStart('+');
|
||||
}
|
||||
|
||||
var voipNumber = new VoipNumber
|
||||
{
|
||||
Id = phone.Id,
|
||||
Number = phone.Number,
|
||||
Alias = phone.Alias,
|
||||
Settings = phone.Settings.ToString(),
|
||||
TenantId = TenantID
|
||||
};
|
||||
|
||||
VoipDbContext.VoipNumbers.Add(voipNumber);
|
||||
VoipDbContext.SaveChanges();
|
||||
|
||||
return phone;
|
||||
}
|
||||
|
||||
public virtual void DeleteNumber(string phoneId = "")
|
||||
{
|
||||
var number = VoipDbContext.VoipNumbers.Where(r => r.Id == phoneId && r.TenantId == TenantID).FirstOrDefault();
|
||||
VoipDbContext.VoipNumbers.Remove(number);
|
||||
VoipDbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public virtual IEnumerable<VoipPhone> GetAllNumbers()
|
||||
{
|
||||
return VoipDbContext.VoipNumbers
|
||||
.Where(r => r.TenantId == TenantID)
|
||||
.ToList()
|
||||
.ConvertAll(ToPhone);
|
||||
}
|
||||
|
||||
public virtual IEnumerable<VoipPhone> GetNumbers(params string[] ids)
|
||||
{
|
||||
var numbers = VoipDbContext.VoipNumbers.Where(r => r.TenantId == TenantID);
|
||||
|
||||
if (ids.Length > 0)
|
||||
{
|
||||
numbers = numbers.Where(r => ids.Any(a => a == r.Number || a == r.Id));
|
||||
}
|
||||
|
||||
return numbers.ToList().ConvertAll(ToPhone);
|
||||
}
|
||||
|
||||
public VoipPhone GetNumber(string id)
|
||||
{
|
||||
return GetNumbers(id.TrimStart('+')).FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual VoipPhone GetCurrentNumber()
|
||||
{
|
||||
return GetNumbers().FirstOrDefault(r => r.Caller != null);
|
||||
}
|
||||
|
||||
|
||||
public VoipCall SaveOrUpdateCall(VoipCall call)
|
||||
{
|
||||
var voipCall = new DbVoipCall
|
||||
{
|
||||
TenantId = TenantID,
|
||||
Id = call.Id,
|
||||
NumberFrom = call.NumberFrom,
|
||||
NumberTo = call.NumberTo,
|
||||
ContactId = call.ContactId
|
||||
};
|
||||
|
||||
if (!string.IsNullOrEmpty(call.ParentCallId))
|
||||
{
|
||||
voipCall.ParentCallId = call.ParentCallId;
|
||||
}
|
||||
|
||||
if (call.Status.HasValue)
|
||||
{
|
||||
voipCall.Status = (int)call.Status.Value;
|
||||
}
|
||||
|
||||
if (!call.AnsweredBy.Equals(Guid.Empty))
|
||||
{
|
||||
voipCall.AnsweredBy = call.AnsweredBy;
|
||||
}
|
||||
|
||||
if (call.DialDate == DateTime.MinValue)
|
||||
{
|
||||
call.DialDate = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
voipCall.DialDate = _tenantUtil.DateTimeToUtc(call.DialDate);
|
||||
|
||||
if (call.DialDuration > 0)
|
||||
{
|
||||
voipCall.DialDuration = call.DialDuration;
|
||||
}
|
||||
|
||||
if (call.Price > decimal.Zero)
|
||||
{
|
||||
voipCall.Price = call.Price;
|
||||
}
|
||||
|
||||
if (call.VoipRecord != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(call.VoipRecord.Sid))
|
||||
{
|
||||
voipCall.Sid = call.VoipRecord.Sid;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(call.VoipRecord.Uri))
|
||||
{
|
||||
voipCall.Uri = call.VoipRecord.Uri;
|
||||
}
|
||||
|
||||
if (call.VoipRecord.Duration != 0)
|
||||
{
|
||||
voipCall.Duration = call.VoipRecord.Duration;
|
||||
}
|
||||
|
||||
if (call.VoipRecord.Price != default)
|
||||
{
|
||||
voipCall.RecordPrice = call.VoipRecord.Price;
|
||||
}
|
||||
}
|
||||
|
||||
VoipDbContext.VoipCalls.Add(voipCall);
|
||||
VoipDbContext.SaveChanges();
|
||||
|
||||
return call;
|
||||
}
|
||||
|
||||
public IEnumerable<VoipCall> GetCalls(VoipCallFilter filter)
|
||||
{
|
||||
var query = GetCallsQuery(filter);
|
||||
|
||||
if (filter.SortByColumn != null)
|
||||
{
|
||||
query.OrderBy(filter.SortByColumn, filter.SortOrder);
|
||||
}
|
||||
|
||||
query = query.Skip((int)filter.Offset);
|
||||
query = query.Take((int)filter.Max * 3);
|
||||
|
||||
var calls = _mapper.Map<List<CallContact>, IEnumerable<VoipCall>>(query.ToList());
|
||||
|
||||
calls = calls.GroupJoin(calls, call => call.Id, h => h.ParentCallId, (call, h) =>
|
||||
{
|
||||
call.ChildCalls.AddRange(h);
|
||||
return call;
|
||||
}).Where(r => string.IsNullOrEmpty(r.ParentCallId)).ToList();
|
||||
|
||||
return calls;
|
||||
}
|
||||
|
||||
public VoipCall GetCall(string id)
|
||||
{
|
||||
return GetCalls(new VoipCallFilter { Id = id }).FirstOrDefault();
|
||||
}
|
||||
|
||||
public int GetCallsCount(VoipCallFilter filter)
|
||||
{
|
||||
return GetCallsQuery(filter).Where(r => r.DbVoipCall.ParentCallId == "").Count();
|
||||
}
|
||||
|
||||
public IEnumerable<VoipCall> GetMissedCalls(Guid agent, long count = 0, DateTime? from = null)
|
||||
{
|
||||
var query = GetCallsQuery(new VoipCallFilter { Agent = agent, SortBy = "date", SortOrder = true, Type = "missed" });
|
||||
|
||||
if (from.HasValue)
|
||||
{
|
||||
query = query.Where(r => r.DbVoipCall.DialDate >= _tenantUtil.DateTimeFromUtc(from.Value));
|
||||
}
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
query = query.Take((int)count);
|
||||
}
|
||||
|
||||
query = query.Select(ca => new
|
||||
{
|
||||
dbVoipCall = ca,
|
||||
tmpDate = VoipDbContext.VoipCalls
|
||||
.Where(tmp => tmp.TenantId == ca.DbVoipCall.TenantId)
|
||||
.Where(tmp => tmp.NumberFrom == ca.DbVoipCall.NumberFrom || tmp.NumberTo == ca.DbVoipCall.NumberFrom)
|
||||
.Where(tmp => tmp.Status <= (int)VoipCallStatus.Missed)
|
||||
.Max(tmp => tmp.DialDate)
|
||||
}).Where(r => r.dbVoipCall.DbVoipCall.DialDate >= r.tmpDate || r.tmpDate == default)
|
||||
.Select(q => q.dbVoipCall);
|
||||
|
||||
return _mapper.Map<List<CallContact>, IEnumerable<VoipCall>>(query.ToList());
|
||||
}
|
||||
|
||||
private IQueryable<CallContact> GetCallsQuery(VoipCallFilter filter)
|
||||
{
|
||||
var q = VoipDbContext.VoipCalls
|
||||
.Where(r => r.TenantId == TenantID);
|
||||
|
||||
if (!string.IsNullOrEmpty(filter.Id))
|
||||
{
|
||||
q = q.Where(r => r.Id == filter.Id || r.ParentCallId == filter.Id);
|
||||
}
|
||||
|
||||
if (filter.ContactID.HasValue)
|
||||
{
|
||||
q = q.Where(r => r.ContactId == filter.ContactID.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(filter.SearchText))
|
||||
{
|
||||
q = q.Where(r => r.Id.StartsWith(filter.SearchText));
|
||||
}
|
||||
|
||||
if (filter.TypeStatus.HasValue)
|
||||
{
|
||||
q = q.Where(r => r.Status == filter.TypeStatus.Value);
|
||||
}
|
||||
|
||||
if (filter.FromDate.HasValue)
|
||||
{
|
||||
q = q.Where(r => r.DialDate >= filter.FromDate.Value);
|
||||
}
|
||||
|
||||
if (filter.ToDate.HasValue)
|
||||
{
|
||||
q = q.Where(r => r.DialDate <= filter.ToDate.Value);
|
||||
}
|
||||
|
||||
if (filter.Agent.HasValue)
|
||||
{
|
||||
q = q.Where(r => r.AnsweredBy == filter.Agent.Value);
|
||||
}
|
||||
|
||||
return from voipCalls in q
|
||||
join crmContact in VoipDbContext.CrmContact on voipCalls.ContactId equals crmContact.Id into grouping
|
||||
from g in grouping.DefaultIfEmpty()
|
||||
select new CallContact { DbVoipCall = voipCalls, CrmContact = g };
|
||||
}
|
||||
|
||||
private VoipPhone ToPhone(VoipNumber r)
|
||||
{
|
||||
return GetProvider().GetPhone(r);
|
||||
}
|
||||
|
||||
public Consumer Consumer
|
||||
{
|
||||
get { return _consumerFactory.GetByKey("twilio"); }
|
||||
}
|
||||
|
||||
public TwilioProvider GetProvider()
|
||||
{
|
||||
return new TwilioProvider(Consumer["twilioAccountSid"], Consumer["twilioAuthToken"], _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility);
|
||||
}
|
||||
|
||||
public bool ConfigSettingsExist
|
||||
{
|
||||
get
|
||||
{
|
||||
return !string.IsNullOrEmpty(Consumer["twilioAccountSid"]) &&
|
||||
!string.IsNullOrEmpty(Consumer["twilioAuthToken"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CallContact
|
||||
{
|
||||
public DbVoipCall DbVoipCall { get; set; }
|
||||
public CrmContact CrmContact { get; set; }
|
||||
}
|
@ -1,58 +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
|
||||
|
||||
global using System.Reflection;
|
||||
global using System.Text;
|
||||
global using System.Web;
|
||||
|
||||
global using ASC.Common;
|
||||
global using ASC.Common.Mapping;
|
||||
global using ASC.Core;
|
||||
global using ASC.Core.Common;
|
||||
global using ASC.Core.Common.Configuration;
|
||||
global using ASC.Core.Common.EF;
|
||||
global using ASC.Core.Common.EF.Context;
|
||||
global using ASC.Core.Common.EF.Model;
|
||||
global using ASC.Core.Tenants;
|
||||
global using ASC.VoipService.Dao;
|
||||
global using ASC.VoipService.Mappings;
|
||||
global using ASC.VoipService.Twilio;
|
||||
|
||||
global using AutoMapper;
|
||||
|
||||
global using Newtonsoft.Json;
|
||||
global using Newtonsoft.Json.Linq;
|
||||
global using Newtonsoft.Json.Serialization;
|
||||
|
||||
global using Twilio.Clients;
|
||||
global using Twilio.Exceptions;
|
||||
global using Twilio.Jwt;
|
||||
global using Twilio.Jwt.Client;
|
||||
global using Twilio.Rest.Api.V2010.Account;
|
||||
global using Twilio.Rest.Api.V2010.Account.AvailablePhoneNumberCountry;
|
||||
global using Twilio.Rest.Api.V2010.Account.Queue;
|
||||
global using Twilio.TwiML;
|
||||
global using Twilio.Types;
|
@ -1,54 +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.VoipService;
|
||||
|
||||
public interface IVoipProvider
|
||||
{
|
||||
IEnumerable<VoipPhone> GetExistingPhoneNumbers();
|
||||
|
||||
IEnumerable<VoipPhone> GetAvailablePhoneNumbers(PhoneNumberType phoneNumberType, string isoCountryCode);
|
||||
|
||||
VoipPhone BuyNumber(string phoneNumber);
|
||||
|
||||
VoipPhone DeleteNumber(VoipPhone phone);
|
||||
|
||||
VoipPhone GetPhone(VoipNumber r);
|
||||
|
||||
VoipPhone GetPhone(string id);
|
||||
|
||||
VoipCall GetCall(string callId);
|
||||
|
||||
string GetToken(Agent agent, int seconds = 60 * 60 * 24);
|
||||
|
||||
void UpdateSettings(VoipPhone phone);
|
||||
|
||||
VoipRecord GetRecord(string callId, string recordId);
|
||||
|
||||
void CreateQueue(VoipPhone newPhone);
|
||||
|
||||
void DisablePhone(VoipPhone phone);
|
||||
}
|
@ -1,60 +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.VoipService.Mappings;
|
||||
|
||||
[Scope]
|
||||
public class CallTypeConverter : ITypeConverter<CallContact, VoipCall>
|
||||
{
|
||||
public VoipCall Convert(CallContact source, VoipCall destination, ResolutionContext context)
|
||||
{
|
||||
var result = context.Mapper.Map<DbVoipCall, VoipCall>(source.DbVoipCall);
|
||||
result.VoipRecord = context.Mapper.Map<DbVoipCall, VoipRecord>(source.DbVoipCall);
|
||||
|
||||
if (source.CrmContact != null)
|
||||
{
|
||||
result.ContactId = source.CrmContact.Id;
|
||||
result.ContactIsCompany = source.CrmContact.IsCompany;
|
||||
result.ContactTitle = result.ContactIsCompany
|
||||
? source.CrmContact.CompanyName
|
||||
: source.CrmContact.FirstName == null || source.CrmContact.LastName == null ? null : $"{source.CrmContact.FirstName} {source.CrmContact.LastName}";
|
||||
}
|
||||
else
|
||||
{
|
||||
result.ContactId = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public class EventTypeConverterExtension
|
||||
{
|
||||
public static void Register(DIHelper services)
|
||||
{
|
||||
services.TryAdd<CallTypeConverter>();
|
||||
}
|
||||
}
|
@ -1,126 +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
|
||||
|
||||
using HttpMethod = Twilio.Http.HttpMethod;
|
||||
|
||||
namespace ASC.VoipService.Twilio;
|
||||
|
||||
public class TwilioPhone : VoipPhone
|
||||
{
|
||||
private readonly TwilioRestClient _twilio;
|
||||
public TwilioPhone(
|
||||
TwilioRestClient twilio,
|
||||
AuthContext authContext,
|
||||
TenantUtil tenantUtil,
|
||||
SecurityContext securityContext,
|
||||
BaseCommonLinkUtility baseCommonLinkUtility) :
|
||||
base(authContext, tenantUtil, securityContext, baseCommonLinkUtility)
|
||||
{
|
||||
_twilio = twilio;
|
||||
Settings = new TwilioVoipSettings(authContext, tenantUtil, securityContext, baseCommonLinkUtility);
|
||||
}
|
||||
|
||||
#region Calls
|
||||
|
||||
public override VoipCall Call(string to, string contactId = null)
|
||||
{
|
||||
var number = to.Split('#');
|
||||
|
||||
var call = CallResource.Create(new CreateCallOptions(new PhoneNumber("+" + number[0].TrimStart('+')), new PhoneNumber("+" + Number.TrimStart('+')))
|
||||
{
|
||||
SendDigits = number.Length > 1 ? number[1] + "#" : string.Empty,
|
||||
Record = Settings.Caller.Record,
|
||||
Url = new Uri(Settings.Connect(contactId: contactId))
|
||||
}, _twilio);
|
||||
|
||||
return new VoipCall { Id = call.Sid, NumberFrom = call.From, NumberTo = call.To };
|
||||
}
|
||||
|
||||
public override VoipCall LocalCall(string to)
|
||||
{
|
||||
return Call(Number + "#" + to);
|
||||
}
|
||||
|
||||
public override VoipCall RedirectCall(string callId, string to)
|
||||
{
|
||||
var call = CallResource.Update(callId, url: new Uri(Settings.Redirect(to)), method: HttpMethod.Post, client: _twilio);
|
||||
return new VoipCall { Id = call.Sid, NumberTo = to };
|
||||
}
|
||||
|
||||
public override VoipCall HoldUp(string callId)
|
||||
{
|
||||
return RedirectCall(callId, "hold");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Queue
|
||||
|
||||
public Queue CreateQueue(string name, int size, string waitUrl, int waitTime)
|
||||
{
|
||||
var queues = QueueResource.Read(new ReadQueueOptions(), _twilio);
|
||||
var queue = queues.FirstOrDefault(r => r.FriendlyName == name);
|
||||
if (queue == null)
|
||||
{
|
||||
queue = QueueResource.Create(name, client: _twilio);
|
||||
}
|
||||
return new Queue(queue.Sid, name, size, waitUrl, waitTime);
|
||||
}
|
||||
|
||||
public string GetQueue(string name)
|
||||
{
|
||||
var queues = QueueResource.Read(new ReadQueueOptions(), _twilio);
|
||||
return queues.First(r => r.FriendlyName == name).Sid;
|
||||
}
|
||||
|
||||
public IEnumerable<string> QueueCalls(string id)
|
||||
{
|
||||
var calls = MemberResource.Read(id, client: _twilio);
|
||||
return calls.Select(r => r.CallSid);
|
||||
}
|
||||
|
||||
private void AnswerQueueCall(string queueId, string callId, bool reject = false)
|
||||
{
|
||||
var calls = QueueCalls(queueId);
|
||||
if (calls.Contains(callId))
|
||||
{
|
||||
MemberResource.Update(queueId, callId, new Uri(Settings.Dequeue(reject)), HttpMethod.Post,
|
||||
client: _twilio);
|
||||
}
|
||||
}
|
||||
|
||||
public override void AnswerQueueCall(string callId)
|
||||
{
|
||||
AnswerQueueCall(Settings.Queue.Id, callId);
|
||||
}
|
||||
|
||||
public override void RejectQueueCall(string callId)
|
||||
{
|
||||
AnswerQueueCall(Settings.Queue.Id, callId, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
@ -1,232 +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
|
||||
|
||||
using RecordingResource = Twilio.Rest.Api.V2010.Account.Call.RecordingResource;
|
||||
|
||||
|
||||
namespace ASC.VoipService.Twilio;
|
||||
|
||||
public class TwilioProvider : IVoipProvider
|
||||
{
|
||||
private readonly string _accountSid;
|
||||
private readonly string _authToken;
|
||||
private readonly TwilioRestClient _client;
|
||||
private readonly AuthContext _authContext;
|
||||
private readonly TenantUtil _tenantUtil;
|
||||
private readonly SecurityContext _securityContext;
|
||||
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
|
||||
|
||||
public TwilioProvider(string accountSid, string authToken, AuthContext authContext, TenantUtil tenantUtil, SecurityContext securityContext, BaseCommonLinkUtility baseCommonLinkUtility)
|
||||
{
|
||||
ArgumentNullOrEmptyException.ThrowIfNullOrEmpty(accountSid);
|
||||
ArgumentNullOrEmptyException.ThrowIfNullOrEmpty(authToken);
|
||||
|
||||
_authToken = authToken;
|
||||
_authContext = authContext;
|
||||
_tenantUtil = tenantUtil;
|
||||
_securityContext = securityContext;
|
||||
_baseCommonLinkUtility = baseCommonLinkUtility;
|
||||
_accountSid = accountSid;
|
||||
|
||||
_client = new TwilioRestClient(accountSid, authToken);
|
||||
}
|
||||
|
||||
#region Call
|
||||
|
||||
public VoipRecord GetRecord(string callId, string recordSid)
|
||||
{
|
||||
var result = new VoipRecord { Sid = recordSid };
|
||||
var count = 6;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var record = RecordingResource.Fetch(callId, recordSid, client: _client);
|
||||
|
||||
if (!record.Price.HasValue)
|
||||
{
|
||||
count--;
|
||||
Thread.Sleep(10000);
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Price = (-1) * record.Price.Value;
|
||||
|
||||
result.Duration = Convert.ToInt32(record.Duration);
|
||||
if (record.Uri != null)
|
||||
{
|
||||
result.Uri = record.Uri;
|
||||
}
|
||||
break;
|
||||
}
|
||||
catch (ApiException)
|
||||
{
|
||||
count--;
|
||||
Thread.Sleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void CreateQueue(VoipPhone newPhone)
|
||||
{
|
||||
newPhone.Settings.Queue = ((TwilioPhone)newPhone).CreateQueue(newPhone.Number, 5, string.Empty, 5);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Numbers
|
||||
|
||||
public VoipPhone BuyNumber(string phoneNumber)
|
||||
{
|
||||
var newNumber = IncomingPhoneNumberResource.Create(
|
||||
new CreateIncomingPhoneNumberOptions
|
||||
{
|
||||
PathAccountSid = _accountSid,
|
||||
PhoneNumber = new PhoneNumber(phoneNumber)
|
||||
}, _client);
|
||||
|
||||
return new TwilioPhone(_client, _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility) { Id = newNumber.Sid, Number = phoneNumber.Substring(1) };
|
||||
}
|
||||
|
||||
public VoipPhone DeleteNumber(VoipPhone phone)
|
||||
{
|
||||
IncomingPhoneNumberResource.Delete(phone.Id, client: _client);
|
||||
return phone;
|
||||
}
|
||||
|
||||
public IEnumerable<VoipPhone> GetExistingPhoneNumbers()
|
||||
{
|
||||
var result = IncomingPhoneNumberResource.Read(client: _client);
|
||||
return result.Select(r => new TwilioPhone(_client, _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility) { Id = r.Sid, Number = r.PhoneNumber.ToString() });
|
||||
}
|
||||
|
||||
public IEnumerable<VoipPhone> GetAvailablePhoneNumbers(PhoneNumberType phoneNumberType, string isoCountryCode)
|
||||
{
|
||||
return phoneNumberType switch
|
||||
{
|
||||
PhoneNumberType.Local => LocalResource.Read(isoCountryCode, voiceEnabled: true, client: _client).Select(r => new TwilioPhone(_client, _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility) { Number = r.PhoneNumber.ToString() }),
|
||||
PhoneNumberType.TollFree => TollFreeResource.Read(isoCountryCode, voiceEnabled: true, client: _client).Select(r => new TwilioPhone(_client, _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility) { Number = r.PhoneNumber.ToString() }),
|
||||
|
||||
_ => new List<VoipPhone>(),
|
||||
};
|
||||
}
|
||||
|
||||
public VoipPhone GetPhone(string phoneSid)
|
||||
{
|
||||
var phone = IncomingPhoneNumberResource.Fetch(phoneSid, client: _client);
|
||||
|
||||
var result = new TwilioPhone(_client, _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility)
|
||||
{
|
||||
Id = phone.Sid,
|
||||
Number = phone.PhoneNumber.ToString(),
|
||||
Settings = new TwilioVoipSettings(_authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility)
|
||||
};
|
||||
|
||||
if (phone.VoiceUrl == null)
|
||||
{
|
||||
result.Settings.VoiceUrl = result.Settings.Connect(false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public VoipPhone GetPhone(VoipNumber data)
|
||||
{
|
||||
return new TwilioPhone(_client, _authContext, _tenantUtil, _securityContext, _baseCommonLinkUtility)
|
||||
{
|
||||
Id = data.Id,
|
||||
Number = data.Number,
|
||||
Alias = data.Alias,
|
||||
Settings = new TwilioVoipSettings(data.Settings, _authContext)
|
||||
};
|
||||
}
|
||||
|
||||
public VoipCall GetCall(string callId)
|
||||
{
|
||||
var result = new VoipCall { Id = callId };
|
||||
var count = 6;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var call = CallResource.Fetch(result.Id, client: _client);
|
||||
if (!call.Price.HasValue || string.IsNullOrEmpty(call.Duration))
|
||||
{
|
||||
count--;
|
||||
Thread.Sleep(10000);
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Price = (-1) * call.Price.Value;
|
||||
result.DialDuration = Convert.ToInt32(call.Duration);
|
||||
break;
|
||||
}
|
||||
catch (ApiException)
|
||||
{
|
||||
count--;
|
||||
Thread.Sleep(10000);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetToken(Agent agent, int seconds = 60 * 60 * 24)
|
||||
{
|
||||
var scopes = new HashSet<IScope>
|
||||
{
|
||||
new IncomingClientScope(agent.ClientID)
|
||||
};
|
||||
var capability = new ClientCapability(_accountSid, _authToken, scopes: scopes);
|
||||
|
||||
return capability.ToJwt();
|
||||
}
|
||||
|
||||
public void UpdateSettings(VoipPhone phone)
|
||||
{
|
||||
IncomingPhoneNumberResource.Update(phone.Id, voiceUrl: new Uri(phone.Settings.Connect(false)), client: _client);
|
||||
}
|
||||
|
||||
public void DisablePhone(VoipPhone phone)
|
||||
{
|
||||
IncomingPhoneNumberResource.Update(phone.Id, voiceUrl: new Uri("https://demo.twilio.com/welcome/voice/"), client: _client);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
|
||||
public enum PhoneNumberType
|
||||
{
|
||||
Local,
|
||||
/* Mobile,*/
|
||||
TollFree
|
||||
}
|
@ -1,216 +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.VoipService.Twilio;
|
||||
|
||||
public class TwilioResponseHelper
|
||||
{
|
||||
private readonly VoipSettings _settings;
|
||||
private readonly string _baseUrl;
|
||||
private readonly AuthContext _authContext;
|
||||
private readonly TenantUtil _tenantUtil;
|
||||
private readonly SecurityContext _securityContext;
|
||||
|
||||
public TwilioResponseHelper(
|
||||
VoipSettings settings,
|
||||
string baseUrl,
|
||||
AuthContext authContext,
|
||||
TenantUtil tenantUtil,
|
||||
SecurityContext securityContext)
|
||||
{
|
||||
_settings = settings;
|
||||
_authContext = authContext;
|
||||
_tenantUtil = tenantUtil;
|
||||
_securityContext = securityContext;
|
||||
_baseUrl = baseUrl.TrimEnd('/') + "/twilio/";
|
||||
}
|
||||
|
||||
public VoiceResponse Inbound(Tuple<Agent, bool> agentTuple)
|
||||
{
|
||||
var agent = agentTuple?.Item1;
|
||||
var anyOnline = agentTuple != null && agentTuple.Item2;
|
||||
var response = new VoiceResponse();
|
||||
|
||||
if (_settings.WorkingHours != null && _settings.WorkingHours.Enabled)
|
||||
{
|
||||
var now = _tenantUtil.DateTimeFromUtc(DateTime.UtcNow);
|
||||
if (!(_settings.WorkingHours.From <= now.TimeOfDay && _settings.WorkingHours.To >= now.TimeOfDay))
|
||||
{
|
||||
return AddVoiceMail(response);
|
||||
}
|
||||
}
|
||||
|
||||
if (anyOnline)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_settings.GreetingAudio))
|
||||
{
|
||||
response.Play(Uri.EscapeDataString(_settings.GreetingAudio));
|
||||
}
|
||||
|
||||
response.Enqueue(_settings.Queue.Name, GetEcho("Enqueue", agent != null), "POST",
|
||||
GetEcho("Wait", agent != null), "POST");
|
||||
}
|
||||
|
||||
return AddVoiceMail(response);
|
||||
}
|
||||
|
||||
public VoiceResponse Outbound()
|
||||
{
|
||||
return !_settings.Caller.AllowOutgoingCalls
|
||||
? new VoiceResponse()
|
||||
: AddToResponse(new VoiceResponse(), _settings.Caller);
|
||||
}
|
||||
|
||||
public VoiceResponse Dial()
|
||||
{
|
||||
return new VoiceResponse();
|
||||
}
|
||||
|
||||
public VoiceResponse Queue()
|
||||
{
|
||||
return new VoiceResponse();
|
||||
}
|
||||
|
||||
public VoiceResponse Enqueue(string queueResult)
|
||||
{
|
||||
return queueResult == "leave" ? AddVoiceMail(new VoiceResponse()) : new VoiceResponse();
|
||||
}
|
||||
|
||||
public VoiceResponse Dequeue()
|
||||
{
|
||||
return AddToResponse(new VoiceResponse(), _settings.Caller);
|
||||
}
|
||||
|
||||
public VoiceResponse Leave()
|
||||
{
|
||||
return AddVoiceMail(new VoiceResponse());
|
||||
}
|
||||
|
||||
public VoiceResponse Wait(string queueTime, string queueSize)
|
||||
{
|
||||
var response = new VoiceResponse();
|
||||
var queue = _settings.Queue;
|
||||
|
||||
if (Convert.ToInt32(queueTime) > queue.WaitTime || Convert.ToInt32(queueSize) > queue.Size)
|
||||
{
|
||||
return response.Leave();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(queue.WaitUrl))
|
||||
{
|
||||
var gather = new Gather(method: "POST", action: GetEcho("gatherQueue"));
|
||||
gather.Play(Uri.EscapeDataString(queue.WaitUrl));
|
||||
response.Gather(gather);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.Pause(queue.WaitTime);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public VoiceResponse GatherQueue(string digits, List<Agent> availableOperators)
|
||||
{
|
||||
var response = new VoiceResponse();
|
||||
|
||||
if (digits == "#")
|
||||
{
|
||||
return AddVoiceMail(response);
|
||||
}
|
||||
|
||||
var oper = _settings.Operators.Find(r => r.PostFix == digits && availableOperators.Contains(r)) ??
|
||||
_settings.Operators.FirstOrDefault(r => availableOperators.Contains(r));
|
||||
|
||||
return oper != null ? AddToResponse(response, oper) : response;
|
||||
}
|
||||
|
||||
public VoiceResponse Redirect(string to)
|
||||
{
|
||||
if (to == "hold")
|
||||
{
|
||||
return new VoiceResponse().Play(Uri.EscapeDataString(_settings.HoldAudio), 0);
|
||||
}
|
||||
|
||||
|
||||
if (Guid.TryParse(to, out var newCallerId))
|
||||
{
|
||||
_securityContext.AuthenticateMeWithoutCookie(newCallerId);
|
||||
}
|
||||
|
||||
return new VoiceResponse().Enqueue(_settings.Queue.Name, GetEcho("enqueue"), "POST",
|
||||
GetEcho("wait") + "&RedirectTo=" + to, "POST");
|
||||
}
|
||||
|
||||
public VoiceResponse VoiceMail()
|
||||
{
|
||||
return new VoiceResponse();
|
||||
}
|
||||
|
||||
private VoiceResponse AddToResponse(VoiceResponse response, Agent agent)
|
||||
{
|
||||
var dial = new Dial(method: "POST", action: GetEcho("dial"), timeout: agent.TimeOut, record: agent.Record ? "record-from-answer" : "do-not-record");
|
||||
|
||||
switch (agent.Answer)
|
||||
{
|
||||
case AnswerType.Number:
|
||||
response.Dial(dial.Number(agent.PhoneNumber, method: "POST", url: GetEcho("client")));
|
||||
break;
|
||||
case AnswerType.Client:
|
||||
response.Dial(dial.Client(agent.ClientID, "POST", GetEcho("client")));
|
||||
break;
|
||||
case AnswerType.Sip:
|
||||
response.Dial(dial.Sip(agent.ClientID, method: "POST", url: GetEcho("client")));
|
||||
break;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
private VoiceResponse AddVoiceMail(VoiceResponse response)
|
||||
{
|
||||
return string.IsNullOrEmpty(_settings.VoiceMail)
|
||||
? response.Say("")
|
||||
: response.Play(Uri.EscapeDataString(_settings.VoiceMail)).Record(method: "POST", action: GetEcho("voiceMail"), maxLength: 30);
|
||||
}
|
||||
|
||||
public string GetEcho(string action, bool user = true)
|
||||
{
|
||||
var result = _baseUrl.TrimEnd('/');
|
||||
|
||||
if (!string.IsNullOrEmpty(action))
|
||||
{
|
||||
result += "/" + action.TrimStart('/');
|
||||
}
|
||||
if (user)
|
||||
{
|
||||
result += "?CallerId=" + _authContext.CurrentAccount.ID;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,85 +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
|
||||
|
||||
using Uri = System.Uri;
|
||||
|
||||
namespace ASC.VoipService.Twilio;
|
||||
|
||||
public class TwilioVoipSettings : VoipSettings
|
||||
{
|
||||
public TwilioVoipSettings(
|
||||
AuthContext authContext,
|
||||
TenantUtil tenantUtil,
|
||||
SecurityContext securityContext,
|
||||
BaseCommonLinkUtility baseCommonLinkUtility) :
|
||||
base(authContext, tenantUtil, securityContext, baseCommonLinkUtility)
|
||||
{ }
|
||||
|
||||
public TwilioVoipSettings(
|
||||
Uri voiceUrl,
|
||||
AuthContext authContext,
|
||||
TenantUtil tenantUtil,
|
||||
SecurityContext securityContext,
|
||||
BaseCommonLinkUtility baseCommonLinkUtility) :
|
||||
this(authContext, tenantUtil, securityContext, baseCommonLinkUtility)
|
||||
{
|
||||
if (string.IsNullOrEmpty(voiceUrl.Query))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JsonSettings = Encoding.UTF8.GetString(Convert.FromBase64String(HttpUtility.UrlDecode(HttpUtility.ParseQueryString(voiceUrl.Query)["settings"])));
|
||||
}
|
||||
|
||||
public TwilioVoipSettings(string settings, AuthContext authContext) : base(settings, authContext)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Connect(bool user = true, string contactId = null)
|
||||
{
|
||||
var result = GetEcho("", user);
|
||||
if (!string.IsNullOrEmpty(contactId))
|
||||
{
|
||||
result += "&ContactId=" + contactId;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string Redirect(string to)
|
||||
{
|
||||
return GetEcho("redirect") + "&RedirectTo=" + to;
|
||||
}
|
||||
|
||||
public override string Dequeue(bool reject)
|
||||
{
|
||||
return GetEcho("dequeue") + "&Reject=" + reject;
|
||||
}
|
||||
|
||||
private string GetEcho(string method, bool user = true)
|
||||
{
|
||||
return new TwilioResponseHelper(this, BaseCommonLinkUtility.GetFullAbsolutePath(""), AuthContext, TenantUtil, SecurityContext).GetEcho(method, user);
|
||||
}
|
||||
}
|
@ -1,69 +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.VoipService;
|
||||
|
||||
public class VoipCall : IMapFrom<CallContact>
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string ParentCallId { get; set; }
|
||||
public string NumberFrom { get; set; }
|
||||
public string NumberTo { get; set; }
|
||||
public Guid AnsweredBy { get; set; }
|
||||
public DateTime DialDate { get; set; }
|
||||
public int DialDuration { get; set; }
|
||||
public VoipCallStatus? Status { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public int ContactId { get; set; }
|
||||
public bool ContactIsCompany { get; set; }
|
||||
public string ContactTitle { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public DateTime EndDialDate { get; set; }
|
||||
public VoipRecord VoipRecord { get; set; }
|
||||
public List<VoipCall> ChildCalls { get; set; }
|
||||
|
||||
public VoipCall()
|
||||
{
|
||||
ChildCalls = new List<VoipCall>();
|
||||
VoipRecord = new VoipRecord();
|
||||
}
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<DbVoipCall, VoipCall>();
|
||||
|
||||
profile.CreateMap<CallContact, VoipCall>()
|
||||
.ConvertUsing<CallTypeConverter>();
|
||||
}
|
||||
}
|
||||
|
||||
public enum VoipCallStatus
|
||||
{
|
||||
Incoming,
|
||||
Outcoming,
|
||||
Answered,
|
||||
Missed
|
||||
}
|
@ -1,163 +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.VoipService;
|
||||
|
||||
public class Agent
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public AnswerType Answer { get; set; }
|
||||
public string ClientID { get { return PhoneNumber + PostFix; } }
|
||||
public bool Record { get; set; }
|
||||
public int TimeOut { get; set; }
|
||||
public AgentStatus Status { get; set; }
|
||||
public bool AllowOutgoingCalls { get; set; }
|
||||
public string PostFix { get; set; }
|
||||
public string PhoneNumber { get; set; }
|
||||
public string RedirectToNumber { get; set; }
|
||||
|
||||
public Agent()
|
||||
{
|
||||
Status = AgentStatus.Offline;
|
||||
TimeOut = 30;
|
||||
AllowOutgoingCalls = true;
|
||||
Record = true;
|
||||
}
|
||||
|
||||
public Agent(Guid id, AnswerType answer, VoipPhone phone, string postFix)
|
||||
: this()
|
||||
{
|
||||
Id = id;
|
||||
Answer = answer;
|
||||
PhoneNumber = phone.Number;
|
||||
AllowOutgoingCalls = phone.Settings.AllowOutgoingCalls;
|
||||
Record = phone.Settings.Record;
|
||||
PostFix = postFix;
|
||||
}
|
||||
}
|
||||
|
||||
public class Queue
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int Size { get; set; }
|
||||
public string WaitUrl { get; set; }
|
||||
public int WaitTime { get; set; }
|
||||
|
||||
public Queue() { }
|
||||
|
||||
public Queue(string id, string name, int size, string waitUrl, int waitTime)
|
||||
{
|
||||
Id = id;
|
||||
Name = name;
|
||||
WaitUrl = waitUrl;
|
||||
WaitTime = waitTime;
|
||||
Size = size;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class WorkingHours
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
public TimeSpan? From { get; set; }
|
||||
public TimeSpan? To { get; set; }
|
||||
|
||||
public WorkingHours() { }
|
||||
|
||||
public WorkingHours(TimeSpan from, TimeSpan to)
|
||||
{
|
||||
From = from;
|
||||
To = to;
|
||||
}
|
||||
|
||||
|
||||
private bool Equals(WorkingHours other)
|
||||
{
|
||||
return Enabled.Equals(other.Enabled) && From.Equals(other.From) && To.Equals(other.To);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((WorkingHours)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(Enabled, From, To);
|
||||
}
|
||||
}
|
||||
|
||||
public class VoipUpload
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string Path { get; set; }
|
||||
public AudioType AudioType { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
}
|
||||
|
||||
public enum AnswerType
|
||||
{
|
||||
Number,
|
||||
Sip,
|
||||
Client
|
||||
}
|
||||
|
||||
public enum GreetingMessageVoice
|
||||
{
|
||||
Man,
|
||||
Woman,
|
||||
Alice
|
||||
}
|
||||
|
||||
public enum AgentStatus
|
||||
{
|
||||
Online,
|
||||
Paused,
|
||||
Offline
|
||||
}
|
||||
|
||||
public enum AudioType
|
||||
{
|
||||
Greeting,
|
||||
HoldUp,
|
||||
VoiceMail,
|
||||
Queue
|
||||
}
|
@ -1,88 +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.VoipService;
|
||||
|
||||
public class VoipPhone
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Number { get; set; }
|
||||
public string Alias { get; set; }
|
||||
public VoipSettings Settings { get; set; }
|
||||
public Agent Caller
|
||||
{
|
||||
get { return Settings.Caller; }
|
||||
}
|
||||
|
||||
public VoipPhone(AuthContext authContext, TenantUtil tenantUtil, SecurityContext securityContext, BaseCommonLinkUtility baseCommonLinkUtility)
|
||||
{
|
||||
Settings = new VoipSettings(authContext, tenantUtil, securityContext, baseCommonLinkUtility);
|
||||
}
|
||||
|
||||
public virtual VoipCall Call(string to, string contactId = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual VoipCall LocalCall(string to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual VoipCall RedirectCall(string callId, string to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual VoipCall HoldUp(string callId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual void AnswerQueueCall(string callId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual void RejectQueueCall(string callId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public class VoipRecord : IMapFrom<DbVoipCall>
|
||||
{
|
||||
public string Sid { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public int Duration { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
|
||||
public void Mapping(Profile profile)
|
||||
{
|
||||
profile.CreateMap<DbVoipCall, VoipRecord>()
|
||||
.ForMember(dest => dest.Price, opt => opt.MapFrom(src => src.RecordPrice));
|
||||
}
|
||||
}
|
@ -1,175 +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.VoipService;
|
||||
|
||||
public class VoipSettings
|
||||
{
|
||||
public string VoiceUrl { get; set; }
|
||||
public string Name { get; set; }
|
||||
public List<Agent> Operators { get; set; }
|
||||
public Queue Queue { get; set; }
|
||||
public Agent Caller { get { return Operators.FirstOrDefault(r => r.Id == AuthContext.CurrentAccount.ID); } }
|
||||
public WorkingHours WorkingHours { get; set; }
|
||||
public string VoiceMail { get; set; }
|
||||
public string GreetingAudio { get; set; }
|
||||
public string HoldAudio { get; set; }
|
||||
public bool AllowOutgoingCalls { get; set; }
|
||||
public bool Pause { get; set; }
|
||||
public bool Record { get; set; }
|
||||
internal string JsonSettings
|
||||
{
|
||||
get
|
||||
{
|
||||
return JsonConvert.SerializeObject(
|
||||
new
|
||||
{
|
||||
Operators,
|
||||
GreetingAudio,
|
||||
Name,
|
||||
Queue,
|
||||
WorkingHours,
|
||||
VoiceMail,
|
||||
HoldAudio,
|
||||
AllowOutgoingCalls,
|
||||
Pause,
|
||||
Record
|
||||
},
|
||||
new JsonSerializerSettings { ContractResolver = CustomSerializeContractResolver.Instance });
|
||||
}
|
||||
set
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = JsonConvert.DeserializeObject<VoipSettings>(value, new JsonSerializerSettings { ContractResolver = CustomSerializeContractResolver.Instance });
|
||||
|
||||
Operators = settings.Operators ?? new List<Agent>();
|
||||
Name = settings.Name;
|
||||
Queue = settings.Queue;
|
||||
WorkingHours = settings.WorkingHours;
|
||||
GreetingAudio = settings.GreetingAudio;
|
||||
VoiceMail = settings.VoiceMail;
|
||||
HoldAudio = settings.HoldAudio;
|
||||
AllowOutgoingCalls = settings.AllowOutgoingCalls;
|
||||
Pause = settings.Pause;
|
||||
Record = settings.Record;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected AuthContext AuthContext { get; }
|
||||
protected TenantUtil TenantUtil { get; }
|
||||
protected SecurityContext SecurityContext { get; }
|
||||
protected BaseCommonLinkUtility BaseCommonLinkUtility { get; }
|
||||
|
||||
public VoipSettings(AuthContext authContext, TenantUtil tenantUtil, SecurityContext securityContext, BaseCommonLinkUtility baseCommonLinkUtility)
|
||||
{
|
||||
Operators = new List<Agent>();
|
||||
AuthContext = authContext;
|
||||
TenantUtil = tenantUtil;
|
||||
SecurityContext = securityContext;
|
||||
BaseCommonLinkUtility = baseCommonLinkUtility;
|
||||
}
|
||||
|
||||
public VoipSettings(string settings, AuthContext authContext)
|
||||
{
|
||||
JsonSettings = settings;
|
||||
AuthContext = authContext;
|
||||
}
|
||||
|
||||
public virtual string Connect(bool user = true, string contactId = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual string Redirect(string to)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual string Dequeue(bool reject)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return JsonSettings;
|
||||
}
|
||||
|
||||
public VoipSettings GetSettings(string settings)
|
||||
{
|
||||
return new VoipSettings(AuthContext, TenantUtil, SecurityContext, BaseCommonLinkUtility) { JsonSettings = settings };
|
||||
}
|
||||
}
|
||||
|
||||
class CustomSerializeContractResolver : CamelCasePropertyNamesContractResolver
|
||||
{
|
||||
public static readonly CustomSerializeContractResolver Instance = new CustomSerializeContractResolver();
|
||||
|
||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||
{
|
||||
var property = base.CreateProperty(member, memberSerialization);
|
||||
|
||||
if (property.PropertyName == "voiceMail")
|
||||
{
|
||||
property.Converter = new VoiceMailConverter();
|
||||
}
|
||||
|
||||
return property;
|
||||
}
|
||||
}
|
||||
|
||||
class VoiceMailConverter : JsonConverter
|
||||
{
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
serializer.Serialize(writer, value);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.ValueType != null && reader.ValueType.Name == "String")
|
||||
{
|
||||
return reader.Value;
|
||||
}
|
||||
|
||||
var jObject = JObject.Load(reader);
|
||||
var url = jObject.Value<string>("url");
|
||||
|
||||
return !string.IsNullOrEmpty(url) ? url : "";
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package ASC.VoipService.Dao;
|
||||
|
||||
message CachedVoipItem {
|
||||
int32 tenant = 1;
|
||||
}
|
@ -33,14 +33,15 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
public AuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options, ILoggerFactory logger, UrlEncoder encoder, ISystemClock clock) :
|
||||
base(options, logger, encoder, clock)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public AuthHandler(
|
||||
IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock,
|
||||
IConfiguration configuration,
|
||||
IOptionsMonitor<ILog> option,
|
||||
ILogger<AuthHandler> log,
|
||||
ApiSystemHelper apiSystemHelper,
|
||||
MachinePseudoKeys machinePseudoKeys,
|
||||
IHttpContextAccessor httpContextAccessor) :
|
||||
@ -48,14 +49,14 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
Configuration = configuration;
|
||||
|
||||
Log = option.Get("ASC.ApiSystem");
|
||||
Log = log;
|
||||
|
||||
ApiSystemHelper = apiSystemHelper;
|
||||
MachinePseudoKeys = machinePseudoKeys;
|
||||
HttpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
private ILog Log { get; }
|
||||
private ILogger<AuthHandler> Log { get; }
|
||||
|
||||
private IConfiguration Configuration { get; }
|
||||
|
||||
@ -67,7 +68,7 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
if (Convert.ToBoolean(Configuration[Scheme.Name] ?? "false"))
|
||||
{
|
||||
Log.DebugFormat("Auth for {0} skipped", Scheme.Name);
|
||||
Log.LogDebug("Auth for {0} skipped", Scheme.Name);
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, new AuthenticationProperties(), Scheme.Name)));
|
||||
}
|
||||
@ -80,7 +81,7 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
|
||||
if (string.IsNullOrEmpty(header))
|
||||
{
|
||||
Log.Debug("Auth header is NULL");
|
||||
Log.LogDebug("Auth header is NULL");
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.Unauthorized))));
|
||||
}
|
||||
@ -93,7 +94,7 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
|
||||
if (splitted.Length < 3)
|
||||
{
|
||||
Log.DebugFormat("Auth failed: invalid token {0}.", header);
|
||||
Log.LogDebug("Auth failed: invalid token {0}.", header);
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.Unauthorized))));
|
||||
}
|
||||
@ -102,7 +103,7 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
var date = splitted[1];
|
||||
var orighash = splitted[2];
|
||||
|
||||
Log.Debug("Variant of correct auth:" + ApiSystemHelper.CreateAuthToken(pkey));
|
||||
Log.LogDebug("Variant of correct auth:" + ApiSystemHelper.CreateAuthToken(pkey));
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(date))
|
||||
{
|
||||
@ -112,7 +113,7 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
|
||||
if (DateTime.UtcNow > timestamp.Add(trustInterval))
|
||||
{
|
||||
Log.DebugFormat("Auth failed: invalid timesatmp {0}, now {1}.", timestamp, DateTime.UtcNow);
|
||||
Log.LogDebug("Auth failed: invalid timesatmp {0}, now {1}.", timestamp, DateTime.UtcNow);
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.Forbidden))));
|
||||
}
|
||||
@ -125,27 +126,27 @@ public class AuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
|
||||
if (WebEncoders.Base64UrlEncode(hash) != orighash && Convert.ToBase64String(hash) != orighash)
|
||||
{
|
||||
Log.DebugFormat("Auth failed: invalid token {0}, expect {1} or {2}.", orighash, WebEncoders.Base64UrlEncode(hash), Convert.ToBase64String(hash));
|
||||
Log.LogDebug("Auth failed: invalid token {0}, expect {1} or {2}.", orighash, WebEncoders.Base64UrlEncode(hash), Convert.ToBase64String(hash));
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.Forbidden))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.DebugFormat("Auth failed: invalid auth header. Sheme: {0}, parameter: {1}.", Scheme.Name, header);
|
||||
Log.LogDebug("Auth failed: invalid auth header. Sheme: {0}, parameter: {1}.", Scheme.Name, header);
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.Forbidden))));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex);
|
||||
Log.LogError(ex, "auth error");
|
||||
|
||||
return Task.FromResult(AuthenticateResult.Fail(new AuthenticationException(nameof(HttpStatusCode.InternalServerError))));
|
||||
}
|
||||
var identity = new ClaimsIdentity(Scheme.Name);
|
||||
|
||||
Log.InfoFormat("Auth success {0}", Scheme.Name);
|
||||
Log.LogInformation("Auth success {0}", Scheme.Name);
|
||||
if (HttpContextAccessor?.HttpContext != null) HttpContextAccessor.HttpContext.User = new CustomClaimsPrincipal(new ClaimsIdentity(Scheme.Name), identity);
|
||||
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(Context.User, new AuthenticationProperties(), Scheme.Name)));
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public class CommonMethods
|
||||
|
||||
private IConfiguration Configuration { get; }
|
||||
|
||||
private ILog Log { get; }
|
||||
private ILogger<CommonMethods> Log { get; }
|
||||
|
||||
private CoreSettings CoreSettings { get; }
|
||||
|
||||
@ -86,7 +86,7 @@ public class CommonMethods
|
||||
public CommonMethods(
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IConfiguration configuration,
|
||||
IOptionsMonitor<ILog> option,
|
||||
ILogger<CommonMethods> log,
|
||||
CoreSettings coreSettings,
|
||||
CommonLinkUtility commonLinkUtility,
|
||||
EmailValidationKeyProvider emailValidationKeyProvider,
|
||||
@ -101,7 +101,7 @@ public class CommonMethods
|
||||
|
||||
Configuration = configuration;
|
||||
|
||||
Log = option.Get("ASC.ApiSystem");
|
||||
Log = log;
|
||||
|
||||
CoreSettings = coreSettings;
|
||||
|
||||
@ -166,7 +166,7 @@ public class CommonMethods
|
||||
|
||||
if (skipWelcome)
|
||||
{
|
||||
Log.DebugFormat("congratulations skiped");
|
||||
Log.LogDebug("congratulations skiped");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ public class CommonMethods
|
||||
|
||||
var result = reader.ReadToEnd();
|
||||
|
||||
Log.DebugFormat("congratulations result = {0}", result);
|
||||
Log.LogDebug("congratulations result = {0}", result);
|
||||
|
||||
var resObj = JObject.Parse(result);
|
||||
|
||||
@ -194,7 +194,7 @@ public class CommonMethods
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("SendCongratulations error", ex);
|
||||
Log.LogError(ex, "SendCongratulations error");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ public class CommonMethods
|
||||
{
|
||||
if (IsTestEmail(model.Email)) return false;
|
||||
|
||||
Log.DebugFormat("clientIP = {0}", clientIP);
|
||||
Log.LogDebug("clientIP = {0}", clientIP);
|
||||
|
||||
var cacheKey = "ip_" + clientIP;
|
||||
|
||||
@ -272,7 +272,7 @@ public class CommonMethods
|
||||
|
||||
if (ipAttemptsCount <= CommonConstants.MaxAttemptsCount) return false;
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; Too much reqests from ip: {1}", model.PortalName, clientIP);
|
||||
Log.LogDebug("PortalName = {0}; Too much reqests from ip: {1}", model.PortalName, clientIP);
|
||||
sw.Stop();
|
||||
|
||||
return true;
|
||||
@ -338,17 +338,17 @@ public class CommonMethods
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.DebugFormat("Recaptcha error: {0}", resp);
|
||||
Log.LogDebug("Recaptcha error: {0}", resp);
|
||||
}
|
||||
|
||||
if (resObj["error-codes"] != null && resObj["error-codes"].HasValues)
|
||||
{
|
||||
Log.DebugFormat("Recaptcha api returns errors: {0}", resp);
|
||||
Log.LogDebug("Recaptcha api returns errors: {0}", resp);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex);
|
||||
Log.LogError(ex, "ValidateRecaptcha");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,3 +1,29 @@
|
||||
// (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
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
@ -28,13 +54,13 @@ namespace ASC.ApiSystem.Classes;
|
||||
[Singletone]
|
||||
public class TimeZonesProvider
|
||||
{
|
||||
public ILog Log { get; }
|
||||
public ILogger<TimeZonesProvider> Log { get; }
|
||||
|
||||
private CommonConstants CommonConstants { get; }
|
||||
|
||||
public TimeZonesProvider(IOptionsMonitor<ILog> option, CommonConstants commonConstants)
|
||||
public TimeZonesProvider(ILogger<TimeZonesProvider> logger, CommonConstants commonConstants)
|
||||
{
|
||||
Log = option.Get("ASC.ApiSystem");
|
||||
Log = logger;
|
||||
|
||||
CommonConstants = commonConstants;
|
||||
}
|
||||
@ -112,7 +138,7 @@ public class TimeZonesProvider
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
Log.LogError(e, "GetCurrentTimeZoneInfo");
|
||||
|
||||
return TimeZoneInfo.Utc;
|
||||
}
|
||||
|
@ -1,3 +1,29 @@
|
||||
// (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
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
@ -35,7 +61,7 @@ public class CalDavController : ControllerBase
|
||||
private CoreSettings CoreSettings { get; }
|
||||
private CommonConstants CommonConstants { get; }
|
||||
public InstanceCrypto InstanceCrypto { get; }
|
||||
private ILog Log { get; }
|
||||
private ILogger<CalDavController> Log { get; }
|
||||
private IHttpClientFactory ClientFactory { get; }
|
||||
|
||||
public CalDavController(
|
||||
@ -44,14 +70,14 @@ public class CalDavController : ControllerBase
|
||||
CoreSettings coreSettings,
|
||||
CommonConstants commonConstants,
|
||||
InstanceCrypto instanceCrypto,
|
||||
IOptionsMonitor<ILog> option)
|
||||
ILogger<CalDavController> logger)
|
||||
{
|
||||
CommonMethods = commonMethods;
|
||||
EmailValidationKeyProvider = emailValidationKeyProvider;
|
||||
CoreSettings = coreSettings;
|
||||
CommonConstants = commonConstants;
|
||||
InstanceCrypto = instanceCrypto;
|
||||
Log = option.Get("ASC.ApiSystem");
|
||||
Log = logger;
|
||||
}
|
||||
|
||||
#region For TEST api
|
||||
@ -85,7 +111,7 @@ public class CalDavController : ControllerBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error change_to_storage", ex);
|
||||
Log.LogError(ex, "Error change_to_storage");
|
||||
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, new
|
||||
{
|
||||
@ -114,7 +140,7 @@ public class CalDavController : ControllerBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Error caldav_delete_event", ex);
|
||||
Log.LogError(ex, "Error caldav_delete_event");
|
||||
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, new
|
||||
{
|
||||
@ -132,7 +158,7 @@ public class CalDavController : ControllerBase
|
||||
{
|
||||
if (userPassword == null || string.IsNullOrEmpty(userPassword.User) || string.IsNullOrEmpty(userPassword.Password))
|
||||
{
|
||||
Log.Error("CalDav authenticated data is null");
|
||||
Log.LogError("CalDav authenticated data is null");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
@ -149,7 +175,7 @@ public class CalDavController : ControllerBase
|
||||
|
||||
try
|
||||
{
|
||||
Log.Info(string.Format("Caldav auth user: {0}, tenant: {1}", email, tenant.Id));
|
||||
Log.LogInformation(string.Format("Caldav auth user: {0}, tenant: {1}", email, tenant.Id));
|
||||
|
||||
if (InstanceCrypto.Encrypt(email) == userPassword.Password)
|
||||
{
|
||||
@ -172,7 +198,7 @@ public class CalDavController : ControllerBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error("Caldav authenticated", ex);
|
||||
Log.LogError(ex, "Caldav authenticated");
|
||||
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, new
|
||||
{
|
||||
@ -192,7 +218,7 @@ public class CalDavController : ControllerBase
|
||||
|
||||
if (string.IsNullOrEmpty(calendarParam))
|
||||
{
|
||||
Log.Error("calendarParam is empty");
|
||||
Log.LogError("calendarParam is empty");
|
||||
|
||||
error = new
|
||||
{
|
||||
@ -204,7 +230,7 @@ public class CalDavController : ControllerBase
|
||||
return false;
|
||||
}
|
||||
|
||||
Log.Info($"CalDav calendarParam: {calendarParam}");
|
||||
Log.LogInformation($"CalDav calendarParam: {calendarParam}");
|
||||
|
||||
var userParam = calendarParam.Split('/')[0];
|
||||
return GetUserData(userParam, out _, out tenant, out error);
|
||||
@ -218,7 +244,7 @@ public class CalDavController : ControllerBase
|
||||
|
||||
if (string.IsNullOrEmpty(userParam))
|
||||
{
|
||||
Log.Error("userParam is empty");
|
||||
Log.LogError("userParam is empty");
|
||||
|
||||
error = new
|
||||
{
|
||||
@ -234,7 +260,7 @@ public class CalDavController : ControllerBase
|
||||
|
||||
if (userData.Length < 3)
|
||||
{
|
||||
Log.Error($"Error Caldav username: {userParam}");
|
||||
Log.LogError($"Error Caldav username: {userParam}");
|
||||
|
||||
error = new
|
||||
{
|
||||
@ -257,13 +283,13 @@ public class CalDavController : ControllerBase
|
||||
tenantName = tenantName.Replace("." + baseUrl, "");
|
||||
}
|
||||
|
||||
Log.Info($"CalDav: user:{userParam} tenantName:{tenantName}");
|
||||
Log.LogInformation($"CalDav: user:{userParam} tenantName:{tenantName}");
|
||||
|
||||
var tenantModel = new TenantModel { PortalName = tenantName };
|
||||
|
||||
if (!CommonMethods.GetTenant(tenantModel, out tenant))
|
||||
{
|
||||
Log.Error("Model without tenant");
|
||||
Log.LogError("Model without tenant");
|
||||
|
||||
error = new
|
||||
{
|
||||
@ -277,7 +303,7 @@ public class CalDavController : ControllerBase
|
||||
|
||||
if (tenant == null)
|
||||
{
|
||||
Log.Error("Tenant not found " + tenantName);
|
||||
Log.LogError("Tenant not found " + tenantName);
|
||||
|
||||
error = new
|
||||
{
|
||||
@ -305,7 +331,7 @@ public class CalDavController : ControllerBase
|
||||
|
||||
var url = $"{requestUriScheme}{Uri.SchemeDelimiter}{tenant.GetTenantDomain(CoreSettings)}{CommonConstants.WebApiBaseUrl}{path}{(string.IsNullOrEmpty(query) ? "" : "?" + query)}";
|
||||
|
||||
Log.Info($"CalDav: SendToApi: {url}");
|
||||
Log.LogInformation($"CalDav: SendToApi: {url}");
|
||||
|
||||
var request = new HttpRequestMessage();
|
||||
request.RequestUri = new Uri(url);
|
||||
|
@ -48,7 +48,7 @@ namespace ASC.ApiSystem.Controllers;
|
||||
[Route("[controller]")]
|
||||
public class PeopleController : ControllerBase
|
||||
{
|
||||
private ILog Log { get; }
|
||||
private ILogger<PeopleController> Log { get; }
|
||||
private HostedSolution HostedSolution { get; }
|
||||
private UserFormatter UserFormatter { get; }
|
||||
private ICache Cache { get; }
|
||||
@ -57,7 +57,7 @@ public class PeopleController : ControllerBase
|
||||
public IHttpContextAccessor HttpContextAccessor { get; }
|
||||
|
||||
public PeopleController(
|
||||
IOptionsMonitor<ILog> option,
|
||||
ILogger<PeopleController> option,
|
||||
IOptionsSnapshot<HostedSolution> hostedSolutionOptions,
|
||||
UserFormatter userFormatter,
|
||||
ICache cache,
|
||||
@ -65,7 +65,7 @@ public class PeopleController : ControllerBase
|
||||
CommonLinkUtility commonLinkUtility,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
Log = option.Get("ASC.ApiSystem.People");
|
||||
Log = option;
|
||||
HostedSolution = hostedSolutionOptions.Value;
|
||||
UserFormatter = userFormatter;
|
||||
Cache = cache;
|
||||
@ -107,7 +107,7 @@ public class PeopleController : ControllerBase
|
||||
link = GetUserProfileLink(user)
|
||||
});
|
||||
|
||||
Log.DebugFormat("People find {0} / {1}; Elapsed {2} ms", result.Count(), userIds.Count(), sw.ElapsedMilliseconds);
|
||||
Log.LogDebug("People find {0} / {1}; Elapsed {2} ms", result.Count(), userIds.Count(), sw.ElapsedMilliseconds);
|
||||
sw.Stop();
|
||||
|
||||
return Ok(new
|
||||
|
@ -46,7 +46,7 @@ public class PortalController : ControllerBase
|
||||
private TimeZonesProvider TimeZonesProvider { get; }
|
||||
private TimeZoneConverter TimeZoneConverter { get; }
|
||||
public PasswordHasher PasswordHasher { get; }
|
||||
private ILog Log { get; }
|
||||
private ILogger<PortalController> Log { get; }
|
||||
|
||||
public PortalController(
|
||||
IConfiguration configuration,
|
||||
@ -61,7 +61,7 @@ public class PortalController : ControllerBase
|
||||
UserFormatter userFormatter,
|
||||
UserManagerWrapper userManagerWrapper,
|
||||
CommonConstants commonConstants,
|
||||
IOptionsMonitor<ILog> option,
|
||||
ILogger<PortalController> option,
|
||||
TimeZonesProvider timeZonesProvider,
|
||||
TimeZoneConverter timeZoneConverter,
|
||||
PasswordHasher passwordHasher)
|
||||
@ -81,7 +81,7 @@ public class PortalController : ControllerBase
|
||||
TimeZonesProvider = timeZonesProvider;
|
||||
TimeZoneConverter = timeZoneConverter;
|
||||
PasswordHasher = passwordHasher;
|
||||
Log = option.Get("ASC.ApiSystem");
|
||||
Log = option;
|
||||
}
|
||||
|
||||
#region For TEST api
|
||||
@ -170,7 +170,7 @@ public class PortalController : ControllerBase
|
||||
return BadRequest(error);
|
||||
}
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. CheckExistingNamePortal: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. CheckExistingNamePortal: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
|
||||
var clientIP = CommonMethods.GetClientIp();
|
||||
|
||||
@ -188,27 +188,22 @@ public class PortalController : ControllerBase
|
||||
return BadRequest(error);
|
||||
}
|
||||
|
||||
if (!CheckRegistrationPayment(out error))
|
||||
{
|
||||
return BadRequest(error);
|
||||
}
|
||||
|
||||
var language = model.Language ?? string.Empty;
|
||||
|
||||
var tz = TimeZonesProvider.GetCurrentTimeZoneInfo(language);
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. TimeZonesProvider.GetCurrentTimeZoneInfo: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. TimeZonesProvider.GetCurrentTimeZoneInfo: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
|
||||
if (!string.IsNullOrEmpty(model.TimeZoneName))
|
||||
{
|
||||
tz = TimeZoneConverter.GetTimeZone(model.TimeZoneName.Trim(), false) ?? tz;
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. TimeZonesProvider.OlsonTimeZoneToTimeZoneInfo: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. TimeZonesProvider.OlsonTimeZoneToTimeZoneInfo: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
var lang = TimeZonesProvider.GetCurrentCulture(language);
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; model.Language = {1}, resultLang.DisplayName = {2}", model.PortalName, language, lang.DisplayName);
|
||||
Log.LogDebug("PortalName = {0}; model.Language = {1}, resultLang.DisplayName = {2}", model.PortalName, language, lang.DisplayName);
|
||||
|
||||
var info = new TenantRegistrationInfo
|
||||
{
|
||||
@ -255,20 +250,20 @@ public class PortalController : ControllerBase
|
||||
{
|
||||
await ApiSystemHelper.AddTenantToCacheAsync(info.Address, SecurityContext.CurrentAccount.ID);
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. CacheController.AddTenantToCache: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. CacheController.AddTenantToCache: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
HostedSolution.RegisterTenant(info, out t);
|
||||
|
||||
/*********/
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. HostedSolution.RegisterTenant: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. HostedSolution.RegisterTenant: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
sw.Stop();
|
||||
|
||||
Log.Error(e);
|
||||
Log.LogError(e, "");
|
||||
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, new
|
||||
{
|
||||
@ -321,13 +316,13 @@ public class PortalController : ControllerBase
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e);
|
||||
Log.LogError(e, "RegisterAsync");
|
||||
}
|
||||
}
|
||||
|
||||
var reference = CommonMethods.CreateReference(Request.Scheme, t.GetTenantDomain(CoreSettings), info.Email, isFirst);
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. CreateReferenceByCookie...: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. CreateReferenceByCookie...: {1}", model.PortalName, sw.ElapsedMilliseconds);
|
||||
|
||||
sw.Stop();
|
||||
|
||||
@ -346,7 +341,7 @@ public class PortalController : ControllerBase
|
||||
{
|
||||
if (!CommonMethods.GetTenant(model, out var tenant))
|
||||
{
|
||||
Log.Error("Model without tenant");
|
||||
Log.LogError("Model without tenant");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
@ -357,7 +352,7 @@ public class PortalController : ControllerBase
|
||||
|
||||
if (tenant == null)
|
||||
{
|
||||
Log.Error("Tenant not found");
|
||||
Log.LogError("Tenant not found");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
@ -381,7 +376,7 @@ public class PortalController : ControllerBase
|
||||
{
|
||||
if (!CommonMethods.GetTenant(model, out var tenant))
|
||||
{
|
||||
Log.Error("Model without tenant");
|
||||
Log.LogError("Model without tenant");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
@ -392,7 +387,7 @@ public class PortalController : ControllerBase
|
||||
|
||||
if (tenant == null)
|
||||
{
|
||||
Log.Error("Tenant not found");
|
||||
Log.LogError("Tenant not found");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
@ -505,7 +500,7 @@ public class PortalController : ControllerBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex);
|
||||
Log.LogError(ex, "");
|
||||
|
||||
return StatusCode(StatusCodes.Status500InternalServerError, new
|
||||
{
|
||||
@ -578,7 +573,7 @@ public class PortalController : ControllerBase
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex);
|
||||
Log.LogError(ex, "CheckExistingNamePortal");
|
||||
error = new { error = "error", message = ex.Message, stacktrace = ex.StackTrace };
|
||||
return (false, error);
|
||||
}
|
||||
@ -624,28 +619,6 @@ public class PortalController : ControllerBase
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool CheckRegistrationPayment(out object error)
|
||||
{
|
||||
error = null;
|
||||
if (Configuration["core:base-domain"] == "localhost")
|
||||
{
|
||||
var tenants = HostedSolution.GetTenants(DateTime.MinValue);
|
||||
var firstTenant = tenants.FirstOrDefault();
|
||||
if (firstTenant != null)
|
||||
{
|
||||
var activePortals = tenants.Count(r => r.Status != TenantStatus.Suspended && r.Status != TenantStatus.RemovePending);
|
||||
|
||||
var quota = HostedSolution.GetTenantQuota(firstTenant.Id);
|
||||
if (quota.CountPortals > 0 && quota.CountPortals <= activePortals)
|
||||
{
|
||||
error = new { error = "portalsCountTooMuch", message = "Too much portals registered already", };
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#region Recaptcha
|
||||
|
||||
@ -657,7 +630,7 @@ public class PortalController : ControllerBase
|
||||
{
|
||||
if (!string.IsNullOrEmpty(model.AppKey) && CommonConstants.AppSecretKeys.Contains(model.AppKey))
|
||||
{
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. ValidateRecaptcha via app key: {1}. {2}", model.PortalName, model.AppKey, sw.ElapsedMilliseconds);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. ValidateRecaptcha via app key: {1}. {2}", model.PortalName, model.AppKey, sw.ElapsedMilliseconds);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -666,7 +639,7 @@ public class PortalController : ControllerBase
|
||||
/*** validate recaptcha ***/
|
||||
if (!CommonMethods.ValidateRecaptcha(model.RecaptchaResponse, model.RecaptchaType, clientIP))
|
||||
{
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. ValidateRecaptcha error: {1} {2}", model.PortalName, sw.ElapsedMilliseconds, data);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. ValidateRecaptcha error: {1} {2}", model.PortalName, sw.ElapsedMilliseconds, data);
|
||||
sw.Stop();
|
||||
|
||||
error = new { error = "recaptchaInvalid", message = "Recaptcha is invalid" };
|
||||
@ -674,7 +647,7 @@ public class PortalController : ControllerBase
|
||||
|
||||
}
|
||||
|
||||
Log.DebugFormat("PortalName = {0}; Elapsed ms. ValidateRecaptcha: {1} {2}", model.PortalName, sw.ElapsedMilliseconds, data);
|
||||
Log.LogDebug("PortalName = {0}; Elapsed ms. ValidateRecaptcha: {1} {2}", model.PortalName, sw.ElapsedMilliseconds, data);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1,3 +1,29 @@
|
||||
// (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
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
@ -32,16 +58,16 @@ public class SettingsController : ControllerBase
|
||||
{
|
||||
private CommonMethods CommonMethods { get; }
|
||||
private CoreSettings CoreSettings { get; }
|
||||
private ILog Log { get; }
|
||||
private ILogger<SettingsController> Log { get; }
|
||||
|
||||
public SettingsController(
|
||||
CommonMethods commonMethods,
|
||||
CoreSettings coreSettings,
|
||||
IOptionsMonitor<ILog> option)
|
||||
ILogger<SettingsController> option)
|
||||
{
|
||||
CommonMethods = commonMethods;
|
||||
CoreSettings = coreSettings;
|
||||
Log = option.Get("ASC.ApiSystem");
|
||||
Log = option;
|
||||
}
|
||||
|
||||
#region For TEST api
|
||||
@ -112,7 +138,7 @@ public class SettingsController : ControllerBase
|
||||
});
|
||||
}
|
||||
|
||||
Log.DebugFormat("Set {0} value {1} for {2}", model.Key, model.Value, tenantId);
|
||||
Log.LogDebug("Set {0} value {1} for {2}", model.Key, model.Value, tenantId);
|
||||
|
||||
CoreSettings.SaveSetting(model.Key, model.Value, tenantId);
|
||||
|
||||
@ -141,7 +167,7 @@ public class SettingsController : ControllerBase
|
||||
message = "PortalName is required"
|
||||
};
|
||||
|
||||
Log.Error("Model is null");
|
||||
Log.LogError("Model is null");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -160,7 +186,7 @@ public class SettingsController : ControllerBase
|
||||
message = "PortalName is required"
|
||||
};
|
||||
|
||||
Log.Error("Model without tenant");
|
||||
Log.LogError("Model without tenant");
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -173,7 +199,7 @@ public class SettingsController : ControllerBase
|
||||
message = "Portal not found"
|
||||
};
|
||||
|
||||
Log.Error("Tenant not found");
|
||||
Log.LogError("Tenant not found");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -58,16 +58,16 @@ public class TariffController : ControllerBase
|
||||
{
|
||||
private CommonMethods CommonMethods { get; }
|
||||
private HostedSolution HostedSolution { get; }
|
||||
private ILog Log { get; }
|
||||
private ILogger<TariffController> Log { get; }
|
||||
public TariffController(
|
||||
CommonMethods commonMethods,
|
||||
IOptionsSnapshot<HostedSolution> hostedSolutionOptions,
|
||||
IOptionsMonitor<ILog> option
|
||||
ILogger<TariffController> option
|
||||
)
|
||||
{
|
||||
CommonMethods = commonMethods;
|
||||
HostedSolution = hostedSolutionOptions.Value;
|
||||
Log = option.Get("ASC.ApiSystem");
|
||||
Log = option;
|
||||
}
|
||||
|
||||
#region For TEST api
|
||||
@ -92,7 +92,7 @@ public class TariffController : ControllerBase
|
||||
{
|
||||
if (!CommonMethods.GetTenant(model, out var tenant))
|
||||
{
|
||||
Log.Error("Model without tenant");
|
||||
Log.LogError("Model without tenant");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
@ -103,7 +103,7 @@ public class TariffController : ControllerBase
|
||||
|
||||
if (tenant == null)
|
||||
{
|
||||
Log.Error("Tenant not found");
|
||||
Log.LogError("Tenant not found");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
@ -156,7 +156,7 @@ public class TariffController : ControllerBase
|
||||
{
|
||||
if (!CommonMethods.GetTenant(model, out var tenant))
|
||||
{
|
||||
Log.Error("Model without tenant");
|
||||
Log.LogError("Model without tenant");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
@ -167,7 +167,7 @@ public class TariffController : ControllerBase
|
||||
|
||||
if (tenant == null)
|
||||
{
|
||||
Log.Error("Tenant not found");
|
||||
Log.LogError("Tenant not found");
|
||||
|
||||
return BadRequest(new
|
||||
{
|
||||
|
@ -58,8 +58,6 @@ public class LoginEventsRepository
|
||||
from q in MessagesContext.LoginEvents
|
||||
from p in MessagesContext.Users.Where(p => q.UserId == p.Id).DefaultIfEmpty()
|
||||
where q.TenantId == tenant
|
||||
where q.Date >= fromDate
|
||||
where q.Date <= to
|
||||
orderby q.Date descending
|
||||
select new LoginEventQuery
|
||||
{
|
||||
|
@ -20,10 +20,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.2.0" />
|
||||
<PackageReference Include="Grpc" Version="2.32.0">
|
||||
<PackageReference Include="Grpc" Version="2.45.0">
|
||||
<TreatAsUsed>true</TreatAsUsed>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Grpc.Tools" Version="2.40.0">
|
||||
<PackageReference Include="Grpc.Tools" Version="2.45.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ASC.Common;
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
[Singletone]
|
||||
public class EncryptionServiceLauncher : IHostedService
|
||||
{
|
||||
private EncryptionServiceListener EncryptionServiceListener { get; set; }
|
||||
|
||||
public EncryptionServiceLauncher(EncryptionServiceListener encryptionServiceListener)
|
||||
{
|
||||
EncryptionServiceListener = encryptionServiceListener;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (EncryptionServiceListener != null)
|
||||
{
|
||||
EncryptionServiceListener.Start();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (EncryptionServiceListener != null)
|
||||
{
|
||||
EncryptionServiceListener.Stop();
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Core.Encryption;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
[Singletone]
|
||||
public class EncryptionServiceListener
|
||||
{
|
||||
private ICacheNotify<EncryptionSettingsProto> NotifySettings { get; }
|
||||
private ICacheNotify<EncryptionStop> NotifyStop { get; }
|
||||
private EncryptionWorker EncryptionWorker { get; }
|
||||
|
||||
public EncryptionServiceListener(ICacheNotify<EncryptionSettingsProto> notifySettings, ICacheNotify<EncryptionStop> notifyStop, EncryptionWorker encryptionWorker)
|
||||
{
|
||||
NotifySettings = notifySettings;
|
||||
NotifyStop = notifyStop;
|
||||
EncryptionWorker = encryptionWorker;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
NotifySettings.Subscribe((n) => StartEncryption(n), CacheNotifyAction.Insert);
|
||||
NotifyStop.Subscribe((n) => StopEncryption(), CacheNotifyAction.Insert);
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
NotifySettings.Unsubscribe(CacheNotifyAction.Insert);
|
||||
NotifySettings.Unsubscribe(CacheNotifyAction.Insert);
|
||||
}
|
||||
|
||||
public void StartEncryption(EncryptionSettingsProto encryptionSettings)
|
||||
{
|
||||
EncryptionWorker.Start(encryptionSettings);
|
||||
}
|
||||
|
||||
public void StopEncryption()
|
||||
{
|
||||
EncryptionWorker.Stop();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,110 +1,64 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
// (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
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
|
||||
using ASC.Api.Core;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.Api.Core.Extensions;
|
||||
using ASC.Data.Storage.Encryption.IntegrationEvents.Events;
|
||||
using ASC.EventBus.Abstractions;
|
||||
using ASC.Notify.IntegrationEvents.EventHandling;
|
||||
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting.WindowsServices;
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public async static Task Main(string[] args)
|
||||
{
|
||||
var host = CreateHostBuilder(args).Build();
|
||||
var options = new WebApplicationOptions
|
||||
{
|
||||
Args = args,
|
||||
ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default
|
||||
};
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.UseSystemd()
|
||||
.UseWindowsService()
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
var builder = webBuilder.UseStartup<Startup>();
|
||||
var builder = WebApplication.CreateBuilder(options);
|
||||
|
||||
builder.ConfigureKestrel((hostingContext, serverOptions) =>
|
||||
{
|
||||
var kestrelConfig = hostingContext.Configuration.GetSection("Kestrel");
|
||||
builder.Host.ConfigureDefault(args);
|
||||
|
||||
if (!kestrelConfig.Exists()) return;
|
||||
builder.WebHost.ConfigureDefaultKestrel();
|
||||
|
||||
var unixSocket = kestrelConfig.GetValue<string>("ListenUnixSocket");
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(unixSocket))
|
||||
{
|
||||
unixSocket = String.Format(unixSocket, hostingContext.HostingEnvironment.ApplicationName.Replace("ASC.", "").Replace(".", ""));
|
||||
var app = builder.Build();
|
||||
|
||||
serverOptions.ListenUnixSocket(unixSocket);
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.ConfigureAppConfiguration((hostContext, config) =>
|
||||
{
|
||||
var buided = config.Build();
|
||||
var path = buided["pathToConf"];
|
||||
if (!Path.IsPathRooted(path))
|
||||
{
|
||||
path = Path.GetFullPath(CrossPlatform.PathCombine(hostContext.HostingEnvironment.ContentRootPath, path));
|
||||
}
|
||||
config.SetBasePath(path);
|
||||
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
|
||||
config
|
||||
.AddInMemoryCollection(new Dictionary<string, string>
|
||||
{
|
||||
{"pathToConf", path }
|
||||
}
|
||||
)
|
||||
.AddJsonFile("appsettings.json")
|
||||
.AddJsonFile($"appsettings.{env}.json", true)
|
||||
.AddJsonFile("storage.json")
|
||||
.AddJsonFile("notify.json")
|
||||
.AddJsonFile($"notify.{env}.json", true)
|
||||
.AddJsonFile("kafka.json")
|
||||
.AddJsonFile($"kafka.{env}.json", true)
|
||||
.AddJsonFile("rabbitmq.json")
|
||||
.AddJsonFile($"rabbitmq.{env}.json", true)
|
||||
.AddJsonFile("redis.json")
|
||||
.AddJsonFile($"redis.{env}.json", true)
|
||||
.AddEnvironmentVariables();
|
||||
})
|
||||
.ConfigureNLogLogging();
|
||||
}
|
||||
}
|
||||
var eventBus = ((IApplicationBuilder)app).ApplicationServices.GetRequiredService<IEventBus>();
|
||||
|
||||
eventBus.Subscribe<EncryptionDataStorageRequestedIntegration, EncryptionDataStorageRequestedIntegrationEventHandler>();
|
||||
|
||||
app.Run();
|
||||
|
||||
|
||||
public partial class Program
|
||||
{
|
||||
public static string AppName = Assembly.GetExecutingAssembly().GetName().Name;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
using StackExchange.Redis.Extensions.Core.Configuration;
|
||||
using StackExchange.Redis.Extensions.Newtonsoft;
|
||||
|
||||
namespace ASC.Data.Storage.Encryption
|
||||
{
|
||||
public class Startup : BaseStartup
|
||||
{
|
||||
public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment) : base(configuration, hostEnvironment)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
base.ConfigureServices(services);
|
||||
|
||||
DIHelper.TryAdd<EncryptionServiceLauncher>();
|
||||
|
||||
services.AddHostedService<EncryptionServiceLauncher>();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,30 @@
|
||||
/*
|
||||
// (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
|
||||
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
@ -28,13 +54,12 @@ using System;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Core;
|
||||
using ASC.Data.Storage.Configuration;
|
||||
using ASC.Protos.Migration;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace ASC.Data.Storage.Migration
|
||||
{
|
||||
@ -87,20 +112,20 @@ namespace ASC.Data.Storage.Migration
|
||||
public StaticUploader StaticUploader { get; }
|
||||
public StorageFactoryConfig StorageFactoryConfig { get; }
|
||||
public IServiceProvider ServiceProvider { get; }
|
||||
public ILog Log { get; }
|
||||
public ILogger<MigrationService> Log { get; }
|
||||
|
||||
public MigrationService(
|
||||
StorageUploader storageUploader,
|
||||
StaticUploader staticUploader,
|
||||
StorageFactoryConfig storageFactoryConfig,
|
||||
IServiceProvider serviceProvider,
|
||||
IOptionsMonitor<ILog> options)
|
||||
ILogger<MigrationService> logger)
|
||||
{
|
||||
StorageUploader = storageUploader;
|
||||
StaticUploader = staticUploader;
|
||||
StorageFactoryConfig = storageFactoryConfig;
|
||||
ServiceProvider = serviceProvider;
|
||||
Log = options.Get("ASC.Data.Storage.Migration");
|
||||
Log = logger;
|
||||
}
|
||||
|
||||
public void Migrate(int tenantId, StorageSettings newStorageSettings)
|
||||
@ -115,7 +140,7 @@ namespace ASC.Data.Storage.Migration
|
||||
tenantManager.SetCurrentTenant(tenantId);
|
||||
|
||||
StaticUploader.UploadDir(relativePath, mappedPath);
|
||||
Log.DebugFormat("UploadDir {0}", mappedPath);
|
||||
Log.LogDebug("UploadDir {0}", mappedPath);
|
||||
}
|
||||
|
||||
public double GetProgress(int tenantId)
|
||||
|
@ -30,6 +30,8 @@ namespace ASC.ElasticSearch.Core;
|
||||
public class SearchSettings : ISettings<SearchSettings>
|
||||
{
|
||||
public string Data { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public Guid ID => new Guid("{93784AB2-10B5-4C2F-9B36-F2662CCCF316}");
|
||||
internal List<SearchSettingsItem> Items
|
||||
{
|
||||
|
@ -1,34 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ApplicationIcon />
|
||||
<OutputType>Exe</OutputType>
|
||||
<RazorCompileOnBuild>false</RazorCompileOnBuild>
|
||||
<GenerateMvcApplicationPartsAssemblyAttributes>false</GenerateMvcApplicationPartsAssemblyAttributes>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Encryption\ASC.Data.Encryption.csproj" />
|
||||
<ProjectReference Include="..\..\ASC.Data.Storage\ASC.Data.Storage.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="6.0.0" />
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="8.0.4" />
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.Newtonsoft" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2020
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ASC.Api.Core;
|
||||
using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
using Autofac;
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
using StackExchange.Redis.Extensions.Core.Configuration;
|
||||
using StackExchange.Redis.Extensions.Newtonsoft;
|
||||
|
||||
namespace ASC.Thumbnails.Svc
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public async static Task Main(string[] args)
|
||||
{
|
||||
var host = CreateHostBuilder(args).Build();
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.UseSystemd()
|
||||
.UseWindowsService()
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
||||
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<BaseWorkerStartup>())
|
||||
.ConfigureAppConfiguration((hostContext, config) =>
|
||||
{
|
||||
var buided = config.Build();
|
||||
var path = buided["pathToConf"];
|
||||
if (!Path.IsPathRooted(path))
|
||||
{
|
||||
path = Path.GetFullPath(CrossPlatform.PathCombine(hostContext.HostingEnvironment.ContentRootPath, path));
|
||||
}
|
||||
config.SetBasePath(path);
|
||||
var env = hostContext.Configuration.GetValue("ENVIRONMENT", "Production");
|
||||
config
|
||||
.AddJsonFile("appsettings.json")
|
||||
.AddJsonFile("storage.json")
|
||||
.AddJsonFile("kafka.json")
|
||||
.AddJsonFile($"kafka.{env}.json", true)
|
||||
.AddJsonFile("rabbitmq.json")
|
||||
.AddJsonFile($"rabbitmq.{env}.json", true)
|
||||
.AddJsonFile("redis.json")
|
||||
.AddJsonFile($"redis.{env}.json", true)
|
||||
.AddJsonFile("thumb.json")
|
||||
.AddJsonFile($"appsettings.{env}.json", true)
|
||||
.AddJsonFile($"thumb.{env}.json", true)
|
||||
.AddEnvironmentVariables()
|
||||
.AddCommandLine(args)
|
||||
.AddInMemoryCollection(new Dictionary<string, string>
|
||||
{
|
||||
{"pathToConf", path }
|
||||
}
|
||||
);
|
||||
})
|
||||
.ConfigureServices((hostContext, services) =>
|
||||
{
|
||||
services.AddMemoryCache();
|
||||
var diHelper = new DIHelper(services);
|
||||
|
||||
var redisConfiguration = hostContext.Configuration.GetSection("Redis").Get<RedisConfiguration>();
|
||||
var kafkaConfiguration = hostContext.Configuration.GetSection("kafka").Get<KafkaSettings>();
|
||||
var rabbitMQConfiguration = hostContext.Configuration.GetSection("RabbitMQ").Get<RabbitMQSettings>();
|
||||
|
||||
if (kafkaConfiguration != null)
|
||||
{
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCacheNotify<>));
|
||||
}
|
||||
else if (rabbitMQConfiguration != null)
|
||||
{
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(RabbitMQCache<>));
|
||||
}
|
||||
else if (redisConfiguration != null)
|
||||
{
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(RedisCacheNotify<>));
|
||||
|
||||
services.AddStackExchangeRedisExtensions<NewtonsoftSerializer>(redisConfiguration);
|
||||
}
|
||||
else
|
||||
{
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(MemoryCacheNotify<>));
|
||||
}
|
||||
|
||||
services.AddHostedService<ThumbnailsServiceLauncher>();
|
||||
diHelper.TryAdd<ThumbnailsServiceLauncher>();
|
||||
|
||||
})
|
||||
.ConfigureContainer<ContainerBuilder>((context, builder) =>
|
||||
{
|
||||
builder.Register(context.Configuration, false, false);
|
||||
})
|
||||
.ConfigureNLogLogging();
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
{
|
||||
"profiles": {
|
||||
"Kestrel WebServer": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": false,
|
||||
"environmentVariables": {
|
||||
"$STORAGE_ROOT": "../../../Data",
|
||||
"log__name": "thumbnails",
|
||||
"log__dir": "../../../Logs",
|
||||
"core__products__folder": "../../../products",
|
||||
"ASPNETCORE_URLS": "http://localhost:5030",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"WSL 2 : Ubuntu 20.04": {
|
||||
"commandName": "WSL2",
|
||||
"launchBrowser": false,
|
||||
"environmentVariables": {
|
||||
"$STORAGE_ROOT": "../../../Data",
|
||||
"log__name": "thumbnails",
|
||||
"log__dir": "../../../Logs",
|
||||
"core__products__folder": "../../../products",
|
||||
"ASPNETCORE_URLS": "http://localhost:5030",
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"distributionName": "Ubuntu-20.04"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* (c) Copyright Ascensio System Limited 2010-2018
|
||||
*
|
||||
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
|
||||
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
|
||||
* In accordance with Section 7(a) of the GNU GPL 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 more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
|
||||
*
|
||||
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
|
||||
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
|
||||
*
|
||||
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
|
||||
* relevant author attributions when distributing the software. If the display of the logo in its graphic
|
||||
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
|
||||
* in every copy of the program you distribute.
|
||||
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ASC.Common;
|
||||
using ASC.Common.Logging;
|
||||
using ASC.Common.Utils;
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ASC.Thumbnails.Svc
|
||||
{
|
||||
[Singletone]
|
||||
public class ThumbnailsServiceLauncher : IHostedService
|
||||
{
|
||||
private ProcessStartInfo StartInfo { get; set; }
|
||||
private Process Proc { get; set; }
|
||||
private ILog Logger { get; set; }
|
||||
private ConfigurationExtension Configuration { get; set; }
|
||||
private IHostEnvironment HostEnvironment { get; set; }
|
||||
|
||||
public ThumbnailsServiceLauncher(IOptionsMonitor<ILog> options, ConfigurationExtension configuration, IHostEnvironment hostEnvironment)
|
||||
{
|
||||
Logger = options.CurrentValue;
|
||||
Configuration = configuration;
|
||||
HostEnvironment = hostEnvironment;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = Configuration.GetSetting<ThumbnailsSettings>("thumb");
|
||||
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
CreateNoWindow = false,
|
||||
UseShellExecute = false,
|
||||
FileName = "node",
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
Arguments = $"\"{Path.GetFullPath(CrossPlatform.PathCombine(HostEnvironment.ContentRootPath, settings.Path, "index.js"))}\"",
|
||||
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory
|
||||
};
|
||||
|
||||
var savePath = settings.SavePath;
|
||||
if (!savePath.EndsWith("/"))
|
||||
{
|
||||
savePath += "/";
|
||||
}
|
||||
StartInfo.EnvironmentVariables.Add("port", settings.Port);
|
||||
StartInfo.EnvironmentVariables.Add("logPath", CrossPlatform.PathCombine(Logger.LogDirectory, "web.thumbnails.log"));
|
||||
StartInfo.EnvironmentVariables.Add("savePath", Path.GetFullPath(savePath));
|
||||
|
||||
StartNode(cancellationToken);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("Start", e);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Proc != null && !Proc.HasExited)
|
||||
{
|
||||
Proc.Kill();
|
||||
Proc.WaitForExit(10000);
|
||||
|
||||
Proc.Close();
|
||||
Proc.Dispose();
|
||||
Proc = null;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("Stop", e);
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void StartNode(CancellationToken cancellationToken)
|
||||
{
|
||||
StopAsync(cancellationToken);
|
||||
Proc = Process.Start(StartInfo);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace ASC.Thumbnails.Svc
|
||||
{
|
||||
public class ThumbnailsSettings
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public string Port { get; set; }
|
||||
public string SavePath { get; set; }
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
{
|
||||
"pathToConf": "..\\..\\..\\config"
|
||||
}
|
2098
i18next/files.babel
2098
i18next/files.babel
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<babeledit_project be_version="3.0.0" version="1.2">
|
||||
<babeledit_project be_version="3.0.1" version="1.2">
|
||||
<!--
|
||||
|
||||
BabelEdit project file
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<babeledit_project be_version="3.0.0" version="1.2">
|
||||
<babeledit_project be_version="3.0.1" version="1.2">
|
||||
<!--
|
||||
|
||||
BabelEdit project file
|
||||
@ -3458,12 +3458,16 @@
|
||||
<name>DeleteProfileEverDialog</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>DeleteUserConfirmation</name>
|
||||
<name>DeleteUser</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
@ -3524,6 +3528,10 @@
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
@ -3541,19 +3549,7 @@
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
@ -3561,22 +3557,30 @@
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>DeleteUserDataConfirmation</name>
|
||||
<name>DeleteUserMessage</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
@ -3637,6 +3641,10 @@
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
@ -3654,19 +3662,7 @@
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
@ -3674,11 +3670,15 @@
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
@ -4034,232 +4034,6 @@
|
||||
<file_node>
|
||||
<name>DeleteUsersDialog</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>DeleteGroupUsersMessage</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>cs-CZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>el-GR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-ES</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fi-FI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>it-IT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ja-JP</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ko-KR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lo-LA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lv-LV</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>nl-NL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ro-RO</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sk-SK</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>DeleteGroupUsersMessageHeader</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>cs-CZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>el-GR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-ES</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fi-FI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>it-IT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ja-JP</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ko-KR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lo-LA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lv-LV</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>nl-NL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ro-RO</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sk-SK</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>DeleteGroupUsersSuccessMessage</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@ -4374,12 +4148,16 @@
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>DeleteUserDataConfirmation</name>
|
||||
<name>DeleteUsers</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
@ -4440,6 +4218,10 @@
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
@ -4457,19 +4239,7 @@
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
@ -4477,13 +4247,130 @@
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>DeleteUsersMessage</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>cs-CZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>el-GR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-ES</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fi-FI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>it-IT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ja-JP</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ko-KR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lo-LA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lv-LV</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>nl-NL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ro-RO</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sk-SK</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
@ -9607,119 +9494,6 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>Disconnect</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>cs-CZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>el-GR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-ES</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fi-FI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>it-IT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ja-JP</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ko-KR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lo-LA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lv-LV</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>nl-NL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ro-RO</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sk-SK</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>EditPhoto</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@ -15281,6 +15055,119 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>DeleteUserDataConfirmation</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>cs-CZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>el-GR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-ES</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fi-FI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>it-IT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ja-JP</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ko-KR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lo-LA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lv-LV</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>nl-NL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ro-RO</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sk-SK</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>DisableUserButton</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@ -16411,119 +16298,6 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>NotBeUndone</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description/>
|
||||
<comment/>
|
||||
<default_text/>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>bg-BG</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>cs-CZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>de-DE</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>el-GR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-ES</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fi-FI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-FR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>it-IT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ja-JP</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ko-KR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lo-LA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>lv-LV</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>nl-NL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pl-PL</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-PT</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ro-RO</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>ru-RU</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sk-SK</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>az-Cyrl-AZ</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>zh-CN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>vi-VN</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>uk-UA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>tr-TR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>sl-SI</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>pt-BR</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>PasswordChangeButton</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
|
@ -55,18 +55,32 @@ export function setDNSSettings(dnsName, enable) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getIpRestrictions() {
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/settings/iprestrictions",
|
||||
});
|
||||
}
|
||||
|
||||
export function setIpRestrictions(data) {
|
||||
return request({
|
||||
method: "put",
|
||||
url: "/settings/iprestrictions.json",
|
||||
url: "/settings/iprestrictions",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
export function getIpRestrictionsEnable() {
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/settings/iprestrictions/settings",
|
||||
});
|
||||
}
|
||||
|
||||
export function setIpRestrictionsEnable(data) {
|
||||
return request({
|
||||
method: "put",
|
||||
url: "/settings/iprestrictions/settings.json",
|
||||
url: "/settings/iprestrictions/settings",
|
||||
data,
|
||||
});
|
||||
}
|
||||
@ -87,6 +101,13 @@ export function setCookieSettings(lifeTime) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getCookieSettings() {
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/settings/cookiesettings.json",
|
||||
});
|
||||
}
|
||||
|
||||
export function setLifetimeAuditSettings(data) {
|
||||
return request({
|
||||
method: "post",
|
||||
|
@ -121,6 +121,7 @@ const StyledArticle = styled.article`
|
||||
|
||||
.article-body__scrollbar {
|
||||
.scroll-body {
|
||||
padding-top: 16px;
|
||||
padding-right: 0px !important;
|
||||
|
||||
@media ${mobile} {
|
||||
@ -158,7 +159,7 @@ const StyledArticleHeader = styled.div`
|
||||
@media ${mobile} {
|
||||
border-bottom: ${(props) => props.theme.catalog.header.borderBottom};
|
||||
padding: 12px 16px 12px;
|
||||
margin-bottom: 16px !important;
|
||||
//margin-bottom: 16px !important;
|
||||
}
|
||||
|
||||
${isTablet &&
|
||||
@ -173,7 +174,7 @@ const StyledArticleHeader = styled.div`
|
||||
border-bottom: ${(props) =>
|
||||
props.theme.catalog.header.borderBottom} !important;
|
||||
padding: 12px 16px 12px !important;
|
||||
margin-bottom: 16px !important;
|
||||
//margin-bottom: 16px !important;
|
||||
`}
|
||||
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
@ -262,11 +263,10 @@ const StyledArticleMainButton = styled.div`
|
||||
`;
|
||||
|
||||
const StyledControlContainer = styled.div`
|
||||
background: ${(props) => props.theme.catalog.control.background};
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
top: 37px;
|
||||
right: 10px;
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
@ -279,8 +279,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};
|
||||
}
|
||||
|
@ -4,21 +4,25 @@ import StyledDialogAsideLoader from "./StyledDialogAsideLoader";
|
||||
import Aside from "@appserver/components/aside";
|
||||
import Backdrop from "@appserver/components/backdrop";
|
||||
|
||||
const DialogAsideLoader = ({ isPanel, withoutAside }) => {
|
||||
const DialogAsideLoader = ({
|
||||
isPanel,
|
||||
withoutAside,
|
||||
withFooterBorder = false,
|
||||
}) => {
|
||||
const zIndex = 310;
|
||||
|
||||
const renderClearDialogAsideLoader = () => {
|
||||
return (
|
||||
<StyledDialogAsideLoader visible isPanel={isPanel}>
|
||||
<StyledDialogAsideLoader withFooterBorder={withFooterBorder} visible>
|
||||
<div className="dialog-loader-header">
|
||||
<Loaders.Rectangle />
|
||||
<Loaders.Rectangle height="29px" />
|
||||
</div>
|
||||
<div className="dialog-loader-body">
|
||||
<Loaders.Rectangle height="200px" />
|
||||
</div>
|
||||
|
||||
<div className="dialog-loader-footer">
|
||||
<Loaders.Rectangle />
|
||||
<Loaders.Rectangle height="40px" />
|
||||
</div>
|
||||
</StyledDialogAsideLoader>
|
||||
);
|
||||
|
@ -40,18 +40,23 @@ const StyledDialogAsideLoader = styled.div`
|
||||
`
|
||||
: css`
|
||||
.dialog-loader-header {
|
||||
border-bottom: 1px solid rgb(222, 226, 230);
|
||||
padding: 12px 0;
|
||||
border-bottom: ${(props) =>
|
||||
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.dialog-loader-body {
|
||||
padding: 16px 0;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.dialog-loader-footer {
|
||||
${(props) =>
|
||||
props.withFooterBorder &&
|
||||
`border-top: 1px solid ${props.theme.modalDialog.headerBorderColor}`};
|
||||
padding: 16px;
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
width: 293px;
|
||||
bottom: 0;
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
@ -2,28 +2,18 @@ import React from "react";
|
||||
import Loaders from "../../Loaders";
|
||||
import StyledDialogLoader from "./StyledDialogLoader";
|
||||
|
||||
const DialogLoader = ({ bodyHeight = "150px" }) => {
|
||||
const DialogLoader = ({ isLarge, withFooterBorder }) => {
|
||||
return (
|
||||
<StyledDialogLoader>
|
||||
<StyledDialogLoader withFooterBorder={withFooterBorder} isLarge={isLarge}>
|
||||
<div className="dialog-loader-header">
|
||||
<Loaders.Rectangle height="28px" width="470px" />
|
||||
<Loaders.Rectangle
|
||||
className="dialog-loader-icon"
|
||||
height="28px"
|
||||
width="28px"
|
||||
/>
|
||||
<Loaders.Rectangle height="29px" />
|
||||
</div>
|
||||
<div className="dialog-loader-body">
|
||||
<Loaders.Rectangle height={bodyHeight} />
|
||||
<Loaders.Rectangle height={isLarge ? "175px" : "73px"} />
|
||||
</div>
|
||||
|
||||
<div className="dialog-loader-footer">
|
||||
<Loaders.Rectangle height="30px" width="120px" />
|
||||
<Loaders.Rectangle
|
||||
className="dialog-loader-icon"
|
||||
height="30px"
|
||||
width="100px"
|
||||
/>
|
||||
<Loaders.Rectangle height="40px" />
|
||||
<Loaders.Rectangle height="40px" />
|
||||
</div>
|
||||
</StyledDialogLoader>
|
||||
);
|
||||
|
@ -1,27 +1,31 @@
|
||||
import { Base } from "@appserver/components/themes";
|
||||
import styled from "styled-components";
|
||||
import { mobile } from "@appserver/components/utils/device";
|
||||
|
||||
const StyledDialogLoader = styled.div`
|
||||
height: auto;
|
||||
width: ${(props) => (props.isLarge ? "520px" : "400px")};
|
||||
@media ${mobile} {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dialog-loader-header {
|
||||
border-bottom: ${(props) => props.theme.dialogLoader.borderBottom};
|
||||
display: flex;
|
||||
padding: 12px 0;
|
||||
border-bottom: ${(props) =>
|
||||
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.dialog-loader-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding-top: 12px;
|
||||
padding: 12px 16px 8px;
|
||||
}
|
||||
|
||||
.dialog-loader-footer {
|
||||
${(props) =>
|
||||
props.withFooterBorder &&
|
||||
`border-top: 1px solid ${props.theme.modalDialog.headerBorderColor}`};
|
||||
display: flex;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.dialog-loader-icon {
|
||||
margin-left: auto;
|
||||
gap: 10px;
|
||||
padding: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -36,6 +36,9 @@ class SettingsStore {
|
||||
: Base;
|
||||
trustedDomains = [];
|
||||
trustedDomainsType = 0;
|
||||
ipRestrictionEnable = false;
|
||||
ipRestrictions = [];
|
||||
sessionLifetime = "1440";
|
||||
timezone = "UTC";
|
||||
timezones = [];
|
||||
tenantAlias = "";
|
||||
@ -474,6 +477,47 @@ class SettingsStore {
|
||||
this.tenantAlias = tenantAlias;
|
||||
};
|
||||
|
||||
getIpRestrictions = async () => {
|
||||
const res = await api.settings.getIpRestrictions();
|
||||
this.ipRestrictions = res?.map((el) => el.ip);
|
||||
};
|
||||
|
||||
setIpRestrictions = async (ips) => {
|
||||
const data = {
|
||||
ips: ips,
|
||||
};
|
||||
const res = await api.settings.setIpRestrictions(data);
|
||||
this.ipRestrictions = res;
|
||||
};
|
||||
|
||||
getIpRestrictionsEnable = async () => {
|
||||
const res = await api.settings.getIpRestrictionsEnable();
|
||||
this.ipRestrictionEnable = res.enable;
|
||||
};
|
||||
|
||||
setIpRestrictionsEnable = async (enable) => {
|
||||
const data = {
|
||||
enable: enable,
|
||||
};
|
||||
const res = await api.settings.setIpRestrictionsEnable(data);
|
||||
this.ipRestrictionEnable = res.enable;
|
||||
};
|
||||
|
||||
setMessageSettings = async (turnOn) => {
|
||||
await api.settings.setMessageSettings(turnOn);
|
||||
this.enableAdmMess = turnOn;
|
||||
};
|
||||
|
||||
getSessionLifetime = async () => {
|
||||
const res = await api.settings.getCookieSettings();
|
||||
this.sessionLifetime = res;
|
||||
};
|
||||
|
||||
setSessionLifetimeSettings = async (lifeTime) => {
|
||||
const res = await api.settings.setCookieSettings(lifeTime);
|
||||
this.sessionLifetime = lifeTime;
|
||||
};
|
||||
|
||||
setIsBurgerLoading = (isBurgerLoading) => {
|
||||
this.isBurgerLoading = isBurgerLoading;
|
||||
};
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
} from "./styled-aside";
|
||||
|
||||
const Aside = React.memo((props) => {
|
||||
//console.log("Aside render");
|
||||
const {
|
||||
visible,
|
||||
children,
|
||||
@ -29,6 +28,7 @@ const Aside = React.memo((props) => {
|
||||
contentPaddingBottom={contentPaddingBottom}
|
||||
className={`${className} not-selectable aside`}
|
||||
>
|
||||
{/* <CloseButton displayType="aside" zIndex={zIndex}/> */}
|
||||
{withoutBodyScroll ? (
|
||||
children
|
||||
) : (
|
||||
|
@ -135,7 +135,7 @@ class AvatarEditor extends React.Component {
|
||||
return useModalDialog ? (
|
||||
<ModalDialog
|
||||
visible={this.state.visible}
|
||||
displayType={displayType}
|
||||
displayType="aside"
|
||||
scale={false}
|
||||
contentHeight="initial"
|
||||
contentWidth="initial"
|
||||
@ -174,8 +174,16 @@ class AvatarEditor extends React.Component {
|
||||
isLoading={saveButtonLoading}
|
||||
primary={true}
|
||||
size="normal"
|
||||
scale
|
||||
onClick={this.onSaveButtonClick}
|
||||
/>
|
||||
<Button
|
||||
key="CancelBtn"
|
||||
label={cancelButtonLabel}
|
||||
size="normal"
|
||||
scale
|
||||
onClick={this.onCancelButtonClick}
|
||||
/>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
) : (
|
||||
|
@ -127,7 +127,7 @@ const StyledAvatarContainer = styled.div`
|
||||
.preview-container {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-column-gap: 16px;
|
||||
grid-column-gap: 44px;
|
||||
|
||||
.custom-range {
|
||||
width: 100%;
|
||||
@ -165,7 +165,7 @@ const StyledAvatarContainer = styled.div`
|
||||
display: grid;
|
||||
|
||||
@media ${desktop} {
|
||||
width: 224px;
|
||||
width: 216px;
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
|
@ -7,11 +7,13 @@ import DropDownItem from "../drop-down-item";
|
||||
import {
|
||||
StyledSpan,
|
||||
StyledText,
|
||||
StyledTextWithExpander,
|
||||
StyledLinkWithDropdown,
|
||||
Caret,
|
||||
} from "./styled-link-with-dropdown";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
import Scrollbar from "@appserver/components/scrollbar";
|
||||
import { ReactSVG } from "react-svg";
|
||||
|
||||
class LinkWithDropdown extends React.Component {
|
||||
constructor(props) {
|
||||
@ -101,6 +103,7 @@ class LinkWithDropdown extends React.Component {
|
||||
directionY,
|
||||
theme,
|
||||
hasScroll,
|
||||
withExpander,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
@ -118,6 +121,24 @@ class LinkWithDropdown extends React.Component {
|
||||
/>
|
||||
));
|
||||
|
||||
const styledText = (
|
||||
<StyledText
|
||||
className="text"
|
||||
isTextOverflow={isTextOverflow}
|
||||
truncate={isTextOverflow}
|
||||
fontSize={fontSize}
|
||||
fontWeight={fontWeight}
|
||||
color={color}
|
||||
isBold={isBold}
|
||||
title={title}
|
||||
dropdownType={dropdownType}
|
||||
isDisabled={isDisabled}
|
||||
withTriangle
|
||||
>
|
||||
{this.props.children}
|
||||
</StyledText>
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledSpan className={className} id={id} style={style} ref={this.ref}>
|
||||
<span onClick={this.onOpen}>
|
||||
@ -127,26 +148,17 @@ class LinkWithDropdown extends React.Component {
|
||||
color={color}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
<StyledText
|
||||
className="text"
|
||||
isTextOverflow={isTextOverflow}
|
||||
truncate={isTextOverflow}
|
||||
fontSize={fontSize}
|
||||
fontWeight={fontWeight}
|
||||
color={color}
|
||||
isBold={isBold}
|
||||
title={title}
|
||||
dropdownType={dropdownType}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
{this.props.children}
|
||||
</StyledText>
|
||||
<Caret
|
||||
color={color}
|
||||
dropdownType={dropdownType}
|
||||
isOpen={this.state.isOpen}
|
||||
isDisabled={isDisabled}
|
||||
/>
|
||||
{withExpander ? (
|
||||
<StyledTextWithExpander isOpen={this.state.isOpen}>
|
||||
{styledText}
|
||||
<ReactSVG
|
||||
className="expander"
|
||||
src={"/static/images/expander-down.react.svg"}
|
||||
/>
|
||||
</StyledTextWithExpander>
|
||||
) : (
|
||||
styledText
|
||||
)}
|
||||
</StyledLinkWithDropdown>
|
||||
</span>
|
||||
<DropDown
|
||||
@ -156,6 +168,7 @@ class LinkWithDropdown extends React.Component {
|
||||
withArrow={false}
|
||||
forwardedRef={this.ref}
|
||||
directionY={directionY}
|
||||
isDropdown={false}
|
||||
clickOutsideAction={this.onClose}
|
||||
{...rest}
|
||||
>
|
||||
@ -185,6 +198,7 @@ LinkWithDropdown.propTypes = {
|
||||
/** Type of dropdown: alwaysDashed is always show dotted style and icon of arrow,
|
||||
* appearDashedAfterHover is show dotted style and icon arrow only after hover */
|
||||
dropdownType: PropTypes.oneOf(["alwaysDashed", "appearDashedAfterHover"]),
|
||||
withExpander: PropTypes.bool,
|
||||
/** Font size of link */
|
||||
fontSize: PropTypes.string,
|
||||
/** Font weight of link */
|
||||
@ -225,6 +239,7 @@ LinkWithDropdown.defaultProps = {
|
||||
className: "",
|
||||
isDisabled: false,
|
||||
hasScroll: false,
|
||||
withExpander: false,
|
||||
};
|
||||
|
||||
export default LinkWithDropdown;
|
||||
|
@ -5,6 +5,7 @@ import PropTypes from "prop-types";
|
||||
import Text from "../text";
|
||||
import Base from "../themes/base";
|
||||
import ExpanderDownIcon from "../../../public/images/expander-down.react.svg";
|
||||
import { transform } from "lodash";
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const SimpleLinkWithDropdown = ({
|
||||
isBold,
|
||||
@ -123,6 +124,27 @@ const StyledLinkWithDropdown = styled(SimpleLinkWithDropdown)`
|
||||
}
|
||||
`;
|
||||
StyledLinkWithDropdown.defaultProps = { theme: Base };
|
||||
|
||||
const StyledTextWithExpander = styled.div`
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
|
||||
.expander {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 6.35px;
|
||||
svg {
|
||||
transform: ${(props) => (props.isOpen ? "rotate(180deg)" : "rotate(0)")};
|
||||
width: 6.35px;
|
||||
height: auto;
|
||||
path {
|
||||
fill: ${(props) => props.theme.linkWithDropdown.expander.iconColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// eslint-disable-next-line react/prop-types, no-unused-vars
|
||||
const SimpleText = ({ color, ...props }) => <Text as="span" {...props} />;
|
||||
const StyledText = styled(SimpleText)`
|
||||
@ -150,4 +172,10 @@ const StyledSpan = styled.span`
|
||||
`;
|
||||
StyledSpan.defaultProps = { theme: Base };
|
||||
|
||||
export { StyledSpan, StyledText, StyledLinkWithDropdown, Caret };
|
||||
export {
|
||||
StyledSpan,
|
||||
StyledTextWithExpander,
|
||||
StyledText,
|
||||
StyledLinkWithDropdown,
|
||||
Caret,
|
||||
};
|
||||
|
@ -0,0 +1,71 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import styled, { css } from "styled-components";
|
||||
import { smallTablet } from "../../utils/device";
|
||||
import IconButton from "../../icon-button";
|
||||
import Base from "../../themes/base";
|
||||
|
||||
const StyledCloseButtonWrapper = styled.div`
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
|
||||
${(props) =>
|
||||
props.currentDisplayType === "modal"
|
||||
? css`
|
||||
top: 0;
|
||||
right: -34px;
|
||||
@media ${smallTablet} {
|
||||
right: 10px;
|
||||
top: -27px;
|
||||
}
|
||||
`
|
||||
: css`
|
||||
top: 10px;
|
||||
left: -27px;
|
||||
@media ${smallTablet} {
|
||||
top: -27px;
|
||||
left: auto;
|
||||
right: 10px;
|
||||
}
|
||||
`}
|
||||
|
||||
.close-button, .close-button:hover {
|
||||
cursor: pointer;
|
||||
path {
|
||||
fill: ${(props) => props.theme.modalDialog.closeButton.fillColor};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
StyledCloseButtonWrapper.defaultProps = { theme: Base };
|
||||
|
||||
const CloseButton = ({ currentDisplayType, zIndex, onClick }) => {
|
||||
return (
|
||||
<StyledCloseButtonWrapper
|
||||
zIndex={zIndex}
|
||||
onClick={onClick}
|
||||
currentDisplayType={currentDisplayType}
|
||||
>
|
||||
<IconButton
|
||||
size="17px"
|
||||
className="close-button"
|
||||
iconName="/static/images/cross.react.svg"
|
||||
/>
|
||||
</StyledCloseButtonWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
CloseButton.propTypes = {
|
||||
currentDisplayType: PropTypes.oneOf(["modal", "aside"]),
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default CloseButton;
|
@ -0,0 +1,64 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
const StyledModalBackdrop = styled.div.attrs((props) => ({
|
||||
style: {
|
||||
backdropFilter: `${
|
||||
props.modalSwipeOffset
|
||||
? `blur(${
|
||||
props.modalSwipeOffset < 0 && 8 - props.modalSwipeOffset * -0.0667
|
||||
}px)`
|
||||
: "blur(8px)"
|
||||
}`,
|
||||
|
||||
background: `${
|
||||
props.modalSwipeOffset
|
||||
? `rgba(6, 22, 38, ${
|
||||
props.modalSwipeOffset < 0 && 0.2 - props.modalSwipeOffset * -0.002
|
||||
})`
|
||||
: `rgba(6, 22, 38, 0.2)`
|
||||
}`,
|
||||
},
|
||||
}))`
|
||||
display: block;
|
||||
height: 100%;
|
||||
min-height: fill-available;
|
||||
max-height: 100vh;
|
||||
width: 100vw;
|
||||
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: ${(props) => props.zIndex};
|
||||
|
||||
transition: 0.2s;
|
||||
opacity: 0;
|
||||
&.modal-backdrop-active {
|
||||
opacity: 1;
|
||||
}
|
||||
`;
|
||||
|
||||
const ModalBackdrop = ({ className, zIndex, modalSwipeOffset, children }) => {
|
||||
return (
|
||||
<StyledModalBackdrop
|
||||
zIndex={zIndex}
|
||||
className={className}
|
||||
modalSwipeOffset={modalSwipeOffset}
|
||||
>
|
||||
{children}
|
||||
</StyledModalBackdrop>
|
||||
);
|
||||
};
|
||||
|
||||
ModalBackdrop.propTypes = {
|
||||
id: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
children: PropTypes.any,
|
||||
|
||||
zIndex: PropTypes.number,
|
||||
visible: PropTypes.bool,
|
||||
modalSwipeOffset: PropTypes.number,
|
||||
};
|
||||
|
||||
export default ModalBackdrop;
|
@ -0,0 +1,30 @@
|
||||
export const parseChildren = (
|
||||
children,
|
||||
headerDisplayName,
|
||||
bodyDisplayName,
|
||||
footerDisplayName
|
||||
) => {
|
||||
let header = null,
|
||||
body = null,
|
||||
footer = null;
|
||||
|
||||
children.forEach((child) => {
|
||||
const childType =
|
||||
child && child.type && (child.type.displayName || child.type.name);
|
||||
|
||||
switch (childType) {
|
||||
case headerDisplayName:
|
||||
header = child;
|
||||
break;
|
||||
case bodyDisplayName:
|
||||
body = child;
|
||||
break;
|
||||
case footerDisplayName:
|
||||
footer = child;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
return [header, body, footer];
|
||||
};
|
@ -0,0 +1,24 @@
|
||||
import { size } from "../../utils/device";
|
||||
|
||||
const getCurrentSizeName = () => {
|
||||
const innerWidth = window.innerWidth;
|
||||
return innerWidth > size.tablet
|
||||
? "desktop"
|
||||
: innerWidth <= size.tablet && innerWidth > size.smallTablet
|
||||
? "tablet"
|
||||
: innerWidth <= size.smallTablet && innerWidth > size.mobile
|
||||
? "smallTablet"
|
||||
: "mobile";
|
||||
};
|
||||
|
||||
export const getCurrentDisplayType = (
|
||||
propsDisplayType,
|
||||
propsDisplayTypeDetailed
|
||||
) => {
|
||||
if (!propsDisplayTypeDetailed) return propsDisplayType;
|
||||
|
||||
const detailedDisplayType = propsDisplayTypeDetailed[getCurrentSizeName()];
|
||||
|
||||
if (detailedDisplayType) return detailedDisplayType;
|
||||
return propsDisplayType;
|
||||
};
|
@ -0,0 +1,27 @@
|
||||
import { isSmallTablet, isTouchDevice } from "../../utils/device";
|
||||
|
||||
let y1 = null;
|
||||
|
||||
export const handleTouchStart = (e) => {
|
||||
if (!(isTouchDevice && isSmallTablet())) {
|
||||
y1 = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
const firstTouch = e.touches[0];
|
||||
if (firstTouch.target.id !== "modal-header-swipe") {
|
||||
y1 = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
y1 = firstTouch.clientY;
|
||||
};
|
||||
|
||||
export const handleTouchMove = (e, onClose) => {
|
||||
if (!y1) return 0;
|
||||
|
||||
let y2 = e.touches[0].clientY;
|
||||
if (y2 - y1 > 120) onClose();
|
||||
|
||||
return y1 - y2;
|
||||
};
|
@ -1,299 +1,164 @@
|
||||
import React from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import Backdrop from "../backdrop";
|
||||
import Aside from "../aside";
|
||||
import Heading from "../heading";
|
||||
import { getModalType } from "../utils/device";
|
||||
import throttle from "lodash/throttle";
|
||||
import Box from "../box";
|
||||
import {
|
||||
CloseButton,
|
||||
StyledHeader,
|
||||
Content,
|
||||
Dialog,
|
||||
BodyBox,
|
||||
} from "./styled-modal-dialog";
|
||||
import Portal from "../portal";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
|
||||
function Header() {
|
||||
return null;
|
||||
}
|
||||
import Portal from "../portal";
|
||||
import ModalAside from "./views/modal-aside";
|
||||
import { handleTouchMove, handleTouchStart } from "./handlers/swipeHandler";
|
||||
import { getCurrentDisplayType } from "./handlers/resizeHandler";
|
||||
import { parseChildren } from "./handlers/childrenParseHandler";
|
||||
|
||||
const Header = () => null;
|
||||
Header.displayName = "DialogHeader";
|
||||
|
||||
function Body() {
|
||||
return null;
|
||||
}
|
||||
const Body = () => null;
|
||||
Body.displayName = "DialogBody";
|
||||
|
||||
function Footer() {
|
||||
return null;
|
||||
}
|
||||
const Footer = () => null;
|
||||
Footer.displayName = "DialogFooter";
|
||||
|
||||
class ModalDialog extends React.Component {
|
||||
static Header = Header;
|
||||
static Body = Body;
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const ModalDialog = ({
|
||||
id,
|
||||
style,
|
||||
children,
|
||||
visible,
|
||||
onClose,
|
||||
isLarge,
|
||||
zIndex,
|
||||
className,
|
||||
displayType,
|
||||
displayTypeDetailed,
|
||||
isLoading,
|
||||
autoMaxHeight,
|
||||
autoMaxWidth,
|
||||
withBodyScroll,
|
||||
modalLoaderBodyHeight,
|
||||
withFooterBorder,
|
||||
}) => {
|
||||
const [currentDisplayType, setCurrentDisplayType] = useState(
|
||||
getCurrentDisplayType(displayType, displayTypeDetailed)
|
||||
);
|
||||
const [modalSwipeOffset, setModalSwipeOffset] = useState(0);
|
||||
|
||||
this.state = { displayType: this.getTypeByWidth() };
|
||||
|
||||
this.getTypeByWidth = this.getTypeByWidth.bind(this);
|
||||
this.resize = this.resize.bind(this);
|
||||
this.popstate = this.popstate.bind(this);
|
||||
this.throttledResize = throttle(this.resize, 300);
|
||||
}
|
||||
|
||||
getTypeByWidth() {
|
||||
if (this.props.displayType !== "auto") return this.props.displayType;
|
||||
|
||||
return getModalType();
|
||||
}
|
||||
|
||||
resize() {
|
||||
if (this.props.displayType !== "auto") return;
|
||||
|
||||
const type = this.getTypeByWidth();
|
||||
if (type === this.state.displayType) return;
|
||||
|
||||
this.setState({ displayType: type });
|
||||
|
||||
this.props.onResize && this.props.onResize(type);
|
||||
}
|
||||
|
||||
popstate() {
|
||||
window.removeEventListener("popstate", this.popstate, false);
|
||||
this.props.onClose();
|
||||
window.history.go(1);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.displayType !== prevProps.displayType) {
|
||||
this.setState({ displayType: this.getTypeByWidth() });
|
||||
}
|
||||
if (this.props.visible && this.state.displayType === "aside") {
|
||||
window.addEventListener("popstate", this.popstate, false);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.throttledResize);
|
||||
window.addEventListener("keyup", this.onKeyPress);
|
||||
|
||||
window.onpopstate = () => {
|
||||
this.props.onClose();
|
||||
};
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.throttledResize);
|
||||
window.removeEventListener("keyup", this.onKeyPress);
|
||||
|
||||
window.onpopstate = null;
|
||||
}
|
||||
|
||||
onKeyPress = (event) => {
|
||||
if (event.key === "Esc" || event.key === "Escape") {
|
||||
this.props.onClose();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
visible,
|
||||
scale,
|
||||
onClose,
|
||||
zIndex,
|
||||
asideBodyPadding,
|
||||
modalBodyPadding,
|
||||
contentHeight,
|
||||
contentWidth,
|
||||
className,
|
||||
id,
|
||||
style,
|
||||
children,
|
||||
isLoading,
|
||||
contentPaddingBottom,
|
||||
withoutBodyScroll,
|
||||
modalLoaderBodyHeight,
|
||||
withoutCloseButton,
|
||||
theme,
|
||||
width,
|
||||
} = this.props;
|
||||
|
||||
let header = null;
|
||||
let body = null;
|
||||
let footer = null;
|
||||
|
||||
React.Children.forEach(children, (child) => {
|
||||
const childType =
|
||||
child && child.type && (child.type.displayName || child.type.name);
|
||||
|
||||
switch (childType) {
|
||||
case Header.displayName:
|
||||
header = child;
|
||||
break;
|
||||
case Body.displayName:
|
||||
body = child;
|
||||
break;
|
||||
case Footer.displayName:
|
||||
footer = child;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
const renderModal = () => {
|
||||
return this.state.displayType === "modal" ? (
|
||||
<Backdrop
|
||||
visible={visible}
|
||||
zIndex={zIndex}
|
||||
withBackground={true}
|
||||
isModalDialog
|
||||
>
|
||||
<Dialog
|
||||
width={width}
|
||||
className={`${className} not-selectable`}
|
||||
id={id}
|
||||
style={style}
|
||||
>
|
||||
<Content
|
||||
contentHeight={contentHeight}
|
||||
contentWidth={contentWidth}
|
||||
displayType={this.state.displayType}
|
||||
className="modal-dialog-content"
|
||||
>
|
||||
{isLoading ? (
|
||||
<Loaders.DialogLoader bodyHeight={modalLoaderBodyHeight} />
|
||||
) : (
|
||||
<>
|
||||
{header && (
|
||||
<StyledHeader>
|
||||
<Heading
|
||||
className="heading"
|
||||
size="medium"
|
||||
truncate={true}
|
||||
>
|
||||
{header ? header.props.children : null}
|
||||
</Heading>
|
||||
{!withoutCloseButton && (
|
||||
<CloseButton
|
||||
className="modal-dialog-button_close"
|
||||
onClick={onClose}
|
||||
></CloseButton>
|
||||
)}
|
||||
</StyledHeader>
|
||||
)}
|
||||
<BodyBox paddingProp={modalBodyPadding}>
|
||||
{body ? body.props.children : null}
|
||||
</BodyBox>
|
||||
<Box className="modal-dialog-modal-footer">
|
||||
{footer ? footer.props.children : null}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Content>
|
||||
</Dialog>
|
||||
</Backdrop>
|
||||
) : (
|
||||
<Box className={className} id={id} style={style}>
|
||||
<Backdrop
|
||||
visible={visible}
|
||||
onClick={onClose}
|
||||
zIndex={zIndex}
|
||||
isAside={true}
|
||||
/>
|
||||
<Aside
|
||||
visible={visible}
|
||||
scale={scale}
|
||||
zIndex={zIndex}
|
||||
onClose={onClose}
|
||||
contentPaddingBottom={contentPaddingBottom}
|
||||
className="modal-dialog-aside not-selectable"
|
||||
withoutBodyScroll={withoutBodyScroll}
|
||||
>
|
||||
<Content
|
||||
contentHeight={contentHeight}
|
||||
contentWidth={contentWidth}
|
||||
withoutBodyScroll={withoutBodyScroll}
|
||||
displayType={this.state.displayType}
|
||||
className="modal-dialog-content"
|
||||
>
|
||||
{isLoading ? (
|
||||
<Loaders.DialogAsideLoader withoutAside />
|
||||
) : (
|
||||
<>
|
||||
<StyledHeader className="modal-dialog-aside-header">
|
||||
<Heading className="heading" size="medium" truncate={true}>
|
||||
{header ? header.props.children : null}
|
||||
</Heading>
|
||||
{scale ? <CloseButton onClick={onClose}></CloseButton> : ""}
|
||||
</StyledHeader>
|
||||
<BodyBox
|
||||
className="modal-dialog-aside-body"
|
||||
paddingProp={asideBodyPadding}
|
||||
withoutBodyScroll={withoutBodyScroll}
|
||||
>
|
||||
{body ? body.props.children : null}
|
||||
</BodyBox>
|
||||
<Box className="modal-dialog-aside-footer">
|
||||
{footer ? footer.props.children : null}
|
||||
</Box>
|
||||
</>
|
||||
)}
|
||||
</Content>
|
||||
</Aside>
|
||||
</Box>
|
||||
useEffect(() => {
|
||||
const onResize = throttle(() => {
|
||||
setCurrentDisplayType(
|
||||
getCurrentDisplayType(displayType, displayTypeDetailed)
|
||||
);
|
||||
}, 300);
|
||||
const onSwipe = (e) => setModalSwipeOffset(handleTouchMove(e, onClose));
|
||||
const onSwipeEnd = () => setModalSwipeOffset(0);
|
||||
const onKeyPress = (e) => {
|
||||
if ((e.key === "Esc" || e.key === "Escape") && visible) onClose();
|
||||
};
|
||||
|
||||
const modalDialog = renderModal();
|
||||
window.addEventListener("resize", onResize);
|
||||
window.addEventListener("keyup", onKeyPress);
|
||||
window.addEventListener("touchstart", handleTouchStart);
|
||||
window.addEventListener("touchmove", onSwipe);
|
||||
window.addEventListener("touchend", onSwipeEnd);
|
||||
return () => {
|
||||
window.removeEventListener("resize", onResize);
|
||||
window.removeEventListener("keyup", onKeyPress);
|
||||
window.removeEventListener("touchstart", handleTouchStart);
|
||||
window.removeEventListener("touchmove", onSwipe);
|
||||
window.addEventListener("touchend", onSwipeEnd);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <Portal element={modalDialog} />;
|
||||
}
|
||||
}
|
||||
const [header, body, footer] = parseChildren(
|
||||
children,
|
||||
Header.displayName,
|
||||
Body.displayName,
|
||||
Footer.displayName
|
||||
);
|
||||
|
||||
return (
|
||||
<Portal
|
||||
element={
|
||||
<ModalAside
|
||||
id={id}
|
||||
style={style}
|
||||
className={className}
|
||||
currentDisplayType={currentDisplayType}
|
||||
withBodyScroll={withBodyScroll}
|
||||
isLarge={isLarge}
|
||||
zIndex={zIndex}
|
||||
autoMaxHeight={autoMaxHeight}
|
||||
autoMaxWidth={autoMaxWidth}
|
||||
withFooterBorder={withFooterBorder}
|
||||
onClose={onClose}
|
||||
isLoading={isLoading}
|
||||
header={header}
|
||||
body={body}
|
||||
footer={footer}
|
||||
visible={visible}
|
||||
modalSwipeOffset={modalSwipeOffset}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
ModalDialog.propTypes = {
|
||||
id: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
zIndex: PropTypes.number,
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
children: PropTypes.any,
|
||||
|
||||
/** Display dialog or not */
|
||||
visible: PropTypes.bool,
|
||||
/** Display type */
|
||||
displayType: PropTypes.oneOf(["auto", "modal", "aside"]),
|
||||
/** Indicates the side panel has scale */
|
||||
scale: PropTypes.bool,
|
||||
/** Will be triggered when a close button is clicked */
|
||||
onClose: PropTypes.func,
|
||||
onResize: PropTypes.func,
|
||||
/**Display close button or not */
|
||||
withoutCloseButton: PropTypes.bool,
|
||||
/** CSS z-index */
|
||||
zIndex: PropTypes.number,
|
||||
/** CSS padding props for body section */
|
||||
asideBodyPadding: PropTypes.string,
|
||||
modalBodyPadding: PropTypes.string,
|
||||
contentHeight: PropTypes.string,
|
||||
contentWidth: PropTypes.string,
|
||||
|
||||
/** Display type */
|
||||
displayType: PropTypes.oneOf(["modal", "aside"]),
|
||||
/** Detailed display type for each dimension */
|
||||
displayTypeDetailed: PropTypes.object,
|
||||
|
||||
/** Show loader in body */
|
||||
isLoading: PropTypes.bool,
|
||||
withoutBodyScroll: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
id: PropTypes.string,
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
contentPaddingBottom: PropTypes.string,
|
||||
modalLoaderBodyHeight: PropTypes.string,
|
||||
width: PropTypes.string,
|
||||
|
||||
/** **`MODAL-ONLY`**
|
||||
|
||||
Sets `width: 520px` and `max-hight: 400px`*/
|
||||
isLarge: PropTypes.bool,
|
||||
|
||||
/** **`MODAL-ONLY`**
|
||||
|
||||
Sets `max-width: auto`*/
|
||||
autoMaxWidth: PropTypes.bool,
|
||||
|
||||
/** **`MODAL-ONLY`**
|
||||
|
||||
Sets `max-height: auto`*/
|
||||
autoMaxHeight: PropTypes.bool,
|
||||
|
||||
/** **`MODAL-ONLY`**
|
||||
|
||||
Displays border betweeen body and footer`*/
|
||||
withFooterBorder: PropTypes.bool,
|
||||
|
||||
/** **`ASIDE-ONLY`**
|
||||
|
||||
Enables Body scroll */
|
||||
withBodyScroll: PropTypes.bool,
|
||||
/** **`ASIDE-ONLY`**
|
||||
|
||||
Sets modal dialog size equal to window */
|
||||
scale: PropTypes.bool,
|
||||
};
|
||||
|
||||
ModalDialog.defaultProps = {
|
||||
displayType: "auto",
|
||||
displayType: "modal",
|
||||
zIndex: 310,
|
||||
asideBodyPadding: "16px 0",
|
||||
modalBodyPadding: "12px 0",
|
||||
contentWidth: "100%",
|
||||
isLarge: false,
|
||||
isLoading: false,
|
||||
withoutCloseButton: false,
|
||||
withoutBodyScroll: false,
|
||||
withBodyScroll: false,
|
||||
withFooterBorder: false,
|
||||
};
|
||||
|
||||
ModalDialog.Header = Header;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React, { useState } from "react";
|
||||
import ModalDialog from ".";
|
||||
import ModalDialog from "./index.js";
|
||||
import Button from "../button";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
export default {
|
||||
title: "Components/ModalDialog",
|
||||
@ -13,64 +14,63 @@ export default {
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
onClick: { action: "onClick" },
|
||||
onClose: { action: "onClose" },
|
||||
onOk: { action: "onOk", table: { disable: true } },
|
||||
onOk: { action: "onOk" },
|
||||
},
|
||||
};
|
||||
|
||||
const Template = ({ onClick, onClose, onOk, ...args }) => {
|
||||
const [isVisible, setIsVisible] = useState(args.visible);
|
||||
const Template = ({ onOk, ...args }) => {
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
const toggleVisible = (e) => {
|
||||
setIsVisible(!isVisible);
|
||||
onClick(e);
|
||||
};
|
||||
const openModal = () => setIsVisible(true);
|
||||
const closeModal = () => setIsVisible(false);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
label="Show"
|
||||
primary={true}
|
||||
size="small"
|
||||
onClick={toggleVisible}
|
||||
/>
|
||||
<ModalDialog
|
||||
{...args}
|
||||
visible={isVisible}
|
||||
onClose={(e) => {
|
||||
onClose(e);
|
||||
setIsVisible(!isVisible);
|
||||
}}
|
||||
>
|
||||
<ModalDialog.Header>{"Change password"}</ModalDialog.Header>
|
||||
<>
|
||||
<Button label="Show" primary={true} size="medium" onClick={openModal} />
|
||||
<ModalDialog {...args} visible={isVisible} onClose={closeModal}>
|
||||
<ModalDialog.Header>Change password</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<div>
|
||||
<span>
|
||||
Send the password change instruction to the{" "}
|
||||
<a href="mailto:asc@story.book">asc@story.book</a> email address
|
||||
</div>
|
||||
</span>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
key="SendBtn"
|
||||
label="Send"
|
||||
primary={true}
|
||||
size="small"
|
||||
onClick={(e) => {
|
||||
onOk(e);
|
||||
setIsVisible(!isVisible);
|
||||
scale
|
||||
size="normal"
|
||||
onClick={() => {
|
||||
onOk();
|
||||
closeModal();
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
key="CloseBtn"
|
||||
label="Cancel"
|
||||
scale
|
||||
size="normal"
|
||||
onClick={closeModal}
|
||||
/>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Template.propTypes = {
|
||||
onOk: PropTypes.func,
|
||||
};
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
scale: false,
|
||||
displayType: "auto",
|
||||
zIndex: 310,
|
||||
headerContent: "Change password",
|
||||
displayType: "aside",
|
||||
displayTypeDetailed: {
|
||||
desktop: "modal",
|
||||
tablet: "aside",
|
||||
smallTablet: "modal",
|
||||
mobile: "aside",
|
||||
},
|
||||
};
|
||||
|
@ -1,99 +1,135 @@
|
||||
import styled, { css } from "styled-components";
|
||||
import Base from "../themes/base";
|
||||
import Box from "../box";
|
||||
import CrossSidebarIcon from "../../../public/images/cross.sidebar.react.svg";
|
||||
import { smallTablet, tablet } from "../utils/device";
|
||||
|
||||
const StyledModal = styled.div`
|
||||
pointer-events: none;
|
||||
&.modal-active {
|
||||
pointer-events: all;
|
||||
}
|
||||
.loader-wrapper {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Dialog = styled.div`
|
||||
position: relative;
|
||||
display: flex;
|
||||
cursor: default;
|
||||
align-items: center;
|
||||
|
||||
width: ${(props) => props.width || props.theme.modalDialog.width};
|
||||
max-width: ${(props) => props.theme.modalDialog.maxwidth};
|
||||
margin: ${(props) => props.theme.modalDialog.margin};
|
||||
min-height: ${(props) => props.theme.modalDialog.minHeight};
|
||||
justify-content: center;
|
||||
width: auto;
|
||||
margin: 0 auto;
|
||||
min-height: 100%;
|
||||
`;
|
||||
Dialog.defaultProps = { theme: Base };
|
||||
|
||||
const Content = styled.div`
|
||||
position: relative;
|
||||
const Content = styled.div.attrs((props) => ({
|
||||
style: {
|
||||
marginBottom:
|
||||
props.modalSwipeOffset < 0 ? `${props.modalSwipeOffset * 1.1}px` : "0px",
|
||||
},
|
||||
}))`
|
||||
box-sizing: border-box;
|
||||
|
||||
height: ${(props) => props.contentHeight};
|
||||
width: ${(props) => props.contentWidth};
|
||||
background-color: ${(props) =>
|
||||
props.theme.modalDialog.content.backgroundColor};
|
||||
position: relative;
|
||||
background-color: ${(props) => props.theme.modalDialog.backgroundColor};
|
||||
color: ${(props) => props.theme.modalDialog.textColor};
|
||||
padding: ${(props) =>
|
||||
props.displayType === "modal"
|
||||
? props.theme.modalDialog.content.modalPadding
|
||||
: props.theme.modalDialog.content.asidePadding};
|
||||
border-radius: ${(props) =>
|
||||
props.theme.modalDialog.content.modalBorderRadius};
|
||||
|
||||
.modal-dialog-aside-header {
|
||||
margin: 0 -16px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.heading {
|
||||
max-width: ${(props) => props.theme.modalDialog.content.heading.maxWidth};
|
||||
margin: ${(props) => props.theme.modalDialog.content.heading.margin};
|
||||
line-height: ${(props) =>
|
||||
props.displayType === "modal"
|
||||
? props.theme.modalDialog.content.heading.modalLineHeight
|
||||
: props.theme.modalDialog.content.heading.asideLineHeight};
|
||||
font-weight: ${(props) =>
|
||||
props.theme.modalDialog.content.heading.fontWeight};
|
||||
font-size: ${(props) =>
|
||||
props.displayType === "modal"
|
||||
? props.theme.modalDialog.content.heading.modalFontSize
|
||||
: props.theme.modalDialog.content.heading.asideFontSize};
|
||||
}
|
||||
props.currentDisplayType === "modal" ? "0" : "0 0 -16px"};
|
||||
|
||||
${(props) =>
|
||||
props.withoutBodyScroll &&
|
||||
css`
|
||||
overflow: hidden;
|
||||
`}
|
||||
props.currentDisplayType === "modal"
|
||||
? css`
|
||||
height: auto;
|
||||
max-height: ${(props) =>
|
||||
props.autoMaxHeight ? "auto" : props.isLarge ? "400px" : "280px"};
|
||||
width: ${(props) =>
|
||||
props.autoMaxWidth ? "auto" : props.isLarge ? "520px" : "400px"};
|
||||
|
||||
border-radius: 6px;
|
||||
@media ${smallTablet} {
|
||||
transform: translateY(${(props) => (props.visible ? "0" : "100%")});
|
||||
transition: transform 0.3s ease-in-out;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
`
|
||||
: css`
|
||||
width: 480px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transform: translateX(${(props) => (props.visible ? "0" : "100%")});
|
||||
transition: transform 0.3s ease-in-out;
|
||||
@media ${smallTablet} {
|
||||
transform: translateY(${(props) => (props.visible ? "0" : "100%")});
|
||||
height: calc(100% - 64px);
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
}
|
||||
`}
|
||||
`;
|
||||
Content.defaultProps = { theme: Base };
|
||||
|
||||
const StyledHeader = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: ${(props) => props.theme.modalDialog.header.borderBottom};
|
||||
`;
|
||||
StyledHeader.defaultProps = { theme: Base };
|
||||
border-bottom: ${(props) =>
|
||||
`1px solid ${props.theme.modalDialog.headerBorderColor}`};
|
||||
margin-bottom: 16px;
|
||||
height: 52px;
|
||||
|
||||
const CloseButton = styled(CrossSidebarIcon)`
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px 0;
|
||||
|
||||
width: ${(props) => props.theme.modalDialog.closeButton.width};
|
||||
height: ${(props) => props.theme.modalDialog.closeButton.height};
|
||||
min-width: ${(props) => props.theme.modalDialog.closeButton.minWidth};
|
||||
min-height: ${(props) => props.theme.modalDialog.closeButton.minHeight};
|
||||
|
||||
right: ${(props) => props.theme.modalDialog.closeButton.right};
|
||||
top: ${(props) => props.theme.modalDialog.closeButton.top};
|
||||
|
||||
&:hover {
|
||||
path {
|
||||
stroke: ${(props) => props.theme.modalDialog.closeButton.hoverColor};
|
||||
}
|
||||
.heading {
|
||||
font-family: "Open Sans";
|
||||
color: ${(props) => props.theme.modalDialog.textColor};
|
||||
font-weight: 700;
|
||||
font-size: ${(props) =>
|
||||
props.currentDisplayType === "modal" ? "18px" : "21px"};
|
||||
}
|
||||
`;
|
||||
CloseButton.defaultProps = { theme: Base };
|
||||
|
||||
const BodyBox = styled(Box)`
|
||||
const StyledBody = styled(Box)`
|
||||
position: relative;
|
||||
padding: 0 16px;
|
||||
padding-bottom: ${(props) =>
|
||||
props.currentDisplayType === "aside" || props.hasFooter ? "8px" : "16px"};
|
||||
|
||||
margin-right: ${(props) => (props.withBodyScroll ? "-16px" : "0")};
|
||||
|
||||
${(props) =>
|
||||
props.withoutBodyScroll &&
|
||||
props.currentDisplayType === "aside" &&
|
||||
css`
|
||||
padding-bottom: 8px;
|
||||
height: 100%;
|
||||
min-height: auto;
|
||||
`}
|
||||
`;
|
||||
|
||||
export { CloseButton, StyledHeader, Content, Dialog, BodyBox };
|
||||
const StyledFooter = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
${(props) =>
|
||||
props.withFooterBorder &&
|
||||
`border-top: 1px solid ${props.theme.modalDialog.headerBorderColor}`};
|
||||
padding: 16px;
|
||||
|
||||
gap: 8px;
|
||||
@media ${tablet} {
|
||||
gap: 10px;
|
||||
}
|
||||
`;
|
||||
|
||||
Dialog.defaultProps = { theme: Base };
|
||||
StyledHeader.defaultProps = { theme: Base };
|
||||
Content.defaultProps = { theme: Base };
|
||||
|
||||
export { StyledModal, StyledHeader, Content, Dialog, StyledBody, StyledFooter };
|
||||
|
156
packages/asc-web-components/modal-dialog/views/modal-aside.js
Normal file
156
packages/asc-web-components/modal-dialog/views/modal-aside.js
Normal file
@ -0,0 +1,156 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
|
||||
import Heading from "../../heading";
|
||||
import {
|
||||
StyledModal,
|
||||
StyledHeader,
|
||||
Content,
|
||||
Dialog,
|
||||
StyledBody,
|
||||
StyledFooter,
|
||||
} from "../styled-modal-dialog";
|
||||
import CloseButton from "../components/CloseButton";
|
||||
import ModalBackdrop from "../components/ModalBackdrop";
|
||||
import Scrollbar from "../../scrollbar";
|
||||
|
||||
const Modal = ({
|
||||
id,
|
||||
style,
|
||||
className,
|
||||
currentDisplayType,
|
||||
withBodyScroll,
|
||||
isLarge,
|
||||
zIndex,
|
||||
autoMaxHeight,
|
||||
autoMaxWidth,
|
||||
onClose,
|
||||
isLoading,
|
||||
header,
|
||||
body,
|
||||
footer,
|
||||
visible,
|
||||
withFooterBorder,
|
||||
modalSwipeOffset,
|
||||
}) => {
|
||||
const headerComponent = header ? header.props.children : null;
|
||||
const bodyComponent = body ? body.props.children : null;
|
||||
const footerComponent = footer ? footer.props.children : null;
|
||||
|
||||
return (
|
||||
<StyledModal
|
||||
className={visible ? "modal-active" : ""}
|
||||
modalSwipeOffset={modalSwipeOffset}
|
||||
>
|
||||
<ModalBackdrop
|
||||
className={visible ? "modal-backdrop-active" : ""}
|
||||
visible={true}
|
||||
zIndex={zIndex}
|
||||
modalSwipeOffset={modalSwipeOffset}
|
||||
>
|
||||
<Dialog
|
||||
className={`${className} dialog not-selectable`}
|
||||
currentDisplayType={currentDisplayType}
|
||||
id={id}
|
||||
style={style}
|
||||
onClick={onClose}
|
||||
>
|
||||
<Content
|
||||
id="modal-dialog"
|
||||
visible={visible}
|
||||
isLarge={isLarge}
|
||||
currentDisplayType={currentDisplayType}
|
||||
autoMaxHeight={autoMaxHeight}
|
||||
autoMaxWidth={autoMaxWidth}
|
||||
modalSwipeOffset={modalSwipeOffset}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<CloseButton
|
||||
currentDisplayType={currentDisplayType}
|
||||
onClick={onClose}
|
||||
/>
|
||||
{isLoading ? (
|
||||
currentDisplayType === "modal" ? (
|
||||
<Loaders.DialogLoader
|
||||
isLarge={isLarge}
|
||||
withFooterBorder={withFooterBorder}
|
||||
/>
|
||||
) : (
|
||||
<Loaders.DialogAsideLoader
|
||||
withoutAside
|
||||
withFooterBorder={withFooterBorder}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<>
|
||||
{header && (
|
||||
<StyledHeader
|
||||
id="modal-header-swipe"
|
||||
currentDisplayType={currentDisplayType}
|
||||
{...header.props}
|
||||
>
|
||||
<Heading
|
||||
level={1}
|
||||
className={"heading"}
|
||||
size="medium"
|
||||
truncate={true}
|
||||
>
|
||||
{headerComponent}
|
||||
</Heading>
|
||||
</StyledHeader>
|
||||
)}
|
||||
{body && (
|
||||
<StyledBody
|
||||
withBodyScroll={withBodyScroll}
|
||||
hasFooter={1 && footer}
|
||||
currentDisplayType={currentDisplayType}
|
||||
{...body.props}
|
||||
>
|
||||
{currentDisplayType === "aside" && withBodyScroll ? (
|
||||
<Scrollbar stype="mediumBlack">{bodyComponent}</Scrollbar>
|
||||
) : (
|
||||
bodyComponent
|
||||
)}
|
||||
</StyledBody>
|
||||
)}
|
||||
{footer && (
|
||||
<StyledFooter
|
||||
withFooterBorder={withFooterBorder}
|
||||
currentDisplayType={currentDisplayType}
|
||||
{...footer.props}
|
||||
>
|
||||
{footerComponent}
|
||||
</StyledFooter>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Content>
|
||||
</Dialog>
|
||||
</ModalBackdrop>
|
||||
</StyledModal>
|
||||
);
|
||||
};
|
||||
|
||||
Modal.propTypes = {
|
||||
id: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
zIndex: PropTypes.number,
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
onClose: PropTypes.func,
|
||||
visible: PropTypes.bool,
|
||||
modalSwipeOffset: PropTypes.number,
|
||||
|
||||
isLoading: PropTypes.bool,
|
||||
modalLoaderBodyHeight: PropTypes.string,
|
||||
|
||||
currentDisplayType: PropTypes.oneOf(["auto", "modal", "aside"]),
|
||||
isLarge: PropTypes.bool,
|
||||
|
||||
header: PropTypes.object,
|
||||
body: PropTypes.object,
|
||||
footer: PropTypes.object,
|
||||
};
|
||||
|
||||
export default Modal;
|
@ -570,6 +570,10 @@ const Base = {
|
||||
},
|
||||
|
||||
modalDialog: {
|
||||
backgroundColor: white,
|
||||
textColor: black,
|
||||
headerBorderColor: globalColors.grayLightMid,
|
||||
footerBorderColor: globalColors.grayLightMid,
|
||||
width: "auto",
|
||||
maxwidth: "560px",
|
||||
margin: " 0 auto",
|
||||
@ -598,14 +602,8 @@ const Base = {
|
||||
},
|
||||
|
||||
closeButton: {
|
||||
width: "14px",
|
||||
height: "14px",
|
||||
minWidth: "14px",
|
||||
minHeight: "14px",
|
||||
|
||||
right: "16px",
|
||||
top: "13px",
|
||||
hoverColor: grayMain,
|
||||
//backgroundColor: "#9a9ea3",
|
||||
fillColor: white,
|
||||
},
|
||||
},
|
||||
|
||||
@ -868,6 +866,10 @@ const Base = {
|
||||
|
||||
span: { maxWidth: "300px" },
|
||||
|
||||
expander: {
|
||||
iconColor: black,
|
||||
},
|
||||
|
||||
caret: {
|
||||
width: "5px",
|
||||
minWidth: "5px",
|
||||
@ -1926,7 +1928,7 @@ const Base = {
|
||||
|
||||
header: {
|
||||
backgroundColor: "#0F4071",
|
||||
|
||||
recoveryColor: "#27537F",
|
||||
linkColor: "#7a95b0",
|
||||
productColor: white,
|
||||
},
|
||||
@ -2233,6 +2235,14 @@ const Base = {
|
||||
},
|
||||
},
|
||||
|
||||
connectCloud: {
|
||||
connectBtnContent: black,
|
||||
connectBtnTextBg: white,
|
||||
connectBtnIconBg: white,
|
||||
connectBtnTextBorder: grayMid,
|
||||
connectBtnIconBorder: grayMid,
|
||||
},
|
||||
|
||||
filesThirdPartyDialog: {
|
||||
border: "1px solid #d1d1d1",
|
||||
},
|
||||
|
@ -567,6 +567,10 @@ const Dark = {
|
||||
},
|
||||
|
||||
modalDialog: {
|
||||
backgroundColor: black,
|
||||
textColor: white,
|
||||
headerBorderColor: "#474747",
|
||||
footerBorderColor: "#474747",
|
||||
width: "auto",
|
||||
maxwidth: "560px",
|
||||
margin: " 0 auto",
|
||||
@ -596,14 +600,8 @@ const Dark = {
|
||||
},
|
||||
|
||||
closeButton: {
|
||||
width: "14px",
|
||||
height: "14px",
|
||||
minWidth: "14px",
|
||||
minHeight: "14px",
|
||||
|
||||
right: "16px",
|
||||
top: "13px",
|
||||
hoverColor: grayMaxLight,
|
||||
//backgroundColor: "#9A9EA3",
|
||||
fillColor: "#9A9EA3",
|
||||
},
|
||||
},
|
||||
|
||||
@ -865,6 +863,10 @@ const Dark = {
|
||||
|
||||
span: { maxWidth: "300px" },
|
||||
|
||||
expander: {
|
||||
iconColor: white,
|
||||
},
|
||||
|
||||
caret: {
|
||||
width: "5px",
|
||||
minWidth: "5px",
|
||||
@ -1926,7 +1928,7 @@ const Dark = {
|
||||
|
||||
header: {
|
||||
backgroundColor: "#1f1f1f ",
|
||||
|
||||
recoveryColor: "#4C4C4C",
|
||||
linkColor: "#606060",
|
||||
productColor: "#eeeeee",
|
||||
},
|
||||
@ -2241,6 +2243,14 @@ const Dark = {
|
||||
},
|
||||
},
|
||||
|
||||
connectCloud: {
|
||||
connectBtnContent: silver,
|
||||
connectBtnTextBg: "none",
|
||||
connectBtnIconBg: "#none",
|
||||
connectBtnTextBorder: silver,
|
||||
connectBtnIconBorder: "#474747",
|
||||
},
|
||||
|
||||
filesThirdPartyDialog: {
|
||||
border: "1px solid #474747",
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
export const size = {
|
||||
mobile: 375,
|
||||
hugeMobile: 414,
|
||||
hugeMobile: 428,
|
||||
smallTablet: 600,
|
||||
tablet: 1024,
|
||||
desktop: 1025,
|
||||
|
@ -4,8 +4,8 @@
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="7.2.1" />
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.Newtonsoft" Version="7.2.1" />
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.AspNetCore" Version="8.0.4" />
|
||||
<PackageReference Include="StackExchange.Redis.Extensions.Newtonsoft" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Server\ASC.CRM.csproj" />
|
||||
|
@ -1,4 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
// (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
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -7,7 +33,6 @@ using ASC.Common;
|
||||
using ASC.Common.Caching;
|
||||
using ASC.Common.DependencyInjection;
|
||||
using ASC.Common.Utils;
|
||||
using ASC.ElasticSearch;
|
||||
using ASC.Web.CRM.Core.Search;
|
||||
|
||||
using Autofac;
|
||||
@ -24,7 +49,7 @@ namespace ASC.CRM.BackgroundTasks
|
||||
{
|
||||
class Program
|
||||
{
|
||||
public async static Task Main(string[] args)
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
var host = CreateHostBuilder(args).Build();
|
||||
|
||||
@ -79,7 +104,7 @@ namespace ASC.CRM.BackgroundTasks
|
||||
|
||||
if (kafkaConfiguration != null)
|
||||
{
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCache<>));
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(KafkaCacheNotify<>));
|
||||
}
|
||||
else if (rabbitMQConfiguration != null)
|
||||
{
|
||||
@ -87,7 +112,7 @@ namespace ASC.CRM.BackgroundTasks
|
||||
}
|
||||
else if (redisConfiguration != null)
|
||||
{
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(RedisCache<>));
|
||||
diHelper.TryAdd(typeof(ICacheNotify<>), typeof(RedisCacheNotify<>));
|
||||
|
||||
services.AddStackExchangeRedisExtensions<NewtonsoftSerializer>(redisConfiguration);
|
||||
}
|
||||
@ -98,8 +123,8 @@ namespace ASC.CRM.BackgroundTasks
|
||||
|
||||
diHelper.RegisterProducts(hostContext.Configuration, hostContext.HostingEnvironment.ContentRootPath);
|
||||
|
||||
services.AddHostedService<ServiceLauncher>();
|
||||
diHelper.TryAdd<ServiceLauncher>();
|
||||
//services.AddHostedService<ServiceLauncher>();
|
||||
//diHelper.TryAdd<ServiceLauncher>();
|
||||
diHelper.TryAdd<FactoryIndexerCase>();
|
||||
diHelper.TryAdd<FactoryIndexerContact>();
|
||||
diHelper.TryAdd<FactoryIndexerContactInfo>();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user