fix(audit): corrige errores criticos y mayores, mejora UX/accesibilidad y optimiza rendimiento
- Arregla @require_auth, permisos, race conditions, locks de caja/stock - Elimina N+1 en layaway, flotilla, dashboard y global_invoice - Asegura folios atomicos para CFDI, ordenes de servicio y polizas - Protege client_secret de MercadoLibre en backend - Conecta botones/filtros de config, customers, accounting e invoicing - Mejora accesibilidad (labels/aria-label) y estados de carga/vacio - Limpia accounting.js obsoleto y consolida accounting.v9.js - Actualiza cache busting a v32 y Service Worker a v32 - Documenta todo en docs/AUDIT_Y_MEJORAS_2026-06-15.md Tests: 35 passed
This commit is contained in:
@@ -24,6 +24,8 @@ Routes:
|
||||
POST /pos/api/marketplace-ext/webhook/meli
|
||||
"""
|
||||
|
||||
import urllib.parse
|
||||
|
||||
from flask import Blueprint, request, jsonify, g
|
||||
from middleware import require_auth, has_permission
|
||||
from tenant_db import get_tenant_conn, get_master_conn
|
||||
@@ -81,6 +83,49 @@ def get_config():
|
||||
conn.close()
|
||||
|
||||
|
||||
@marketplace_ext_bp.route("/connect/init", methods=["POST"])
|
||||
@require_auth()
|
||||
def init_meli_connect():
|
||||
"""Store client credentials server-side and return the MercadoLibre auth URL.
|
||||
|
||||
The frontend no longer keeps the client_secret in localStorage.
|
||||
"""
|
||||
err = _require_meli_manage()
|
||||
if err:
|
||||
return err
|
||||
|
||||
data = request.get_json() or {}
|
||||
client_id = data.get("client_id", "").strip()
|
||||
client_secret = data.get("client_secret", "").strip()
|
||||
category = data.get("category", "").strip()
|
||||
shipping = data.get("shipping", "").strip()
|
||||
|
||||
if not client_id or not client_secret:
|
||||
return jsonify({"error": "client_id and client_secret required"}), 400
|
||||
|
||||
base = _get_public_base_url().rstrip("/")
|
||||
redirect_uri = f"{base}/pos/marketplace-external/callback"
|
||||
|
||||
conn = get_tenant_conn(g.tenant_id)
|
||||
try:
|
||||
meli_svc.save_meli_config(conn, {
|
||||
"meli_client_id": client_id,
|
||||
"meli_client_secret": client_secret,
|
||||
"meli_default_category_id": category,
|
||||
"meli_shipping_mode": shipping,
|
||||
})
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
auth_url = (
|
||||
"https://auth.mercadolibre.com.mx/authorization?response_type=code"
|
||||
f"&client_id={urllib.parse.quote(client_id)}"
|
||||
f"&redirect_uri={urllib.parse.quote(redirect_uri)}"
|
||||
"&scope=read+write+offline_access"
|
||||
)
|
||||
return jsonify({"auth_url": auth_url, "redirect_uri": redirect_uri})
|
||||
|
||||
|
||||
@marketplace_ext_bp.route("/connect", methods=["POST"])
|
||||
@require_auth()
|
||||
def connect_meli():
|
||||
@@ -90,12 +135,21 @@ def connect_meli():
|
||||
|
||||
data = request.get_json() or {}
|
||||
code = data.get("code")
|
||||
client_id = data.get("client_id")
|
||||
client_secret = data.get("client_secret")
|
||||
redirect_uri = data.get("redirect_uri", "")
|
||||
|
||||
if not code or not client_id or not client_secret:
|
||||
return jsonify({"error": "code, client_id and client_secret required"}), 400
|
||||
if not code:
|
||||
return jsonify({"error": "code required"}), 400
|
||||
|
||||
conn = get_tenant_conn(g.tenant_id)
|
||||
try:
|
||||
cfg = meli_svc.get_meli_config(conn)
|
||||
client_id = data.get("client_id") or cfg.get("meli_client_id")
|
||||
client_secret = data.get("client_secret") or cfg.get("meli_client_secret")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
if not client_id or not client_secret:
|
||||
return jsonify({"error": "ML credentials not configured"}), 400
|
||||
|
||||
try:
|
||||
token_data = MeliService.exchange_code(code, client_id, client_secret, redirect_uri)
|
||||
|
||||
Reference in New Issue
Block a user