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
This commit is contained in:
Abdullah Atta
2025-10-09 14:13:11 +05:00
parent 32b24dead2
commit 1ecd8adee1
3 changed files with 46 additions and 34 deletions
@@ -42,10 +42,10 @@ namespace Notesnook.API.Controllers
[HttpGet("active")] [HttpGet("active")]
[AllowAnonymous] [AllowAnonymous]
public async Task<IActionResult> GetActiveAnnouncements([FromQuery] string userId) public async Task<IActionResult> GetActiveAnnouncements([FromQuery] string? userId)
{ {
var totalActive = await Announcements.Collection.CountDocumentsAsync(Builders<Announcement>.Filter.Eq("IsActive", true)); var totalActive = await Announcements.Collection.CountDocumentsAsync(Builders<Announcement>.Filter.Eq("IsActive", true));
if (totalActive <= 0) return Ok(new Announcement[] { }); if (totalActive <= 0) return Ok(Array.Empty<Announcement>());
var announcements = (await Announcements.FindAsync((a) => a.IsActive)).Where((a) => a.UserIds == null || a.UserIds.Length == 0 || a.UserIds.Contains(userId)); 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) foreach (var announcement in announcements)
+21 -15
View File
@@ -63,20 +63,23 @@ namespace Notesnook.API.Controllers
return Ok(uploadUrl); return Ok(uploadUrl);
} }
var subscriptionService = await WampServers.SubscriptionServer.GetServiceAsync<IUserSubscriptionService>(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); var userSettings = await Repositories.UsersSettings.FindOneAsync((u) => u.UserId == userId);
userSettings.StorageLimit ??= new Limit { Value = 0, UpdatedAt = 0 }; if (!Constants.IS_SELF_HOSTED)
userSettings.StorageLimit.Value += fileSize; {
if (StorageHelper.IsStorageLimitReached(subscription, userSettings.StorageLimit)) var subscriptionService = await WampServers.SubscriptionServer.GetServiceAsync<IUserSubscriptionService>(SubscriptionServerTopics.UserSubscriptionServiceTopic);
return BadRequest(new { error = "Storage limit exceeded." }); 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); var url = S3Service.GetUploadObjectUrl(userId, name);
if (url == null) return BadRequest(new { error = "Could not create signed url." }); 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<Response>(url, null, HttpMethod.Put, content); var response = await httpClient.SendRequestAsync<Response>(url, null, HttpMethod.Put, content);
if (!response.Success) return BadRequest(await response.Content.ReadAsStringAsync()); if (!response.Success) return BadRequest(await response.Content.ReadAsStringAsync());
userSettings.StorageLimit.UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); if (!Constants.IS_SELF_HOSTED)
await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == userId); {
userSettings.StorageLimit.UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == userId);
}
return Ok(response); return Ok(response);
} }
+23 -17
View File
@@ -229,16 +229,6 @@ namespace Notesnook.API.Services
var objectName = GetFullObjectName(userId, uploadRequest.Key); var objectName = GetFullObjectName(userId, uploadRequest.Key);
if (userId == null || objectName == null) throw new Exception("Could not abort multipart upload."); if (userId == null || objectName == null) throw new Exception("Could not abort multipart upload.");
var subscriptionService = await WampServers.SubscriptionServer.GetServiceAsync<IUserSubscriptionService>(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); var userSettings = await Repositories.UsersSettings.FindOneAsync((u) => u.UserId == userId);
if (userSettings == null) if (userSettings == null)
{ {
@@ -246,12 +236,25 @@ namespace Notesnook.API.Services
throw new Exception("User settings not found."); throw new Exception("User settings not found.");
} }
userSettings.StorageLimit ??= new Limit { Value = 0, UpdatedAt = 0 }; if (!Constants.IS_SELF_HOSTED)
userSettings.StorageLimit.Value += fileSize;
if (StorageHelper.IsStorageLimitReached(subscription, userSettings.StorageLimit))
{ {
await this.AbortMultipartUploadAsync(userId, uploadRequest.Key, uploadRequest.UploadId); var subscriptionService = await WampServers.SubscriptionServer.GetServiceAsync<IUserSubscriptionService>(SubscriptionServerTopics.UserSubscriptionServiceTopic);
throw new Exception("Storage limit reached."); 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; uploadRequest.Key = objectName;
@@ -259,8 +262,11 @@ namespace Notesnook.API.Services
var response = await GetS3Client(S3ClientMode.INTERNAL).CompleteMultipartUploadAsync(uploadRequest); var response = await GetS3Client(S3ClientMode.INTERNAL).CompleteMultipartUploadAsync(uploadRequest);
if (!IsSuccessStatusCode(((int)response.HttpStatusCode))) throw new Exception("Failed to complete multipart upload."); if (!IsSuccessStatusCode(((int)response.HttpStatusCode))) throw new Exception("Failed to complete multipart upload.");
userSettings.StorageLimit.UpdatedAt = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); if (!Constants.IS_SELF_HOSTED)
await Repositories.UsersSettings.UpsertAsync(userSettings, (u) => u.UserId == userId); {
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) private string? GetPresignedURL(string userId, string name, HttpVerb httpVerb, S3ClientMode mode = S3ClientMode.EXTERNAL)