From ab01430aaea3e998b698aebe0f90f3eb626072aa Mon Sep 17 00:00:00 2001 From: fmodf Date: Mon, 16 Dec 2024 13:51:12 +0100 Subject: [PATCH] wip --- AnotherIM/xmpp/XMPPClient.swift | 11 ++++++-- AnotherIM/xmpp/models/JID.swift | 6 +++- AnotherIM/xmpp/models/Stanza.swift | 14 ++++++++-- .../xmpp/modules/roster/RosterModule.swift | 28 +++++++++++++++++++ .../xmpp/modules/session/SessionModule.swift | 2 +- 5 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 AnotherIM/xmpp/modules/roster/RosterModule.swift diff --git a/AnotherIM/xmpp/XMPPClient.swift b/AnotherIM/xmpp/XMPPClient.swift index 35ba221..c82353a 100644 --- a/AnotherIM/xmpp/XMPPClient.swift +++ b/AnotherIM/xmpp/XMPPClient.swift @@ -38,7 +38,12 @@ enum Event { case bindStream case bindStreamDone(String) case bindStreamError + + // stream established, RFC-6120 procedure done case streamReady + + case requestRoster + // case gotRoster // by request or by server push } // MARK: State @@ -83,6 +88,7 @@ struct ClientState: Codable & Equatable { } } +// MARK: Client final class XMPPClient { private var state = ClientState.initial private let logger = ClientLogger() @@ -94,7 +100,8 @@ final class XMPPClient { SessionModule(), AuthorizationModule(self.storage), StanzaModule(self.storage), - DiscoveryModule() + DiscoveryModule(), + RosterModule() ] init(storage: any XMPPClientStorageProtocol, userAgent: UserAgent) { @@ -103,7 +110,7 @@ final class XMPPClient { } func tryLogin(jid: JID, credentialsId: UUID) { - logger.update(jid.description) + logger.update(jid.full) Task { await fire(.startClientLogin(jid: jid, credsId: credentialsId)) } diff --git a/AnotherIM/xmpp/models/JID.swift b/AnotherIM/xmpp/models/JID.swift index 058e447..4c77e72 100644 --- a/AnotherIM/xmpp/models/JID.swift +++ b/AnotherIM/xmpp/models/JID.swift @@ -10,7 +10,7 @@ struct JID: Hashable, CustomStringConvertible, Codable, Equatable { resourcePart = parts.2 } - var description: String { + var full: String { var str = "\(localPart)@\(domainPart)" if let resource = resourcePart { str += "/\(resource)" @@ -18,6 +18,10 @@ struct JID: Hashable, CustomStringConvertible, Codable, Equatable { return str } + var description: String { + full + } + var hash: Int { if let resourcePart { return "\(localPart)@\(domainPart)/\(resourcePart)".hashValue diff --git a/AnotherIM/xmpp/models/Stanza.swift b/AnotherIM/xmpp/models/Stanza.swift index 85a89e3..fd67ae7 100644 --- a/AnotherIM/xmpp/models/Stanza.swift +++ b/AnotherIM/xmpp/models/Stanza.swift @@ -75,18 +75,26 @@ struct Stanza { // MARK: Init extension Stanza { - static func iqGet(payload: XMLElement) -> Stanza? { + static func iqGet(jid: String? = nil, payload: XMLElement) -> Stanza? { + var attributes = ["id": XMLElement.randomId, "type": "get"] + if let jid { + attributes["from"] = jid + } let req = XMLElement( name: "iq", xmlns: nil, - attributes: ["type": "get", "id": XMLElement.randomId], + attributes: attributes, content: nil, nodes: [payload] ) return Stanza(wrap: req) } - static func iqSet(payload: XMLElement) -> Stanza? { + static func iqSet(jid: String? = nil, payload: XMLElement) -> Stanza? { + var attributes = ["id": XMLElement.randomId, "type": "get"] + if let jid { + attributes["from"] = jid + } let req = XMLElement( name: "iq", xmlns: nil, diff --git a/AnotherIM/xmpp/modules/roster/RosterModule.swift b/AnotherIM/xmpp/modules/roster/RosterModule.swift new file mode 100644 index 0000000..4b16ea6 --- /dev/null +++ b/AnotherIM/xmpp/modules/roster/RosterModule.swift @@ -0,0 +1,28 @@ +import Foundation + +final class RosterModule: XmppModule { + let id = "Roseter module" + + func reduce(oldState: ClientState, with _: Event) -> ClientState { + oldState + } + + func process(state: ClientState, with event: Event) async -> Event? { + switch event { + case .streamReady: + return .requestRoster + + case .requestRoster: + // TODO: check version! + let req = Stanza.iqGet(jid: state.jid.full, payload: XMLElement(name: "query", xmlns: "jabber:iq:roster", attributes: [:], content: nil, nodes: [])) + if let req { + return .stanzaOutbound(req) + } else { + return nil + } + + default: + return nil + } + } +} diff --git a/AnotherIM/xmpp/modules/session/SessionModule.swift b/AnotherIM/xmpp/modules/session/SessionModule.swift index af58dfb..6e88123 100644 --- a/AnotherIM/xmpp/modules/session/SessionModule.swift +++ b/AnotherIM/xmpp/modules/session/SessionModule.swift @@ -92,7 +92,7 @@ final class SessionModule: XmppModule { name: "stream:stream", xmlns: nil, attributes: [ - "from": state.jid.description, + "from": state.jid.bare, "to": state.jid.domainPart, "xml:lang": "en", "version": "1.0",