Repository navigation
refactor: migrate app passcode flows to SwiftUI - #4419
Conversation
Support passcode authentication, creation, changes and removal with biometrics and shared lockout protection. Keep the existing passcode flow active until callers are migrated. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Update lock settings after passcode completion and handle reset results. Add toolbar dismissal and require the current passcode when changing it. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Require authentication in Debug builds and verify the account before executing E2EE actions. Present cancellable passcode flows as sheets and handle completion during dismissal. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Use the shared passcode view for app unlock and enforced setup. Scope lifecycle handling to the presenting window scene and cancel optional operations when backgrounded. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Replace TOPasscode in the main app and Share Extension, remove the legacy implementation, and add passcode UI tests. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Clear only the retry counter and lockout deadline when the delay expires. Add UI coverage verifying app reset after ten failures across lockouts. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Present the mandatory lock in a dedicated window per scene and preserve underlying UI after unlocking. Add UI regression coverage, improve authentication test handling, and enforce CI test timeouts with retained diagnostics. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Allow the initial HTTPS request to time out before expecting the localhost authentication page, and skip UI queries against authentication services that are not running. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com> Assisted-by: Codex:GPT-6
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Preserve the auto-upload suspension message until all reads finish, and discard cancelled or stale refreshes. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Embed the passcode view in the content controller while hiding the enclosing navigation bar, and constrain its width to the available space. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
|
|
Actually now that I think about it, to me the "too many attempts" 60 seconds cooldown is a bit useless. What is the point of it? We are not really doing anything security wise. We can remove it and instead turn on the "reset data after 10 attempts" on always? |
|
@marinofaggiana the UI tests should be included in the CI. Also keep in mind UI tests must be maintained with time so they are always green. |
done. |
Preserve mandatory authentication across scenes and relaunches after lockout. Require biometric authorization before enabling Touch ID or Face ID, add passcode error feedback, and update lockout UI tests. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
Right, but in this case the UI tests will be not super useful as no one will run them (let's be honest). You can add the UI tests as a separate CI workflow and either:
Claude can do this. |
They require so much time, far too much time! |
good idea. I do |
Shorten reset-test lockouts and let XCTest terminate the app after observing completed cleanup to avoid TSan exit issues. Run passcode UI tests when related files change and increase CI test timeouts. Signed-off-by: Marino Faggiana <marino.faggiana@nextcloud.com>
…(XEN-293) All 21 PasscodeUITests (new from upstream nextcloud#4419) failed at login on PR #35: BaseUIXCTestCase.logIn() waits for the intro "login" button and types TestConstants.server (http://localhost:8080) into the server field, but our single-tenant lock skips the intro and disables that field, so the app showed only submitServerAddress and the QR button. Restore upstream's login flow (intro shown, empty editable server field) for UI_TESTING launches only, under #if DEBUG. The scheme's Test action builds Debug and Archive builds Release, so no shipped binary contains the escape hatch. Same call as talk-ios XEN-202. No test file touched. Assisted-by: ClaudeCode:claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DfGtQofgcLaqMsHHJCGrNo
The passcode UI tests time out on the xcode-27 runner because the app's main thread is saturated serving XCTest accessibility snapshots. The login helpers poll every 250 ms with about 8 queries a pass, and each query snapshots the app on its main thread, where the http fallback, the Login Flow v2 poll and the grant handling all run. Upstream's own CI fails the same way on nextcloud#4419. - NCLogin: dismiss the keyboard on the login button, as the Return key path already does. The keyboard keys were about half of every snapshot. - BaseUIXCTestCase: poll once a second instead of every 250 ms in waitForAuthenticationConsent and authenticationWebView. No test is skipped or disabled. Passes locally on the Mac Mini; only a run on the xcode-27 runner can confirm the fix. Assisted-by: ClaudeCode:claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DfGtQofgcLaqMsHHJCGrNo
Replace the legacy TOPasscodeViewController implementation with shared SwiftUI passcode components for the main app, Share Extension and E2EE authentication, while preserving existing Keychain credentials and preferences.
Behavior
UI tests and CI
Add seven XCUITests in
PasscodeUITests:The main
xcode.ymlworkflow conditionally includes these tests when the PR changes passcode code, Settings integration, preferences, scene/app lifecycle, Share integration, branding, UI-test infrastructure, project configuration or the workflow itself. Otherwise it skipsPasscodeUITestsand continues running the other enabled tests. There is no separate passcode workflow.The test environment uses an English simulator and server. The login helper reuses an existing account or performs the real web login, including handling the password-saving prompt. Removing the asynchronous account deletion at launch avoids opening an interface whose account is being deleted underneath it.
Debug-only test setup resets passcode state before each test. The reset-threshold test uses 10-second lockouts while keeping all ten failures and three lockouts; persistence tests retain the normal 60-second delay. With
UI_TESTING_NO_EXIT, real reset cleanup completes and exposes a completion marker before XCTest terminates the app itself, avoiding theexit(0)/ Thread Sanitizer finalization issue. Normal app execution retainsexit(0).CI uploads
TestResult.xcresulteven after test failure when available. The bundle includes test results and retained diagnostic screenshots/UI hierarchies for the instrumented failure paths. Console output is available in the Run Xcode Test step.Running locally
http://localhost:8080, withadmin/admin.Tests/Server.shprovides the Docker setup. Keep Docker and the server running throughout the suite.docker exec --user www-data xcode-test-server php /var/www/html/occ config:system:set force_language --value=en curl --fail --show-error http://localhost:8080/status.phpAdditional device verification
🤖 AI (if applicable)