From 57cd9aa2a58745ff05a86461edc606b5a551bbc3 Mon Sep 17 00:00:00 2001 From: jikrana Date: Mon, 22 Jun 2026 13:00:27 +0530 Subject: [PATCH] feat: improve user schema validation and serialization --- BACKEND/models/user.model.js | 57 ++++++++++++++++++++++++------------ FRONTEND/package-lock.json | 34 +++++++++------------ 2 files changed, 53 insertions(+), 38 deletions(-) diff --git a/BACKEND/models/user.model.js b/BACKEND/models/user.model.js index 176b893..2fdec44 100644 --- a/BACKEND/models/user.model.js +++ b/BACKEND/models/user.model.js @@ -1,17 +1,20 @@ import mongoose from "mongoose"; -const addressSchema = new mongoose.Schema({ - label: { type: String, trim: true, default: 'Home' }, - fullName: { type: String, trim: true, required: true }, - phone: { type: String, trim: true, default: '' }, - line1: { type: String, trim: true, required: true }, - line2: { type: String, trim: true, default: '' }, - city: { type: String, trim: true, required: true }, - state: { type: String, trim: true, default: '' }, - postalCode: { type: String, trim: true, required: true }, - country: { type: String, trim: true, required: true }, - isDefault: { type: Boolean, default: false }, -}, { _id: true }); +const addressSchema = new mongoose.Schema( + { + label: { type: String, trim: true, default: "Home" }, + fullName: { type: String, trim: true, required: true }, + phone: { type: String, trim: true, default: "" }, + line1: { type: String, trim: true, required: true }, + line2: { type: String, trim: true, default: "" }, + city: { type: String, trim: true, required: true }, + state: { type: String, trim: true, default: "" }, + postalCode: { type: String, trim: true, required: true }, + country: { type: String, trim: true, required: true }, + isDefault: { type: Boolean, default: false }, + }, + { _id: true } +); const userSchema = new mongoose.Schema( { @@ -19,6 +22,7 @@ const userSchema = new mongoose.Schema( type: String, required: [true, "Name is required"], trim: true, + maxlength: [50, "Name cannot exceed 50 characters"], }, email: { @@ -27,31 +31,39 @@ const userSchema = new mongoose.Schema( unique: true, lowercase: true, trim: true, + match: [ + /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/, + "Please enter a valid email address", + ], }, password: { type: String, minlength: 6, - // Not required because OAuth users won't have a password initially + // Keeping it visible to avoid breaking login flow }, googleId: { type: String, + unique: true, + sparse: true, }, githubId: { type: String, + unique: true, + sparse: true, }, phone: { type: String, trim: true, - default: '', + default: "", }, avatar: { type: String, - default: '', + default: "", }, addresses: { @@ -61,8 +73,8 @@ const userSchema = new mongoose.Schema( provider: { type: String, - enum: ['local', 'google', 'github'], - default: 'local', + enum: ["local", "google", "github"], + default: "local", }, resetPasswordToken: { @@ -77,9 +89,18 @@ const userSchema = new mongoose.Schema( }, { timestamps: true, + toJSON: { + transform: function (doc, ret) { + delete ret.password; + delete ret.resetPasswordToken; + delete ret.resetPasswordExpires; + delete ret.__v; + return ret; + }, + }, } ); const User = mongoose.model("User", userSchema); -export default User; +export default User; \ No newline at end of file diff --git a/FRONTEND/package-lock.json b/FRONTEND/package-lock.json index f039cba..f40d81d 100644 --- a/FRONTEND/package-lock.json +++ b/FRONTEND/package-lock.json @@ -123,7 +123,6 @@ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -418,7 +417,6 @@ "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-2.10.10.tgz", "integrity": "sha512-uahxAfb83/O9fcgBm3ew/nVeQiNgE0uQf8NdQQp3I6u/PCuR2OjSEneV4Ba86W8z50Ppwcxvf9XDk5btYceggQ==", "license": "MIT", - "peer": true, "dependencies": { "@chakra-ui/hooks": "2.4.6", "@chakra-ui/styled-system": "2.12.5", @@ -444,7 +442,6 @@ "resolved": "https://registry.npmjs.org/@chakra-ui/styled-system/-/styled-system-2.12.5.tgz", "integrity": "sha512-sy39LJWnOvGcOHYBXQxT3bC5zj+R7GVUgxzkkoqx+auV5KVKOOE5aZD+POsciWEt86bqdEa+LpFm+E5pcdbkyg==", "license": "MIT", - "peer": true, "dependencies": { "@chakra-ui/utils": "2.2.6", "csstype": "^3.1.2" @@ -579,7 +576,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -603,7 +599,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -651,6 +646,7 @@ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", "license": "MIT", + "peer": true, "dependencies": { "@emotion/memoize": "^0.9.0" } @@ -666,7 +662,6 @@ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -1935,7 +1930,8 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -2023,7 +2019,6 @@ "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -2034,7 +2029,6 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -2260,7 +2254,6 @@ "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2326,6 +2319,7 @@ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } @@ -2469,7 +2463,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -2855,7 +2848,8 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/dunder-proto": { "version": "1.0.1", @@ -3015,7 +3009,6 @@ "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3702,7 +3695,6 @@ } ], "license": "MIT", - "peer": true, "peerDependencies": { "typescript": "^5 || ^6" }, @@ -4111,6 +4103,7 @@ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -4227,6 +4220,7 @@ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.40.0.tgz", "integrity": "sha512-HxU3ZaBwNPVQUBQf1xxgq+7JrPNZvjLVxgbpEZL7RrWJnsxOf0/OM+yrHG9ogLQ31Do/r57Oz2gQWPK+6q62mg==", "license": "MIT", + "peer": true, "dependencies": { "motion-utils": "^12.39.0" } @@ -4235,7 +4229,8 @@ "version": "12.39.0", "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.39.0.tgz", "integrity": "sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/ms": { "version": "2.1.3", @@ -4507,7 +4502,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -4579,6 +4573,7 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -4594,6 +4589,7 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -4606,7 +4602,8 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/prop-types": { "version": "15.8.1", @@ -4663,7 +4660,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -4685,7 +4681,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -5465,7 +5460,6 @@ "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4",