Skip to content

fix(account): avoid duplicated accounts + remove existing duplicates - #6559

Open
mahibi wants to merge 2 commits into
masterfrom
bugfix/noid/fixDuplicateAccounts
Open

fix(account): avoid duplicated accounts + remove existing duplicates#6559
mahibi wants to merge 2 commits into
masterfrom
bugfix/noid/fixDuplicateAccounts

Conversation

@mahibi

@mahibi mahibi commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

This PR will

  • at least avoid one way how duplicated accounts could occur (related: Multi Account issues overview聽#4649). No guarantee there are more ways how they occur.
  • remove found duplicates via AccountRemovalWorker itself

AccountVerificationActivity kicked off its login-verification network chain (capabilities -> profile -> storeProfile) from onResume(), which fires again any time the activity is resumed (e.g. a screen lock/unlock) while verification is still in flight. Each re-entry ran the whole chain again and inserted another User row with the same username/baseUrl/token, since storeProfile() always creates a new row and never checks for an existing match.

Move the verification trigger into onCreate(), which runs exactly once per activity instance, so a resume mid-verification no longer restarts the flow.

To reproduce:

  1. Remove any existing account for the test user so the local DB has no matching User row.
  2. Start "Add account" and log in normally; this lands on AccountVerificationActivity and shows "Verifying account..." while it makes several sequential network calls.
  3. While that screen is still showing, lock and unlock the screen a couple of times in quick succession (e.g. adb shell input keyevent KEYCODE_POWER twice, repeated) to force onResume() to fire again mid-verification.
  4. Once login completes, inspect the local User table (e.g. via adb exec-out run-as <pkg> cat databases/nextcloud_talk.sqlite and sqlcipher) - before this fix, one extra row appears per resume that landed during verification, all sharing the same username/baseUrl/ token.

Assisted-by: Claude:claude-sonnet-5

Signed-off-by: Marcel Hibbe dev@mhibbe.de

馃弫 Checklist

  • 鉀戯笍 Tests (unit and/or integration) are included or not needed
  • 馃敄 Capability is checked or not needed
  • 馃敊 Backport requests are created or not needed: /backport to stable-xx.x
  • 馃搮 Milestone is set
  • 馃尭 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

馃 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@mahibi mahibi added this to the 25.0.0 milestone Aug 24, 2026
@mahibi mahibi self-assigned this Aug 24, 2026
@mahibi mahibi added the 3. to review Waiting for reviews label Aug 24, 2026
@mahibi
mahibi requested a review from rapterjet2004 August 24, 2026 15:18
@github-actions

Copy link
Copy Markdown
Contributor

APK file: https://github.com/nextcloud/talk-android/actions/runs/32744036675/artifacts/9527172309
To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app.
qrcode (please click on link to get QR code displayed)

mahibi added 2 commits August 24, 2026 19:36
AccountVerificationActivity kicked off its login-verification network
chain (capabilities -> profile -> storeProfile) from onResume(), which
fires again any time the activity is resumed (e.g. a screen lock/unlock)
while verification is still in flight. Each re-entry ran the whole chain
again and inserted another User row with the same username/baseUrl/token,
since storeProfile() always creates a new row and never checks for an
existing match.

Move the verification trigger into onCreate(), which runs exactly once
per activity instance, so a resume mid-verification no longer restarts
the flow.

To reproduce:
1. Remove any existing account for the test user so the local DB has no
 matching User row.
2. Start "Add account" and log in normally; this lands on
 AccountVerificationActivity and shows "Verifying account..." while it
 makes several sequential network calls.
3. While that screen is still showing, lock and unlock the screen a
 couple of times in quick succession (e.g. `adb shell input keyevent
 KEYCODE_POWER` twice, repeated) to force onResume() to fire again
 mid-verification.
4. Once login completes, inspect the local User table (e.g. via
 `adb exec-out run-as <pkg> cat databases/nextcloud_talk.sqlite` and
 sqlcipher) - before this fix, one extra row appears per resume that
 landed during verification, all sharing the same username/baseUrl/
 token.

 Assisted-by: Claude:claude-sonnet-5

 Signed-off-by: Marcel Hibbe <dev@mhibbe.de>

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Add UserManager.scheduleDuplicateAccountsForDeletion(): for each set of
local User rows sharing the same username+baseUrl, keep the current
account if present, otherwise the oldest row, and schedule the rest for
deletion.

AccountRemovalWorker now runs this check before its existing removal
pass, so duplicates are fully cleaned up (push unregistration,
shortcuts, arbitrary storage, WebSocket instance, DB row) through the
same path as any other account removal, and before
WebsocketConnectionsWorker would otherwise open a parallel signaling
connection per duplicate. Logs a warning via the file-backed Logger
when duplicates are found, so it's visible without the user needing to
have enabled logging beforehand.

Add UserManagerTest covering: keeping the current vs. oldest row,
groups of three or more duplicates, multiple independent duplicate
groups in one pass, rows with a null/blank username or baseUrl never
being grouped, and the no-duplicates/no-users no-op cases.

Assisted-by: Claude:claude-sonnet-5

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
@mahibi
mahibi force-pushed the bugfix/noid/fixDuplicateAccounts branch from 1aaaaf7 to ba4eba5 Compare August 24, 2026 17:36
@mahibi mahibi changed the title fix(account): avoid duplicated accounts fix(account): avoid duplicated accounts + remove existing duplicates Aug 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

APK file: https://github.com/nextcloud/talk-android/actions/runs/32757600969/artifacts/9531703020
To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app.
qrcode (please click on link to get QR code displayed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews AI assisted

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant