Skip to content

feat!: the idle timeout belongs to the canister - #181

Open
sea-snake wants to merge 4 commits into
feat/auth-foreground-refreshfrom
feat/auth-idle-bound
Open

feat!: the idle timeout belongs to the canister#181
sea-snake wants to merge 4 commits into
feat/auth-foreground-refreshfrom
feat/auth-idle-bound

Conversation

@sea-snake

Copy link
Copy Markdown
Contributor

maxTimeToIdle on signIn(), carried in the session request beside maxTimeToLive and clamped by the canister the same way — 10 minutes to the session's own granted length, defaulting to seven days where a request names none.

Sent only where the caller asked, so the provider's own default applies otherwise rather than a number this library invented.

IdleManager goes with it. A timer in a page is skipped by clearing storage or by a tab that never runs it, and it saw one document, so a backgrounded tab could sign a user out of the tab beside it. The canister enforces the bound across every tab of a browser at once.

The half that makes this safe is in the PR below: activity mints, so a user reading rather than clicking still keeps the session alive.

Breaking

IdleManager, IdleOptions and AuthClientCreateOptions.idleOptions are removed. Applications that set onIdle subscribe for the sign-out instead; applications that set disableIdle drop the option.

`maxTimeToIdle` on `signIn()`, carried in the session request beside
`maxTimeToLive` and clamped by the canister the same way. Sent only where the
caller asked, so the provider's own default applies otherwise rather than a
number this library invented.
… here

BREAKING CHANGE: `IdleManager`, `IdleOptions` and `AuthClientCreateOptions.idleOptions`
are removed. Pass `maxTimeToIdle` to `signIn()` instead, and subscribe for the
sign-out a lapsed session produces.

A timer in a page is skipped by clearing storage or by a tab that never runs it,
and it saw one document, so a backgrounded tab could sign a user out of the tab
beside it. The canister enforces the bound instead, across every tab of a
browser at once, and activity minting is what keeps a present user from tripping
it.

The burst test now watches its own identity rather than a mint counter every
live client increments.
@sea-snake
sea-snake requested a review from a team as a code owner August 31, 2026 22:54
@sea-snake
sea-snake requested a lite review from Copilot August 31, 2026 23:04

Copilot AI 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.

Pull request overview

This PR moves “idle timeout” enforcement out of the browser and into the identity provider canister by introducing maxTimeToIdle on AuthClient.signIn(), and removes the client-side IdleManager in favor of canister-side bounds. It also introduces activity-based foreground refresh triggers so sessions can be kept alive by user activity (including “reading” patterns like mouse movement), aligning safety with the new canister-enforced idle semantics.

Changes:

  • Add maxTimeToIdle plumbing through AuthClient.signIn()requestSessionDelegation() and ensure it’s omitted unless explicitly provided.
  • Remove the IdleManager API and associated tests; update AuthClient behavior and tests accordingly.
  • Add watchActivity() and use it (alongside watchForeground()) to opportunistically refresh identities in the foreground while preventing overlapping refresh calls.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/client/idle-manager.test.ts Removes tests for the retired IdleManager.
tests/client/foreground-refresh.test.ts Adds test coverage for new watchActivity() behavior.
tests/client/auth-client.test.ts Updates AuthClient tests for removed idle options and adds coverage for maxTimeToIdle + activity-driven minting.
tests/client/auth-client-redirect.test.ts Removes idle-manager-related setup/teardown in redirect-mode tests.
src/client/state-storage.ts Changes StateStorage API around discard() and adds resumable metadata.
src/client/session-delegation.ts Adds maxTimeToIdle to the session delegation JSON-RPC request when provided.
src/client/index.ts Stops exporting the removed idle-manager module.
src/client/idle-manager.ts Deletes the IdleManager implementation.
src/client/foreground-refresh.ts Adds watchActivity() for activity-driven foreground refresh triggers.
src/client/auth-client.ts Removes idle manager integration, adds maxTimeToIdle forwarding, and hooks activity/foreground refresh with concurrency guarding.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/client/state-storage.ts
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