Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature : room settings - security and privacy #4212

Merged
merged 30 commits into from
Jan 29, 2025

Conversation

ganfra
Copy link
Member

@ganfra ganfra commented Jan 28, 2025

Content

This PR introduce the new screens of security and privacy, it includes the following change :

  • Room details reorganisation
  • New Security & Privacy screen
  • New Edit Room Address screen

It includes also the necessary changes from the sdk allowing to update and listen those settings.

Motivation and context

Figma : https://www.figma.com/design/7TqjqdMBaPpm3IavKsMYu6/Ask-to-join-(Knocking)?node-id=5147-58412&m=dev
Meta issue : element-hq/element-meta#2631

Screenshots / GIFs

Tests

  • Make sure knock requests are enabled
  • Open a non DM room where you have some moderator/admin rights
  • Open details/ security and privacy
  • Play with all the settings and hit save

Tested devices

  • Physical
  • Emulator
  • OS version(s):

Checklist

  • Changes have been tested on an Android device or Android emulator with API 24
  • UI change has been tested on both light and dark themes
  • Accessibility has been taken into account. See https://github.com/element-hq/element-x-android/blob/develop/CONTRIBUTING.md#accessibility
  • Pull request is based on the develop branch
  • Pull request title will be used in the release note, it clearly define what will change for the user
  • Pull request includes screenshots or videos if containing UI changes
  • You've made a self review of your PR

ganfra added 26 commits January 17, 2025 17:44
@ganfra ganfra added PR-Wip For anything that isn't ready to ship and will be enabled at a later date Record-Screenshots Runs the 'Record Screenshots' CI job and adds a commit with any new screenshots found. labels Jan 28, 2025
@ganfra ganfra marked this pull request as ready for review January 28, 2025 20:14
@ganfra ganfra requested a review from a team as a code owner January 28, 2025 20:14
@github-actions github-actions bot removed the Record-Screenshots Runs the 'Record Screenshots' CI job and adds a commit with any new screenshots found. label Jan 28, 2025
@ganfra ganfra requested review from bmarty and removed request for a team January 28, 2025 20:14
Copy link
Contributor

github-actions bot commented Jan 28, 2025

📱 Scan the QR code below to install the build (arm64 only) for this PR.
QR code
If you can't scan the QR code you can install the build via this link: https://i.diawi.com/XNfE2U

Copy link

codecov bot commented Jan 28, 2025

Codecov Report

Attention: Patch coverage is 88.18061% with 89 lines in your changes missing coverage. Please review.

Project coverage is 83.40%. Comparing base (d00bc30) to head (c10da01).
Report is 126 commits behind head on develop.

Files with missing lines Patch % Lines
.../securityandprivacy/SecurityAndPrivacyPresenter.kt 78.01% 10 Missing and 21 partials ⚠️
.../impl/securityandprivacy/SecurityAndPrivacyView.kt 88.54% 9 Missing and 13 partials ⚠️
...atrix/ui/room/address/RoomAddressValidityEffect.kt 73.68% 2 Missing and 3 partials ⚠️
...droid/features/roomdetails/impl/RoomDetailsView.kt 90.47% 0 Missing and 4 partials ⚠️
.../securityandprivacy/SecurityAndPrivacyNavigator.kt 0.00% 4 Missing ⚠️
.../features/roomdetails/impl/RoomDetailsPresenter.kt 78.57% 0 Missing and 3 partials ⚠️
...rivacy/editroomaddress/EditRoomAddressPresenter.kt 95.00% 3 Missing ⚠️
...yandprivacy/editroomaddress/EditRoomAddressView.kt 93.61% 1 Missing and 2 partials ⚠️
...atures/createroom/impl/configureroom/RoomAccess.kt 0.00% 2 Missing ⚠️
...impl/securityandprivacy/SecurityAndPrivacyState.kt 94.59% 1 Missing and 1 partial ⚠️
... and 8 more
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #4212      +/-   ##
===========================================
+ Coverage    83.31%   83.40%   +0.09%     
===========================================
  Files         1881     1896      +15     
  Lines        49101    49752     +651     
  Branches      5769     5856      +87     
===========================================
+ Hits         40909    41498     +589     
- Misses        6116     6139      +23     
- Partials      2076     2115      +39     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@jmartinesp jmartinesp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM in general, although I have some worries about the error(...) being used while mapping some SDK data.

There are a few nits that I pointed out, but it's mostly naming and asking for more docs/comments, so you can ignore them if you don't agree.

Note I haven't tested the new features yet.

trailingContent = ListItemContent.RadioButton(selected = selected == SecurityAndPrivacyRoomAccess.Anyone),
onClick = { onSelected(SecurityAndPrivacyRoomAccess.Anyone) },
)
if (selected == SecurityAndPrivacyRoomAccess.SpaceMember) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add some comments on why this is needed?

title = stringResource(CommonStrings.screen_security_and_privacy_room_history_section_header),
modifier = modifier,
) {
Spacer(Modifier.height(16.dp))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this spacer needed? Also, it seems larger than spacers in other sections, at least it seems larger in the screenshots.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

supportingContent = { Text(text = stringResource(CommonStrings.screen_security_and_privacy_encryption_section_footer)) },
trailingContent = ListItemContent.Switch(
checked = isEncryptionEnabled,
enabled = !isEncryptionEnabled,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could add a comment here to to explain encryption can't be disabled once enabled.

Comment on lines 431 to 432
* [Public](`RoomVisibility::Public`) rooms are listed in the room
* directory and can be found using it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦀 spotted!

Comment on lines 104 to 107
is JoinRule.Custom,
JoinRule.Invite,
JoinRule.Private,
null -> SecurityAndPrivacyRoomAccess.InviteOnly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe explain why all these are mapped to InviteOnly?

SecurityAndPrivacyRoomAccess.Anyone -> JoinRule.Public
SecurityAndPrivacyRoomAccess.AskToJoin -> JoinRule.Knock
SecurityAndPrivacyRoomAccess.InviteOnly -> JoinRule.Private
SecurityAndPrivacyRoomAccess.SpaceMember -> error("Unsupported")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is used in a safe context at the moment (a runCatching wrapped block), but maybe we should be more careful about it? If we add some other usage in the future we might be crashing the app.

Also, documenting why this is not supported would be nice.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to nullable

if (this.alias?.matchesServer(serverName) == true) {
return this.alias
}
return this.alternativeAliases.firstOrNull { it.value.contains(serverName) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't this use matchesServer too?

Comment on lines 115 to 127
val newAlternativeAliases = room.alternativeAliases.filter { it != savedAliasFromHomeserver }
room.updateCanonicalAlias(newRoomAlias, newAlternativeAliases).getOrThrow()
}
// Otherwise, update the alternative aliases and keep the current canonical alias
// Otherwise, only update the alternative aliases and keep the current canonical alias
else -> {
val newAlternativeAliases = listOf(newRoomAlias) + room.alternativeAliases
val newAlternativeAliases = buildList {
add(newRoomAlias)
for (alias in room.alternativeAliases) {
if (alias != savedAliasFromHomeserver) {
add(alias)
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These seem super difficult to follow for me, could we document the different cases?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have simplified and added comment

@@ -71,6 +71,9 @@ class SecurityAndPrivacyPresenter @AssistedInject constructor(
var currentIsEncrypted by remember(savedSettings.isEncrypted) {
mutableStateOf(savedSettings.isEncrypted)
}

var showEncryptionConfirmation by remember { mutableStateOf(false) }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

showEnableEncryptionConfirmation maybe?

Copy link
Member

@bmarty bmarty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this huge PR.

I have a concerned about enabling encryption UX which could be improved, maybe discussed with product? I have attached a video of the problem.

val securityAndPrivacyPermissions = room.securityAndPrivacyPermissionsAsState(syncUpdateFlow.value)
val canShowSecurityAndPrivacy by remember {
derivedStateOf {
isKnockRequestsEnabled && roomType is RoomDetailsType.Room && securityAndPrivacyPermissions.value.hasAny
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange to see this new screen behind isKnockRequestsEnabled since it also allow to for instance enable encryption IIUC.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this has been discussed, and for now this is what we want...

Copy link
Member

@bmarty bmarty Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Encryption will not be enabled until user press the "Save" button. So maybe show this popup when the user press the Save button?

This is really a problem because the user will strongly think that the encryption is enabled after this popup is closed, and this is enforced by the fact that there is no confirmation when leaving the screen without saving the change.

See the video below:

EnableEncryptionMisleading.mp4

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's a bit misleading, but this is what product/design want.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mxandreas can you see my video ^? And confirm that this is fine. The risk is that user may think they have enabled encryption and this will actually no be the case until the save button has been pressed. Thanks.

Copy link
Member

@bmarty bmarty Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe adding a confirmation dialog when user leaves without saving pending changes can mitigate this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, it can be misleading and mainly due to the popup.

Maybe adding a confirmation dialog when user leaves without saving pending changes can mitigate this.

This is the only consistent/scalable option, I see but not sure how easy it is to be done. Since @gaelledel has been the one driving such details about interaction, I think she needs to make call about this to make sure the bigger picture remains consistent.

Copy link
Contributor

@mxandreas mxandreas Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we can proceed of releasing this "as is" and apply an update/fix sooner/later, though.

val securityAndPrivacyPermissions = room.securityAndPrivacyPermissionsAsState(syncUpdateFlow.value)
val canShowSecurityAndPrivacy by remember {
derivedStateOf {
isKnockRequestsEnabled && roomType is RoomDetailsType.Room && securityAndPrivacyPermissions.value.hasAny
Copy link
Member

@bmarty bmarty Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small neat, securityAndPrivacyPermissions.value.hasAny seems not to be live, I was on the room details screen when I became admin of the room and the item "Security & Privacy" did not appear. I had to go back to the previous screen and come back to see it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's not live, because powerlevels are not live

Copy link
Member

@bmarty bmarty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the answers to my comments.

I hope we will implement a "Leaving without saving" alert that would be good for the UX and is not hard to do technically speaking.

@ganfra ganfra added the Record-Screenshots Runs the 'Record Screenshots' CI job and adds a commit with any new screenshots found. label Jan 29, 2025
@github-actions github-actions bot removed the Record-Screenshots Runs the 'Record Screenshots' CI job and adds a commit with any new screenshots found. label Jan 29, 2025
@ganfra ganfra enabled auto-merge January 29, 2025 15:48
@ganfra ganfra merged commit 346e364 into develop Jan 29, 2025
26 checks passed
@ganfra ganfra deleted the feature/fga/room_settings_security_privacy branch January 29, 2025 16:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR-Wip For anything that isn't ready to ship and will be enabled at a later date
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants