From 1ecd8adee1971b75057bc0bdd9d626e8e9dbbb33 Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Thu, 9 Oct 2025 14:13:11 +0500 Subject: [PATCH] s3: fix attachments not uploading on self hosted servers this was due to s3 endpoints requesting user's subscription which didn't exist in case of self hosted setups --- .../Controllers/AnnouncementController.cs | 4 +- Notesnook.API/Controllers/S3Controller.cs | 36 ++++++++++------- Notesnook.API/Services/S3Service.cs | 40 +++++++++++-------- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/Notesnook.API/Controllers/AnnouncementController.cs b/Notesnook.API/Controllers/AnnouncementController.cs index 9e5f904..9b138ed 100644 --- a/Notesnook.API/Controllers/AnnouncementController.cs +++ b/Notesnook.API/Controllers/AnnouncementController.cs @@ -42,10 +42,10 @@ namespace Notesnook.API.Controllers [HttpGet("active")] [AllowAnonymous] - public async Task GetActiveAnnouncements([FromQuery] string userId) + public async Task GetActiveAnnouncements([FromQuery] string? userId) { var totalActive = await Announcements.Collection.CountDocumentsAsync(Builders.Filter.Eq("IsActive", true)); - if (totalActive <= 0) return Ok(new Announcement[] { }); + if (totalActive <= 0) return Ok(Array.Empty()); var announcements = (await Announcements.FindAsync((a) => a.IsActive)).Where((a) => a.UserIds == null || a.UserIds.Length == 0 || a.UserIds.Contains(userId)); foreach (var announcement in announcements) diff --git a/Notesnook.API/Controllers/S3Controller.cs b/Notesnook.API/Controllers/S3Controller.cs index 39a0f09..eaab871 100644 --- a/Notesnook.API/Controllers/S3Controller.cs +++ b/Notesnook.API/Controllers/S3Controller.cs @@ -63,20 +63,23 @@ namespace Notesnook.API.Controllers return Ok(uploadUrl); } - var subscriptionService = await WampServers.SubscriptionServer.GetServiceAsync(SubscriptionServerTopics.UserSubscriptionServiceTopic); - var subscription = await subscriptionService.GetUserSubscriptionAsync(Clients.Notesnook.Id, userId); - if (subscription is null) return BadRequest(new { error = "User subscription not found." }); - - if (StorageHelper.IsFileSizeExceeded(subscription, fileSize)) - { - return BadRequest(new { error = "Max file size exceeded." }); - } - var userSettings = await Repositories.UsersSettings.FindOneAsync((u) => u.UserId == userId); - userSettings.StorageLimit ??= new Limit { Value = 0, UpdatedAt = 0 }; - userSettings.StorageLimit.Value += fileSize; - if (StorageHelper.IsStorageLimitReached(subscription, userSettings.StorageLimit)) - return BadRequest(new { error = "Storage limit exceeded." }); + if (!Constants.IS_SELF_HOSTED) + { + var subscriptionService = await WampServers.SubscriptionServer.GetServiceAsync(SubscriptionServerTopics.UserSubscriptionServiceTopic); + var subscription = await subscriptionService.GetUserSubscriptionAsync(Clients.Notesnook.Id, userId); + if (subscription is null) return BadRequest(new { error = "User subscription not found." }); + + if (StorageHelper.IsFileSizeExceeded(subscription, fileSize)) + { + return BadRequest(new { error = "Max file size exceeded." }); + } + + userSettings.StorageLimit ??= new Limit { Value = 0, UpdatedAt = 0 }; + userSettings.StorageLimit.Value += fileSize; + if (StorageHelper.IsStorageLimitReached(subscription, userSettings.StorageLimit)) + return BadRequest(new { error = "Storage limit exceeded." }); + } var url = S3Service.GetUploadObjectUrl(userId, name); if (url == null) return BadRequest(new { error = "Could not create signed url." }); @@ -87,8 +90,11 @@ namespace Notesnook.API.Controllers var response = await httpClient.SendRequestAsync(url, null, HttpMethod.Put, content); if (!response.Success) return BadRequest(await response.Content.ReadAsStringAsync()); - userSettings.StorageLimit.UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == userId); + if (!Constants.IS_SELF_HOSTED) + { + userSettings.StorageLimit.UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == userId); + } return Ok(response); } diff --git a/Notesnook.API/Services/S3Service.cs b/Notesnook.API/Services/S3Service.cs index d940d1b..ebe1cd0 100644 --- a/Notesnook.API/Services/S3Service.cs +++ b/Notesnook.API/Services/S3Service.cs @@ -229,16 +229,6 @@ namespace Notesnook.API.Services var objectName = GetFullObjectName(userId, uploadRequest.Key); if (userId == null || objectName == null) throw new Exception("Could not abort multipart upload."); - var subscriptionService = await WampServers.SubscriptionServer.GetServiceAsync(SubscriptionServerTopics.UserSubscriptionServiceTopic); - var subscription = await subscriptionService.GetUserSubscriptionAsync(Clients.Notesnook.Id, userId) ?? throw new Exception("User subscription not found."); - - long fileSize = await GetMultipartUploadSizeAsync(userId, uploadRequest.Key, uploadRequest.UploadId); - if (StorageHelper.IsFileSizeExceeded(subscription, fileSize)) - { - await this.AbortMultipartUploadAsync(userId, uploadRequest.Key, uploadRequest.UploadId); - throw new Exception("Max file size exceeded."); - } - var userSettings = await Repositories.UsersSettings.FindOneAsync((u) => u.UserId == userId); if (userSettings == null) { @@ -246,12 +236,25 @@ namespace Notesnook.API.Services throw new Exception("User settings not found."); } - userSettings.StorageLimit ??= new Limit { Value = 0, UpdatedAt = 0 }; - userSettings.StorageLimit.Value += fileSize; - if (StorageHelper.IsStorageLimitReached(subscription, userSettings.StorageLimit)) + if (!Constants.IS_SELF_HOSTED) { - await this.AbortMultipartUploadAsync(userId, uploadRequest.Key, uploadRequest.UploadId); - throw new Exception("Storage limit reached."); + var subscriptionService = await WampServers.SubscriptionServer.GetServiceAsync(SubscriptionServerTopics.UserSubscriptionServiceTopic); + var subscription = await subscriptionService.GetUserSubscriptionAsync(Clients.Notesnook.Id, userId) ?? throw new Exception("User subscription not found."); + + long fileSize = await GetMultipartUploadSizeAsync(userId, uploadRequest.Key, uploadRequest.UploadId); + if (StorageHelper.IsFileSizeExceeded(subscription, fileSize)) + { + await this.AbortMultipartUploadAsync(userId, uploadRequest.Key, uploadRequest.UploadId); + throw new Exception("Max file size exceeded."); + } + + userSettings.StorageLimit ??= new Limit { Value = 0, UpdatedAt = 0 }; + userSettings.StorageLimit.Value += fileSize; + if (StorageHelper.IsStorageLimitReached(subscription, userSettings.StorageLimit)) + { + await this.AbortMultipartUploadAsync(userId, uploadRequest.Key, uploadRequest.UploadId); + throw new Exception("Storage limit reached."); + } } uploadRequest.Key = objectName; @@ -259,8 +262,11 @@ namespace Notesnook.API.Services var response = await GetS3Client(S3ClientMode.INTERNAL).CompleteMultipartUploadAsync(uploadRequest); if (!IsSuccessStatusCode(((int)response.HttpStatusCode))) throw new Exception("Failed to complete multipart upload."); - userSettings.StorageLimit.UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == userId); + if (!Constants.IS_SELF_HOSTED) + { + userSettings.StorageLimit.UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == userId); + } } private string? GetPresignedURL(string userId, string name, HttpVerb httpVerb, S3ClientMode mode = S3ClientMode.EXTERNAL)