Successfully Merging the Debounce LLM Buttons PR

This week, I successfully merged the PR for the Debounce LLM Buttons feature. During the review process, Dr. Shawn pointed out an important software engineering principle regarding error handling.

Initially, I was detecting Gemini API rate limits through string processing and regular expressions by searching for keywords in the error message. However, Dr. Shawn explained that this approach is fragile because human-readable messages can change at any time. Instead, I should parse the JSON response directly and retrieve information from the appropriate fields.

This feedback helped me better understand the difference between processing machine-readable data versus relying on human-readable text. After applying the necessary improvements and revisions, the PR was approved and successfully merged.

Implementing ES256 JWT Verification

After completing the debounce task, I moved on to a new assignment: migrating the QR scanner authentication from HS256 JWT verification to ES256 JWT verification.

The migration involved updating multiple components, including:

  • jwt_client.dart
  • Unit tests
  • Android build configuration

The goal was to replace the shared secret key approach (HS256) with a public/private key pair implementation (ES256) for improved security.

Challenges Faced and Solutions

1. Algorithm Mismatch in Unit Tests

The existing “wrong signature” test used SecretKey('WRONG_SECRET'), which was designed for HS256 verification. Since the application now uses ES256, this resulted in an assertion error instead of the expected JWT exception.

Solution:
Instead of using an incorrect key type, I modified the test by directly tampering with the JWT signature segment to properly simulate an invalid signature scenario.

2. Android Build Compatibility Issues

While testing the implementation, the Android build failed because several dependencies were outdated and incompatible with the current Flutter and Kotlin versions.

Solution:
Updated the following components:

  • AGP: 8.4.0 → 8.9.1
  • Kotlin: 1.9.0 → 2.1.0
  • Gradle: 8.6.0 → 8.11.1

3. JWT Verification Failure During Real QR Testing

The most challenging issue occurred during testing at the final competition event held at Sunway University on 23rd–24th May.

Even after successfully matching the public and private keys, scanning a real QR code still resulted in a JWTInvalidException: not a jwt error.

To investigate, I performed systematic debugging by:

  • Logging the complete QR content
  • Verifying key lengths
  • Comparing key values
  • Testing the JWT independently using jwt.io

After eliminating several possible causes, I discovered that the JWT signature itself was valid. The actual problem was within the payload.

The backend generated the iat (Issued At) claim as a floating-point value:

1777376957.045304

instead of an integer:

1777376957

The dart_jsonwebtoken library strictly requires iat to be an integer and rejects tokens containing floating-point values, resulting in the misleading “not a jwt” error.

After identifying the root cause, I informed Dr. Shawn and proposed changing the backend implementation to generate integer timestamps using:

Math.floor(Date.now() / 1000)

instead of:

Date.now() / 1000

Dr. Shawn acknowledged the findings and requested that I raise a PR and provide sample QR codes so that he could perform further testing and determine the most appropriate long-term solution.

What I Learned

This week reinforced the importance of systematic debugging and understanding the technologies being used instead of making assumptions.

I learned that:

  • Structured data should always be processed through its actual fields rather than through string matching.
  • Security-related changes often affect multiple layers of the application, including tests, build configurations, and deployment environments.
  • Careful debugging and elimination of possibilities can uncover root causes that are not immediately obvious.
  • Valid signatures do not necessarily mean valid JWT tokens if the payload format violates library requirements.

Looking Ahead

For next week, I plan to:

  • Fix any remaining issues related to the current ES256 JWT PR.
  • Continue testing and reviewing the QR authentication flow.

Hopefully, the remaining JWT verification issue can be resolved so the feature can be completed and merged successfully.

Categories: Experiential

0 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.