Commit graph

14036 commits

Author SHA1 Message Date
de2edafe61 feat(wallet): rewrite SSSS on account data + AES-256-GCM envelope
The Rust SDK removed the low-level SecretStoreWrapper.putSecret/getSecret
API between 26.03.x and 26.04.x — it was an escape hatch we were using
to pin arbitrary bytes into a Matrix 4S slot. The SDK maintainers never
contracted that primitive; locking it down lets their recovery code
evolve without worrying about third-party storage.

This commit replaces that dependency with a self-contained design we
own end-to-end, so future SDK moves no longer break our backup flow.

### Design
- Slot: `com.sulkta.wallet.seed.v1` in Matrix account data.
  Our namespace, not a Matrix-spec 4S slot — we are NOT impersonating
  Matrix secret storage, we are holding our own opaque blob.
- Envelope (JSON): version tag, algorithm tag, random 12-byte IV, GCM
  output (ciphertext || tag), AAD = slot name. AES-256-GCM via stock
  javax.crypto. AAD binds a blob to its slot so a blob can't be lifted
  from one namespace and successfully opened in another.
- Key: derived from the user's existing Matrix recovery key via
  HKDF-SHA256 with info label "sulkta.wallet.seed.v1". The info label
  guarantees we never produce the same key bytes Matrix uses for its
  own crypto — same secret, different domain.
- I/O: client.setAccountData(key, json) + client.accountData(key)
  via the SDK; the homeserver only ever sees the opaque encrypted blob.

### Files
- api/walletsecretstorage/WalletSecretStorage.kt — new interface
- impl/walletsecretstorage/WalletSecretEnvelope.kt — AES-GCM envelope
  (with unit tests: round-trip, wrong key, tampered ct, tampered iv,
  wrong AAD, wrong version, malformed JSON)
- impl/walletsecretstorage/RecoveryKeyDerivation.kt — base58 decode
  + parity check + HKDF-SHA256 (with unit tests: determinism,
  whitespace tolerance, distinct info labels → distinct keys)
- impl/walletsecretstorage/MatrixAccountDataWalletSecretStorage.kt —
  WalletSecretStorage impl wrapping Client account data
- test/walletsecretstorage/FakeWalletSecretStorage.kt — in-memory fake
- api/MatrixClient.kt: old .secretStorage → .walletSecretStorage
- features/wallet/.../WalletBackupServiceImpl.kt — rewired to use the
  new interface; hasBackupWithoutKey now goes through the same path
  instead of manually poking the raw Matrix HTTP API.
- DELETED: api/secretstorage/SecretStorage.kt, SecretStore.kt, impl/
  secretstorage/RustSecretStorage.kt — the old SDK-dependent path.

### Backward compat note
Users who backed up a wallet seed on the OLD SDK have a blob in Matrix's
4S at `com.sulkta.cardano.wallet_seed`. This branch cannot read those.
Since the prior integration was only tested internally, acceptable
today — anyone with an old backup re-enters their mnemonic.
2026-04-17 10:16:53 -07:00
a944499eda fix(sdk): adapt to matrix-rust-sdk 26.04.x API shifts
TracingConfiguration gained a required sentryConfig parameter between
26.03.x and 26.04.x. Pass null — we don't use SDK-side Sentry.

Timeline.sendRaw was moved off Timeline onto Room. Add sendRawEvent to
the JoinedRoom API interface, implement in JoinedRustRoom by calling
innerRoom.sendRaw, and have RustTimeline.sendRaw proxy through the
owning JoinedRoom. Our /pay event path keeps working without callers
having to know about the SDK move.
2026-04-17 10:12:48 -07:00
0ef6b69a79 Merge branch 'main' into wallet
# Conflicts:
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNavigator.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsPickerView.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/suggestions/SuggestionsProcessor.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/threads/ThreadedMessagesNode.kt
#	features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/topbars/MessagesViewTopBar.kt
#	libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/mentions/ResolvedSuggestion.kt
2026-04-16 22:05:16 -07:00
84519ab6c9 docs: add SYNC.md explaining repo topology + upstream sync procedure 2026-04-16 21:01:31 -07:00
Benoit Marty
9eac64067b
Merge pull request #6596 from element-hq/renovate/androidx.annotation-annotation-jvm-1.x
Update dependency androidx.annotation:annotation-jvm to v1.10.0
2026-04-16 18:07:50 +02:00
Benoit Marty
20bb52e59f
Merge pull request #6593 from element-hq/renovate/io.element.android-element-call-embedded-0.x
Update dependency io.element.android:element-call-embedded to v0.19.1
2026-04-16 18:06:16 +02:00
Benoit Marty
2e4c9954b7 Changelog for version 26.04.3 2026-04-16 17:34:48 +02:00
Benoit Marty
bd0aa4ba75 Merge tag 'v26.04.3' into develop
tag
2026-04-16 16:40:17 +02:00
Benoit Marty
1dbdd4905d Merge branch 'release/26.04.3' 2026-04-16 16:40:07 +02:00
Benoit Marty
d7118bfad8 Adding fastlane file for version 26.04.3 2026-04-16 16:40:04 +02:00
Benoit Marty
228f188b5a Setting version for the release 26.04.3 2026-04-16 16:39:44 +02:00
Jorge Martin Espinosa
c349f74ce8
Fix loading initial items of non-live timelines (#6598)
This was done automatically by the SDK in the past by returning a `Reset` timeline update, but this behaviour changed and now we have to do it.
2026-04-16 14:19:29 +00:00
renovate[bot]
67c0e4c140
Update nschloe/action-cached-lfs-checkout action to v1.2.5 (#6600)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 15:26:20 +02:00
renovate[bot]
d8c540956a
Update dependency org.matrix.rustcomponents:sdk-android to v26.04.15 (#6595)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 09:56:48 +02:00
renovate[bot]
42bd404a20
Update dependency androidx.annotation:annotation-jvm to v1.10.0 2026-04-16 07:39:35 +00:00
renovate[bot]
b21f7cd18f
Update dependency io.element.android:element-call-embedded to v0.19.1 2026-04-16 07:32:12 +00:00
Benoit Marty
9699488ae5
Merge pull request #6587 from element-hq/feature/bma/flagsFromOnBoarding
Split developer settings into 2 screens to be able to access global settings when no logged in.
2026-04-15 16:16:23 +02:00
Jorge Martín
7cdad11753 Use Devices.PHONE directly in the landscape preview 2026-04-15 15:51:06 +02:00
Jorge Martín
69fb344517 Use WindowSizeClass instead of just checking portrait/landscape orientation 2026-04-15 15:51:06 +02:00
ElementBot
15eca13ff8 Update screenshots 2026-04-15 15:51:06 +02:00
Jorge Martín
9a5ed43f80 Try generating landscape screenshots again 2026-04-15 15:51:06 +02:00
Jorge Martín
42a572cce2 Add landscape previews 2026-04-15 15:51:06 +02:00
Jorge Martín
70e45d9bfe Some tweaks for landscape and insets 2026-04-15 15:51:06 +02:00
bxdxnn
f389eae868 Make media captions scrollable (#6498) 2026-04-15 15:51:06 +02:00
Jorge Martin Espinosa
0058de9bca
Add extra logs for timeline pagination (#6589)
We found some possible rare issues with pagination these could help understand.
2026-04-15 15:14:42 +02:00
Benoit Marty
8503d1c548 Fix tests compilation 2026-04-15 14:45:38 +02:00
Jorge Martin Espinosa
66513bc905
Take into account homeserver capabilities (#6507)
* Take into account homeserver capabilities: add `HomeserverCapabilitiesProvider` to check if the HS allows changing the user's display name or avatar. Also, modify the edit user profile screen to reflect these values.

* Add `/myavatar` command. Filter both `/nick` and `/myavatar` commands based on the homeserver capabilities.

* Update screenshots

* Assume the use can change their display name and avatar url if the capabilities check fails: if they try to change those, the HS will return an error anyway.

* Disable also `/myroomname` and `/myroomavatar` based on the HS capabilities.

---------

Co-authored-by: ElementBot <android@element.io>
2026-04-15 12:29:41 +00:00
Jorge Martin Espinosa
80470b3792
Feature: add room threads list (#6575)
Add threads list screen for rooms:

- Add `ThreadsListService` to subscribe to thread changes in the room.
- Create `ThreadsListView` and its associated node a presenters (the UI may change).
- Add a menu icon in the room screen to open it.

This is still pending info about unread threads, so several UI components related to it will be hidden.

* Add feature flag and use it to hide the access to this new screen

---------

Co-authored-by: ElementBot <android@element.io>
2026-04-15 12:14:22 +00:00
ElementBot
6d3b4aaaee Update screenshots 2026-04-15 10:27:54 +00:00
Benoit Marty
be775d686e
Merge pull request #6586 from element-hq/feature/bma/useSignInWithClassicFlag
Take into account the value of FeatureFlags.SignInWithClassic
2026-04-15 12:21:29 +02:00
ganfra
b60f3e2ca0
Merge pull request #6571 from element-hq/renovate/metro
Update metro to v0.13.2
2026-04-15 12:21:08 +02:00
Benoit Marty
1b03dd1dcb Split developer settings into 2 screens to be able to access global settings when no logged in. 2026-04-15 12:11:25 +02:00
Benoit Marty
e4bee737b1 Take into account the value of FeatureFlags.SignInWithClassic 2026-04-15 12:00:29 +02:00
Skye Elliot
897c68e7b7
Add confirmation dialog when inviting users with unknown identities (#6523)
* feat: Add confirmation modal when inviting unknown users

* tests: Add preview tests for invite confirmation modal

* tests: Add unit tests for invite confirmation modal

* feat: Switch confirmation sheet contents based on identity state

* tests: Add history sharing unit tests for `DefaultStartDMActionTest`

* tests: Update snapshots for `CreateDmConfirmationBottomSheet`

* chore: Fix tiny nits

* fix: Remove default param on `ConfirmingStartDmWithMatrixUser`

* refactor: Use new AsyncAction over boolean flag

* fix: Add sleeps to tests

* refactor: Remove `PromptOrInvite` and switch on async action

* fix: Remove redundant `assertThat`

* feat: Alllow invite confirmation modal to be dismissed

* tests: Update snapshots for InvitePeopleView

* fix: Adjust `CreateDmConfirmationBottomSheet` to conform to design

* feat: Use localazy translations and plurals

* fix: When users are unselected, unselect them in search results too

* tests: Use aMatrixUserList to provide multiple users

* Update screenshots

* fix: Add missing parameter in UserProfilePresenterTest

---------

Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
Co-authored-by: ElementBot <android@element.io>
2026-04-15 10:25:58 +01:00
Jorge Martin Espinosa
e0554bbaf3
Use Coil3 for ZoomableAsyncImage (#6582)
The `-coil` version uses Coil 2.X, there is a `-coil3` version using the latest one, which matches the one we use in the rest of the app.
2026-04-15 07:58:03 +00:00
Benoit Marty
b6188a7646
Merge pull request #6576 from element-hq/renovate/com.google.testparameterinjector-test-parameter-injector-1.x
Update dependency com.google.testparameterinjector:test-parameter-injector to v1.22
2026-04-15 09:45:56 +02:00
Benoit Marty
937973570a Use @TestParameter instead of doing the work manually. 2026-04-15 08:39:14 +02:00
Benoit Marty
4cc9c77264 Use @TestParameter instead of doing the work manually. 2026-04-15 08:32:26 +02:00
Benoit Marty
4b8368f242
Merge pull request #6296 from element-hq/feature/bma/signInWithElementClassicFinal
Sign in with element classic final
2026-04-14 23:00:47 +02:00
Valere Fedronic
8bd6035511
Merge pull request #6574 from element-hq/feature/valere/call/ongoing_voice_call_join
feat: Default to camera muted when joining ongoing voice call
2026-04-14 22:47:58 +02:00
Benoit Marty
65f3e74e35
Merge pull request #6561 from element-hq/feature/bma/removeSpaceAnnouncement
Remove space announcement
2026-04-14 16:58:25 +02:00
Benoit Marty
fd3c4c2b2b Refresh Element Classic state each time ClassicFlowNode is resumed.
This ensure that Element X is always up to date regarding Element Classic state.
2026-04-14 16:51:00 +02:00
renovate[bot]
29e4771b22
Update dependency com.google.testparameterinjector:test-parameter-injector to v1.22 2026-04-14 13:56:35 +00:00
Jorge Martin Espinosa
7a7a5a68b9
Fix isInAirGappedEnvironment check for older APIs (#6573)
* Fix `isInAirGappedEnvironment` check for older APIs: use `networkCapabilities.hasCapability` instead of `networkCapabilities.capabilities.contains`, which only works on Android 12 and newer versions

* Check for air-gapped env in the FOSS app too: this unifies the notification behaviour on EXA and Element Pro
2026-04-14 15:52:41 +02:00
Valere
8ccb5cbf72 Merge remote-tracking branch 'origin/feature/valere/call/ongoing_voice_call_join' into feature/valere/call/ongoing_voice_call_join 2026-04-14 15:21:08 +02:00
Valere
b033f2e129 fixup: test compilation pb 2026-04-14 15:20:56 +02:00
ElementBot
107524b01d Update screenshots 2026-04-14 13:18:21 +00:00
Valere
83c4fa8278 feat: Default to camera muted when joining ongoing voice call 2026-04-14 14:45:35 +02:00
Benoit Marty
76de9db94e Move vals at the top of the class. 2026-04-14 12:21:44 +02:00
Benoit Marty
d7e3c2df93 Add missing test for AnnouncementEvent.Continue 2026-04-14 12:16:09 +02:00