Merge branch 'develop' into feature/appserver-develop-docker-build

This commit is contained in:
Alexey Safronov 2022-07-21 15:05:34 +03:00 committed by GitHub
commit b4cd5ffa0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1191 changed files with 20294 additions and 38167 deletions

22
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -0,0 +1,38 @@
const { join } = require("path");
const { readdirSync, readFileSync, writeFileSync } = require("fs");
const minifyJson = require("../../packages/asc-web-common/utils/minifyJson.js");
const localesDir = join(
__dirname,
"../../build",
"deploy",
"public",
"locales"
);
const getFileList = (dirName) => {
let files = [];
const items = readdirSync(dirName, { withFileTypes: true });
for (const item of items) {
if (item.isDirectory()) {
files = [...files, ...getFileList(`${dirName}/${item.name}`)];
} else {
files.push(`${dirName}/${item.name}`);
}
}
return files;
};
const files = getFileList(localesDir);
files.forEach((filePath) => {
try {
let content = readFileSync(filePath);
writeFileSync(filePath, minifyJson(content, filePath));
//console.log(`File '${filePath}' minified`);
} catch (e) {
console.error("Unable to minify file ", filePath, e);
}
});

View File

@ -33,19 +33,16 @@ public class LdapNotifyService : BackgroundService
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly WorkContext _workContext;
private readonly LdapSaveSyncOperation _ldapSaveSyncOperation;
private readonly NotifyEngineQueue _notifyEngineQueue;
public LdapNotifyService(
IServiceScopeFactory serviceScopeFactory,
WorkContext workContext,
LdapSaveSyncOperation ldapSaveSyncOperation,
NotifyEngineQueue notifyEngineQueue)
LdapSaveSyncOperation ldapSaveSyncOperation)
{
_clients = new ConcurrentDictionary<int, Tuple<INotifyClient, LdapNotifySource>>();
_serviceScopeFactory = serviceScopeFactory;
_workContext = workContext;
_ldapSaveSyncOperation = ldapSaveSyncOperation;
_notifyEngineQueue = notifyEngineQueue;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
@ -82,10 +79,11 @@ public class LdapNotifyService : BackgroundService
{
if (!_clients.ContainsKey(tenant.Id))
{
using var scope = _serviceScopeFactory.CreateScope();
var source = scope.ServiceProvider.GetRequiredService<LdapNotifySource>();
var scope = _serviceScopeFactory.CreateScope();
var source = scope.ServiceProvider.GetRequiredService<LdapNotifySource>();
var notifyEngineQueue = scope.ServiceProvider.GetRequiredService<NotifyEngineQueue>();
source.Init(tenant);
var client = _workContext.NotifyContext.RegisterClient(_notifyEngineQueue, source);
var client = _workContext.NotifyContext.RegisterClient(notifyEngineQueue, source);
_workContext.RegisterSendMethod(source.AutoSync, cron);
_clients.TryAdd(tenant.Id, new Tuple<INotifyClient, LdapNotifySource>(client, source));
}

View File

@ -26,6 +26,8 @@
using static ASC.Security.Cryptography.EmailValidationKeyProvider;
using Constants = ASC.Core.Users.Constants;
namespace ASC.Api.Core.Security;
[Transient]
@ -58,10 +60,10 @@ 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 (Enum.TryParse<ConfirmType>(type, out var confirmType))
if (ConfirmTypeExtensions.TryParse(type, out var confirmType))
{
cType = confirmType;
}
@ -69,7 +71,7 @@ public class EmailValidationKeyModelHelper
request.TryGetValue("key", out var key);
request.TryGetValue("emplType", out var emplType);
Enum.TryParse<EmployeeType>(emplType, out var employeeType);
EmployeeTypeExtensions.TryParse(emplType, out var employeeType);
request.TryGetValue("email", out var _email);
@ -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;
}

View File

@ -45,6 +45,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Primitives" Version="6.0.0" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
<PackageReference Include="EtaEmre.NetEscapades.EnumGenerators" Version="1.0.0-beta07" />
<!-- <PackageReference Include="Microsoft.CodeQuality.Analyzers" Version="2.9.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@ -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 _);

View File

@ -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();
}

View File

@ -36,7 +36,7 @@ global using System.Runtime.CompilerServices;
global using System.Runtime.Loader;
global using System.Runtime.Serialization;
global using System.Security.Cryptography;
global using System.Security.Principal;
global using System.Security.Principal;
global using System.ServiceModel;
global using System.Text;
global using System.Text.RegularExpressions;
@ -92,6 +92,8 @@ global using Microsoft.Extensions.Options;
global using Microsoft.Extensions.Primitives;
global using Microsoft.Net.Http.Headers;
global using NetEscapades.EnumGenerators;
global using Newtonsoft.Json;
global using Newtonsoft.Json.Serialization;

View File

@ -26,6 +26,7 @@
namespace ASC.Common.Security.Authorizing;
[EnumExtensions]
public enum AceType
{
Allow,

View File

@ -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()
@ -70,7 +75,7 @@ public class AzRecord : IMapFrom<Acl>
result.Object = cache.ObjectId;
if (Enum.TryParse<AceType>(cache.Reaction, out var reaction))
if (AceTypeExtensions.TryParse(cache.Reaction, out var reaction))
{
result.AceType = reaction;
}

View File

@ -31,6 +31,7 @@ namespace ASC.Core.Users;
[Flags]
[JsonConverter(typeof(JsonStringEnumConverter))]
[EnumExtensions]
public enum EmployeeType
{
All = 0,

View File

@ -73,7 +73,7 @@ public class UserGroupRef : IMapFrom<UserGroup>
GroupId = new Guid(cache.GroupId)
};
if (Enum.TryParse<UserGroupRefType>(cache.RefType, out var refType))
if (UserGroupRefTypeExtensions.TryParse(cache.RefType, out var refType))
{
result.RefType = refType;
}

View File

@ -26,6 +26,7 @@
namespace ASC.Core;
[EnumExtensions]
public enum UserGroupRefType
{
Contains,

View File

@ -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)

View File

@ -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>();
}
}

View File

@ -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");
});
}
}

View File

@ -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");
});
}
}

View File

@ -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))

View File

@ -59,7 +59,7 @@ public static class UserDavExtension
entity.Property(e => e.TenantId).HasColumnName("tenant_id");
entity.Property(e => e.UserId)
.HasColumnName("userid")
.HasColumnName("user_id")
.HasColumnType("varchar(38)")
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
@ -78,7 +78,7 @@ public static class UserDavExtension
entity.Property(e => e.TenantId).HasColumnName("tenant_id");
entity.Property(e => e.UserId)
.HasColumnName("userid")
.HasColumnName("user_id")
.HasMaxLength(38);
});

View File

@ -34,7 +34,7 @@ global using System.Diagnostics;
global using System.Globalization;
global using System.Linq;
global using System.Linq.Expressions;
global using System.Net;
global using System.Net;
global using System.Net.Http.Headers;
global using System.Reflection;
global using System.Resources;
@ -148,6 +148,8 @@ global using Microsoft.Extensions.Options;
global using MimeKit;
global using NetEscapades.EnumGenerators;
global using Newtonsoft.Json;
global using NVelocity;
@ -158,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;

View File

@ -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)
{

View File

@ -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>();
}

View File

@ -25,7 +25,8 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
namespace ASC.MessagingSystem.Core;
[EnumExtensions]
public enum MessageAction
{
None = -1,
@ -462,20 +463,20 @@ public enum MessageAction
FolderMarkedAsRead = 5065,
RoomCreated = 5066,
RoomRenamed = 5067,
RoomArchived = 5068,
RoomUnarchived = 5069,
RoomDeleted = 5070,
RoomUpdateAccess = 5071,
RoomCreated = 5070,
RoomRenamed = 5071,
RoomArchived = 5072,
RoomUnarchived = 5073,
RoomDeleted = 5074,
RoomUpdateAccess = 5075,
TagCreated = 5072,
TagsDeleted = 5073,
AddedRoomTags = 5074,
DeletedRoomTags = 5075,
TagCreated = 5076,
TagsDeleted = 5077,
AddedRoomTags = 5078,
DeletedRoomTags = 5079,
RoomLogoCreated = 5076,
RoomLogoDeleted = 5077,
RoomLogoCreated = 5080,
RoomLogoDeleted = 5081,
#endregion

View File

@ -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
}
}
}

View File

@ -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");
}
}

View File

@ -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
}
}
}

View File

@ -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
}
}
}

View File

@ -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");
}
}

View File

@ -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
}
}
}

View File

@ -413,10 +413,10 @@ public class NotifyEngine : INotifyEngine, IDisposable
request.CurrentMessage = noticeMessage;
var preventresponse = CheckPreventInterceptors(request, InterceptorPlace.MessageSend, serviceScope, channel.SenderName);
if (preventresponse != null)
{
return preventresponse;
}
if (preventresponse != null)
{
return preventresponse;
}
channel.SendAsync(noticeMessage);
@ -664,7 +664,7 @@ public class NotifyEngine : INotifyEngine, IDisposable
}
}
[Singletone]
[Scope]
public class NotifyEngineQueue
{
private readonly NotifyEngine _notifyEngine;

View File

@ -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)
{

View File

@ -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);

View File

@ -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()

View File

@ -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()

View File

@ -49,6 +49,7 @@ public class TenantCookieSettings : ISettings<TenantCookieSettings>
return new TenantCookieSettings();
}
[JsonIgnore]
public Guid ID => new Guid("{16FB8E67-E96D-4B22-B217-C80F25C5DE1B}");
}

View File

@ -35,6 +35,7 @@ namespace ASC.Web.Studio.Utility;
// portal-remove - confirm portal deletation - Tenant.SetStatus(TenantStatus.RemovePending)
// DnsChange - change Portal Address and/or Custom domain name
[JsonConverter(typeof(JsonStringEnumConverter))]
[EnumExtensions]
public enum ConfirmType
{
EmpInvite,

View File

@ -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}"); }

View File

@ -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; }

View File

@ -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()

View File

@ -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)

View File

@ -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;

View File

@ -37,7 +37,7 @@ global using System.Security.Cryptography.X509Certificates;
global using System.Text;
global using System.Text.Json.Serialization;
global using System.Web;
global using System.Xml.XPath;
global using System.Xml.XPath;
global using ASC.Common;
global using ASC.Common.Caching;

View File

@ -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();
});

View File

@ -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()

View File

@ -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>

View File

@ -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;
}
}

View File

@ -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"
},
};
}
}
}

View File

@ -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; }
}

View File

@ -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;

View File

@ -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>();
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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));
}
}

View File

@ -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;
}
}

View File

@ -1,7 +0,0 @@
syntax = "proto3";
package ASC.VoipService.Dao;
message CachedVoipItem {
int32 tenant = 1;
}

View File

@ -905,6 +905,7 @@
"авторизацията",
"Азърбайджан",
"Азърбайджански",
"Вер",
"Двуфакторно",
"Двуфакторното",
"др",
@ -1155,6 +1156,7 @@
"Thumbnails",
"usw",
"Verbindungs-URL",
"Ver",
"White",
"XLSX-Format",
"ZIP-Datei",
@ -2121,6 +2123,7 @@
"Store",
"sull",
"texto",
"Ver",
"Azərbaycan",
"Azərbaycan",
"Latın",

View File

@ -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)));
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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
{

View File

@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="27.2.1" />
<PackageReference Include="EtaEmre.NetEscapades.EnumGenerators" Version="1.0.0-beta07" />
</ItemGroup>
<ItemGroup>

View File

@ -57,4 +57,6 @@ global using CsvHelper.Configuration;
global using Microsoft.Extensions.Logging;
global using NetEscapades.EnumGenerators;
global using Newtonsoft.Json;

View File

@ -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
{

View File

@ -1,26 +1,26 @@
namespace ASC.AuditTrail.Types
namespace ASC.AuditTrail.Types;
[EnumExtensions]
public enum ActionType
{
public enum ActionType
{
None,
Create,
Update,
Delete,
Link,
Unlink,
Attach,
Detach,
Send,
Import,
Export,
UpdateAccess,
Download,
Upload,
Copy,
Move,
Reassigns,
Follow,
Unfollow,
Logout
}
}
None,
Create,
Update,
Delete,
Link,
Unlink,
Attach,
Detach,
Send,
Import,
Export,
UpdateAccess,
Download,
Upload,
Copy,
Move,
Reassigns,
Follow,
Unfollow,
Logout
}

View File

@ -1,31 +1,31 @@
namespace ASC.AuditTrail.Types
namespace ASC.AuditTrail.Types;
[EnumExtensions]
public enum EntryType
{
public enum EntryType
{
None,
File,
Folder,
Project,
Contact,
Milestone,
Task,
Comment,
SubTask,
Message,
TimeSpend,
ReportTemplate,
Template,
Relationship,
CRMTask,
Opportunity,
Invoice,
Case,
ListItem,
InvoiceItem,
InvoiceTax,
FieldDescription,
OpportunityMilestone,
User,
Group
}
None,
File,
Folder,
Project,
Contact,
Milestone,
Task,
Comment,
SubTask,
Message,
TimeSpend,
ReportTemplate,
Template,
Relationship,
CRMTask,
Opportunity,
Invoice,
Case,
ListItem,
InvoiceItem,
InvoiceTax,
FieldDescription,
OpportunityMilestone,
User,
Group
}

View File

@ -1,33 +1,33 @@
namespace ASC.AuditTrail.Types
namespace ASC.AuditTrail.Types;
[EnumExtensions]
public enum ModuleType
{
public enum ModuleType
{
None,
Files,
Folders,
DocumentsSettings,
Companies,
Persons,
Contacts,
CrmTasks,
Opportunities,
Invoices,
Cases,
CommonCrmSettings,
ContactsSettings,
ContactTypes,
InvoiceSettings,
OtherCrmSettings,
Users,
Groups,
Projects,
Milestones,
Tasks,
Discussions,
TimeTracking,
Reports,
ProjectsSettings,
General,
Products
}
None,
Files,
Folders,
DocumentsSettings,
Companies,
Persons,
Contacts,
CrmTasks,
Opportunities,
Invoices,
Cases,
CommonCrmSettings,
ContactsSettings,
ContactTypes,
InvoiceSettings,
OtherCrmSettings,
Users,
Groups,
Projects,
Milestones,
Tasks,
Discussions,
TimeTracking,
Reports,
ProjectsSettings,
General,
Products
}

View File

@ -1,14 +1,14 @@
namespace ASC.AuditTrail.Types
namespace ASC.AuditTrail.Types;
[EnumExtensions]
public enum ProductType
{
public enum ProductType
{
None,
CRM,
Documents,
Login,
Others,
People,
Projects,
Settings
}
None,
CRM,
Documents,
Login,
Others,
People,
Projects,
Settings
}

View File

@ -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>

View File

@ -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;
}
}
}

View File

@ -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();
}
}
}

View File

@ -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;
}

View File

@ -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>();
}
}
}

View File

@ -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)

View File

@ -26,6 +26,7 @@
namespace ASC.ElasticSearch;
[EnumExtensions]
public enum Analyzer
{
standard,
@ -34,6 +35,7 @@ public enum Analyzer
}
[Flags]
[EnumExtensions]
public enum CharFilter
{
io,

View File

@ -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
{

View File

@ -153,13 +153,13 @@ public class BaseIndexer<T> where T : class, ISearchItem
{
IPromise<IAnalyzers> analyzers(AnalyzersDescriptor b)
{
foreach (var c in Enum.GetNames(typeof(Analyzer)))
foreach (var c in AnalyzerExtensions.GetNames())
{
var c1 = c;
b.Custom(c1 + "custom", ca => ca.Tokenizer(c1).Filters(nameof(Filter.lowercase)).CharFilters(nameof(CharFilter.io)));
}
foreach (var c in Enum.GetNames(typeof(CharFilter)))
foreach (var c in CharFilterExtensions.GetNames())
{
if (c == nameof(CharFilter.io))
{

View File

@ -56,6 +56,8 @@ global using Microsoft.Extensions.Logging;
global using Nest;
global using NetEscapades.EnumGenerators;
global using Newtonsoft.Json;
global using LogLevel = Microsoft.Extensions.Logging.LogLevel;

View File

@ -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>

View File

@ -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();
}
}

View File

@ -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"
}
}
}

View File

@ -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);
}
}
}

View File

@ -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; }
}
}

View File

@ -1,3 +0,0 @@
{
"pathToConf": "..\\..\\..\\config"
}

View File

@ -1,4 +1,3 @@
{
"kafka": {
}
"kafka": {}
}

File diff suppressed because it is too large Load Diff

View 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

View 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>

View File

@ -1,6 +1,6 @@
{
"name": "appserver",
"version": "1.1.1",
"version": "1.2.0",
"private": true,
"workspaces": [
"packages/asc-web-components",
@ -20,8 +20,8 @@
"build:test.translation:personal": "lerna run build:test.translation:personal --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc --ignore @appserver/debug-info",
"bump": "lerna version --no-push --no-git-tag-version",
"clean": "lerna run clean --parallel",
"deploy": "shx rm -rf build/deploy/products && shx rm -rf build/deploy/public && shx rm -rf build/deploy/studio && lerna run deploy --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc && shx cp -r public build/deploy",
"deploy:personal": "shx rm -rf build/deploy/products && shx rm -rf build/deploy/public && shx rm -rf build/deploy/studio && lerna run deploy --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor} && shx cp -r public build/deploy",
"deploy": "shx rm -rf build/deploy/products && shx rm -rf build/deploy/public && shx rm -rf build/deploy/studio && lerna run deploy --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc && shx cp -r public build/deploy && node build/scripts/minify-common-locales.js",
"deploy:personal": "shx rm -rf build/deploy/products && shx rm -rf build/deploy/public && shx rm -rf build/deploy/studio && lerna run deploy --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor} && shx cp -r public build/deploy && node build/scripts/minify-common-locales.js",
"serve": "lerna run serve --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc",
"start": "lerna run start --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc",
"start:personal": "lerna run start:personal --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor}",

View File

@ -3,7 +3,7 @@ import axios from "axios";
import FilesFilter from "./filter";
import { FolderType } from "../../constants";
import find from "lodash/find";
import { getFolderOptions } from "../../utils";
import { getFolderOptions, decodeDisplayName } from "../../utils";
import { Encoder } from "../../utils/encoder";
export function openEdit(fileId, version, doc, view) {
@ -49,24 +49,6 @@ export function getFolderPath(folderId) {
return request(options);
}
const decodeDisplayName = (items) => {
return items.map((item) => {
if (!item) return item;
if (item.updatedBy?.displayName) {
item.updatedBy.displayName = Encoder.htmlDecode(
item.updatedBy.displayName
);
}
if (item.createdBy?.displayName) {
item.createdBy.displayName = Encoder.htmlDecode(
item.createdBy.displayName
);
}
return item;
});
};
export function getFolder(folderId, filter) {
const options = getFolderOptions(folderId, filter);
return request(options).then((res) => {
@ -109,6 +91,18 @@ const sortInDisplayOrder = (folders) => {
);
myFolder && sorted.push(myFolder);
const shareRoom = find(
folders,
(folder) => folder.current.rootFolderType == FolderType.Rooms
);
shareRoom && sorted.push(shareRoom);
const archiveRoom = find(
folders,
(folder) => folder.current.rootFolderType == FolderType.Archive
);
archiveRoom && sorted.push(archiveRoom);
const shareFolder = find(
folders,
(folder) => folder.current.rootFolderType == FolderType.SHARE
@ -158,6 +152,7 @@ export function getFoldersTree() {
return request({ method: "get", url: "/files/@root?filterType=2" }).then(
(response) => {
const folders = sortInDisplayOrder(response);
return folders.map((data, index) => {
const type = +data.current.rootFolderType;
const name = getFolderClassNameByType(type);

View File

@ -1,5 +1,6 @@
import Filter from "./people/filter";
import FilesFilter from "./files/filter";
import RoomsFilter from "./rooms/filter";
import * as people from "./people";
import * as user from "./user";
import * as settings from "./settings";
@ -7,10 +8,12 @@ import * as modules from "./modules";
import * as portal from "./portal";
import * as groups from "./groups";
import * as files from "./files";
import * as rooms from "./rooms";
export default {
Filter,
FilesFilter,
RoomsFilter,
people,
user,
settings,
@ -18,4 +21,5 @@ export default {
portal,
groups,
files,
rooms,
};

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