mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-17 23:18:27 +02:00
Merge branch 'develop' into feature/5365_photos_picker
This commit is contained in:
@@ -58,6 +58,9 @@ class AppConfiguration: CommonConfiguration {
|
||||
|
||||
// bwi: #4941 deactivate voice broadcast
|
||||
RiotSettings.shared.enableVoiceBroadcast = BWIBuildSettings.shared.enableFeatureVoiceBroadcastsByDefault
|
||||
|
||||
// bwi: #5506 activate use latest avatar
|
||||
RiotSettings.shared.roomScreenUseOnlyLatestUserAvatarAndName = BWIBuildSettings.shared.enableRoomScreenUseOnlyLatestUserAvatarAndNameByDefault
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -208,7 +208,8 @@ class BWIBuildSettings: NSObject {
|
||||
"36a9ec7368bddedd9deb1e2d1c627bd7304865135c9be30b1979659e3ac9ad07",
|
||||
"dbaf8618e8a2f8d681591dfbcc73243c921c10dec69a2e5ee50bc91ca7dedcda",
|
||||
"ed1af0fd873ec749f17c3b61ce4e481ab1644c132003f97a9c4e36516325788a",
|
||||
"081e6ef90ba86102d678756fd13b07ca744340ad4d58a340e1956dca992f18e3"
|
||||
"081e6ef90ba86102d678756fd13b07ca744340ad4d58a340e1956dca992f18e3",
|
||||
"40b22592f2417c8031a0c38098c83dd0bfd28dee4c77ed1e9a022556c6ec0ded"
|
||||
]
|
||||
|
||||
// use a different badge color if the user was mentioned in a room
|
||||
@@ -544,6 +545,9 @@ class BWIBuildSettings: NSObject {
|
||||
|
||||
var bwiShowTimelineSettings = false
|
||||
|
||||
// #5506 alway use the latest avatar for data privacy
|
||||
var enableRoomScreenUseOnlyLatestUserAvatarAndNameByDefault = true
|
||||
|
||||
// MARK BWI personal state
|
||||
var bwiPersonalState = false
|
||||
|
||||
@@ -715,4 +719,8 @@ class BWIBuildSettings: NSObject {
|
||||
|
||||
// MARK: Contacts List
|
||||
var showContactIdentifierInDetailRow = true
|
||||
|
||||
// MARK: Room Participants
|
||||
// activates swipe gesture action to remove participants from room (RoomParticipantsViewController)
|
||||
var bwiCanEditRoomParticipants = false
|
||||
}
|
||||
|
||||
@@ -295,7 +295,8 @@ final class RiotSettings: NSObject {
|
||||
///
|
||||
/// Note: this is set up from Room perspective, which means that if a user updates their profile after
|
||||
/// leaving a Room, it will show up the latest profile used in the Room rather than the latest overall.
|
||||
@UserDefault(key: "roomScreenUseOnlyLatestUserAvatarAndName", defaultValue: BuildSettings.roomScreenUseOnlyLatestUserAvatarAndName, storage: defaults)
|
||||
// bwi: #5506 alway use the latest avatar
|
||||
@UserDefault(key: "roomScreenUseOnlyLatestUserAvatarAndName", defaultValue: BWIBuildSettings.shared.enableRoomScreenUseOnlyLatestUserAvatarAndNameByDefault, storage: defaults)
|
||||
var roomScreenUseOnlyLatestUserAvatarAndName
|
||||
|
||||
// MARK: - Room Contextual Menu
|
||||
|
||||
@@ -123,7 +123,7 @@ final class EnterNewRoomDetailsViewModel: EnterNewRoomDetailsViewModelType, Obse
|
||||
return alias
|
||||
} else if BWIBuildSettings.shared.bwiAutoCreateAliasOnRoomCreation {
|
||||
if let roomName = roomCreationParameters.name {
|
||||
return self.createAlias(from: roomName)
|
||||
return MXTools.createAlias(from: roomName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,14 +248,4 @@ final class EnterNewRoomDetailsViewModel: EnterNewRoomDetailsViewModelType, Obse
|
||||
self.currentOperation?.cancel()
|
||||
}
|
||||
|
||||
// MARK bwi Alias creation
|
||||
|
||||
private func createAlias(from roomName: String) -> String {
|
||||
var alias = roomName.trimmingCharacters(in: .whitespacesAndNewlines).filter { "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".contains($0) }
|
||||
|
||||
let timeInterval = String(Int(NSDate().timeIntervalSince1970))
|
||||
alias.append(timeInterval)
|
||||
|
||||
return alias
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1747,7 +1747,7 @@ static NSString *const kRepliedTextPattern = @"<mx-reply>.*<blockquote>.*<br>(.*
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:string];
|
||||
|
||||
NSRange wholeString = NSMakeRange(0, str.length);
|
||||
@@ -1795,7 +1795,12 @@ static NSString *const kRepliedTextPattern = @"<mx-reply>.*<blockquote>.*<br>(.*
|
||||
{
|
||||
// body font is the same with the whole string font, no need to change body font
|
||||
// apply additional treatments
|
||||
[self postRenderAttributedString:str];
|
||||
|
||||
// bwi #5290 remove links from status cells
|
||||
if (!event.isState) {
|
||||
[self postRenderAttributedString:str];
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -1820,6 +1825,7 @@ static NSString *const kRepliedTextPattern = @"<mx-reply>.*<blockquote>.*<br>(.*
|
||||
[str addAttribute:NSFontAttributeName value:fontForBody range:bodyRange];
|
||||
// apply additional treatments
|
||||
[self postRenderAttributedString:str];
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
@@ -1151,9 +1151,13 @@
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (indexPath.section == participantsSection || indexPath.section == invitedSection)
|
||||
// bwi: #5671 deactivate swipe gesture - remove participant from room
|
||||
if (BWIBuildSettings.shared.bwiCanEditRoomParticipants)
|
||||
{
|
||||
return YES;
|
||||
if (indexPath.section == participantsSection || indexPath.section == invitedSection)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@@ -1709,6 +1709,9 @@ BOOL reloadToggleCell = false;
|
||||
if (serverACLRule)
|
||||
{
|
||||
|
||||
// bwi: #5383 set alias
|
||||
[mxRoom setAliasIfNeededWithRoomName:mxRoom.summary.displayName];
|
||||
|
||||
NSDictionary *content = [mxRoom createServerACLContentWithServerACL:serverACLRule];
|
||||
|
||||
pendingOperation = [mxRoom sendStateEventOfType:kMXEventTypeStringRoomServerACL content:content stateKey:nil success:^(NSString *eventId) {
|
||||
|
||||
@@ -47,6 +47,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupMessageTextView {
|
||||
[super setupMessageTextView];
|
||||
|
||||
// bwi #5290 remove links from status cells
|
||||
self.messageTextView.dataDetectorTypes = UIDataDetectorTypeNone;
|
||||
}
|
||||
|
||||
- (void)render:(MXKCellData *)cellData
|
||||
{
|
||||
[super render:cellData];
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -35,7 +35,6 @@
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
<dataDetectorType key="dataDetectorTypes" link="YES"/>
|
||||
</textView>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IOg-Kt-8vW">
|
||||
<rect key="frame" x="515" y="3" width="70" height="31"/>
|
||||
@@ -46,7 +45,7 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="stw-MD-khQ">
|
||||
<rect key="frame" x="7" y="3" width="586" height="28"/>
|
||||
<rect key="frame" x="8" y="3" width="584" height="28"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</subviews>
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22130"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@@ -16,10 +13,10 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="70"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WmY-Jw-mqv" id="ef1-Tq-U3Z">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="69.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="70"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="df5-x1-Zhy">
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="df5-x1-Zhy">
|
||||
<rect key="frame" x="531" y="3" width="54" height="29"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<state key="normal" title="collapse"/>
|
||||
@@ -28,7 +25,7 @@
|
||||
</connections>
|
||||
</button>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dJl-MG-cbs">
|
||||
<rect key="frame" x="55" y="35" width="530" height="1"/>
|
||||
<rect key="frame" x="55" y="38" width="530" height="1"/>
|
||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="Jyb-5H-rlc"/>
|
||||
@@ -44,7 +41,7 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="text message" translatesAutoresizingMaskIntoConstraints="NO" id="HTH-5n-MSU">
|
||||
<rect key="frame" x="71" y="39" width="102" height="30.5"/>
|
||||
<rect key="frame" x="79" y="39" width="102" height="31"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="MessageTextView"/>
|
||||
<constraints>
|
||||
@@ -53,10 +50,9 @@
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
<dataDetectorType key="dataDetectorTypes" link="YES"/>
|
||||
</textView>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IOg-Kt-8vW">
|
||||
<rect key="frame" x="515" y="42" width="70" height="27.5"/>
|
||||
<rect key="frame" x="515" y="42" width="70" height="28"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<accessibility key="accessibilityConfiguration" identifier="BubbleInfoContainer"/>
|
||||
<constraints>
|
||||
@@ -64,7 +60,7 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="stw-MD-khQ">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="79.5"/>
|
||||
<rect key="frame" x="8" y="3" width="584" height="64"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</subviews>
|
||||
@@ -108,6 +104,7 @@
|
||||
<outlet property="pictureViewTopConstraint" destination="2Ih-ga-N9s" id="rpQ-bN-moE"/>
|
||||
<outlet property="separatorView" destination="dJl-MG-cbs" id="Vnp-K7-DEh"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="-218" y="-79"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
|
||||
@@ -58,6 +58,7 @@ targets:
|
||||
- path: ../bwi/MatomoAnalytics/DecryptedEvent.swift
|
||||
- path: ../bwi/MatomoAnalytics/E2EEError.swift
|
||||
- path: ../bwi/URLScheme/CustomURLSchemeHelper.swift
|
||||
- path: ../bwi/Extentions/MXTools+Alias.swift
|
||||
- path: ../bwi/Federation/MXRoom+Federation.swift
|
||||
- path: ../Riot/Managers/Settings/RiotSettings.swift
|
||||
- path: ../Config/BuildSettings.swift
|
||||
|
||||
@@ -40,11 +40,11 @@ enum MockAuthenticationChoosePasswordScreenState: MockScreenState, CaseIterable
|
||||
case .emptyPassword:
|
||||
viewModel = AuthenticationChoosePasswordViewModel()
|
||||
case .enteredInvalidPassword:
|
||||
viewModel = AuthenticationChoosePasswordViewModel(password: "1234")
|
||||
viewModel = AuthenticationChoosePasswordViewModel(password: "1234") //NOSONAR Password for mock Unittests
|
||||
case .enteredValidPassword:
|
||||
viewModel = AuthenticationChoosePasswordViewModel(password: "12345678")
|
||||
viewModel = AuthenticationChoosePasswordViewModel(password: "12345678") //NOSONAR Password for mock Unittests
|
||||
case .enteredValidPasswordAndSignoutAllDevicesChecked:
|
||||
viewModel = AuthenticationChoosePasswordViewModel(password: "12345678", signoutAllDevices: true)
|
||||
viewModel = AuthenticationChoosePasswordViewModel(password: "12345678", signoutAllDevices: true) //NOSONAR Password for mock Unittests
|
||||
}
|
||||
|
||||
// can simulate service and viewModel actions here if needs be.
|
||||
|
||||
@@ -71,7 +71,7 @@ class AuthenticationLoginViewModelTests: XCTestCase {
|
||||
|
||||
// When entering a password without a username.
|
||||
context.username = ""
|
||||
context.password = "12345678"
|
||||
context.password = "12345678" //NOSONAR Password for Unittests
|
||||
|
||||
// Then the credentials should be considered invalid.
|
||||
XCTAssertFalse(context.viewState.hasValidCredentials, "The credentials should be invalid.")
|
||||
@@ -85,7 +85,7 @@ class AuthenticationLoginViewModelTests: XCTestCase {
|
||||
|
||||
// When entering a username and an 8-character password.
|
||||
context.username = "bob"
|
||||
context.password = "12345678"
|
||||
context.password = "12345678" //NOSONAR Password for Unittests
|
||||
|
||||
// Then the credentials should be considered valid.
|
||||
XCTAssertTrue(context.viewState.hasValidCredentials, "The credentials should be valid when the username and password are valid.")
|
||||
@@ -94,7 +94,7 @@ class AuthenticationLoginViewModelTests: XCTestCase {
|
||||
@MainActor func testLoadingServer() {
|
||||
// Given a form with valid credentials.
|
||||
context.username = "bob"
|
||||
context.password = "12345678"
|
||||
context.password = "12345678" //NOSONAR Password for Unittests
|
||||
XCTAssertTrue(context.viewState.hasValidCredentials, "The credentials should be valid.")
|
||||
XCTAssertTrue(context.viewState.canSubmit, "The form should be valid to submit.")
|
||||
XCTAssertFalse(context.viewState.isLoading, "The view shouldn't start in a loading state.")
|
||||
|
||||
@@ -150,7 +150,7 @@ import XCTest
|
||||
|
||||
// When entering a password of 7 characters without a username.
|
||||
context.username = ""
|
||||
context.password = "1234567"
|
||||
context.password = "1234567" //NOSONAR Password for Unittests
|
||||
|
||||
// Then the credentials should remain invalid.
|
||||
XCTAssertTrue(context.viewState.isPasswordInvalid, "A 7-character password should be invalid.")
|
||||
@@ -168,7 +168,7 @@ import XCTest
|
||||
|
||||
// When entering a password of 8 characters without a username.
|
||||
context.username = ""
|
||||
context.password = "12345678"
|
||||
context.password = "12345678" //NOSONAR Password for Unittests
|
||||
|
||||
// Then the password should be valid but the credentials should still be invalid.
|
||||
XCTAssertFalse(context.viewState.isPasswordInvalid, "An 8-character password should be valid.")
|
||||
@@ -204,7 +204,7 @@ import XCTest
|
||||
|
||||
// When entering a username and password and encountering a username error
|
||||
context.username = "bob"
|
||||
context.password = "12345678"
|
||||
context.password = "12345678" //NOSONAR Password for Unittests
|
||||
|
||||
let errorMessage = "Username unavailable"
|
||||
viewModel.displayError(.usernameUnavailable(errorMessage))
|
||||
@@ -225,7 +225,7 @@ import XCTest
|
||||
|
||||
// When entering a username and an 8-character password.
|
||||
context.username = "bob"
|
||||
context.password = "12345678"
|
||||
context.password = "12345678" //NOSONAR Password for Unittests
|
||||
|
||||
// Then the credentials should be considered valid.
|
||||
XCTAssertFalse(context.viewState.isPasswordInvalid, "An 8-character password should be valid.")
|
||||
@@ -236,7 +236,7 @@ import XCTest
|
||||
@MainActor func testLoadingServer() {
|
||||
// Given a form with valid credentials.
|
||||
context.username = "bob"
|
||||
context.password = "12345678"
|
||||
context.password = "12345678" //NOSONAR Password for Unittests
|
||||
XCTAssertTrue(context.viewState.hasValidCredentials, "The credentials should be valid.")
|
||||
XCTAssertTrue(context.viewState.canSubmit, "The form should be valid to submit.")
|
||||
XCTAssertFalse(context.viewState.isLoading, "The view shouldn't start in a loading state.")
|
||||
|
||||
@@ -51,7 +51,7 @@ enum MockAuthenticationSoftLogoutScreenState: MockScreenState, CaseIterable {
|
||||
viewModel = AuthenticationSoftLogoutViewModel(credentials: credentials,
|
||||
homeserver: .mockMatrixDotOrg,
|
||||
keyBackupNeeded: true,
|
||||
password: "12345678")
|
||||
password: "12345678") //NOSONAR Password for mock Unittests
|
||||
case .ssoOnly:
|
||||
viewModel = AuthenticationSoftLogoutViewModel(credentials: credentials,
|
||||
homeserver: .mockEnterpriseSSO,
|
||||
|
||||
@@ -40,16 +40,16 @@ enum MockChangePasswordScreenState: MockScreenState, CaseIterable {
|
||||
case .allEmpty:
|
||||
viewModel = ChangePasswordViewModel()
|
||||
case .cannotSubmit:
|
||||
viewModel = ChangePasswordViewModel(oldPassword: "12345678",
|
||||
newPassword1: "87654321")
|
||||
viewModel = ChangePasswordViewModel(oldPassword: "12345678", //NOSONAR Password for mock Unittests
|
||||
newPassword1: "87654321") //NOSONAR Password for mock Unittests
|
||||
case .canSubmit:
|
||||
viewModel = ChangePasswordViewModel(oldPassword: "12345678",
|
||||
newPassword1: "87654321",
|
||||
newPassword2: "87654321")
|
||||
viewModel = ChangePasswordViewModel(oldPassword: "12345678", //NOSONAR Password for mock Unittests
|
||||
newPassword1: "87654321", //NOSONAR Password for mock Unittests
|
||||
newPassword2: "87654321") //NOSONAR Password for mock Unittests
|
||||
case .canSubmitAndSignoutAllDevicesChecked:
|
||||
viewModel = ChangePasswordViewModel(oldPassword: "12345678",
|
||||
newPassword1: "87654321",
|
||||
newPassword2: "87654321",
|
||||
viewModel = ChangePasswordViewModel(oldPassword: "12345678", //NOSONAR Password for mock Unittests
|
||||
newPassword1: "87654321", //NOSONAR Password for mock Unittests
|
||||
newPassword2: "87654321", //NOSONAR Password for mock Unittests
|
||||
signoutAllDevices: true)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ class ChangePasswordViewModelTests: XCTestCase {
|
||||
}
|
||||
|
||||
@MainActor func testValidState() async {
|
||||
let viewModel = ChangePasswordViewModel(oldPassword: "12345678",
|
||||
newPassword1: "87654321",
|
||||
newPassword2: "87654321",
|
||||
let viewModel = ChangePasswordViewModel(oldPassword: "12345678", //NOSONAR Password for mock Unittests
|
||||
newPassword1: "87654321", //NOSONAR Password for mock Unittests
|
||||
newPassword2: "87654321", //NOSONAR Password for mock Unittests
|
||||
signoutAllDevices: true)
|
||||
let context = viewModel.context
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ extension UserSessionInfo {
|
||||
name: "Element Mobile: iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: verificationState,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: hasTimestamp ? Date().timeIntervalSince1970 : nil,
|
||||
applicationName: "Element iOS",
|
||||
applicationVersion: "1.9.14",
|
||||
|
||||
@@ -146,7 +146,7 @@ struct UserSessionCardViewPreview: View {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: verificationState,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: nil,
|
||||
applicationName: "Element iOS",
|
||||
applicationVersion: "1.0.0",
|
||||
|
||||
@@ -90,7 +90,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: nil,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -106,7 +106,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "macOS",
|
||||
deviceType: .desktop,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 8_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -122,7 +122,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "Firefox on Windows",
|
||||
deviceType: .web,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "2.0.0.2",
|
||||
lastSeenIP: "2.0.0.2", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 9_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -138,7 +138,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "Android",
|
||||
deviceType: .mobile,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "3.0.0.3",
|
||||
lastSeenIP: "3.0.0.3", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 10_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -157,7 +157,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: nil,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -173,7 +173,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "macOS",
|
||||
deviceType: .desktop,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 8_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -192,7 +192,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: nil,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -208,7 +208,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "macOS",
|
||||
deviceType: .desktop,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 8_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -227,7 +227,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 500_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -243,7 +243,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "macOS",
|
||||
deviceType: .desktop,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 8_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -259,7 +259,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "Firefox on Windows",
|
||||
deviceType: .web,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "2.0.0.2",
|
||||
lastSeenIP: "2.0.0.2", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 9_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -275,7 +275,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "Android",
|
||||
deviceType: .mobile,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "3.0.0.3",
|
||||
lastSeenIP: "3.0.0.3", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 10_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -291,7 +291,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 11_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
@@ -307,7 +307,7 @@ enum MockUserOtherSessionsScreenState: MockScreenState, CaseIterable {
|
||||
name: "macOS",
|
||||
deviceType: .desktop,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 20_000_000,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
|
||||
@@ -377,7 +377,7 @@ class UserOtherSessionsViewModelTests: XCTestCase {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: verificationState,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 100,
|
||||
applicationName: nil,
|
||||
applicationVersion: nil,
|
||||
|
||||
@@ -45,7 +45,7 @@ enum MockUserSessionDetailsScreenState: MockScreenState, CaseIterable {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: nil,
|
||||
applicationName: "Element iOS",
|
||||
applicationVersion: "1.0.0",
|
||||
|
||||
@@ -55,7 +55,7 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: state,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: nil,
|
||||
applicationName: "Element iOS",
|
||||
applicationVersion: "1.0.0",
|
||||
@@ -73,7 +73,7 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable {
|
||||
name: "macOS",
|
||||
deviceType: .desktop,
|
||||
verificationState: state,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 130_000,
|
||||
applicationName: "Element MacOS",
|
||||
applicationVersion: "1.0.0",
|
||||
@@ -91,7 +91,7 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable {
|
||||
name: "macOS",
|
||||
deviceType: .desktop,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 130_000,
|
||||
applicationName: "Element MacOS",
|
||||
applicationVersion: "1.0.0",
|
||||
@@ -109,7 +109,7 @@ enum MockUserSessionOverviewScreenState: MockScreenState, CaseIterable {
|
||||
name: "macOS",
|
||||
deviceType: .desktop,
|
||||
verificationState: .verified,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 130_000,
|
||||
applicationName: "Element MacOS",
|
||||
applicationVersion: "1.0.0",
|
||||
|
||||
@@ -90,7 +90,7 @@ class UserSessionOverviewViewModelTests: XCTestCase {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: .unverified,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 100,
|
||||
applicationName: "Element iOS",
|
||||
applicationVersion: "1.9.7",
|
||||
|
||||
@@ -87,7 +87,7 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
|
||||
name: "iOS",
|
||||
deviceType: .mobile,
|
||||
verificationState: mode == .currentSessionVerified ? .verified : .unverified,
|
||||
lastSeenIP: "10.0.0.10",
|
||||
lastSeenIP: "10.0.0.10", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: nil,
|
||||
applicationName: "Element iOS",
|
||||
applicationVersion: "1.0.0",
|
||||
@@ -106,7 +106,7 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
|
||||
name: "macOS verified: \(verified) active: \(active)",
|
||||
deviceType: .desktop,
|
||||
verificationState: verified ? .verified : .unverified,
|
||||
lastSeenIP: "1.0.0.1",
|
||||
lastSeenIP: "1.0.0.1", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 8_000_000,
|
||||
applicationName: "Element MacOS",
|
||||
applicationVersion: "1.0.0",
|
||||
@@ -122,7 +122,7 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
|
||||
name: "Firefox on Windows verified: \(verified) active: \(active)",
|
||||
deviceType: .web,
|
||||
verificationState: verified ? .verified : .unverified,
|
||||
lastSeenIP: "2.0.0.2",
|
||||
lastSeenIP: "2.0.0.2", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 100,
|
||||
applicationName: "Element Web",
|
||||
applicationVersion: "1.0.0",
|
||||
@@ -138,7 +138,7 @@ class MockUserSessionsOverviewService: UserSessionsOverviewServiceProtocol {
|
||||
name: "Android verified: \(verified) active: \(active)",
|
||||
deviceType: .mobile,
|
||||
verificationState: verified ? .verified : .unverified,
|
||||
lastSeenIP: "3.0.0.3",
|
||||
lastSeenIP: "3.0.0.3", //NOSONAR mocking ip for testing
|
||||
lastSeenTimestamp: Date().timeIntervalSince1970 - 10,
|
||||
applicationName: "Element Android",
|
||||
applicationVersion: "1.0.0",
|
||||
|
||||
30
bwi/Extentions/MXTools+Alias.swift
Normal file
30
bwi/Extentions/MXTools+Alias.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
/*
|
||||
* Copyright (c) 2024 BWI GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import Foundation
|
||||
|
||||
extension MXTools {
|
||||
|
||||
static func createAlias(from roomName: String) -> String {
|
||||
var alias = roomName.trimmingCharacters(in: .whitespacesAndNewlines).filter { "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".contains($0) }
|
||||
|
||||
let timeInterval = String(Int(NSDate().timeIntervalSince1970))
|
||||
alias.append(timeInterval)
|
||||
|
||||
return alias
|
||||
}
|
||||
}
|
||||
@@ -145,4 +145,45 @@ import MatrixSDK
|
||||
return content
|
||||
}
|
||||
|
||||
// #5383 Check if no canonical alias exists, create alias from name and timestamp and add as canonical alias
|
||||
func setAliasIfNeeded(roomName: String?) {
|
||||
Task {
|
||||
do {
|
||||
var needsAlias: Bool = false
|
||||
let state = try await state()
|
||||
|
||||
// Check if canonical exists
|
||||
if let canonicalAlias = state.canonicalAlias {
|
||||
if canonicalAlias.isEmpty {
|
||||
needsAlias = true
|
||||
} else {
|
||||
needsAlias = false
|
||||
}
|
||||
} else {
|
||||
needsAlias = true
|
||||
}
|
||||
if needsAlias {
|
||||
if let roomName = roomName {
|
||||
if !roomName.isEmpty {
|
||||
// Create new alias
|
||||
var newAlias = MXTools.createAlias(from: roomName)
|
||||
// Generate local alias
|
||||
newAlias = MXTools.fullLocalAlias(from: newAlias, with: mxSession)
|
||||
|
||||
// Add local alias
|
||||
addAlias(newAlias) { [self] response in
|
||||
if response.isSuccess {
|
||||
// Set new alias as canonical alias
|
||||
setCanonicalAlias(newAlias) { response in
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch { return }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ struct RoomFederationDecisionView: View {
|
||||
.lineLimit(nil)
|
||||
.foregroundColor(Color(theme.colors.primaryContent))
|
||||
Text(BWIL10n.roomAdminFederationDecisionSheetText)
|
||||
.font(.system(size: 12))
|
||||
.font(Font(theme.fonts.subheadline))
|
||||
.multilineTextAlignment(.center)
|
||||
.lineLimit(nil)
|
||||
.foregroundColor(Color(theme.colors.secondaryContent))
|
||||
@@ -163,6 +163,8 @@ struct RoomFederationDecisionView: View {
|
||||
func setServerACL(isFederated: Bool) {
|
||||
let content: [String:Any] = room.createServerACL(isFederated: isFederated)
|
||||
isUpdatingServerACLs = true
|
||||
// #5383 set alias
|
||||
room.setAliasIfNeeded(roomName: room.displayName)
|
||||
pendingRequest = room.sendStateEvent(MXEventType.roomServerACL, content: content, stateKey: "") { response in
|
||||
isUpdatingServerACLs = false
|
||||
if response.isSuccess {
|
||||
|
||||
@@ -102,11 +102,19 @@ extension PersonalNotesDefaultService : PersonalNotesService {
|
||||
func createPersonalNotesRoomIfNeeded() {
|
||||
|
||||
self.fetchRoomID() { (roomId, error) in
|
||||
if let mxerror = error as? MXError {
|
||||
if let errcode = mxerror.userInfo["errcode"] as? String {
|
||||
if errcode != kMXErrCodeStringNotFound {
|
||||
// request error, don't create room
|
||||
return
|
||||
|
||||
// bwi #5740 don't create room after connection error that is not translated to mxerror
|
||||
if let error = error {
|
||||
if MXError.isMXError(error) {
|
||||
if let mxError = MXError(nsError: error) {
|
||||
if let errcode = mxError.userInfo["errcode"] as? String {
|
||||
if errcode != kMXErrCodeStringNotFound {
|
||||
// request error, don't create room
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return
|
||||
|
||||
@@ -6,6 +6,7 @@ sonar.projectName=BundesMessenger iOS
|
||||
|
||||
sonar.sources=Riot,RiotSwiftUI,RiotNSE,RiotShareExtension,DesignKit,bwi,CommonKit,Config
|
||||
sonar.tests=RiotTests
|
||||
sonar.exclusions=RiotSwiftUI/**/Test/Unit/**,RiotSwiftUI/**/Mock*,Riot/Assets/js/**
|
||||
|
||||
# disable obj-c scans
|
||||
sonar.c.file.suffixes=-
|
||||
|
||||
Reference in New Issue
Block a user