def use_jti_claim(jti_claim, expires):
    """
    Use a jti claim
    :param jti_claim: jti claim to mark as used.
    :param expires: when the jti claim expires.
    :raises ValueError: when jti_claim is None.
    :raises TypeError: when jti_claim is not a valid uuid4.
    :raises JtiTokenUsed: when jti_claim has already been used.
    """
    if jti_claim is None:
        raise ValueError
    if not _is_valid(jti_claim):
        logger.info("jti claim is invalid", jti_claim=jti_claim)
        raise TypeError

    try:
        used_at = datetime.now(tz=tzutc())
        # Make claim expire a little later than exp to avoid race conditions with out of sync clocks.
        expires += timedelta(seconds=60)

        jti = UsedJtiClaim(jti_claim, used_at, expires)

        current_app.eq["ephemeral_storage"].put_jti(jti)
    except ItemAlreadyExistsError as e:
        logger.error("jti claim has already been used", jti_claim=jti_claim)
        raise JtiTokenUsed(jti_claim) from e
 def test_used_jti_claim(self):
     self._test_model(UsedJtiClaim('claimid', NOW, NOW))