Skip to content

fix: re-initialise poll loop after re-authentication (#175) - #176

Merged
Percy2Live merged 1 commit into
mainfrom
fix/175-reauth-restart-polling
Sep 26, 2026
Merged

Percy2Live merged 1 commit into
mainfrom
fix/175-reauth-restart-polling

Conversation

@Percy2Live

Copy link
Copy Markdown
Owner

Fixes #175.

Problem

After re-authenticating via the admin OAuth flow, the adapter kept using the old in-memory token: info.connection stayed false and no telemetry was written until the instance was manually restarted (iobroker restart bluetti.0).

Root cause: handleOAuthCallback() completes the login and calls persistTokenJson(), which only updates the in-memory this.oauthTokenJson string and the encrypted auth.tokenJson state. The live BluettiPollRunner + BluettiStoredTokenProvider are built once in startPolling() at onReady and capture the token at that time — nothing rebuilds them, and there is no subscribeStates on the token. So the running poll loop never sees the new token.

This bit a real instance whose refresh token had expired (invalid_grant): re-auth in admin appeared to do nothing, and only a manual restart recovered it.

Fix

  • Add restartPolling(): stop the current pollRunner and call startPolling() again, rebuilding the token provider from the updated this.oauthTokenJson.
  • Call it after persistTokenJson() in handleOAuthCallback().

Stopping the previous loop first prevents two concurrent poll loops. startPolling() stays a graceful no-op when auth/device are not yet configured (first-time login before device selection), and changing the device still restarts the instance via native-config as before.

Test

Adds a regression test that drives the OAuth start-link + callback path with a stubbed fetch and asserts the device is re-bound with the new token (TOKEN_B) after re-auth. Without the fix only the initial bind (TOKEN_A) happens and the assertion fails.

npx tsc --noEmit and eslint are clean.

The running poll loop is built once at startup from the stored OAuth token.
handleOAuthCallback only persisted the new token to the auth state and the
in-memory JSON, but never rebuilt the pollRunner / token provider, so a
re-authentication had no effect until the instance was manually restarted —
the loop kept using the stale (often expired) token.

Add restartPolling() and call it after persistTokenJson in the OAuth callback
so the token provider is rebuilt from the new token. Stopping the previous
loop first prevents two concurrent poll loops.

Adds a regression test that drives the OAuth start-link + callback path with a
stubbed fetch and asserts the device is re-bound with the new token after
re-auth (fails with only the pre-fix single bind).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Percy2Live
Percy2Live enabled auto-merge (squash) September 26, 2026 17:55
@Percy2Live
Percy2Live merged commit 4e9e29e into main Sep 26, 2026
11 checks passed
@Percy2Live
Percy2Live deleted the fix/175-reauth-restart-polling branch September 26, 2026 17:56
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.

Re-authentication has no effect until manual restart: running poll loop keeps the stale token

1 participant