updates
This commit is contained in:
@@ -1,34 +1,94 @@
|
||||
# ============================================
|
||||
# Hotel Booking API - Environment Variables
|
||||
# ============================================
|
||||
# Copy this file to .env and fill in your actual values
|
||||
# All variables are optional and have sensible defaults
|
||||
# See src/config/settings.py for default values
|
||||
|
||||
# ============================================
|
||||
# Email/SMTP Configuration
|
||||
# Application Configuration
|
||||
# ============================================
|
||||
# SMTP Server Settings
|
||||
SMTP_HOST=smtp.gmail.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your-email@gmail.com
|
||||
SMTP_PASSWORD=your-app-specific-password
|
||||
|
||||
# Email Sender Information
|
||||
SMTP_FROM_EMAIL=noreply@yourdomain.com
|
||||
SMTP_FROM_NAME=Hotel Booking
|
||||
|
||||
# Alternative: Legacy environment variable names (for backward compatibility)
|
||||
# MAIL_HOST=smtp.gmail.com
|
||||
# MAIL_PORT=587
|
||||
# MAIL_USER=your-email@gmail.com
|
||||
# MAIL_PASS=your-app-specific-password
|
||||
# MAIL_FROM=noreply@yourdomain.com
|
||||
# MAIL_SECURE=false
|
||||
ENVIRONMENT=development
|
||||
# Options: development, staging, production
|
||||
DEBUG=true
|
||||
# Set to false in production
|
||||
HOST=0.0.0.0
|
||||
PORT=8000
|
||||
API_V1_PREFIX=/api/v1
|
||||
|
||||
# ============================================
|
||||
# Other Required Variables
|
||||
# Database Configuration
|
||||
# ============================================
|
||||
CLIENT_URL=http://localhost:5173
|
||||
DB_USER=root
|
||||
DB_PASS=your_database_password
|
||||
DB_NAME=hotel_db
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
JWT_SECRET=your-super-secret-jwt-key-change-in-production
|
||||
DB_USER=root
|
||||
DB_PASS=
|
||||
# Leave empty if using MySQL without password
|
||||
DB_NAME=hotel_db
|
||||
|
||||
# ============================================
|
||||
# JWT Authentication
|
||||
# ============================================
|
||||
# JWT_SECRET will be auto-generated on startup if not set
|
||||
# The generated secret will be saved here automatically
|
||||
JWT_ALGORITHM=HS256
|
||||
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
|
||||
|
||||
# ============================================
|
||||
# CORS & Client Configuration
|
||||
# ============================================
|
||||
CLIENT_URL=http://localhost:5173
|
||||
# Frontend application URL
|
||||
CORS_ORIGINS=["http://localhost:5173","http://localhost:3000","http://127.0.0.1:5173"]
|
||||
# JSON array of allowed origins (only used in production)
|
||||
|
||||
# ============================================
|
||||
# Email & Payment Settings
|
||||
# ============================================
|
||||
# NOTE: Email (SMTP) and Payment Gateway (Stripe, PayPal) settings
|
||||
# are configured in the Admin Dashboard, not via environment variables.
|
||||
# Log in as admin and go to Settings page to configure these.
|
||||
|
||||
# ============================================
|
||||
# Redis Configuration (Optional)
|
||||
# ============================================
|
||||
REDIS_ENABLED=false
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_DB=0
|
||||
REDIS_PASSWORD=
|
||||
# Leave empty if Redis has no password
|
||||
|
||||
# ============================================
|
||||
# File Upload Configuration
|
||||
# ============================================
|
||||
UPLOAD_DIR=uploads
|
||||
MAX_UPLOAD_SIZE=5242880
|
||||
# Max upload size in bytes (5MB default)
|
||||
ALLOWED_EXTENSIONS=["jpg","jpeg","png","gif","webp"]
|
||||
# JSON array
|
||||
|
||||
# ============================================
|
||||
# Rate Limiting
|
||||
# ============================================
|
||||
RATE_LIMIT_ENABLED=true
|
||||
RATE_LIMIT_PER_MINUTE=60
|
||||
|
||||
# ============================================
|
||||
# Logging Configuration
|
||||
# ============================================
|
||||
LOG_LEVEL=INFO
|
||||
# Options: DEBUG, INFO, WARNING, ERROR, CRITICAL
|
||||
LOG_FILE=logs/app.log
|
||||
LOG_MAX_BYTES=10485760
|
||||
# Max log file size in bytes (10MB)
|
||||
LOG_BACKUP_COUNT=5
|
||||
|
||||
# ============================================
|
||||
# Server Configuration
|
||||
# ============================================
|
||||
REQUEST_TIMEOUT=30
|
||||
# Request timeout in seconds (0 to disable)
|
||||
HEALTH_CHECK_INTERVAL=30
|
||||
# Health check interval in seconds
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import bcrypt
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
from src.config.database import SessionLocal
|
||||
from src.models.user import User
|
||||
from src.config.logging_config import setup_logging
|
||||
|
||||
logger = setup_logging()
|
||||
|
||||
|
||||
def hash_password(password: str) -> str:
|
||||
password_bytes = password.encode('utf-8')
|
||||
salt = bcrypt.gensalt()
|
||||
hashed = bcrypt.hashpw(password_bytes, salt)
|
||||
return hashed.decode('utf-8')
|
||||
|
||||
|
||||
def reset_password(db: Session, email: str, new_password: str) -> bool:
|
||||
user = db.query(User).filter(User.email == email).first()
|
||||
|
||||
if not user:
|
||||
print(f"❌ User with email '{email}' not found")
|
||||
return False
|
||||
|
||||
hashed_password = hash_password(new_password)
|
||||
|
||||
user.password = hashed_password
|
||||
db.commit()
|
||||
db.refresh(user)
|
||||
|
||||
print(f"✅ Password reset for {email}")
|
||||
print(f" New password: {new_password}")
|
||||
print(f" Hash length: {len(user.password)} characters")
|
||||
print()
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
db = SessionLocal()
|
||||
|
||||
try:
|
||||
print("="*80)
|
||||
print("RESETTING TEST USER PASSWORDS")
|
||||
print("="*80)
|
||||
print()
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error: {e}", exc_info=True)
|
||||
print(f"\n❌ Error: {e}")
|
||||
db.rollback()
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Binary file not shown.
@@ -11,6 +11,9 @@ from slowapi.errors import RateLimitExceeded
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
import sys
|
||||
import secrets
|
||||
import os
|
||||
import re
|
||||
from .config.settings import settings
|
||||
from .config.logging_config import setup_logging, get_logger
|
||||
from .config.database import engine, Base, get_db
|
||||
@@ -151,8 +154,50 @@ app.include_router(page_content_routes.router, prefix='/api')
|
||||
app.include_router(page_content_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
logger.info('All routes registered successfully')
|
||||
|
||||
def ensure_jwt_secret():
|
||||
"""Generate and save JWT secret if it's using the default value."""
|
||||
default_secret = 'dev-secret-key-change-in-production-12345'
|
||||
current_secret = settings.JWT_SECRET
|
||||
|
||||
if not current_secret or current_secret == default_secret:
|
||||
new_secret = secrets.token_urlsafe(64)
|
||||
|
||||
os.environ['JWT_SECRET'] = new_secret
|
||||
|
||||
env_file = Path(__file__).parent.parent / '.env'
|
||||
if env_file.exists():
|
||||
try:
|
||||
env_content = env_file.read_text(encoding='utf-8')
|
||||
|
||||
jwt_pattern = re.compile(r'^JWT_SECRET=.*$', re.MULTILINE)
|
||||
|
||||
if jwt_pattern.search(env_content):
|
||||
env_content = jwt_pattern.sub(f'JWT_SECRET={new_secret}', env_content)
|
||||
else:
|
||||
jwt_section_pattern = re.compile(r'(# =+.*JWT.*=+.*\n)', re.IGNORECASE | re.MULTILINE)
|
||||
match = jwt_section_pattern.search(env_content)
|
||||
if match:
|
||||
insert_pos = match.end()
|
||||
env_content = env_content[:insert_pos] + f'JWT_SECRET={new_secret}\n' + env_content[insert_pos:]
|
||||
else:
|
||||
env_content += f'\nJWT_SECRET={new_secret}\n'
|
||||
|
||||
env_file.write_text(env_content, encoding='utf-8')
|
||||
logger.info('✓ JWT secret generated and saved to .env file')
|
||||
except Exception as e:
|
||||
logger.warning(f'Could not update .env file: {e}')
|
||||
logger.info(f'Generated JWT secret (add to .env manually): JWT_SECRET={new_secret}')
|
||||
else:
|
||||
logger.info(f'Generated JWT secret (add to .env file): JWT_SECRET={new_secret}')
|
||||
|
||||
logger.info('✓ Secure JWT secret generated automatically')
|
||||
else:
|
||||
logger.info('✓ JWT secret is configured')
|
||||
|
||||
@app.on_event('startup')
|
||||
async def startup_event():
|
||||
ensure_jwt_secret()
|
||||
|
||||
logger.info(f'{settings.APP_NAME} started successfully')
|
||||
logger.info(f'Environment: {settings.ENVIRONMENT}')
|
||||
logger.info(f'Debug mode: {settings.DEBUG}')
|
||||
|
||||
Reference in New Issue
Block a user