diff --git a/Notesnook.API/Helpers/StorageHelper.cs b/Notesnook.API/Helpers/StorageHelper.cs
index 4ea49bf..1f0aee0 100644
--- a/Notesnook.API/Helpers/StorageHelper.cs
+++ b/Notesnook.API/Helpers/StorageHelper.cs
@@ -52,6 +52,17 @@ namespace Notesnook.API.Helpers
return fileSize > maxFileSize;
}
+ public static Limit RolloverStorageLimit(Limit? limit)
+ {
+ var updatedAt = DateTimeOffset.FromUnixTimeMilliseconds(limit?.UpdatedAt ?? 0);
+ if (limit == null || DateTimeOffset.UtcNow.Year > updatedAt.Year || DateTimeOffset.UtcNow.Month > updatedAt.Month)
+ {
+ limit = new Limit { UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), Value = 0 };
+ return limit;
+ }
+ return limit;
+ }
+
private static readonly string[] sizes = ["B", "KB", "MB", "GB", "TB"];
public static string FormatBytes(long size)
{
diff --git a/Notesnook.API/Models/UserSettings.cs b/Notesnook.API/Models/UserSettings.cs
index e6cfaa6..ef817a6 100644
--- a/Notesnook.API/Models/UserSettings.cs
+++ b/Notesnook.API/Models/UserSettings.cs
@@ -17,6 +17,7 @@ You should have received a copy of the Affero GNU General Public License
along with this program. If not, see .
*/
+using System;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using Notesnook.API.Interfaces;
@@ -25,8 +26,21 @@ namespace Notesnook.API.Models
{
public class Limit
{
- public long Value { get; set; }
- public long UpdatedAt { get; set; }
+ private long _value = 0;
+ public long Value
+ {
+ get => _value;
+ set
+ {
+ _value = value;
+ UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
+ }
+ }
+ public long UpdatedAt
+ {
+ get;
+ set;
+ }
}
public class UserSettings
diff --git a/Notesnook.API/Services/S3Service.cs b/Notesnook.API/Services/S3Service.cs
index 7d657c1..a9e6b30 100644
--- a/Notesnook.API/Services/S3Service.cs
+++ b/Notesnook.API/Services/S3Service.cs
@@ -239,7 +239,7 @@ namespace Notesnook.API.Services
await this.AbortMultipartUploadAsync(userId, uploadRequest.Key, uploadRequest.UploadId);
throw new Exception("User settings not found.");
}
- userSettings.StorageLimit ??= new Limit { Value = 0, UpdatedAt = 0 };
+ userSettings.StorageLimit ??= StorageHelper.RolloverStorageLimit(userSettings.StorageLimit);
if (!Constants.IS_SELF_HOSTED)
{
@@ -268,8 +268,11 @@ namespace Notesnook.API.Services
if (!Constants.IS_SELF_HOSTED)
{
- userSettings.StorageLimit.UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == userId);
+ await Repositories.UsersSettings.Collection.UpdateOneAsync(
+ Builders.Filter.Eq(u => u.UserId, userId),
+ Builders.Update.Set(u => u.StorageLimit, userSettings.StorageLimit)
+ );
}
}
diff --git a/Notesnook.API/Services/UserService.cs b/Notesnook.API/Services/UserService.cs
index 60f8da3..5d55bc7 100644
--- a/Notesnook.API/Services/UserService.cs
+++ b/Notesnook.API/Services/UserService.cs
@@ -24,6 +24,7 @@ using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
+using MongoDB.Driver;
using Notesnook.API.Helpers;
using Notesnook.API.Interfaces;
using Notesnook.API.Models;
@@ -115,10 +116,14 @@ namespace Notesnook.API.Services
var userSettings = await Repositories.UsersSettings.FindOneAsync((u) => u.UserId == user.UserId) ?? throw new Exception("User settings not found.");
// reset user's attachment limit every month
- if (userSettings.StorageLimit == null || DateTimeOffset.UtcNow.Month > DateTimeOffset.FromUnixTimeMilliseconds(userSettings.StorageLimit.UpdatedAt).Month)
+ var limit = StorageHelper.RolloverStorageLimit(userSettings.StorageLimit);
+ if (userSettings.StorageLimit == null || limit.UpdatedAt != userSettings.StorageLimit?.UpdatedAt)
{
- userSettings.StorageLimit ??= new Limit { UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), Value = 0 };
- await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == user.UserId);
+ userSettings.StorageLimit = limit;
+ await Repositories.UsersSettings.Collection.UpdateOneAsync(
+ Builders.Filter.Eq(u => u.UserId, user.UserId),
+ Builders.Update.Set(u => u.StorageLimit, userSettings.StorageLimit)
+ );
}
return new UserResponse