From cf84e8f99d938e6366efd3a091612a5a1dc395d2 Mon Sep 17 00:00:00 2001 From: StormLord07 Date: Sun, 10 Aug 2025 21:05:44 +0300 Subject: [PATCH 01/10] glz::json_t trait support --- .../traits/stephenberry-glaze/defaults.h | 91 +++++++++++++++++++ .../traits/stephenberry-glaze/traits.h | 84 +++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 include/jwt-cpp/traits/stephenberry-glaze/defaults.h create mode 100644 include/jwt-cpp/traits/stephenberry-glaze/traits.h diff --git a/include/jwt-cpp/traits/stephenberry-glaze/defaults.h b/include/jwt-cpp/traits/stephenberry-glaze/defaults.h new file mode 100644 index 000000000..facc15e7e --- /dev/null +++ b/include/jwt-cpp/traits/stephenberry-glaze/defaults.h @@ -0,0 +1,91 @@ +#ifndef JWT_CPP_STEPHENBERRY_GLAZE_DEFAULTS_H +#define JWT_CPP_STEPHENBERRY_GLAZE_DEFAULTS_H + +#ifndef JWT_DISABLE_PICOJSON +#define JWT_DISABLE_PICOJSON +#endif + +#include "traits.h" + +namespace jwt { + /** + * \brief a class to store a generic [glz::json_t](https://github.com/stephenberry/glaze/) value as claim + * + * This type is the specialization of the \ref basic_claim class which + * uses the standard template types. + */ + using claim = basic_claim; + + /** + * Create a verifier using the default clock + * \return verifier instance + */ + inline verifier verify() { + return verify(default_clock{}); + } + + /** + * Create a builder using the default clock + * \return builder instance to create a new token + */ + inline builder create() { + return builder(default_clock{}); + } + +#ifndef JWT_DISABLE_BASE64 + /** + * Decode a token + * \param token Token to decode + * \return Decoded token + * \throw std::invalid_argument Token is not in correct format + * \throw std::runtime_error Base64 decoding failed or invalid json + */ + inline decoded_jwt decode(const std::string& token) { + return decoded_jwt(token); + } +#endif + + /** + * Decode a token + * \tparam Decode is callable, taking a string_type and returns a string_type. + * It should ensure the padding of the input and then base64url decode and + * return the results. + * \param token Token to decode + * \param decode The token to parse + * \return Decoded token + * \throw std::invalid_argument Token is not in correct format + * \throw std::runtime_error Base64 decoding failed or invalid json + */ + template + decoded_jwt decode(const std::string& token, Decode decode) { + return decoded_jwt(token, decode); + } + + /** + * Parse a jwk + * \param token JWK Token to parse + * \return Parsed JWK + * \throw std::runtime_error Token is not in correct format + */ + inline jwk parse_jwk(const traits::stephenberry_glaze::string_type& token) { + return jwk(token); + } + + /** + * Parse a jwks + * \param token JWKs Token to parse + * \return Parsed JWKs + * \throw std::runtime_error Token is not in correct format + */ + inline jwks parse_jwks(const traits::stephenberry_glaze::string_type& token) { + return jwks(token); + } + + /** + * This type is the specialization of the \ref verify_ops::verify_context class which + * uses the standard template types. + */ + using verify_context = verify_ops::verify_context; +} // namespace jwt + +#endif // JWT_CPP_STEPHENBERRY_GLAZE_DEFAULTS_H diff --git a/include/jwt-cpp/traits/stephenberry-glaze/traits.h b/include/jwt-cpp/traits/stephenberry-glaze/traits.h new file mode 100644 index 000000000..0d3bc42b2 --- /dev/null +++ b/include/jwt-cpp/traits/stephenberry-glaze/traits.h @@ -0,0 +1,84 @@ +#ifndef JWT_CPP_STEPHENBERRY_GLAZE_TRAITS_H +#define JWT_CPP_STEPHENBERRY_GLAZE_TRAITS_H + +#include "jwt-cpp/jwt.h" +#include + +namespace jwt { + /** + * \brief Namespace containing all the json_trait implementations for a jwt::basic_claim. + */ + namespace traits { + struct stephenberry_glaze { + using json = glz::json_t; + using value_type = json; // ← ключевое + using object_type = json::object_t; // map + using array_type = json::array_t; // vector + using string_type = std::string; + using number_type = double; + using integer_type = std::int64_t; + using boolean_type = bool; + + static jwt::json::type get_type(const value_type& val) { + using jwt::json::type; + + if (val.is_object()) return type::object; + if (val.is_array()) return type::array; + if (val.is_string()) return type::string; + if (val.is_boolean()) return type::boolean; + + // Если у json_t нет отдельного integer-типа: + if (val.is_number()) return type::number; + + if (val.is_null()) throw std::logic_error("invalid type: null"); + throw std::logic_error("invalid type"); + } + + static object_type as_object(const value_type& val) { + if (!val.is_object()) throw std::bad_cast(); + return std::get(val.data); + } + + static array_type as_array(const value_type& val) { + if (!val.is_array()) throw std::bad_cast(); + return std::get(val.data); + } + + static string_type as_string(const value_type& val) { + if (!val.is_string()) throw std::bad_cast(); + return std::get(val.data); + } + + static number_type as_number(const value_type& val) { + if (!val.is_number()) throw std::bad_cast(); + return std::get(val.data); + } + + static integer_type as_integer(const value_type& val) { + if (!val.is_number()) throw std::bad_cast(); + double d = std::get(val.data); + // optional: ensure it's an exact int64 + auto i = static_cast(d); + if (static_cast(i) != d) throw std::bad_cast(); + return i; + } + + static boolean_type as_boolean(const value_type& val) { + if (!val.is_boolean()) throw std::bad_cast(); + return std::get(val.data); + } + + static bool parse(value_type& val, string_type str) { + if (auto r = glz::read_json(val, str); r) { return false; } + return true; + } + + static string_type serialize(const value_type& val) { + if (auto r = glz::write_json(val); r) return *r; + throw std::runtime_error("serialize failed"); + } + }; + } // namespace traits +} // namespace jwt + +#endif // JWT_CPP_STEPHENBERRY_GLAZE_TRAITS_H \ No newline at end of file From b7789c48970c68ddf6edd81695f1e229cdd0753e Mon Sep 17 00:00:00 2001 From: StormLord07 Date: Sat, 16 Aug 2025 00:09:04 +0300 Subject: [PATCH 02/10] first test --- tests/CMakeLists.txt | 8 +++ tests/traits/GlazeTest.cpp | 112 +++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 tests/traits/GlazeTest.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6c7b75504..1acc57966 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -44,6 +44,11 @@ if(TARGET jsoncpp_static) list(APPEND TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/traits/OspJsoncppTest.cpp) endif() +find_package(glaze CONFIG) +if(TARGET glaze) + list(APPEND TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/traits/StephenberryGlazeTest.cpp) +endif() + add_executable(jwt-cpp-test ${TEST_SOURCES}) # NOTE: Don't use space inside a generator expression here, because the function prematurely breaks the expression into @@ -69,6 +74,9 @@ else() if(TARGET jsoncpp_static) target_link_libraries(jwt-cpp-test PRIVATE jsoncpp_static) endif() + if (TARGET glaze) + target_link_libraries(jwt-cpp-test PRIVATE glaze) + endif() endif() target_link_libraries(jwt-cpp-test PRIVATE jwt-cpp nlohmann_json::nlohmann_json $<$>:${CMAKE_DL_LIBS}>) diff --git a/tests/traits/GlazeTest.cpp b/tests/traits/GlazeTest.cpp new file mode 100644 index 000000000..0f2e3636d --- /dev/null +++ b/tests/traits/GlazeTest.cpp @@ -0,0 +1,112 @@ +#include "jwt-cpp/traits/stephenberry-glaze/traits.h" +#include +#include +#include +#include +#include + + +// This is the expanded version of the Mustache template you pasted +TEST(StephenberryGlazeTest, BasicClaims) { + const auto string_claim = + jwt::basic_claim(jwt::traits::stephenberry_glaze::string_type("string")); + ASSERT_EQ(string_claim.get_type(), jwt::json::type::string); + + const auto array_claim = jwt::basic_claim( + std::set{"string", "string"}); + ASSERT_EQ(array_claim.get_type(), jwt::json::type::array); + + const auto integer_claim = jwt::basic_claim(159816816); + ASSERT_EQ(integer_claim.get_type(), jwt::json::type::integer); +} + +TEST(StephenberryGlazeTest, AudienceAsString) { + jwt::traits::stephenberry_glaze::string_type token = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ0ZXN0In0.WZnM3SIiSRHsbO3O7Z2bmIzTJ4EC32HRBKfLznHhrh4"; + auto decoded = jwt::decode(token); + + ASSERT_TRUE(decoded.has_algorithm()); + ASSERT_TRUE(decoded.has_type()); + ASSERT_FALSE(decoded.has_content_type()); + ASSERT_FALSE(decoded.has_key_id()); + ASSERT_FALSE(decoded.has_issuer()); + ASSERT_FALSE(decoded.has_subject()); + ASSERT_TRUE(decoded.has_audience()); + ASSERT_FALSE(decoded.has_expires_at()); + ASSERT_FALSE(decoded.has_not_before()); + ASSERT_FALSE(decoded.has_issued_at()); + ASSERT_FALSE(decoded.has_id()); + + ASSERT_EQ("HS256", decoded.get_algorithm()); + ASSERT_EQ("JWT", decoded.get_type()); + auto aud = decoded.get_audience(); + ASSERT_EQ(1, aud.size()); + ASSERT_EQ("test", *aud.begin()); +} + +TEST(StephenberryGlazeTest, SetArray) { + std::vector vect = {100, 20, 10}; + auto token = + jwt::create() + .set_payload_claim("test", jwt::basic_claim(vect.begin(), vect.end())) + .sign(jwt::algorithm::none{}); + ASSERT_EQ(token, "eyJhbGciOiJub25lIn0.eyJ0ZXN0IjpbMTAwLDIwLDEwXX0."); +} + +TEST(StephenberryGlazeTest, SetObject) { + std::istringstream iss{"{\"api-x\": [1]}"}; + jwt::basic_claim object; + iss >> object; + ASSERT_EQ(object.get_type(), jwt::json::type::object); + + auto token = jwt::create() + .set_payload_claim("namespace", object) + .sign(jwt::algorithm::hs256("test")); + ASSERT_EQ(token, + "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lc3BhY2UiOnsiYXBpLXgiOlsxXX19.F8I6I2RcSF98bKa0IpIz09fRZtHr1CWnWKx2za-tFQA"); +} + +TEST(StephenberryGlazeTest, VerifyTokenHS256) { + jwt::traits::stephenberry_glaze::string_type token = + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJpc3MiOiJhdXRoMCJ9.AbIJTDMFc7yUa5MhvcP03nJPyCPzZtQcGEp-zWfOkEE"; + + const auto decoded_token = jwt::decode(token); + const auto verify = jwt::verify() + .allow_algorithm(jwt::algorithm::hs256{"secret"}) + .with_issuer("auth0"); + verify.verify(decoded_token); +} + +TEST(StephenberryGlazeTest, VerifyTokenExpirationValid) { + const auto token = jwt::create() + .set_issuer("auth0") + .set_issued_at(std::chrono::system_clock::now()) + .set_expires_at(std::chrono::system_clock::now() + std::chrono::seconds{3600}) + .sign(jwt::algorithm::hs256{"secret"}); + + const auto decoded_token = jwt::decode(token); + const auto verify = jwt::verify() + .allow_algorithm(jwt::algorithm::hs256{"secret"}) + .with_issuer("auth0"); + verify.verify(decoded_token); +} + +TEST(StephenberryGlazeTest, VerifyTokenExpired) { + const auto token = jwt::create() + .set_issuer("auth0") + .set_issued_at(std::chrono::system_clock::now() - std::chrono::seconds{3601}) + .set_expires_at(std::chrono::system_clock::now() - std::chrono::seconds{1}) + .sign(jwt::algorithm::hs256{"secret"}); + + const auto decoded_token = jwt::decode(token); + const auto verify = jwt::verify() + .allow_algorithm(jwt::algorithm::hs256{"secret"}) + .with_issuer("auth0"); + ASSERT_THROW(verify.verify(decoded_token), jwt::error::token_verification_exception); + + std::error_code ec; + ASSERT_NO_THROW(verify.verify(decoded_token, ec)); + ASSERT_TRUE(!(!ec)); + ASSERT_EQ(ec.category(), jwt::error::token_verification_error_category()); + ASSERT_EQ(ec.value(), static_cast(jwt::error::token_verification_error::token_expired)); +} From 33f42c3c68a5256f8464977370aede0f3fe09669 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Aug 2025 22:10:08 +0000 Subject: [PATCH 03/10] tests added --- tests/CMakeLists.txt | 8 ++++---- tests/traits/{GlazeTest.cpp => StephenberryGlazeTest.cpp} | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) rename tests/traits/{GlazeTest.cpp => StephenberryGlazeTest.cpp} (93%) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1acc57966..f88c675f6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -45,8 +45,8 @@ if(TARGET jsoncpp_static) endif() find_package(glaze CONFIG) -if(TARGET glaze) - list(APPEND TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/traits/StephenberryGlazeTest.cpp) +if(TARGET glaze::glaze) + list(APPEND TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/traits/StephenberryGlazeTest.cpp) endif() add_executable(jwt-cpp-test ${TEST_SOURCES}) @@ -74,8 +74,8 @@ else() if(TARGET jsoncpp_static) target_link_libraries(jwt-cpp-test PRIVATE jsoncpp_static) endif() - if (TARGET glaze) - target_link_libraries(jwt-cpp-test PRIVATE glaze) + if (TARGET glaze::glaze) + target_link_libraries(jwt-cpp-test PRIVATE glaze::glaze) endif() endif() target_link_libraries(jwt-cpp-test PRIVATE jwt-cpp nlohmann_json::nlohmann_json diff --git a/tests/traits/GlazeTest.cpp b/tests/traits/StephenberryGlazeTest.cpp similarity index 93% rename from tests/traits/GlazeTest.cpp rename to tests/traits/StephenberryGlazeTest.cpp index 0f2e3636d..9773d12d9 100644 --- a/tests/traits/GlazeTest.cpp +++ b/tests/traits/StephenberryGlazeTest.cpp @@ -5,7 +5,6 @@ #include #include - // This is the expanded version of the Mustache template you pasted TEST(StephenberryGlazeTest, BasicClaims) { const auto string_claim = @@ -17,7 +16,7 @@ TEST(StephenberryGlazeTest, BasicClaims) { ASSERT_EQ(array_claim.get_type(), jwt::json::type::array); const auto integer_claim = jwt::basic_claim(159816816); - ASSERT_EQ(integer_claim.get_type(), jwt::json::type::integer); + ASSERT_EQ(integer_claim.get_type(), jwt::json::type::number); // glaze has no integers in it, only doubles } TEST(StephenberryGlazeTest, AudienceAsString) { @@ -56,7 +55,9 @@ TEST(StephenberryGlazeTest, SetArray) { TEST(StephenberryGlazeTest, SetObject) { std::istringstream iss{"{\"api-x\": [1]}"}; jwt::basic_claim object; - iss >> object; + // iss >> object; // THere is no operator >> for string streams in glz::json_t + object = jwt::basic_claim( + *glz::read_json(iss.str())); ASSERT_EQ(object.get_type(), jwt::json::type::object); auto token = jwt::create() From 8a5e71e7ff31f63071d11c88cdaf3b04ef937a41 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Aug 2025 22:41:59 +0000 Subject: [PATCH 04/10] added CI/CD --- .../install/stephenberry-glaze/action.yaml | 19 +++++++++++++++++++ .github/workflows/jwt.yml | 1 + 2 files changed, 20 insertions(+) create mode 100644 .github/actions/install/stephenberry-glaze/action.yaml diff --git a/.github/actions/install/stephenberry-glaze/action.yaml b/.github/actions/install/stephenberry-glaze/action.yaml new file mode 100644 index 000000000..bf8b704c5 --- /dev/null +++ b/.github/actions/install/stephenberry-glaze/action.yaml @@ -0,0 +1,19 @@ +name: Install Glaze +description: Install Glaze header-only library for building test applications +inputs: + version: + description: The desired Glaze version to install + required: false + default: "v5.5.4" +runs: + using: composite + steps: + - run: | + cd /tmp + wget https://github.com/stephenberry/glaze/archive/refs/tags/${{ inputs.version }}.tar.gz + tar -zxf /tmp/${{ inputs.version }}.tar.gz + cd glaze-${{ inputs.version }} + cmake . -B build + cd build + sudo cmake --install . + shell: bash diff --git a/.github/workflows/jwt.yml b/.github/workflows/jwt.yml index 46eed9718..3177a6cd0 100644 --- a/.github/workflows/jwt.yml +++ b/.github/workflows/jwt.yml @@ -16,6 +16,7 @@ jobs: - uses: ./.github/actions/install/danielaparker-jsoncons - uses: ./.github/actions/install/boost-json - uses: ./.github/actions/install/open-source-parsers-jsoncpp + - uses: ./.github/actions/install/stephenberry-glaze - name: configure run: cmake --preset coverage From 692ce2522ef87fbb4dd974811b38bd91435016a4 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Aug 2025 22:59:59 +0000 Subject: [PATCH 05/10] ci fix --- .github/actions/install/stephenberry-glaze/action.yaml | 4 ++-- .github/workflows/traits.yml | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/actions/install/stephenberry-glaze/action.yaml b/.github/actions/install/stephenberry-glaze/action.yaml index bf8b704c5..cfe619462 100644 --- a/.github/actions/install/stephenberry-glaze/action.yaml +++ b/.github/actions/install/stephenberry-glaze/action.yaml @@ -4,13 +4,13 @@ inputs: version: description: The desired Glaze version to install required: false - default: "v5.5.4" + default: "5.5.4" runs: using: composite steps: - run: | cd /tmp - wget https://github.com/stephenberry/glaze/archive/refs/tags/${{ inputs.version }}.tar.gz + wget https://github.com/stephenberry/glaze/archive/refs/tags/v${{ inputs.version }}.tar.gz tar -zxf /tmp/${{ inputs.version }}.tar.gz cd glaze-${{ inputs.version }} cmake . -B build diff --git a/.github/workflows/traits.yml b/.github/workflows/traits.yml index aedcb14af..e830e62fa 100644 --- a/.github/workflows/traits.yml +++ b/.github/workflows/traits.yml @@ -18,6 +18,7 @@ jobs: - { name: "nlohmann-json", tag: "3.12.0", version: "v3.12.0" } - { name: "kazuho-picojson", tag: "111c9be5188f7350c2eac9ddaedd8cca3d7bf394", version: "111c9be" } - { name: "open-source-parsers-jsoncpp", tag: "1.9.6", version: "v1.9.6" } + - { name: "stephenberry-glaze", tag: "5.5.5", version: "v5.5.5" } steps: - uses: actions/checkout@v4 - uses: lukka/get-cmake@latest @@ -56,6 +57,11 @@ jobs: with: version: ${{matrix.target.tag}} + - if: matrix.target.name == 'open-source-parsers-jsoncpp' + uses: ./.github/actions/install/stephenberry-glaze + with: + version: ${{matrix.target.tag}} + - name: test working-directory: example/traits run: | From 1c1669689e1d8435d7668fc58e4b25298f70cbd9 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Aug 2025 23:07:58 +0000 Subject: [PATCH 06/10] tar gz fix for ci --- .github/actions/install/stephenberry-glaze/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/install/stephenberry-glaze/action.yaml b/.github/actions/install/stephenberry-glaze/action.yaml index cfe619462..70eedd054 100644 --- a/.github/actions/install/stephenberry-glaze/action.yaml +++ b/.github/actions/install/stephenberry-glaze/action.yaml @@ -11,7 +11,7 @@ runs: - run: | cd /tmp wget https://github.com/stephenberry/glaze/archive/refs/tags/v${{ inputs.version }}.tar.gz - tar -zxf /tmp/${{ inputs.version }}.tar.gz + tar -zxf /tmp/v${{ inputs.version }}.tar.gz cd glaze-${{ inputs.version }} cmake . -B build cd build From 584cdf109e92e1069edb5cc7d83a21d731cc5cfa Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Aug 2025 23:15:15 +0000 Subject: [PATCH 07/10] CI Fix, made it use propper matrix name --- .github/workflows/traits.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/traits.yml b/.github/workflows/traits.yml index e830e62fa..7d66321be 100644 --- a/.github/workflows/traits.yml +++ b/.github/workflows/traits.yml @@ -57,7 +57,7 @@ jobs: with: version: ${{matrix.target.tag}} - - if: matrix.target.name == 'open-source-parsers-jsoncpp' + - if: matrix.target.name == 'stephenberry-glaze' uses: ./.github/actions/install/stephenberry-glaze with: version: ${{matrix.target.tag}} From fa26ab23a2136b4fcccee60bbd560b85f73c7c4c Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Aug 2025 23:53:10 +0000 Subject: [PATCH 08/10] added examples for stephenberry --- example/traits/CMakeLists.txt | 6 +++ example/traits/stephenberry-glaze.cpp | 65 +++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 example/traits/stephenberry-glaze.cpp diff --git a/example/traits/CMakeLists.txt b/example/traits/CMakeLists.txt index 4734fabc7..32d891c1a 100644 --- a/example/traits/CMakeLists.txt +++ b/example/traits/CMakeLists.txt @@ -34,3 +34,9 @@ if(TARGET jsoncpp_static) add_executable(open-source-parsers-jsoncpp open-source-parsers-jsoncpp.cpp) target_link_libraries(open-source-parsers-jsoncpp jsoncpp_static jwt-cpp::jwt-cpp) endif() + +find_package(glaze CONFIG) +if(TARGET glaze::glaze) + add_executable(stephenberry-glaze stephenberry-glaze.cpp) + target_link_libraries(tephenberry-glaze glaze::glaze jwt-cpp::jwt-cpp) +endif() diff --git a/example/traits/stephenberry-glaze.cpp b/example/traits/stephenberry-glaze.cpp new file mode 100644 index 000000000..5000b46e3 --- /dev/null +++ b/example/traits/stephenberry-glaze.cpp @@ -0,0 +1,65 @@ +#include "jwt-cpp/traits/stephenberry-glaze/traits.h" +#include +#include +#include +#include + +int main() { + using sec = std::chrono::seconds; + using min = std::chrono::minutes; + + using traits = jwt::traits::stephenberry_glaze; + using claim = jwt::basic_claim; + + // Parse raw JSON into claim + claim from_raw_json; + std::istringstream iss{R"##({"api":{"array":[1,2,3],"null":null}})##"}; + from_raw_json = jwt::basic_claim( + *glz::read_json(iss.str())); + // iss >> from_raw_json; // no >> for glaze + + // Example claim sets + claim::set_t list{"once", "twice"}; + std::vector big_numbers{727663072LL, 770979831LL, 427239169LL, 525936436LL}; + + // JWT creation + const auto time = jwt::date::clock::now(); + const auto token = jwt::create() + .set_type("JWT") + .set_issuer("auth.mydomain.io") + .set_audience("mydomain.io") + .set_issued_at(time) + .set_not_before(time) + .set_expires_at(time + min{2} + sec{15}) + .set_payload_claim("boolean", true) + .set_payload_claim("integer", 12345) + .set_payload_claim("precision", 12.3456789) + .set_payload_claim("strings", claim(list)) + .set_payload_claim("array", claim{big_numbers.begin(), big_numbers.end()}) + .set_payload_claim("object", from_raw_json) + .sign(jwt::algorithm::none{}); + + // Decode + const auto decoded = jwt::decode(token); + + // Access array inside the payload object + const auto array = + traits::as_array(decoded.get_payload_claim("object").to_json().get_object()["api"].get_object()["array"]); + // std::cout << "payload /object/api/array = " << array << '\n'; + std::cout << "payload /object/api/array = [ "; + for (size_t i = 0; i < array.size(); ++i) { + std::cout << array[i].dump().value_or("error"); + if (i + 1 < array.size()) std::cout << ", "; + } + std::cout << " ]\n"; + + // Verification + jwt::verify() + .allow_algorithm(jwt::algorithm::none{}) + .with_issuer("auth.mydomain.io") + .with_audience("mydomain.io") + .with_claim("object", from_raw_json) + .verify(decoded); + + return 0; +} From b15ca1f754cc9e4f29b966a59763fdcd6ba319be Mon Sep 17 00:00:00 2001 From: root Date: Fri, 15 Aug 2025 23:55:37 +0000 Subject: [PATCH 09/10] type fix' --- example/traits/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/traits/CMakeLists.txt b/example/traits/CMakeLists.txt index 32d891c1a..f16bc4947 100644 --- a/example/traits/CMakeLists.txt +++ b/example/traits/CMakeLists.txt @@ -38,5 +38,5 @@ endif() find_package(glaze CONFIG) if(TARGET glaze::glaze) add_executable(stephenberry-glaze stephenberry-glaze.cpp) - target_link_libraries(tephenberry-glaze glaze::glaze jwt-cpp::jwt-cpp) + target_link_libraries(stephenberry-glaze glaze::glaze jwt-cpp::jwt-cpp) endif() From 408377de32bb1e62a9f94eb842afaaff4cc71193 Mon Sep 17 00:00:00 2001 From: Ilya Repnev <50772416+StormLord07@users.noreply.github.com> Date: Tue, 19 Aug 2025 15:42:53 +0300 Subject: [PATCH 10/10] Update CMakeLists.txt to pass lint --- tests/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f88c675f6..cc079b6f0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -46,7 +46,7 @@ endif() find_package(glaze CONFIG) if(TARGET glaze::glaze) - list(APPEND TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/traits/StephenberryGlazeTest.cpp) + list(APPEND TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/traits/StephenberryGlazeTest.cpp) endif() add_executable(jwt-cpp-test ${TEST_SOURCES}) @@ -74,7 +74,7 @@ else() if(TARGET jsoncpp_static) target_link_libraries(jwt-cpp-test PRIVATE jsoncpp_static) endif() - if (TARGET glaze::glaze) + if(TARGET glaze::glaze) target_link_libraries(jwt-cpp-test PRIVATE glaze::glaze) endif() endif()