Skip to content

feat(api): expose whether sessions have a maximum lifetime - #960

Merged
swolfand merged 7 commits into
mainfrom
sam/mobile-session-lifetimes
Oct 22, 2026
Merged

swolfand merged 7 commits into
mainfrom
sam/mobile-session-lifetimes

Conversation

@swolfand

@swolfand swolfand commented Sep 22, 2026 •

Copy link
Copy Markdown
Collaborator

What & why

Add Session.hasMaximumLifetime so callers can distinguish indefinite native sessions from finite expiration deadlines. Cover zero-deadline serialization and keep session status separate from lifetime.

Companion to the backend native-session policy, clerk_go#22459 → #22460 → #22461 → #22462 → #22369. Part of MOBILE-517.

Other companions: iOS, JavaScript/Expo, Dashboard, edge regression tests, docs.

What to focus on

expireAt == 0 means no maximum lifetime, including when a session is revoked.

expireAt stays a required Long. The backend always sends expire_at as a number, 0 for sessions without a maximum lifetime, never omitted or null: the client and server session serializers in api/serialize/session.go declare it as a plain int64 without omitempty and fill it with UnixMilliOrZero (clerk_go#22459).

Nothing in the SDK compares Session.expireAt against the current time, so a zero deadline is never treated as expired. Token refresh uses the session token's own expiry.

Screenshots / video

No UI changes.

Summary by CodeRabbit

  • New Features
    • Sessions now indicate whether they have a maximum lifetime.
    • Session expiration information distinguishes the maximum-lifetime deadline from the inactivity deadline; a value of zero indicates that the corresponding deadline is not set.
    • Session lifetime data can be safely read when the maximum-lifetime value is omitted or null, with no maximum lifetime reported in those cases.

Verified on an Android emulator, as reported by the session that swolfand started. Run r20261021-124556-569e on Clerk_Verify_Pixel on ubuntu-24.04 at 4c6189d0cc8b, 2 of 2 passed.

signed-in relaunched
signed-in relaunched

Add hasMaximumLifetime and verify indefinite deadlines survive session serialization.

Part of MOBILE-517
@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: clerk/clerk-android/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Team
  • Run ID: fa964e4f-11a5-406e-aad1-4b97097c0ccd
📥 Commits

Reviewing files that changed from the base of the PR and between 5d9d1ff and 4c6189d.

📒 Files selected for processing: 3
  • source/api/api/api.api
  • source/api/src/main/kotlin/com/clerk/api/session/Session.kt
  • source/api/src/test/java/com/clerk/api/session/SessionLifetimeTest.kt

Included review availability: This review used your included allowance. 3 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.

📝 Walkthrough

Session now treats missing or null expire_at values as 0L. It adds hasMaximumLifetime, which is true when expireAt is greater than zero. Tests cover decoding, status behavior, abandonment timestamps, and serialization.

Changes: Session lifetime

Layer / File(s) Summary
Define and validate the maximum lifetime property
source/api/src/main/kotlin/com/clerk/api/session/Session.kt, source/api/api/api.api, source/api/src/test/java/com/clerk/api/session/SessionLifetimeTest.kt
Session defaults missing or null expire_at values to 0L and documents zero as no maximum lifetime. The public API exposes hasMaximumLifetime. Tests cover zero and future expiration values, revoked sessions, abandonment timestamps, decoding, and serialization.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Feature

Suggested reviewers: seanperez29

Merge Risk: ⚪ Minimal · up to 4c618

Zero-deadline sessions retain their lifetime value when stored and restored. No issue identified here needs to block merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 2 files. (1 skipped: 1 … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary change: exposing whether sessions have a maximum lifetime.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description includes all required sections: rationale, review focus, and screenshots/video status. It explains the lifetime semantics, serialization behavior, related work, testing evidence, and t…
Full details: Description check

Explanation

The description includes all required sections: rationale, review focus, and screenshots/video status. It explains the lifetime semantics, serialization behavior, related work, testing evidence, and the absence of UI changes.

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 2 files. (1 skipped: 1 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@swolfand

Copy link
Copy Markdown
Collaborator Author
  • Won't build on main: explicitApi() is on since build: enable explicit API mode for api, ui and telemetry #1023, and val hasMaximumLifetime (Session.kt:67) has no public modifier.
  • source/api/api/api.api isn't updated, so apiCheck fails.
  • Conflicts in Session.kt (chore: remove comments that restate code #977 removed the abandon_at comment); consider moving that note to KDoc.
  • expireAt is still a required Long. If the backend omits expire_at for indefinite sessions rather than sending 0, decoding fails; confirm or default it.
  • SessionLifetimeTest asserts seven unrelated things in one test; split it.

Resolve Session.kt conflict by keeping main's structure and moving the abandonAt semantics into KDoc. Make hasMaximumLifetime explicitly public and update the API dump for explicitApi()/apiCheck.
…etime

Default Session.expireAt to 0 so a response that omits expire_at, or
sends null, decodes instead of failing. The type stays Long, so the
public API is unchanged. Split the lifetime tests so each checks one
behaviour, and decode through the SDK's own Json configuration.
@swolfand
swolfand merged commit d77ae00 into main Oct 22, 2026
15 of 16 checks passed
@swolfand
swolfand deleted the sam/mobile-session-lifetimes branch October 22, 2026 00:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant