Re-enable joining V1 open groups

This commit is contained in:
Niels Andriesse 2021-03-29 11:33:52 +11:00
parent 5504f74659
commit 7558e0b32a
6 changed files with 68 additions and 13 deletions

View file

@ -253,6 +253,7 @@
B88A1AC725C90A4700E6D421 /* TypingIndicatorInteraction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B6A904218B4C90007C4606 /* TypingIndicatorInteraction.swift */; };
B88FA7B826045D100049422F /* OpenGroupAPIV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88FA7B726045D100049422F /* OpenGroupAPIV2.swift */; };
B88FA7F2260C3EB10049422F /* OpenGroupSuggestionGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88FA7F1260C3EB10049422F /* OpenGroupSuggestionGrid.swift */; };
B88FA7FB26114EA70049422F /* Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88FA7FA26114EA70049422F /* Hex.swift */; };
B893063F2383961A005EAA8E /* ScanQRCodeWrapperVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */; };
B894D0752339EDCF00B4D94D /* NukeDataModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B894D0742339EDCF00B4D94D /* NukeDataModal.swift */; };
B897621C25D201F7004F83B2 /* ScrollToBottomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B897621B25D201F7004F83B2 /* ScrollToBottomButton.swift */; };
@ -1243,6 +1244,7 @@
B886B4A82398BA1500211ABE /* QRCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCode.swift; sourceTree = "<group>"; };
B88FA7B726045D100049422F /* OpenGroupAPIV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupAPIV2.swift; sourceTree = "<group>"; };
B88FA7F1260C3EB10049422F /* OpenGroupSuggestionGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenGroupSuggestionGrid.swift; sourceTree = "<group>"; };
B88FA7FA26114EA70049422F /* Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hex.swift; sourceTree = "<group>"; };
B893063E2383961A005EAA8E /* ScanQRCodeWrapperVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScanQRCodeWrapperVC.swift; sourceTree = "<group>"; };
B894D0742339EDCF00B4D94D /* NukeDataModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NukeDataModal.swift; sourceTree = "<group>"; };
B897621B25D201F7004F83B2 /* ScrollToBottomButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollToBottomButton.swift; sourceTree = "<group>"; };
@ -2266,6 +2268,7 @@
C3C2ABD12553C6C900C340D1 /* Data+SecureRandom.swift */,
C3A71D662558A0170043A11F /* DiffieHellman.swift */,
C33FDA73255A57FA00E217F9 /* ECKeyPair+Hexadecimal.swift */,
B88FA7FA26114EA70049422F /* Hex.swift */,
C3A71F882558BA9F0043A11F /* Mnemonic.swift */,
);
path = Crypto;
@ -4732,6 +4735,7 @@
C3D9E41F25676C870040E4F3 /* OWSPrimaryStorageProtocol.swift in Sources */,
C3BBE0A72554D4DE0050F1E3 /* Promise+Retrying.swift in Sources */,
B8856D7B256F14F4001CE70E /* UIView+OWS.m in Sources */,
B88FA7FB26114EA70049422F /* Hex.swift in Sources */,
C35D0DB525AE5F1200B6BF49 /* UIEdgeInsets.swift in Sources */,
C3D9E4F4256778AF0040E4F3 /* NSData+Image.m in Sources */,
C32C5E0C256DDAFA003C73A2 /* NSRegularExpression+SSK.swift in Sources */,

View file

@ -124,15 +124,55 @@ final class JoinOpenGroupVC : BaseVC, UIPageViewControllerDataSource, UIPageView
joinOpenGroup(with: string)
}
fileprivate func joinOpenGroup(with url: String) {
// TODO: V1 open groups
fileprivate func joinOpenGroup(with string: String) {
// A V1 open group URL will look like: https:// + <host>
// A V2 open group URL will look like: <optional scheme> + <host> + <optional port> + <room> + <public key>
// The host doesn't parse if no explicit scheme is provided
if let url = URL(string: string), let host = url.host ?? given(string.split(separator: "/").first, { String($0) }) {
if let query = url.query {
// Inputs that should work:
// https://sessionopengroup.co/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
// http://sessionopengroup.co/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
// sessionopengroup.co/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c (does NOT go to HTTPS)
// https://143.198.213.225:443/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
// 143.198.213.255:80/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
let useTLS = (url.scheme == "https")
let room = String(url.path.dropFirst()) // Drop the leading slash
let queryParts = query.split(separator: "=")
guard !room.isEmpty && !room.contains("/"), queryParts.count == 2, queryParts[0] == "public_key" else {
let title = NSLocalizedString("invalid_url", comment: "")
let message = "Please check the URL you entered and try again."
return showError(title: title, message: message)
}
let publicKey = String(queryParts[1])
guard publicKey.count == 64 && Hex.isValid(publicKey) else {
let title = NSLocalizedString("invalid_url", comment: "")
let message = "Please check the URL you entered and try again."
return showError(title: title, message: message)
}
var server = (useTLS ? "https://" : "http://") + host
if let port = url.port { server += ":\(port)" }
joinV2OpenGroup(room: room, server: server, publicKey: publicKey)
} else {
// Inputs that should work:
// loki.opensession.id
// https://loki.opensession.id
// http://loki.opensession.id (still goes to HTTPS)
joinV1OpenGroup("https://" + host)
}
} else {
let title = NSLocalizedString("invalid_url", comment: "")
let message = "Please check the URL you entered and try again."
showError(title: title, message: message)
}
}
private func joinV1OpenGroup(_ string: String) {
guard !isJoining else { return }
isJoining = true
ModalActivityIndicatorViewController.present(fromViewController: navigationController!, canCancel: false) { [weak self] _ in
Storage.shared.write { transaction in
OpenGroupManagerV2.shared.add(room: "main", server: "https://sessionopengroup.com", publicKey: "658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231b", using: transaction)
OpenGroupManager.shared.add(with: string, using: transaction)
.done(on: DispatchQueue.main) { [weak self] _ in
self?.presentingViewController!.dismiss(animated: true, completion: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
@ -140,8 +180,12 @@ final class JoinOpenGroupVC : BaseVC, UIPageViewControllerDataSource, UIPageView
}
.catch(on: DispatchQueue.main) { [weak self] error in
self?.dismiss(animated: true, completion: nil) // Dismiss the loader
let title = "Couldn't Join"
let message = error.localizedDescription
var title = "Couldn't Join"
var message = ""
if case OnionRequestAPI.Error.httpRequestFailedAtDestination(let statusCode, _) = error, statusCode == 401 || statusCode == 403 {
title = "Unauthorized"
message = "Please ask the open group operator to add you to the group."
}
self?.isJoining = false
self?.showError(title: title, message: message)
}
@ -149,7 +193,7 @@ final class JoinOpenGroupVC : BaseVC, UIPageViewControllerDataSource, UIPageView
}
}
fileprivate func join(_ room: String, on server: String, with publicKey: String) {
fileprivate func joinV2OpenGroup(room: String, server: String, publicKey: String) {
guard !isJoining else { return }
isJoining = true
ModalActivityIndicatorViewController.present(fromViewController: navigationController!, canCancel: false) { [weak self] _ in
@ -187,6 +231,7 @@ private final class EnterURLVC : UIViewController, UIGestureRecognizerDelegate,
let result = TextField(placeholder: NSLocalizedString("vc_enter_chat_url_text_field_hint", comment: ""))
result.keyboardType = .URL
result.autocapitalizationType = .none
result.autocorrectionType = .no
return result
}()
@ -251,7 +296,7 @@ private final class EnterURLVC : UIViewController, UIGestureRecognizerDelegate,
}
func join(_ room: OpenGroupAPIV2.Info) {
joinOpenGroupVC.join(room.id, on: OpenGroupAPIV2.defaultServer, with: OpenGroupAPIV2.defaultServerPublicKey)
joinOpenGroupVC.joinV2OpenGroup(room: room.id, server: OpenGroupAPIV2.defaultServer, publicKey: OpenGroupAPIV2.defaultServerPublicKey)
}
@objc private func joinOpenGroup() {

View file

@ -2,7 +2,6 @@ import PromiseKit
import SessionSnodeKit
// TODO: Show images w/ room suggestions
// TODO: Distinguish between V1 and V2 open groups in the join open group screen
@objc(SNOpenGroupAPIV2)
public final class OpenGroupAPIV2 : NSObject {

View file

@ -34,10 +34,10 @@ public final class OpenGroupManagerV2 : NSObject {
storage.removeLastMessageServerID(for: room, on: server, using: transaction)
storage.removeLastDeletionServerID(for: room, on: server, using: transaction)
storage.removeAuthToken(for: room, on: server, using: transaction)
storage.setOpenGroupPublicKey(for: server, to: publicKey, using: transaction)
let (promise, seal) = Promise<Void>.pending()
let transaction = transaction as! YapDatabaseReadWriteTransaction
transaction.addCompletionQueue(DispatchQueue.global(qos: .default)) {
storage.setOpenGroupPublicKey(for: server, to: publicKey, using: transaction)
OpenGroupAPIV2.getInfo(for: room, on: server).done(on: DispatchQueue.global(qos: .default)) { info in
let openGroup = OpenGroupV2(server: server, room: room, name: info.name, imageID: info.imageID)
let groupID = LKGroupUtilities.getEncodedOpenGroupIDAsData(openGroup.id)

View file

@ -13,8 +13,7 @@ public extension ECKeyPair {
@objc static func isValidHexEncodedPublicKey(candidate: String) -> Bool {
// Check that it's a valid hexadecimal encoding
let allowedCharacters = CharacterSet(charactersIn: "0123456789ABCDEF")
guard candidate.uppercased().unicodeScalars.allSatisfy({ allowedCharacters.contains($0) }) else { return false }
guard Hex.isValid(candidate) else { return false }
// Check that it has length 66 and a leading "05"
guard candidate.count == 66 && candidate.hasPrefix("05") else { return false }
// It appears to be a valid public key

View file

@ -0,0 +1,8 @@
public enum Hex {
public static func isValid(_ string: String) -> Bool {
let allowedCharacters = CharacterSet(charactersIn: "0123456789ABCDEF")
return string.uppercased().unicodeScalars.allSatisfy { allowedCharacters.contains($0) }
}
}