This commit is contained in:
5t4l1n
2025-07-25 11:10:44 +05:30
parent 4455b39267
commit 7e6f0d0b1e
32 changed files with 2093 additions and 15 deletions
+99
View File
@@ -0,0 +1,99 @@
from flask import Blueprint, request, jsonify, current_app
import jwt
from datetime import datetime, timedelta
import uuid
bp = Blueprint('auth', __name__)
@bp.route('/nonce', methods=['POST'])
async def get_nonce():
"""Generate nonce for wallet signature"""
data = request.get_json()
wallet_address = data.get('wallet_address')
if not wallet_address:
return jsonify({"error": "Wallet address required"}), 400
web3_service = current_app.config['WEB3_SERVICE']
nonce = web3_service.generate_nonce()
# Store nonce temporarily (in production, use Redis)
message = f"Sign this message to authenticate with OpenLearnX: {nonce}"
return jsonify({
"nonce": nonce,
"message": message
})
@bp.route('/verify', methods=['POST'])
async def verify_signature():
"""Verify MetaMask signature and create session"""
data = request.get_json()
wallet_address = data.get('wallet_address')
signature = data.get('signature')
message = data.get('message')
if not all([wallet_address, signature, message]):
return jsonify({"error": "Missing required fields"}), 400
web3_service = current_app.config['WEB3_SERVICE']
mongo_service = current_app.config['MONGO_SERVICE']
# Verify signature
if not web3_service.verify_signature(wallet_address, message, signature):
return jsonify({"error": "Invalid signature"}), 401
# Create or get user
user = await mongo_service.create_user(wallet_address)
await mongo_service.update_user_login(wallet_address)
# Create JWT token
token_payload = {
'user_id': str(user['_id']),
'wallet_address': wallet_address,
'exp': datetime.utcnow() + timedelta(days=7)
}
token = jwt.encode(
token_payload,
current_app.config['SECRET_KEY'],
algorithm='HS256'
)
return jsonify({
"success": True,
"token": token,
"user": {
"id": str(user['_id']),
"wallet_address": user['wallet_address'],
"created_at": user['created_at'].isoformat(),
"total_tests": user.get('total_tests', 0),
"certificates": len(user.get('certificates', []))
}
})
@bp.route('/profile', methods=['GET'])
async def get_profile():
"""Get user profile"""
token = request.headers.get('Authorization', '').replace('Bearer ', '')
if not token:
return jsonify({"error": "Token required"}), 401
try:
payload = jwt.decode(
token,
current_app.config['SECRET_KEY'],
algorithms=['HS256']
)
user_id = payload['user_id']
mongo_service = current_app.config['MONGO_SERVICE']
analytics = await mongo_service.get_user_analytics(user_id)
return jsonify(analytics)
except jwt.ExpiredSignatureError:
return jsonify({"error": "Token expired"}), 401
except jwt.InvalidTokenError:
return jsonify({"error": "Invalid token"}), 401