Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Changes in 1.11.38 (2026-05-27)

🐛 Bugfixes

- Hook up the Reset flow to Verification when there is no recovery or other devices. ([#8024](https://github.com/element-hq/element-ios/issues/8024))

## Changes in 1.11.37 (2026-04-01)

🙌 Improvements
Expand Down
4 changes: 2 additions & 2 deletions Config/AppVersion.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
//

// Version
MARKETING_VERSION = 1.11.37
CURRENT_PROJECT_VERSION = 1.11.37
MARKETING_VERSION = 1.11.38
CURRENT_PROJECT_VERSION = 1.11.38
8 changes: 4 additions & 4 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ PODS:
- AFNetworking (~> 4.0.0)
- GZIP (~> 1.3.0)
- libbase58 (~> 0.1.4)
- MatrixSDKCrypto (= 0.11.1)
- MatrixSDKCrypto (= 0.17.0)
- Realm (= 10.27.0)
- SwiftyBeaver (= 1.9.5)
- MatrixSDK/JingleCallStack (0.27.18):
- JitsiMeetSDKLite (= 12.0.0-lite)
- MatrixSDK/Core
- MatrixSDKCrypto (0.11.1)
- MatrixSDKCrypto (0.17.0)
- ReadMoreTextView (3.0.1)
- Realm (10.27.0):
- Realm/Headers (= 10.27.0)
Expand Down Expand Up @@ -176,8 +176,8 @@ SPEC CHECKSUMS:
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
LoggerAPI: ad9c4a6f1e32f518fdb43a1347ac14d765ab5e3d
Logging: beeb016c9c80cf77042d62e83495816847ef108b
MatrixSDK: c2ee6ae269e0fe57b06d824530481fcb879265f7
MatrixSDKCrypto: e44608012cae9befc52f13cd8e56c6f51ac83702
MatrixSDK: fdccd88405ec9e9f8e9978091bc0ac67cf396542
MatrixSDKCrypto: aa38e272e573c7798aa3cd761b2b61ec5c7731b8
ReadMoreTextView: 19147adf93abce6d7271e14031a00303fe28720d
Realm: 9ca328bd7e700cc19703799785e37f77d1a130f2
Reusable: 6bae6a5e8aa793c9c441db0213c863a64bce9136
Expand Down
8 changes: 7 additions & 1 deletion Riot/Assets/de.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@
"user_verification_sessions_list_user_trust_level_trusted_title" = "Vertraut";
"user_verification_sessions_list_user_trust_level_warning_title" = "Warnung";
"user_verification_sessions_list_user_trust_level_unknown_title" = "Unbekannt";
"user_verification_sessions_list_information" = "Nachrichten mit diesem Gegenüber sind Ende-zu-Ende verschlüsselt und können nicht von Dritten gelesen werden.";
"user_verification_sessions_list_information" = "Nachrichten mit diesem Gegenüber in diesem Raum sind Ende-zu-Ende verschlüsselt und können nicht von Dritten gelesen werden.";
"user_verification_sessions_list_table_title" = "Sitzungen";
"user_verification_sessions_list_session_trusted" = "Vertraut";
"user_verification_sessions_list_session_untrusted" = "Nicht vertraut";
Expand Down Expand Up @@ -2795,3 +2795,9 @@
"call_unsupported_matrix_rtc_call" = "Nicht unterstützter Anruf. Die neue Element X App wird benötigt, um an diesem Anruf teilzunehmen.";
"wysiwyg_composer_action_minimise_action" = "Editor verkleinern";
"wysiwyg_composer_action_maximise_action" = "Editor erweitern";

// Verification Required Banner
"verification_required_banner_title" = "Verifiziere dieses Gerät";
"verification_required_banner_description" = "Ab Oktober 2026 können unverifizierte Geräte keine Nachrichten mehr senden und empfangen.";
"verification_required_banner_learn_more" = "Mehr erfahren";
"verification_required_banner_verify_button" = "Jetzt verifizieren";
2 changes: 1 addition & 1 deletion Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2617,7 +2617,7 @@ To enable access, tap Settings> Location and select Always";

// MARK: - Verification Required Banner
"verification_required_banner_title" = "Verify this device";
"verification_required_banner_description" = "As of April 2026 unverified devices will not be able to send and receive messages";
"verification_required_banner_description" = "As of October 2026 unverified devices will not be able to send and receive messages";
"verification_required_banner_learn_more" = "Learn more";
"verification_required_banner_verify_button" = "Verify now";

Expand Down
9 changes: 8 additions & 1 deletion Riot/Assets/fi.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
/* New message from a specific person, not referencing a room */
"MSG_FROM_USER" = "Viesti käyttäjältä %@";
"MSG_FROM_USER" = "%@ lähetti viestin";
"LOCATION_FROM_USER" = "%@ jakoi sijaintinsa";
"REPLY_FROM_USER_TITLE" = "%@ vastasi";
"PICTURE_FROM_USER" = "%@ lähetti kuvan";
"VIDEO_FROM_USER" = "%@ lähetti videon";
"VOICE_MESSAGE_FROM_USER" = "%@ lähetti ääniviestin";
"FILE_FROM_USER" = "%@ lähetti tiedoston %@";
"Notification" = "Ilmoitus";
15 changes: 15 additions & 0 deletions Riot/Assets/fi.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,18 @@
"active_call" = "Aktiivinen puhelu";
"enable" = "Ota käyttöön";
"store_promotional_text" = "Yksityisyyttä varjeleva chat ja yhteistyösovellus, avoimessa verkossa. Hajautettu hallintaa varten. Ei datalouhintaa, takaovia tai kolmannen osapuolen pääsyä.";
"people_invites_section" = "KUTSUT";
"people_conversation_section" = "KESKUSTELUT";
"home_context_menu_unfavourite" = "Poista suosikeista";
"room_recents_no_conversation" = "Ei huoneita";
"people_no_conversation" = "Ei keskusteluja";
"group_invite_section" = "KUTSUT";
"all_chats_edit_layout_unreads" = "Lukemattomat";
"people_empty_view_title" = "Ihmiset";
"room_recents_favourites_section" = "SUOSIKIT";
"room_recents_people_section" = "IHMISET";
"room_recents_suggested_rooms_section" = "EHDOTETUT HUONEET";
"spaces_creation_email_invites_email_title" = "Sähköposti";
"room_recents_invites_section" = "KUTSUT";
"rooms_empty_view_title" = "Huoneet";
"room_recents_conversations_section" = "HUONEET";
6 changes: 6 additions & 0 deletions Riot/Assets/fr.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2733,3 +2733,9 @@
// MARK: Password policy errors
"password_policy_too_short_pwd_error" = "Mot de passe trop court";
"accessibility_selected" = "sélectionné";

// Verification Required Banner
"verification_required_banner_title" = "Vérifier cet appareil";
"verification_required_banner_description" = "À partir d’octobre 2026, les appareils non vérifiés ne pourront plus envoyer ni recevoir de messages.";
"verification_required_banner_learn_more" = "En savoir plus";
"verification_required_banner_verify_button" = "Vérifier maintenant";
6 changes: 6 additions & 0 deletions Riot/Assets/nl.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2800,3 +2800,9 @@
"manage_session_sign_out_other_sessions" = "Bij alle andere sessies afmelden";
"user_sessions_hide_location_info" = "Verberg IP-adres";
"user_sessions_show_location_info" = "Toon IP-adres";

// Verification Required Banner
"verification_required_banner_title" = "Dit apparaat verifiëren";
"verification_required_banner_description" = "Vanaf oktober 2026 kunnen niet-geverifieerde apparaten geen berichten meer verzenden en ontvangen.";
"verification_required_banner_learn_more" = "Meer informatie";
"verification_required_banner_verify_button" = "Nu verifiëren";
7 changes: 7 additions & 0 deletions Riot/Assets/pl.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2868,3 +2868,10 @@
"wysiwyg_composer_action_maximise_action" = "Powiększ edytora treści";
"room_action_report_prompt_reason" = "Powód zgłoszenia tego pokoju";
"room_action_report" = "Zgłoś pokój";

// Verification Required Banner
"verification_required_banner_title" = "Zweryfikuj to urządzenie";
"verification_required_banner_description" = "Od października 2026 r. niezweryfikowane urządzenia nie będą mogły wysyłać ani odbierać wiadomości.";
"verification_required_banner_learn_more" = "Dowiedz się więcej";
"verification_required_banner_verify_button" = "Zweryfikuj teraz";

1 change: 1 addition & 0 deletions Riot/Assets/sl.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

117 changes: 117 additions & 0 deletions Riot/Assets/tr.lproj/Vector.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
"store_short_description" = "Güvenli sohbet/VoIP";
"title_home" = "Ana Sayfa";
"title_favourites" = "Favoriler";
"title_people" = "Kişiler";
"title_rooms" = "Odalar";
"title_groups" = "Topluluklar";
"warning" = "Uyarı";
"next" = "Sonraki";
"back" = "Geri";
"continue" = "Devam";
"create" = "Oluştur";
"start" = "Başla";
"leave" = "Ayrıl";
"remove" = "Çıkart";
"on" = "Aç";
"enable" = "Aktif";
"cancel" = "İptal";
"save" = "Kaydet";
"join" = "Üye ol";
"decline" = "Reddet";
"accept" = "Kabul et";
"preview" = "Ön izleme";
"camera" = "Kamera";
"voice" = "Ses";
"video" = "Video";
"active_call" = "Aktif Çağrı";
"active_call_details" = "(%@) Aktif Çağrı";
"later" = "Sonra";
"collapse" = "sorun oluştu";
"send_to" = "%@ gönder";
"skip" = "Geç";
"joined" = "Katıldı";
"switch" = "Değiştir";
"more" = "Daha çok";
"less" = "Az";
"open" = "Açık";
"done" = "Tamamla";
"private" = "Özel";
"public" = "Genel";
"stop" = "Durdur";
"new_word" = "Yeni";
"existing" = "Mevcut";
"add" = "Ekle";
"ok" = "Tamam";
"error" = "Hata";
"suggest" = "Öneri";
"edit" = "Düzenle";
"invite_to" = "%@ davet";
"loading" = "Yükleniyor";
"sending" = "Gönderiliyor";
"saving" = "Kaydediliyor";
"callbar_active_and_single_paused" = "1 aktif arama (%@) · 1 duraklatılmış arama";
"callbar_active_and_multiple_paused" = "1 aktif arama (%@) · %@ duraklatılmış aramalar";
"callbar_only_single_paused" = "Arama duraklatıldı";
"callbar_only_multiple_paused" = "%@ duraklatılmış aramalar";
"accessibility_checkbox_label" = "onay kutusu";
"accessibility_button_label" = "düğme";
"accessibility_selected" = "seçildi";
"sunset_delegated_oidc_registration_not_supported_message" = "Hesabınız için %2$@'yi kullanmak üzere %1$@'yi indirin veya farklı bir sunucusu seçin.";
"store_promotional_text" = "Gizliliği koruyan sohbet ve iş birliği uygulaması, açık bir ağ üzerinde çalışır. Kontrolü size veren **dağıtık yapıya sahip**tir. Veri madenciliği yoktur, arka kapı bulunmaz ve üçüncü taraf erişimi söz konusu değildir.";
"view" = "Görünüm";
"off" = "Kapat";
"confirm" = "Onayla";
"invite" = "Davet et";
"close" = "Kapalı";
"callbar_only_single_active" = "Aramaya geri dönmek için dokunun (%@)";
"retry" = "Tekrar";
"rename" = "Yeni ad";
"joining" = "Katılma";
"callbar_return" = "Geri dönüş";
"callbar_only_single_active_group" = "(%@) Grup görüşmesine katılmak için dokunun";
"sunset_delegated_oidc_registration_not_supported_title" = "Bu uygulama üzerinden artık %1$@ ile hesap oluşturamazsınız";
"authentication_verify_email_text_field_placeholder" = "E-posta";
"authentication_choose_password_input_message" = "En az 8 karakter olduğundan emin olun";
"authentication_choose_password_text_field_placeholder" = "Yeni Parola";
"authentication_verify_email_waiting_title" = "E-postanızı doğrulayın.";
"authentication_verify_email_waiting_message" = "%@ adresine gönderilen talimatları izleyin";
"authentication_verify_email_waiting_hint" = "E-posta almadınız mı?";
"authentication_verify_email_waiting_button" = "E-postayı yeniden gönder";
"authentication_forgot_password_input_title" = "E-posta adresinizi giriniz";
"authentication_forgot_password_text_field_placeholder" = "E-posta";
"authentication_forgot_password_waiting_title" = "E-postanızı kontrol edin.";
"authentication_forgot_password_waiting_message" = "%@ adresine gönderilen talimatları izleyin";
"authentication_forgot_password_waiting_button" = "E-postayı yeniden gönder";
"authentication_choose_password_submit_button" = "Parolayı Sıfırla";
"authentication_choose_password_not_verified_title" = "E-posta doğrulanmadı";
"authentication_choose_password_not_verified_message" = "Gelen kutunuzu kontrol edin";
"authentication_verify_msisdn_input_title" = "Telefon numaranızı girin";
"authentication_verify_msisdn_text_field_placeholder" = "Telefon Numarası";
"authentication_verify_msisdn_otp_text_field_placeholder" = "Onay Kodu";
"authentication_verify_msisdn_waiting_title" = "Telefon numaranızı doğrulayın";
"authentication_verify_msisdn_waiting_button" = "Kodu yeniden gönder";
"authentication_verify_msisdn_invalid_phone_number" = "Geçersiz telefon numarası";
"authentication_terms_title" = "Gizlilik politikaları";
"authentication_terms_policy_url_error" = "Seçilen politika bulunamadı. Lütfen daha sonra tekrar deneyin.";
"authentication_recaptcha_title" = "İnsan olduğunu doğrular mısın?";
"authentication_qr_login_start_title" = "QR kodu okutun";
"authentication_qr_login_start_subtitle" = "Bu cihazdaki kamerayı kullanarak diğer cihazınızda gösterilen QR kodunu tarayın:";
"authentication_qr_login_start_step3" = "‘Bir cihaz bağla’ seçeneğini seçin";
"authentication_qr_login_start_step4" = "‘Bu cihazda QR kodunu göster’ seçeneğini işaretleyin";
"authentication_qr_login_start_need_alternative" = "Alternatif bir yönteme mi ihtiyacınız var?";
"authentication_qr_login_start_display_qr" = "Bu cihazda QR kodunu göster";
"authentication_qr_login_display_title" = "Bir cihaz bağlayın";
"authentication_qr_login_display_step1" = "Element'i diğer cihazınızda açın";
"authentication_qr_login_display_step2" = "‘QR koduyla giriş yap’ seçeneğini seçin";
"authentication_qr_login_scan_title" = "QR kodunu tarayın";
"authentication_qr_login_scan_subtitle" = "QR kodunu aşağıdaki kareye yerleştirin";
"authentication_qr_login_confirm_title" = "Güvenli bağlantı kuruldu";
"authentication_choose_password_input_title" = "Yeni bir parola belirleyin";
"authentication_terms_message" = "Lütfen %@'nin şartlarını ve politikalarını okuyun";
"authentication_qr_login_start_step1" = "Element'i diğer cihazınızda açın";
"authentication_choose_password_signout_all_devices" = "Tüm cihazlardan çıkış yapın";
"authentication_verify_msisdn_input_message" = "%@ hesabınızı doğrulamalıdır";
"authentication_qr_login_start_step2" = "Ayarlar -> Güvenlik ve Gizlilik bölümüne gidin";
"authentication_forgot_password_input_message" = "%@ size bir doğrulama bağlantısı gönderecektir";
"authentication_verify_msisdn_waiting_message" = "%@ adresine bir kod gönderildi";
"authentication_qr_login_display_subtitle" = "Oturumunuz kapalı olan cihazınızla aşağıdaki QR kodunu tarayın.";
2 changes: 1 addition & 1 deletion Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9367,7 +9367,7 @@ public class VectorL10n: NSObject {
public static func userVerificationStartWaitingPartner(_ p1: String) -> String {
return VectorL10n.tr("Vector", "user_verification_start_waiting_partner", p1)
}
/// As of April 2026 unverified devices will not be able to send and receive messages
/// As of October 2026 unverified devices will not be able to send and receive messages
public static var verificationRequiredBannerDescription: String {
return VectorL10n.tr("Vector", "verification_required_banner_description")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ final class CrossSigningSetupCoordinator: CrossSigningSetupCoordinatorType {

// MARK: - Private methods

private func setupCrossSigning(with authenticationParameters: [String: Any] = [:]) {
private func setupCrossSigning(with authenticationParameters: [String: Any] = [:], hasAuthenticated: Bool = false) {
guard let crossSigning = parameters.session.crypto?.crossSigning else { return }

crossSigning.setup(withAuthParams: authenticationParameters) { [weak self] in
Expand All @@ -64,7 +64,8 @@ final class CrossSigningSetupCoordinator: CrossSigningSetupCoordinatorType {
guard let self else { return }

if let responseData = (error as NSError).userInfo[MXHTTPClientErrorResponseDataKey] as? [AnyHashable: Any],
let authenticationSession = MXAuthenticationSession(fromJSON: responseData) {
let authenticationSession = MXAuthenticationSession(fromJSON: responseData),
!hasAuthenticated { // Don't re-presenting authentication if the user closes the web view without finishing.
showReauthentication(authenticationSession: authenticationSession)
} else {
delegate?.crossSigningSetupCoordinator(self, didFailWithError: error)
Expand Down Expand Up @@ -93,7 +94,7 @@ final class CrossSigningSetupCoordinator: CrossSigningSetupCoordinatorType {
extension CrossSigningSetupCoordinator: ReauthenticationCoordinatorDelegate {

func reauthenticationCoordinatorDidComplete(_ coordinator: ReauthenticationCoordinatorType, withAuthenticationParameters authenticationParameters: [String: Any]?) {
self.setupCrossSigning(with: authenticationParameters ?? [:])
self.setupCrossSigning(with: authenticationParameters ?? [:], hasAuthenticated: true)
}

func reauthenticationCoordinatorDidCancel(_ coordinator: ReauthenticationCoordinatorType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,17 @@ final class KeyVerificationCoordinator: KeyVerificationCoordinatorType {
return coordinator
}

private func showSecretsReset() {
let coordinator = SecretsResetCoordinator(session: self.session, isCancellable: false)
coordinator.delegate = self
coordinator.start()

self.add(childCoordinator: coordinator)
self.navigationRouter.push(coordinator.toPresentable(), animated: true, popCompletion: { [weak self] in
self?.remove(childCoordinator: coordinator)
})
}

private func showSecretsRecovery(with recoveryMode: SecretsRecoveryMode) {
let coordinator = SecretsRecoveryCoordinator(session: self.session, recoveryMode: recoveryMode, recoveryGoal: .verifyDevice, navigationRouter: self.navigationRouter, cancellable: self.cancellable)
coordinator.delegate = self
Expand Down Expand Up @@ -436,9 +447,13 @@ extension KeyVerificationCoordinator: KeyVerificationSelfVerifyWaitCoordinatorDe
self.didCancel()
}

func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, wantsToRecoverSecretsWith secretsRecoveryMode: SecretsRecoveryMode) {
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, wantsToRecoverSecretsWith secretsRecoveryMode: SecretsRecoveryMode) {
self.showSecretsRecovery(with: secretsRecoveryMode)
}

func keyVerificationSelfVerifyWaitCoordinatorWantsToResetSecrets(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType) {
self.showSecretsReset()
}
}

// MARK: - KeyVerificationScanConfirmationCoordinatorDelegate
Expand Down Expand Up @@ -466,3 +481,15 @@ extension KeyVerificationCoordinator: SecretsRecoveryCoordinatorDelegate {
self.didCancel()
}
}

// MARK: - SecretsResetCoordinatorDelegate
extension KeyVerificationCoordinator: SecretsResetCoordinatorDelegate {

func secretsResetCoordinatorDidResetSecrets(_ coordinator: SecretsResetCoordinatorType) {
self.showVerified(animated: true)
}

func secretsResetCoordinatorDidCancel(_ coordinator: SecretsResetCoordinatorType) {
// Not used, the cancel button is hidden.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,8 @@ extension KeyVerificationSelfVerifyWaitCoordinator: KeyVerificationSelfVerifyWai
func keyVerificationSelfVerifyWaitViewModel(_ coordinator: KeyVerificationSelfVerifyWaitViewModelType, wantsToRecoverSecretsWith secretsRecoveryMode: SecretsRecoveryMode) {
self.delegate?.keyVerificationSelfVerifyWaitCoordinator(self, wantsToRecoverSecretsWith: secretsRecoveryMode)
}

func keyVerificationSelfVerifyWaitViewModelWantsToResetSecrets(_ viewModel: KeyVerificationSelfVerifyWaitViewModelType) {
self.delegate?.keyVerificationSelfVerifyWaitCoordinatorWantsToResetSecrets(self)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ protocol KeyVerificationSelfVerifyWaitCoordinatorDelegate: AnyObject {
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, didAcceptIncomingSASTransaction incomingSASTransaction: MXSASTransaction)
func keyVerificationSelfVerifyWaitCoordinatorDidCancel(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType)
func keyVerificationSelfVerifyWaitCoordinator(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType, wantsToRecoverSecretsWith secretsRecoveryMode: SecretsRecoveryMode)
func keyVerificationSelfVerifyWaitCoordinatorWantsToResetSecrets(_ coordinator: KeyVerificationSelfVerifyWaitCoordinatorType)
}

/// `KeyVerificationSelfVerifyWaitCoordinatorType` is a protocol describing a Coordinator that handle key backup setup passphrase navigation flow.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ enum KeyVerificationSelfVerifyWaitViewAction {
case loadData
case cancel
case recoverSecrets
case resetSecrets
}
Loading
Loading