3 Commits

Author SHA1 Message Date
1a82a3a8fc docs: add v1.6.1 and v1.6.2 CHANGELOG entries
Documents StatusView eventify_id addition and the security fix
that stops internal Python exceptions from reaching API callers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 09:27:15 +05:30
d182cfe5ee security: never expose internal exceptions to API callers
All except blocks in user.py and events.py now log the real
error server-side (via eventify_logger) and return a generic
"An unexpected server error occurred." message to the client.
Python tracebacks, model field names, and ORM errors are no
longer visible in API responses.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 09:23:26 +05:30
a6e080bf6c feat(api): return eventify_id in StatusView response
Adds `eventify_id` to the `/api/user/status/` endpoint so that
`initProfileTickets` can fetch the EVT-XXXXXXXX badge for users
whose localStorage session pre-dates the eventify_id login field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 09:14:37 +05:30
3 changed files with 50 additions and 19 deletions

View File

@@ -5,6 +5,24 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), version
---
## [1.6.2] — 2026-04-03
### Security
- **Internal exceptions no longer exposed to API callers** — all 15 `except Exception as e` blocks across `mobile_api/views/user.py` and `mobile_api/views/events.py` now log the real error via `eventify_logger` and return a generic `"An unexpected server error occurred."` to the caller
- Affected views: `RegisterView`, `WebRegisterView`, `LoginView`, `StatusView`, `LogoutView`, `UpdateProfileView`, `EventTypeAPI`, `EventListAPI`, `EventDetailAPI`, `EventImagesListAPI`, `EventsByDateAPI`, `DateSheetAPI`, `PincodeEventsAPI`, `FeaturedEventsAPI`, `TopEventsAPI`
- `StatusView` and `UpdateProfileView` were also missing `log(...)` calls entirely — added
- `from eventify_logger.services import log` import added to `events.py` (was absent)
---
## [1.6.1] — 2026-04-03
### Added
- **`eventify_id` in `StatusView` response** (`/api/user/status/`) — consumer app uses this to refresh the Eventify ID badge (`EVT-XXXXXXXX`) for sessions that pre-date the `eventify_id` login field
- **`accounts` migration `0012_user_eventify_id` deployed to production containers** — backfilled all existing users with unique Eventify IDs; previously the migration existed locally but had not been applied in production
---
## [1.6.0] — 2026-04-02
### Added

View File

@@ -13,6 +13,7 @@ from datetime import datetime, timedelta
import calendar
import math
from mobile_api.utils import validate_token_and_get_user
from eventify_logger.services import log
def _haversine_km(lat1, lon1, lat2, lon2):
@@ -43,7 +44,8 @@ class EventTypeListAPIView(APIView):
event_types.append(event_type_data)
return JsonResponse({"status": "success", "event_types": event_types})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
log("error", "EventTypeAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse({"status": "error", "message": "An unexpected server error occurred."})
class EventListAPI(APIView):
@@ -198,7 +200,8 @@ class EventListAPI(APIView):
"radius_km": used_radius,
})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
log("error", "EventListAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse({"status": "error", "message": "An unexpected server error occurred."})
class EventDetailAPI(APIView):
@@ -224,7 +227,8 @@ class EventDetailAPI(APIView):
event_data["images"] = event_images_list
return JsonResponse(event_data)
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
log("error", "EventDetailAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse({"status": "error", "message": "An unexpected server error occurred."})
class EventImagesListAPI(APIView):
@@ -252,8 +256,9 @@ class EventImagesListAPI(APIView):
return JsonResponse(res_data)
except Exception as e:
log("error", "EventImagesListAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse(
{"status": "error", "message": str(e)},
{"status": "error", "message": "An unexpected server error occurred."},
)
@@ -291,8 +296,9 @@ class EventsByCategoryAPI(APIView):
})
except Exception as e:
log("error", "EventsByDateAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse(
{"status": "error", "message": str(e)},
{"status": "error", "message": "An unexpected server error occurred."},
)
@@ -415,8 +421,9 @@ class EventsByMonthYearAPI(APIView):
})
except Exception as e:
log("error", "DateSheetAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse(
{"status": "error", "message": str(e)},
{"status": "error", "message": "An unexpected server error occurred."},
)
@@ -473,8 +480,9 @@ class EventsByDateAPI(APIView):
})
except Exception as e:
log("error", "PincodeEventsAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse(
{"status": "error", "message": str(e)},
{"status": "error", "message": "An unexpected server error occurred."},
)
@@ -503,7 +511,8 @@ class FeaturedEventsAPI(APIView):
return JsonResponse({"status": "success", "events": event_list})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
log("error", "FeaturedEventsAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse({"status": "error", "message": "An unexpected server error occurred."})
@method_decorator(csrf_exempt, name='dispatch')
@@ -531,4 +540,5 @@ class TopEventsAPI(APIView):
return JsonResponse({"status": "success", "events": event_list})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)})
log("error", "TopEventsAPI exception", request=request, logger_data={"error": str(e)})
return JsonResponse({"status": "error", "message": "An unexpected server error occurred."})

View File

@@ -29,7 +29,7 @@ class RegisterView(View):
return JsonResponse({'errors': form.errors}, status=400)
except Exception as e:
log("error", "API registration exception", request=request, logger_data={"error": str(e)})
return JsonResponse({'error': str(e)}, status=500)
return JsonResponse({'error': 'An unexpected server error occurred. Please try again.'}, status=500)
@method_decorator(csrf_exempt, name='dispatch')
@@ -64,7 +64,7 @@ class WebRegisterView(View):
return JsonResponse({'errors': form.errors}, status=400)
except Exception as e:
log("error", "Web registration exception", request=request, logger_data={"error": str(e)})
return JsonResponse({'error': str(e)}, status=500)
return JsonResponse({'error': 'An unexpected server error occurred. Please try again.'}, status=500)
@method_decorator(csrf_exempt, name='dispatch')
@@ -108,7 +108,7 @@ class LoginView(View):
return JsonResponse(simplify_form_errors(form), status=401)
except Exception as e:
log("error", "API login exception", request=request, logger_data={"error": str(e)})
return JsonResponse({'error': str(e)}, status=500)
return JsonResponse({'error': 'An unexpected server error occurred. Please try again.'}, status=500)
@method_decorator(csrf_exempt, name='dispatch')
@@ -122,11 +122,13 @@ class StatusView(View):
return JsonResponse({
"status": "logged_in",
"username": user.username,
"email": user.email
"email": user.email,
"eventify_id": user.eventify_id or '',
})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)}, status=500)
log("error", "API status exception", request=request, logger_data={"error": str(e)})
return JsonResponse({"status": "error", "message": "An unexpected server error occurred."}, status=500)
@method_decorator(csrf_exempt, name='dispatch')
@@ -151,7 +153,7 @@ class LogoutView(View):
except Exception as e:
log("error", "API logout exception", request=request, logger_data={"error": str(e)})
return JsonResponse({"status": "error", "message": str(e)}, status=500)
return JsonResponse({"status": "error", "message": "An unexpected server error occurred."}, status=500)
@method_decorator(csrf_exempt, name='dispatch')
@@ -329,7 +331,8 @@ class UpdateProfileView(View):
}, status=400)
except Exception as e:
log("error", "API update profile exception", request=request, logger_data={"error": str(e)})
return JsonResponse({
'success': False,
'error': str(e)
'error': 'An unexpected server error occurred. Please try again.'
}, status=500)