fix(login): elimina fallback legacy y exige employee_id + PIN correcto
- auth_bp.py: ahora login requiere employee_id. Si el PIN no coincide con el empleado seleccionado, devuelve 401. Ya no escanea todos los empleados ni permite entrar como otro usuario con el mismo PIN. Esto evita que al elegir un usuario se entre como mecanico solo porque comparten PIN.
This commit is contained in:
@@ -90,53 +90,26 @@ def login_pin():
|
||||
|
||||
matched_employee = None
|
||||
|
||||
if employee_id:
|
||||
# Secure flow: user selected an employee, verify only that PIN.
|
||||
cur.execute("""
|
||||
SELECT e.id, e.name, e.pin, e.role, e.branch_id, e.max_discount_pct
|
||||
FROM employees e
|
||||
WHERE e.id = %s AND e.is_active = true AND e.pin IS NOT NULL
|
||||
""", (employee_id,))
|
||||
emp = cur.fetchone()
|
||||
if emp:
|
||||
emp_id, emp_name, emp_pin_hash, emp_role, emp_branch, emp_discount = emp
|
||||
if emp_pin_hash and bcrypt.checkpw(pin.encode(), emp_pin_hash.encode()):
|
||||
matched_employee = {
|
||||
'id': emp_id, 'name': emp_name, 'role': emp_role,
|
||||
'branch_id': emp_branch, 'max_discount_pct': float(emp_discount) if emp_discount else 0
|
||||
}
|
||||
if not employee_id:
|
||||
_record_attempt(device_id, False)
|
||||
cur.close()
|
||||
conn.close()
|
||||
return jsonify({'error': 'Empleado no seleccionado'}), 400
|
||||
|
||||
if not matched_employee:
|
||||
# Legacy fallback: scan active employees (kept for old clients without employee_id)
|
||||
if device_branch_id:
|
||||
cur.execute("""
|
||||
SELECT e.id, e.name, e.pin, e.role, e.branch_id, e.max_discount_pct
|
||||
FROM employees e
|
||||
WHERE e.is_active = true AND e.pin IS NOT NULL AND e.branch_id = %s
|
||||
""", (device_branch_id,))
|
||||
for emp in cur.fetchall():
|
||||
emp_id, emp_name, emp_pin_hash, emp_role, emp_branch, emp_discount = emp
|
||||
if emp_pin_hash and bcrypt.checkpw(pin.encode(), emp_pin_hash.encode()):
|
||||
matched_employee = {
|
||||
'id': emp_id, 'name': emp_name, 'role': emp_role,
|
||||
'branch_id': emp_branch, 'max_discount_pct': float(emp_discount) if emp_discount else 0
|
||||
}
|
||||
break
|
||||
|
||||
if not matched_employee:
|
||||
cur.execute("""
|
||||
SELECT e.id, e.name, e.pin, e.role, e.branch_id, e.max_discount_pct
|
||||
FROM employees e
|
||||
WHERE e.is_active = true AND e.pin IS NOT NULL
|
||||
""")
|
||||
for emp in cur.fetchall():
|
||||
emp_id, emp_name, emp_pin_hash, emp_role, emp_branch, emp_discount = emp
|
||||
if emp_pin_hash and bcrypt.checkpw(pin.encode(), emp_pin_hash.encode()):
|
||||
matched_employee = {
|
||||
'id': emp_id, 'name': emp_name, 'role': emp_role,
|
||||
'branch_id': emp_branch, 'max_discount_pct': float(emp_discount) if emp_discount else 0
|
||||
}
|
||||
break
|
||||
# Verify the PIN only for the selected employee.
|
||||
cur.execute("""
|
||||
SELECT e.id, e.name, e.pin, e.role, e.branch_id, e.max_discount_pct
|
||||
FROM employees e
|
||||
WHERE e.id = %s AND e.is_active = true AND e.pin IS NOT NULL
|
||||
""", (employee_id,))
|
||||
emp = cur.fetchone()
|
||||
if emp:
|
||||
emp_id, emp_name, emp_pin_hash, emp_role, emp_branch, emp_discount = emp
|
||||
if emp_pin_hash and bcrypt.checkpw(pin.encode(), emp_pin_hash.encode()):
|
||||
matched_employee = {
|
||||
'id': emp_id, 'name': emp_name, 'role': emp_role,
|
||||
'branch_id': emp_branch, 'max_discount_pct': float(emp_discount) if emp_discount else 0
|
||||
}
|
||||
|
||||
if not matched_employee:
|
||||
_record_attempt(device_id, False)
|
||||
|
||||
Reference in New Issue
Block a user