from flask import Blueprint, request, jsonify from flask_jwt_extended import jwt_required, get_jwt_identity from .database import db, PushDevice, User device_bp = Blueprint('devices', __name__, url_prefix='/api/devices') @device_bp.route('', methods=['POST']) @jwt_required() def register_device(): current_user_id = get_jwt_identity() data = request.get_json() if not data: return jsonify({"error": "Request must be JSON"}), 400 device_type = data.get('type') token = data.get('token') if not device_type or not token: return jsonify({"error": "Missing 'type' or 'token'"}), 400 if device_type not in ['web', 'ios', 'android']: return jsonify({"error": "Invalid device type"}), 400 # Check if token already exists to prevent duplicates existing = PushDevice.query.filter_by(token=token).first() if existing: # Optional: Update user_id if token somehow got registered by another user? # Or just return OK indicating it's known if existing.user_id != current_user_id: # Decide handling: update owner or error? Let's update. existing.user_id = current_user_id db.session.commit() print(f"Warning: Push token {token[:10]}... re-assigned to user {current_user_id}") return jsonify({"message": "Device already registered"}), 200 new_device = PushDevice( user_id=current_user_id, device_type=device_type, token=token ) db.session.add(new_device) try: db.session.commit() return jsonify({"message": "Device registered successfully"}), 201 except Exception as e: db.session.rollback() # Could be unique constraint violation if race condition, or DB error print(f"Error registering device: {e}") # Check again if it exists now (due to race condition) existing = PushDevice.query.filter_by(token=token).first() if existing: return jsonify({"message": "Device already registered"}), 200 return jsonify({"error": "Failed to register device"}), 500 @device_bp.route('/', methods=['DELETE']) @jwt_required() def unregister_device(token_prefix): # Note: Deleting by full token in URL can be problematic (length, encoding). # A better approach might be POST /api/devices/unregister { "token": "..." } # Or require the client to store the device ID returned on registration and use that. # For simplicity now, we'll assume we search by token. current_user_id = get_jwt_identity() # This is inefficient if tokens are long. A dedicated device ID is better. # Let's simulate finding based on a prefix if needed, but ideally use full token from body # device = PushDevice.query.filter(PushDevice.token.like(f'{token_prefix}%'), PushDevice.user_id==current_user_id).first() # --- Alternative using request body --- data = request.get_json() token_to_delete = data.get('token') if data else None if not token_to_delete: return jsonify({"error": "Token required in request body for deletion"}), 400 device = PushDevice.query.filter_by(token=token_to_delete, user_id=current_user_id).first() if not device: return jsonify({"error": "Device not found or not owned by user"}), 404 db.session.delete(device) db.session.commit() return '', 204