Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chat Sample app #76

Merged
merged 2 commits into from
Mar 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AtalaPrismSDK/Castor/Sources/CastorImpl+Public.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ extension CastorImpl: Castor {
/// - Returns: The DID Document associated with the DID
/// - Throws: An error if the DID is invalid or the document cannot be retrieved
public func resolveDID(did: DID) async throws -> DIDDocument {
logger.info(message: "Trying to resolve DID", metadata: [
logger.debug(message: "Trying to resolve DID", metadata: [
.maskedMetadataByLevel(key: "DID", value: did.string, level: .debug)
])

Expand Down
2 changes: 1 addition & 1 deletion AtalaPrismSDK/Domain/Sources/BBs/Mercury.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public protocol Mercury {
/// - Returns: The response data
/// - Throws: An error if the message is invalid or the send operation fails
@discardableResult
func sendMessage(msg: Message) async throws -> Data?
func sendMessage(_ msg: Message) async throws -> Data?

/// sendMessageParseMessage asynchronously sends a given message and returns the response message object. This function may throw an error if the message is invalid, the send operation fails, or the response message is invalid.
///
Expand Down
19 changes: 14 additions & 5 deletions AtalaPrismSDK/Domain/Sources/Models/Errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ public enum UnknownError: UnknownPrismError {
return errors
}
}

public var errorDescription: String? { message }
}

extension UnknownError: Equatable {
Expand Down Expand Up @@ -143,6 +145,10 @@ public enum CommonError: KnownPrismError {
return message
}
}

public var description: String {
"Code \(code): \(message)"
}
}

extension CommonError: Equatable {
Expand Down Expand Up @@ -380,11 +386,11 @@ public enum MercuryError: KnownPrismError {

/**
An error case representing a DIDComm error.

- Parameters:
- msg: The message describing the error.
*/
case didcommError(msg: String)
- underlyingErrors: An array of underlying errors that may have contributed to this error, if provided.
*/
case didcommError(msg: String, underlyingErrors: [Error]? = nil)

/// The error code returned by the server.
public var code: Int {
Expand Down Expand Up @@ -427,8 +433,11 @@ public enum MercuryError: KnownPrismError {
return "While decoding a message, a message attachment was found without \"id\" this is invalid"
case .messageInvalidBodyDataError:
return "While decoding a message, a body was found to be invalid while decoding"
case .didcommError(let msg):
return "DIDComm error as ocurred with message: \(msg)"
case let .didcommError(msg, errors):
let errorsMessages = errors.map {
"\n" + $0.map { $0.localizedDescription }.joined(separator: "\n")
} ?? ""
return "DIDComm error as ocurred with message: \(msg)\nErrors: \(errorsMessages)"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public struct AttachmentDescriptor {
/// - byteCount: The byte count associated with the attachment.
/// - description: The description associated with the attachment.
public init(
id: String,
id: String = UUID().uuidString,
mediaType: String? = nil,
data: AttachmentData,
filename: [String]? = nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,26 @@ class DIDCommSecretsResolverWrapper {
let pluto: Pluto
let castor: Castor
let logger: PrismLogger
@Published var availableSecrets = [Domain.Secret]()
var cancellables = [AnyCancellable]()

init(apollo: Apollo, pluto: Pluto, castor: Castor, logger: PrismLogger) {
self.apollo = apollo
self.pluto = pluto
self.castor = castor
self.logger = logger

startUpdating()
}

private func startUpdating() {
pluto
fileprivate func getListOfAllSecrets() async throws -> [Domain.Secret] {
try await pluto
.getAllPeerDIDs()
.tryMap { [weak self] in
.first()
.tryMap {
try $0.map { did, privateKeys, _ in
try self?.parsePrivateKeys(did: did, privateKeys: privateKeys)
try self.parsePrivateKeys(did: did, privateKeys: privateKeys)
}
}
.map { $0.compactMap { $0 }.flatMap { $0 } }
.replaceError(with: [])
.assign(to: &$availableSecrets)
.first()
.await()
}

private func parsePrivateKeys(
Expand Down Expand Up @@ -68,45 +65,92 @@ extension DIDCommSecretsResolverWrapper: SecretsResolver {
secretid: String,
cb: OnGetSecretResult
) -> ErrorCode {
$availableSecrets
.first()
.map { $0.first { $0.id == secretid } }
.sink { [weak self] in
do {
try cb.success(result: $0.map { DIDCommxSwift.Secret(from: $0) })
} catch {
self?.logger.error(message: "Could not find secret", metadata: [
.publicMetadata(key: "SecretId", value: secretid),
.publicMetadata(key: "Error", value: error.localizedDescription)
])
}
Task {
do {
let secret = try await getListOfAllSecrets().first { $0.id == secretid }
try cb.success(result: secret.map { DIDCommxSwift.Secret(from: $0) })
} catch let error {
let mercuryError = MercuryError.didcommError(
msg: "Could not find secret \(secretid)",
underlyingErrors: [error]
)
logger.error(error: mercuryError)
}
.store(in: &cancellables)
}
// getListOfAllSecrets()
// .first()
// .map {
// $0.first { $0.id == secretid }
// }
// .sink { [weak self] in
// do {
// try cb.success(result: $0.map { DIDCommxSwift.Secret(from: $0) })
// } catch {
// self?.logger.error(message: "Could not find secret", metadata: [
// .publicMetadata(key: "SecretId", value: secretid),
// .publicMetadata(key: "Error", value: error.localizedDescription)
// ])
// }
// }
// .store(in: &cancellables)
return .success
}

func findSecrets(
secretids: [String],
cb: OnFindSecretsResult
) -> ErrorCode {
$availableSecrets
.first()
.map {
$0
.filter { secretids.contains($0.id) }
.map { $0.id }
}
.sink { [weak self] in
do {
try cb.success(result: $0)
} catch {
self?.logger.error(message: "Could not find secrets", metadata: [
.publicMetadata(key: "SecretsIds", value: secretids.description),
.publicMetadata(key: "Error", value: error.localizedDescription)
])
Task {
do {
let secrets = try await getListOfAllSecrets()
.filter { secretids.contains($0.id) }
.map { $0.id }
let secretsSet = Set(secretids)
let resultsSet = Set(secrets)
let missingSecrets = secretsSet.subtracting(resultsSet)
if !missingSecrets.isEmpty {
logger.error(message:
"""
Could not find secrets the following secrets:\(missingSecrets.joined(separator: ", "))
"""
)
}
try cb.success(result: secrets)
} catch {
let mercuryError = MercuryError.didcommError(
msg: "Could not find secrets \(secretids.joined(separator: "\n"))",
underlyingErrors: [error]
)
logger.error(error: mercuryError)
}
.store(in: &cancellables)
}
// getListOfAllSecrets()
// .first()
// .map {
// $0
// .filter { secretids.contains($0.id) }
// .map { $0.id }
// }
// .sink { [weak self] in
// do {
// let secretsSet = Set(secretids)
// let resultsSet = Set($0)
// let missingSecrets = secretsSet.subtracting(resultsSet)
// if !missingSecrets.isEmpty {
// self?.logger.error(
// message:
//"""
//Could not find secrets the following secrets:\(missingSecrets.joined(separator: ", "))
//"""
// )
// }
// try cb.success(result: $0)
// } catch {
// let error = MercuryError.didcommError(msg: error.localizedDescription)
// self?.logger.error(error: error)
// }
// }
// .store(in: &cancellables)
return .success
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,19 @@ import Foundation
final class PackEncryptedOperation: OnPackEncryptedResult {
private let didcomm: DIDCommProtocol
private let logger: PrismLogger
private let message: Domain.Message
private var published = CurrentValueSubject<String?, Error>(nil)
private var cancellable: AnyCancellable?

init(didcomm: DIDCommProtocol, logger: PrismLogger) {
init(didcomm: DIDCommProtocol, message: Domain.Message, logger: PrismLogger) {
self.didcomm = didcomm
self.logger = logger
self.message = message
}

func packEncrypted(msg: Domain.Message) async throws -> String {
guard let fromDID = msg.from else { throw MercuryError.noSenderDIDSetError }
guard let toDID = msg.to else { throw MercuryError.noRecipientDIDSetError }
func packEncrypted() async throws -> String {
guard let fromDID = message.from else { throw MercuryError.noSenderDIDSetError }
guard let toDID = message.to else { throw MercuryError.noRecipientDIDSetError }

let result: String = try await withCheckedThrowingContinuation { [weak self] continuation in
guard let self else { return }
Expand All @@ -42,8 +44,12 @@ final class PackEncryptedOperation: OnPackEncryptedResult {
continuation.resume(returning: result)
})
do {
logger.debug(message: "Packing message \(message.piuri)", metadata: [
.maskedMetadataByLevel(key: "Sender", value: fromDID.string, level: .debug),
.maskedMetadataByLevel(key: "Receiver", value: toDID.string, level: .debug)
])
let status = didcomm.packEncrypted(
msg: try DIDCommxSwift.Message(domain: msg, mediaType: .contentTypePlain),
msg: try DIDCommxSwift.Message(domain: message, mediaType: .contentTypePlain),
to: toDID.string,
from: fromDID.string,
signBy: nil,
Expand All @@ -65,7 +71,7 @@ final class PackEncryptedOperation: OnPackEncryptedResult {
msg: "Unknown error on initializing pack encrypted function"
))
}
} catch let error {
} catch {
continuation.resume(throwing: MercuryError.didcommError(
msg: "Error on parsing Domain message to DIDComm library model: \(error.localizedDescription)"
))
Expand All @@ -80,19 +86,20 @@ final class PackEncryptedOperation: OnPackEncryptedResult {
}

func error(err: DIDCommxSwift.ErrorKind, msg: String) {
let error = MercuryError.didcommError(
msg: """
Error on trying to pack encrypted a message of type \(message.piuri): \(msg)
"""
)
logger.error(
message: "Packing message failed with error",
metadata: [
.publicMetadata(
key: "Error",
value: MercuryError
.didcommError(msg: msg)
.localizedDescription
value: error.errorDescription ?? ""
)
]
)
published.send(completion: .failure(MercuryError.didcommError(
msg: "Error on trying to pack encrypted a message: \(msg)"
)))
published.send(completion: .failure(error))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,45 @@ final class UnpackOperation: OnUnpackResult {
do {
let message: Domain.Message = try result.toDomain(castor: castor)
published.send(message)
} catch {
} catch let error as LocalizedError {
logger.error(
message: "Could not unpack message",
metadata: [
.publicMetadata(key: "Error", value: error.localizedDescription)
]
)
published.send(completion: .failure(MercuryError.didcommError(
msg: "Error on parsing DIDComm library model message to Domain message : \(error.localizedDescription)"
msg:
"""
Error on parsing DIDComm library model message to Domain message : \(error.errorDescription ?? "")
"""
)))
} catch {
published.send(completion: .failure(MercuryError.didcommError(
msg:
"""
Error on parsing DIDComm library model message to Domain message : \(error.localizedDescription)
"""
)))
}
}

func error(err: DIDCommxSwift.ErrorKind, msg: String) {
published.send(completion: .failure(MercuryError.didcommError(
msg: "Error on trying to unpack a message: \(msg)"
)))
let error = MercuryError.didcommError(
msg:
"""
Error on trying to unpack a message: \(msg)
"""
)
logger.error(
message: "Unpack message failed with error",
metadata: [
.publicMetadata(
key: "Error",
value: error.errorDescription ?? ""
)
]
)
published.send(completion: .failure(error))
}
}
Loading