Skip to content
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
4 changes: 2 additions & 2 deletions Vault/Sources/CryptoEngine/Helpers/BlockExporter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public struct BlockExporter {
/// Generate the next block.
///
/// - Returns: `nil` when there are no more blocks.
public mutating func next() throws -> Data? {
public mutating func next() throws(HeaderTooLargeError) -> Data? {
defer { currentBlockNumber += 1 }

let header = try makeHeader(blockNumber: currentBlockNumber)
Expand All @@ -50,7 +50,7 @@ public struct BlockExporter {
return header + payload.subdata(in: blockRange)
}

private func makeHeader(blockNumber: Int) throws -> Data {
private func makeHeader(blockNumber: Int) throws(HeaderTooLargeError) -> Data {
let context = BlockContext(blockNumber: blockNumber)
let header = blockHeader?(context) ?? Data()
guard header.count < maxBlockSize else {
Expand Down
4 changes: 2 additions & 2 deletions Vault/Sources/CryptoEngine/Key Derivation/KeyDeriver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public protocol KeyDeriver<Key>: Sendable {
public struct FailingKeyDeriver< let bytes: Int>: KeyDeriver {
public init() {}

struct KeyDeriverError: Error {}
public func key(password _: Data, salt _: Data) throws -> KeyData<bytes> {
public struct KeyDeriverError: Error {}
public func key(password _: Data, salt _: Data) throws(KeyDeriverError) -> KeyData<bytes> {
throw KeyDeriverError()
}

Expand Down
2 changes: 1 addition & 1 deletion Vault/Sources/FoundationExtensions/KeyData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ public struct KeyData< let bytes: Int>: Equatable, Hashable, Sendable {

public struct LengthError: Error {}

public init(data: Data) throws {
public init(data: Data) throws(LengthError) {
guard data.count == bytes else { throw LengthError() }
self.data = data
}
Expand Down
15 changes: 9 additions & 6 deletions Vault/Sources/FoundationExtensions/MappedError.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import Foundation

@inlinable
public func withMappedError<T>(body: () throws -> T, error: (any Error) -> some Error) throws -> T {
try Result {
try body()
}.mapError {
error($0)
}.get()
public func withMappedError<T, Failure: Error>(
body: () throws -> T,
error mapError: (any Error) -> Failure,
) throws(Failure) -> T {
do {
return try body()
} catch {
throw mapError(error)
}
}

/// Catches an error and returns the error type.
Expand Down
14 changes: 9 additions & 5 deletions Vault/Sources/FoundationExtensions/SemVer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@ public struct SemVer: Equatable, Hashable, Sendable {
self.patch = patch
}

struct ParseError: Error {
var reason: String
public struct ParseError: Error {
public let reason: String
}

public init(string: String) throws {
public init(string: String) throws(ParseError) {
let values = string.split(separator: ".")
guard values.count == 3 else {
throw ParseError(reason: "Bad number of SemVer components")
}
let ints = try values.map {
if let i = Int($0) { i } else { throw ParseError(reason: "Component is not a number.") }
var ints: [Int] = []
for value in values {
guard let int = Int(value) else {
throw ParseError(reason: "Component is not a number.")
}
ints.append(int)
}
major = ints[0]
minor = ints[1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ public final class VaultBackupDecryptor {

/// Throws decryption error if fails.
/// Performs no other validation.
public func verifyCanDecrypt(encryptedVault: EncryptedVault) throws {
public func verifyCanDecrypt(encryptedVault: EncryptedVault) throws(Error) {
try withMappedError {
_ = try VaultDecryptor(key: key).decrypt(encryptedVault: encryptedVault)
} error: {
Error.decryptionFailed($0)
}
}

public func decryptBackupPayload(from encryptedVault: EncryptedVault) throws -> VaultBackupPayload {
public func decryptBackupPayload(from encryptedVault: EncryptedVault) throws(Error) -> VaultBackupPayload {
// Encrypted vault version.
guard encryptedVault.version.isCompatible(with: "1.0.0") else {
throw Error.incompatibleVersion
Expand Down
2 changes: 1 addition & 1 deletion Vault/Sources/VaultBackup/Export/DataShardDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public struct DataShardDecoder {
}

/// Extract the data based on the shards.
public func decodeData() throws -> Data {
public func decodeData() throws(DecoderError) -> Data {
guard isReadyToDecode else { throw DecoderError.missingShards }
let sortedShards = currentShards.sorted { $0.key < $1.key }.map(\.value)
return sortedShards.reduce(into: Data()) { result, shard in
Expand Down
22 changes: 11 additions & 11 deletions Vault/Sources/VaultCore/Base32/Base32.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ public func base32HexEncode(_ data: Data) -> String {
}
}

public func base32DecodeToData(_ string: String) throws -> Data {
public func base32DecodeToData(_ string: String) throws(Base32Error) -> Data {
let bytes = try base32decode(string, alphabetDecodeTable)
return Data(bytes)
}

public func base32HexDecodeToData(_ string: String) throws -> Data {
public func base32HexDecodeToData(_ string: String) throws(Base32Error) -> Data {
let bytes = try base32decode(string, extendedHexAlphabetDecodeTable)
return Data(bytes)
}
Expand All @@ -64,11 +64,11 @@ public func base32HexEncode(_ array: [UInt8]) -> String {
base32encode(array, array.count, extendedHexAlphabetEncodeTable)
}

public func base32Decode(_ string: String) throws -> [UInt8] {
public func base32Decode(_ string: String) throws(Base32Error) -> [UInt8] {
try base32decode(string, alphabetDecodeTable)
}

public func base32HexDecode(_ string: String) throws -> [UInt8] {
public func base32HexDecode(_ string: String) throws(Base32Error) -> [UInt8] {
try base32decode(string, extendedHexAlphabetDecodeTable)
}

Expand All @@ -77,7 +77,7 @@ public func base32HexDecode(_ string: String) throws -> [UInt8] {
extension String {
// base32
public var base32DecodedData: Data {
get throws {
get throws(Base32Error) {
try base32DecodeToData(self)
}
}
Expand All @@ -88,14 +88,14 @@ extension String {
}
}

public func base32DecodedString(_: String.Encoding = .utf8) throws -> String? {
public func base32DecodedString(_: String.Encoding = .utf8) throws(Base32Error) -> String? {
let data = try base32DecodedData
return String(data: data, encoding: .utf8)
}

// base32Hex
public var base32HexDecodedData: Data {
get throws {
get throws(Base32Error) {
try base32HexDecodeToData(self)
}
}
Expand All @@ -106,7 +106,7 @@ extension String {
}
}

public func base32HexDecodedString(_: String.Encoding = .utf8) throws -> String? {
public func base32HexDecodedString(_: String.Encoding = .utf8) throws(Base32Error) -> String? {
let data = try base32HexDecodedData
return String(data: data, encoding: .utf8)
}
Expand All @@ -123,7 +123,7 @@ extension Data {
}

public var base32DecodedData: Data? {
get throws {
get throws(Base32Error) {
try String(data: self, encoding: .utf8).flatMap(base32DecodeToData)
}
}
Expand All @@ -138,7 +138,7 @@ extension Data {
}

public var base32HexDecodedData: Data? {
get throws {
get throws(Base32Error) {
try String(data: self, encoding: .utf8).flatMap(base32HexDecodeToData)
}
}
Expand Down Expand Up @@ -344,7 +344,7 @@ let extendedHexAlphabetDecodeTable: [UInt8] = [
__, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0xF0 - 0xFF
]

private func base32decode(_ string: String, _ table: [UInt8]) throws -> [UInt8] {
private func base32decode(_ string: String, _ table: [UInt8]) throws(Base32Error) -> [UInt8] {
let length = string.unicodeScalars.count
if length == 0 {
return []
Expand Down
2 changes: 1 addition & 1 deletion Vault/Sources/VaultCore/OTPAuthCodeData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public struct OTPAuthSecret: Equatable, Hashable, Sendable {
.init(data: Data(), format: format)
}

public static func base32EncodedString(_ string: String) throws -> OTPAuthSecret {
public static func base32EncodedString(_ string: String) throws(Base32Error) -> OTPAuthSecret {
let data = try string.base32DecodedData
return .init(data: data, format: .base32)
}
Expand Down
10 changes: 5 additions & 5 deletions Vault/Sources/VaultCore/URI/OTPAuthURIDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ public struct OTPAuthURIDecoder {
// MARK: - Helpers

extension OTPAuthURIDecoder {
private func decodeSecret(uri: URL) throws -> OTPAuthSecret {
private func decodeSecret(uri: URL) throws(Base32Error) -> OTPAuthSecret {
guard let secret = uri.otpParameter(.secret) else {
return .empty(.base32)
}
let data = try secret.base32DecodedData
return .init(data: data, format: .base32)
}

private func decodeDigits(uri: URL) throws -> OTPAuthDigits {
private func decodeDigits(uri: URL) throws(URIDecodingError) -> OTPAuthDigits {
guard let digits = uri.otpParameter(.digits) else {
return .default
}
Expand All @@ -53,7 +53,7 @@ extension OTPAuthURIDecoder {
return OTPAuthDigits(value: value)
}

private func decodeAlgorithm(uri: URL) throws -> OTPAuthAlgorithm {
private func decodeAlgorithm(uri: URL) throws(URIDecodingError) -> OTPAuthAlgorithm {
guard let algorithm = uri.otpParameter(.algorithm) else {
return .default
}
Expand All @@ -69,7 +69,7 @@ extension OTPAuthURIDecoder {
}
}

private func decodeLabel(uri: URL) throws -> (accountName: String, issuer: String) {
private func decodeLabel(uri: URL) throws(URIDecodingError) -> (accountName: String, issuer: String) {
guard uri.pathComponents.count > 1 else {
throw URIDecodingError.invalidLabel
}
Expand All @@ -85,7 +85,7 @@ extension OTPAuthURIDecoder {
return (String(accountName), issuer)
}

private func decodeType(uri: URL) throws -> OTPAuthType {
private func decodeType(uri: URL) throws(URIDecodingError) -> OTPAuthType {
guard let host = uri.host else {
throw URIDecodingError.invalidType
}
Expand Down
4 changes: 2 additions & 2 deletions Vault/Sources/VaultCore/URI/OTPAuthURIEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import Foundation
///
/// https://docs.yubico.com/yesdk/users-manual/application-oath/uri-string-format.html
public struct OTPAuthURIEncoder {
enum URIEncodingError: Error {
public enum URIEncodingError: Error {
case badURIComponents
}

public init() {}

public func encode(code: OTPAuthCode) throws -> OTPAuthURI {
public func encode(code: OTPAuthCode) throws(URIEncodingError) -> OTPAuthURI {
var components = URLComponents()
components.scheme = OTPAuthURI.otpAuthScheme
components.host = makeFormatted(type: code.type)
Expand Down
2 changes: 1 addition & 1 deletion Vault/Sources/VaultExport/PDF/PDFContentDrawerer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct PDFContentDrawerer {
/// Draws to the current page or next page (if there's not enough room).
///
/// Throws an error if unable to draw due to insufficient space, even on a new page.
func drawContent() throws {
func drawContent() throws(DrawError) {
let result = draw()
switch result {
case .success:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private final class PDFDocumentDrawerHelper<Layout: PageLayout> {
}

/// Throws if unable to draw.
func draw(label: DataBlockLabel) throws {
func draw(label: DataBlockLabel) throws(PDFContentDrawerer.DrawError) {
let drawerer = PDFContentDrawerer { [self] in
let currentLayoutEngine = pageLayout(contentArea.currentBounds)
let attributedString = labelRenderer.makeAttributedTextForLabel(label)
Expand Down Expand Up @@ -126,7 +126,7 @@ private final class PDFDocumentDrawerHelper<Layout: PageLayout> {
images: [Data],
imageRenderer: some ImageDataRenderer,
rectSeriesLayout: @escaping (CGRect) -> some RectSeriesLayout,
) throws {
) throws(PDFContentDrawerer.DrawError) {
var currentImageNumberOnPage: UInt = 0
var currentLayoutEngine = rectSeriesLayout(contentArea.currentBounds)

Expand Down
4 changes: 2 additions & 2 deletions Vault/Sources/VaultFeed/Encryption/VaultItemDecryptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct VaultItemDecryptor {
}

/// Decrypts the identifier for this item, so we know what kind of item it is.
func decryptItemIdentifier(item: EncryptedItem) throws -> String {
func decryptItemIdentifier(item: EncryptedItem) throws(Error) -> String {
let decryptor = AESGCMDecryptor(key: key.key.data)
let item = try withMappedError {
try decryptor.decrypt(
Expand All @@ -40,7 +40,7 @@ struct VaultItemDecryptor {
}

/// Decodes and decrypts an encryptable item from the vault.
func decrypt<T: VaultItemEncryptable>(item: EncryptedItem, expectedItemIdentifier: String) throws -> T {
func decrypt<T: VaultItemEncryptable>(item: EncryptedItem, expectedItemIdentifier: String) throws(Error) -> T {
let decryptor = AESGCMDecryptor(key: key.key.data)
let item = try withMappedError {
try decryptor.decrypt(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final class DetailEditState<T: Equatable> {
isInEditMode = true
}

func saveChanges(performUpdate: @MainActor @Sendable () async throws -> Void) async throws {
func saveChanges(performUpdate: @MainActor @Sendable () async throws -> Void) async throws(OperationError) {
guard !isSaving else { return }
isSaving = true
defer { isSaving = false }
Expand All @@ -30,7 +30,7 @@ final class DetailEditState<T: Equatable> {
func deleteItem(
performDeletion: @MainActor @Sendable () async throws -> Void,
finished: @MainActor @Sendable () -> Void,
) async throws {
) async throws(OperationError) {
guard !isSaving else { return }
isSaving = true
defer { isSaving = false }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public final class RealCredentialIdentityStore: CredentialIdentityStore {
try await store.removeAllCredentialIdentities()
}

public func getCredentialIdentities() async throws -> [any ASCredentialIdentity] {
public func getCredentialIdentities() async throws(CredentialIdentityStoreError) -> [any ASCredentialIdentity] {
let state = await store.state()

guard state.isEnabled else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ extension VaultBackupItemDecoder {
}
}

private func decodeSecret(data: VaultBackupItem.OTP) throws -> OTPAuthSecret {
private func decodeSecret(data: VaultBackupItem.OTP) throws(OTPDecodeError) -> OTPAuthSecret {
let format: OTPAuthSecret.Format = switch data.secretFormat {
case VaultEncodingConstants.OTPAuthSecret.Format.base32: .base32
default: throw OTPDecodeError.invalidSecretFormat
Expand All @@ -150,7 +150,7 @@ extension VaultBackupItemDecoder {
)
}

private func decodeAlgorithm(data: VaultBackupItem.OTP) throws -> OTPAuthAlgorithm {
private func decodeAlgorithm(data: VaultBackupItem.OTP) throws(OTPDecodeError) -> OTPAuthAlgorithm {
switch data.algorithm {
case VaultEncodingConstants.OTPAuthAlgorithm.sha1: .sha1
case VaultEncodingConstants.OTPAuthAlgorithm.sha256: .sha256
Expand Down Expand Up @@ -178,7 +178,7 @@ extension VaultBackupItemDecoder {
// MARK: - Encrypted

extension VaultBackupItemDecoder {
private func decodeEncrypted(item: VaultBackupItem.Encrypted) throws -> EncryptedItem {
private func decodeEncrypted(item: VaultBackupItem.Encrypted) throws(SemVer.ParseError) -> EncryptedItem {
try .init(
version: SemVer(string: item.version),
title: item.title,
Expand Down
Loading
Loading