Skip to content

Commit

Permalink
Merge pull request 'feature/removing-unused-portals' (#104) from feat…
Browse files Browse the repository at this point in the history
…ure/removing-unused-portals into develop
  • Loading branch information
pavelbannov committed Dec 13, 2024
2 parents 0a4b734 + f27cd41 commit 74465c6
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,16 @@ private static IQueryable<DbAuditEvent> FindByEntry(IQueryable<DbAuditEvent> q,
return q;
}

public async Task<DbAuditEvent> GetLastEventAsync(int tenantId)
{
await using var auditTrailContext = await dbContextFactory.CreateDbContextAsync();

return await auditTrailContext.AuditEvents
.Where(r => r.TenantId == tenantId)
.OrderByDescending(r => r.Id)
.FirstOrDefaultAsync();
}

public async Task<IEnumerable<int>> GetTenantsAsync(DateTime? from = null, DateTime? to = null)
{
await using var feedDbContext = await dbContextFactory.CreateDbContextAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,30 @@ orderby q.Date descending
}
return events;
}

public async Task<DbLoginEvent> GetLastSuccessEventAsync(int tenantId)
{
await using var auditTrailContext = await dbContextFactory.CreateDbContextAsync();

var successLoginEvents = new List<int>() {
(int)MessageAction.LoginSuccess,
(int)MessageAction.LoginSuccessViaSocialAccount,
(int)MessageAction.LoginSuccessViaSms,
(int)MessageAction.LoginSuccessViaApi,
(int)MessageAction.LoginSuccessViaSocialApp,
(int)MessageAction.LoginSuccessViaApiSms,
(int)MessageAction.LoginSuccessViaSSO,
(int)MessageAction.LoginSuccessViaApiSocialAccount,
(int)MessageAction.LoginSuccesViaTfaApp,
(int)MessageAction.LoginSuccessViaApiTfa,

(int)MessageAction.Logout,
};

return await auditTrailContext.LoginEvents
.Where(r => r.TenantId == tenantId)
.Where(r => successLoginEvents.Contains(r.Action ?? 0))
.OrderByDescending(r => r.Id)
.FirstOrDefaultAsync();
}
}
1 change: 1 addition & 0 deletions web/ASC.Web.Core/Notify/Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public static class Actions
public static readonly INotifyAction EnterpriseAdminUserDocsTipsV1 = new NotifyAction("enterprise_admin_user_docs_tips_v1");

public static readonly INotifyAction SaasAdminTrialWarningAfterHalfYearV1 = new NotifyAction("saas_admin_trial_warning_after_half_year_v1");
public static readonly INotifyAction SaasAdminStartupWarningAfterYearV1 = new NotifyAction("saas_admin_startup_warning_after_year_v1");

public static readonly INotifyAction PortalDeleteSuccessV1 = new NotifyAction("portal_delete_success_v1");

Expand Down
1 change: 1 addition & 0 deletions web/ASC.Web.Core/Notify/StudioNotifySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ protected override IActionProvider CreateActionProvider()
Actions.EnterpriseAdminUserDocsTipsV1,

Actions.SaasAdminTrialWarningAfterHalfYearV1,
Actions.SaasAdminStartupWarningAfterYearV1,

Actions.PortalDeleteSuccessV1,

Expand Down
92 changes: 63 additions & 29 deletions web/ASC.Web.Core/Notify/StudioPeriodicNotify.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@ public class StudioPeriodicNotify(ILoggerProvider log,
DisplayUserSettingsHelper displayUserSettingsHelper,
CoreSettings coreSettings,
IServiceProvider serviceProvider,
AuditEventsRepository auditEventsRepository,
LoginEventsRepository loginEventsRepository,
IDistributedCache distributedCache,
IEventBus eventBus)
{
private readonly ILogger _log = log.CreateLogger("ASC.Notify");

private const string CacheKey = "notification_date_for_unused_portals";

public async ValueTask SendSaasLettersAsync(string senderName, DateTime scheduleDate)
{
_log.InformationStartSendSaasTariffLetters();
Expand All @@ -60,6 +65,19 @@ public async ValueTask SendSaasLettersAsync(string senderName, DateTime schedule
}

var nowDate = scheduleDate.Date;
var startDateToNotifyUnusedPortals = nowDate;

var cacheValue = await distributedCache.GetStringAsync(CacheKey);
if (string.IsNullOrEmpty(cacheValue))
{
await distributedCache.SetStringAsync(CacheKey, JsonSerializer.Serialize(startDateToNotifyUnusedPortals));
}
else
{
startDateToNotifyUnusedPortals = JsonSerializer.Deserialize<DateTime>(cacheValue);
}

var startDateToRemoveUnusedPortals = startDateToNotifyUnusedPortals.AddDays(7);

foreach (var tenant in activeTenants)
{
Expand Down Expand Up @@ -115,7 +133,7 @@ public async ValueTask SendSaasLettersAsync(string senderName, DateTime schedule
{
#region After registration letters

#region 1 days after registration to admins SAAS TRIAL
#region 1 days after registration to admins SAAS Free

if (createdDate.AddDays(1) == nowDate)
{
Expand All @@ -132,7 +150,7 @@ public async ValueTask SendSaasLettersAsync(string senderName, DateTime schedule

#endregion

#region 4 days after registration to admins SAAS TRIAL
#region 4 days after registration to admins SAAS Free

if (createdDate.AddDays(4) == nowDate)
{
Expand All @@ -154,10 +172,9 @@ public async ValueTask SendSaasLettersAsync(string senderName, DateTime schedule
trulyYoursAsTebleRow = true;
}


#endregion

#region 7 days after registration to admins and users SAAS TRIAL
#region 7 days after registration to admins and users SAAS Free

else if (createdDate.AddDays(7) == nowDate)
{
Expand All @@ -180,6 +197,8 @@ public async ValueTask SendSaasLettersAsync(string senderName, DateTime schedule

#endregion

#region 10 days after registration to admins SAAS Free

else if (createdDate.AddDays(10) == nowDate)
{
action = Actions.SaasAdminIntegrations;
Expand Down Expand Up @@ -210,7 +229,9 @@ public async ValueTask SendSaasLettersAsync(string senderName, DateTime schedule
trulyYoursAsTebleRow = true;
}

#region 14 days after registration to admins and users SAAS TRIAL
#endregion

#region 14 days after registration to admins and users SAAS Free

else if (createdDate.AddDays(14) == nowDate)
{
Expand All @@ -233,36 +254,49 @@ public async ValueTask SendSaasLettersAsync(string senderName, DateTime schedule

#endregion

#region 6 months after SAAS TRIAL expired
#region 1 year whithout activity to owner SAAS Free

else if (dueDateIsNotMax && dueDate.AddMonths(6) == nowDate)
else if (nowDate.Day == tenant.CreationDateTime.Day || nowDate.AddDays(-7).Day == tenant.CreationDateTime.Day)
{
action = Actions.SaasAdminTrialWarningAfterHalfYearV1;
toowner = true;

orangeButtonText = c => WebstudioNotifyPatternResource.ResourceManager.GetString("ButtonLeaveFeedback", c);

var owner = await userManager.GetUsersAsync(tenant.OwnerId);
orangeButtonUrl = setupInfo.TeamlabSiteRedirect + "/remove-portal-feedback-form.aspx#" +
HttpUtility.UrlEncode(Convert.ToBase64String(
Encoding.UTF8.GetBytes("{\"firstname\":\"" + owner.FirstName +
"\",\"lastname\":\"" + owner.LastName +
"\",\"alias\":\"" + tenant.Alias +
"\",\"email\":\"" + owner.Email + "\"}")));

topGif = studioNotifyHelper.GetNotificationImageUrl("docspace_deleted.gif");
var lastAuditEvent = await auditEventsRepository.GetLastEventAsync(tenant.Id);
var lastAuditEventDate = lastAuditEvent != null ? lastAuditEvent.Date.Date : tenant.CreationDateTime.Date;

trulyYoursAsTebleRow = true;
}
else if (dueDateIsNotMax && dueDate.AddMonths(6).AddDays(7) <= nowDate)
{
await tenantManager.RemoveTenantAsync(tenant.Id, true);
var lastLoginEvent = await loginEventsRepository.GetLastSuccessEventAsync(tenant.Id);
var lastLoginEventDate = lastLoginEvent != null ? lastLoginEvent.Date.Date : tenant.CreationDateTime.Date;

if (!coreBaseSettings.Standalone && apiSystemHelper.ApiCacheEnable)
if ((lastAuditEventDate > lastLoginEventDate ? lastAuditEventDate : lastLoginEventDate).AddYears(1) <= nowDate)
{
await apiSystemHelper.RemoveTenantFromCacheAsync(tenant.GetTenantDomain(coreSettings));
if (nowDate >= startDateToNotifyUnusedPortals && nowDate.Day == tenant.CreationDateTime.Day)
{
action = Actions.SaasAdminStartupWarningAfterYearV1;
toowner = true;

orangeButtonText = c => WebstudioNotifyPatternResource.ResourceManager.GetString("ButtonLeaveFeedback", c);

var owner = await userManager.GetUsersAsync(tenant.OwnerId);
orangeButtonUrl = setupInfo.TeamlabSiteRedirect + "/remove-portal-feedback-form.aspx#" +
HttpUtility.UrlEncode(Convert.ToBase64String(
Encoding.UTF8.GetBytes("{\"firstname\":\"" + owner.FirstName +
"\",\"lastname\":\"" + owner.LastName +
"\",\"alias\":\"" + tenant.Alias +
"\",\"email\":\"" + owner.Email + "\"}")));

topGif = studioNotifyHelper.GetNotificationImageUrl("docspace_deleted.gif");

trulyYoursAsTebleRow = true;
}

if (nowDate >= startDateToRemoveUnusedPortals && nowDate.AddDays(-7).Day == tenant.CreationDateTime.Day)
{
await tenantManager.RemoveTenantAsync(tenant.Id, true);

if (!coreBaseSettings.Standalone && apiSystemHelper.ApiCacheEnable)
{
await apiSystemHelper.RemoveTenantFromCacheAsync(tenant.GetTenantDomain(coreSettings));
}
await eventBus.PublishAsync(new RemovePortalIntegrationEvent(Guid.Empty, tenant.Id));
}
}
await eventBus.PublishAsync(new RemovePortalIntegrationEvent(Guid.Empty, tenant.Id));
}

#endregion
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1130,7 +1130,7 @@ ONLYOFFICE աջակցման թիմ

* Կարևոր! Ձեր պորտալում պահվող բոլոր տվյալները, ինչպես նաև գրանցման տվյալները կկորչեն և չեն կարող վերականգնվել:*

#if ($AutoRenew == "Ճիշտ է")
#if ($AutoRenew == "True")
Նախքան պորտալը ջնջելը, համոզվեք, որ ավտոմատ վճարումն անջատված է: Դուք կարող եք ստուգել ավտոմատ վճարման կարգավիճակը ձեր "Avangate հաշվում":"https://secure.avangate.com/myaccount/":
#end

Expand Down Expand Up @@ -1322,7 +1322,7 @@ $TrulyYours</value>

_Կարևոր! Ձեր պորտալում պահվող բոլոր տվյալները, ինչպես նաև գրանցման տվյալները կկորչեն և չեն կարող վերականգնվել:_

#if($AutoRenew == "Ճիշտ է")
#if($AutoRenew == "True")
Նախքան պորտալը ջնջելը, համոզվեք, որ ավտոմատ վճարումն անջատված է: Դուք կարող եք ստուգել ավտոմատ վճարման կարգավիճակը ձեր [Avangate հաշվում] (https://secure.avangate.com/myaccount/"):
#end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2790,4 +2790,33 @@ If you need help, browse our "Help Center":"${__HelpLink}" or ask our "support t

$TrulyYours</comment>
</data>
<data name="pattern_saas_admin_startup_warning_after_year_v1" xml:space="preserve">
<value>&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;&lt;td class="fol" style="font-family: 'Open Sans', Helvetica, Arial, Tahoma, sans-serif; font-size: 24px; font-weight: 700; line-height: 1.33em; letter-spacing: -0.02em; Margin: 0; padding: 0 40px 32px; text-align: center;"&gt;Your ONLYOFFICE DocSpace will be &lt;span style="color: #FF6F3D;"&gt;deleted&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;&lt;td class="fol" style="font-family: 'Open Sans', Helvetica, Arial, Tahoma, sans-serif; font-size: 14px; line-height: 21px; Margin: 0; padding-left: 40px; padding-right: 40px; padding-bottom: 8px; text-align: center;"&gt;Your ONLYOFFICE DocSpace &lt;a href="${__VirtualRootPath}" style="color: #FF6F3D"&gt;${__VirtualRootPath}&lt;/a&gt; has been inactive for more than a year.&lt;/td&gt;&lt;/tr&gt;

&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;&lt;td class="fol" style="font-family: 'Open Sans', Helvetica, Arial, Tahoma, sans-serif; font-size: 14px; line-height: 21px; Margin: 0; padding-left: 40px; padding-right: 40px; padding-bottom: 32px; text-align: center;"&gt;Since you have decided not to use it anymore, your ONLYOFFICE DocSpace and all the data will be deleted in accordance with our &lt;a style="color: #FF6F3D; text-decoration: underline;" target="_blank" href="https://help.onlyoffice.com/products/files/doceditor.aspx?fileid=5048502&amp;doc=SXhWMEVzSEYxNlVVaXJJeUVtS0kyYk14YWdXTEFUQmRWL250NllHNUFGbz0_IjUwNDg1MDIi0"&gt;Privacy Policy&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;

&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;&lt;td class="fol" style="font-family: 'Open Sans', Helvetica, Arial, Tahoma, sans-serif; Margin: 0; padding-left: 40px; padding-right: 40px; padding-bottom: 32px; text-align: center;"&gt;&lt;table cellspacing="0" cellpadding="0" background="#ffffff" style="background-color: #ffffff; border: 0 none; border-spacing: 0; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; empty-cells: show; height: 0px; Margin: 0 auto; max-width: 520px; padding: 0; vertical-align: top; width: 100%; text-align: left; border: 1px solid #FF6F3D; border-radius: 8px;"&gt;&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;&lt;td class="fol" style="font-family: 'Open Sans', Helvetica, Arial, Tahoma, sans-serif; font-size: 14px; line-height: 22px; Margin: 0; padding-left: 40px; padding-right: 40px; padding-top: 32px; padding-bottom: 24px; text-align: center;"&gt;We would appreciate your feedback. Why have you decided to stop using ONLYOFFICE DocSpace?&lt;/td&gt;&lt;/tr&gt;&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;&lt;td style="font-family: 'Open Sans', Helvetica, Arial, Tahoma; font-size: 16px; font-weight: bold; line-height: 22px; Margin: 0; padding-bottom: 32px; padding-top: 0; text-align: center;"&gt;$OrangeButton&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr border="0" cellspacing="0" cellpadding="0"&gt;&lt;td class="fol" style="font-family: 'Open Sans', Helvetica, Arial, Tahoma, sans-serif; font-size: 13px; line-height: 20px; Margin: 0; padding-left: 40px; padding-right: 40px; padding-bottom: 32px; text-align: center;"&gt;If you want to continue using your ONLYOFFICE DocSpace, just enter it and make any action.&lt;/td&gt;&lt;/tr&gt;

$TrulyYours</value>
<comment>Your ONLYOFFICE DocSpace will be deleted

Your ONLYOFFICE DocSpace ${__VirtualRootPath} has been inactive for more than a year.

Since you have decided not to use it anymore, your ONLYOFFICE DocSpace and all the data will be deleted in accordance with our Privacy Policy.

We would appreciate your feedback. Why have you decided to stop using ONLYOFFICE DocSpace?

$OrangeButton

If you want to continue using your ONLYOFFICE DocSpace, just enter it and make any action.

$TrulyYours</comment>
</data>
<data name="subject_saas_admin_startup_warning_after_year_v1" xml:space="preserve">
<value>Your ONLYOFFICE DocSpace will be deleted</value>
</data>
</root>
Loading

0 comments on commit 74465c6

Please sign in to comment.