Skip to content

Commit

Permalink
Fixes #3753 - Add support for initiating and responding to user verif…
Browse files Browse the repository at this point in the history
…ication requests
  • Loading branch information
stefanceriu committed Feb 7, 2025
1 parent 2515cde commit 3dcae93
Show file tree
Hide file tree
Showing 101 changed files with 577 additions and 217 deletions.
2 changes: 1 addition & 1 deletion ElementX.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8509,7 +8509,7 @@
repositoryURL = "https://github.com/element-hq/matrix-rust-components-swift";
requirement = {
kind = exactVersion;
version = 25.02.06;
version = 25.02.07;
};
};
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/element-hq/matrix-rust-components-swift",
"state" : {
"revision" : "355364952fdd14a3e26b317180af89c79f9e03a5",
"version" : "25.2.6"
"revision" : "bc819f09ac66bbe1adc2fde2afeb7ab023d1b909",
"version" : "25.2.7"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@
"common_verified" = "Verified";
"common_verify_device" = "Verify device";
"common_verify_identity" = "Verify identity";
"common_verify_user" = "Verify user";
"common_video" = "Video";
"common_voice_message" = "Voice message";
"common_waiting" = "Waiting…";
Expand Down Expand Up @@ -947,9 +948,11 @@
"screen_session_verification_cancelled_subtitle" = "Something doesn’t seem right. Either the request timed out or the request was denied.";
"screen_session_verification_compare_emojis_subtitle" = "Confirm that the emojis below match those shown on your other session.";
"screen_session_verification_compare_emojis_title" = "Compare emojis";
"screen_session_verification_compare_emojis_user_subtitle" = "Confirm that the emojis below match those shown on the other user’s device.";
"screen_session_verification_compare_numbers_subtitle" = "Confirm that the numbers below match those shown on your other session.";
"screen_session_verification_compare_numbers_title" = "Compare numbers";
"screen_session_verification_complete_subtitle" = "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.";
"screen_session_verification_complete_user_subtitle" = "Now you can trust the identity of this user when sending or receiving messages.";
"screen_session_verification_enter_recovery_key" = "Enter recovery key";
"screen_session_verification_failed_subtitle" = "Either the request timed out, the request was denied, or there was a verification mismatch.";
"screen_session_verification_open_existing_session_subtitle" = "Prove it’s you in order to access your encrypted message history.";
Expand All @@ -970,8 +973,14 @@
"screen_session_verification_they_match" = "They match";
"screen_session_verification_use_another_device_subtitle" = "Make sure you have the app open in the other device before starting verification from here.";
"screen_session_verification_use_another_device_title" = "Open the app on another verified device";
"screen_session_verification_user_initiator_subtitle" = "For extra security, verify this user by comparing a set of emojis on your devices. Do this by using a trusted way to communicate.";
"screen_session_verification_user_initiator_title" = "Verify this user?";
"screen_session_verification_user_responder_subtitle" = "For extra security, another user wants to verify your identity. You’ll be shown a set of emojis to compare.";
"screen_session_verification_waiting_another_device_subtitle" = "You should see a popup on the other device. Start the verification from there now.";
"screen_session_verification_waiting_another_device_title" = "Start verification on the other device";
"screen_session_verification_waiting_other_device_title" = "Waiting for the other device";
"screen_session_verification_waiting_other_user_title" = "Waiting for the other user";
"screen_session_verification_waiting_subtitle" = "Once accepted you’ll be able to continue with the verification.";
"screen_session_verification_waiting_to_accept_subtitle" = "Accept the request to start the verification process in your other session to continue.";
"screen_session_verification_waiting_to_accept_title" = "Waiting to accept request";
"screen_share_location_title" = "Share location";
Expand Down
9 changes: 9 additions & 0 deletions ElementX/Resources/Localizations/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@
"common_verified" = "Verified";
"common_verify_device" = "Verify device";
"common_verify_identity" = "Verify identity";
"common_verify_user" = "Verify user";
"common_video" = "Video";
"common_voice_message" = "Voice message";
"common_waiting" = "Waiting…";
Expand Down Expand Up @@ -947,9 +948,11 @@
"screen_session_verification_cancelled_subtitle" = "Something doesn’t seem right. Either the request timed out or the request was denied.";
"screen_session_verification_compare_emojis_subtitle" = "Confirm that the emojis below match those shown on your other session.";
"screen_session_verification_compare_emojis_title" = "Compare emojis";
"screen_session_verification_compare_emojis_user_subtitle" = "Confirm that the emojis below match those shown on the other user’s device.";
"screen_session_verification_compare_numbers_subtitle" = "Confirm that the numbers below match those shown on your other session.";
"screen_session_verification_compare_numbers_title" = "Compare numbers";
"screen_session_verification_complete_subtitle" = "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.";
"screen_session_verification_complete_user_subtitle" = "Now you can trust the identity of this user when sending or receiving messages.";
"screen_session_verification_enter_recovery_key" = "Enter recovery key";
"screen_session_verification_failed_subtitle" = "Either the request timed out, the request was denied, or there was a verification mismatch.";
"screen_session_verification_open_existing_session_subtitle" = "Prove it’s you in order to access your encrypted message history.";
Expand All @@ -970,8 +973,14 @@
"screen_session_verification_they_match" = "They match";
"screen_session_verification_use_another_device_subtitle" = "Make sure you have the app open in the other device before starting verification from here.";
"screen_session_verification_use_another_device_title" = "Open the app on another verified device";
"screen_session_verification_user_initiator_subtitle" = "For extra security, verify this user by comparing a set of emojis on your devices. Do this by using a trusted way to communicate.";
"screen_session_verification_user_initiator_title" = "Verify this user?";
"screen_session_verification_user_responder_subtitle" = "For extra security, another user wants to verify your identity. You’ll be shown a set of emojis to compare.";
"screen_session_verification_waiting_another_device_subtitle" = "You should see a popup on the other device. Start the verification from there now.";
"screen_session_verification_waiting_another_device_title" = "Start verification on the other device";
"screen_session_verification_waiting_other_device_title" = "Waiting for the other device";
"screen_session_verification_waiting_other_user_title" = "Waiting for the other user";
"screen_session_verification_waiting_subtitle" = "Once accepted you’ll be able to continue with the verification.";
"screen_session_verification_waiting_to_accept_subtitle" = "Accept the request to start the verification process in your other session to continue.";
"screen_session_verification_waiting_to_accept_title" = "Waiting to accept request";
"screen_share_location_title" = "Share location";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,9 @@ class OnboardingFlowCoordinator: FlowCoordinatorProtocol {
}

let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController,
flow: .initiator)
flow: .deviceInitiator,
appSettings: appSettings,
mediaProvider: userSession.mediaProvider)

let coordinator = SessionVerificationScreenCoordinator(parameters: parameters)

Expand Down
7 changes: 7 additions & 0 deletions ElementX/Sources/FlowCoordinators/RoomFlowCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import UserNotifications

enum RoomFlowCoordinatorAction: Equatable {
case presentCallScreen(roomProxy: JoinedRoomProxyProtocol)
case verifyUser(userID: String)
case finished

static func == (lhs: RoomFlowCoordinatorAction, rhs: RoomFlowCoordinatorAction) -> Bool {
Expand Down Expand Up @@ -1247,6 +1248,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: [], entryPoint: .room))
case .startCall(let roomID):
Task { await self.presentCallScreen(roomID: roomID) }
case .verifyUser(let userID):
actionsSubject.send(.verifyUser(userID: userID))
}
}
.store(in: &cancellables)
Expand All @@ -1272,6 +1275,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
stateMachine.tryEvent(.startChildFlow(roomID: roomID, via: [], entryPoint: .room))
case .startCall(let roomID):
Task { await self.presentCallScreen(roomID: roomID) }
case .verifyUser(let userID):
actionsSubject.send(.verifyUser(userID: userID))
case .dismiss:
break // Not supported when pushed.
}
Expand Down Expand Up @@ -1530,6 +1535,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
switch action {
case .presentCallScreen(let roomProxy):
actionsSubject.send(.presentCallScreen(roomProxy: roomProxy))
case .verifyUser(let userID):
actionsSubject.send(.verifyUser(userID: userID))
case .finished:
stateMachine.tryEvent(.dismissChildFlow)
}
Expand Down
22 changes: 18 additions & 4 deletions ElementX/Sources/FlowCoordinators/UserSessionFlowCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -440,18 +440,26 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {

MXLog.info("Received session verification request")

presentSessionVerificationScreen(details: details)
if details.senderProfile.userID == userSession.clientProxy.userID {
presentSessionVerificationScreen(flow: .deviceResponder(requestDetails: details))
} else {
presentSessionVerificationScreen(flow: .userResponder(requestDetails: details))
}
}
.store(in: &cancellables)
}

private func presentSessionVerificationScreen(details: SessionVerificationRequestDetails) {
private func presentSessionVerificationScreen(flow: SessionVerificationScreenFlow) {
guard let sessionVerificationController = userSession.clientProxy.sessionVerificationController else {
fatalError("The sessionVerificationController should aways be valid at this point")
}

let navigationStackCoordinator = NavigationStackCoordinator()

let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationController,
flow: .responder(details: details))
flow: flow,
appSettings: appSettings,
mediaProvider: userSession.mediaProvider)

let coordinator = SessionVerificationScreenCoordinator(parameters: parameters)

Expand All @@ -464,7 +472,9 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
}
.store(in: &cancellables)

navigationSplitCoordinator.setSheetCoordinator(coordinator)
navigationStackCoordinator.setRootCoordinator(coordinator)

navigationSplitCoordinator.setSheetCoordinator(navigationStackCoordinator)
}

private func presentHomeScreen() {
Expand Down Expand Up @@ -590,6 +600,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
case .presentCallScreen(let roomProxy):
// Here we assume that the app is running and the call state is already up to date
presentCallScreen(roomProxy: roomProxy, notifyOtherParticipants: !roomProxy.infoPublisher.value.hasRoomCall)
case .verifyUser(let userID):
presentSessionVerificationScreen(flow: .userIntiator(userID: userID))
case .finished:
stateMachine.processEvent(.deselectRoom)
}
Expand Down Expand Up @@ -911,6 +923,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
stateMachine.processEvent(.selectRoom(roomID: roomID, via: [], entryPoint: .room))
case .startCall(let roomID):
Task { await self.presentCallScreen(roomID: roomID, notifyOtherParticipants: false) }
case .verifyUser(let userID):
presentSessionVerificationScreen(flow: .userIntiator(userID: userID))
case .dismiss:
navigationSplitCoordinator.setSheetCoordinator(nil)
}
Expand Down
18 changes: 18 additions & 0 deletions ElementX/Sources/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ internal enum L10n {
internal static var commonVerifyDevice: String { return L10n.tr("Localizable", "common_verify_device") }
/// Verify identity
internal static var commonVerifyIdentity: String { return L10n.tr("Localizable", "common_verify_identity") }
/// Verify user
internal static var commonVerifyUser: String { return L10n.tr("Localizable", "common_verify_user") }
/// Video
internal static var commonVideo: String { return L10n.tr("Localizable", "common_video") }
/// Voice message
Expand Down Expand Up @@ -2306,12 +2308,16 @@ internal enum L10n {
internal static var screenSessionVerificationCompareEmojisSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_compare_emojis_subtitle") }
/// Compare emojis
internal static var screenSessionVerificationCompareEmojisTitle: String { return L10n.tr("Localizable", "screen_session_verification_compare_emojis_title") }
/// Confirm that the emojis below match those shown on the other user’s device.
internal static var screenSessionVerificationCompareEmojisUserSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_compare_emojis_user_subtitle") }
/// Confirm that the numbers below match those shown on your other session.
internal static var screenSessionVerificationCompareNumbersSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_compare_numbers_subtitle") }
/// Compare numbers
internal static var screenSessionVerificationCompareNumbersTitle: String { return L10n.tr("Localizable", "screen_session_verification_compare_numbers_title") }
/// Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.
internal static var screenSessionVerificationCompleteSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_complete_subtitle") }
/// Now you can trust the identity of this user when sending or receiving messages.
internal static var screenSessionVerificationCompleteUserSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_complete_user_subtitle") }
/// Enter recovery key
internal static var screenSessionVerificationEnterRecoveryKey: String { return L10n.tr("Localizable", "screen_session_verification_enter_recovery_key") }
/// Either the request timed out, the request was denied, or there was a verification mismatch.
Expand Down Expand Up @@ -2354,10 +2360,22 @@ internal enum L10n {
internal static var screenSessionVerificationUseAnotherDeviceSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_use_another_device_subtitle") }
/// Open the app on another verified device
internal static var screenSessionVerificationUseAnotherDeviceTitle: String { return L10n.tr("Localizable", "screen_session_verification_use_another_device_title") }
/// For extra security, verify this user by comparing a set of emojis on your devices. Do this by using a trusted way to communicate.
internal static var screenSessionVerificationUserInitiatorSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_user_initiator_subtitle") }
/// Verify this user?
internal static var screenSessionVerificationUserInitiatorTitle: String { return L10n.tr("Localizable", "screen_session_verification_user_initiator_title") }
/// For extra security, another user wants to verify your identity. You’ll be shown a set of emojis to compare.
internal static var screenSessionVerificationUserResponderSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_user_responder_subtitle") }
/// You should see a popup on the other device. Start the verification from there now.
internal static var screenSessionVerificationWaitingAnotherDeviceSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_waiting_another_device_subtitle") }
/// Start verification on the other device
internal static var screenSessionVerificationWaitingAnotherDeviceTitle: String { return L10n.tr("Localizable", "screen_session_verification_waiting_another_device_title") }
/// Waiting for the other device
internal static var screenSessionVerificationWaitingOtherDeviceTitle: String { return L10n.tr("Localizable", "screen_session_verification_waiting_other_device_title") }
/// Waiting for the other user
internal static var screenSessionVerificationWaitingOtherUserTitle: String { return L10n.tr("Localizable", "screen_session_verification_waiting_other_user_title") }
/// Once accepted you’ll be able to continue with the verification.
internal static var screenSessionVerificationWaitingSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_waiting_subtitle") }
/// Accept the request to start the verification process in your other session to continue.
internal static var screenSessionVerificationWaitingToAcceptSubtitle: String { return L10n.tr("Localizable", "screen_session_verification_waiting_to_accept_subtitle") }
/// Waiting to accept request
Expand Down
Loading

0 comments on commit 3dcae93

Please sign in to comment.