From ad96ec33e6d644557427695e4594f6e323380f22 Mon Sep 17 00:00:00 2001 From: dvirlabs Date: Mon, 11 May 2026 08:04:19 +0300 Subject: [PATCH] Fix product filters and add admin password reset feature - Fix: Product filters now properly send only non-empty values to backend - Fix: Brand/gender/model filters now work correctly - Add: FORCE_ADMIN_PASSWORD_RESET flag for resetting admin password on deployment - Add: ADMIN_PASSWORD_RESET.md guide with instructions - Update: Admin password reset logic with clear console messages --- ADMIN_PASSWORD_RESET.md | 51 +++++++++++++++++++++++++++++++++ backend/app/config.py | 1 + backend/app/main.py | 22 ++++++++------ brand-master-chart/values.yaml | 2 ++ frontend/src/pages/Products.jsx | 28 ++++++++++++------ 5 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 ADMIN_PASSWORD_RESET.md diff --git a/ADMIN_PASSWORD_RESET.md b/ADMIN_PASSWORD_RESET.md new file mode 100644 index 0000000..45a39c1 --- /dev/null +++ b/ADMIN_PASSWORD_RESET.md @@ -0,0 +1,51 @@ +# Admin Password Reset Guide + +## How to Reset Admin Password + +If you've changed your admin password and forgotten it, you can reset it using one of these methods: + +### Method 1: Force Reset on Deployment (Recommended) + +1. Edit the Helm values file: `~/OneDrive/Desktop/gitea/my-apps/charts/brand-master-chart/values.yaml` +2. Set the following environment variables: + ```yaml + ADMIN_PASSWORD: "your-new-password" + FORCE_ADMIN_PASSWORD_RESET: "true" + ``` +3. Deploy the changes: + ```bash + cd ~/OneDrive/Desktop/gitea/my-apps/charts + helm upgrade brand-master ./brand-master-chart -n my-apps + ``` +4. Wait for the backend pod to restart +5. **Important**: After logging in successfully, change `FORCE_ADMIN_PASSWORD_RESET` back to `"false"` and redeploy to prevent password reset on every startup + +### Method 2: Use Password Reset Flow (If Email is Configured) + +1. Go to the login page: https://brand-master.dvirlabs.com/login +2. Click "Forgot Password" +3. Enter your admin email address +4. Check your email for the PIN code +5. Enter the PIN and your new password +6. Login with the new password + +### Method 3: Change Password from Profile (If Logged In) + +1. Login to the admin account +2. Go to Profile page +3. Scroll to "Change Password" section +4. Enter old password and new password +5. Submit + +## Current Admin Credentials + +Check your deployment values file or pod logs for current credentials: +```bash +kubectl logs -n my-apps deployment/brand-master-backend | grep -A 3 "Admin" +``` + +## Notes + +- The `FORCE_ADMIN_PASSWORD_RESET` flag is set to `"false"` by default for security +- Only set it to `"true"` when you need to reset the password +- Always change it back to `"false"` after resetting to prevent security issues diff --git a/backend/app/config.py b/backend/app/config.py index 97e2b27..51e65a6 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -14,6 +14,7 @@ class Settings(BaseSettings): admin_email: str = "admin@brandmaster.com" admin_password: str = "Admin123!" # Change via ADMIN_PASSWORD env var admin_full_name: str = "System Administrator" + force_admin_password_reset: bool = False # Set to True to reset admin password on every startup # Email configuration for password reset smtp_host: str = "smtp.gmail.com" diff --git a/backend/app/main.py b/backend/app/main.py index ecdbe3e..73f7a17 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -46,15 +46,19 @@ def create_admin_user(): admin = db.query(User).filter(User.email == settings.admin_email).first() if admin: - # Admin exists, update password and details - admin.hashed_password = get_password_hash(settings.admin_password) - admin.full_name = settings.admin_full_name - admin.is_active = True - admin.is_admin = True - db.commit() - print(f"✅ Admin user updated: {settings.admin_email}") - print(f"📧 Email: {settings.admin_email}") - print(f"🔐 Password: {settings.admin_password}") + # Admin exists - update password if force reset is enabled + if settings.force_admin_password_reset: + admin.hashed_password = get_password_hash(settings.admin_password) + admin.full_name = settings.admin_full_name + admin.is_active = True + admin.is_admin = True + db.commit() + print(f"🔄 Admin password RESET (force_admin_password_reset=True): {settings.admin_email}") + print(f"📧 Email: {settings.admin_email}") + print(f"🔐 New Password: {settings.admin_password}") + else: + print(f"â„šī¸ Admin user exists: {settings.admin_email} (password unchanged)") + print(f"💡 To reset password, set FORCE_ADMIN_PASSWORD_RESET=true and redeploy") else: # Create new admin user admin = User( diff --git a/brand-master-chart/values.yaml b/brand-master-chart/values.yaml index 7892a7f..6691d43 100644 --- a/brand-master-chart/values.yaml +++ b/brand-master-chart/values.yaml @@ -32,6 +32,8 @@ backend: ADMIN_EMAIL: "admin@brand-master.com" ADMIN_PASSWORD: "admin123" # CHANGE THIS! ADMIN_FULL_NAME: "System Administrator" + # Set to "true" to reset admin password on every deployment (useful if you forgot password) + FORCE_ADMIN_PASSWORD_RESET: "false" # Email configuration for password reset (optional) SMTP_HOST: "smtp.gmail.com" SMTP_PORT: "587" diff --git a/frontend/src/pages/Products.jsx b/frontend/src/pages/Products.jsx index 690d8e1..adc97f4 100644 --- a/frontend/src/pages/Products.jsx +++ b/frontend/src/pages/Products.jsx @@ -20,7 +20,7 @@ export default function Products() { try { setLoading(true) const categorySlug = searchParams.get('category') - const params = { limit: 50, ...activeFilters } + const params = { limit: 50 } if (categorySlug) { // Get category by slug @@ -29,13 +29,25 @@ export default function Products() { if (category) params.category_id = category.id } - // Convert filter values to API parameters - if (activeFilters.gender) params.gender = activeFilters.gender - if (activeFilters.brand) params.brand = activeFilters.brand - if (activeFilters.min_price) params.min_price = parseFloat(activeFilters.min_price) - if (activeFilters.max_price) params.max_price = parseFloat(activeFilters.max_price) - if (activeFilters.onSale) params.on_sale = true - if (activeFilters.model_id) params.model_id = parseInt(activeFilters.model_id) + // Only add non-empty filter values to params + if (activeFilters.gender && activeFilters.gender !== '') { + params.gender = activeFilters.gender + } + if (activeFilters.brand && activeFilters.brand !== '') { + params.brand = activeFilters.brand + } + if (activeFilters.model_id && activeFilters.model_id !== '') { + params.model_id = parseInt(activeFilters.model_id) + } + if (activeFilters.min_price && activeFilters.min_price !== '') { + params.min_price = parseFloat(activeFilters.min_price) + } + if (activeFilters.max_price && activeFilters.max_price !== '') { + params.max_price = parseFloat(activeFilters.max_price) + } + if (activeFilters.onSale === true) { + params.on_sale = true + } // Map sortBy to backend parameter if (sortBy === 'price-low') {