You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.6 KiB
Python
91 lines
2.6 KiB
Python
2 years ago
|
import json
|
||
|
|
||
|
from quart import Blueprint, jsonify, request
|
||
|
from flask_login import current_user
|
||
|
|
||
|
from flipbook.helpers import verify_signature
|
||
|
from flipbook.models import Wallet, rand_id
|
||
|
|
||
|
|
||
|
bp = Blueprint('api', 'api', url_prefix='/api/v1')
|
||
|
|
||
|
|
||
|
@bp.route('/user_authenticated')
|
||
|
async def user_authenticated():
|
||
|
"""
|
||
|
Check to see if sender is authenticated.
|
||
|
Useful for AJAX calls to "check" we're still authenticated
|
||
|
instead of assuming (especially with old, loaded forms/pages).
|
||
|
"""
|
||
|
return jsonify(current_user.is_authenticated)
|
||
|
|
||
|
|
||
|
@bp.route('/user_exists/<wallet_address>')
|
||
|
async def user_exists(wallet_address):
|
||
|
"""
|
||
|
Check to see if a given wallet exists in the database.
|
||
|
This logic will help the login/connect MetaMask flow.
|
||
|
"""
|
||
|
nonce = rand_id()
|
||
|
wallet = Wallet.select().where(
|
||
|
Wallet.address == wallet_address.lower()
|
||
|
).first()
|
||
|
if wallet:
|
||
|
nonce = wallet.nonce
|
||
|
return jsonify({
|
||
|
'user_exists': wallet is not None,
|
||
|
'nonce': nonce,
|
||
|
'success': True
|
||
|
})
|
||
|
|
||
|
|
||
|
@bp.route('/authenticate/metamask', methods=['POST'])
|
||
|
async def authenticate_metamask():
|
||
|
"""
|
||
|
This is the login/authenticate route for this dApp.
|
||
|
Users POST a `signedData` blob, a message signed by the user with MetaMask
|
||
|
(`personal_sign` method).
|
||
|
This route will verify the signed data against the user's public ETH
|
||
|
address. If no user exists, they get an entry in the database.
|
||
|
If user does exist, they get logged in.
|
||
|
"""
|
||
|
data = await request.get_data()
|
||
|
data = json.loads(data)
|
||
|
if current_user.is_authenticated:
|
||
|
return jsonify({
|
||
|
'success': False,
|
||
|
'message': 'Already registered and authenticated.'
|
||
|
})
|
||
|
|
||
|
_u = Wallet.select().where(
|
||
|
Wallet.address == data['public_address']
|
||
|
).first()
|
||
|
|
||
|
if _u:
|
||
|
if data['message'].endswith(_u.nonce):
|
||
|
if verify_signature(data['message'], data['signed_data'], data['public_address']):
|
||
|
_u.login()
|
||
|
return jsonify({
|
||
|
'success': True,
|
||
|
'message': 'Logged in'
|
||
|
})
|
||
|
else:
|
||
|
return jsonify({
|
||
|
'success': False,
|
||
|
'message': 'Invalid signature'
|
||
|
})
|
||
|
else:
|
||
|
return jsonify({
|
||
|
'success': False,
|
||
|
'message': 'Invalid nonce in signed message'
|
||
|
})
|
||
|
else:
|
||
|
w = Wallet(
|
||
|
address=data['public_address'].lower()
|
||
|
)
|
||
|
w.save()
|
||
|
w.login()
|
||
|
return jsonify({
|
||
|
'success': True,
|
||
|
'message': 'Registered'
|
||
|
})
|