Merge branch 'develop' into feature/create-room

This commit is contained in:
mushka 2022-08-25 15:36:52 +03:00
commit 64f899fbbf
52 changed files with 1578 additions and 208 deletions

View File

@ -70,6 +70,7 @@ public abstract class BaseStartup
services.AddBaseDbContextPool<TenantDbContext>();
services.AddBaseDbContextPool<UserDbContext>();
services.AddBaseDbContextPool<TelegramDbContext>();
services.AddBaseDbContextPool<FirebaseDbContext>();
services.AddBaseDbContextPool<CustomDbContext>();
services.AddBaseDbContextPool<WebstudioDbContext>();
services.AddBaseDbContextPool<InstanceRegistrationContext>();

View File

@ -50,6 +50,7 @@
<ItemGroup>
<PackageReference Include="AWSSDK.Core" Version="3.7.10.11" />
<PackageReference Include="AWSSDK.SimpleEmail" Version="3.7.0.150" />
<PackageReference Include="FirebaseAdmin" Version="2.3.0" />
<PackageReference Include="Grpc.Tools" Version="2.47.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@ -134,42 +134,6 @@ public class UserServiceCache
}
}
[Scope]
class ConfigureCachedUserService : IConfigureNamedOptions<CachedUserService>
{
internal readonly IOptionsSnapshot<EFUserService> Service;
internal readonly UserServiceCache UserServiceCache;
internal readonly CoreBaseSettings CoreBaseSettings;
public ConfigureCachedUserService(
IOptionsSnapshot<EFUserService> service,
UserServiceCache userServiceCache,
CoreBaseSettings coreBaseSettings)
{
Service = service;
UserServiceCache = userServiceCache;
CoreBaseSettings = coreBaseSettings;
}
public void Configure(string name, CachedUserService options)
{
Configure(options);
options.Service = Service.Get(name);
}
public void Configure(CachedUserService options)
{
options.Service = Service.Value;
options.CoreBaseSettings = CoreBaseSettings;
options.UserServiceCache = UserServiceCache;
options.Cache = UserServiceCache.Cache;
options.CacheUserInfoItem = UserServiceCache.CacheUserInfoItem;
options.CacheUserPhotoItem = UserServiceCache.CacheUserPhotoItem;
options.CacheGroupCacheItem = UserServiceCache.CacheGroupCacheItem;
options.CacheUserGroupRefItem = UserServiceCache.CacheUserGroupRefItem;
}
}
[Scope]
public class CachedUserService : IUserService, ICachedService
{

View File

@ -66,38 +66,7 @@ public class CoreBaseSettings
public bool DisableDocSpace => _disableDocSpace ?? (bool)(_disableDocSpace = string.Equals(Configuration["core:disableDocspace"], "true", StringComparison.OrdinalIgnoreCase));
}
class ConfigureCoreSettings : IConfigureNamedOptions<CoreSettings>
{
private readonly IOptionsSnapshot<CachedTenantService> _tenantService;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly IConfiguration _configuration;
public ConfigureCoreSettings(
IOptionsSnapshot<CachedTenantService> tenantService,
CoreBaseSettings coreBaseSettings,
IConfiguration configuration
)
{
_tenantService = tenantService;
_coreBaseSettings = coreBaseSettings;
_configuration = configuration;
}
public void Configure(string name, CoreSettings options)
{
Configure(options);
options.TenantService = _tenantService.Get(name);
}
public void Configure(CoreSettings options)
{
options.Configuration = _configuration;
options.CoreBaseSettings = _coreBaseSettings;
options.TenantService = _tenantService.Value;
}
}
[Scope(typeof(ConfigureCoreSettings))]
[Scope]
public class CoreSettings
{
public string BaseDomain

View File

@ -41,6 +41,7 @@ public class WorkContext
private readonly SmtpSender _smtpSender;
private readonly NotifyServiceSender _notifyServiceSender;
private readonly TelegramSender _telegramSender;
private readonly PushSender _pushSender;
private static bool _notifyStarted;
private static bool? _isMono;
private static string _monoVersion;
@ -87,7 +88,8 @@ public class WorkContext
AWSSender awsSender,
SmtpSender smtpSender,
NotifyServiceSender notifyServiceSender,
TelegramSender telegramSender
TelegramSender telegramSender,
PushSender pushSender
)
{
_serviceProvider = serviceProvider;
@ -100,6 +102,7 @@ public class WorkContext
_smtpSender = smtpSender;
_notifyServiceSender = notifyServiceSender;
_telegramSender = telegramSender;
_pushSender = pushSender;
}
public void NotifyStartUp()
@ -119,6 +122,8 @@ public class WorkContext
INotifySender jabberSender = _notifyServiceSender;
INotifySender emailSender = _notifyServiceSender;
INotifySender telegramSender = _telegramSender;
INotifySender pushSender = _pushSender;
var postman = _configuration["core:notify:postman"];
@ -148,6 +153,7 @@ public class WorkContext
NotifyContext.RegisterSender(_dispatchEngine, Constants.NotifyEMailSenderSysName, new EmailSenderSink(emailSender, _serviceProvider));
NotifyContext.RegisterSender(_dispatchEngine, Constants.NotifyMessengerSenderSysName, new JabberSenderSink(jabberSender, _serviceProvider));
NotifyContext.RegisterSender(_dispatchEngine, Constants.NotifyTelegramSenderSysName, new TelegramSenderSink(telegramSender, _serviceProvider));
NotifyContext.RegisterSender(_dispatchEngine, Constants.NotifyPushSenderSysName, new PushSenderSink(pushSender, _serviceProvider));
NotifyEngine.AddAction<NotifyTransferRequest>();
@ -199,6 +205,7 @@ public static class WorkContextExtension
dIHelper.TryAdd<TelegramHelper>();
dIHelper.TryAdd<TelegramSenderSinkMessageCreator>();
dIHelper.TryAdd<JabberSenderSinkMessageCreator>();
dIHelper.TryAdd<PushSenderSinkMessageCreator>();
dIHelper.TryAdd<EmailSenderSinkMessageCreator>();
}
}

View File

@ -0,0 +1,44 @@
// (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 FirebaseDbContext : DbContext
{
public DbSet<FireBaseUser> Users { get; set; }
public FirebaseDbContext(DbContextOptions<FirebaseDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
ModelBuilderWrapper
.From(modelBuilder, Database)
.AddFireBaseUsers();
}
}

View File

@ -0,0 +1,122 @@
// (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;
public class FireBaseUser : BaseEntity
{
public int Id { get; set; }
public Guid UserId { get; set; }
public int TenantId { get; set; }
public string FirebaseDeviceToken { get; set; }
public string Application { get; set; }
public bool? IsSubscribed { get; set; }
public override object[] GetKeys()
{
return new object[] { Id };
}
}
public static class FireBaseUserExtension
{
public static ModelBuilderWrapper AddFireBaseUsers(this ModelBuilderWrapper modelBuilder)
{
modelBuilder
.Add(MySqlAddFireBaseUsers, Provider.MySql)
.Add(PgSqlAddFireBaseUsers, Provider.PostgreSql);
return modelBuilder;
}
public static void MySqlAddFireBaseUsers(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<FireBaseUser>(entity =>
{
entity.HasKey(e => new { e.Id })
.HasName("PRIMARY");
entity.ToTable("firebase_users");
entity.HasIndex(e => new { e.TenantId, e.UserId })
.HasDatabaseName("user_id");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.TenantId).HasColumnName("tenant_id");
entity.Property(e => e.IsSubscribed).HasColumnName("is_subscribed");
entity.Property(e => e.UserId)
.HasColumnName("user_id")
.HasColumnType("varchar(36)")
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
entity.Property(e => e.FirebaseDeviceToken)
.HasColumnName("firebase_device_token")
.HasColumnType("varchar(255)")
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
entity.Property(e => e.Application)
.HasColumnName("application")
.HasColumnType("varchar(20)")
.HasCharSet("utf8")
.UseCollation("utf8_general_ci");
});
}
public static void PgSqlAddFireBaseUsers(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<FireBaseUser>(entity =>
{
entity.HasKey(e => e.Id)
.HasName("firebase_users_pkey");
entity.ToTable("firebase_users", "onlyoffice");
entity.HasIndex(e => new { e.TenantId, e.UserId })
.HasDatabaseName("user_id");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.TenantId).HasColumnName("tenant_id");
entity.Property(e => e.IsSubscribed).HasColumnName("is_subscribed");
entity.Property(e => e.UserId)
.HasColumnName("user_id")
.HasMaxLength(36);
entity.Property(e => e.FirebaseDeviceToken)
.HasColumnName("firebase_device_token")
.HasMaxLength(255);
entity.Property(e => e.Application)
.HasColumnName("application")
.HasMaxLength(20);
});
}
}

View File

@ -126,6 +126,8 @@ global using Autofac;
global using AutoMapper;
global using AutoMapper.QueryableExtensions;
global using Google.Apis.Auth.OAuth2;
global using MailKit.Security;
global using Microsoft.AspNetCore.Http;
@ -161,4 +163,7 @@ global using Telegram.Bot;
global using static ASC.Security.Cryptography.EmailValidationKeyProvider;
global using JsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;
global using JsonIgnoreAttribute = System.Text.Json.Serialization.JsonIgnoreAttribute;
global using FirebaseAdminMessaging = FirebaseAdmin.Messaging;
global using FirebaseApp = FirebaseAdmin.FirebaseApp;
global using AppOptions = FirebaseAdmin.AppOptions;

View File

@ -0,0 +1,119 @@
// (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.Notify;
[Serializable]
class FirebaseApiKey
{
private readonly IConfiguration _configuration;
public FirebaseApiKey(IConfiguration configuration)
{
_configuration = configuration;
}
[JsonProperty("type")]
public string Type
{
get
{
return "service_account";
}
}
[JsonProperty("project_id")]
public string ProjectId
{
get
{
return _configuration["firebase:projectId"] ?? "";
}
}
[JsonProperty("private_key_id")]
public string PrivateKeyId
{
get
{
return _configuration["firebase:privateKeyId"] ?? "";
}
}
[JsonProperty("private_key")]
public string PrivateKey
{
get
{
return _configuration["firebase:privateKey"] ?? "";
}
}
[JsonProperty("client_email")]
public string ClientEmail
{
get
{
return _configuration["firebase:clientEmail"] ?? "";
}
}
[JsonProperty("client_id")]
public string ClientId
{
get
{
return _configuration["firebase:clientId"] ?? "";
}
}
[JsonProperty("auth_uri")]
public string AuthUri
{
get
{
return "https://accounts.google.com/o/oauth2/auth";
}
}
[JsonProperty("token_uri")]
public string TokenUri
{
get
{
return "https://oauth2.googleapis.com/token";
}
}
[JsonProperty("auth_provider_x509_cert_url")]
public string AuthProviderX509CertUrl
{
get
{
return "https://www.googleapis.com/oauth2/v1/certs";
}
}
[JsonProperty("client_x509_cert_url")]
public string ClientX509CertUrl
{
get
{
return _configuration["firebase:x509CertUrl"] ?? "";
}
}
}

View File

@ -65,6 +65,12 @@ public class NotifyMessage : IMapFrom<NotifyQueue>
[ProtoMember(12)]
public int TenantId { get; set; }
[ProtoMember(13)]
public string ProductID { get; set; }
[ProtoMember(14)]
public string Data { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<NotifyQueue, NotifyMessage>()

View File

@ -0,0 +1,99 @@
// (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.Notify.Push;
[Scope]
public class FirebaseDao
{
private readonly IDbContextFactory<FirebaseDbContext> _dbContextFactory;
public FirebaseDao(IDbContextFactory<FirebaseDbContext> dbContextFactory)
{
_dbContextFactory = dbContextFactory;
}
public FireBaseUser RegisterUserDevice(Guid userId, int tenantId, string fbDeviceToken, bool isSubscribed, string application)
{
using var dbContext = _dbContextFactory.CreateDbContext();
var user = dbContext.Users
.AsNoTracking()
.Where(r => r.UserId == userId)
.Where(r => r.TenantId == tenantId)
.Where(r => r.Application == application)
.Where(r => r.FirebaseDeviceToken == fbDeviceToken)
.FirstOrDefault();
if (user == null)
{
var newUser = new FireBaseUser
{
UserId = userId,
TenantId = tenantId,
FirebaseDeviceToken = fbDeviceToken,
IsSubscribed = isSubscribed,
Application = application
};
dbContext.Add(newUser);
dbContext.SaveChanges();
return newUser;
}
return user;
}
public List<FireBaseUser> GetUserDeviceTokens(Guid userId, int tenantId, string application)
{
using var dbContext = _dbContextFactory.CreateDbContext();
return dbContext.Users
.AsNoTracking()
.Where(r => r.UserId == userId)
.Where(r => r.TenantId == tenantId)
.Where(r => r.Application == application)
.ToList();
}
public FireBaseUser UpdateUser(Guid userId, int tenantId, string fbDeviceToken, bool isSubscribed, string application)
{
using var dbContext = _dbContextFactory.CreateDbContext();
var user = new FireBaseUser
{
UserId = userId,
TenantId = tenantId,
FirebaseDeviceToken = fbDeviceToken,
IsSubscribed = isSubscribed,
Application = application
};
dbContext.Update(user);
dbContext.SaveChanges();
return user;
}
}

View File

@ -0,0 +1,46 @@
// (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.Notify.Push.Dao;
[Serializable]
public class NotifyData
{
[JsonProperty("portal")]
public string Portal { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("file")]
public NotifyFileData File { get; set; }
[JsonProperty("folder")]
public NotifyFolderData Folder { get; set; }
[JsonProperty("originalUrl")]
public string OriginalUrl { get; set; }
}

View File

@ -0,0 +1,39 @@
// (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.Notify.Push.Dao;
[Serializable]
public class NotifyFileData
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
[JsonProperty("extension")]
public string Extension { get; set; }
}

View File

@ -0,0 +1,37 @@
// (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.Notify.Push.Dao;
public class NotifyFolderData
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("parentId")]
public string ParentId { get; set; }
[JsonProperty("rootFolderType")]
public int RootFolderType { get; set; }
}

View File

@ -0,0 +1,127 @@
// (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.Notify.Push;
[Scope]
public class FirebaseHelper
{
protected readonly UserManager _userManager;
private readonly AuthContext _authContext;
private readonly TenantManager _tenantManager;
private readonly ILogger<FirebaseHelper> _logger;
private readonly IConfiguration _configuration;
private readonly FirebaseDao _firebaseDao;
public FirebaseHelper(
AuthContext authContext,
UserManager userManager,
TenantManager tenantManager,
IConfiguration configuration,
ILogger<FirebaseHelper> logger,
FirebaseDao firebaseDao)
{
_authContext = authContext;
_userManager = userManager;
_tenantManager = tenantManager;
_configuration = configuration;
_logger = logger;
_firebaseDao = firebaseDao;
}
public void SendMessage(NotifyMessage msg)
{
var defaultInstance = FirebaseApp.DefaultInstance;
if (defaultInstance == null)
{
try
{
var credentials = JsonConvert.SerializeObject(new FirebaseApiKey(_configuration)).Replace("\\\\", "\\");
FirebaseApp.Create(new AppOptions()
{
Credential = GoogleCredential.FromJson(credentials)
});
}
catch (Exception e)
{
_logger.ErrorUnexpected(e);
}
}
_tenantManager.SetCurrentTenant(msg.TenantId);
var user = _userManager.GetUserByUserName(msg.Reciever);
Guid productID;
if (!Guid.TryParse(msg.ProductID, out productID))
{
return;
}
var fireBaseUser = new List<FireBaseUser>();
if (productID == new Guid("{E67BE73D-F9AE-4ce1-8FEC-1880CB518CB4}")) //documents product
{
fireBaseUser = _firebaseDao.GetUserDeviceTokens(user.Id, msg.TenantId, PushConstants.PushDocAppName);
}
foreach (var fb in fireBaseUser)
{
if (fb.IsSubscribed.HasValue && fb.IsSubscribed.Value == true)
{
var m = new FirebaseAdminMessaging.Message()
{
Data = new Dictionary<string, string>{
{ "data", msg.Data }
},
Token = fb.FirebaseDeviceToken,
Notification = new FirebaseAdminMessaging.Notification()
{
Body = msg.Content
}
};
FirebaseAdminMessaging.FirebaseMessaging.DefaultInstance.SendAsync(m);
}
}
}
public FireBaseUser RegisterUserDevice(string fbDeviceToken, bool isSubscribed, string application)
{
var userId = _authContext.CurrentAccount.ID;
var tenantId = _tenantManager.GetCurrentTenant().Id;
return _firebaseDao.RegisterUserDevice(userId, tenantId, fbDeviceToken, isSubscribed, application);
}
public FireBaseUser UpdateUser(string fbDeviceToken, bool isSubscribed, string application)
{
var userId = _authContext.CurrentAccount.ID;
var tenantId = _tenantManager.GetCurrentTenant().Id;
return _firebaseDao.UpdateUser(userId, tenantId, fbDeviceToken, isSubscribed, application);
}
}

View File

@ -32,4 +32,6 @@ public static class PushConstants
public const string PushParentItemTagName = "PushParentItem";
public const string PushModuleTagName = "PushModule";
public const string PushActionTagName = "PushAction";
public const string PushDocAppName = "doc";
}

View File

@ -24,19 +24,22 @@
// 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 ASC.Core.Common.Notify.Push.Dao;
using Constants = ASC.Core.Configuration.Constants;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace ASC.Core.Common.Notify;
class PushSenderSink : Sink
{
private readonly ILogger<PushSenderSink> _logger;
private bool _configured = true;
private static readonly string _senderName = Constants.NotifyPushSenderSysName;
private readonly INotifySender _sender;
public PushSenderSink(IServiceProvider serviceProvider, ILogger<PushSenderSink> logger)
public PushSenderSink(INotifySender sender, IServiceProvider serviceProvider)
{
_sender = sender ?? throw new ArgumentNullException(nameof(sender));
_serviceProvider = serviceProvider;
_logger = logger;
}
private readonly IServiceProvider _serviceProvider;
@ -45,42 +48,21 @@ class PushSenderSink : Sink
{
try
{
var result = SendResult.OK;
using var scope = _serviceProvider.CreateScope();
var tenantManager = scope.ServiceProvider.GetService<TenantManager>();
var notification = new PushNotification
var m = scope.ServiceProvider.GetRequiredService<PushSenderSinkMessageCreator>().CreateNotifyMessage(message, _senderName);
if (string.IsNullOrEmpty(m.Reciever))
{
Module = GetTagValue<PushModule>(message, PushConstants.PushModuleTagName),
Action = GetTagValue<PushAction>(message, PushConstants.PushActionTagName),
Item = GetTagValue<PushItem>(message, PushConstants.PushItemTagName),
ParentItem = GetTagValue<PushItem>(message, PushConstants.PushParentItemTagName),
Message = message.Body,
ShortMessage = message.Subject
};
if (_configured)
{
try
{
using var pushClient = new PushServiceClient();
pushClient.EnqueueNotification(
tenantManager.GetCurrentTenant().Id,
message.Recipient.ID,
notification,
new List<string>());
}
catch (InvalidOperationException)
{
_configured = false;
_logger.DebugPushSender();
}
result = SendResult.IncorrectRecipient;
}
else
{
_logger.DebugPushSender();
_sender.Send(m);
}
return new SendResponse(message, Constants.NotifyPushSenderSysName, SendResult.OK);
return new SendResponse(message, Constants.NotifyPushSenderSysName, result);
}
catch (Exception error)
{
@ -95,3 +77,95 @@ class PushSenderSink : Sink
return tag != null ? (T)tag.Value : default;
}
}
public class LowerCaseNamingPolicy : JsonNamingPolicy
{
public override string ConvertName(string name) =>
name.ToLower();
}
[Scope]
public class PushSenderSinkMessageCreator : SinkMessageCreator
{
private readonly UserManager _userManager;
private readonly TenantManager _tenantManager;
public PushSenderSinkMessageCreator(UserManager userManager, TenantManager tenantManager)
{
_tenantManager = tenantManager;
_userManager = userManager;
}
public override NotifyMessage CreateNotifyMessage(INoticeMessage message, string senderName)
{
var tenant = _tenantManager.GetCurrentTenant(false);
if (tenant == null)
{
_tenantManager.SetCurrentTenant(Tenant.DefaultTenant);
tenant = _tenantManager.GetCurrentTenant(false);
}
var user = _userManager.GetUsers(new Guid(message.Recipient.ID));
var username = user.UserName;
var fromTag = message.Arguments.FirstOrDefault(x => x.Tag.Equals("MessageFrom"));
var productID = message.Arguments.FirstOrDefault(x => x.Tag.Equals("__ProductID"));
var originalUrl = message.Arguments.FirstOrDefault(x => x.Tag.Equals("DocumentURL"));
var folderId = message.Arguments.FirstOrDefault(x => x.Tag.Equals("FolderID"));
var rootFolderId = message.Arguments.FirstOrDefault(x => x.Tag.Equals("FolderParentId"));
var rootFolderType = message.Arguments.FirstOrDefault(x => x.Tag.Equals("FolderRootFolderType"));
var notifyData = new NotifyData()
{
Email = user.Email,
Portal = _tenantManager.GetCurrentTenant().TrustedDomains.FirstOrDefault(),
OriginalUrl = originalUrl != null && originalUrl.Value != null ? originalUrl.Value.ToString() : "",
Folder = new NotifyFolderData
{
Id = folderId != null && folderId.Value != null ? folderId.Value.ToString() : "",
ParentId = rootFolderId != null && rootFolderId.Value != null ? rootFolderId.Value.ToString() : "",
RootFolderType = rootFolderType != null && rootFolderType.Value != null ? (int)rootFolderType.Value : 0
},
};
var msg = (NoticeMessage)message;
if (msg.ObjectID.StartsWith("file_"))
{
var documentTitle = message.Arguments.FirstOrDefault(x => x.Tag.Equals("DocumentTitle"));
var documentExtension = message.Arguments.FirstOrDefault(x => x.Tag.Equals("DocumentExtension"));
notifyData.File = new NotifyFileData()
{
Id = msg.ObjectID.Substring(5),
Title = documentTitle != null && documentTitle.Value != null ? documentTitle.Value.ToString() : "",
Extension = documentExtension != null && documentExtension.Value != null ? documentExtension.Value.ToString() : ""
};
}
var serializeOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = new LowerCaseNamingPolicy(),
WriteIndented = true
};
var jsonNotifyData = JsonSerializer.Serialize(notifyData, serializeOptions);
var m = new NotifyMessage
{
TenantId = tenant.Id,
Reciever = username,
Subject = fromTag != null && fromTag.Value != null ? fromTag.Value.ToString() : message.Subject,
ContentType = message.ContentType,
Content = message.Body,
Sender = Constants.NotifyPushSenderSysName,
CreationDate = DateTime.UtcNow,
ProductID = fromTag != null && fromTag.Value != null ? productID.Value.ToString() : null,
Data = jsonNotifyData
};
return m;
}
}

View File

@ -0,0 +1,71 @@
// (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.Notify.Senders;
[Singletone(Additional = typeof(FirebaseSenderExtension))]
public class PushSender : INotifySender
{
private readonly ILogger _logger;
private readonly IServiceProvider _serviceProvider;
public PushSender(ILoggerProvider options, IServiceProvider serviceProvider)
{
_logger = options.CreateLogger("ASC.Notify");
_serviceProvider = serviceProvider;
}
public void Init(IDictionary<string, string> properties) { }
public NoticeSendResult Send(NotifyMessage m)
{
if (!string.IsNullOrEmpty(m.Content))
{
m.Content = m.Content.Replace("\r\n", "\n").Trim('\n', '\r', ' ');
m.Content = Regex.Replace(m.Content, "\n{3,}", "\n\n");
}
try
{
using var scope = _serviceProvider.CreateScope();
var FirebaseHelper = scope.ServiceProvider.GetService<FirebaseHelper>();
FirebaseHelper.SendMessage(m);
}
catch (Exception e)
{
_logger.ErrorUnexpected(e);
}
return NoticeSendResult.OK;
}
}
public static class FirebaseSenderExtension
{
public static void Register(DIHelper services)
{
services.TryAdd<FirebaseHelper>();
}
}

View File

@ -27,34 +27,6 @@
namespace ASC.Core.Tenants;
[Scope]
class ConfigureTenantUtil : IConfigureNamedOptions<TenantUtil>
{
private readonly IOptionsSnapshot<TenantManager> _tenantManager;
private readonly TimeZoneConverter _timeZoneConverter;
public ConfigureTenantUtil(
IOptionsSnapshot<TenantManager> tenantManager,
TimeZoneConverter timeZoneConverter
)
{
_tenantManager = tenantManager;
_timeZoneConverter = timeZoneConverter;
}
public void Configure(string name, TenantUtil options)
{
Configure(options);
options._tenantManager = _tenantManager.Get(name);
}
public void Configure(TenantUtil options)
{
options._timeZoneConverter = _timeZoneConverter;
options._tenantManager = _tenantManager.Value;
}
}
[Scope(typeof(ConfigureTenantUtil))]
public class TenantUtil
{
internal TenantManager _tenantManager;

View File

@ -33,20 +33,20 @@ public class EncryptionLoginProvider
private readonly SecurityContext _securityContext;
private readonly Signature _signature;
private readonly InstanceCrypto _instanceCrypto;
private readonly IOptionsSnapshot<AccountLinker> _snapshot;
private readonly AccountLinker _accountLinker;
public EncryptionLoginProvider(
ILogger<EncryptionLoginProvider> logger,
SecurityContext securityContext,
Signature signature,
InstanceCrypto instanceCrypto,
IOptionsSnapshot<AccountLinker> snapshot)
AccountLinker accountLinker)
{
_logger = logger;
_securityContext = securityContext;
_signature = signature;
_instanceCrypto = instanceCrypto;
_snapshot = snapshot;
_accountLinker = accountLinker;
}
@ -63,8 +63,7 @@ public class EncryptionLoginProvider
Name = _instanceCrypto.Encrypt(keys)
};
var linker = _snapshot.Get("webstudio");
linker.AddLink(userId.ToString(), loginProfile);
_accountLinker.AddLink(userId.ToString(), loginProfile);
}
public string GetKeys()
@ -74,8 +73,7 @@ public class EncryptionLoginProvider
public string GetKeys(Guid userId)
{
var linker = _snapshot.Get("webstudio");
var profile = linker.GetLinkedProfiles(userId.ToString(), ProviderConstants.Encryption).FirstOrDefault();
var profile = _accountLinker.GetLinkedProfiles(userId.ToString(), ProviderConstants.Encryption).FirstOrDefault();
if (profile == null)
{
return null;

View File

@ -58,6 +58,7 @@ builder.WebHost.ConfigureServices((hostContext, services) =>
services.AddBaseDbContext<FilesDbContext>();
services.AddBaseDbContext<NotifyDbContext>();
services.AddBaseDbContext<UrlShortenerFakeDbContext>();
services.AddBaseDbContext<FirebaseDbContext>();
});
var app = builder.Build();

View File

@ -45,6 +45,7 @@ builder.WebHost.ConfigureServices((hostContext, services) =>
services.AddBaseDbContext<TenantDbContext>();
services.AddBaseDbContext<UserDbContext>();
services.AddBaseDbContext<TelegramDbContext>();
services.AddBaseDbContext<FirebaseDbContext>();
services.AddBaseDbContext<CustomDbContext>();
services.AddBaseDbContext<WebstudioDbContext>();
services.AddBaseDbContext<InstanceRegistrationContext>();

View File

@ -161,9 +161,14 @@
}
},
"firebase": {
"projectId": "",
"privateKeyId": "",
"privateKey": "",
"clientEmail": "",
"clientId": "",
"x509CertUrl": "",
"apiKey": "",
"authDomain": "",
"projectId": "",
"storageBucket": "",
"messagingSenderId": "",
"appId": "",

View File

@ -0,0 +1,69 @@
// <auto-generated />
using System;
using ASC.Core.Common.EF.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace ASC.Migrations.MySql.Migrations.FirebaseDb
{
[DbContext(typeof(FirebaseDbContext))]
[Migration("20220823165923_FirebaseDbContextMigrate")]
partial class FirebaseDbContextMigrate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.FireBaseUser", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("id");
b.Property<string>("Application")
.HasColumnType("varchar(20)")
.HasColumnName("application")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("FirebaseDeviceToken")
.HasColumnType("varchar(255)")
.HasColumnName("firebase_device_token")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<bool?>("IsSubscribed")
.HasColumnType("tinyint(1)")
.HasColumnName("is_subscribed");
b.Property<int>("TenantId")
.HasColumnType("int")
.HasColumnName("tenant_id");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(36)")
.HasColumnName("user_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.HasKey("Id")
.HasName("PRIMARY");
b.HasIndex("TenantId", "UserId")
.HasDatabaseName("user_id");
b.ToTable("firebase_users", (string)null);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,48 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ASC.Migrations.MySql.Migrations.FirebaseDb
{
public partial class FirebaseDbContextMigrate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "firebase_users",
columns: table => new
{
id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
user_id = table.Column<string>(type: "varchar(36)", nullable: false, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
tenant_id = table.Column<int>(type: "int", nullable: false),
firebase_device_token = table.Column<string>(type: "varchar(255)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
application = table.Column<string>(type: "varchar(20)", nullable: true, collation: "utf8_general_ci")
.Annotation("MySql:CharSet", "utf8"),
is_subscribed = table.Column<bool>(type: "tinyint(1)", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PRIMARY", x => x.id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "user_id",
table: "firebase_users",
columns: new[] { "tenant_id", "user_id" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "firebase_users");
}
}
}

View File

@ -0,0 +1,67 @@
// <auto-generated />
using System;
using ASC.Core.Common.EF.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace ASC.Migrations.MySql.Migrations.FirebaseDb
{
[DbContext(typeof(FirebaseDbContext))]
partial class FirebaseDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("ASC.Core.Common.EF.FireBaseUser", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("id");
b.Property<string>("Application")
.HasColumnType("varchar(20)")
.HasColumnName("application")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<string>("FirebaseDeviceToken")
.HasColumnType("varchar(255)")
.HasColumnName("firebase_device_token")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.Property<bool?>("IsSubscribed")
.HasColumnType("tinyint(1)")
.HasColumnName("is_subscribed");
b.Property<int>("TenantId")
.HasColumnType("int")
.HasColumnName("tenant_id");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(36)")
.HasColumnName("user_id")
.UseCollation("utf8_general_ci")
.HasAnnotation("MySql:CharSet", "utf8");
b.HasKey("Id")
.HasName("PRIMARY");
b.HasIndex("TenantId", "UserId")
.HasDatabaseName("user_id");
b.ToTable("firebase_users", (string)null);
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,68 @@
// <auto-generated />
using System;
using ASC.Core.Common.EF.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ASC.Migrations.PostgreSql.Migrations.FirebaseDb
{
[DbContext(typeof(FirebaseDbContext))]
[Migration("20220823165923_FirebaseDbContextMigrate")]
partial class FirebaseDbContextMigrate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ASC.Core.Common.EF.FireBaseUser", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Application")
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasColumnName("application");
b.Property<string>("FirebaseDeviceToken")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("firebase_device_token");
b.Property<bool?>("IsSubscribed")
.HasColumnType("boolean")
.HasColumnName("is_subscribed");
b.Property<int>("TenantId")
.HasColumnType("integer")
.HasColumnName("tenant_id");
b.Property<Guid>("UserId")
.HasMaxLength(36)
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("firebase_users_pkey");
b.HasIndex("TenantId", "UserId")
.HasDatabaseName("user_id");
b.ToTable("firebase_users", "onlyoffice");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,48 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ASC.Migrations.PostgreSql.Migrations.FirebaseDb
{
public partial class FirebaseDbContextMigrate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.EnsureSchema(
name: "onlyoffice");
migrationBuilder.CreateTable(
name: "firebase_users",
schema: "onlyoffice",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
user_id = table.Column<Guid>(type: "uuid", maxLength: 36, nullable: false),
tenant_id = table.Column<int>(type: "integer", nullable: false),
firebase_device_token = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
application = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: true),
is_subscribed = table.Column<bool>(type: "boolean", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("firebase_users_pkey", x => x.id);
});
migrationBuilder.CreateIndex(
name: "user_id",
schema: "onlyoffice",
table: "firebase_users",
columns: new[] { "tenant_id", "user_id" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "firebase_users",
schema: "onlyoffice");
}
}
}

View File

@ -0,0 +1,66 @@
// <auto-generated />
using System;
using ASC.Core.Common.EF.Context;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace ASC.Migrations.PostgreSql.Migrations.FirebaseDb
{
[DbContext(typeof(FirebaseDbContext))]
partial class FirebaseDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "6.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
modelBuilder.Entity("ASC.Core.Common.EF.FireBaseUser", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Application")
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasColumnName("application");
b.Property<string>("FirebaseDeviceToken")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("firebase_device_token");
b.Property<bool?>("IsSubscribed")
.HasColumnType("boolean")
.HasColumnName("is_subscribed");
b.Property<int>("TenantId")
.HasColumnType("integer")
.HasColumnName("tenant_id");
b.Property<Guid>("UserId")
.HasMaxLength(36)
.HasColumnType("uuid")
.HasColumnName("user_id");
b.HasKey("Id")
.HasName("firebase_users_pkey");
b.HasIndex("TenantId", "UserId")
.HasDatabaseName("user_id");
b.ToTable("firebase_users", "onlyoffice");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -66,6 +66,7 @@
"i18next-express-middleware": "^2.0.0",
"i18next-fs-backend": "^1.1.4",
"morgan": "^1.10.0",
"nconf": "^0.12.0",
"utf-8-validate": "^5.0.9",
"winston": "^3.8.1",
"winston-daily-rotate-file": "^4.7.1"

View File

@ -1,3 +1,6 @@
{
"PORT": "5013"
"PORT": "5013",
"app": {
"appsettings": "../../../config"
}
}

View File

@ -0,0 +1,35 @@
import nconf from "nconf";
import path from "path";
import fs from "fs";
nconf.argv().env().file("config", path.join(__dirname, "config.json"));
getAndSaveAppsettings();
function getAndSaveAppsettings() {
let appsettings = nconf.get("app").appsettings;
if (!path.isAbsolute(appsettings)) {
appsettings = path.join(__dirname, appsettings);
}
const env = nconf.get("app").environment;
const valueEnv = nconf.get(env);
const fileWithEnv = path.join(
appsettings,
"appsettings." + valueEnv + ".json"
);
if (fs.existsSync(fileWithEnv)) {
nconf.file("appsettings", fileWithEnv);
} else {
nconf.file("appsettings", path.join(appsettings, "appsettings.json"));
}
nconf.file(
"appsettingsServices",
path.join(appsettings, "appsettings.services.json")
);
}
export default nconf;

View File

@ -2,19 +2,18 @@ import winston from "winston";
import "winston-daily-rotate-file";
import path from "path";
import fs from "fs";
import config from "../config";
let logpath = process.env.logpath || null;
let logPath = config.get("logPath");
if (logpath != null) {
if (!path.isAbsolute(logpath)) {
logpath = path.join(__dirname, "..", logpath);
if (logPath != null) {
if (!path.isAbsolute(logPath)) {
logPath = path.join(__dirname, "..", logPath);
}
}
const fileName = IS_DEVELOPMENT
? path.join(__dirname, "..", "..", "..", "Logs", "editor.%DATE%.log")
: logpath
? path.join(logpath, "editor.%DATE%.log")
const fileName = logPath
? path.join(logPath, "editor.%DATE%.log")
: path.join(__dirname, "..", "..", "..", "Logs", "editor.%DATE%.log");
const dirName = path.dirname(fileName);

View File

@ -35,6 +35,16 @@ public enum RoomType
CustomRoom = 5
}
public enum RoomFilterType
{
FillingFormsRoomOnly = 1,
EditingRoomOnly = 2,
ReviewRoomOnly = 3,
ReadOnlyRoomOnly = 4,
CustomRoomOnly = 5,
FoldersOnly = 6,
}
public class CreateRoomRequestDto
{
public string Title { get; set; }

View File

@ -176,7 +176,7 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
var filter = GetRoomTypeFilter(filterType);
var searchByTags = tags != null && tags.Any() && !withoutTags;
var searchByTypes = filterType != FilterType.None;
var searchByTypes = filterType != FilterType.None && filterType != FilterType.FoldersOnly;
var filesDbContext = _dbContextFactory.CreateDbContext();
var q = GetFolderQuery(filesDbContext, r => r.ParentId == parentId).AsNoTracking();
@ -206,7 +206,7 @@ internal class FolderDao : AbstractDao, IFolderDao<int>
var filter = GetRoomTypeFilter(filterType);
var searchByTags = tags != null && tags.Any() && !withoutTags;
var searchByTypes = filterType != FilterType.None;
var searchByTypes = filterType != FilterType.None && filterType != FilterType.FoldersOnly;
var filesDbContext = _dbContextFactory.CreateDbContext();
var q = GetFolderQuery(filesDbContext, f => roomsIds.Contains(f.Id)).AsNoTracking();

View File

@ -948,7 +948,7 @@ public class FileSecurity : IFileSecurity
foldersInt.AddRange(roomsEntries);
foldersString.AddRange(thirdPartyRoomsEntries);
if (withSubfolders)
if (withSubfolders && filterType != FilterType.FoldersOnly)
{
List<File<int>> files;
List<File<string>> thirdPartyFiles;
@ -980,7 +980,7 @@ public class FileSecurity : IFileSecurity
foldersInt.AddRange(roomsEntries);
foldersString.AddRange(thirdPartyRoomsEntries);
if (withSubfolders)
if (withSubfolders && filterType != FilterType.FoldersOnly)
{
List<File<int>> files;
List<File<string>> thirdPartyFiles;
@ -1063,7 +1063,7 @@ public class FileSecurity : IFileSecurity
entries.AddRange(fileEntries);
if (withSubfolders)
if (withSubfolders && filterType != FilterType.FoldersOnly)
{
List<File<T>> files;

View File

@ -428,7 +428,7 @@ internal abstract class ThirdPartyProviderDao<T> : ThirdPartyProviderDao, IDispo
protected IAsyncEnumerable<Folder<string>> FilterByRoomType(IAsyncEnumerable<Folder<string>> rooms, FilterType filterType)
{
if (filterType == FilterType.None)
if (filterType == FilterType.None || filterType == FilterType.FoldersOnly)
{
return rooms;
}

View File

@ -273,7 +273,7 @@ public class FilesLinkUtility
public string FileWebViewerUrlString
{
get { return FileWebEditorUrlString + "&" + Action + "=view"; }
get { return $"{FileWebEditorUrlString}&{Action}=view"; }
}
public string GetFileWebViewerUrlForMobile(object fileId, int fileVersion)
@ -296,10 +296,10 @@ public class FilesLinkUtility
public string FileWebEditorUrlString
{
get { return FilesBaseAbsolutePath + EditorPage + "?" + FileId + "={0}"; }
get { return $"/{EditorPage}?{FileId}={{0}}"; }
}
public string GetFileWebEditorUrl(object fileId, int fileVersion = 0)
public string GetFileWebEditorUrl<T>(T fileId, int fileVersion = 0)
{
return string.Format(FileWebEditorUrlString, HttpUtility.UrlEncode(fileId.ToString()))
+ (fileVersion > 0 ? "&" + Version + "=" + fileVersion : string.Empty);

View File

@ -61,7 +61,7 @@ namespace ASC.Files.Core.Services.NotifyService {
}
/// <summary>
/// Looks up a localized string similar to h1. All signers completed $DocumentTitle
/// Looks up a localized string similar to h1. All signers completed $DocumentTitle
///
///This is an email notification to inform you that all signers completed &quot;$DocumentTitle&quot;:&quot;$DocumentURL&quot;..
/// </summary>
@ -72,7 +72,7 @@ namespace ASC.Files.Core.Services.NotifyService {
}
/// <summary>
/// Looks up a localized string similar to h1. $Message: $DocumentTitle
/// Looks up a localized string similar to h1. $Message: $DocumentTitle
///
///Sign in to your DocuSign account for more information..
/// </summary>
@ -83,7 +83,7 @@ namespace ASC.Files.Core.Services.NotifyService {
}
/// <summary>
/// Looks up a localized string similar to h1. &quot;$__AuthorName&quot;:&quot;$__AuthorUrl&quot; mentioned you in the document comment
/// Looks up a localized string similar to h1. &quot;$__AuthorName&quot;:&quot;$__AuthorUrl&quot; mentioned you in the document comment
///
///This is a mail message to notify that you have been mentioned by &quot;$__AuthorName&quot;:&quot;$__AuthorUrl&quot; in the comment to the &quot;$DocumentTitle&quot;:&quot;$DocumentURL&quot; document:
///
@ -96,7 +96,7 @@ namespace ASC.Files.Core.Services.NotifyService {
}
/// <summary>
/// Looks up a localized string similar to h1. Mailing completed
/// Looks up a localized string similar to h1. Mailing completed
///
///This is an email notification to inform you that you have requested the mailing of $MailsCount messages and the process is now complete. $Message
///
@ -109,7 +109,7 @@ namespace ASC.Files.Core.Services.NotifyService {
}
/// <summary>
/// Looks up a localized string similar to h1. Access granted to document: &quot;$DocumentTitle&quot;:&quot;$DocumentURL&quot;
/// Looks up a localized string similar to h1. Access granted to document: &quot;$DocumentTitle&quot;:&quot;$DocumentURL&quot;
///
///$__DateTime &quot;$__AuthorName&quot;:&quot;$__AuthorUrl&quot; granted you the access to the &quot;$DocumentTitle&quot;:&quot;$DocumentURL&quot; document with the following access rights: &quot;$AccessRights&quot;.
///
@ -122,7 +122,7 @@ namespace ASC.Files.Core.Services.NotifyService {
}
/// <summary>
/// Looks up a localized string similar to h1. Access granted to folder: &quot;$DocumentTitle&quot;:&quot;$DocumentURL&quot;
/// Looks up a localized string similar to h1. Access granted to folder: &quot;$DocumentTitle&quot;:&quot;$DocumentURL&quot;
///
///$__DateTime &quot;$__AuthorName&quot;:&quot;$__AuthorUrl&quot; granted you the access to the &quot;$DocumentTitle&quot;:&quot;$DocumentURL&quot; folder with the following access rights: &quot;$AccessRights&quot;.
///
@ -159,6 +159,15 @@ namespace ASC.Files.Core.Services.NotifyService {
}
}
/// <summary>
/// Looks up a localized string similar to All signers completed $DocumentTitle.
/// </summary>
public static string subject_DocuSignComplete_push {
get {
return ResourceManager.GetString("subject_DocuSignComplete_push", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Documents. All signers completed [$DocumentTitle]($DocumentURL).
/// </summary>
@ -177,6 +186,15 @@ namespace ASC.Files.Core.Services.NotifyService {
}
}
/// <summary>
/// Looks up a localized string similar to Sign status changed.
/// </summary>
public static string subject_DocuSignStatus_push {
get {
return ResourceManager.GetString("subject_DocuSignStatus_push", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Documents. Mentioned in document.
/// </summary>
@ -186,6 +204,15 @@ namespace ASC.Files.Core.Services.NotifyService {
}
}
/// <summary>
/// Looks up a localized string similar to Mentioned in document.
/// </summary>
public static string subject_EditorMentions_push {
get {
return ResourceManager.GetString("subject_EditorMentions_push", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Documents. Mailing is complete..
/// </summary>
@ -195,6 +222,15 @@ namespace ASC.Files.Core.Services.NotifyService {
}
}
/// <summary>
/// Looks up a localized string similar to Mailing is complete..
/// </summary>
public static string subject_MailMergeEnd_push {
get {
return ResourceManager.GetString("subject_MailMergeEnd_push", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Documents. Access granted to document: $DocumentTitle.
/// </summary>
@ -204,6 +240,15 @@ namespace ASC.Files.Core.Services.NotifyService {
}
}
/// <summary>
/// Looks up a localized string similar to Documents. Access granted to document: [$DocumentTitle]($DocumentURL).
/// </summary>
public static string subject_ShareDocument_push {
get {
return ResourceManager.GetString("subject_ShareDocument_push", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Documents. Access granted to document: [$DocumentTitle]($DocumentURL).
/// </summary>
@ -213,6 +258,15 @@ namespace ASC.Files.Core.Services.NotifyService {
}
}
/// <summary>
/// Looks up a localized string similar to Access granted to the encrypted document: $DocumentTitle.
/// </summary>
public static string subject_ShareEncryptedDocument_push {
get {
return ResourceManager.GetString("subject_ShareEncryptedDocument_push", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Documents. Access granted to folder: $DocumentTitle.
/// </summary>
@ -222,6 +276,15 @@ namespace ASC.Files.Core.Services.NotifyService {
}
}
/// <summary>
/// Looks up a localized string similar to Access granted to folder: $DocumentTitle.
/// </summary>
public static string subject_ShareFolder_push {
get {
return ResourceManager.GetString("subject_ShareFolder_push", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Documents. Access granted to folder: [$DocumentTitle]($DocumentURL).
/// </summary>

View File

@ -127,4 +127,25 @@ $Message</value>
<data name="patterns" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>patterns.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="subject_ShareDocument_push" xml:space="preserve">
<value>Access granted to document: $DocumentTitle</value>
</data>
<data name="subject_DocuSignComplete_push" xml:space="preserve">
<value>All signers completed $DocumentTitle</value>
</data>
<data name="subject_DocuSignStatus_push" xml:space="preserve">
<value>Sign status changed</value>
</data>
<data name="subject_EditorMentions_push" xml:space="preserve">
<value>Mentioned in document</value>
</data>
<data name="subject_MailMergeEnd_push" xml:space="preserve">
<value>Mailing is complete.</value>
</data>
<data name="subject_ShareEncryptedDocument_push" xml:space="preserve">
<value>Access granted to the encrypted document: $DocumentTitle</value>
</data>
<data name="subject_ShareFolder_push" xml:space="preserve">
<value>Access granted to folder: $DocumentTitle</value>
</data>
</root>

View File

@ -143,6 +143,21 @@ public class NotifyClient
var url = fileEntry.FileEntryType == FileEntryType.File
? _filesLinkUtility.GetFileWebPreviewUrl(_fileUtility, fileEntry.Title, fileEntry.Id)
: await _pathProvider.GetFolderUrlAsync((Folder<T>)fileEntry);
Folder<T> folder;
var fileExtension = "";
if (fileEntry.FileEntryType == FileEntryType.File)
{
var file = (File<T>)fileEntry;
fileExtension = file.ConvertedExtension;
folder = await folderDao.GetFolderAsync(file.ParentId);
}
else
{
folder = (Folder<T>)fileEntry;
}
var recipientsProvider = _notifySource.GetRecipientsProvider();
@ -170,9 +185,14 @@ public class NotifyClient
true,
new TagValue(NotifyConstants.TagDocumentTitle, fileEntry.Title),
new TagValue(NotifyConstants.TagDocumentUrl, _baseCommonLinkUtility.GetFullAbsolutePath(url)),
new TagValue(NotifyConstants.TagDocumentExtension, fileExtension),
new TagValue(NotifyConstants.TagAccessRights, aceString),
new TagValue(NotifyConstants.TagMessage, message.HtmlEncode()),
TagValues.Image(_studioNotifyHelper, 0, "privacy.png")
new TagValue(NotifyConstants.TagFolderID, folder.Id),
new TagValue(NotifyConstants.TagFolderParentId, folder.RootId),
new TagValue(NotifyConstants.TagFolderRootFolderType, folder.RootFolderType),
TagValues.Image(_studioNotifyHelper, 0, "privacy.png"),
new AdditionalSenderTag("push.sender")
);
}
}
@ -201,7 +221,9 @@ public class NotifyClient
true,
new TagValue(NotifyConstants.TagDocumentTitle, file.Title),
new TagValue(NotifyConstants.TagDocumentUrl, _baseCommonLinkUtility.GetFullAbsolutePath(documentUrl)),
new TagValue(NotifyConstants.TagMessage, message.HtmlEncode())
new TagValue(NotifyConstants.TagMessage, message.HtmlEncode()),
new TagValue(NotifyConstants.TagFolderID, ((File<T>)file).ParentId),
new AdditionalSenderTag("push.sender")
);
}
}

View File

@ -43,8 +43,11 @@ public static class NotifyConstants
#region Tags
public static readonly string TagFolderID = "FolderID";
public static readonly string TagFolderParentId = "FolderParentId";
public static readonly string TagFolderRootFolderType = "FolderRootFolderType";
public static readonly string TagDocumentTitle = "DocumentTitle";
public static readonly string TagDocumentUrl = "DocumentURL";
public static readonly string TagDocumentExtension = "DocumentExtension";
public static readonly string TagAccessRights = "AccessRights";
public static readonly string TagMessage = "Message";
public static readonly string TagMailsCount = "MailsCount";

View File

@ -51,6 +51,10 @@ $Message
<subject resource="|subject_ShareDocument|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
<body styler="ASC.Notify.Textile.TextileStyler,ASC.Notify.Textile" resource="|pattern_ShareDocument|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
</pattern>
<pattern id="ShareDocument" sender="push.sender">
<subject></subject>
<body styler="ASC.Notify.Textile.PushStyler, ASC.Notify.Textile" resource="|subject_ShareDocument_push|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core"/>
</pattern>
<pattern id="ShareDocument" sender="messanger.sender">
<subject resource="|subject_ShareDocument|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
<body styler="ASC.Notify.Textile.JabberStyler, ASC.Notify.Textile">$__AuthorName
@ -77,6 +81,12 @@ $DocumentURL
<subject resource="|subject_ShareFolder|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
<body styler="ASC.Notify.Textile.TextileStyler,ASC.Notify.Textile" resource="|pattern_ShareFolder|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
</pattern>
<pattern id="ShareFolder" sender="push.sender">
<subject resource="|subject_ShareFolder|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
<body styler="ASC.Notify.Textile.PushStyler, ASC.Notify.Textile" resource="|subject_ShareFolder_push|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
</pattern>
<pattern id="ShareFolder" sender="messanger.sender">
<subject resource="|subject_ShareFolder|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
<body styler="ASC.Notify.Textile.JabberStyler, ASC.Notify.Textile">$__AuthorName
@ -102,6 +112,12 @@ $Message
<subject resource="|subject_EditorMentions|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
<body styler="ASC.Notify.Textile.TextileStyler,ASC.Notify.Textile" resource="|pattern_EditorMentions|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
</pattern>
<pattern id="EditorMentions" sender="push.sender">
<subject resource="|subject_EditorMentions|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
<body styler="ASC.Notify.Textile.PushStyler, ASC.Notify.Textile" resource="|subject_EditorMentions_push|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
</pattern>
<pattern id="EditorMentions" sender="messanger.sender">
<subject resource="|subject_EditorMentions|ASC.Files.Core.Services.NotifyService.FilesPatternResource,ASC.Files.Core" />
<body styler="ASC.Notify.Textile.JabberStyler, ASC.Notify.Textile">$__AuthorName

View File

@ -57,7 +57,7 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
private readonly SettingsManager _settingsManager;
private readonly PersonalSettingsHelper _personalSettingsHelper;
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
private readonly IOptionsSnapshot<AccountLinker> _snapshot;
private readonly AccountLinker _accountLinker;
private readonly SetupInfo _setupInfo;
private readonly TokenHelper _tokenHelper;
private readonly DocumentServiceConnector _documentServiceConnector;
@ -85,7 +85,7 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
SettingsManager settingsManager,
PersonalSettingsHelper personalSettingsHelper,
BaseCommonLinkUtility baseCommonLinkUtility,
IOptionsSnapshot<AccountLinker> snapshot,
AccountLinker accountLinker,
SetupInfo setupInfo,
TokenHelper tokenHelper,
DocumentServiceConnector documentServiceConnector,
@ -117,7 +117,7 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
_settingsManager = settingsManager;
_personalSettingsHelper = personalSettingsHelper;
_baseCommonLinkUtility = baseCommonLinkUtility;
_snapshot = snapshot;
_accountLinker = accountLinker;
_setupInfo = setupInfo;
_tokenHelper = tokenHelper;
_documentServiceConnector = documentServiceConnector;
@ -465,8 +465,7 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
private bool CurrentUser(string boxUserId)
{
var linkedProfiles = _snapshot.Get("webstudio")
.GetLinkedObjectsByHashId(HashHelper.MD5($"{ProviderConstants.Box}/{boxUserId}"));
var linkedProfiles = _accountLinker.GetLinkedObjectsByHashId(HashHelper.MD5($"{ProviderConstants.Box}/{boxUserId}"));
return linkedProfiles.Any(profileId => Guid.TryParse(profileId, out var tmp) && tmp == _authContext.CurrentAccount.ID);
}
@ -474,8 +473,8 @@ public class BoxApp : Consumer, IThirdPartyApp, IOAuthProvider
private void AddLinker(string boxUserId)
{
_logger.DebugBoxAppAddLinker(boxUserId);
var linker = _snapshot.Get("webstudio");
linker.AddLink(_authContext.CurrentAccount.ID.ToString(), boxUserId, ProviderConstants.Box);
_accountLinker.AddLink(_authContext.CurrentAccount.ID.ToString(), boxUserId, ProviderConstants.Box);
}
private UserInfo GetUserInfo(Token token, out bool isNew)

View File

@ -63,7 +63,7 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
private readonly BaseCommonLinkUtility _baseCommonLinkUtility;
private readonly FileUtility _fileUtility;
private readonly FilesSettingsHelper _filesSettingsHelper;
private readonly IOptionsSnapshot<AccountLinker> _snapshot;
private readonly AccountLinker _accountLinker;
private readonly SetupInfo _setupInfo;
private readonly GoogleLoginProvider _googleLoginProvider;
private readonly TokenHelper _tokenHelper;
@ -97,7 +97,7 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
ILogger<GoogleDriveApp> logger,
FileUtility fileUtility,
FilesSettingsHelper filesSettingsHelper,
IOptionsSnapshot<AccountLinker> snapshot,
AccountLinker accountLinker,
SetupInfo setupInfo,
GoogleLoginProvider googleLoginProvider,
TokenHelper tokenHelper,
@ -111,9 +111,9 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
ICacheNotify<ConsumerCacheItem> cache,
ConsumerFactory consumerFactory,
IHttpClientFactory clientFactory,
OAuth20TokenHelper oAuth20TokenHelper,
RequestHelper requestHelper,
ThirdPartySelector thirdPartySelector,
OAuth20TokenHelper oAuth20TokenHelper,
RequestHelper requestHelper,
ThirdPartySelector thirdPartySelector,
string name, int order, Dictionary<string, string> additional)
: base(tenantManager, coreBaseSettings, coreSettings, configuration, cache, consumerFactory, name, order, additional)
{
@ -135,7 +135,7 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
_baseCommonLinkUtility = baseCommonLinkUtility;
_fileUtility = fileUtility;
_filesSettingsHelper = filesSettingsHelper;
_snapshot = snapshot;
_accountLinker = accountLinker;
_setupInfo = setupInfo;
_googleLoginProvider = googleLoginProvider;
_tokenHelper = tokenHelper;
@ -618,8 +618,7 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
private bool CurrentUser(string googleId)
{
var linker = _snapshot.Get("webstudio");
var linkedProfiles = linker.GetLinkedObjectsByHashId(HashHelper.MD5($"{ProviderConstants.Google}/{googleId}"));
var linkedProfiles = _accountLinker.GetLinkedObjectsByHashId(HashHelper.MD5($"{ProviderConstants.Google}/{googleId}"));
return linkedProfiles.Any(profileId => Guid.TryParse(profileId, out var tmp) && tmp == _authContext.CurrentAccount.ID);
}
@ -627,8 +626,8 @@ public class GoogleDriveApp : Consumer, IThirdPartyApp, IOAuthProvider
private void AddLinker(string googleUserId)
{
_logger.DebugGoogleDriveApAddLinker(googleUserId);
var linker = _snapshot.Get("webstudio");
linker.AddLink(_authContext.CurrentAccount.ID.ToString(), googleUserId, ProviderConstants.Google);
_accountLinker.AddLink(_authContext.CurrentAccount.ID.ToString(), googleUserId, ProviderConstants.Google);
}
private UserInfo GetUserInfo(Token token, out bool isNew)

View File

@ -680,20 +680,21 @@ public class VirtualRoomsCommonController : ApiControllerBase
/// Virtual Rooms content
/// </returns>
[HttpGet("rooms")]
public async Task<FolderContentDto<int>> GetRoomsFolderAsync(RoomType? type, string subjectId, bool? searchInContent, bool? withSubfolders, SearchArea? searchArea, bool? withoutTags, string tags, bool? withoutMe)
public async Task<FolderContentDto<int>> GetRoomsFolderAsync(RoomFilterType? type, string subjectId, bool? searchInContent, bool? withSubfolders, SearchArea? searchArea, bool? withoutTags, string tags, bool? withoutMe)
{
ErrorIfNotDocSpace();
var parentId = searchArea != SearchArea.Archive ? await _globalFolderHelper.GetFolderVirtualRooms<int>()
: await _globalFolderHelper.GetFolderArchive<int>();
var filterType = type switch
var filter = type switch
{
RoomType.FillingFormsRoom => FilterType.FillingFormsRooms,
RoomType.ReadOnlyRoom => FilterType.ReadOnlyRooms,
RoomType.EditingRoom => FilterType.EditingRooms,
RoomType.ReviewRoom => FilterType.ReviewRooms,
RoomType.CustomRoom => FilterType.CustomRooms,
RoomFilterType.FillingFormsRoomOnly => FilterType.FillingFormsRooms,
RoomFilterType.ReadOnlyRoomOnly => FilterType.ReadOnlyRooms,
RoomFilterType.EditingRoomOnly => FilterType.EditingRooms,
RoomFilterType.ReviewRoomOnly => FilterType.ReviewRooms,
RoomFilterType.CustomRoomOnly => FilterType.CustomRooms,
RoomFilterType.FoldersOnly => FilterType.FoldersOnly,
_ => FilterType.None
};
@ -709,7 +710,7 @@ public class VirtualRoomsCommonController : ApiControllerBase
var count = Convert.ToInt32(_apiContext.Count);
var filterValue = _apiContext.FilterValue;
var content = await _fileStorageService.GetFolderItemsAsync(parentId, startIndex, count, filterType, false, subjectId, filterValue,
var content = await _fileStorageService.GetFolderItemsAsync(parentId, startIndex, count, filter, false, subjectId, filterValue,
searchInContent ?? false, withSubfolders ?? false, orderBy, searchArea ?? SearchArea.Active, withoutTags ?? false, tagNames, withoutMe ?? false);
var dto = await _folderContentDtoHelper.GetAsync(content, startIndex);

View File

@ -30,7 +30,7 @@ namespace ASC.People.Api;
public class ThirdpartyController : ApiControllerBase
{
private readonly IOptionsSnapshot<AccountLinker> _accountLinker;
private readonly AccountLinker _accountLinker;
private readonly CookiesManager _cookiesManager;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly DisplayUserSettingsHelper _displayUserSettingsHelper;
@ -52,7 +52,7 @@ public class ThirdpartyController : ApiControllerBase
private readonly StudioNotifyService _studioNotifyService;
public ThirdpartyController(
IOptionsSnapshot<AccountLinker> accountLinker,
AccountLinker accountLinker,
CookiesManager cookiesManager,
CoreBaseSettings coreBaseSettings,
DisplayUserSettingsHelper displayUserSettingsHelper,
@ -104,7 +104,7 @@ public class ThirdpartyController : ApiControllerBase
if (_authContext.IsAuthenticated)
{
linkedAccounts = _accountLinker.Get("webstudio").GetLinkedProfiles(_authContext.CurrentAccount.ID.ToString());
linkedAccounts = _accountLinker.GetLinkedProfiles(_authContext.CurrentAccount.ID.ToString());
}
fromOnly = string.IsNullOrWhiteSpace(fromOnly) ? string.Empty : fromOnly.ToLower();
@ -148,7 +148,7 @@ public class ThirdpartyController : ApiControllerBase
if (string.IsNullOrEmpty(profile.AuthorizationError))
{
GetLinker().AddLink(_securityContext.CurrentAccount.ID.ToString(), profile);
_accountLinker.AddLink(_securityContext.CurrentAccount.ID.ToString(), profile);
_messageService.Send(MessageAction.UserLinkedSocialAccount, GetMeaningfulProviderName(profile.Provider));
}
else
@ -204,7 +204,7 @@ public class ThirdpartyController : ApiControllerBase
SaveContactImage(userID, thirdPartyProfile.Avatar);
}
GetLinker().AddLink(userID.ToString(), thirdPartyProfile);
_accountLinker.AddLink(userID.ToString(), thirdPartyProfile);
}
finally
{
@ -232,7 +232,7 @@ public class ThirdpartyController : ApiControllerBase
[HttpDelete("thirdparty/unlinkaccount")]
public void UnlinkAccount(string provider)
{
GetLinker().RemoveProvider(_securityContext.CurrentAccount.ID.ToString(), provider);
_accountLinker.RemoveProvider(_securityContext.CurrentAccount.ID.ToString(), provider);
_messageService.Send(MessageAction.UserUnlinkedSocialAccount, GetMeaningfulProviderName(provider));
}
@ -262,11 +262,6 @@ public class ThirdpartyController : ApiControllerBase
return _userManagerWrapper.AddUser(userInfo, passwordHash, true, true, isVisitor, fromInviteLink);
}
private AccountLinker GetLinker()
{
return _accountLinker.Get("webstudio");
}
private void SaveContactImage(Guid userID, string url)
{
using (var memstream = new MemoryStream())

View File

@ -46,7 +46,7 @@ public class AuthenticationController : ControllerBase
private readonly SetupInfo _setupInfo;
private readonly MessageService _messageService;
private readonly ProviderManager _providerManager;
private readonly IOptionsSnapshot<AccountLinker> _accountLinker;
private readonly AccountLinker _accountLinker;
private readonly CoreBaseSettings _coreBaseSettings;
private readonly PersonalSettingsHelper _personalSettingsHelper;
private readonly StudioNotifyService _studioNotifyService;
@ -80,7 +80,7 @@ public class AuthenticationController : ControllerBase
SetupInfo setupInfo,
MessageService messageService,
ProviderManager providerManager,
IOptionsSnapshot<AccountLinker> accountLinker,
AccountLinker accountLinker,
CoreBaseSettings coreBaseSettings,
PersonalSettingsHelper personalSettingsHelper,
StudioNotifyService studioNotifyService,
@ -534,8 +534,7 @@ public class AuthenticationController : ControllerBase
}
}
var linker = _accountLinker.Get("webstudio");
linker.AddLink(userInfo.Id.ToString(), loginProfile);
_accountLinker.AddLink(userInfo.Id.ToString(), loginProfile);
return userInfo;
}
@ -581,7 +580,7 @@ public class AuthenticationController : ControllerBase
return false;
}
var linkedProfiles = _accountLinker.Get("webstudio").GetLinkedObjectsByHashId(hashId);
var linkedProfiles = _accountLinker.GetLinkedObjectsByHashId(hashId);
var tmp = Guid.Empty;
if (linkedProfiles.Any(profileId => Guid.TryParse(profileId, out tmp) && _userManager.UserExists(tmp)))
{

View File

@ -0,0 +1,66 @@
// (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 ASC.Web.Api.Controllers.Settings;
namespace ASC.Web.Api.Api.Settings;
public class PushController : BaseSettingsController
{
private readonly FirebaseHelper _firebaseHelper;
public PushController(
ApiContext apiContext,
WebItemManager webItemManager,
IMemoryCache memoryCache,
FirebaseHelper firebaseHelper,
IHttpContextAccessor httpContextAccessor
) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
{
_firebaseHelper = firebaseHelper;
}
/// <summary>
/// Saves a documents firebase device token specified in the request.
/// </summary>
/// <returns>FireBase user</returns>
[HttpPost("push/docregisterdevice")]
public FireBaseUser DocRegisterPusnNotificationDevice(FirebaseRequestsDto inDto)
{
return _firebaseHelper.RegisterUserDevice(inDto.FirebaseDeviceToken, inDto.IsSubscribed, PushConstants.PushDocAppName);
}
/// <summary>
/// Subscribe to documents push notification.
/// </summary>
/// <returns>FireBase user</returns>
[HttpPut("push/docsubscribe")]
public FireBaseUser SubscribeDocumentsPushNotification(FirebaseRequestsDto inDto)
{
return _firebaseHelper.UpdateUser(inDto.FirebaseDeviceToken, inDto.IsSubscribed, PushConstants.PushDocAppName);
}
}

View File

@ -58,6 +58,7 @@ public class SettingsController : BaseSettingsController
private readonly PasswordHasher _passwordHasher;
private readonly ILogger _log;
private readonly TelegramHelper _telegramHelper;
private readonly FirebaseHelper _firebaseHelper;
private readonly Constants _constants;
private readonly DnsSettings _dnsSettings;
private readonly AdditionalWhiteLabelSettingsHelper _additionalWhiteLabelSettingsHelper;
@ -91,6 +92,7 @@ public class SettingsController : BaseSettingsController
ProviderManager providerManager,
FirstTimeTenantSettings firstTimeTenantSettings,
TelegramHelper telegramHelper,
FirebaseHelper firebaseHelper,
UrlShortener urlShortener,
PasswordHasher passwordHasher,
Constants constants,
@ -126,6 +128,7 @@ public class SettingsController : BaseSettingsController
_passwordHasher = passwordHasher;
_urlShortener = urlShortener;
_telegramHelper = telegramHelper;
_firebaseHelper = firebaseHelper;
_constants = constants;
_dnsSettings = dnsSettings;
_additionalWhiteLabelSettingsHelper = additionalWhiteLabelSettingsHelper;
@ -705,5 +708,4 @@ public class SettingsController : BaseSettingsController
{
_telegramHelper.Disconnect(_authContext.CurrentAccount.ID, Tenant.Id);
}
}

View File

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

View File

@ -2211,6 +2211,7 @@ __metadata:
i18next-fs-backend: ^1.1.4
json-loader: ^0.5.7
morgan: ^1.10.0
nconf: ^0.12.0
nodemon: ^2.0.7
npm-run-all: ^4.1.5
sass: ^1.53.0
@ -7255,7 +7256,7 @@ __metadata:
languageName: node
linkType: hard
"async@npm:^3.2.3":
"async@npm:^3.0.0, async@npm:^3.2.3":
version: 3.2.4
resolution: "async@npm:3.2.4"
checksum: 43d07459a4e1d09b84a20772414aa684ff4de085cbcaec6eea3c7a8f8150e8c62aa6cd4e699fe8ee93c3a5b324e777d34642531875a0817a35697522c1b02e89
@ -14115,6 +14116,13 @@ __metadata:
languageName: node
linkType: hard
"ini@npm:^2.0.0":
version: 2.0.0
resolution: "ini@npm:2.0.0"
checksum: e7aadc5fb2e4aefc666d74ee2160c073995a4061556b1b5b4241ecb19ad609243b9cceafe91bae49c219519394bbd31512516cb22a3b1ca6e66d869e0447e84e
languageName: node
linkType: hard
"inline-style-parser@npm:0.1.1":
version: 0.1.1
resolution: "inline-style-parser@npm:0.1.1"
@ -17745,6 +17753,18 @@ __metadata:
languageName: node
linkType: hard
"nconf@npm:^0.12.0":
version: 0.12.0
resolution: "nconf@npm:0.12.0"
dependencies:
async: ^3.0.0
ini: ^2.0.0
secure-keys: ^1.0.0
yargs: ^16.1.1
checksum: 70c1ce82d91149940dbe57555372c99282a9625a961915b302093b34e04ab308d978d1885224b9738a0873c064a0aa48914a7260e67ba312441fc4917221dbd8
languageName: node
linkType: hard
"nearley@npm:^2.7.10":
version: 2.20.1
resolution: "nearley@npm:2.20.1"
@ -21852,6 +21872,13 @@ __metadata:
languageName: node
linkType: hard
"secure-keys@npm:^1.0.0":
version: 1.0.0
resolution: "secure-keys@npm:1.0.0"
checksum: 3dd4e64e6717fe6e2dc4c70e172982fcbad87b853e96566ab1cfaec540587f737bac106853ae469cb32d4a6413cfe80a28176cfe7dfcf7ddd35c9f92e58dffed
languageName: node
linkType: hard
"select-hose@npm:^2.0.0":
version: 2.0.0
resolution: "select-hose@npm:2.0.0"
@ -25739,7 +25766,7 @@ __metadata:
languageName: node
linkType: hard
"yargs@npm:16.2.0, yargs@npm:^16.2.0":
"yargs@npm:16.2.0, yargs@npm:^16.1.1, yargs@npm:^16.2.0":
version: 16.2.0
resolution: "yargs@npm:16.2.0"
dependencies: