Merge pull request #5937 from vector-im/andy/4858_resolve_alias

Enable joining a room via identifier from another home server
This commit is contained in:
Anderas 2022-03-29 10:54:48 +01:00 committed by GitHub
commit 4e67b0b406
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 111 additions and 26 deletions

View file

@ -1487,7 +1487,7 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
// Ask the HS to resolve the room alias into a room id and then retry
self->universalLinkFragmentPending = fragment;
MXKAccount* account = accountManager.activeAccounts.firstObject;
[account.mxSession.matrixRestClient roomIDForRoomAlias:roomIdOrAlias success:^(NSString *roomId) {
[account.mxSession.matrixRestClient resolveRoomAlias:roomIdOrAlias success:^(MXRoomAliasResolution *resolution) {
// Note: the activity indicator will not disappear if the session is not ready
[homeViewController stopActivityIndicator];
@ -1495,34 +1495,20 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni
// Check that 'fragment' has not been cancelled
if ([self->universalLinkFragmentPending isEqualToString:fragment])
{
// Retry opening the link but with the returned room id
NSString *newUniversalLinkFragment =
[fragment stringByReplacingOccurrencesOfString:[MXTools encodeURIComponent:roomIdOrAlias]
withString:[MXTools encodeURIComponent:roomId]
];
// The previous operation can fail because of percent encoding
// TBH we are not clean on data inputs. For the moment, just give another try with no encoding
// TODO: Have a dedicated module and tests to handle universal links (matrix.to, email link, etc)
if ([newUniversalLinkFragment isEqualToString:fragment])
NSString *newFragment = resolution.deeplinkFragment;
if (newFragment && ![newFragment isEqualToString:fragment])
{
newUniversalLinkFragment =
[fragment stringByReplacingOccurrencesOfString:roomIdOrAlias
withString:[MXTools encodeURIComponent:roomId]];
}
if (![newUniversalLinkFragment isEqualToString:fragment])
{
self->universalLinkFragmentPendingRoomAlias = @{roomId: roomIdOrAlias};
UniversalLinkParameters *newParameters = [[UniversalLinkParameters alloc] initWithFragment:newUniversalLinkFragment universalLinkURL:universalLinkURL presentationParameters:presentationParameters];
self->universalLinkFragmentPendingRoomAlias = @{resolution.roomId: roomIdOrAlias};
UniversalLinkParameters *newParameters = [[UniversalLinkParameters alloc] initWithFragment:newFragment
universalLinkURL:universalLinkURL
presentationParameters:presentationParameters];
[self handleUniversalLinkWithParameters:newParameters];
}
else
{
// Do not continue. Else we will loop forever
MXLogDebug(@"[AppDelegate] Universal link: Error: Cannot resolve alias in %@ to the room id %@", fragment, roomId);
MXLogDebug(@"[AppDelegate] Universal link: Error: Cannot resolve alias in %@ to the room id %@", fragment, resolution.roomId);
}
}

View file

@ -867,14 +867,13 @@
__weak typeof(self) weakSelf = self;
[self startActivityIndicator];
[self.mxSession.matrixRestClient roomIDForRoomAlias:roomIdOrAlias success:^(NSString *roomId) {
[self.mxSession.matrixRestClient resolveRoomAlias:roomIdOrAlias success:^(MXRoomAliasResolution *resolution) {
if (roomId && weakSelf)
{
typeof(self) self = weakSelf;
[self stopActivityIndicator];
[self didSelectRoomId:roomId];
[self didSelectRoomId:resolution.roomId];
}
} failure:^(NSError *error) {

View file

@ -0,0 +1,43 @@
//
// Copyright 2022 New Vector Ltd
//
// 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
import MatrixSDK
@objc extension MXRoomAliasResolution {
/// Deeplink fragment using a room identifier and a list of servers aware of this identifier
///
/// For more details see
/// https://github.com/matrix-org/matrix-spec-proposals/blob/old_master/proposals/1704-matrix.to-permalinks.md
var deeplinkFragment: String? {
guard let roomId = roomId else {
MXLog.debug("[MXRoomAliasResolution]: Missing room identifier")
return nil
}
return MXTools.encodeURIComponent(
fragment(for: roomId)
)
}
private func fragment(for roomId: String) -> String {
guard let servers = servers, !servers.isEmpty else {
return roomId
}
return roomId + "?via=" + servers.joined(separator: "&via=")
}
}

View file

@ -0,0 +1,56 @@
//
// Copyright 2022 New Vector Ltd
//
// 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
import XCTest
@testable import Riot
class MXRoomAliasResolutionDeeplinkTests: XCTestCase {
func test_fragmentIsNilForInvalidResolution() {
let resolution = MXRoomAliasResolution()
XCTAssertNil(resolution.deeplinkFragment)
}
func test_fragmentDoesNotContainServers_ifNoServers() {
let resolution = MXRoomAliasResolution()
resolution.roomId = "!abc:matrix.org"
XCTAssertEqual(resolution.deeplinkFragment, "!abc%3Amatrix.org")
}
func test_fragmentContainsSingleServer() {
let resolution = MXRoomAliasResolution()
resolution.roomId = "xyz:element.io"
resolution.servers = [
"matrix.org"
]
XCTAssertEqual(resolution.deeplinkFragment, "xyz%3Aelement.io%3Fvia%3Dmatrix.org")
}
func test_fragmentContainsMultipleSerivers() {
let resolution = MXRoomAliasResolution()
resolution.roomId = "mno:server.com"
resolution.servers = [
"server.com",
"element.io",
"wikipedia.org",
"matrix.org"
]
XCTAssertEqual(resolution.deeplinkFragment, "mno%3Aserver.com%3Fvia%3Dserver.com%26via%3Delement.io%26via%3Dwikipedia.org%26via%3Dmatrix.org")
}
}

1
changelog.d/4858.bugfix Normal file
View file

@ -0,0 +1 @@
Room: Enable joining a room via identifier from another home server