diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index c0f6f1879..a8b26206c 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -39,7 +39,6 @@ blocks: - name: TypeScript - Core standalone tests commands: - sem-version node 12 - - checkout - mkdir .custom-npm - cd .custom-npm - npm install npm@7.23.0 diff --git a/FlowCrypt.xcodeproj/project.pbxproj b/FlowCrypt.xcodeproj/project.pbxproj index 21fc15e9c..970a8943f 100644 --- a/FlowCrypt.xcodeproj/project.pbxproj +++ b/FlowCrypt.xcodeproj/project.pbxproj @@ -54,6 +54,7 @@ 50531BE42629B9A80039BAE9 /* AttachmentNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50531BE32629B9A80039BAE9 /* AttachmentNode.swift */; }; 510A260126FDFEBE00163271 /* MailCore2 in Frameworks */ = {isa = PBXBuildFile; productRef = 510A260026FDFEBE00163271 /* MailCore2 */; }; 51775C32270B01C200D7C944 /* PrvKeyInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51775C31270B01C200D7C944 /* PrvKeyInfoTests.swift */; }; + 51775C39270C7D2400D7C944 /* StorageMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51775C38270C7D2400D7C944 /* StorageMethod.swift */; }; 5A39F42D239EC321001F4607 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A39F42C239EC321001F4607 /* SettingsViewController.swift */; }; 5A39F430239EC396001F4607 /* SettingsViewDecorator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A39F42F239EC396001F4607 /* SettingsViewDecorator.swift */; }; 5A39F437239ECC23001F4607 /* KeySettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A39F436239ECC23001F4607 /* KeySettingsViewController.swift */; }; @@ -131,7 +132,7 @@ 9F6F3C7D26ADFC60005BD9C6 /* ContactsServiceMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6F3C7C26ADFC60005BD9C6 /* ContactsServiceMock.swift */; }; 9F6F5F6C26A2F66B00C625C7 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8220D426336626004B2009 /* Logger.swift */; }; 9F716308234FC73E0031645E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 9F71630A234FC73E0031645E /* Localizable.strings */; }; - 9F7920F52667CEF100DA3D80 /* PassPraseSaveable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7920F42667CEF100DA3D80 /* PassPraseSaveable.swift */; }; + 9F7920F52667CEF100DA3D80 /* PassPhraseSaveable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7920F42667CEF100DA3D80 /* PassPhraseSaveable.swift */; }; 9F79228826696B0200DA3D80 /* PassPhraseService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F79228726696B0200DA3D80 /* PassPhraseService.swift */; }; 9F79229426696B9300DA3D80 /* KeyDataStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F79229326696B9300DA3D80 /* KeyDataStorage.swift */; }; 9F7E5137267AA51B00CE37C3 /* AlertsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7E5136267AA51B00CE37C3 /* AlertsFactory.swift */; }; @@ -455,6 +456,7 @@ 4A76C3D4559C9F415D392A62 /* Pods-FlowCryptTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FlowCryptTests.debug.xcconfig"; path = "Target Support Files/Pods-FlowCryptTests/Pods-FlowCryptTests.debug.xcconfig"; sourceTree = ""; }; 50531BE32629B9A80039BAE9 /* AttachmentNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentNode.swift; sourceTree = ""; }; 51775C31270B01C200D7C944 /* PrvKeyInfoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrvKeyInfoTests.swift; sourceTree = ""; }; + 51775C38270C7D2400D7C944 /* StorageMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageMethod.swift; sourceTree = ""; }; 567BA6739257FE0D2924D82C /* Pods_FlowCryptUIApplication.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FlowCryptUIApplication.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5A39F42C239EC321001F4607 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; 5A39F42F239EC396001F4607 /* SettingsViewDecorator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewDecorator.swift; sourceTree = ""; }; @@ -564,7 +566,7 @@ 9F716309234FC73E0031645E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 9F71630B234FC7500031645E /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; 9F72E866263ECE2A0039CF81 /* Trace.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Trace.swift; sourceTree = ""; }; - 9F7920F42667CEF100DA3D80 /* PassPraseSaveable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassPraseSaveable.swift; sourceTree = ""; }; + 9F7920F42667CEF100DA3D80 /* PassPhraseSaveable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassPhraseSaveable.swift; sourceTree = ""; }; 9F79228726696B0200DA3D80 /* PassPhraseService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PassPhraseService.swift; sourceTree = ""; }; 9F79229326696B9300DA3D80 /* KeyDataStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyDataStorage.swift; sourceTree = ""; }; 9F7E5136267AA51B00CE37C3 /* AlertsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertsFactory.swift; sourceTree = ""; }; @@ -1668,7 +1670,7 @@ 9F268890237DC55600428A94 /* SetupManuallyImportKeyViewController.swift */, 9FD364852381EFCB00657302 /* SetupManuallyEnterPassPhraseViewController.swift */, 9F17976C2368EEBD002BF770 /* SetupViewDecorator.swift */, - 9F7920F42667CEF100DA3D80 /* PassPraseSaveable.swift */, + 9F7920F42667CEF100DA3D80 /* PassPhraseSaveable.swift */, ); path = Setup; sourceTree = ""; @@ -1845,6 +1847,7 @@ 9F589F19238C82A1007FD759 /* Local Storage */, 9F003D6C25EA8F3200EB38C0 /* UserAccountService.swift */, 9F003DB525EA92BC00EB38C0 /* LogOutHandler.swift */, + 51775C38270C7D2400D7C944 /* StorageMethod.swift */, ); path = DataManager; sourceTree = ""; @@ -2630,7 +2633,7 @@ D212D35D24C1AACF00035991 /* PrvKeyInfo.swift in Sources */, 9F23EA50237217140017DFED /* ComposeViewDecorator.swift in Sources */, D21574B724376852006B094F /* ConnectionType.swift in Sources */, - 9F7920F52667CEF100DA3D80 /* PassPraseSaveable.swift in Sources */, + 9F7920F52667CEF100DA3D80 /* PassPhraseSaveable.swift in Sources */, 9F6F3BEF26ADF5DE005BD9C6 /* ComposeMessageError.swift in Sources */, 5ADEDCAF23A3EA9E00EC495E /* KeySettingsViewDecorator.swift in Sources */, 9F3EF33123B1785600FA0CEF /* MsgListViewConroller.swift in Sources */, @@ -2645,6 +2648,7 @@ 215897E8267A553300423694 /* FilesManager.swift in Sources */, 9F5C2A77257D705100DE9B4B /* MessageLabel.swift in Sources */, 9F93623F2573D16F0009912F /* Gmail+Message.swift in Sources */, + 51775C39270C7D2400D7C944 /* StorageMethod.swift in Sources */, 9FC4112E2595EA8B001180A8 /* Gmail+Search.swift in Sources */, 5A948DC5239EF2F4006284D7 /* LegalViewController.swift in Sources */, D274724124F97C5C006BA6EF /* CacheService.swift in Sources */, diff --git a/FlowCrypt/Controllers/Setup/PassPraseSaveable.swift b/FlowCrypt/Controllers/Setup/PassPhraseSaveable.swift similarity index 84% rename from FlowCrypt/Controllers/Setup/PassPraseSaveable.swift rename to FlowCrypt/Controllers/Setup/PassPhraseSaveable.swift index 960c07769..d8772e9d6 100644 --- a/FlowCrypt/Controllers/Setup/PassPraseSaveable.swift +++ b/FlowCrypt/Controllers/Setup/PassPhraseSaveable.swift @@ -9,7 +9,7 @@ import FlowCryptUI protocol PassPhraseSaveable { - var shouldStorePassPhrase: Bool { get set } + var storageMethod: StorageMethod { get set } var passPhraseIndexes: [IndexPath] { get } var saveLocallyNode: CellNode { get } var saveInMemoryNode: CellNode { get } @@ -26,11 +26,11 @@ extension PassPhraseSaveable where Self: TableNodeViewController { } var saveLocallyNode: CellNode { - CheckBoxTextNode(input: .passPhraseLocally(isSelected: self.shouldStorePassPhrase)) + CheckBoxTextNode(input: .passPhraseLocally(isSelected: storageMethod == .persistent)) } var saveInMemoryNode: CellNode { - CheckBoxTextNode(input: .passPhraseMemory(isSelected: !self.shouldStorePassPhrase)) + CheckBoxTextNode(input: .passPhraseMemory(isSelected: storageMethod == .memory)) } func showPassPhraseErrorAlert() { diff --git a/FlowCrypt/Controllers/Setup/SetupBackupsViewController.swift b/FlowCrypt/Controllers/Setup/SetupBackupsViewController.swift index 3df8241e8..f3190c3aa 100644 --- a/FlowCrypt/Controllers/Setup/SetupBackupsViewController.swift +++ b/FlowCrypt/Controllers/Setup/SetupBackupsViewController.swift @@ -34,7 +34,7 @@ final class SetupBackupsViewController: TableNodeViewController, PassPhraseSavea private var passPhrase: String? - var shouldStorePassPhrase = true { + var storageMethod: StorageMethod = .persistent { didSet { handleSelectedPassPhraseOption() } @@ -144,20 +144,20 @@ extension SetupBackupsViewController { return } - if !shouldStorePassPhrase { + if storageMethod == .memory { // save pass phrase matchingKeyBackups .map { PassPhrase(value: passPhrase, fingerprints: $0.fingerprints) } .forEach { - passPhraseService.savePassPhrase(with: $0, inStorage: shouldStorePassPhrase) + passPhraseService.savePassPhrase(with: $0, storageMethod: storageMethod) } } // save keys keyStorage.addKeys(keyDetails: Array(matchingKeyBackups), - passPhrase: shouldStorePassPhrase ? passPhrase : nil, + passPhrase: storageMethod == .persistent ? passPhrase : nil, source: .backup, for: user.email) @@ -261,9 +261,9 @@ extension SetupBackupsViewController: ASTableDelegate, ASTableDataSource { switch part { case .saveLocally: - shouldStorePassPhrase = true + storageMethod = .persistent case .saveInMemory: - shouldStorePassPhrase = false + storageMethod = .memory default: break } diff --git a/FlowCrypt/Controllers/Setup/SetupCreatePassphraseAbstractViewController.swift b/FlowCrypt/Controllers/Setup/SetupCreatePassphraseAbstractViewController.swift index 02a9a7bb8..f8b154831 100644 --- a/FlowCrypt/Controllers/Setup/SetupCreatePassphraseAbstractViewController.swift +++ b/FlowCrypt/Controllers/Setup/SetupCreatePassphraseAbstractViewController.swift @@ -34,7 +34,7 @@ class SetupCreatePassphraseAbstractViewController: TableNodeViewController, Pass let passPhraseService: PassPhraseServiceType var shouldShowBackButton: Bool { false } - var shouldStorePassPhrase = true { + var storageMethod: StorageMethod = .persistent { didSet { handleSelectedPassPhraseOption() } @@ -282,9 +282,9 @@ extension SetupCreatePassphraseAbstractViewController: ASTableDelegate, ASTableD case .description: showChoosingOptions() case .saveLocally: - shouldStorePassPhrase = true + storageMethod = .persistent case .saveInMemory: - shouldStorePassPhrase = false + storageMethod = .memory default: break } diff --git a/FlowCrypt/Controllers/Setup/SetupEKMKeyViewController.swift b/FlowCrypt/Controllers/Setup/SetupEKMKeyViewController.swift index 8ea71c69b..7c8e9635d 100644 --- a/FlowCrypt/Controllers/Setup/SetupEKMKeyViewController.swift +++ b/FlowCrypt/Controllers/Setup/SetupEKMKeyViewController.swift @@ -52,7 +52,7 @@ final class SetupEKMKeyViewController: SetupCreatePassphraseAbstractViewControll keyStorage: keyStorage, passPhraseService: passPhraseService ) - self.shouldStorePassPhrase = false + self.storageMethod = .memory } override func viewDidLoad() { @@ -88,16 +88,16 @@ extension SetupEKMKeyViewController { ) let parsedKey = try self.core.parseKeys(armoredOrBinary: encryptedPrv.encryptedKey.data()) self.keyStorage.addKeys(keyDetails: parsedKey.keyDetails, - passPhrase: self.shouldStorePassPhrase ? passPhrase : nil, + passPhrase: self.storageMethod == .persistent ? passPhrase : nil, source: .ekm, for: self.user.email) allFingerprints.append(contentsOf: parsedKey.keyDetails.flatMap { $0.fingerprints }) } } - if !self.shouldStorePassPhrase { + if self.storageMethod == .memory { let passPhrase = PassPhrase(value: passPhrase, fingerprints: allFingerprints.unique()) - self.passPhraseService.savePassPhrase(with: passPhrase, inStorage: self.shouldStorePassPhrase) + self.passPhraseService.savePassPhrase(with: passPhrase, storageMethod: self.storageMethod) } } .then(on: .main) { [weak self] in diff --git a/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift b/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift index da33a4a76..468767723 100644 --- a/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift +++ b/FlowCrypt/Controllers/Setup/SetupGenerateKeyViewController.swift @@ -88,13 +88,13 @@ extension SetupGenerateKeyViewController { try awaitPromise(self.backupService.backupToInbox(keys: [encryptedPrv.key], for: self.user)) self.keyStorage.addKeys(keyDetails: [encryptedPrv.key], - passPhrase: self.shouldStorePassPhrase ? passPhrase: nil, + passPhrase: self.storageMethod == .persistent ? passPhrase: nil, source: .generated, for: self.user.email) - if !self.shouldStorePassPhrase { + if self.storageMethod == .memory { let passPhrase = PassPhrase(value: passPhrase, fingerprints: encryptedPrv.key.fingerprints) - self.passPhraseService.savePassPhrase(with: passPhrase, inStorage: false) + self.passPhraseService.savePassPhrase(with: passPhrase, storageMethod: .memory) } let updateKey = self.attester.updateKey( diff --git a/FlowCrypt/Controllers/Setup/SetupManuallyEnterPassPhraseViewController.swift b/FlowCrypt/Controllers/Setup/SetupManuallyEnterPassPhraseViewController.swift index 918f16bbe..2b340b86e 100644 --- a/FlowCrypt/Controllers/Setup/SetupManuallyEnterPassPhraseViewController.swift +++ b/FlowCrypt/Controllers/Setup/SetupManuallyEnterPassPhraseViewController.swift @@ -34,7 +34,7 @@ final class SetupManuallyEnterPassPhraseViewController: TableNodeViewController, private var passPhrase: String? - var shouldStorePassPhrase = true { + var storageMethod: StorageMethod = .persistent { didSet { handleSelectedPassPhraseOption() } @@ -197,9 +197,9 @@ extension SetupManuallyEnterPassPhraseViewController: ASTableDelegate, ASTableDa switch part { case .saveLocally: - shouldStorePassPhrase = true + storageMethod = .persistent case .saveInMemory: - shouldStorePassPhrase = false + storageMethod = .memory default: break } @@ -244,13 +244,13 @@ extension SetupManuallyEnterPassPhraseViewController { keysStorage.addKeys(keyDetails: newKeysToAdd, passPhrase: passPhrase, source: .imported, for: email) keysStorage.updateKeys(keyDetails: keysToUpdate, passPhrase: passPhrase, source: .imported, for: email) - if !shouldStorePassPhrase { + if storageMethod == .memory { keysToUpdate .map { PassPhrase(value: passPhrase, fingerprints: $0.fingerprints) } .forEach { - passPhraseService.updatePassPhrase(with: $0, inStorage: shouldStorePassPhrase) + passPhraseService.updatePassPhrase(with: $0, storageMethod: storageMethod) } newKeysToAdd @@ -258,7 +258,7 @@ extension SetupManuallyEnterPassPhraseViewController { PassPhrase(value: passPhrase, fingerprints: $0.fingerprints) } .forEach { - passPhraseService.savePassPhrase(with: $0, inStorage: shouldStorePassPhrase) + passPhraseService.savePassPhrase(with: $0, storageMethod: storageMethod) } } diff --git a/FlowCrypt/Functionality/DataManager/StorageMethod.swift b/FlowCrypt/Functionality/DataManager/StorageMethod.swift new file mode 100644 index 000000000..0d02c7b64 --- /dev/null +++ b/FlowCrypt/Functionality/DataManager/StorageMethod.swift @@ -0,0 +1,13 @@ +// +// StorageMethod.swift +// FlowCrypt +// +// Created by Roma Sosnovsky on 05/10/21 +// Copyright © 2017-present FlowCrypt a. s. All rights reserved. +// + +import Foundation + +enum StorageMethod { + case persistent, memory +} diff --git a/FlowCrypt/Functionality/Mail Provider/Message Provider/MessageService.swift b/FlowCrypt/Functionality/Mail Provider/Message Provider/MessageService.swift index 36408d11d..1769a97ba 100644 --- a/FlowCrypt/Functionality/Mail Provider/Message Provider/MessageService.swift +++ b/FlowCrypt/Functionality/Mail Provider/Message Provider/MessageService.swift @@ -107,7 +107,7 @@ final class MessageService { private func savePassPhrases(value passPhrase: String, with privateKeys: [PrvKeyInfo]) { privateKeys .map { PassPhrase(value: passPhrase, fingerprints: $0.fingerprints) } - .forEach { self.passPhraseService.savePassPhrase(with: $0, inStorage: false) } + .forEach { self.passPhraseService.savePassPhrase(with: $0, storageMethod: .memory) } } func getAndProcessMessage(with input: Message, folder: String) -> Promise { diff --git a/FlowCrypt/Functionality/Services/Key Services/PassPhraseService.swift b/FlowCrypt/Functionality/Services/Key Services/PassPhraseService.swift index fdfee264b..2901c783d 100644 --- a/FlowCrypt/Functionality/Services/Key Services/PassPhraseService.swift +++ b/FlowCrypt/Functionality/Services/Key Services/PassPhraseService.swift @@ -59,8 +59,8 @@ protocol PassPhraseStorageType { // MARK: - PassPhraseService protocol PassPhraseServiceType { func getPassPhrases() -> [PassPhrase] - func savePassPhrase(with passPhrase: PassPhrase, inStorage: Bool) - func updatePassPhrase(with passPhrase: PassPhrase, inStorage: Bool) + func savePassPhrase(with passPhrase: PassPhrase, storageMethod: StorageMethod) + func updatePassPhrase(with passPhrase: PassPhrase, storageMethod: StorageMethod) } final class PassPhraseService: PassPhraseServiceType { @@ -80,11 +80,12 @@ final class PassPhraseService: PassPhraseServiceType { self.currentUserEmail = emailProvider.email } - func savePassPhrase(with passPhrase: PassPhrase, inStorage: Bool) { - if inStorage { + func savePassPhrase(with passPhrase: PassPhrase, storageMethod: StorageMethod) { + switch storageMethod { + case .persistent: logger.logInfo("Save passphrase to storage") encryptedStorage.save(passPhrase: passPhrase) - } else { + case .memory: logger.logInfo("Save passphrase in memory") inMemoryStorage.save(passPhrase: passPhrase) @@ -97,10 +98,11 @@ final class PassPhraseService: PassPhraseServiceType { } } - func updatePassPhrase(with passPhrase: PassPhrase, inStorage: Bool) { - if inStorage { + func updatePassPhrase(with passPhrase: PassPhrase, storageMethod: StorageMethod) { + switch storageMethod { + case .persistent: encryptedStorage.update(passPhrase: passPhrase) - } else { + case .memory: inMemoryStorage.save(passPhrase: passPhrase) } } diff --git a/FlowCryptAppTests/Functionality/Services/PassPhraseStorageTests/PassPhraseStorageTests.swift b/FlowCryptAppTests/Functionality/Services/PassPhraseStorageTests/PassPhraseStorageTests.swift index 5cc121729..91b65be03 100644 --- a/FlowCryptAppTests/Functionality/Services/PassPhraseStorageTests/PassPhraseStorageTests.swift +++ b/FlowCryptAppTests/Functionality/Services/PassPhraseStorageTests/PassPhraseStorageTests.swift @@ -110,7 +110,7 @@ class PassPhraseStorageTests: XCTestCase { XCTAssertTrue(result.count == 3) } - func testSavePassPhraseInStorage() { + func testSavePassPhraseInPersistenStorage() { let passPhraseToSave = PassPhrase(value: "pass", fingerprints: ["fingerprint 1", "123333"]) let expectation = XCTestExpectation() @@ -132,14 +132,14 @@ class PassPhraseStorageTests: XCTestCase { } } - sut.savePassPhrase(with: passPhraseToSave, inStorage: true) + sut.savePassPhrase(with: passPhraseToSave, storageMethod: .persistent) XCTAssertFalse(inMemoryStorage.saveResult != nil ) wait(for: [expectation], timeout: 0.1, enforceOrder: false) } - func testSavePassPhraseInStorageWithoutAnyPassPhrases() { + func testSavePassPhraseInPersistentStorageWithoutAnyPassPhrases() { let passPhraseToSave = PassPhrase(value: "pass", fingerprints: ["fingerprint 1", "123333"]) let expectation = XCTestExpectation() @@ -152,7 +152,7 @@ class PassPhraseStorageTests: XCTestCase { expectation.fulfill() } - sut.savePassPhrase(with: passPhraseToSave, inStorage: true) + sut.savePassPhrase(with: passPhraseToSave, storageMethod: .persistent) XCTAssertFalse(inMemoryStorage.saveResult != nil ) diff --git a/Podfile.lock b/Podfile.lock index 911ca3b96..bc5bfafbe 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -48,7 +48,7 @@ PODS: - Realm/Headers (10.16.0) - RealmSwift (10.16.0): - Realm (= 10.16.0) - - SwiftFormat/CLI (0.48.12) + - SwiftFormat/CLI (0.48.13) - SwiftLint (0.44.0) - SwiftyRSA (1.7.0): - SwiftyRSA/ObjC (= 1.7.0) @@ -132,7 +132,7 @@ SPEC CHECKSUMS: PromisesSwift: e0b2a6433469efb0b83a2b84c62a2abab8e5e5d4 Realm: b6027801398f3743fc222f096faa85281b506e6c RealmSwift: b02a3d0e4947955da960b642c98ad3a461fc4e70 - SwiftFormat: 036d3d8d85a187bf8f6d7808bb917811ce883680 + SwiftFormat: 0c4b53c1acb503e2a743ecd9a18f51958d41d40a SwiftLint: e96c0a8c770c7ebbc4d36c55baf9096bb65c4584 SwiftyRSA: 8c6dd1ea7db1b8dc4fb517a202f88bb1354bc2c6 Texture: 2f109e937850d94d1d07232041c9c7313ccddb81