import json from flask import Blueprint, flash, jsonify, redirect, request, url_for from flask_login import current_user, login_required, login_user from app import db from app.passkey_service import ( authentication_options, delete_passkey, registration_options, verify_authentication, verify_registration, ) from webauthn.helpers.options_to_json import options_to_json bp = Blueprint("passkey", __name__, url_prefix="/auth/passkey") @bp.route("/register/options", methods=["POST"]) @login_required def register_options(): options = registration_options(current_user) return jsonify(json.loads(options_to_json(options))) @bp.route("/register/verify", methods=["POST"]) @login_required def register_verify(): data = request.get_json(silent=True) or {} name = data.get("name", "Passkey") credential = data.get("credential") if not credential: return jsonify({"error": "Нет данных passkey"}), 400 try: passkey = verify_registration(current_user, credential, name) return jsonify({"ok": True, "id": passkey.id, "name": passkey.name}) except Exception as exc: return jsonify({"error": str(exc)}), 400 @bp.route("/login/options", methods=["POST"]) def login_options(): from app.models import User username = (request.get_json(silent=True) or {}).get("username", "").strip() if not username: return jsonify({"error": "Укажите логин или email"}), 400 user = User.query.filter( (User.username == username) | (User.email == username.lower()) ).first() if not user or not user.is_active: return jsonify({"error": "Passkey не найден для этого аккаунта"}), 404 try: options = authentication_options(user) return jsonify(json.loads(options_to_json(options))) except ValueError as exc: return jsonify({"error": str(exc)}), 400 @bp.route("/login/verify", methods=["POST"]) def login_verify(): from app.folder_utils import process_pending_invites from app.session_service import create_user_session data = request.get_json(silent=True) or {} credential = data.get("credential") remember = bool(data.get("remember")) if not credential: return jsonify({"error": "Нет данных passkey"}), 400 try: user = verify_authentication(credential) if not user.is_active: return jsonify({"error": "Аккаунт заблокирован"}), 403 login_user(user, remember=remember) create_user_session(user, remember=remember) process_pending_invites(user) redirect_url = url_for("admin.dashboard") if user.is_admin else url_for("cabinet.index") return jsonify({"ok": True, "redirect": redirect_url}) except Exception as exc: return jsonify({"error": str(exc)}), 400