From 44dbbf7cf1db6dde3b450d120bf3c72e7421d140 Mon Sep 17 00:00:00 2001 From: anvesh Date: Thu, 24 Jul 2025 15:57:21 +0545 Subject: [PATCH 1/8] feat: add profilePhotoMaxSizeLimit to UserConfig interface --- packages/user/src/types/config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/user/src/types/config.ts b/packages/user/src/types/config.ts index 81e325d11..1f02a6b90 100644 --- a/packages/user/src/types/config.ts +++ b/packages/user/src/types/config.ts @@ -88,6 +88,7 @@ interface UserConfig { }; password?: StrongPasswordOptions; permissions?: string[]; + profilePhotoMaxSizeLimit?: number; role?: string; roles?: string[]; routePrefix?: string; From aa4e9eadc3318a1628f4c95a0d4b18915a1d54dd Mon Sep 17 00:00:00 2001 From: anvesh Date: Thu, 24 Jul 2025 15:59:32 +0545 Subject: [PATCH 2/8] feat: enforce photo size limit in uploadPhoto handler --- .../user/src/model/users/handlers/uploadPhoto.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/user/src/model/users/handlers/uploadPhoto.ts b/packages/user/src/model/users/handlers/uploadPhoto.ts index e490531ed..ef4bb1f44 100644 --- a/packages/user/src/model/users/handlers/uploadPhoto.ts +++ b/packages/user/src/model/users/handlers/uploadPhoto.ts @@ -38,6 +38,20 @@ const uploadPhoto = async (request: SessionRequest, reply: FastifyReply) => { }); } + const photoSizeLimit = request.config.user.profilePhotoMaxSizeLimit; + + if (photoSizeLimit) { + const maxLimitInBytes = photoSizeLimit * 1024 * 1024; // Convert to bytes + + if (Buffer.isBuffer(photo.data) && photo.data.length > maxLimitInBytes) { + throw new CustomApiError({ + message: "File size exceeds limit", + name: "ERROR_FILE_TOO_LARGE", + statusCode: 413, + }); + } + } + const file = await service.uploadPhoto(photo, user.id, user.id); const updatedUser = await service.update(user.id, { From 22db993ef99b719468fed10bbd194b2ce47a4932 Mon Sep 17 00:00:00 2001 From: anvesh Date: Thu, 24 Jul 2025 16:45:05 +0545 Subject: [PATCH 3/8] feat: add default max size for user photos --- packages/user/src/constants.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/user/src/constants.ts b/packages/user/src/constants.ts index 60d93cee9..ff734329d 100644 --- a/packages/user/src/constants.ts +++ b/packages/user/src/constants.ts @@ -48,7 +48,11 @@ const PERMISSIONS_USERS_ENABLE = "users:enable"; const PERMISSIONS_USERS_LIST = "users:list"; const PERMISSIONS_USERS_READ = "users:read"; +// Default max size for user photos in MB +const DEFAULT_PHOTO_MAX_SIZE = 5; + export { + DEFAULT_PHOTO_MAX_SIZE, EMAIL_VERIFICATION_MODE, EMAIL_VERIFICATION_PATH, INVITATION_ACCEPT_LINK_PATH, From 57eb73d008dd44a9e62b93473db5c2e780e87a4d Mon Sep 17 00:00:00 2001 From: anvesh Date: Thu, 24 Jul 2025 16:46:17 +0545 Subject: [PATCH 4/8] feat: rename profilePhotoMaxSizeLimit to photoMaxSizeInMB in UserConfig interface --- packages/user/src/types/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/user/src/types/config.ts b/packages/user/src/types/config.ts index 1f02a6b90..d98cd658f 100644 --- a/packages/user/src/types/config.ts +++ b/packages/user/src/types/config.ts @@ -88,7 +88,7 @@ interface UserConfig { }; password?: StrongPasswordOptions; permissions?: string[]; - profilePhotoMaxSizeLimit?: number; + photoMaxSizeInMB?: number; role?: string; roles?: string[]; routePrefix?: string; From 2c3b8c3f2b87812f2672d1497c6fcf43015e89fe Mon Sep 17 00:00:00 2001 From: anvesh Date: Thu, 24 Jul 2025 16:47:41 +0545 Subject: [PATCH 5/8] feat: implement photo size limit in UserService using default value --- .../user/src/model/users/handlers/uploadPhoto.ts | 14 -------------- packages/user/src/model/users/service.ts | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/user/src/model/users/handlers/uploadPhoto.ts b/packages/user/src/model/users/handlers/uploadPhoto.ts index ef4bb1f44..e490531ed 100644 --- a/packages/user/src/model/users/handlers/uploadPhoto.ts +++ b/packages/user/src/model/users/handlers/uploadPhoto.ts @@ -38,20 +38,6 @@ const uploadPhoto = async (request: SessionRequest, reply: FastifyReply) => { }); } - const photoSizeLimit = request.config.user.profilePhotoMaxSizeLimit; - - if (photoSizeLimit) { - const maxLimitInBytes = photoSizeLimit * 1024 * 1024; // Convert to bytes - - if (Buffer.isBuffer(photo.data) && photo.data.length > maxLimitInBytes) { - throw new CustomApiError({ - message: "File size exceeds limit", - name: "ERROR_FILE_TOO_LARGE", - statusCode: 413, - }); - } - } - const file = await service.uploadPhoto(photo, user.id, user.id); const updatedUser = await service.update(user.id, { diff --git a/packages/user/src/model/users/service.ts b/packages/user/src/model/users/service.ts index cdf6ce0c8..de5faca4e 100644 --- a/packages/user/src/model/users/service.ts +++ b/packages/user/src/model/users/service.ts @@ -4,6 +4,7 @@ import Session from "supertokens-node/recipe/session"; import ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword"; import UserSqlFactory from "./sqlFactory"; +import { DEFAULT_PHOTO_MAX_SIZE } from "../../constants"; import CustomApiError from "../../customApiError"; import validatePassword from "../../validator/password"; @@ -242,6 +243,21 @@ class UserService extends BaseService { return undefined; } + const photoSizeLimit = + this.config.user.photoMaxSizeInMB || DEFAULT_PHOTO_MAX_SIZE; + + if (photoSizeLimit) { + const maxSizeInBytes = photoSizeLimit * 1024 * 1024; // Convert to bytes + + if (Buffer.isBuffer(data.data) && data.data.length > maxSizeInBytes) { + throw new CustomApiError({ + message: "File size exceeds limit", + name: "ERROR_FILE_TOO_LARGE", + statusCode: 413, + }); + } + } + if (!this._supportedMimeTypes.includes(data.mimetype)) { throw new CustomApiError({ message: "Unsupported file type for profile picture", From 8045a108dc29e2dac1e775833b7bb9855c453410 Mon Sep 17 00:00:00 2001 From: anvesh Date: Thu, 24 Jul 2025 16:52:06 +0545 Subject: [PATCH 6/8] docs: change comment for constants --- packages/user/src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/user/src/constants.ts b/packages/user/src/constants.ts index ff734329d..11e74d6a4 100644 --- a/packages/user/src/constants.ts +++ b/packages/user/src/constants.ts @@ -48,7 +48,7 @@ const PERMISSIONS_USERS_ENABLE = "users:enable"; const PERMISSIONS_USERS_LIST = "users:list"; const PERMISSIONS_USERS_READ = "users:read"; -// Default max size for user photos in MB +// Default max size for user photo in MB const DEFAULT_PHOTO_MAX_SIZE = 5; export { From 41fc75e69ff547f6aa16a823b52dd5f5f5f20bb5 Mon Sep 17 00:00:00 2001 From: anvesh Date: Thu, 24 Jul 2025 16:58:30 +0545 Subject: [PATCH 7/8] feat: update error message for file size limit in uploadPhoto method --- packages/user/src/model/users/service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/user/src/model/users/service.ts b/packages/user/src/model/users/service.ts index de5faca4e..494a1e924 100644 --- a/packages/user/src/model/users/service.ts +++ b/packages/user/src/model/users/service.ts @@ -251,7 +251,7 @@ class UserService extends BaseService { if (Buffer.isBuffer(data.data) && data.data.length > maxSizeInBytes) { throw new CustomApiError({ - message: "File size exceeds limit", + message: `File size exceeds ${photoSizeLimit}MB limit`, name: "ERROR_FILE_TOO_LARGE", statusCode: 413, }); From a66529a0b963b803a908b4f0ec17ffd5e0dc4bff Mon Sep 17 00:00:00 2001 From: anvesh Date: Thu, 24 Jul 2025 17:02:17 +0545 Subject: [PATCH 8/8] feat: rename default photo max size constant and update usage in UserService --- packages/user/src/constants.ts | 4 ++-- packages/user/src/model/users/service.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/user/src/constants.ts b/packages/user/src/constants.ts index 11e74d6a4..d6b27d0e4 100644 --- a/packages/user/src/constants.ts +++ b/packages/user/src/constants.ts @@ -49,10 +49,10 @@ const PERMISSIONS_USERS_LIST = "users:list"; const PERMISSIONS_USERS_READ = "users:read"; // Default max size for user photo in MB -const DEFAULT_PHOTO_MAX_SIZE = 5; +const DEFAULT_USER_PHOTO_MAX_SIZE_IN_MB = 5; export { - DEFAULT_PHOTO_MAX_SIZE, + DEFAULT_USER_PHOTO_MAX_SIZE_IN_MB, EMAIL_VERIFICATION_MODE, EMAIL_VERIFICATION_PATH, INVITATION_ACCEPT_LINK_PATH, diff --git a/packages/user/src/model/users/service.ts b/packages/user/src/model/users/service.ts index 494a1e924..7671c1774 100644 --- a/packages/user/src/model/users/service.ts +++ b/packages/user/src/model/users/service.ts @@ -4,7 +4,7 @@ import Session from "supertokens-node/recipe/session"; import ThirdPartyEmailPassword from "supertokens-node/recipe/thirdpartyemailpassword"; import UserSqlFactory from "./sqlFactory"; -import { DEFAULT_PHOTO_MAX_SIZE } from "../../constants"; +import { DEFAULT_USER_PHOTO_MAX_SIZE_IN_MB } from "../../constants"; import CustomApiError from "../../customApiError"; import validatePassword from "../../validator/password"; @@ -244,7 +244,7 @@ class UserService extends BaseService { } const photoSizeLimit = - this.config.user.photoMaxSizeInMB || DEFAULT_PHOTO_MAX_SIZE; + this.config.user.photoMaxSizeInMB || DEFAULT_USER_PHOTO_MAX_SIZE_IN_MB; if (photoSizeLimit) { const maxSizeInBytes = photoSizeLimit * 1024 * 1024; // Convert to bytes