diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8fcf7f7..85b69d1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,7 +1,4 @@ -# This workflow will build a Swift project -# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift - -name: Swift +name: PR on: pull_request: @@ -12,7 +9,7 @@ concurrency: cancel-in-progress: true jobs: - build: + test: runs-on: macos-13 diff --git a/Package.swift b/Package.swift index 61d3b48..b1a1609 100644 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,7 @@ let package = Package( dependencies: [ .package(url: "https://github.com/swift-libp2p/swift-multibase.git", .upToNextMajor(from: "0.0.1")), .package(url: "https://github.com/swift-libp2p/swift-bases.git", .upToNextMajor(from: "0.0.3")), - .package(url: "https://github.com/beatt83/didcore-swift.git", .upToNextMinor(from: "1.0.1")) + .package(url: "https://github.com/beatt83/didcore-swift.git", .upToNextMinor(from: "1.1.0")) ], targets: [ .target( diff --git a/Sources/PeerDID/Models/PeerDID.swift b/Sources/PeerDID/Models/PeerDID.swift index b68a8f6..1b4be11 100644 --- a/Sources/PeerDID/Models/PeerDID.swift +++ b/Sources/PeerDID/Models/PeerDID.swift @@ -74,10 +74,10 @@ public struct PeerDID { .map { String($0.dropFirst()) } } - public var algo2Service: String? { - guard algo == ._2 else { return nil } + public var algo2Service: [String] { + guard algo == ._2 else { return [] } return allAttributes .filter { $0.hasPrefix(Algorithm.Algo2Prefix.service.rawValue) } - .first.map { String($0.dropFirst()) } + .map { String($0.dropFirst()) } } } diff --git a/Sources/PeerDID/PeerDID/PeerDIDHelper+ResolveAlgo2.swift b/Sources/PeerDID/PeerDID/PeerDIDHelper+ResolveAlgo2.swift index 379a18e..e8bc61b 100644 --- a/Sources/PeerDID/PeerDID/PeerDIDHelper+ResolveAlgo2.swift +++ b/Sources/PeerDID/PeerDID/PeerDIDHelper+ResolveAlgo2.swift @@ -13,7 +13,7 @@ extension PeerDIDHelper { public func resolvePeerDIDAlgo2(peerDID: PeerDID, format: VerificationMaterialFormat) throws -> DIDDocument { let authenticationKeys = peerDID.algo2AuthenticationKeys let agreementKeys = peerDID.algo2KeyAgreementKeys - let service = peerDID.algo2Service + let services = peerDID.algo2Service var keyIdCount = 1 let authenticationVerificationMethods = try authenticationKeys @@ -40,12 +40,14 @@ extension PeerDIDHelper { return method } - let documentService = try service.map { try decodedPeerDIDService(did: peerDID.string, serviceString: $0) } + let documentServices = try services.enumerated().map { + try decodedPeerDIDService(did: peerDID.string, serviceString: $0.element, index: $0.offset) + } return DIDDocument( id: peerDID.string, verificationMethods: authenticationVerificationMethods + agreementVerificationMethods, - services: documentService ?? [] + services: documentServices ) } } diff --git a/Sources/PeerDID/PeerDID/PeerDIDHelper.swift b/Sources/PeerDID/PeerDID/PeerDIDHelper.swift index 0478a6b..3dc187d 100644 --- a/Sources/PeerDID/PeerDID/PeerDIDHelper.swift +++ b/Sources/PeerDID/PeerDID/PeerDIDHelper.swift @@ -34,8 +34,8 @@ public struct PeerDIDHelper { .map { try PeerDIDHelper().createMultibaseEncnumbasis(material: $0) } .map { "V\($0)" } - let encodedServiceStr = try PeerDIDHelper().encodePeerDIDServices(services: services) - let methodId = (["2"] + encodedAgreementsStrings + encodedAuthenticationsStrings + [encodedServiceStr]) + let encodedServiceStrs = try services.map { try PeerDIDHelper().encodePeerDIDServices(service: $0) } + let methodId = (["2"] + encodedAgreementsStrings + encodedAuthenticationsStrings + encodedServiceStrs) .compactMap { $0 } .joined(separator: ".") @@ -72,7 +72,7 @@ public extension PeerDIDHelper { ecnumbasis: String, format: VerificationMaterialFormat ) throws -> PeerDIDVerificationMaterial { - let (base, decodedMultibase) = try BaseEncoding.decode(ecnumbasis) + let (_, decodedMultibase) = try BaseEncoding.decode(ecnumbasis) let (codec, decodedMulticodec) = try Multicodec().fromMulticodec(value: decodedMultibase) try decodedMulticodec.validateKeyLength() @@ -130,6 +130,43 @@ extension PeerDIDHelper { struct PeerDIDService: Codable { + struct ServiceEndpoint: Codable { + let uri: String + let r: [String]? // Routing keys + let a: [String]? // Accept + } + + let t: String // Type + let s: ServiceEndpoint // Service Endpoint + + init(from: DIDDocument.Service) throws { + self.t = from.type + guard + let dic = from.serviceEndpoint.value as? [String: Any], + let uri = dic["uri"] as? String + else { + throw PeerDIDError.invalidPeerDIDService + } + self.s = .init( + uri: uri, + r: dic["routing_keys"] as? [String], + a: dic["accept"] as? [String] + ) + } + + func toDIDDocumentService(did: String, index: Int) throws -> DIDDocument.Service { + return .init( + id: "\(did)#\(t.lowercased())-\(index+1)", + type: t, + serviceEndpoint: AnyCodable( + dictionaryLiteral: ("uri", s.uri), ("accept", s.a ?? []), ("routing_keys", s.r ?? []) + ) + ) + } + } + + struct PeerDIDServiceLegacy: Codable { + let t: String // Type let s: String // Service Endpoint let r: [String]? // Routing keys @@ -144,79 +181,37 @@ extension PeerDIDHelper { init(from: DIDDocument.Service) throws { self.t = from.type - self.s = try from.serviceEndpoint.getJsonString() ?? "" - self.r = from.routingKeys - self.a = from.accept + guard + let uri = from.serviceEndpoint.value as? String + else { + throw PeerDIDError.invalidPeerDIDService + } + self.s = uri + self.r = [] + self.a = [] } func toDIDDocumentService(did: String, index: Int) throws -> DIDDocument.Service { - let serviceEndpoint: DIDDocument.Service.ServiceEndpoint - if let s = try? parseServiceEndpoint(serviceEndpoint: s) { - serviceEndpoint = s - } else { - serviceEndpoint = try parseServiceEndpoint(serviceEndpoint: "\"\(s)\"") - } + var serviceEndpoint: [String: Any] = ["uri": s] + a.map { serviceEndpoint["accept"] = $0 } + r.map { serviceEndpoint["routing_keys"] = $0 } + return .init( id: "\(did)#\(t.lowercased())-\(index+1)", type: t, - serviceEndpoint: serviceEndpoint, - routingKeys: r, - accept: a + serviceEndpoint: AnyCodable(dictionaryLiteral: ("uri", s), ("accept", a ?? []), ("routing_keys", r ?? [])) ) } - - private func parseServiceEndpoint(serviceEndpoint: String) throws -> DIDDocument.Service.ServiceEndpoint { - guard let serviceData = serviceEndpoint.data(using: .utf8) else { - throw PeerDIDError.somethingWentWrong - } - return try JSONDecoder().decode(DIDDocument.Service.ServiceEndpoint.self, from: serviceData) - } - - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: PeerDIDHelper.PeerDIDService.CodingKeys.self) - try container.encode(self.s, forKey: PeerDIDHelper.PeerDIDService.CodingKeys.s) - try container.encode(self.r, forKey: PeerDIDHelper.PeerDIDService.CodingKeys.r) - try container.encodeIfPresent(self.a, forKey: PeerDIDHelper.PeerDIDService.CodingKeys.a) - try container.encodeIfPresent(self.t, forKey: PeerDIDHelper.PeerDIDService.CodingKeys.t) - } - - enum CodingKeys: CodingKey { - case t - case s - case r - case a - } - - init(from decoder: Decoder) throws { - let container: KeyedDecodingContainer = try decoder.container(keyedBy: PeerDIDHelper.PeerDIDService.CodingKeys.self) - self.t = try container.decode(String.self, forKey: PeerDIDHelper.PeerDIDService.CodingKeys.t) - self.s = try container.decode(String.self, forKey: PeerDIDHelper.PeerDIDService.CodingKeys.s) - self.r = try container.decodeIfPresent([String].self, forKey: PeerDIDHelper.PeerDIDService.CodingKeys.r) - self.a = try container.decodeIfPresent([String].self, forKey: PeerDIDHelper.PeerDIDService.CodingKeys.a) - } } - public func encodePeerDIDServices(services: [DIDDocument.Service]) throws -> String? { - guard !services.isEmpty else { return nil } + public func encodePeerDIDServices(service: DIDDocument.Service) throws -> String { let encoder = JSONEncoder.peerDIDEncoder() - let parsingStr: String - - if services.count > 1 { - let peerDidServices = try services.map { try PeerDIDService(from: $0) } - guard let jsonStr = String(data: try encoder.encode(peerDidServices), encoding: .utf8) else { - throw PeerDIDError.somethingWentWrong - } - parsingStr = jsonStr - } else if let service = services.first { - let peerDIDService = try PeerDIDService(from: service) - guard let jsonStr = String(data: try encoder.encode(peerDIDService), encoding: .utf8) else { - throw PeerDIDError.somethingWentWrong - } - parsingStr = jsonStr - } else { - throw PeerDIDError.somethingWentWrong // This should never happen since we handle all the cases + let peerDIDService = try PeerDIDService(from: service) + guard let jsonStr = String(data: try encoder.encode(peerDIDService), encoding: .utf8) else { + throw PeerDIDError.somethingWentWrong } + let parsingStr = jsonStr let parsedService = parsingStr .replacingOccurrences(of: "[\n\t\\s]*", with: "", options: .regularExpression) @@ -229,7 +224,7 @@ extension PeerDIDHelper { return "S\(encodedService)" } - public func decodedPeerDIDService(did: String, serviceString: String) throws -> [DIDDocument.Service] { + public func decodedPeerDIDService(did: String, serviceString: String, index: Int) throws -> DIDDocument.Service { guard let serviceBase64Data = Data(base64URLEncoded: serviceString), let serviceStr = String(data: serviceBase64Data, encoding: .utf8) @@ -246,20 +241,17 @@ extension PeerDIDHelper { let decoder = JSONDecoder() if let service = try? decoder.decode( - PeerDIDService.self, + PeerDIDServiceLegacy.self, from: peerDIDServiceData ) { - return [try service.toDIDDocumentService(did: did, index: 0)] + return try service.toDIDDocumentService(did: did, index: index) } else { - let services = try decoder.decode( - [PeerDIDService].self, + let service = try decoder.decode( + PeerDIDService.self, from: peerDIDServiceData ) - - return try Dictionary(grouping: services, by: \.t) - .mapValues { try $0.enumerated().map { try $0.element.toDIDDocumentService(did: did, index: $0.offset) } } - .flatMap { $0.value } + return try service.toDIDDocumentService(did: did, index: index) } } } @@ -283,7 +275,7 @@ extension DIDDocument.VerificationMethod { ) } } -extension DIDDocument.Service.ServiceEndpoint { +extension DIDDocument.Service { func getJsonString() throws -> String? { let encoder = JSONEncoder.peerDIDEncoder() diff --git a/Tests/PeerDIDTests/CreatePeerDIDAlgo2Tests.swift b/Tests/PeerDIDTests/CreatePeerDIDAlgo2Tests.swift index 0161fc4..c05026e 100644 --- a/Tests/PeerDIDTests/CreatePeerDIDAlgo2Tests.swift +++ b/Tests/PeerDIDTests/CreatePeerDIDAlgo2Tests.swift @@ -67,9 +67,8 @@ final class CreatePeerDIDAlgo2Tests: XCTestCase { let validService = DIDDocument.Service( id: "test", type: "DIDCommMessaging", - serviceEndpoint: .string("https://example.com/endpoint"), - routingKeys: ["did:example:somemediator#somekey"], - accept: nil + serviceEndpoint: AnyCodable( + dictionaryLiteral: ("uri","https://example.com/endpoint"), ("routing_keys", ["did:example:somemediator#somekey"])) ) func testCreatePeerDIDAlgo2Base58() throws { @@ -79,12 +78,12 @@ final class CreatePeerDIDAlgo2Tests: XCTestCase { services: [validService] ) - XCTAssertEqual("did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il0sInMiOiJcImh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnRcIiIsInQiOiJkbSJ9", peerDID.string) + XCTAssertEqual("did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ", peerDID.string) XCTAssertTrue(peerDID.algo2KeyAgreementKeys.contains("z6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc")) XCTAssertTrue(peerDID.algo2AuthenticationKeys.contains("z6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V")) XCTAssertTrue(peerDID.algo2AuthenticationKeys.contains("z6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg")) - XCTAssertTrue(peerDID.algo2Service?.contains("eyJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il0sInMiOiJcImh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnRcIiIsInQiOiJkbSJ9") ?? false) + XCTAssertTrue(peerDID.algo2Service.contains("eyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ")) } func testCreatePeerDIDAlgo2Multibase() throws { @@ -94,12 +93,12 @@ final class CreatePeerDIDAlgo2Tests: XCTestCase { services: [validService] ) - XCTAssertEqual("did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il0sInMiOiJcImh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnRcIiIsInQiOiJkbSJ9", peerDID.string) + XCTAssertEqual("did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ", peerDID.string) XCTAssertTrue(peerDID.algo2KeyAgreementKeys.contains("z6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc")) XCTAssertTrue(peerDID.algo2AuthenticationKeys.contains("z6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V")) XCTAssertTrue(peerDID.algo2AuthenticationKeys.contains("z6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg")) - XCTAssertTrue(peerDID.algo2Service?.contains("eyJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il0sInMiOiJcImh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnRcIiIsInQiOiJkbSJ9") ?? false) + XCTAssertTrue(peerDID.algo2Service.contains("eyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ")) } func testCreatePeerDIDAlgo2JWK() throws { @@ -109,12 +108,12 @@ final class CreatePeerDIDAlgo2Tests: XCTestCase { services: [validService] ) - XCTAssertEqual("did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il0sInMiOiJcImh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnRcIiIsInQiOiJkbSJ9", peerDID.string) + XCTAssertEqual("did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.Vz6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ", peerDID.string) XCTAssertTrue(peerDID.algo2KeyAgreementKeys.contains("z6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc")) XCTAssertTrue(peerDID.algo2AuthenticationKeys.contains("z6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V")) XCTAssertTrue(peerDID.algo2AuthenticationKeys.contains("z6MkgoLTnTypo3tDRwCkZXSccTPHRLhF4ZnjhueYAFpEX6vg")) - XCTAssertTrue(peerDID.algo2Service?.contains("eyJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il0sInMiOiJcImh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnRcIiIsInQiOiJkbSJ9") ?? false) + XCTAssertTrue(peerDID.algo2Service.contains("eyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ")) } func testCreatePeerDIDAlgo2MultipleServices() throws { @@ -124,9 +123,9 @@ final class CreatePeerDIDAlgo2Tests: XCTestCase { services: [validService, validService] ) - XCTAssertEqual("did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.SW3siciI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJzIjoiXCJodHRwczovL2V4YW1wbGUuY29tL2VuZHBvaW50XCIiLCJ0IjoiZG0ifSx7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwicyI6IlwiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludFwiIiwidCI6ImRtIn1d", peerDID.string) + XCTAssertEqual("did:peer:2.Ez6LSbysY2xFMRpGMhb7tFTLMpeuPRaqaWM1yECx2AtzE3KCc.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ", peerDID.string) - XCTAssertTrue(peerDID.algo2Service?.contains("W3siciI6WyJkaWQ6ZXhhbXBsZTpzb21lbWVkaWF0b3Ijc29tZWtleSJdLCJzIjoiXCJodHRwczovL2V4YW1wbGUuY29tL2VuZHBvaW50XCIiLCJ0IjoiZG0ifSx7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwicyI6IlwiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludFwiIiwidCI6ImRtIn1d") ?? false) + XCTAssertTrue(peerDID.algo2Service.contains("eyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ")) } func testCreatePeerDIDAlgo2NoServices() throws { diff --git a/Tests/PeerDIDTests/EncodeServiceTests.swift b/Tests/PeerDIDTests/EncodeServiceTests.swift index ff02343..1ed983c 100644 --- a/Tests/PeerDIDTests/EncodeServiceTests.swift +++ b/Tests/PeerDIDTests/EncodeServiceTests.swift @@ -13,73 +13,44 @@ final class EncodeEcnumbasisTests: XCTestCase { func testEncodeService() throws { let service = DIDDocument.Service( - id: "test", + id: "did:test:abc#didcommmessaging-1", type: "DIDCommMessaging", - serviceEndpoint: .string("https://example.com/endpoint"), - routingKeys: ["did:example:somemediator#somekey"], - accept: ["didcomm/v2", "didcomm/aip2;env=rfc587"] + serviceEndpoint: AnyCodable( + dictionaryLiteral: ("uri","https://example.com/endpoint"), ("routing_keys", ["did:example:somemediator#somekey"]), ("accept", ["didcomm/v2", "didcomm/aip2;env=rfc587"])) ) - let expect = "SeyJhIjpbImRpZGNvbW0vdjIiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzU4NyJdLCJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il0sInMiOiJcImh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnRcIiIsInQiOiJkbSJ9" + let expect = "SeyJzIjp7ImEiOlsiZGlkY29tbS92MiIsImRpZGNvbW0vYWlwMjtlbnY9cmZjNTg3Il0sInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ" - XCTAssertEqual(expect, try PeerDIDHelper().encodePeerDIDServices(services: [service])) + XCTAssertEqual(expect, try PeerDIDHelper().encodePeerDIDServices(service: service)) } func testDecodeService() throws { let did = "did:test:abc" let service = "eyJ0IjoiZG0iLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCIsInIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwiYSI6WyJkaWRjb21tL3YyIiwiZGlkY29tbS9haXAyO2Vudj1yZmM1ODciXX0" - let expected = [DIDDocument.Service( - id: "\(did)#didcommmessaging-1", + let expected = DIDDocument.Service( + id: "did:test:abc#didcommmessaging-1", type: "DIDCommMessaging", - serviceEndpoint: .string("https://example.com/endpoint"), - routingKeys: ["did:example:somemediator#somekey"], - accept: ["didcomm/v2", "didcomm/aip2;env=rfc587"] - )] + serviceEndpoint: AnyCodable( + dictionaryLiteral: ("uri","https://example.com/endpoint"), ("routing_keys", ["did:example:somemediator#somekey"]), ("accept", ["didcomm/v2", "didcomm/aip2;env=rfc587"])) + ) - XCTAssertEqual(expected, try PeerDIDHelper().decodedPeerDIDService(did: did, serviceString: service)) + XCTAssertEqual(expected, try PeerDIDHelper().decodedPeerDIDService(did: did, serviceString: service, index: 0)) } } extension DIDDocument.Service: Equatable { public static func == (lhs: DIDDocument.Service, rhs: DIDDocument.Service) -> Bool { - lhs.id == rhs.id && - lhs.type == rhs.type && - lhs.serviceEndpoint == rhs.serviceEndpoint && - lhs.routingKeys == rhs.routingKeys && - lhs.accept == rhs.accept - } -} - -extension DIDDocument.Service.ServiceEndpoint: Equatable { - public static func == (lhs: DIDDocument.Service.ServiceEndpoint, rhs: DIDDocument.Service.ServiceEndpoint) -> Bool { - switch (lhs, rhs) { - case let (.string(lhsValue), .string(rhsValue)): - return lhsValue == rhsValue - case let (.set(lhsValue), .set(rhsValue)): - return lhsValue == rhsValue - case let (.map(lhsValue), .map(rhsValue)): - return lhsValue == rhsValue - case let (.combo(lhsValue), .combo(rhsValue)): - return lhsValue == rhsValue - default: - return false - } - } -} - -extension DIDDocument.Service.ServiceEndpoint.EndpointElement: Equatable { - public static func == ( - lhs: DIDDocument.Service.ServiceEndpoint.EndpointElement, - rhs: DIDDocument.Service.ServiceEndpoint.EndpointElement - ) -> Bool { - switch (lhs, rhs) { - case let (.mapValue(lhsValue), .mapValue(rhsValue)): - return lhsValue == rhsValue - case let (.stringValue(lhsValue), .stringValue(rhsValue)): - return lhsValue == rhsValue - default: + guard + let lhsS = lhs.serviceEndpoint.value as? [String: Any], + let rhsS = rhs.serviceEndpoint.value as? [String: Any] + else { return false } + return lhs.id == rhs.id && + lhs.type == rhs.type && + (lhsS["uri"] as! String) == (rhsS["uri"] as! String) && + (lhsS["accept"] as? [String]) == (rhsS["accept"] as? [String]) && + (lhsS["routing_keys"] as? [String]) == (rhsS["routing_keys"] as? [String]) } } diff --git a/Tests/PeerDIDTests/ResolvePeerDIDAlgo2Tests.swift b/Tests/PeerDIDTests/ResolvePeerDIDAlgo2Tests.swift index e3e6983..69215ce 100644 --- a/Tests/PeerDIDTests/ResolvePeerDIDAlgo2Tests.swift +++ b/Tests/PeerDIDTests/ResolvePeerDIDAlgo2Tests.swift @@ -18,7 +18,8 @@ final class ReselvePeerDIDAlgo2Tests: XCTestCase { let validDid2Services = "did:peer:2" + ".Ez6LSpSrLxbAhg2SHwKk7kwpsH7DM7QjFS5iK6qP87eViohud" + ".Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V" + - ".SW3sidCI6ImRtIiwicyI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il19LHsidCI6ImV4YW1wbGUiLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludDIiLCJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5MiJdLCJhIjpbImRpZGNvbW0vdjIiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzU4NyJdfV0" + ".SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ" + + ".SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ" func testResolvePeerDIDAlgo2Base58() throws { let did = try PeerDID(didString: validDid) @@ -84,8 +85,9 @@ final class ReselvePeerDIDAlgo2Tests: XCTestCase { let encoder = JSONEncoder.peerDIDEncoder() let encodedDocument = String(data: try encoder.encode(document), encoding: .utf8)! + print(encodedDocument) - XCTAssertTrue(encodedDocument.contains("\"id\":\"did:peer:2.Ez6LSpSrLxbAhg2SHwKk7kwpsH7DM7QjFS5iK6qP87eViohud.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.SW3sidCI6ImRtIiwicyI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il19LHsidCI6ImV4YW1wbGUiLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludDIiLCJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5MiJdLCJhIjpbImRpZGNvbW0vdjIiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzU4NyJdfV0#didcommmessaging-1\"")) - XCTAssertTrue(encodedDocument.contains("\"id\":\"did:peer:2.Ez6LSpSrLxbAhg2SHwKk7kwpsH7DM7QjFS5iK6qP87eViohud.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.SW3sidCI6ImRtIiwicyI6Imh0dHBzOi8vZXhhbXBsZS5jb20vZW5kcG9pbnQiLCJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5Il19LHsidCI6ImV4YW1wbGUiLCJzIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludDIiLCJyIjpbImRpZDpleGFtcGxlOnNvbWVtZWRpYXRvciNzb21la2V5MiJdLCJhIjpbImRpZGNvbW0vdjIiLCJkaWRjb21tL2FpcDI7ZW52PXJmYzU4NyJdfV0#example-1\"")) + XCTAssertTrue(encodedDocument.contains("\"id\":\"did:peer:2.Ez6LSpSrLxbAhg2SHwKk7kwpsH7DM7QjFS5iK6qP87eViohud.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ#didcommmessaging-1\"")) + XCTAssertTrue(encodedDocument.contains("\"id\":\"did:peer:2.Ez6LSpSrLxbAhg2SHwKk7kwpsH7DM7QjFS5iK6qP87eViohud.Vz6MkqRYqQiSgvZQdnBytw86Qbs2ZWUkGv22od935YF4s8M7V.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ.SeyJzIjp7InIiOlsiZGlkOmV4YW1wbGU6c29tZW1lZGlhdG9yI3NvbWVrZXkiXSwidXJpIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9lbmRwb2ludCJ9LCJ0IjoiZG0ifQ#didcommmessaging-2\"")) } }