• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hyperledger / identus-edge-agent-sdk-swift / 11461349631

22 Oct 2024 01:13PM UTC coverage: 42.668% (+0.05%) from 42.623%
11461349631

push

github

goncalo-frade-iohk
feat(edgeAgent): KID will be present on any signed JWTs

Signed-off-by: goncalo-frade-iohk <goncalo.frade@iohk.io>

53 of 77 new or added lines in 14 files covered. (68.83%)

2 existing lines in 1 file now uncovered.

5479 of 12841 relevant lines covered (42.67%)

99.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

56.25
/EdgeAgentSDK/EdgeAgent/Sources/DIDCommAgent/DIDCommAgent+Invitations.swift
1
import Core
2
import Domain
3
import Foundation
4

5
public extension DIDCommAgent {
6
    /// Enumeration representing the type of invitation
7
    enum InvitationType {
8
        /// Struct representing a Prism Onboarding invitation
9
        public struct PrismOnboarding {
10
            /// Sender of the invitation
11
            public let from: String
12
            /// Onboarding endpoint
13
            public let endpoint: URL
14
            /// The own DID of the user
15
            public let ownDID: DID
16
        }
17

18
        /// Case representing a Prism Onboarding invitation
19
        case onboardingPrism(PrismOnboarding)
20
        /// Case representing a DIDComm Out-of-Band invitation
21
        case onboardingDIDComm(OutOfBandInvitation)
22
        /// Case representing a DIDComm Connectionless Presentation
23
        case connectionlessPresentation(RequestPresentation)
24
        /// Case representing a DIDComm Connectionless Issuance
25
        case connectionlessIssuance(OfferCredential3_0)
26
    }
27

28
    /// Parses the given string as an Out-of-Band invitation
29
    /// - Parameter url: The string to parse
30
    /// - Returns: The parsed Out-of-Band invitation
31
    /// - Throws: `EdgeAgentError` if the string is not a valid URL
32
    func parseOOBInvitation(url: String) throws -> OutOfBandInvitation {
6✔
33
        if let base64url = Data(base64URLEncoded: url) {
6✔
34
            return try JSONDecoder.didComm().decode(OutOfBandInvitation.self, from: base64url)
4✔
35
        } else if let url = URL(string: url) {
4✔
36
            return try parseOOBInvitation(url: url)
2✔
37
        } else {
2✔
NEW
38
            throw CommonError.invalidURLError(url: url)
×
UNCOV
39
        }
×
UNCOV
40
    }
×
41

42
    /// Parses the given URL as an Out-of-Band invitation
43
    /// - Parameter url: The URL to parse
44
    /// - Returns: The parsed Out-of-Band invitation
45
    /// - Throws: `EdgeAgentError` if the URL is not a valid Out-of-Band invitation
46
    func parseOOBInvitation(url: URL) throws -> OutOfBandInvitation {
2✔
47
        return try DIDCommInvitationRunner(url: url).run()
2✔
48
    }
2✔
49

50
    /// Accepts a Prism Onboarding invitation and performs the onboarding process
51
    /// - Parameter invitation: The Prism Onboarding invitation to accept
52
    /// - Throws: `EdgeAgentError` if the onboarding process fails
53
    func acceptPrismInvitation(invitation: InvitationType.PrismOnboarding) async throws {
×
54
        struct SendDID: Encodable {
×
55
            let did: String
×
56
        }
×
57
        var request = URLRequest(url: invitation.endpoint)
×
58
        request.httpMethod = "POST"
×
59
        request.httpBody = try JSONEncoder().encode(SendDID(did: invitation.ownDID.string))
×
60
        request.setValue("application/json", forHTTPHeaderField: "content-type")
×
61
        do {
×
62
            let response = try await URLSession.shared.data(for: request)
×
63
            guard let urlResponse = response.1 as? HTTPURLResponse else {
×
64
                throw CommonError.invalidCoding(
×
65
                    message: "This should not happen cannot convert URLResponse to HTTPURLResponse"
×
66
                )
×
67
            }
×
68
            guard urlResponse.statusCode == 200 else {
×
69
                throw CommonError.httpError(
×
70
                    code: urlResponse.statusCode,
×
71
                    message: String(data: response.0, encoding: .utf8) ?? ""
×
72
                )
×
73
            }
×
74
        }
×
75
    }
×
76

77
    /// Parses the given string as an invitation
78
    /// - Parameter str: The string to parse
79
    /// - Returns: The parsed invitation
80
    /// - Throws: `EdgeAgentError` if the invitation is not a valid Prism or OOB type
81
    func parseInvitation(str: String) async throws -> InvitationType {
6✔
82
        if let prismOnboarding = try? await parsePrismInvitation(str: str) {
6✔
83
            return .onboardingPrism(prismOnboarding)
×
84
        } else if let oobMessage = try? parseOOBInvitation(url: str) {
6✔
85
            if let attachment = oobMessage.attachments?.first {
6✔
86
                let invitationType = try await parseAttachmentConnectionlessMessage(oob: oobMessage, attachment: attachment)
4✔
87
                switch invitationType {
4✔
88
                case .connectionlessPresentation(let message):
4✔
89
                    try await pluto.storeMessage(
2✔
90
                        message: message.makeMessage(),
2✔
91
                        direction: .received
2✔
92
                    ).first().await()
2✔
93
                case .connectionlessIssuance(let message):
4✔
94
                    try await pluto.storeMessage(
2✔
95
                        message: message.makeMessage(),
2✔
96
                        direction: .received
2✔
97
                    ).first().await()
2✔
98
                default:
4✔
99
                    break
×
100
                }
4✔
101
                return invitationType
4✔
102
            }
4✔
103
            return .onboardingDIDComm(oobMessage)
2✔
104
        }
6✔
105
        throw EdgeAgentError.unknownInvitationTypeError
×
106
    }
6✔
107

108
    /// Parses the given string as a Prism Onboarding invitation
109
    /// - Parameter str: The string to parse
110
    /// - Returns: The parsed Prism Onboarding invitation
111
    /// - Throws: `EdgeAgentError` if the string is not a valid Prism Onboarding invitation
112
    func parsePrismInvitation(
113
        str: String
114
    ) async throws -> InvitationType.PrismOnboarding {
6✔
115
        let prismOnboarding = try PrismOnboardingInvitation(jsonString: str)
6✔
116
        guard
6✔
117
            let url = URL(string: prismOnboarding.body.onboardEndpoint)
6✔
118
        else { throw CommonError.invalidURLError(url: prismOnboarding.body.onboardEndpoint) }
6✔
119

6✔
120
        let ownDID = try await createNewPeerDID(
6✔
121
            services: [.init(
6✔
122
                id: "#didcomm-1",
6✔
123
                type: ["DIDCommMessaging"],
6✔
124
                serviceEndpoint: [.init(
6✔
125
                    uri: "https://localhost:8080/didcomm"
6✔
126
                )]
6✔
127
            )],
6✔
128
            updateMediator: false
6✔
129
        )
6✔
130

6✔
131
        return .init(
6✔
132
            from: prismOnboarding.body.from,
6✔
133
            endpoint: url,
6✔
134
            ownDID: ownDID
6✔
135
        )
6✔
136
    }
6✔
137

138
    /// Accepts an Out-of-Band (DIDComm) invitation and establishes a new connection
139
    /// - Parameter invitation: The Out-of-Band invitation to accept
140
    /// - Throws: `EdgeAgentError` if there is no mediator available or other errors occur during the acceptance process
141
    func acceptDIDCommInvitation(invitation: OutOfBandInvitation) async throws {
×
142
        guard
×
143
            let connectionManager
×
144
        else { throw EdgeAgentError.noMediatorAvailableError }
×
145
        logger.info(message: "Start accept DIDComm invitation")
×
146
        let ownDID = try await createNewPeerDID(updateMediator: true)
×
147

×
148
        logger.info(message: "Sending DIDComm Connection message")
×
149

×
150
        let pair = try await DIDCommConnectionRunner(
×
151
            invitationMessage: invitation,
×
152
            pluto: pluto,
×
153
            ownDID: ownDID,
×
154
            connection: connectionManager
×
155
        ).run()
×
156
        try await connectionManager.addConnection(pair)
×
157
    }
×
158

159
    private func parseAttachmentConnectionlessMessage(
160
        oob: OutOfBandInvitation,
161
        attachment: AttachmentDescriptor
162
    ) async throws -> InvitationType {
4✔
163
        let newDID = try await createNewPeerDID(updateMediator: true)
4✔
164
        switch attachment.data {
4✔
165
        case let value as AttachmentJsonData:
4✔
166
            let normalizeJson = try JSONEncoder.didComm().encode(value.json)
4✔
167
            let message = try JSONDecoder.didComm().decode(Message.self, from: normalizeJson)
4✔
168
            if let request = try? RequestPresentation(fromMessage: message, toDID: newDID) {
4✔
169
                return .connectionlessPresentation(request)
2✔
170
            }
2✔
171
            else if let offer = try? OfferCredential3_0(fromMessage: message, toDID: newDID){
2✔
172
                return .connectionlessIssuance(offer)
2✔
173
            }
2✔
174
            return .onboardingDIDComm(oob)
×
175

4✔
176
        case let value as AttachmentBase64:
4✔
177
            let message = try JSONDecoder.didComm().decode(Message.self, from: try value.decoded())
×
178
            if let request = try? RequestPresentation(fromMessage: message, toDID: newDID) {
×
179
                return .connectionlessPresentation(request)
×
180
            }
×
181
            else if let offer = try? OfferCredential3_0(fromMessage: message, toDID: newDID){
×
182
                return .connectionlessIssuance(offer)
×
183
            }
×
184
            return .onboardingDIDComm(oob)
×
185
        default:
4✔
186
            return .onboardingDIDComm(oob)
×
187
        }
4✔
188
    }
4✔
189
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc