Rate-limit public bookings per contact; add direct owner contact endpoint
Test backoffice (smb-crm) / test (push) Successful in 1m43s
Test backoffice (smb-crm) / test (push) Successful in 1m43s
Public booking API now rejects a 6th active booking from the same customer_contact within 24h (429), stopping one contact from filling every slot on every resource, while owner-entered manual bookings stay unaffected. Add POST /api/contact: client sites can reach their own owner's inbox directly (via their existing login email) for general inquiries, separate from the agency's leads/Telegram pipeline (n8n/lead-intake.json), which stays reserved for actual prospects contacting the agency itself. Paris Barber Shop's contact form and Rückruf widget now point here; the Rückruf floating widget itself has been removed from the site. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,13 @@ bp = Blueprint("booking_api", __name__, url_prefix="/api/booking")
|
||||
TOKEN_SECRET = os.environ.get("BOOKING_TOKEN_SECRET", "")
|
||||
TOKEN_TTL_DAYS = 30
|
||||
|
||||
# Per-contact rate limit on the public booking endpoint: stops one phone
|
||||
# number/email from filling every slot on every resource. Deliberately not
|
||||
# applied to owner_booking.py's manual-entry path (source="owner") -- it
|
||||
# calls create_booking_row directly, never through this route.
|
||||
CONTACT_BOOKING_LIMIT = 5
|
||||
CONTACT_BOOKING_WINDOW_HOURS = 24
|
||||
|
||||
|
||||
def _mint_manage_token(client_id, booking_id):
|
||||
payload = {
|
||||
@@ -290,6 +297,13 @@ def create_booking():
|
||||
and body.get("customer_name") and body.get("customer_contact")):
|
||||
return jsonify({"error": "client_id, resource_id, service_id, start_time, "
|
||||
"customer_name, customer_contact are required"}), 400
|
||||
|
||||
since = datetime.now(timezone.utc) - timedelta(hours=CONTACT_BOOKING_WINDOW_HOURS)
|
||||
recent = bdb.count_recent_bookings_by_contact(
|
||||
client_id, body["customer_contact"], since)
|
||||
if recent >= CONTACT_BOOKING_LIMIT:
|
||||
return jsonify({"error": "too many recent bookings for this contact"}), 429
|
||||
|
||||
try:
|
||||
booking, token = create_booking_row(
|
||||
client_id, resource_id, service_id, start_time,
|
||||
|
||||
Reference in New Issue
Block a user