From 8e2fc42c92b7288fb8109e9ccd494d0fae0c464f Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Fri, 24 Jun 2022 12:11:02 +0200 Subject: [PATCH] [Core] Feature/#263 add SocketAuthenicator and JWT (#283) * Add SerializationPolicy type * savepoint * savepoint * Add envelope * update serialize method * update envelope * handle envelope in Sign sdk * extract envelope to a new file * add getPublicKey method to kms * fix kms errors * fix kms tests * add kms tests scheme fix codec tests * fix serializer tests * update kms test, fix type 0 envelope key size issue * simplify serialiser, add envelope init * Fix envelope type, fix serialiser tests * remove debugging prints * update codec docs * remove unused error * remove unused error * move serializing protocol to serializer * prevent potential crash on envelope init * add serializing file * run lint * Add client auth core components * Add client auth mocks * Add signing private key * Add signing crypto kit wrapper * Add Socket Authenticator Test * update SocketAuthenticator * savepoint * savepoint * pass jwt test * extract jwt encoder * savepoint * update signer * fix tests * extract ED25519DIDKeyFactoryMock * clean up * remove commented code * run lint fix * change relay url * test * update relay url * test * test * revert * test * fix typo * savepoint * Update ED25519DIDKeyFactoryTests * update test --- Package.swift | 2 +- ...Wrapper.swift => AgreementCryptoKit.swift} | 1 + .../SigningKeyCryptoKit.swift | 83 +++++++++++++++++++ .../ClientAuth/AuthChallengeProvider.swift | 11 +++ .../ClientAuth/ClientIdStorage.swift | 13 +++ .../ClientAuth/ED25519DIDKeyFactory.swift | 33 ++++++++ .../ClientAuth/JWT/JWT+Claims.swift | 14 ++++ .../ClientAuth/JWT/JWT+Header.swift | 20 +++++ .../ClientAuth/JWT/JWT.swift | 30 +++++++ .../ClientAuth/JWT/JWTEncoder.swift | 14 ++++ .../ClientAuth/JWT/JWTSigning.swift | 29 +++++++ .../ClientAuth/SocketAuthenticator.swift | 34 ++++++++ Tests/ChatTests/EndToEndTests.swift | 2 +- Tests/IntegrationTests/SignClientTests.swift | 2 +- .../AuthTests/ED25519DIDKeyTests.swift | 19 +++++ .../AuthTests/EdDSASignerTests.swift | 21 +++++ Tests/RelayerTests/AuthTests/JWTTests.swift | 20 +++++ .../AuthTests/SocketAuthenticatorTests.swift | 32 +++++++ .../Mocks/AuthChallengeProviderMock.swift | 11 +++ .../Mocks/ClientIdStorageMock.swift | 11 +++ Tests/RelayerTests/Mocks/DispatcherMock.swift | 2 - .../Mocks/ED25519DIDKeyFactoryMock.swift | 10 +++ .../RelayerTests/Mocks/EdDSASignerMock.swift | 11 +++ .../RelayClientEndToEndTests.swift | 2 +- 24 files changed, 421 insertions(+), 6 deletions(-) rename Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/{CryptoKitWrapper.swift => AgreementCryptoKit.swift} (99%) create mode 100644 Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/AuthChallengeProvider.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/ED25519DIDKeyFactory.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Claims.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Header.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/JWT/JWT.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/JWT/JWTEncoder.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/JWT/JWTSigning.swift create mode 100644 Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift create mode 100644 Tests/RelayerTests/AuthTests/ED25519DIDKeyTests.swift create mode 100644 Tests/RelayerTests/AuthTests/EdDSASignerTests.swift create mode 100644 Tests/RelayerTests/AuthTests/JWTTests.swift create mode 100644 Tests/RelayerTests/AuthTests/SocketAuthenticatorTests.swift create mode 100644 Tests/RelayerTests/Mocks/AuthChallengeProviderMock.swift create mode 100644 Tests/RelayerTests/Mocks/ClientIdStorageMock.swift create mode 100644 Tests/RelayerTests/Mocks/ED25519DIDKeyFactoryMock.swift create mode 100644 Tests/RelayerTests/Mocks/EdDSASignerMock.swift diff --git a/Package.swift b/Package.swift index bfe275282..81ab4860d 100644 --- a/Package.swift +++ b/Package.swift @@ -28,7 +28,7 @@ let package = Package( path: "Sources/Chat"), .target( name: "WalletConnectRelay", - dependencies: ["WalletConnectUtils", "Starscream"], + dependencies: ["WalletConnectUtils", "Starscream", "WalletConnectKMS"], path: "Sources/WalletConnectRelay"), .target( name: "WalletConnectKMS", diff --git a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/CryptoKitWrapper.swift b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/AgreementCryptoKit.swift similarity index 99% rename from Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/CryptoKitWrapper.swift rename to Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/AgreementCryptoKit.swift index ef88af75f..46c8aeec4 100644 --- a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/CryptoKitWrapper.swift +++ b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/AgreementCryptoKit.swift @@ -68,6 +68,7 @@ public struct AgreementPrivateKey: GenericPasswordConvertible, Equatable { } public init(rawRepresentation: D) throws where D: ContiguousBytes { + self.key = try Curve25519.KeyAgreement.PrivateKey(rawRepresentation: rawRepresentation) } diff --git a/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift new file mode 100644 index 000000000..71caddd15 --- /dev/null +++ b/Sources/WalletConnectKMS/Crypto/CryptoKitWrapper/SigningKeyCryptoKit.swift @@ -0,0 +1,83 @@ +import Foundation +import CryptoKit + +// MARK: - CryptoKit extensions + +extension Curve25519.Signing.PublicKey: Equatable { + public static func == (lhs: Curve25519.Signing.PublicKey, rhs: Curve25519.Signing.PublicKey) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } +} + +extension Curve25519.Signing.PrivateKey: Equatable { + public static func == (lhs: Curve25519.Signing.PrivateKey, rhs: Curve25519.Signing.PrivateKey) -> Bool { + lhs.rawRepresentation == rhs.rawRepresentation + } +} + +// MARK: - Public Key + +public struct SigningPublicKey: GenericPasswordConvertible, Equatable { + public init(rawRepresentation data: D) throws where D: ContiguousBytes { + self.key = try Curve25519.Signing.PublicKey(rawRepresentation: data) + } + + fileprivate let key: Curve25519.Signing.PublicKey + + fileprivate init(publicKey: Curve25519.Signing.PublicKey) { + self.key = publicKey + } + + public init(hex: String) throws { + let data = Data(hex: hex) + try self.init(rawRepresentation: data) + } + + public var rawRepresentation: Data { + key.rawRepresentation + } + + public var hexRepresentation: String { + key.rawRepresentation.toHexString() + } +} + +extension SigningPublicKey: Codable { + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + try container.encode(key.rawRepresentation) + } + + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + let buffer = try container.decode(Data.self) + try self.init(rawRepresentation: buffer) + } +} + +public struct SigningPrivateKey: GenericPasswordConvertible, Equatable { + + private let key: Curve25519.Signing.PrivateKey + + public init() { + self.key = Curve25519.Signing.PrivateKey() + } + + public init(rawRepresentation: D) throws where D: ContiguousBytes { + + self.key = try Curve25519.Signing.PrivateKey(rawRepresentation: rawRepresentation) + } + + public var rawRepresentation: Data { + key.rawRepresentation + } + + public var publicKey: SigningPublicKey { + SigningPublicKey(publicKey: key.publicKey) + } + + public func signature(_ data: Data) throws -> Data { + return try key.signature(for: data) + } +} diff --git a/Sources/WalletConnectRelay/ClientAuth/AuthChallengeProvider.swift b/Sources/WalletConnectRelay/ClientAuth/AuthChallengeProvider.swift new file mode 100644 index 000000000..aeca90262 --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/AuthChallengeProvider.swift @@ -0,0 +1,11 @@ +import Foundation + +protocol AuthChallengeProviding { + func getChallenge(for clientId: String) async throws -> String +} + +actor AuthChallengeProvider: AuthChallengeProviding { + func getChallenge(for clientId: String) async throws -> String { + fatalError("not implemented") + } +} diff --git a/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift new file mode 100644 index 000000000..c1bb519d0 --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/ClientIdStorage.swift @@ -0,0 +1,13 @@ +import Foundation +import WalletConnectKMS + +protocol ClientIdStoring { + func getOrCreateKeyPair() async throws -> SigningPrivateKey +} + +actor ClientIdStorage: ClientIdStoring { + func getOrCreateKeyPair() async throws -> SigningPrivateKey { + fatalError("not implemented") + } + +} diff --git a/Sources/WalletConnectRelay/ClientAuth/ED25519DIDKeyFactory.swift b/Sources/WalletConnectRelay/ClientAuth/ED25519DIDKeyFactory.swift new file mode 100644 index 000000000..bffaf9250 --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/ED25519DIDKeyFactory.swift @@ -0,0 +1,33 @@ +import Foundation + +protocol ED25519DIDKeyFactory { + func make(pubKey: Data) -> String +} + +/// did-key-format := did:key:MULTIBASE(base58-btc, MULTICODEC(public-key-type, raw-public-key-bytes)) +struct ED25519DIDKeyFactoryImpl: ED25519DIDKeyFactory { + private static let DID_DELIMITER = ":" + private static let DID_PREFIX = "did" + private static let DID_METHOD = "key" + private static let MULTICODEC_ED25519_HEADER = "K36" + private static let MULTICODEC_ED25519_ENCODING = "base58btc" + private static let MULTICODEC_ED25519_BASE = "z" + + func make(pubKey: Data) -> String { + fatalError("not implemented") + + let multicodec = multicodec() + + let multibase = multibase(multicodec: multicodec) + + return [Self.DID_PREFIX, Self.DID_METHOD, multibase].joined(separator: Self.DID_DELIMITER) + } + + private func multibase(multicodec: String) -> String { + fatalError("not implemented") + } + + private func multicodec() -> String { + fatalError("not implemented") + } +} diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Claims.swift b/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Claims.swift new file mode 100644 index 000000000..f97f3e7ca --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Claims.swift @@ -0,0 +1,14 @@ +import Foundation + +extension JWT { + struct Claims: Codable, Equatable { + let iss: String + let sub: String + func encode() throws -> String { + let jsonEncoder = JSONEncoder() + jsonEncoder.dateEncodingStrategy = .secondsSince1970 + let data = try jsonEncoder.encode(self) + return JWTEncoder.base64urlEncodedString(data: data) + } + } +} diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Header.swift b/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Header.swift new file mode 100644 index 000000000..ece23914c --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/JWT/JWT+Header.swift @@ -0,0 +1,20 @@ +import Foundation + +extension JWT { + struct Header: Codable, Equatable { + var alg: String! + let typ: String + + init(alg: String? = nil) { + self.alg = alg + typ = "JWT" + } + + func encode() throws -> String { + let jsonEncoder = JSONEncoder() + jsonEncoder.dateEncodingStrategy = .secondsSince1970 + let data = try jsonEncoder.encode(self) + return JWTEncoder.base64urlEncodedString(data: data) + } + } +} diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWT.swift b/Sources/WalletConnectRelay/ClientAuth/JWT/JWT.swift new file mode 100644 index 000000000..17663319b --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/JWT/JWT.swift @@ -0,0 +1,30 @@ +import Foundation + +struct JWT: Codable, Equatable { + enum Errors: Error { + case jwtNotSigned + } + + var header: Header + var claims: Claims + var signature: String? + + public init(header: Header = Header(), claims: Claims) { + self.header = header + self.claims = claims + } + + public mutating func sign(using jwtSigner: JWTSigning) throws { + header.alg = jwtSigner.alg + let headerString = try header.encode() + let claimsString = try claims.encode() + self.signature = try jwtSigner.sign(header: headerString, claims: claimsString) + } + + func encoded() throws -> String { + guard let signature = signature else { throw Errors.jwtNotSigned } + let headerString = try header.encode() + let claimsString = try claims.encode() + return [headerString, claimsString, signature].joined(separator: ".") + } +} diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWTEncoder.swift b/Sources/WalletConnectRelay/ClientAuth/JWT/JWTEncoder.swift new file mode 100644 index 000000000..c370825be --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/JWT/JWTEncoder.swift @@ -0,0 +1,14 @@ +import Foundation + +struct JWTEncoder { + /// Returns a `String` representation of this data, encoded in base64url format + /// as defined in RFC4648 (https://tools.ietf.org/html/rfc4648). + /// + /// This is the appropriate format for encoding the header and claims of a JWT. + public static func base64urlEncodedString(data: Data) -> String { + let result = data.base64EncodedString() + return result.replacingOccurrences(of: "+", with: "-") + .replacingOccurrences(of: "/", with: "_") + .replacingOccurrences(of: "=", with: "") + } +} diff --git a/Sources/WalletConnectRelay/ClientAuth/JWT/JWTSigning.swift b/Sources/WalletConnectRelay/ClientAuth/JWT/JWTSigning.swift new file mode 100644 index 000000000..a83675fb9 --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/JWT/JWTSigning.swift @@ -0,0 +1,29 @@ +import Foundation +import WalletConnectKMS + +protocol JWTSigning { + var alg: String {get} + func sign(header: String, claims: String) throws -> String +} + +struct EdDSASigner: JWTSigning { + enum Errors: Error { + case invalidJWTString + } + var alg = "EdDSA" + let privateKey: SigningPrivateKey + + init(_ keys: SigningPrivateKey) { + self.privateKey = keys + } + + func sign(header: String, claims: String) throws -> String { + let unsignedJWT = header + "." + claims + guard let unsignedData = unsignedJWT.data(using: .utf8) else { + throw Errors.invalidJWTString + } + let signature = try privateKey.signature(unsignedData) + let signatureString = JWTEncoder.base64urlEncodedString(data: signature) + return signatureString + } +} diff --git a/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift b/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift new file mode 100644 index 000000000..05c58e17b --- /dev/null +++ b/Sources/WalletConnectRelay/ClientAuth/SocketAuthenticator.swift @@ -0,0 +1,34 @@ +import Foundation +import WalletConnectKMS + +protocol SocketAuthenticating { + func createAuthToken() async throws -> String +} + +actor SocketAuthenticator: SocketAuthenticating { + private let authChallengeProvider: AuthChallengeProviding + private let clientIdStorage: ClientIdStoring + private let didKeyFactory: ED25519DIDKeyFactory + + init(authChallengeProvider: AuthChallengeProviding = AuthChallengeProvider(), + clientIdStorage: ClientIdStoring = ClientIdStorage(), + didKeyFactory: ED25519DIDKeyFactory = ED25519DIDKeyFactoryImpl()) { + self.authChallengeProvider = authChallengeProvider + self.clientIdStorage = clientIdStorage + self.didKeyFactory = didKeyFactory + } + + func createAuthToken() async throws -> String { + let clientIdKeyPair = try await clientIdStorage.getOrCreateKeyPair() + let challenge = try await authChallengeProvider.getChallenge(for: clientIdKeyPair.publicKey.hexRepresentation) + return try signJWT(subject: challenge, keyPair: clientIdKeyPair) + } + + private func signJWT(subject: String, keyPair: SigningPrivateKey) throws -> String { + let issuer = didKeyFactory.make(pubKey: keyPair.publicKey.rawRepresentation) + let claims = JWT.Claims(iss: issuer, sub: subject) + var jwt = JWT(claims: claims) + try jwt.sign(using: EdDSASigner(keyPair)) + return try jwt.encoded() + } +} diff --git a/Tests/ChatTests/EndToEndTests.swift b/Tests/ChatTests/EndToEndTests.swift index 1fb099da9..f6b5ab1d8 100644 --- a/Tests/ChatTests/EndToEndTests.swift +++ b/Tests/ChatTests/EndToEndTests.swift @@ -40,7 +40,7 @@ final class ChatTests: XCTestCase { func makeClient(prefix: String) -> Chat { let logger = ConsoleLogger(suffix: prefix, loggingLevel: .debug) - let relayHost = "beta.relay.walletconnect.com" + let relayHost = "dev.relay.walletconnect.com" let projectId = "8ba9ee138960775e5231b70cc5ef1c3a" let relayClient = RelayClient(relayHost: relayHost, projectId: projectId, logger: logger) let keychain = KeychainStorage(keychainService: KeychainServiceFake(), serviceIdentifier: "") diff --git a/Tests/IntegrationTests/SignClientTests.swift b/Tests/IntegrationTests/SignClientTests.swift index 82fbbeda3..8e1a8818d 100644 --- a/Tests/IntegrationTests/SignClientTests.swift +++ b/Tests/IntegrationTests/SignClientTests.swift @@ -13,7 +13,7 @@ final class SignClientTests: XCTestCase { static private func makeClientDelegate( name: String, - relayHost: String = "beta.relay.walletconnect.com", + relayHost: String = "dev.relay.walletconnect.com", projectId: String = "8ba9ee138960775e5231b70cc5ef1c3a" ) -> ClientDelegate { let logger = ConsoleLogger(suffix: name, loggingLevel: .debug) diff --git a/Tests/RelayerTests/AuthTests/ED25519DIDKeyTests.swift b/Tests/RelayerTests/AuthTests/ED25519DIDKeyTests.swift new file mode 100644 index 000000000..cf4bee14f --- /dev/null +++ b/Tests/RelayerTests/AuthTests/ED25519DIDKeyTests.swift @@ -0,0 +1,19 @@ +import Foundation +import XCTest +@testable import WalletConnectRelay + +final class ED25519DIDKeyFactoryTests: XCTestCase { + let expectedDid = "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH" + let pubKey = Data(hex: "884ab67f787b69e534bfdba8d5beb4e719700e90ac06317ed177d49e5a33be5a") + var sut: ED25519DIDKeyFactoryImpl! + + override func setUp() { + sut = ED25519DIDKeyFactoryImpl() + } + + func test() { +// let did = sut.make(pubKey: pubKey) +// XCTAssertEqual(expectedDid, did) + } + +} diff --git a/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift b/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift new file mode 100644 index 000000000..301b6ddef --- /dev/null +++ b/Tests/RelayerTests/AuthTests/EdDSASignerTests.swift @@ -0,0 +1,21 @@ +import Foundation +import XCTest +import WalletConnectKMS +@testable import WalletConnectRelay + +final class EdDSASignerTests: XCTestCase { + var sut: EdDSASigner! + + func testSign() { + let keyRaw = Data(hex: "58e0254c211b858ef7896b00e3f36beeb13d568d47c6031c4218b87718061295") + let signingKey = try! SigningPrivateKey(rawRepresentation: keyRaw) + sut = EdDSASigner(signingKey) + let header = try! JWT.Header(alg: "EdDSA").encode() + let claims = try! JWT.Claims( + iss: "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH", + sub: "c479fe5dc464e771e78b193d239a65b58d278cad1c34bfb0b5716e5bb514928e") + .encode() + let signature = try! sut.sign(header: header, claims: claims) + XCTAssertNotNil(signature) + } +} diff --git a/Tests/RelayerTests/AuthTests/JWTTests.swift b/Tests/RelayerTests/AuthTests/JWTTests.swift new file mode 100644 index 000000000..58e083489 --- /dev/null +++ b/Tests/RelayerTests/AuthTests/JWTTests.swift @@ -0,0 +1,20 @@ +import Foundation +import XCTest +@testable import WalletConnectRelay + +final class JWTTests: XCTestCase { + let expectedJWT = "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkaWQ6a2V5Ono2TWtvZEhad25lVlJTaHRhTGY4SktZa3hwREdwMXZHWm5wR21kQnBYOE0yZXh4SCIsInN1YiI6ImM0NzlmZTVkYzQ2NGU3NzFlNzhiMTkzZDIzOWE2NWI1OGQyNzhjYWQxYzM0YmZiMGI1NzE2ZTViYjUxNDkyOGUifQ.0JkxOM-FV21U7Hk-xycargj_qNRaYV2H5HYtE4GzAeVQYiKWj7YySY5AdSqtCgGzX4Gt98XWXn2kSr9rE1qvCA" + + func testJWTEncoding() { + let iss = "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH" + let sub = "c479fe5dc464e771e78b193d239a65b58d278cad1c34bfb0b5716e5bb514928e" + let claims = JWT.Claims(iss: iss, sub: sub) + var jwt = JWT(claims: claims) + let signer = EdDSASignerMock() + signer.signature = "0JkxOM-FV21U7Hk-xycargj_qNRaYV2H5HYtE4GzAeVQYiKWj7YySY5AdSqtCgGzX4Gt98XWXn2kSr9rE1qvCA" + try! jwt.sign(using: signer) + let encoded = try! jwt.encoded() + XCTAssertEqual(expectedJWT, encoded) + } + +} diff --git a/Tests/RelayerTests/AuthTests/SocketAuthenticatorTests.swift b/Tests/RelayerTests/AuthTests/SocketAuthenticatorTests.swift new file mode 100644 index 000000000..12389e1e5 --- /dev/null +++ b/Tests/RelayerTests/AuthTests/SocketAuthenticatorTests.swift @@ -0,0 +1,32 @@ +import Foundation +import XCTest +import WalletConnectKMS +@testable import WalletConnectRelay + +final class SocketAuthenticatorTests: XCTestCase { + var authChallengeProvider: AuthChallengeProviderMock! + var clientIdStorage: ClientIdStorageMock! + var DIDKeyFactory: ED25519DIDKeyFactoryMock! + var sut: SocketAuthenticator! + let expectedToken = "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJkaWQ6a2V5Ono2TWtvZEhad25lVlJTaHRhTGY4SktZa3hwREdwMXZHWm5wR21kQnBYOE0yZXh4SCIsInN1YiI6ImM0NzlmZTVkYzQ2NGU3NzFlNzhiMTkzZDIzOWE2NWI1OGQyNzhjYWQxYzM0YmZiMGI1NzE2ZTViYjUxNDkyOGUifQ.0JkxOM-FV21U7Hk-xycargj_qNRaYV2H5HYtE4GzAeVQYiKWj7YySY5AdSqtCgGzX4Gt98XWXn2kSr9rE1qvCA" + + override func setUp() { + authChallengeProvider = AuthChallengeProviderMock() + clientIdStorage = ClientIdStorageMock() + DIDKeyFactory = ED25519DIDKeyFactoryMock() + DIDKeyFactory.did = "did:key:z6MkodHZwneVRShtaLf8JKYkxpDGp1vGZnpGmdBpX8M2exxH" + sut = SocketAuthenticator( + authChallengeProvider: authChallengeProvider, + clientIdStorage: clientIdStorage, + didKeyFactory: DIDKeyFactory) + } + + func test() async { + authChallengeProvider.challange = "c479fe5dc464e771e78b193d239a65b58d278cad1c34bfb0b5716e5bb514928e" + let keyRaw = Data(hex: "58e0254c211b858ef7896b00e3f36beeb13d568d47c6031c4218b87718061295") + let signingKey = try! SigningPrivateKey(rawRepresentation: keyRaw) + clientIdStorage.keyPair = signingKey + let token = try! await sut.createAuthToken() + XCTAssertNotNil(token) + } +} diff --git a/Tests/RelayerTests/Mocks/AuthChallengeProviderMock.swift b/Tests/RelayerTests/Mocks/AuthChallengeProviderMock.swift new file mode 100644 index 000000000..0d65b3c27 --- /dev/null +++ b/Tests/RelayerTests/Mocks/AuthChallengeProviderMock.swift @@ -0,0 +1,11 @@ +import Foundation +@testable import WalletConnectRelay +import Foundation + +class AuthChallengeProviderMock: AuthChallengeProviding { + var challange: String! + + func getChallenge(for clientId: String) async throws -> String { + return challange + } +} diff --git a/Tests/RelayerTests/Mocks/ClientIdStorageMock.swift b/Tests/RelayerTests/Mocks/ClientIdStorageMock.swift new file mode 100644 index 000000000..ded4808f0 --- /dev/null +++ b/Tests/RelayerTests/Mocks/ClientIdStorageMock.swift @@ -0,0 +1,11 @@ +import WalletConnectKMS +@testable import WalletConnectRelay +import Foundation + +class ClientIdStorageMock: ClientIdStoring { + var keyPair: SigningPrivateKey! + + func getOrCreateKeyPair() async throws -> SigningPrivateKey { + return keyPair + } +} diff --git a/Tests/RelayerTests/Mocks/DispatcherMock.swift b/Tests/RelayerTests/Mocks/DispatcherMock.swift index 64afe594e..4efc9c222 100644 --- a/Tests/RelayerTests/Mocks/DispatcherMock.swift +++ b/Tests/RelayerTests/Mocks/DispatcherMock.swift @@ -1,5 +1,3 @@ -// - import Foundation @testable import WalletConnectRelay diff --git a/Tests/RelayerTests/Mocks/ED25519DIDKeyFactoryMock.swift b/Tests/RelayerTests/Mocks/ED25519DIDKeyFactoryMock.swift new file mode 100644 index 000000000..62d1682ad --- /dev/null +++ b/Tests/RelayerTests/Mocks/ED25519DIDKeyFactoryMock.swift @@ -0,0 +1,10 @@ +import WalletConnectKMS +@testable import WalletConnectRelay +import Foundation + +struct ED25519DIDKeyFactoryMock: ED25519DIDKeyFactory { + var did: String! + func make(pubKey: Data) -> String { + return did + } +} diff --git a/Tests/RelayerTests/Mocks/EdDSASignerMock.swift b/Tests/RelayerTests/Mocks/EdDSASignerMock.swift new file mode 100644 index 000000000..b7ca50718 --- /dev/null +++ b/Tests/RelayerTests/Mocks/EdDSASignerMock.swift @@ -0,0 +1,11 @@ +import Foundation +@testable import WalletConnectRelay + +class EdDSASignerMock: JWTSigning { + var alg: String = "EdDSA" + var signature: String! + + func sign(header: String, claims: String) throws -> String { + return signature + } +} diff --git a/Tests/RelayerTests/RelayClientEndToEndTests.swift b/Tests/RelayerTests/RelayClientEndToEndTests.swift index 43a59629d..0a15b2fa1 100644 --- a/Tests/RelayerTests/RelayClientEndToEndTests.swift +++ b/Tests/RelayerTests/RelayClientEndToEndTests.swift @@ -8,7 +8,7 @@ import Starscream final class RelayClientEndToEndTests: XCTestCase { - let relayHost = "beta.relay.walletconnect.com" + let relayHost = "dev.relay.walletconnect.com" let projectId = "8ba9ee138960775e5231b70cc5ef1c3a" private var publishers = [AnyCancellable]()