Skip to content

refactor(token-scheduler): change token scheduling from days to hours - #423

Open
egalvis27 wants to merge 4 commits into
mainfrom
feat/change-token-scheduler-to-hours
Open

refactor(token-scheduler): change token scheduling from days to hours#423
egalvis27 wants to merge 4 commits into
mainfrom
feat/change-token-scheduler-to-hours

Conversation

@egalvis27

@egalvis27 egalvis27 commented Jul 24, 2026

Copy link
Copy Markdown

What is Changed / Added

  • Refactored the token refresh scheduler to use hours directly instead of converting hours into days.
  • Updated the token renewal logic so the refresh window is calculated from the configured hours-before value.
  • Adjusted the auth schedule creation flow to pass the new hour-based renewal interval.
  • Updated the related tests to reflect the new hour-based behavior and keep the scheduler coverage aligned with the implementation.

Why

  • The authentication flow changed from day-based expiration handling to hour-based handling, and the scheduler logic needed to reflect that change.
  • This makes the refresh timing more accurate and removes the previous awkward conversion logic.
  • The refactor improves clarity, reduces confusion in maintenance, and keeps the behavior consistent with the current product requirements.

Summary by CodeRabbit

  • Bug Fixes

    • Improved token renewal scheduling based on token lifetime for more reliable session continuity.
    • Added safer handling for invalid, expired, non-expiring, or incomplete tokens.
    • Expired sessions now trigger authorization handling, while temporary scheduling issues use a fallback retry interval.
    • Preserved retry and cancellation behavior.
  • Chores

    • Updated development tooling libraries.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@egalvis27, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 22 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8169ad0e-535d-4faa-be49-9e6bde432b31

📥 Commits

Reviewing files that changed from the base of the PR and between eeeb1ce and 1eb0a1b.

📒 Files selected for processing (8)
  • src/apps/main/auth/refresh-token/create-token-schedule-with-retry.test.ts
  • src/apps/main/auth/refresh-token/create-token-schedule-with-retry.ts
  • src/apps/main/token-scheduler/TokenScheduler.ts
  • src/apps/main/token-scheduler/token-scheduler.test.ts
  • src/backend/features/auth/validate-token-and-check-expiration.test.ts
  • src/backend/features/auth/validate-token-and-check-expiration.ts
  • src/backend/features/auth/validate-token.test.ts
  • src/backend/features/auth/validate-token.ts
📝 Walkthrough

Walkthrough

Token validation is centralized in shared authentication helpers. TokenScheduler uses validated claims and shared refresh timing, handles invalid or expired tokens, and applies a five-minute fallback. The refresh-token caller and tests now use the updated scheduler API. @internxt/lib is updated.

Changes

Token Validation and Renewal Scheduling

Layer / File(s) Summary
Shared token validation helpers
src/backend/features/auth/validate-token.ts, src/backend/features/auth/validate-token-and-check-expiration.ts, src/backend/features/auth/*.test.ts
The new helpers validate supplied or stored credentials, return claims or token status, and log normalized errors. Tests cover valid tokens, credential failures, and validation failures.
Validated renewal scheduling and wiring
src/apps/main/token-scheduler/TokenScheduler.ts, src/apps/main/auth/refresh-token/create-token-schedule-with-retry.ts, package.json
TokenScheduler uses shared validation and refresh timing. It handles invalid, expired, and non-expiring tokens and uses a five-minute fallback. The caller uses the two-argument constructor, and @internxt/lib is updated.
Scheduling behavior test coverage
src/apps/main/token-scheduler/token-scheduler.test.ts
Tests cover half-lifetime scheduling, fallback timing, expired-token authorization, invalid and non-expiring tokens, and cancellation.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RefreshScheduler
  participant TokenScheduler
  participant TokenValidation
  participant Timer
  RefreshScheduler->>TokenScheduler: create scheduler with newToken and closeUserSession
  TokenScheduler->>TokenValidation: validate token and read claims
  TokenValidation-->>TokenScheduler: token status and exp/iat claims
  TokenScheduler->>Timer: schedule refresh using shared interval or five-minute fallback
  TokenScheduler->>RefreshScheduler: invoke unauthorized for expired token
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change from day-based token scheduling to hour-based scheduling.
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.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/change-token-scheduler-to-hours

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@egalvis27
egalvis27 force-pushed the feat/change-token-scheduler-to-hours branch from ad68543 to eeeb1ce Compare August 4, 2026 03:06

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
src/apps/main/token-scheduler/token-scheduler.test.ts (2)

45-47: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Restore real timers after each test.

Three tests call vi.useFakeTimers(). The afterEach hook only cancels schedules. Fake timers then remain active for the following tests, which use node-schedule and Date.now(). Add vi.useRealTimers().

🧹 Proposed fix
   afterEach(() => {
     scheduler?.cancelAll();
+    vi.useRealTimers();
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/apps/main/token-scheduler/token-scheduler.test.ts` around lines 45 - 47,
Update the afterEach hook in the token scheduler tests to call
vi.useRealTimers() after cancelling schedules, ensuring every test restores real
timer behavior for subsequent node-schedule and Date.now() usage.

83-102: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

This test depends on undocumented library behavior for a missing iat.

The test creates a token with noTimestamp: true and expects the five-minute fallback. That outcome requires auth.calculateMillisecondsUntilRefresh to return a non-positive value when iat is absent. Confirm that behavior in @internxt/lib 1.5.2. If the library changes, this test becomes misleading rather than failing for a clear reason.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/apps/main/token-scheduler/token-scheduler.test.ts` around lines 83 - 102,
Update the test around TokenScheduler.schedule and
createTokenWithoutIssuedAtExpiringIn to avoid relying on undocumented
`@internxt/lib` behavior for missing iat; explicitly mock or stub
auth.calculateMillisecondsUntilRefresh to return a non-positive value, while
preserving the five-minute fallback assertions.
src/backend/features/auth/validate-token.test.ts (1)

11-19: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the explicit token argument.

The tests only exercise the stored-credential path. TokenScheduler.getTokenClaims calls validateToken({ token }). Add a test that passes a token and asserts that getCredentials is not called.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/backend/features/auth/validate-token.test.ts` around lines 11 - 19, Add a
test alongside the existing valid-token case that calls validateToken with an
explicit token, verifies the decoded claims are returned, asserts validateJwt
was called with that token, and confirms getCredentials was not called.
src/apps/main/token-scheduler/TokenScheduler.ts (1)

37-50: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

The status check and the claims can read different tokens.

validateTokenAndCheckExpiration() reads the stored credentials. getTokenClaims(this.newToken) reads the constructor token. The production caller passes the stored token, so both agree today. If any future caller passes a different token, the scheduler validates one token and schedules from another. Pass this.newToken to both checks to remove that divergence.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/apps/main/token-scheduler/TokenScheduler.ts` around lines 37 - 50, Update
the token validation call in the scheduler flow to pass this.newToken into
validateTokenAndCheckExpiration, matching the token already supplied to
getTokenClaims. Keep the existing invalid and expired status handling unchanged
so both checks consistently operate on the constructor token.
src/backend/features/auth/validate-token-and-check-expiration.ts (1)

6-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider accepting an optional token parameter.

This helper always reads the stored credentials. validateToken accepts an optional token. TokenScheduler needs the status of the token it holds, not only the stored one. An optional token parameter would make both helpers symmetric and let the caller check one specific token.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/backend/features/auth/validate-token-and-check-expiration.ts` around
lines 6 - 9, Update validateTokenAndCheckExpiration to accept an optional token
parameter and use it when provided, falling back to getCredentials only when
omitted. Preserve the existing auth.validateTokenAndCheckExpiration call and
return shape, enabling callers such as TokenScheduler to validate a specific
token while retaining current behavior.
src/backend/features/auth/validate-token.ts (1)

9-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Return the shared Result type from validateToken.

validateTokenAndCheckExpiration uses Result<TokenStatus, Error>, but validateToken returns an inferred { data } | { error } union. Declare validateToken() as Result<JwtPayload, Error>, import Result from context/shared/domain/Result, and return { data: decodedJwtClaims } / { error } consistently.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/backend/features/auth/validate-token.ts` around lines 9 - 24, Update
validateToken to explicitly return Result<JwtPayload, Error>, importing Result
from context/shared/domain/Result. Ensure both successful validation and error
paths return the shared Result shape consistently, while preserving the existing
token validation and logging behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/apps/main/token-scheduler/TokenScheduler.ts`:
- Around line 36-48: Update TokenScheduler.schedule and
createTokenScheduleWithRetry so terminal TokenStatus.EXPIRED and
TokenStatus.INVALID outcomes are represented distinctly from transient
scheduling failures, allowing the caller to stop retrying immediately. Preserve
the existing unauthorized() behavior for expired tokens, ensuring
closeUserSession is invoked at most once, and keep retries only for genuinely
retryable failures.

In `@src/backend/features/auth/validate-token-and-check-expiration.ts`:
- Line 4: Update the Result import in validate-token-and-check-expiration.ts to
replace the duplicated path separator in the module path with a single
separator, without changing the imported symbol or path structure.

In `@src/backend/features/auth/validate-token.ts`:
- Around line 1-24: Run Prettier with write enabled on the added auth files,
including validateToken, and commit the resulting formatting changes without
altering behavior.

---

Nitpick comments:
In `@src/apps/main/token-scheduler/token-scheduler.test.ts`:
- Around line 45-47: Update the afterEach hook in the token scheduler tests to
call vi.useRealTimers() after cancelling schedules, ensuring every test restores
real timer behavior for subsequent node-schedule and Date.now() usage.
- Around line 83-102: Update the test around TokenScheduler.schedule and
createTokenWithoutIssuedAtExpiringIn to avoid relying on undocumented
`@internxt/lib` behavior for missing iat; explicitly mock or stub
auth.calculateMillisecondsUntilRefresh to return a non-positive value, while
preserving the five-minute fallback assertions.

In `@src/apps/main/token-scheduler/TokenScheduler.ts`:
- Around line 37-50: Update the token validation call in the scheduler flow to
pass this.newToken into validateTokenAndCheckExpiration, matching the token
already supplied to getTokenClaims. Keep the existing invalid and expired status
handling unchanged so both checks consistently operate on the constructor token.

In `@src/backend/features/auth/validate-token-and-check-expiration.ts`:
- Around line 6-9: Update validateTokenAndCheckExpiration to accept an optional
token parameter and use it when provided, falling back to getCredentials only
when omitted. Preserve the existing auth.validateTokenAndCheckExpiration call
and return shape, enabling callers such as TokenScheduler to validate a specific
token while retaining current behavior.

In `@src/backend/features/auth/validate-token.test.ts`:
- Around line 11-19: Add a test alongside the existing valid-token case that
calls validateToken with an explicit token, verifies the decoded claims are
returned, asserts validateJwt was called with that token, and confirms
getCredentials was not called.

In `@src/backend/features/auth/validate-token.ts`:
- Around line 9-24: Update validateToken to explicitly return Result<JwtPayload,
Error>, importing Result from context/shared/domain/Result. Ensure both
successful validation and error paths return the shared Result shape
consistently, while preserving the existing token validation and logging
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 947ea1b5-af60-4bb0-bc66-afffd315a4b8

📥 Commits

Reviewing files that changed from the base of the PR and between ad68543 and eeeb1ce.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • package.json
  • src/apps/main/auth/refresh-token/create-token-schedule-with-retry.ts
  • src/apps/main/token-scheduler/TokenScheduler.ts
  • src/apps/main/token-scheduler/token-scheduler.test.ts
  • src/backend/features/auth/validate-token-and-check-expiration.test.ts
  • src/backend/features/auth/validate-token-and-check-expiration.ts
  • src/backend/features/auth/validate-token.test.ts
  • src/backend/features/auth/validate-token.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json

Comment thread src/apps/main/token-scheduler/TokenScheduler.ts Outdated
Comment thread src/backend/features/auth/validate-token-and-check-expiration.ts Outdated
Comment thread src/backend/features/auth/validate-token.ts
@sonarqubecloud

sonarqubecloud Bot commented Aug 4, 2026

Copy link
Copy Markdown

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