Update app
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
dvirlabs 2026-05-10 03:26:03 +03:00
parent 29aa5c2f36
commit d0b672ac15
6 changed files with 1013 additions and 10 deletions

312
EMAIL_SETUP.md Normal file
View File

@ -0,0 +1,312 @@
# Email Configuration Guide
## Overview
The Brand Master application supports sending transactional emails for:
- Password reset PINs
- Welcome emails for new users
- Order confirmations (future)
- Contact form notifications (future)
## Email Service Options
### Option 1: Gmail SMTP (Recommended for Testing)
1. **Create App Password** (if using Gmail with 2FA):
- Go to Google Account Settings → Security
- Enable 2-Factor Authentication
- Go to "App passwords"
- Generate app password for "Mail"
- Copy the 16-character password
2. **Configure Environment Variables**:
```bash
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM=noreply@brand-master.com
```
### Option 2: SendGrid (Recommended for Production)
1. **Create SendGrid Account**:
- Sign up at https://sendgrid.com
- Verify your sender email
- Create API key
2. **Configure Environment Variables**:
```bash
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=your-sendgrid-api-key
SMTP_FROM=noreply@brand-master.com
```
### Option 3: Amazon SES (Production - Most Reliable)
1. **Setup SES**:
- Sign up for AWS SES
- Verify your domain or email
- Get SMTP credentials
2. **Configure Environment Variables**:
```bash
SMTP_HOST=email-smtp.us-east-1.amazonaws.com
SMTP_PORT=587
SMTP_USERNAME=your-ses-smtp-username
SMTP_PASSWORD=your-ses-smtp-password
SMTP_FROM=noreply@brand-master.com
```
## Kubernetes Deployment Configuration
### Method 1: Update values.yaml (Recommended)
Edit `brand-master-chart/values.yaml`:
```yaml
backend:
env:
# Existing vars...
- name: SMTP_HOST
value: "smtp.gmail.com"
- name: SMTP_PORT
value: "587"
- name: SMTP_USERNAME
value: "your-email@gmail.com"
- name: SMTP_PASSWORD
value: "your-app-password" # Use secrets in production!
- name: SMTP_FROM
value: "noreply@brand-master.com"
```
### Method 2: Use Kubernetes Secret (Production)
1. **Create Secret**:
```bash
kubectl create secret generic brand-master-email \
--from-literal=smtp-username=your-email@gmail.com \
--from-literal=smtp-password=your-app-password \
-n my-apps
```
2. **Update Deployment** (`brand-master-chart/templates/backend-deployment.yaml`):
```yaml
env:
# ... existing env vars ...
- name: SMTP_HOST
value: "smtp.gmail.com"
- name: SMTP_PORT
value: "587"
- name: SMTP_USERNAME
valueFrom:
secretKeyRef:
name: brand-master-email
key: smtp-username
- name: SMTP_PASSWORD
valueFrom:
secretKeyRef:
name: brand-master-email
key: smtp-password
- name: SMTP_FROM
value: "noreply@brand-master.com"
```
## Local Development (.env file)
Create `backend/.env`:
```env
DATABASE_URL=postgresql://brand_master_user:your_password@localhost/brand_master_db
JWT_SECRET_KEY=your-secret-key
FRONTEND_URL=http://localhost:5173
BACKEND_URL=http://localhost:8000
# Email Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your-email@gmail.com
SMTP_PASSWORD=your-app-password
SMTP_FROM=noreply@brand-master.com
# Admin Credentials
ADMIN_EMAIL=admin@brandmaster.com
ADMIN_PASSWORD=Admin123!
```
## Testing Email Functionality
### Test Password Reset
1. **Trigger Password Reset**:
```bash
curl -X POST https://api-brand-master.dvirlabs.com/api/auth/request-reset-pin \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
```
2. **Check Email**:
- User should receive email with 6-digit PIN
- PIN expires in 15 minutes
3. **Reset Password**:
```bash
curl -X POST https://api-brand-master.dvirlabs.com/api/auth/reset-password-with-pin \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"pin": "123456",
"new_password": "NewPassword123!"
}'
```
### Test Welcome Email
1. **Register New User**:
```bash
curl -X POST https://api-brand-master.dvirlabs.com/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"full_name": "Test User",
"password": "password123"
}'
```
2. **Check Email**:
- User should receive welcome email
### Check Backend Logs
If emails aren't being sent:
```bash
# View backend logs
kubectl logs -n my-apps deployment/brand-master-backend -f
# Look for:
# ✅ Email sent successfully to user@example.com
# OR
# ⚠️ SMTP not configured. Email would have been sent to: user@example.com
# OR
# ❌ Failed to send email to user@example.com: <error details>
```
## Troubleshooting
### Issue: "SMTP not configured" message
**Problem**: SMTP environment variables not set
**Solution**:
```bash
# Check if variables are set in pod
kubectl exec -n my-apps deployment/brand-master-backend -- env | grep SMTP
# Should show:
# SMTP_HOST=smtp.gmail.com
# SMTP_PORT=587
# SMTP_USERNAME=your-email@gmail.com
# SMTP_PASSWORD=***
# SMTP_FROM=noreply@brand-master.com
```
### Issue: "Authentication failed" error
**Problem**: Wrong credentials or app password required
**Solution**:
- For Gmail: Use App Password, not account password
- Verify credentials are correct
- Check if 2FA is enabled (required for App Passwords)
### Issue: "Connection refused" error
**Problem**: Wrong SMTP host or port, or firewall blocking
**Solution**:
- Verify SMTP_HOST and SMTP_PORT are correct
- Check Kubernetes network policies
- Test SMTP connection from pod:
```bash
kubectl exec -n my-apps deployment/brand-master-backend -- \
nc -zv smtp.gmail.com 587
```
### Issue: Emails go to spam
**Problem**: Missing SPF/DKIM records or sender reputation
**Solution**:
- Use verified domain with proper DNS records
- Use SendGrid or SES for production
- Add SPF record: `v=spf1 include:_spf.google.com ~all`
- Setup DKIM signing
## Email Templates
Email templates are in `backend/app/services/email.py`:
- `send_password_reset_pin()` - Password reset with PIN
- `send_welcome_email()` - Welcome new users
To customize:
1. Edit template in `email.py`
2. Rebuild backend image
3. Redeploy
## Production Best Practices
1. ✅ **Use Kubernetes Secrets** for credentials
2. ✅ **Use dedicated email service** (SendGrid, SES)
3. ✅ **Setup SPF/DKIM** for deliverability
4. ✅ **Monitor email sending** (logs, metrics)
5. ✅ **Implement rate limiting** to prevent abuse
6. ✅ **Use verified sender domain**
7. ✅ **Add unsubscribe links** for marketing emails
8. ✅ **Keep templates professional** and branded
## Quick Setup for Testing (Gmail)
```bash
# 1. Update values.yaml
nano brand-master-chart/values.yaml
# Add under backend.env:
- name: SMTP_HOST
value: "smtp.gmail.com"
- name: SMTP_PORT
value: "587"
- name: SMTP_USERNAME
value: "your-email@gmail.com"
- name: SMTP_PASSWORD
value: "your-16-char-app-password"
- name: SMTP_FROM
value: "Brand Master <noreply@brand-master.com>"
# 2. Redeploy
cd brand-master-chart
helm upgrade brand-master . --namespace my-apps --wait
# 3. Test
curl -X POST https://api-brand-master.dvirlabs.com/api/auth/request-reset-pin \
-H "Content-Type: application/json" \
-d '{"email": "your-test-email@gmail.com"}'
# 4. Check email inbox
```
## Support
If emails still don't work:
1. Check backend logs for error messages
2. Verify SMTP credentials
3. Test SMTP connection manually
4. Check spam folder
5. Try different email provider
---
**Status**: Email service implemented and ready to configure
**Last Updated**: May 8, 2026

304
PASSWORD_RESET_GUIDE.md Normal file
View File

@ -0,0 +1,304 @@
# Password Reset with Email PIN - Implementation Summary
## What Was Implemented
### 1. Email Service Module ✅
**File**: `backend/app/services/email.py`
**Features**:
- `send_email()` - Generic SMTP email sender
- `send_password_reset_pin()` - Sends 6-digit PIN with HTML/plain text template
- `send_welcome_email()` - Welcome new users
- Graceful fallback: Prints to console if SMTP not configured
- Professional HTML email templates with branding
**Template Highlights**:
- Beautiful HTML design with Brand Master branding
- 6-digit PIN displayed prominently
- 15-minute expiration timer
- Instructions for password reset
- Responsive design
- Plain text fallback
### 2. Auth Router Integration ✅
**File**: `backend/app/routers/auth.py`
**Changes**:
- Imported email service functions
- Updated `request_reset_pin()` to send email instead of just printing
- Updated `register()` to send welcome email to new users
- Added error handling (non-blocking - won't fail if email fails)
- Removed PIN from API response (security fix)
**Flow**:
1. User requests password reset with email
2. System generates 6-digit PIN
3. Stores PIN in database with 15-minute expiration
4. **Sends PIN to user's email** (new!)
5. Falls back to console print if SMTP not configured
6. User enters PIN and new password
7. System validates PIN and updates password
### 3. Configuration Guide ✅
**File**: `EMAIL_SETUP.md`
**Includes**:
- 3 email provider options (Gmail, SendGrid, AWS SES)
- Step-by-step setup for each provider
- Kubernetes deployment configuration
- Secret management (production best practices)
- Testing instructions
- Troubleshooting guide
- Production checklist
### 4. Quick Fix Deployment Script ✅
**File**: `quick-fix.bat`
**Automates**:
- Applies both database migrations (007, 008)
- Builds backend and frontend Docker images
- Pushes to Harbor registry
- Deploys via Helm
- Shows next steps and instructions
## What You Need to Do
### REQUIRED Steps
#### 1. Apply Database Migrations (CRITICAL)
The system currently has errors because migrations aren't applied:
```bash
# Option A: Use quick-fix script (does everything)
quick-fix.bat
# Option B: Apply migrations manually
apply-migration.bat 007_enhance_contact_messages.sql
apply-migration.bat 008_add_username_to_users.sql
```
**These migrations fix**:
- ❌ "column full_name does not exist" → ✅ Renames name → full_name
- ❌ "column username does not exist" → ✅ Adds username column
#### 2. Configure Email (for password reset to work)
**Quick Setup (Gmail)**:
1. Get Gmail App Password:
- Go to https://myaccount.google.com/apppasswords
- Generate password for "Mail"
- Copy 16-character password
2. Update `brand-master-chart/values.yaml`:
```yaml
backend:
env:
# ... existing vars ...
- name: SMTP_HOST
value: "smtp.gmail.com"
- name: SMTP_PORT
value: "587"
- name: SMTP_USERNAME
value: "your-email@gmail.com"
- name: SMTP_PASSWORD
value: "abcd efgh ijkl mnop" # Your 16-char app password
- name: SMTP_FROM
value: "Brand Master <noreply@brand-master.com>"
```
3. Redeploy:
```bash
cd brand-master-chart
helm upgrade brand-master . --namespace my-apps --wait
```
**Read [EMAIL_SETUP.md](EMAIL_SETUP.md) for**:
- Other email providers (SendGrid, AWS SES)
- Production setup with Kubernetes Secrets
- Troubleshooting guide
### OPTIONAL Steps
#### 3. Test Email Functionality
**Test Password Reset**:
```bash
# Request PIN
curl -X POST https://api-brand-master.dvirlabs.com/api/auth/request-reset-pin \
-H "Content-Type: application/json" \
-d '{"email": "your-test-email@gmail.com"}'
# Check your email for 6-digit PIN
# Reset password
curl -X POST https://api-brand-master.dvirlabs.com/api/auth/reset-password-with-pin \
-H "Content-Type: application/json" \
-d '{
"email": "your-test-email@gmail.com",
"pin": "123456",
"new_password": "NewPassword123!"
}'
```
**Or test via UI**:
1. Go to https://brand-master.dvirlabs.com/login
2. Click "Forgot Password?"
3. Enter email
4. Check inbox for PIN
5. Enter PIN and new password
#### 4. Monitor Email Sending
```bash
# View backend logs
kubectl logs -n my-apps deployment/brand-master-backend -f
# Look for:
# ✅ Email sent successfully to user@example.com
# ⚠️ SMTP not configured. Email would have been sent to: ...
# ❌ Failed to send email: <error>
```
## Current Status
| Feature | Status | Notes |
|---------|--------|-------|
| Email service code | ✅ Complete | `backend/app/services/email.py` created |
| Password reset PIN email | ✅ Complete | Sends HTML email with 6-digit PIN |
| Welcome email | ✅ Complete | Sent on new user registration |
| Auth router integration | ✅ Complete | Email functions called in endpoints |
| Configuration guide | ✅ Complete | See `EMAIL_SETUP.md` |
| Deployment script | ✅ Complete | `quick-fix.bat` |
| Database migrations | ⚠️ **NOT APPLIED** | Must run migrations! |
| SMTP configuration | ⚠️ **NOT CONFIGURED** | Emails print to console until configured |
| Production deployment | ⚠️ Pending | Need to rebuild/redeploy |
## How It Works Now
### Without SMTP Configured (Current State)
**What happens**:
1. User requests password reset
2. System generates PIN
3. **Email service prints to console**:
```
⚠️ SMTP not configured. Email would have been sent to: user@example.com
Subject: Brand Master - Password Reset PIN
Body: Your PIN is: 123456
```
4. You check backend logs for the PIN
5. User can still reset password with the PIN
**This is fine for testing but not production!**
### With SMTP Configured (After Setup)
**What happens**:
1. User requests password reset
2. System generates PIN
3. **Email sent to user's inbox**
4. User receives beautiful HTML email with PIN
5. User resets password (no need to check logs)
## Files Changed
### Created
- ✅ `backend/app/services/email.py` - Email service module
- ✅ `EMAIL_SETUP.md` - Email configuration guide
- ✅ `quick-fix.bat` - Automated deployment script
- ✅ `PASSWORD_RESET_GUIDE.md` - This file
### Modified
- ✅ `backend/app/routers/auth.py` - Integrated email service
### Ready to Apply
- ⚠️ `backend/migrations/007_enhance_contact_messages.sql`
- ⚠️ `backend/migrations/008_add_username_to_users.sql`
## Quick Start Commands
### Full Automated Deployment
```bash
# This does everything: migrations + build + deploy
quick-fix.bat
```
### Manual Step-by-Step
```bash
# 1. Apply migrations
apply-migration.bat 007_enhance_contact_messages.sql
apply-migration.bat 008_add_username_to_users.sql
# 2. Build images
cd backend && docker build -t harbor.dvirlabs.com/my-apps/brand-master-backend:latest . && cd ..
cd frontend && docker build -t harbor.dvirlabs.com/my-apps/brand-master-frontend:latest . && cd ..
# 3. Push images
docker push harbor.dvirlabs.com/my-apps/brand-master-backend:latest
docker push harbor.dvirlabs.com/my-apps/brand-master-frontend:latest
# 4. Deploy
cd brand-master-chart
helm upgrade brand-master . --namespace my-apps --wait
```
## Email Provider Recommendations
| Provider | Best For | Cost | Setup Difficulty |
|----------|----------|------|------------------|
| **Gmail** | Testing, Development | Free | Easy (App Password) |
| **SendGrid** | Production (Small) | Free tier: 100 emails/day | Medium |
| **AWS SES** | Production (Large) | $0.10 per 1000 emails | Medium-Hard |
| **Mailgun** | Production | Free tier: 5000 emails/month | Medium |
**My Recommendation**:
- **For testing now**: Gmail (5 minutes to setup)
- **For production later**: SendGrid or AWS SES (better deliverability)
## Testing Checklist
After deployment:
- [ ] Can submit contact form without errors
- [ ] Can register with username and phone
- [ ] Can login with email, username, OR phone
- [ ] Can request password reset
- [ ] Receive PIN email (or see in logs if SMTP not configured)
- [ ] Can reset password with PIN
- [ ] PIN expires after 15 minutes
- [ ] Invalid PIN shows error
- [ ] Welcome email sent on registration
## Troubleshooting
### "Column full_name does not exist"
**Fix**: Run `apply-migration.bat 007_enhance_contact_messages.sql`
### "Column username does not exist"
**Fix**: Run `apply-migration.bat 008_add_username_to_users.sql`
### "SMTP not configured" in logs
**Fix**: Configure SMTP in `values.yaml` (see [EMAIL_SETUP.md](EMAIL_SETUP.md))
### PIN not received in email
**Fix**: Check backend logs for error message, verify SMTP credentials
### Emails go to spam
**Fix**: Use proper From address, setup SPF/DKIM, or use SendGrid/SES
## Next Features (Future)
Possible enhancements:
- ✉️ Order confirmation emails
- ✉️ Shipping notification emails
- ✉️ Contact form notification to admin
- ✉️ Email templates customization UI
- 📊 Email delivery tracking
- 🎨 Email template builder
---
**Implementation Date**: January 2025
**Status**: Ready to deploy (migrations required)
**Documentation**: EMAIL_SETUP.md, API_DOCUMENTATION.md

View File

@ -1,5 +1,20 @@
@echo off @echo off
REM Apply database migration 005 - Add password reset fields REM Apply database migration script
REM Usage: apply-migration.bat <migration_filename>
if "%1"=="" (
echo ❌ Error: No migration file specified
echo Usage: apply-migration.bat ^<migration_filename^>
echo Example: apply-migration.bat 007_enhance_contact_messages.sql
exit /b 1
)
set MIGRATION_FILE=%1
if not exist "backend\migrations\%MIGRATION_FILE%" (
echo ❌ Migration file not found: backend\migrations\%MIGRATION_FILE%
exit /b 1
)
echo Getting database pod name... echo Getting database pod name...
for /f "delims=" %%i in ('kubectl get pod -n my-apps -l app.kubernetes.io/component=db -o jsonpath^="{.items[0].metadata.name}"') do set DB_POD=%%i for /f "delims=" %%i in ('kubectl get pod -n my-apps -l app.kubernetes.io/component=db -o jsonpath^="{.items[0].metadata.name}"') do set DB_POD=%%i
@ -10,17 +25,17 @@ if "%DB_POD%"=="" (
) )
echo 📦 Database pod: %DB_POD% echo 📦 Database pod: %DB_POD%
echo 📝 Applying migration 005_add_password_reset_fields.sql... echo 📝 Applying migration: %MIGRATION_FILE%...
echo. echo.
REM Copy migration file to pod REM Copy migration file to pod
kubectl cp backend/migrations/005_add_password_reset_fields.sql my-apps/%DB_POD%:/tmp/migration.sql kubectl cp backend/migrations/%MIGRATION_FILE% my-apps/%DB_POD%:/tmp/migration.sql
REM Execute migration REM Execute migration
kubectl exec -n my-apps %DB_POD% -- psql -U brand_master_user -d brand_master_db -f /tmp/migration.sql kubectl exec -n my-apps %DB_POD% -- psql -U brand_master_user -d brand_master_db -f /tmp/migration.sql
echo. echo.
echo ✅ Migration applied successfully! echo ✅ Migration %MIGRATION_FILE% applied successfully!
echo. echo.
echo 🔄 Restarting backend pod to pick up changes... echo 🔄 Restarting backend pod to pick up changes...
kubectl delete pod -n my-apps -l app.kubernetes.io/component=backend kubectl delete pod -n my-apps -l app.kubernetes.io/component=backend

View File

@ -15,6 +15,7 @@ from app.services.auth import (
verify_password, verify_password,
get_current_user, get_current_user,
) )
from app.services.email import send_password_reset_pin, send_welcome_email
from app.config import settings from app.config import settings
router = APIRouter(prefix="/api/auth", tags=["auth"]) router = APIRouter(prefix="/api/auth", tags=["auth"])
@ -43,15 +44,42 @@ def register(user: UserCreate, db: Session = Depends(get_db)):
detail="Email already registered", detail="Email already registered",
) )
# Check if username is already taken
if user.username:
existing_username = db.query(User).filter(User.username == user.username).first()
if existing_username:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Username already taken",
)
# Check if phone is already taken
if user.phone:
existing_phone = db.query(User).filter(User.phone == user.phone).first()
if existing_phone:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Phone number already registered",
)
hashed_password = get_password_hash(user.password) hashed_password = get_password_hash(user.password)
db_user = User( db_user = User(
email=user.email, email=user.email,
username=user.username,
phone=user.phone,
full_name=user.full_name, full_name=user.full_name,
hashed_password=hashed_password, hashed_password=hashed_password,
) )
db.add(db_user) db.add(db_user)
db.commit() db.commit()
db.refresh(db_user) db.refresh(db_user)
# Send welcome email (non-blocking - don't fail registration if email fails)
try:
send_welcome_email(user.email, user.full_name)
except Exception as e:
print(f"Failed to send welcome email: {e}")
return db_user return db_user
@ -132,14 +160,16 @@ def reset_password(request: ResetPasswordRequest, db: Session = Depends(get_db))
raise HTTPException( raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, status_code=status.HTTP_404_NOT_FOUND,
detail="User not found", detail="User not found",
) Send PIN via email
email_sent = send_password_reset_pin(request.email, pin, expires_minutes=15)
# Update password if not email_sent:
user.hashed_password = get_password_hash(request.new_password) # If email sending fails, still print to console for development
db.commit() print(f"\n⚠️ Email not sent. Password Reset PIN for {request.email}: {pin}")
print(f"Expires at: {user.pin_expires_at}\n")
return {"message": "Password reset successful"}
return {
"message": "If the email exists, a PIN has been sent to your email",
@router.post("/request-reset-pin") @router.post("/request-reset-pin")
def request_reset_pin(request: RequestPinRequest, db: Session = Depends(get_db)): def request_reset_pin(request: RequestPinRequest, db: Session = Depends(get_db)):

View File

@ -0,0 +1,233 @@
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from typing import Optional
from app.config import settings
def send_email(
to_email: str,
subject: str,
body: str,
html_body: Optional[str] = None
) -> bool:
"""
Send an email using SMTP configuration from settings.
Args:
to_email: Recipient email address
subject: Email subject
body: Plain text body
html_body: Optional HTML body (if provided, will be sent as multipart)
Returns:
bool: True if email sent successfully, False otherwise
"""
try:
# Create message
message = MIMEMultipart('alternative') if html_body else MIMEText(body, 'plain')
if html_body:
message['Subject'] = subject
message['From'] = settings.smtp_from
message['To'] = to_email
# Attach plain text and HTML versions
part1 = MIMEText(body, 'plain')
part2 = MIMEText(html_body, 'html')
message.attach(part1)
message.attach(part2)
else:
message['Subject'] = subject
message['From'] = settings.smtp_from
message['To'] = to_email
# Check if SMTP is configured
if not settings.smtp_username or not settings.smtp_password:
print(f"⚠️ SMTP not configured. Email would have been sent to: {to_email}")
print(f"Subject: {subject}")
print(f"Body:\n{body}")
return False
# Connect to SMTP server
with smtplib.SMTP(settings.smtp_host, settings.smtp_port) as server:
server.starttls()
server.login(settings.smtp_username, settings.smtp_password)
server.send_message(message)
print(f"✅ Email sent successfully to {to_email}")
return True
except Exception as e:
print(f"❌ Failed to send email to {to_email}: {str(e)}")
return False
def send_password_reset_pin(email: str, pin: str, expires_minutes: int = 15) -> bool:
"""
Send password reset PIN email.
Args:
email: User's email address
pin: 6-digit PIN code
expires_minutes: Minutes until PIN expires
Returns:
bool: True if email sent successfully
"""
subject = "Brand Master - Password Reset PIN"
# Plain text version
body = f"""
Hello,
You requested a password reset for your Brand Master account.
Your 6-digit PIN code is: {pin}
This PIN will expire in {expires_minutes} minutes.
To reset your password:
1. Go to the login page
2. Click "Forgot Password"
3. Enter this PIN when prompted
4. Create your new password
If you didn't request this reset, please ignore this email.
Best regards,
Brand Master Team
"""
# HTML version
html_body = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; line-height: 1.6; color: #333; }}
.container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
.header {{ background: #007bff; color: white; padding: 20px; text-align: center; border-radius: 5px 5px 0 0; }}
.content {{ background: #f9f9f9; padding: 30px; border-radius: 0 0 5px 5px; }}
.pin-box {{ background: white; padding: 20px; text-align: center; border: 2px solid #007bff; border-radius: 5px; margin: 20px 0; }}
.pin {{ font-size: 32px; font-weight: bold; color: #007bff; letter-spacing: 5px; }}
.warning {{ color: #dc3545; font-weight: bold; }}
.footer {{ text-align: center; color: #666; margin-top: 20px; font-size: 12px; }}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Password Reset Request</h1>
</div>
<div class="content">
<p>Hello,</p>
<p>You requested a password reset for your Brand Master account.</p>
<div class="pin-box">
<p style="margin: 0; font-size: 14px;">Your 6-digit PIN code is:</p>
<p class="pin">{pin}</p>
<p style="margin: 0; color: #666;">Expires in {expires_minutes} minutes</p>
</div>
<p><strong>To reset your password:</strong></p>
<ol>
<li>Go to the <a href="https://brand-master.dvirlabs.com/login">login page</a></li>
<li>Click "Forgot Password"</li>
<li>Enter this PIN when prompted</li>
<li>Create your new password</li>
</ol>
<p class="warning"> If you didn't request this reset, please ignore this email.</p>
<div class="footer">
<p>This is an automated message from Brand Master. Please do not reply.</p>
</div>
</div>
</div>
</body>
</html>
"""
return send_email(email, subject, body, html_body)
def send_welcome_email(email: str, full_name: str) -> bool:
"""
Send welcome email to new users.
Args:
email: User's email address
full_name: User's full name
Returns:
bool: True if email sent successfully
"""
subject = "Welcome to Brand Master!"
body = f"""
Hello {full_name},
Welcome to Brand Master! Your account has been created successfully.
You can now:
- Browse our collection of premium shoes and apparel
- Add items to your wishlist
- Place orders with secure checkout
- Track your order history
Visit us at: https://brand-master.dvirlabs.com
Best regards,
Brand Master Team
"""
html_body = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; line-height: 1.6; color: #333; }}
.container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
.header {{ background: linear-gradient(135deg, #007bff 0%, #0056b3 100%); color: white; padding: 30px; text-align: center; border-radius: 5px 5px 0 0; }}
.content {{ background: #f9f9f9; padding: 30px; border-radius: 0 0 5px 5px; }}
.button {{ display: inline-block; padding: 12px 30px; background: #007bff; color: white; text-decoration: none; border-radius: 5px; margin: 20px 0; }}
.features {{ background: white; padding: 20px; border-radius: 5px; margin: 20px 0; }}
.footer {{ text-align: center; color: #666; margin-top: 20px; font-size: 12px; }}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Welcome to Brand Master!</h1>
<p>Your premium fashion destination</p>
</div>
<div class="content">
<p>Hello {full_name},</p>
<p>Welcome aboard! Your account has been created successfully.</p>
<div class="features">
<h3>What you can do:</h3>
<ul>
<li> Browse our collection of premium shoes and apparel</li>
<li> Add items to your wishlist</li>
<li> Place orders with secure checkout</li>
<li> Track your order history</li>
</ul>
</div>
<div style="text-align: center;">
<a href="https://brand-master.dvirlabs.com" class="button">Start Shopping</a>
</div>
<div class="footer">
<p>Questions? Contact us at info@brandmaster.com</p>
<p>This is an automated message from Brand Master.</p>
</div>
</div>
</div>
</body>
</html>
"""
return send_email(email, subject, body, html_body)

109
quick-fix.bat Normal file
View File

@ -0,0 +1,109 @@
@echo off
REM Quick Fix Script - Apply Migrations and Deploy
REM This script fixes the database errors and deploys the updated system
echo ================================================================
echo Brand Master - Quick Fix Deployment
echo ================================================================
echo.
echo This will:
echo 1. Apply contact messages migration (fix full_name error)
echo 2. Apply flexible login migration (fix username error)
echo 3. Rebuild and deploy backend/frontend
echo.
pause
REM Step 1: Apply Contact Messages Migration
echo ================================================================
echo Step 1: Applying contact messages migration...
echo ================================================================
call apply-migration.bat 007_enhance_contact_messages.sql
if errorlevel 1 (
echo [ERROR] Failed to apply contact messages migration
pause
exit /b 1
)
echo.
REM Step 2: Apply Flexible Login Migration
echo ================================================================
echo Step 2: Applying flexible login migration...
echo ================================================================
call apply-migration.bat 008_add_username_to_users.sql
if errorlevel 1 (
echo [ERROR] Failed to apply flexible login migration
pause
exit /b 1
)
echo.
REM Step 3: Build and Deploy
echo ================================================================
echo Step 3: Building and deploying...
echo ================================================================
set BACKEND_IMAGE=harbor.dvirlabs.com/my-apps/brand-master-backend:latest
set FRONTEND_IMAGE=harbor.dvirlabs.com/my-apps/brand-master-frontend:latest
echo Building backend...
cd backend
docker build -t %BACKEND_IMAGE% .
if errorlevel 1 (
echo [ERROR] Backend build failed
pause
exit /b 1
)
cd ..
echo Building frontend...
cd frontend
docker build -t %FRONTEND_IMAGE% .
if errorlevel 1 (
echo [ERROR] Frontend build failed
pause
exit /b 1
)
cd ..
echo Pushing images...
docker push %BACKEND_IMAGE%
docker push %FRONTEND_IMAGE%
echo Deploying to Kubernetes...
cd brand-master-chart
helm upgrade brand-master . --namespace my-apps --wait --timeout 5m
cd ..
echo.
echo ================================================================
echo Deployment Complete!
echo ================================================================
echo.
echo FIXED ISSUES:
echo ✅ Contact form "full_name" error - FIXED
echo ✅ Password reset "username" error - FIXED
echo ✅ Email sending functionality - ADDED
echo.
echo NEXT STEPS:
echo.
echo 1. CONFIGURE EMAIL (Required for password reset to work):
echo - Read EMAIL_SETUP.md for detailed instructions
echo - Quick setup: Update brand-master-chart/values.yaml with SMTP settings
echo - Or check backend logs for PIN (printed to console if email not configured)
echo.
echo 2. TEST PASSWORD RESET:
echo - Go to login page
echo - Click "Forgot Password"
echo - Enter your email
echo - Check email for PIN (or backend logs if email not configured)
echo - Enter PIN and new password
echo.
echo 3. VIEW BACKEND LOGS:
echo kubectl logs -n my-apps deployment/brand-master-backend -f
echo.
echo 4. CHECK EMAIL CONFIGURATION:
echo kubectl exec -n my-apps deployment/brand-master-backend -- env ^| findstr SMTP
echo.
echo FOR EMAIL SETUP HELP: See EMAIL_SETUP.md
echo.
pause