Skip to content

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

Merged
egalvis27 merged 5 commits into
mainfrom
feat/change-token-scheduler-to-hours
Aug 5, 2026
Merged

refactor(token-scheduler): change token scheduling from days to hours#423
egalvis27 merged 5 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.
    • Improved token validation and error handling during authentication.
  • Chores

    • Updated development tooling libraries.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c0102afa-6408-4f9f-ac85-a74fee332fc7

📥 Commits

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

📒 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
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/backend/features/auth/validate-token.test.ts
  • src/backend/features/auth/validate-token.ts
  • src/apps/main/token-scheduler/token-scheduler.test.ts
  • src/apps/main/auth/refresh-token/create-token-schedule-with-retry.ts
  • src/apps/main/token-scheduler/TokenScheduler.ts

📝 Walkthrough

Walkthrough

Shared authentication helpers now validate tokens and return claims or status. TokenScheduler uses validated claims and shared refresh timing, handles invalid or expired tokens, and returns retryable results. The refresh-token caller and tests use the updated 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 helpers validate supplied or stored credentials, return claims or token status, and log normalized errors. Tests cover successful validation, 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 structured scheduling results. @internxt/lib is updated.
Scheduling behavior test coverage
src/apps/main/token-scheduler/token-scheduler.test.ts, src/apps/main/auth/refresh-token/create-token-schedule-with-retry.test.ts
Tests cover refresh timing, fallback scheduling, expiration handling, retry outcomes, invalid and non-expiring tokens, callback execution, 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: return retryability and optional job
  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 describes the main refactor 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 💡 1
📝 Generate docstrings 💡
  • 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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

src/apps/main/auth/refresh-token/create-token-schedule-with-retry.test.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

src/apps/main/auth/refresh-token/create-token-schedule-with-retry.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

src/apps/main/token-scheduler/TokenScheduler.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

  • 5 others

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
Comment on lines 15 to 24
private getTokenClaims(token?: string) {
const { data, error } = validateToken({ token });

return decoded.exp ? decoded.exp * 1000 : TokenScheduler.MAX_TIME;
} catch (err) {
logger.error({ msg: '[TOKEN] Token could be not decoded' });
if (error || !data.exp) return;

return TokenScheduler.MAX_TIME;
}
return {
exp: data.exp,
iat: data.iat,
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is this method really necessary? does not seem to add much value other than be a wrapper to a method

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done

@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

@egalvis27
egalvis27 merged commit 908bfd0 into main Aug 5, 2026
12 checks passed
@egalvis27
egalvis27 deleted the feat/change-token-scheduler-to-hours branch August 5, 2026 17:17
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.

2 participants