Skip to content

feat: Migration from phone to phone#128

Merged
tevincent merged 30 commits intomainfrom
migration-phone-to-phone
Apr 28, 2026
Merged

feat: Migration from phone to phone#128
tevincent merged 30 commits intomainfrom
migration-phone-to-phone

Conversation

@tevincent
Copy link
Copy Markdown
Contributor

No description provided.

@tevincent tevincent changed the title feat: Migration phone to phone feat: Migration from phone to phone Apr 17, 2026
@tevincent tevincent requested review from LouisCAD and Copilot April 17, 2026 09:23
@tevincent tevincent force-pushed the migration-phone-to-phone branch from e9f1173 to 506a924 Compare April 22, 2026 07:16
Copy link
Copy Markdown

Copilot AI left a comment

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 introduces device-to-device migration support by leveraging platform backups/transfers to restore account state, then re-initializing passkeys on the new device using a marker-folder mechanism to ensure the process runs once per account.

Changes:

  • Add multiplatform file utilities (expect/actual) to create/check a marker folder and per-account marker files.
  • Add a “backed up accounts” handling path that re-authenticates with the restored passkey, registers a new passkey, persists a fresh token, and updates account status.
  • Enable Android backup/device-transfer rules and turn android:allowBackup on, excluding only the marker folder.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
multiplatform-lib/src/commonMain/kotlin/utils/FileUtils.kt Declares common expect APIs for marker folder/file operations.
multiplatform-lib/src/androidMain/kotlin/utils/FileUtils.android.kt Android implementations of marker folder/file operations in filesDir.
multiplatform-lib/src/appleMain/kotlin/utils/FileUtils.apple.kt Apple implementations using Application Support directory (+ exclude from iCloud backup).
multiplatform-lib/src/appleMain/kotlin/internal/utils/FileUtils.kt Adds helper to resolve Application Support directory on Apple platforms.
multiplatform-lib/src/commonMain/kotlin/internal/managers/MigrationManager.kt Adds backed-up account re-initialization (re-register passkey + refresh token).
multiplatform-lib/src/commonMain/kotlin/internal/AuthenticatorFacadeImpl.kt Calls backed-up account handler before legacy migration; writes marker files on addAccounts.
multiplatform-lib/src/commonMain/kotlin/internal/managers/AuthenticatorManager.kt registerPasskey now returns keyId; token retrieval supports explicit keyId; adds keyId getter.
multiplatform-lib/src/commonMain/kotlin/internal/KeyManager.kt Updates KeyPairManager API to search by predicate.
multiplatform-lib/src/commonMain/kotlin/internal/KeyPairManagerImpl.kt Updates expect declaration for new predicate-based lookup.
multiplatform-lib/src/androidMain/kotlin/internal/KeyPairManagerImpl.android.kt Implements predicate-based keyId lookup; small refactor naming.
multiplatform-lib/src/appleMain/kotlin/internal/KeyPairManagerImpl.apple.kt Implements predicate-based keyId lookup in Keychain scanning logic.
app/src/main/res/xml/data_extraction_rules.xml Enables broad device-transfer inclusion of files+db, excludes marker folder.
app/src/main/res/xml/backup_rules.xml Enables broad Auto Backup (API<31) inclusion of files+db, excludes marker folder.
app/src/main/AndroidManifest.xml Enables android:allowBackup="true" and hooks up the above rule files.
Comments suppressed due to low confidence (1)

multiplatform-lib/src/commonMain/kotlin/internal/managers/AuthenticatorManager.kt:120

  • The delete predicate "-$passkeyId-" in it won’t match iOS Keychain tags generated as "$userId-$keyId" (no trailing -). As a result, passkeys may never be deleted on iOS. Align the predicate with the platform storage naming/tagging scheme (e.g., exact match or startsWith("$userId-$passkeyId")).
    suspend fun removeAccount(token: String, userId: Long) {
        val passkeyId = keyPairManager.findKeyIdFor { it.startsWith("$userId-") }.firstOrNull()

        if (passkeyId != null) {
            // If we have a passkey for this account, revoke it against the backend and delete it
            webAuthnRepository.deletePasskey(token, passkeyId)
            val _ = keyPairManager.deleteKeysMatching { "-$passkeyId-" in it }
        }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/src/main/AndroidManifest.xml
Comment thread multiplatform-lib/src/commonMain/kotlin/internal/managers/MigrationManager.kt Outdated
Comment thread multiplatform-lib/src/commonMain/kotlin/internal/managers/MigrationManager.kt Outdated
Comment thread multiplatform-lib/src/androidMain/kotlin/utils/FileUtils.android.kt Outdated
Comment thread app/src/main/res/xml/backup_rules.xml Outdated
Comment thread multiplatform-lib/src/commonMain/kotlin/internal/managers/MigrationManager.kt Outdated
Comment thread multiplatform-lib/src/appleMain/kotlin/internal/KeyPairManagerImpl.apple.kt Outdated
Comment thread app/src/main/res/xml/data_extraction_rules.xml Outdated
@tevincent tevincent force-pushed the migration-phone-to-phone branch from 3f41740 to c5c9f3e Compare April 24, 2026 11:48
@tevincent tevincent enabled auto-merge April 24, 2026 11:58
@tevincent tevincent force-pushed the migration-phone-to-phone branch 2 times, most recently from 314d212 to dd58255 Compare April 27, 2026 10:44
tevincent and others added 19 commits April 28, 2026 09:28
# Conflicts:
#	multiplatform-lib/src/commonMain/kotlin/internal/AuthenticatorFacadeImpl.kt
#	multiplatform-lib/src/commonMain/kotlin/internal/managers/AuthenticatorManager.kt
#	multiplatform-lib/src/commonMain/kotlin/internal/managers/MigrationManager.kt
…ting two sets of files to handle migration account by account
This avoids having 2 files with the exact same name (FileUtils.kt),
and centralizes this code.
@tevincent tevincent force-pushed the migration-phone-to-phone branch from 265260a to d7c4974 Compare April 28, 2026 07:28
@tevincent tevincent merged commit 108c72e into main Apr 28, 2026
7 checks passed
@tevincent tevincent deleted the migration-phone-to-phone branch April 28, 2026 07:35
@sonarqubecloud
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.

3 participants