diff --git a/packages/user/src/constants.ts b/packages/user/src/constants.ts index 60d93cee9..d6b27d0e4 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 photo in MB +const DEFAULT_USER_PHOTO_MAX_SIZE_IN_MB = 5; + export { + 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 cdf6ce0c8..7671c1774 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_USER_PHOTO_MAX_SIZE_IN_MB } 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_USER_PHOTO_MAX_SIZE_IN_MB; + + 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 ${photoSizeLimit}MB limit`, + name: "ERROR_FILE_TOO_LARGE", + statusCode: 413, + }); + } + } + if (!this._supportedMimeTypes.includes(data.mimetype)) { throw new CustomApiError({ message: "Unsupported file type for profile picture", diff --git a/packages/user/src/types/config.ts b/packages/user/src/types/config.ts index 81e325d11..d98cd658f 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[]; + photoMaxSizeInMB?: number; role?: string; roles?: string[]; routePrefix?: string;