~jae/dn0magik-mc

6063499afc59c3605388f4b7f685b8f5ca03da38 — Jae Lo Presti (DN0) 1 year, 8 months ago 8a7ba90
API: Full functional login sequence

Fixes:
 - Abandon base64 for simplicy's sake

Additions:
 - Profile endpoint that returns skins and capes (/minecraft/profile)

TODO:
 - Correct skin server
3 files changed, 61 insertions(+), 9 deletions(-)

M src/api/userapi.py
M src/utils/dbutils.py
M src/utils/secretsutil.py
M src/api/userapi.py => src/api/userapi.py +46 -3
@@ 8,7 8,7 @@ from utils.dbutils import (
    verify_login,
    get_user_remoteid,
)
from utils.secretsutil import encode_auth_jwt
from utils.secretsutil import encode_auth_jwt, check_auth_jwt

user_api = Blueprint("user_api", __name__)



@@ 100,7 100,7 @@ def userapi_auth():
                {"name": "preferredLanguage", "value": "en-us"},
                {"name": "registrationCountry", "value": "SAV"},
            ],
            "id": 1,
            "id": remoteid,
        },
        "clientToken": client_token,
        "accessToken": auth_jwt,


@@ 108,6 108,49 @@ def userapi_auth():
        "selectedProfile": {"name": username, "id": user_uuid},
    }

    print(res)
    return jsonify(res), 200


@user_api.get("/minecraft/profile")
def userapi_minecraft_profile():
    data = request.headers.get("Authorization")

    if not data:
        res = {
            "error": "ForbiddenOperationException",
            "errorMessage": "Incorrect login or password",
        }
        return jsonify(res), 400

    token = data.replace("Bearer ", "")

    jwt_check = check_auth_jwt(token)

    if not jwt_check:
        res = {
            "error": "ForbiddenOperationException",
            "errorMessage": "Incorrect login or password",
        }
        return jsonify(res), 400

    username = jwt_check["sub"]
    uuid = get_uuid_from_username(username)

    # TODO: GET SKINS

    res = {
        "id": uuid,
        "name": username,
        "skins": [
            {
                "id": "8c94945e-d0b4-4df8-97d1-d8d397624f93",
                "state": "ACTIVE",
                # TEMPORARY
                "url": "https://bm.jae.fi/default.png",
                "variant": "SLIM",
            }
        ],
        "CAPES": [],
    }

    return jsonify(res), 200

M src/utils/dbutils.py => src/utils/dbutils.py +1 -1
@@ 101,4 101,4 @@ def get_user_remoteid(username: str):
    if not user_exists:
        return None

    return str(b64encode(str(user_exists.id).encode("ascii")))
    return user_exists.id

M src/utils/secretsutil.py => src/utils/secretsutil.py +14 -5
@@ 12,13 12,13 @@ JWT_SECRET_KEY = environ.get("JWT_SECRET_KEY")

def encode_auth_jwt(username: str, client_token: str):
    # IF THERE IS A GOD, HE WEEPS
    user_base = str(b64encode(username.encode("ascii")))
    token_base = str(b64encode(client_token.encode("ascii")))
    # user_base = str(b64encode(username.encode("ascii")))
    # token_base = str(b64encode(client_token.encode("ascii")))

    payload = {
        "sub": user_base,
        "yggt": token_base,
        "spr": user_base,
        "sub": username,
        "yggt": client_token,
        "spr": username,
        "iss": "dn0magik",
        "exp": int(time()) + 86400 * 180,
        "iat": int(time()),


@@ 27,3 27,12 @@ def encode_auth_jwt(username: str, client_token: str):
    encoded_jwt = encode(payload, JWT_SECRET_KEY, algorithm="HS256")

    return encoded_jwt


def check_auth_jwt(token: str):
    try:
        data = decode(token, JWT_SECRET_KEY, algorithms=["HS256"])
    except:
        return None

    return data