Skip to content

Unexpected behavior from JWT implementation of 'Expires' protocol #235

@cconway

Description

@cconway

Describe the bug?

The implementation of Expires protocol properties .expiresAt, .isExpired, and .isValid, in an extension, are returning unexpected results for JWT object instances.

The Expires.expiresAt value is computed as issuedAt?.addingTimeInterval(expiresIn). When the JWT does not contain the optional claim "exi" (expires in), the JWT.expiresIn value returns zero. This results in the issuedAt and expiresAt dates being identical, causing the isExpired value to always be true and the isValid value to always be false.

What is expected to happen?

The Expires.isExpired and Expires.isValid property values should reflect the actual expiration status of the object adopting the Expires protocol. In the case of JWT instances it is expected that any valid and standardized way of prescribing expiration would be supported: For example, expiration would be determined from the "exp" claim OR "isa" and "exi" claims depending on availability.

What is the actual behavior?

The Expires.isExpired and Expires.isValid properties return expected values for instances of Token but always indicate expired/invalid for JWT instances where the optional "exi" claim is not present, even if the "exp" claim is present and is a future date.

Reproduction Steps?

An example JWT token created with expiration date one year in the future that should identify, on 2025-06-17, as not expired:

let validJWT = JWT("eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImY0ODYxYjIwNDY4MTRlZDdiNGJhZjhkNzIxZDdiNzBkIn0.eyJpc3MiOiJodHRwczovL2lkcC5sb2NhbCIsImF1ZCI6ImFwaTEiLCJzdWIiOiI1YmU4NjM1OTA3M2M0MzRiYWQyZGEzOTMyMjIyZGFiZSIsImNsaWVudF9pZCI6Im15X2NsaWVudF9hcHAiLCJleHAiOjE3ODE3MTk2MzksImlhdCI6MTc1MDE4MzUxOCwianRpIjoiMWQxZTBlZDdmOTc4ZDI1ZjhmYTc2YTFiNzk5ODFiYTIifQ.AoQeE8LFT6Sp969FmFJZPYAhujliuU4XTBhZ0oPdHLUZLokOHHbpXI0BmZbNsVHh7ncD9Umk_IS1g-X51mPPEQ")

validJWT.expirationTime  // 2026-06-17
validJWT.expiresAt  // 2025-06-17
validJWT.expiresIn  // 0.0
validJWT.isExpired  // true
validJWT.isValid  // false

Additional Information?

No response

SDK Version(s)

Reproduced in okta-mobile-swift v1.4.3 but didn't see any obvious relevant changes in the master branch.

Build Information

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions