Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
5a78af5
feat: install react-native-keychain
OtavioStasiak May 27, 2026
8691f37
feat(biometric-trust): add enrollment-bound trust store and Option C …
OtavioStasiak May 27, 2026
3a59438
feat(biometric-trust): invalidate biometric trust on enrollment change
OtavioStasiak May 27, 2026
d384c0c
feat(biometric-trust): show explanatory subtitle on enrollment-change…
OtavioStasiak May 27, 2026
c35c0c6
feat(biometric-trust): silent-bind migration for existing biometry us…
OtavioStasiak May 27, 2026
7ec65a4
feat: i18n translation
OtavioStasiak May 27, 2026
f091568
podfile
OtavioStasiak May 27, 2026
8b84535
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak May 28, 2026
898b8aa
fix(biometric-trust): revert ScreenLockConfig toggle when enrol fails
OtavioStasiak May 28, 2026
3dbb3e3
fix(screen-lock): defer modal resolve until close animation finishes
OtavioStasiak May 28, 2026
1565c0d
feat: add e2e tests
OtavioStasiak May 28, 2026
d01f17a
chore: format code and fix lint issues
OtavioStasiak May 28, 2026
76da4bc
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak May 28, 2026
f6f59cb
fix: e2e tests
OtavioStasiak May 29, 2026
952f38a
fix: test flow
OtavioStasiak May 29, 2026
fe0d66b
refactor: encapsulate biometric trust state and speed up screen-lock E2E
OtavioStasiak Jun 2, 2026
13136b6
refactor: route biometric enabled flag through trust store API
OtavioStasiak Jun 2, 2026
68a257f
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 2, 2026
fdb2cc1
refactor(biometric-trust): encapsulate biometry toggle and clarify tr…
OtavioStasiak Jun 2, 2026
256e90b
refactor(biometric-trust): type unlock outcome as discriminated union…
OtavioStasiak Jun 2, 2026
bc0bd7b
refactor(biometric-trust): remove dead mount-time auto-biometry and v…
OtavioStasiak Jun 2, 2026
063ec62
fix(screen-lock): prompt biometry from behind the passcode modal to s…
OtavioStasiak Jun 2, 2026
4e6a86e
fix(biometric-trust): mark install trust-initialized on enrol to clos…
OtavioStasiak Jun 2, 2026
66ab2f8
fix(biometric-trust): restore biometry opt-in prompt on first-passcod…
OtavioStasiak Jun 2, 2026
5969082
fix(biometric-trust): clear enabled flag on unavailable to fix iOS en…
OtavioStasiak Jun 2, 2026
b7e21c0
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 2, 2026
f9c2f86
chore: biometricTrustStore docs
OtavioStasiak Jun 2, 2026
43c18f4
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 2, 2026
80f688f
chore: format code and fix lint issues
OtavioStasiak Jun 2, 2026
ad26251
chore: doc improvement
OtavioStasiak Jun 2, 2026
dcff7c3
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 2, 2026
b566a47
chore: code improvements
OtavioStasiak Jun 2, 2026
fbfd4e2
chore: format code and fix lint issues
OtavioStasiak Jun 2, 2026
050b438
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 3, 2026
122bc6a
fix: persist passcode attempts across re-renders, guard toggle double…
OtavioStasiak Jun 3, 2026
6bd28b6
fix: reset attempts deterministically on lockout expiry and handle mo…
OtavioStasiak Jun 3, 2026
410d8b0
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 3, 2026
bb51c78
fix: passcode unlock and deep link cancellation regressions
OtavioStasiak Jun 3, 2026
f886398
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 11, 2026
31d068f
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 12, 2026
793262d
fix: restore screen lock and biometric trust safeguards
OtavioStasiak Jun 3, 2026
e752780
fix: test
OtavioStasiak Jun 12, 2026
5e2c094
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 15, 2026
8878a40
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 16, 2026
2d03eac
fix(screen-lock): persist authentication time on unlock, not pre-moda…
OtavioStasiak Jun 16, 2026
dcb1087
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 16, 2026
4ce34cc
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 17, 2026
a9a2091
chore: improve readability
OtavioStasiak Jun 17, 2026
b11be3c
fix: remove anti pattern useeffect and rename keys
OtavioStasiak Jun 17, 2026
62c07d8
fix: md
OtavioStasiak Jun 17, 2026
86d2752
fix: test
OtavioStasiak Jun 17, 2026
73f8707
chore: code improvements
OtavioStasiak Jun 18, 2026
3bc3409
fix: dont eject user when a cold-boot unlock is superseded
OtavioStasiak Jun 18, 2026
1306620
chore: format code and fix lint issues
OtavioStasiak Jun 18, 2026
e776dca
fix: test
OtavioStasiak Jun 18, 2026
ece1cda
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 24, 2026
6b0b888
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 25, 2026
4664e51
fix: enforce screen lock on biometric enrollment change regardless of…
OtavioStasiak Jun 26, 2026
28dc057
fix: force passcode after biometric enrollment change regardless of a…
OtavioStasiak Jun 26, 2026
4d292b7
feat(android): silent keystore probe to force screen lock on biometri…
OtavioStasiak Jun 26, 2026
6574cf1
fix: subtitle cutted
OtavioStasiak Jun 26, 2026
926b1f8
action: organized translations
OtavioStasiak Jun 26, 2026
e345a35
fix(biometric): force passcode on grandfather migration to close enro…
OtavioStasiak Jun 29, 2026
e488408
chore: format code and fix lint issues
OtavioStasiak Jun 29, 2026
4d0cec3
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jun 29, 2026
b0499cb
update test
OtavioStasiak Jun 30, 2026
ff8a1a3
test: cover forced relock on biometric reenrollment inside warm window
OtavioStasiak Jun 30, 2026
ab1bffb
refactor: migrate BiometricEnrollment native module to TurboModule
OtavioStasiak Jun 30, 2026
90e9d34
refactor: dedupe enrollment-relock predicate and extract BiometricPro…
OtavioStasiak Jun 30, 2026
f664d1d
fix: fail closed on non-KPIE keystore errors in biometric enrollment …
OtavioStasiak Jul 1, 2026
f71731b
chore: format code and fix lint issues
OtavioStasiak Jul 1, 2026
4694cd8
test: fix mock leak in localAuthentication biometry-consent tests
OtavioStasiak Jul 1, 2026
23c5ddb
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Jul 1, 2026
d026e4c
fix: persist biometric relock debt across teardown to close kill-at-p…
OtavioStasiak Jul 3, 2026
3bbdb22
fix: fail closed when biometric enrollment probe is unavailable
OtavioStasiak Jul 3, 2026
8bba60c
comment cleanup
OtavioStasiak Jul 3, 2026
ec73624
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Aug 12, 2026
e0161fb
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Aug 12, 2026
c39332e
rollback lock
OtavioStasiak Aug 12, 2026
53d8c89
fix: merge issues
OtavioStasiak Aug 12, 2026
bb89748
fix: sniffler and comments
OtavioStasiak Aug 13, 2026
61a4fe8
test: reduce screen-lock sleeps to 7s
OtavioStasiak Aug 13, 2026
72fd12d
fix(screen-lock): require a fresh biometric on Android, not a sentine…
OtavioStasiak Aug 13, 2026
f6c2a07
fix(screen-lock): match errSecItemNotFound on the error code, not the…
OtavioStasiak Aug 13, 2026
7d9f4b5
chore(screen-lock): restore switch exhaustiveness and fix a stale com…
OtavioStasiak Aug 13, 2026
48b9020
fix(screen-lock): keep the first deferred settle instead of clobberin…
OtavioStasiak Aug 13, 2026
b64eceb
fix(screen-lock): clear the biometry flag even if disenroll rejects
OtavioStasiak Aug 13, 2026
b54eb74
fix(screen-lock): arm the relock marker before the grandfather enroll
OtavioStasiak Aug 13, 2026
929506c
fix(screen-lock): require a strong biometric before enrolling trust
OtavioStasiak Aug 13, 2026
227ee13
chore: format code and fix lint issues
OtavioStasiak Aug 13, 2026
ac570e4
docs(screen-lock): correct the probes fail-closed behaviour
OtavioStasiak Aug 13, 2026
879fe0e
fix: test case 11 and 12 flaky tests (#7564)
OtavioStasiak Aug 12, 2026
480419d
fix(db): move sendMessage reads and prepares inside the writer lock (…
OtavioStasiak Aug 13, 2026
8dffa79
fix: Admin Panel content hidden behind bottom navigation bar (#7538)
Rohit3523 Aug 13, 2026
2fe55df
feat: add tabular numbers (#7568)
OtavioStasiak Aug 13, 2026
74ba19a
chore: pin @rocket.chat/sdk to a specific commit hash (#7569)
Rohit3523 Aug 13, 2026
42ecef8
fix(e2ee): re-fetch subscription inside the write in toggleRoomE2EE (…
OtavioStasiak Aug 13, 2026
1685c2e
fix: run handleDelete finds and prepares inside the writer lock (#7552)
OtavioStasiak Aug 13, 2026
8859c62
fix: crop screen hidden behind navigation bar on iOS 26 (#7529)
Rohit3523 Aug 13, 2026
72885da
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Aug 13, 2026
aa00385
chore: format code and fix lint issues
OtavioStasiak Aug 13, 2026
eca63f1
chore: code improvements
OtavioStasiak Aug 20, 2026
c7f17ea
fix: guard biometry toggle against concurrent enable/disable races
OtavioStasiak Aug 20, 2026
ada5fad
fix: check biometry support in toggle and surface enable failures
OtavioStasiak Aug 20, 2026
2356639
action: organized translations
OtavioStasiak Aug 20, 2026
93420f4
fix: arm relock debt before clearing biometry flag in migration
OtavioStasiak Aug 20, 2026
6357699
refactor: pass handleLocalAuthentication args as options object
OtavioStasiak Aug 20, 2026
b925fba
fix: log non-cancel unlock failures instead of swallowing them
OtavioStasiak Aug 20, 2026
2453751
refactor: extract logUnlessUserCanceled helper for unlock catch blocks
OtavioStasiak Aug 20, 2026
980a65a
fix:translation
OtavioStasiak Aug 20, 2026
2b77e60
cleanup
OtavioStasiak Aug 20, 2026
f5af1c5
fix(screen-lock): require a consent prompt on every biometry enable path
OtavioStasiak Aug 20, 2026
8011a2c
cleanup
OtavioStasiak Aug 20, 2026
f07df94
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Aug 20, 2026
df0d5f4
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Sep 4, 2026
aeaf214
chore: format code and fix lint issues
OtavioStasiak Sep 4, 2026
344e564
fix: Android biometric unlock accepting weak (Class 2) enrollments
OtavioStasiak Sep 4, 2026
65b68cb
test: assert the screen lock actually lifts after the final unlock
OtavioStasiak Sep 4, 2026
9202091
chore: add missing screen-lock test-map dependencies
OtavioStasiak Sep 4, 2026
65883ea
test: assert the deep link unlock catch actually runs
OtavioStasiak Sep 4, 2026
57d3924
fix: app stuck on splash when a deep link unlock fails
OtavioStasiak Sep 4, 2026
12da794
fix: transient biometric errors permanently disenrolling users
OtavioStasiak Sep 4, 2026
fe2c535
fix: keystore probe failing open on a corrupted-but-readable keystore
OtavioStasiak Sep 4, 2026
38828e5
fix: forced-passcode copy claiming an enrollment change that never ha…
OtavioStasiak Sep 4, 2026
d3cbc5f
fix: swallowed probe-key failure causing a false enrollment-change te…
OtavioStasiak Sep 4, 2026
e23e586
fix: the failed attempt that trips the lockout never being persisted
OtavioStasiak Sep 4, 2026
29dc106
fix: a superseding passcode-choose request inheriting the previous on…
OtavioStasiak Sep 4, 2026
8d6cb8f
chore: biometric trust cleanup pass — dead paths, telemetry, naming
OtavioStasiak Sep 4, 2026
e8b8eda
docs: drop the biometric trust comments that restate the code below them
OtavioStasiak Sep 4, 2026
63160b4
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Sep 4, 2026
12d983b
Merge branch 'develop' into feat.authentication-bypass-via-biometric-…
OtavioStasiak Sep 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
270 changes: 270 additions & 0 deletions .maestro/tests/assorted/screen-lock.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
appId: ${APP_ID}
name: Screen Lock
onFlowStart:
- runFlow: '../../helpers/setup.yaml'
onFlowComplete:
- evalScript: ${output.utils.deleteCreatedUsers()}
tags:
- test-8

---
Comment thread
OtavioStasiak marked this conversation as resolved.
- evalScript: ${output.user = output.utils.createUser()}
- runFlow:
file: '../../helpers/login-with-deeplink.yaml'
env:
USERNAME: ${output.user.username}
PASSWORD: ${output.user.password}

# Navigate to Screen Lock config
- extendedWaitUntil:
visible:
id: 'rooms-list-view'
timeout: 60000
- tapOn:
id: 'rooms-list-view-sidebar'
- extendedWaitUntil:
visible:
id: 'sidebar-settings'
timeout: 60000
- tapOn:
id: 'sidebar-settings'
- extendedWaitUntil:
visible:
id: 'settings-view-security-privacy'
timeout: 60000
- tapOn:
id: 'settings-view-security-privacy'
- extendedWaitUntil:
visible:
id: 'security-privacy-view-screen-lock'
timeout: 60000
- tapOn:
id: 'security-privacy-view-screen-lock'
- extendedWaitUntil:
visible:
id: 'screen-lock-config-view'
timeout: 60000

# Enable "Unlock with passcode" -> opens PasscodeChoose
- tapOn:
id: 'screen-lock-config-view-auto-lock'
- extendedWaitUntil:
visible:
id: 'passcode-button-1'
timeout: 60000

# Choose passcode 123456
- tapOn:
id: 'passcode-button-1'
- tapOn:
id: 'passcode-button-2'
- tapOn:
id: 'passcode-button-3'
- tapOn:
id: 'passcode-button-4'
- tapOn:
id: 'passcode-button-5'
- tapOn:
id: 'passcode-button-6'

# Confirm passcode 123456
- extendedWaitUntil:
visible:
text: 'Confirm your new passcode'
timeout: 60000
- tapOn:
id: 'passcode-button-1'
- tapOn:
id: 'passcode-button-2'
- tapOn:
id: 'passcode-button-3'
- tapOn:
id: 'passcode-button-4'
- tapOn:
id: 'passcode-button-5'
- tapOn:
id: 'passcode-button-6'

# Back on Screen Lock config; choose "After 1 minute"
- extendedWaitUntil:
visible:
id: 'screen-lock-config-view-auto-lock-time-60'
timeout: 60000
- tapOn:
id: 'screen-lock-config-view-auto-lock-time-60'

# Background the app, wait past the auto-lock interval, relaunch.
- pressKey: Home
- evalScript: ${output.utils.sleep(7000)}
- launchApp:
appId: ${APP_ID}

# Screen Lock modal must appear; unlock with current passcode
- extendedWaitUntil:
visible:
id: 'passcode-button-1'
timeout: 60000
- tapOn:
id: 'passcode-button-1'
- tapOn:
id: 'passcode-button-2'
- tapOn:
id: 'passcode-button-3'
- tapOn:
id: 'passcode-button-4'
- tapOn:
id: 'passcode-button-5'
- tapOn:
id: 'passcode-button-6'

# launchApp cold-starts, so unlocking lands on the rooms list. Navigate back to Screen Lock config.
- extendedWaitUntil:
visible:
id: 'rooms-list-view'
timeout: 60000
- tapOn:
id: 'rooms-list-view-sidebar'
- extendedWaitUntil:
visible:
id: 'sidebar-settings'
timeout: 60000
- tapOn:
id: 'sidebar-settings'
- extendedWaitUntil:
visible:
id: 'settings-view-security-privacy'
timeout: 60000
- tapOn:
id: 'settings-view-security-privacy'
- extendedWaitUntil:
visible:
id: 'security-privacy-view-screen-lock'
timeout: 60000
- tapOn:
id: 'security-privacy-view-screen-lock'

# Entering the Screen Lock screen requires re-auth (PR #4052); unlock with current passcode
- extendedWaitUntil:
visible:
id: 'passcode-button-1'
timeout: 60000
- tapOn:
id: 'passcode-button-1'
- tapOn:
id: 'passcode-button-2'
- tapOn:
id: 'passcode-button-3'
- tapOn:
id: 'passcode-button-4'
- tapOn:
id: 'passcode-button-5'
- tapOn:
id: 'passcode-button-6'

- extendedWaitUntil:
visible:
id: 'screen-lock-config-view'
timeout: 60000
- extendedWaitUntil:
visible:
id: 'screen-lock-config-view-change-passcode'
timeout: 60000
- tapOn:
id: 'screen-lock-config-view-change-passcode'

# Re-authenticate with current passcode (autoLock is on -> handleLocalAuthentication)
- extendedWaitUntil:
visible:
id: 'passcode-button-1'
timeout: 60000
- tapOn:
id: 'passcode-button-1'
- tapOn:
id: 'passcode-button-2'
- tapOn:
id: 'passcode-button-3'
- tapOn:
id: 'passcode-button-4'
- tapOn:
id: 'passcode-button-5'
- tapOn:
id: 'passcode-button-6'

# Now the ChangePasscodeView (PasscodeChoose) opens; choose new passcode 345678
- extendedWaitUntil:
visible:
text: 'Choose your new passcode'
timeout: 60000
- tapOn:
id: 'passcode-button-3'
- tapOn:
id: 'passcode-button-4'
- tapOn:
id: 'passcode-button-5'
- tapOn:
id: 'passcode-button-6'
- tapOn:
id: 'passcode-button-7'
- tapOn:
id: 'passcode-button-8'

# Confirm new passcode 345678
- extendedWaitUntil:
visible:
text: 'Confirm your new passcode'
timeout: 60000
- tapOn:
id: 'passcode-button-3'
- tapOn:
id: 'passcode-button-4'
- tapOn:
id: 'passcode-button-5'
- tapOn:
id: 'passcode-button-6'
- tapOn:
id: 'passcode-button-7'
- tapOn:
id: 'passcode-button-8'

# Modal closes; we are back on the Screen Lock config screen
- extendedWaitUntil:
visible:
id: 'screen-lock-config-view'
timeout: 60000
- assertVisible:
id: 'screen-lock-config-view-change-passcode'

# Background the app, wait past the auto-lock interval, relaunch.
- pressKey: Home
- evalScript: ${output.utils.sleep(7000)}
- launchApp:
appId: ${APP_ID}

# Screen Lock modal must appear; unlock with current passcode
- extendedWaitUntil:
visible:
id: 'passcode-button-3'
timeout: 60000
- tapOn:
id: 'passcode-button-3'
- tapOn:
id: 'passcode-button-4'
- tapOn:
id: 'passcode-button-5'
- tapOn:
id: 'passcode-button-6'
- tapOn:
id: 'passcode-button-7'
- tapOn:
id: 'passcode-button-8'
Comment thread
OtavioStasiak marked this conversation as resolved.

# The taps above pass whether or not the app accepts the digits, so assert the lock actually lifted.
# launchApp cold-starts, so navigation resets to the rooms list rather than the Screen Lock screen.
- extendedWaitUntil:
notVisible:
id: 'passcode-button-3'
timeout: 60000
- extendedWaitUntil:
visible:
id: 'rooms-list-view'
timeout: 60000
19 changes: 19 additions & 0 deletions .sniffler/test-map.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,25 @@
"test": ".maestro/tests/assorted/profile.yaml",
"dependsOn": ["app/views/ProfileView/**", "app/views/ChangePasswordView/**"]
},
{
"test": ".maestro/tests/assorted/screen-lock.yaml",
"dependsOn": [
"app/views/ScreenLockConfigView.tsx",
"app/views/ScreenLockedView.tsx",
"app/views/ChangePasscodeView.tsx",
"app/views/SecurityPrivacyView.tsx",
"app/containers/Passcode/**",
"app/lib/hooks/useDeferredModalSettle.ts",
"app/lib/methods/helpers/localAuthentication.ts",
"app/lib/biometricTrustStore/**",
"app/lib/native/NativeBiometricEnrollment.ts",
"app/definitions/IBiometricTrustStore.ts",
"app/sagas/init.js",
"app/sagas/deepLinking.js",
"app/sagas/login.js",
"android/app/src/main/java/chat/rocket/reactnative/biometric/**"
Comment thread
OtavioStasiak marked this conversation as resolved.
]
Comment thread
OtavioStasiak marked this conversation as resolved.
},
{
"test": ".maestro/tests/assorted/setting.yaml",
"dependsOn": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import chat.rocket.reactnative.notification.PushNotificationTurboPackage
import chat.rocket.reactnative.VoipTurboPackage
import chat.rocket.reactnative.scroll.InvertedScrollPackage
import chat.rocket.reactnative.input.ExternalInputPackage
import chat.rocket.reactnative.biometric.BiometricEnrollmentPackage

/**
* Main Application class.
Expand Down Expand Up @@ -51,6 +52,7 @@ open class MainApplication : Application(), ReactApplication {
add(SecureStoragePackage())
add(InvertedScrollPackage())
add(ExternalInputPackage())
add(BiometricEnrollmentPackage())
}

override fun getJSMainModuleName(): String = "index"
Expand Down
Loading
Loading