# Path: flask_jwt_extended/exceptions.py
# class CSRFError(JWTExtendedException):
#     """
#     An error with CSRF protection
#     """
# 
#     pass
# 
# Path: flask_jwt_extended/exceptions.py
# class JWTDecodeError(JWTExtendedException):
#     """
#     An error decoding a JWT
#     """
# 
#     pass
# 
# Path: flask_jwt_extended/typing.py



import uuid
import jwt
from datetime import datetime
from datetime import timedelta
from datetime import timezone
from hmac import compare_digest
from typing import Any
from typing import Iterable
from typing import List
from typing import Type
from typing import Union
from flask.json import JSONEncoder
from flask_jwt_extended.exceptions import CSRFError
from flask_jwt_extended.exceptions import JWTDecodeError
from flask_jwt_extended.typing import ExpiresDelta

    # This call verifies the ext, iat, and nbf claims
    # This optionally verifies the exp and aud claims if enabled
    decoded_token = jwt.decode(
        encoded_token,
        secret,
        algorithms=algorithms,
        audience=audience,
        issuer=issuer,
        leeway=leeway,
        options=options,
    )

    # Make sure that any custom claims we expect in the token are present
    if identity_claim_key not in decoded_token:
        raise JWTDecodeError("Missing claim: {}".format(identity_claim_key))

    if "type" not in decoded_token:
        decoded_token["type"] = "access"

    if "fresh" not in decoded_token:
        decoded_token["fresh"] = False

    if "jti" not in decoded_token:
        decoded_token["jti"] = None

    if csrf_value:
        if "csrf" not in decoded_token:
            raise JWTDecodeError("Missing claim: csrf")
        if not compare_digest(decoded_token["csrf"], csrf_value):

# Path: flask_jwt_extended/exceptions.py
# class CSRFError(JWTExtendedException):
#     """
#     An error with CSRF protection
#     """
# 
#     pass
# 
# Path: flask_jwt_extended/exceptions.py
# class JWTDecodeError(JWTExtendedException):
#     """
#     An error decoding a JWT
#     """
# 
#     pass
# 
# Path: flask_jwt_extended/typing.py



# Path: flask_jwt_extended/tokens.py
import uuid
import jwt
from datetime import datetime
from datetime import timedelta
from datetime import timezone
from hmac import compare_digest
from typing import Any
from typing import Iterable
from typing import List
from typing import Type
from typing import Union
from flask.json import JSONEncoder
from flask_jwt_extended.exceptions import CSRFError
from flask_jwt_extended.exceptions import JWTDecodeError
from flask_jwt_extended.typing import ExpiresDelta


    # This call verifies the ext, iat, and nbf claims
    # This optionally verifies the exp and aud claims if enabled
    decoded_token = jwt.decode(
        encoded_token,
        secret,
        algorithms=algorithms,
        audience=audience,
        issuer=issuer,
        leeway=leeway,
        options=options,
    )

    # Make sure that any custom claims we expect in the token are present
    if identity_claim_key not in decoded_token:
        raise JWTDecodeError("Missing claim: {}".format(identity_claim_key))

    if "type" not in decoded_token:
        decoded_token["type"] = "access"

    if "fresh" not in decoded_token:
        decoded_token["fresh"] = False

    if "jti" not in decoded_token:
        decoded_token["jti"] = None

    if csrf_value:
        if "csrf" not in decoded_token:
            raise JWTDecodeError("Missing claim: csrf")
        if not compare_digest(decoded_token["csrf"], csrf_value):

            raise CSRFError("CSRF double submit tokens do not match")