Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-PyJWT for openSUSE:Factory 
checked in at 2022-06-09 14:09:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-PyJWT (Old)
 and      /work/SRC/openSUSE:Factory/.python-PyJWT.new.1548 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-PyJWT"

Thu Jun  9 14:09:16 2022 rev:24 rq:981206 version:2.4.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-PyJWT/python-PyJWT.changes        
2021-11-06 18:18:03.956885640 +0100
+++ /work/SRC/openSUSE:Factory/.python-PyJWT.new.1548/python-PyJWT.changes      
2022-06-09 14:09:17.612326995 +0200
@@ -1,0 +2,36 @@
+Tue Jun  7 17:27:32 UTC 2022 - Marcus Rueckert <mrueck...@suse.de>
+
+- Update to 2.4.0 (CVE-2022-29217 boo#1199756)
+  - Security
+    - [CVE-2022-29217] Prevent key confusion through
+      non-blocklisted public key formats. GHSA-ffqj-6fqr-9h24
+  - Other changes:
+    - Explicit check the key for ECAlgorithm by @estin in
+      https://github.com/jpadilla/pyjwt/pull/713
+    - Raise DeprecationWarning for jwt.decode(verify=...) by @akx
+      in https://github.com/jpadilla/pyjwt/pull/742
+    - Don't use implicit optionals by @rekyungmin in
+      https://github.com/jpadilla/pyjwt/pull/705
+    - documentation fix: show correct scope for decode_complete()
+      by @sseering in https://github.com/jpadilla/pyjwt/pull/661
+    - fix: Update copyright information by @kkirsche in
+      https://github.com/jpadilla/pyjwt/pull/729
+    - Don't mutate options dictionary in .decode_complete() by @akx
+      in https://github.com/jpadilla/pyjwt/pull/743
+    - Add support for Python 3.10 by @hugovk in
+      https://github.com/jpadilla/pyjwt/pull/699
+    - api_jwk: Add PyJWKSet.__getitem__ by @woodruffw in
+      https://github.com/jpadilla/pyjwt/pull/725
+    - Update usage.rst by @guneybilen in
+      https://github.com/jpadilla/pyjwt/pull/727
+    - Docs: mention performance reasons for reusing RSAPrivateKey
+      when encoding by @dmahr1 in
+      https://github.com/jpadilla/pyjwt/pull/734
+    - Fixed typo in usage.rst by @israelabraham in
+      https://github.com/jpadilla/pyjwt/pull/738
+    - Add detached payload support for JWS encoding and decoding by
+      @fviard in https://github.com/jpadilla/pyjwt/pull/723
+    - Replace various string interpolations with f-strings by @akx
+      in https://github.com/jpadilla/pyjwt/pull/744
+
+-------------------------------------------------------------------

Old:
----
  PyJWT-2.3.0.tar.gz

New:
----
  PyJWT-2.4.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-PyJWT.spec ++++++
--- /var/tmp/diff_new_pack.N9AfK9/_old  2022-06-09 14:09:18.900328722 +0200
+++ /var/tmp/diff_new_pack.N9AfK9/_new  2022-06-09 14:09:18.904328727 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-PyJWT
 #
-# Copyright (c) 2021 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %global skip_python2 1
 Name:           python-PyJWT
-Version:        2.3.0
+Version:        2.4.0
 Release:        0
 Summary:        JSON Web Token implementation in Python
 License:        MIT

++++++ PyJWT-2.3.0.tar.gz -> PyJWT-2.4.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/.pre-commit-config.yaml 
new/PyJWT-2.4.0/.pre-commit-config.yaml
--- old/PyJWT-2.3.0/.pre-commit-config.yaml     2021-10-16 14:23:39.000000000 
+0200
+++ new/PyJWT-2.4.0/.pre-commit-config.yaml     2022-05-12 20:44:24.000000000 
+0200
@@ -1,12 +1,12 @@
 repos:
   - repo: https://github.com/psf/black
-    rev: 21.9b0
+    rev: 22.3.0
     hooks:
       - id: black
         args: ["--target-version=py36"]
 
   - repo: https://github.com/asottile/blacken-docs
-    rev: v1.11.0
+    rev: v1.12.1
     hooks:
       - id: blacken-docs
         args: ["--target-version=py36"]
@@ -18,19 +18,19 @@
         language_version: python3.8
 
   - repo: https://github.com/PyCQA/isort
-    rev: 5.9.3
+    rev: 5.10.1
     hooks:
       - id: isort
 
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.0.1
+    rev: v4.2.0
     hooks:
       - id: trailing-whitespace
       - id: end-of-file-fixer
       - id: debug-statements
 
   - repo: https://github.com/mgedmin/check-manifest
-    rev: "0.47"
+    rev: "0.48"
     hooks:
       - id: check-manifest
         args: [--no-build-isolation]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/CHANGELOG.rst 
new/PyJWT-2.4.0/CHANGELOG.rst
--- old/PyJWT-2.3.0/CHANGELOG.rst       2021-10-16 17:53:51.000000000 +0200
+++ new/PyJWT-2.4.0/CHANGELOG.rst       2022-05-12 20:51:37.000000000 +0200
@@ -16,6 +16,40 @@
 Added
 ~~~~~
 
+`v2.4.0 <https://github.com/jpadilla/pyjwt/compare/2.3.0...2.4.0>`__
+-----------------------------------------------------------------------
+
+Security
+~~~~~~~~
+
+- [CVE-2022-29217] Prevent key confusion through non-blocklisted public key 
formats. 
https://github.com/jpadilla/pyjwt/security/advisories/GHSA-ffqj-6fqr-9h24
+
+Changed
+~~~~~~~
+
+- Explicit check the key for ECAlgorithm by @estin in 
https://github.com/jpadilla/pyjwt/pull/713
+- Raise DeprecationWarning for jwt.decode(verify=...) by @akx in 
https://github.com/jpadilla/pyjwt/pull/742
+
+Fixed
+~~~~~
+
+- Don't use implicit optionals by @rekyungmin in 
https://github.com/jpadilla/pyjwt/pull/705
+- documentation fix: show correct scope for decode_complete() by @sseering in 
https://github.com/jpadilla/pyjwt/pull/661
+- fix: Update copyright information by @kkirsche in 
https://github.com/jpadilla/pyjwt/pull/729
+- Don't mutate options dictionary in .decode_complete() by @akx in 
https://github.com/jpadilla/pyjwt/pull/743
+
+Added
+~~~~~
+
+- Add support for Python 3.10 by @hugovk in 
https://github.com/jpadilla/pyjwt/pull/699
+- api_jwk: Add PyJWKSet.__getitem__ by @woodruffw in 
https://github.com/jpadilla/pyjwt/pull/725
+- Update usage.rst by @guneybilen in https://github.com/jpadilla/pyjwt/pull/727
+- Docs: mention performance reasons for reusing RSAPrivateKey when encoding by 
@dmahr1 in https://github.com/jpadilla/pyjwt/pull/734
+- Fixed typo in usage.rst by @israelabraham in 
https://github.com/jpadilla/pyjwt/pull/738
+- Add detached payload support for JWS encoding and decoding by @fviard in 
https://github.com/jpadilla/pyjwt/pull/723
+- Replace various string interpolations with f-strings by @akx in 
https://github.com/jpadilla/pyjwt/pull/744
+- Update CHANGELOG.rst by @hipertracker in 
https://github.com/jpadilla/pyjwt/pull/751
+
 `v2.3.0 <https://github.com/jpadilla/pyjwt/compare/2.2.0...2.3.0>`__
 -----------------------------------------------------------------------
 
@@ -162,6 +196,11 @@
 use
 ``jwt.decode(encoded, key, algorithms=["HS256"], options={"require": 
["exp"]})``.
 
+And the old v1.x syntax
+``jwt.decode(token, verify=False)``
+is now:
+``jwt.decode(jwt=token, key='secret', algorithms=['HS256'], 
options={"verify_signature": False, "verify_exp": True})``
+
 Added
 ~~~~~
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/LICENSE new/PyJWT-2.4.0/LICENSE
--- old/PyJWT-2.3.0/LICENSE     2018-11-26 04:04:17.000000000 +0100
+++ new/PyJWT-2.4.0/LICENSE     2022-05-12 20:31:26.000000000 +0200
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2015 Jos?? Padilla
+Copyright (c) 2015-2022 Jos?? Padilla
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/PKG-INFO new/PyJWT-2.4.0/PKG-INFO
--- old/PyJWT-2.3.0/PKG-INFO    2021-10-16 17:54:33.864155000 +0200
+++ new/PyJWT-2.4.0/PKG-INFO    2022-05-12 20:55:44.584056100 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: PyJWT
-Version: 2.3.0
+Version: 2.4.0
 Summary: JSON Web Token implementation in Python
 Home-page: https://github.com/jpadilla/pyjwt
 Author: Jose Padilla
@@ -82,10 +82,11 @@
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Classifier: Topic :: Utilities
 Requires-Python: >=3.6
 Description-Content-Type: text/x-rst
 Provides-Extra: crypto
+Provides-Extra: dev
 Provides-Extra: tests
 Provides-Extra: docs
-Provides-Extra: dev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/PyJWT.egg-info/PKG-INFO 
new/PyJWT-2.4.0/PyJWT.egg-info/PKG-INFO
--- old/PyJWT-2.3.0/PyJWT.egg-info/PKG-INFO     2021-10-16 17:54:33.000000000 
+0200
+++ new/PyJWT-2.4.0/PyJWT.egg-info/PKG-INFO     2022-05-12 20:55:44.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: PyJWT
-Version: 2.3.0
+Version: 2.4.0
 Summary: JSON Web Token implementation in Python
 Home-page: https://github.com/jpadilla/pyjwt
 Author: Jose Padilla
@@ -82,10 +82,11 @@
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
 Classifier: Topic :: Utilities
 Requires-Python: >=3.6
 Description-Content-Type: text/x-rst
 Provides-Extra: crypto
+Provides-Extra: dev
 Provides-Extra: tests
 Provides-Extra: docs
-Provides-Extra: dev
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/PyJWT.egg-info/SOURCES.txt 
new/PyJWT-2.4.0/PyJWT.egg-info/SOURCES.txt
--- old/PyJWT-2.3.0/PyJWT.egg-info/SOURCES.txt  2021-10-16 17:54:33.000000000 
+0200
+++ new/PyJWT-2.4.0/PyJWT.egg-info/SOURCES.txt  2022-05-12 20:55:44.000000000 
+0200
@@ -36,6 +36,7 @@
 jwt/py.typed
 jwt/utils.py
 tests/__init__.py
+tests/test_advisory.py
 tests/test_algorithms.py
 tests/test_api_jwk.py
 tests/test_api_jws.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/docs/api.rst new/PyJWT-2.4.0/docs/api.rst
--- old/PyJWT-2.3.0/docs/api.rst        2021-08-08 21:28:32.000000000 +0200
+++ new/PyJWT-2.4.0/docs/api.rst        2022-05-12 20:31:26.000000000 +0200
@@ -68,6 +68,8 @@
     :rtype: dict
     :returns: the JWT claims
 
+.. module:: jwt.api_jwt
+
 .. function:: decode_complete(jwt, key="", algorithms=None, options=None, 
audience=None, issuer=None, leeway=0)
 
     Identical to ``jwt.decode`` except for return value which is a dictionary 
containing the token header (JOSE Header),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/docs/conf.py new/PyJWT-2.4.0/docs/conf.py
--- old/PyJWT-2.3.0/docs/conf.py        2020-12-21 17:55:46.000000000 +0100
+++ new/PyJWT-2.4.0/docs/conf.py        2022-05-12 20:31:26.000000000 +0200
@@ -51,7 +51,7 @@
 
 # General information about the project.
 project = "PyJWT"
-copyright = "2015, Jos?? Padilla"
+copyright = "2015-2022, Jos?? Padilla"
 author = "Jos?? Padilla"
 
 # The version info for the project you're documenting, acts as replacement for
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/docs/usage.rst 
new/PyJWT-2.4.0/docs/usage.rst
--- old/PyJWT-2.3.0/docs/usage.rst      2021-10-06 12:37:16.000000000 +0200
+++ new/PyJWT-2.4.0/docs/usage.rst      2022-05-12 20:31:26.000000000 +0200
@@ -45,6 +45,9 @@
     )
     encoded = jwt.encode({"some": "payload"}, private_key, algorithm="RS256")
 
+If you are repeatedly encoding with the same private key, reusing the same
+``RSAPrivateKey`` also has performance benefits because it avoids the
+CPU-intensive ``RSA_check_key`` primality test.
 
 Specifying Additional Headers
 -----------------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/jwt/__init__.py 
new/PyJWT-2.4.0/jwt/__init__.py
--- old/PyJWT-2.3.0/jwt/__init__.py     2021-10-16 17:53:51.000000000 +0200
+++ new/PyJWT-2.4.0/jwt/__init__.py     2022-05-12 20:31:26.000000000 +0200
@@ -25,19 +25,19 @@
 )
 from .jwks_client import PyJWKClient
 
-__version__ = "2.3.0"
+__version__ = "2.4.0"
 
 __title__ = "PyJWT"
 __description__ = "JSON Web Token implementation in Python"
 __url__ = "https://pyjwt.readthedocs.io";
 __uri__ = __url__
-__doc__ = __description__ + " <" + __uri__ + ">"
+__doc__ = f"{__description__} <{__uri__}>"
 
 __author__ = "Jos?? Padilla"
 __email__ = "he...@jpadilla.com"
 
 __license__ = "MIT"
-__copyright__ = "Copyright 2015-2020 Jos?? Padilla"
+__copyright__ = "Copyright 2015-2022 Jos?? Padilla"
 
 
 __all__ = [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/jwt/algorithms.py 
new/PyJWT-2.4.0/jwt/algorithms.py
--- old/PyJWT-2.3.0/jwt/algorithms.py   2021-10-06 12:37:16.000000000 +0200
+++ new/PyJWT-2.4.0/jwt/algorithms.py   2022-05-12 20:31:26.000000000 +0200
@@ -9,6 +9,8 @@
     der_to_raw_signature,
     force_bytes,
     from_base64url_uint,
+    is_pem_format,
+    is_ssh_key,
     raw_to_der_signature,
     to_base64url_uint,
 )
@@ -183,14 +185,7 @@
     def prepare_key(self, key):
         key = force_bytes(key)
 
-        invalid_strings = [
-            b"-----BEGIN PUBLIC KEY-----",
-            b"-----BEGIN CERTIFICATE-----",
-            b"-----BEGIN RSA PUBLIC KEY-----",
-            b"ssh-rsa",
-        ]
-
-        if any(string_value in key for string_value in invalid_strings):
+        if is_pem_format(key) or is_ssh_key(key):
             raise InvalidKeyError(
                 "The specified key is an asymmetric key or x509 certificate 
and"
                 " should not be used as an HMAC secret."
@@ -417,6 +412,12 @@
             except ValueError:
                 key = load_pem_private_key(key, password=None)
 
+            # Explicit check the key to prevent confusing errors from 
cryptography
+            if not isinstance(key, (EllipticCurvePrivateKey, 
EllipticCurvePublicKey)):
+                raise InvalidKeyError(
+                    "Expecting a 
EllipticCurvePrivateKey/EllipticCurvePublicKey. Wrong key provided for ECDSA 
algorithms"
+                )
+
             return key
 
         def sign(self, msg, key):
@@ -545,26 +546,28 @@
             pass
 
         def prepare_key(self, key):
-
-            if isinstance(
-                key,
-                (Ed25519PrivateKey, Ed25519PublicKey, Ed448PrivateKey, 
Ed448PublicKey),
-            ):
-                return key
-
             if isinstance(key, (bytes, str)):
                 if isinstance(key, str):
                     key = key.encode("utf-8")
                 str_key = key.decode("utf-8")
 
                 if "-----BEGIN PUBLIC" in str_key:
-                    return load_pem_public_key(key)
-                if "-----BEGIN PRIVATE" in str_key:
-                    return load_pem_private_key(key, password=None)
-                if str_key[0:4] == "ssh-":
-                    return load_ssh_public_key(key)
+                    key = load_pem_public_key(key)
+                elif "-----BEGIN PRIVATE" in str_key:
+                    key = load_pem_private_key(key, password=None)
+                elif str_key[0:4] == "ssh-":
+                    key = load_ssh_public_key(key)
+
+            # Explicit check the key to prevent confusing errors from 
cryptography
+            if not isinstance(
+                key,
+                (Ed25519PrivateKey, Ed25519PublicKey, Ed448PrivateKey, 
Ed448PublicKey),
+            ):
+                raise InvalidKeyError(
+                    "Expecting a 
EllipticCurvePrivateKey/EllipticCurvePublicKey. Wrong key provided for EdDSA 
algorithms"
+                )
 
-            raise TypeError("Expecting a PEM-formatted or OpenSSH key.")
+            return key
 
         def sign(self, msg, key):
             """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/jwt/api_jwk.py 
new/PyJWT-2.4.0/jwt/api_jwk.py
--- old/PyJWT-2.3.0/jwt/api_jwk.py      2021-04-28 13:23:40.000000000 +0200
+++ new/PyJWT-2.4.0/jwt/api_jwk.py      2022-05-12 20:31:26.000000000 +0200
@@ -11,7 +11,7 @@
 
         kty = self._jwk_data.get("kty", None)
         if not kty:
-            raise InvalidKeyError("kty is not found: %s" % self._jwk_data)
+            raise InvalidKeyError(f"kty is not found: {self._jwk_data}")
 
         if not algorithm and isinstance(self._jwk_data, dict):
             algorithm = self._jwk_data.get("alg", None)
@@ -29,25 +29,25 @@
                 elif crv == "secp256k1":
                     algorithm = "ES256K"
                 else:
-                    raise InvalidKeyError("Unsupported crv: %s" % crv)
+                    raise InvalidKeyError(f"Unsupported crv: {crv}")
             elif kty == "RSA":
                 algorithm = "RS256"
             elif kty == "oct":
                 algorithm = "HS256"
             elif kty == "OKP":
                 if not crv:
-                    raise InvalidKeyError("crv is not found: %s" % 
self._jwk_data)
+                    raise InvalidKeyError(f"crv is not found: 
{self._jwk_data}")
                 if crv == "Ed25519":
                     algorithm = "EdDSA"
                 else:
-                    raise InvalidKeyError("Unsupported crv: %s" % crv)
+                    raise InvalidKeyError(f"Unsupported crv: {crv}")
             else:
-                raise InvalidKeyError("Unsupported kty: %s" % kty)
+                raise InvalidKeyError(f"Unsupported kty: {kty}")
 
         self.Algorithm = self._algorithms.get(algorithm)
 
         if not self.Algorithm:
-            raise PyJWKError("Unable to find a algorithm for key: %s" % 
self._jwk_data)
+            raise PyJWKError(f"Unable to find a algorithm for key: 
{self._jwk_data}")
 
         self.key = self.Algorithm.from_jwk(self._jwk_data)
 
@@ -95,3 +95,9 @@
     def from_json(data):
         obj = json.loads(data)
         return PyJWKSet.from_dict(obj)
+
+    def __getitem__(self, kid):
+        for key in self.keys:
+            if key.key_id == kid:
+                return key
+        raise KeyError(f"keyset has no key for kid: {kid}")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/jwt/api_jws.py 
new/PyJWT-2.4.0/jwt/api_jws.py
--- old/PyJWT-2.3.0/jwt/api_jws.py      2021-10-16 14:23:39.000000000 +0200
+++ new/PyJWT-2.4.0/jwt/api_jws.py      2022-05-12 20:31:26.000000000 +0200
@@ -80,34 +80,54 @@
         algorithm: Optional[str] = "HS256",
         headers: Optional[Dict] = None,
         json_encoder: Optional[Type[json.JSONEncoder]] = None,
+        is_payload_detached: bool = False,
     ) -> str:
         segments = []
 
         if algorithm is None:
             algorithm = "none"
 
-        # Prefer headers["alg"] if present to algorithm parameter.
-        if headers and "alg" in headers and headers["alg"]:
-            algorithm = headers["alg"]
+        # Prefer headers values if present to function parameters.
+        if headers:
+            headers_alg = headers.get("alg")
+            if headers_alg:
+                algorithm = headers["alg"]
+
+            headers_b64 = headers.get("b64")
+            if headers_b64 is False:
+                is_payload_detached = True
 
         # Header
-        header = {"typ": self.header_typ, "alg": algorithm}
+        header = {"typ": self.header_typ, "alg": algorithm}  # type: Dict[str, 
Any]
 
         if headers:
             self._validate_headers(headers)
             header.update(headers)
-            if not header["typ"]:
-                del header["typ"]
+
+        if not header["typ"]:
+            del header["typ"]
+
+        if is_payload_detached:
+            header["b64"] = False
+        elif "b64" in header:
+            # True is the standard value for b64, so no need for it
+            del header["b64"]
 
         json_header = json.dumps(
             header, separators=(",", ":"), cls=json_encoder
         ).encode()
 
         segments.append(base64url_encode(json_header))
-        segments.append(base64url_encode(payload))
+
+        if is_payload_detached:
+            msg_payload = payload
+        else:
+            msg_payload = base64url_encode(payload)
+        segments.append(msg_payload)
 
         # Segments
         signing_input = b".".join(segments)
+
         try:
             alg_obj = self._algorithms[algorithm]
             key = alg_obj.prepare_key(key)
@@ -116,14 +136,15 @@
         except KeyError as e:
             if not has_crypto and algorithm in requires_cryptography:
                 raise NotImplementedError(
-                    "Algorithm '%s' could not be found. Do you have 
cryptography "
-                    "installed?" % algorithm
+                    f"Algorithm '{algorithm}' could not be found. Do you have 
cryptography installed?"
                 ) from e
-            else:
-                raise NotImplementedError("Algorithm not supported") from e
+            raise NotImplementedError("Algorithm not supported") from e
 
         segments.append(base64url_encode(signature))
 
+        # Don't put the payload content inside the encoded token when detached
+        if is_payload_detached:
+            segments[1] = b""
         encoded_string = b".".join(segments)
 
         return encoded_string.decode("utf-8")
@@ -132,8 +153,9 @@
         self,
         jwt: str,
         key: str = "",
-        algorithms: List[str] = None,
-        options: Dict = None,
+        algorithms: Optional[List[str]] = None,
+        options: Optional[Dict] = None,
+        detached_payload: Optional[bytes] = None,
         **kwargs,
     ) -> Dict[str, Any]:
         if options is None:
@@ -148,6 +170,14 @@
 
         payload, signing_input, header, signature = self._load(jwt)
 
+        if header.get("b64", True) is False:
+            if detached_payload is None:
+                raise DecodeError(
+                    'It is required that you pass in a value for the 
"detached_payload" argument to decode a message having the b64 header set to 
false.'
+                )
+            payload = detached_payload
+            signing_input = b".".join([signing_input.rsplit(b".", 1)[0], 
payload])
+
         if verify_signature:
             self._verify_signature(signing_input, header, signature, key, 
algorithms)
 
@@ -161,8 +191,8 @@
         self,
         jwt: str,
         key: str = "",
-        algorithms: List[str] = None,
-        options: Dict = None,
+        algorithms: Optional[List[str]] = None,
+        options: Optional[Dict] = None,
         **kwargs,
     ) -> str:
         decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
@@ -200,7 +230,7 @@
         try:
             header = json.loads(header_data)
         except ValueError as e:
-            raise DecodeError("Invalid header string: %s" % e) from e
+            raise DecodeError(f"Invalid header string: {e}") from e
 
         if not isinstance(header, Mapping):
             raise DecodeError("Invalid header string: must be a json object")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/jwt/api_jwt.py 
new/PyJWT-2.4.0/jwt/api_jwt.py
--- old/PyJWT-2.3.0/jwt/api_jwt.py      2021-10-16 14:23:39.000000000 +0200
+++ new/PyJWT-2.4.0/jwt/api_jwt.py      2022-05-12 20:31:26.000000000 +0200
@@ -1,4 +1,5 @@
 import json
+import warnings
 from calendar import timegm
 from collections.abc import Iterable, Mapping
 from datetime import datetime, timedelta, timezone
@@ -66,14 +67,23 @@
         self,
         jwt: str,
         key: str = "",
-        algorithms: List[str] = None,
-        options: Dict = None,
+        algorithms: Optional[List[str]] = None,
+        options: Optional[Dict] = None,
         **kwargs,
     ) -> Dict[str, Any]:
-        if options is None:
-            options = {"verify_signature": True}
-        else:
-            options.setdefault("verify_signature", True)
+        options = dict(options or {})  # shallow-copy or initialize an empty 
dict
+        options.setdefault("verify_signature", True)
+
+        # If the user has set the legacy `verify` argument, and it doesn't 
match
+        # what the relevant `options` entry for the argument is, inform the 
user
+        # that they're likely making a mistake.
+        if "verify" in kwargs and kwargs["verify"] != 
options["verify_signature"]:
+            warnings.warn(
+                "The `verify` argument to `decode` does nothing in PyJWT 2.0 
and newer. "
+                "The equivalent is setting `verify_signature` to False in the 
`options` dictionary. "
+                "This invocation has a mismatch between the kwarg and the 
option entry.",
+                category=DeprecationWarning,
+            )
 
         if not options["verify_signature"]:
             options.setdefault("verify_exp", False)
@@ -98,7 +108,7 @@
         try:
             payload = json.loads(decoded["payload"])
         except ValueError as e:
-            raise DecodeError("Invalid payload string: %s" % e)
+            raise DecodeError(f"Invalid payload string: {e}")
         if not isinstance(payload, dict):
             raise DecodeError("Invalid payload string: must be a json object")
 
@@ -112,8 +122,8 @@
         self,
         jwt: str,
         key: str = "",
-        algorithms: List[str] = None,
-        options: Dict = None,
+        algorithms: Optional[List[str]] = None,
+        options: Optional[Dict] = None,
         **kwargs,
     ) -> Dict[str, Any]:
         decoded = self.decode_complete(jwt, key, algorithms, options, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/jwt/exceptions.py 
new/PyJWT-2.4.0/jwt/exceptions.py
--- old/PyJWT-2.3.0/jwt/exceptions.py   2020-08-24 18:22:55.000000000 +0200
+++ new/PyJWT-2.4.0/jwt/exceptions.py   2022-05-12 20:31:26.000000000 +0200
@@ -51,7 +51,7 @@
         self.claim = claim
 
     def __str__(self):
-        return 'Token is missing the "%s" claim' % self.claim
+        return f'Token is missing the "{self.claim}" claim'
 
 
 class PyJWKError(PyJWTError):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/jwt/help.py new/PyJWT-2.4.0/jwt/help.py
--- old/PyJWT-2.3.0/jwt/help.py 2020-12-21 17:55:46.000000000 +0100
+++ new/PyJWT-2.4.0/jwt/help.py 2022-05-12 20:31:26.000000000 +0200
@@ -28,10 +28,10 @@
     if implementation == "CPython":
         implementation_version = platform.python_version()
     elif implementation == "PyPy":
-        implementation_version = "{}.{}.{}".format(
-            sys.pypy_version_info.major,
-            sys.pypy_version_info.minor,
-            sys.pypy_version_info.micro,
+        implementation_version = (
+            f"{sys.pypy_version_info.major}."
+            f"{sys.pypy_version_info.minor}."
+            f"{sys.pypy_version_info.micro}"
         )
         if sys.pypy_version_info.releaselevel != "final":
             implementation_version = "".join(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/jwt/utils.py new/PyJWT-2.4.0/jwt/utils.py
--- old/PyJWT-2.3.0/jwt/utils.py        2021-10-06 12:37:16.000000000 +0200
+++ new/PyJWT-2.4.0/jwt/utils.py        2022-05-12 20:31:26.000000000 +0200
@@ -1,5 +1,6 @@
 import base64
 import binascii
+import re
 from typing import Any, Union
 
 try:
@@ -97,3 +98,63 @@
     s = bytes_to_number(raw_sig[num_bytes:])
 
     return encode_dss_signature(r, s)
+
+
+# Based on 
https://github.com/hynek/pem/blob/7ad94db26b0bc21d10953f5dbad3acfdfacf57aa/src/pem/_core.py#L224-L252
+_PEMS = {
+    b"CERTIFICATE",
+    b"TRUSTED CERTIFICATE",
+    b"PRIVATE KEY",
+    b"PUBLIC KEY",
+    b"ENCRYPTED PRIVATE KEY",
+    b"OPENSSH PRIVATE KEY",
+    b"DSA PRIVATE KEY",
+    b"RSA PRIVATE KEY",
+    b"RSA PUBLIC KEY",
+    b"EC PRIVATE KEY",
+    b"DH PARAMETERS",
+    b"NEW CERTIFICATE REQUEST",
+    b"CERTIFICATE REQUEST",
+    b"SSH2 PUBLIC KEY",
+    b"SSH2 ENCRYPTED PRIVATE KEY",
+    b"X509 CRL",
+}
+
+_PEM_RE = re.compile(
+    b"----[- ]BEGIN ("
+    + b"|".join(_PEMS)
+    + b""")[- ]----\r?
+.+?\r?
+----[- ]END \\1[- ]----\r?\n?""",
+    re.DOTALL,
+)
+
+
+def is_pem_format(key: bytes) -> bool:
+    return bool(_PEM_RE.search(key))
+
+
+# Based on 
https://github.com/pyca/cryptography/blob/bcb70852d577b3f490f015378c75cba74986297b/src/cryptography/hazmat/primitives/serialization/ssh.py#L40-L46
+_CERT_SUFFIX = b"-cert-...@openssh.com"
+_SSH_PUBKEY_RC = re.compile(br"\A(\S+)[ \t]+(\S+)")
+_SSH_KEY_FORMATS = [
+    b"ssh-ed25519",
+    b"ssh-rsa",
+    b"ssh-dss",
+    b"ecdsa-sha2-nistp256",
+    b"ecdsa-sha2-nistp384",
+    b"ecdsa-sha2-nistp521",
+]
+
+
+def is_ssh_key(key: bytes) -> bool:
+    if any(string_value in key for string_value in _SSH_KEY_FORMATS):
+        return True
+
+    ssh_pubkey_match = _SSH_PUBKEY_RC.match(key)
+    if ssh_pubkey_match:
+        key_type = ssh_pubkey_match.group(1)
+        if _CERT_SUFFIX == key_type[-len(_CERT_SUFFIX) :]:
+            return True
+
+    return False
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/setup.cfg new/PyJWT-2.4.0/setup.cfg
--- old/PyJWT-2.3.0/setup.cfg   2021-10-16 17:54:33.865428000 +0200
+++ new/PyJWT-2.4.0/setup.cfg   2022-05-12 20:55:44.584843400 +0200
@@ -27,6 +27,7 @@
        Programming Language :: Python :: 3.7
        Programming Language :: Python :: 3.8
        Programming Language :: Python :: 3.9
+       Programming Language :: Python :: 3.10
        Topic :: Utilities
 
 [options]
@@ -70,6 +71,7 @@
 python_version = 3.6
 ignore_missing_imports = true
 warn_unused_ignores = true
+no_implicit_optional = true
 
 [egg_info]
 tag_build = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/tests/test_advisory.py 
new/PyJWT-2.4.0/tests/test_advisory.py
--- old/PyJWT-2.3.0/tests/test_advisory.py      1970-01-01 01:00:00.000000000 
+0100
+++ new/PyJWT-2.4.0/tests/test_advisory.py      2022-05-12 20:34:28.000000000 
+0200
@@ -0,0 +1,112 @@
+import jwt
+import pytest
+from jwt.exceptions import InvalidKeyError
+
+from .utils import crypto_required
+
+priv_key_bytes = b'''-----BEGIN PRIVATE KEY-----
+MC4CAQAwBQYDK2VwBCIEIIbBhdo2ah7X32i50GOzrCr4acZTe6BezUdRIixjTAdL
+-----END PRIVATE KEY-----'''
+
+pub_key_bytes = b'ssh-ed25519 
AAAAC3NzaC1lZDI1NTE5AAAAIPL1I9oiq+B8crkmuV4YViiUnhdLjCp3hvy1bNGuGfNL'
+
+ssh_priv_key_bytes = b"""-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIOWc7RbaNswMtNtc+n6WZDlUblMr2FBPo79fcGXsJlGQoAoGCCqGSM49
+AwEHoUQDQgAElcy2RSSSgn2RA/xCGko79N+7FwoLZr3Z0ij/ENjow2XpUDwwKEKk
+Ak3TDXC9U8nipMlGcY7sDpXp2XyhHEM+Rw==
+-----END EC PRIVATE KEY-----"""
+
+ssh_key_bytes = b"""ecdsa-sha2-nistp256 
AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJXMtkUkkoJ9kQP8QhpKO/TfuxcKC2a92dIo/xDY6MNl6VA8MChCpAJN0w1wvVPJ4qTJRnGO7A6V6dl8oRxDPkc="""
+
+
+class TestAdvisory:
+    @crypto_required
+    def test_ghsa_ffqj_6fqr_9h24(self):
+        # Generate ed25519 private key
+        # private_key = ed25519.Ed25519PrivateKey.generate()
+
+        # Get private key bytes as they would be stored in a file
+        # priv_key_bytes = private_key.private_bytes(
+        #     encoding=serialization.Encoding.PEM,
+        #     format=serialization.PrivateFormat.PKCS8,
+        #     encryption_algorithm=serialization.NoEncryption(),
+        # )
+
+        # Get public key bytes as they would be stored in a file
+        # pub_key_bytes = private_key.public_key().public_bytes(
+        #     encoding=serialization.Encoding.OpenSSH,
+        #     format=serialization.PublicFormat.OpenSSH,
+        # )
+
+        # Making a good jwt token that should work by signing it
+        # with the private key
+        # encoded_good = jwt.encode({"test": 1234}, priv_key_bytes, 
algorithm="EdDSA")
+        encoded_good = 
'eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJ0ZXN0IjoxMjM0fQ.M5y1EEavZkHSlj9i8yi9nXKKyPBSAUhDRTOYZi3zZY11tZItDaR3qwAye8pc74_lZY3Ogt9KPNFbVOSGnUBHDg'
+
+        # Using HMAC with the public key to trick the receiver to think that 
the
+        # public key is a HMAC secret
+        encoded_bad = 
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0ZXN0IjoxMjM0fQ.6ulDpqSlbHmQ8bZXhZRLFko9SwcHrghCwh8d-exJEE4'
+
+        # Both of the jwt tokens are validated as valid
+        jwt.decode(
+            encoded_good,
+            pub_key_bytes,
+            algorithms=jwt.algorithms.get_default_algorithms(),
+        )
+
+        with pytest.raises(InvalidKeyError):
+            jwt.decode(
+                encoded_bad,
+                pub_key_bytes,
+                algorithms=jwt.algorithms.get_default_algorithms(),
+            )
+
+        # Of course the receiver should specify ed25519 algorithm to be used if
+        # they specify ed25519 public key. However, if other algorithms are 
used,
+        # the POC does not work
+        # HMAC specifies illegal strings for the HMAC secret in 
jwt/algorithms.py
+        #
+        #        invalid_str ings = [
+        #            b"-----BEGIN PUBLIC KEY-----",
+        #            b"-----BEGIN CERTIFICATE-----",
+        #            b"-----BEGIN RSA PUBLIC KEY-----",
+        #            b"ssh-rsa",
+        #        ]
+        #
+        # However, OKPAlgorithm (ed25519) accepts the following in  
jwt/algorithms.py:
+        #
+        #                if "-----BEGIN PUBLIC" in str_key:
+        #                    return load_pem_public_key(key)
+        #                if "-----BEGIN PRIVATE" in str_key:
+        #                    return load_pem_private_key(key, password=None)
+        #                if str_key[0:4] == "ssh-":
+        #                    return load_ssh_public_key(key)
+        #
+        # These should most likely made to match each other to prevent this 
behavior
+
+        # POC for the ecdsa-sha2-nistp256 format.
+        # openssl ecparam -genkey -name prime256v1 -noout -out 
ec256-key-priv.pem
+        # openssl ec -in ec256-key-priv.pem -pubout > ec256-key-pub.pem
+        # ssh-keygen -y -f ec256-key-priv.pem > ec256-key-ssh.pub
+
+        # Making a good jwt token that should work by signing it with the 
private key
+        # encoded_good = jwt.encode({"test": 1234}, ssh_priv_key_bytes, 
algorithm="ES256")
+        encoded_good = 
"eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoxMjM0fQ.NX42mS8cNqYoL3FOW9ZcKw8Nfq2mb6GqJVADeMA1-kyHAclilYo_edhdM_5eav9tBRQTlL0XMeu_WFE_mz3OXg"
+
+        # Using HMAC with the ssh public key to trick the receiver to think 
that the public key is a HMAC secret
+        # encoded_bad = jwt.encode({"test": 1234}, ssh_key_bytes, 
algorithm="HS256")
+        encoded_bad = 
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoxMjM0fQ.5eYfbrbeGYmWfypQ6rMWXNZ8bdHcqKng5GPr9MJZITU"
+
+        # Both of the jwt tokens are validated as valid
+        jwt.decode(
+            encoded_good,
+            ssh_key_bytes,
+            algorithms=jwt.algorithms.get_default_algorithms()
+        )
+
+        with pytest.raises(InvalidKeyError):
+            jwt.decode(
+                encoded_bad,
+                ssh_key_bytes,
+                algorithms=jwt.algorithms.get_default_algorithms()
+            )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/tests/test_algorithms.py 
new/PyJWT-2.4.0/tests/test_algorithms.py
--- old/PyJWT-2.3.0/tests/test_algorithms.py    2021-10-06 12:37:16.000000000 
+0200
+++ new/PyJWT-2.4.0/tests/test_algorithms.py    2022-05-12 20:31:26.000000000 
+0200
@@ -226,16 +226,14 @@
         for curve in ("P-256", "P-384", "P-521", "secp256k1"):
             with pytest.raises(InvalidKeyError):
                 algo.from_jwk(
-                    '{{"kty": "EC", "crv": "{}", "x": "dGVzdA==", '
-                    '"y": "dGVzdA=="}}'.format(curve)
+                    f'{{"kty": "EC", "crv": "{curve}", "x": "dGVzdA==", "y": 
"dGVzdA=="}}'
                 )
 
         # EC private key length invalid
         for (curve, point) in valid_points.items():
             with pytest.raises(InvalidKeyError):
                 algo.from_jwk(
-                    '{{"kty": "EC", "crv": "{}", "x": "{}", "y": "{}", '
-                    '"d": "dGVzdA=="}}'.format(curve, point["x"], point["y"])
+                    f'{{"kty": "EC", "crv": "{curve}", "x": "{point["x"]}", 
"y": "{point["y"]}", "d": "dGVzdA=="}}'
                 )
 
     @crypto_required
@@ -495,6 +493,18 @@
         assert not result
 
     @crypto_required
+    def test_ec_should_throw_exception_on_wrong_key(self):
+        algo = ECAlgorithm(ECAlgorithm.SHA256)
+
+        with pytest.raises(InvalidKeyError):
+            with open(key_path("testkey_rsa.priv")) as keyfile:
+                algo.prepare_key(keyfile.read())
+
+        with pytest.raises(InvalidKeyError):
+            with open(key_path("testkey2_rsa.pub.pem")) as pem_key:
+                algo.prepare_key(pem_key.read())
+
+    @crypto_required
     def test_rsa_pss_sign_then_verify_should_return_true(self):
         algo = RSAPSSAlgorithm(RSAPSSAlgorithm.SHA256)
 
@@ -669,7 +679,7 @@
     def test_okp_ed25519_should_reject_non_string_key(self):
         algo = OKPAlgorithm()
 
-        with pytest.raises(TypeError):
+        with pytest.raises(InvalidKeyError):
             algo.prepare_key(None)
 
         with open(key_path("testkey_ed25519")) as keyfile:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/tests/test_api_jwk.py 
new/PyJWT-2.4.0/tests/test_api_jwk.py
--- old/PyJWT-2.3.0/tests/test_api_jwk.py       2021-10-06 12:37:16.000000000 
+0200
+++ new/PyJWT-2.4.0/tests/test_api_jwk.py       2022-05-12 20:31:26.000000000 
+0200
@@ -252,3 +252,26 @@
         assert jwk.key_type == "RSA"
         assert jwk.key_id == "keyid-abc123"
         assert jwk.public_key_use == "sig"
+
+    @crypto_required
+    def test_keyset_should_index_by_kid(self):
+        algo = RSAAlgorithm(RSAAlgorithm.SHA256)
+
+        with open(key_path("jwk_rsa_pub.json")) as keyfile:
+            pub_key = algo.from_jwk(keyfile.read())
+
+        key_data_str = algo.to_jwk(pub_key)
+        key_data = json.loads(key_data_str)
+
+        # TODO Should `to_jwk` set these?
+        key_data["alg"] = "RS256"
+        key_data["use"] = "sig"
+        key_data["kid"] = "keyid-abc123"
+
+        jwk_set = PyJWKSet.from_dict({"keys": [key_data]})
+
+        jwk = jwk_set.keys[0]
+        assert jwk == jwk_set["keyid-abc123"]
+
+        with pytest.raises(KeyError):
+            jwk_set["this-kid-does-not-exist"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/tests/test_api_jws.py 
new/PyJWT-2.4.0/tests/test_api_jws.py
--- old/PyJWT-2.3.0/tests/test_api_jws.py       2021-08-08 21:28:32.000000000 
+0200
+++ new/PyJWT-2.4.0/tests/test_api_jws.py       2022-05-12 20:31:26.000000000 
+0200
@@ -719,3 +719,54 @@
             jws.encode(payload, "secret", headers={"kid": None})
 
         assert "Key ID header parameter must be a string" == str(exc.value)
+
+    def test_encode_decode_with_detached_content(self, jws, payload):
+        secret = "secret"
+        jws_message = jws.encode(
+            payload, secret, algorithm="HS256", is_payload_detached=True
+        )
+
+        jws.decode(jws_message, secret, algorithms=["HS256"], 
detached_payload=payload)
+
+    def test_encode_detached_content_with_b64_header(self, jws, payload):
+        secret = "secret"
+
+        # Check that detached content is automatically detected when b64 is 
false
+        headers = {"b64": False}
+        token = jws.encode(payload, secret, "HS256", headers)
+
+        msg_header, msg_payload, _ = token.split(".")
+        msg_header = base64url_decode(msg_header.encode())
+        msg_header_obj = json.loads(msg_header)
+
+        assert "b64" in msg_header_obj
+        assert msg_header_obj["b64"] is False
+        # Check that the payload is not inside the token
+        assert not msg_payload
+
+        # Check that content is not detached and b64 header removed when b64 
is true
+        headers = {"b64": True}
+        token = jws.encode(payload, secret, "HS256", headers)
+
+        msg_header, msg_payload, _ = token.split(".")
+        msg_header = base64url_decode(msg_header.encode())
+        msg_header_obj = json.loads(msg_header)
+
+        assert "b64" not in msg_header_obj
+        assert msg_payload
+
+    def test_decode_detached_content_without_proper_argument(self, jws):
+        example_jws = (
+            "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImI2NCI6ZmFsc2V9"
+            "."
+            ".65yNkX_ZH4A_6pHaTL_eI84OXOHtfl4K0k5UnlXZ8f4"
+        )
+        example_secret = "secret"
+
+        with pytest.raises(DecodeError) as exc:
+            jws.decode(example_jws, example_secret, algorithms=["HS256"])
+
+        assert (
+            'It is required that you pass in a value for the 
"detached_payload" argument to decode a message having the b64 header set to 
false.'
+            in str(exc.value)
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/tests/test_api_jwt.py 
new/PyJWT-2.4.0/tests/test_api_jwt.py
--- old/PyJWT-2.3.0/tests/test_api_jwt.py       2021-10-16 14:23:39.000000000 
+0200
+++ new/PyJWT-2.4.0/tests/test_api_jwt.py       2022-05-12 20:31:26.000000000 
+0200
@@ -658,3 +658,27 @@
         jwt_message = jwt.encode(payload, secret)
 
         jwt.decode(jwt_message, secret, options={"verify_signature": False})
+
+    def test_decode_legacy_verify_warning(self, jwt, payload):
+        secret = "secret"
+        jwt_message = jwt.encode(payload, secret)
+
+        with pytest.deprecated_call():
+            # The implicit default for options.verify_signature is True,
+            # but the user sets verify to False.
+            jwt.decode(jwt_message, secret, verify=False, algorithms=["HS256"])
+
+        with pytest.deprecated_call():
+            # The user explicitly sets verify=True,
+            # but contradicts it in verify_signature.
+            jwt.decode(
+                jwt_message, secret, verify=True, options={"verify_signature": 
False}
+            )
+
+    def test_decode_no_options_mutation(self, jwt, payload):
+        options = {"verify_signature": True}
+        orig_options = options.copy()
+        secret = "secret"
+        jwt_message = jwt.encode(payload, secret)
+        jwt.decode(jwt_message, secret, options=options, algorithms=["HS256"])
+        assert options == orig_options
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/PyJWT-2.3.0/tox.ini new/PyJWT-2.4.0/tox.ini
--- old/PyJWT-2.3.0/tox.ini     2021-01-12 14:06:52.000000000 +0100
+++ new/PyJWT-2.4.0/tox.ini     2022-05-12 20:31:26.000000000 +0200
@@ -12,6 +12,7 @@
     3.7: py37, docs
     3.8: py38, typing
     3.9: py39
+    3.10: py310
 
 
 [tox]

Reply via email to