diff --git a/Bitwarden.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Bitwarden.xcworkspace/xcshareddata/swiftpm/Package.resolved index 5ad767c331..cd63fb3716 100644 --- a/Bitwarden.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Bitwarden.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -123,7 +123,7 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/bitwarden/sdk-swift", "state" : { - "revision" : "b7e7be7e7f5adde3cafcb27d79fac80a53c5c3c8" + "revision" : "d90abf9f6c11cfacb66b567ae201c9321a3e0eea" } }, { diff --git a/BitwardenKit/Core/Vault/Services/Mocks/BitwardenSdk+VaultMocking.swift b/BitwardenKit/Core/Vault/Services/Mocks/BitwardenSdk+VaultMocking.swift index 7c21b2b667..6f4338d948 100644 --- a/BitwardenKit/Core/Vault/Services/Mocks/BitwardenSdk+VaultMocking.swift +++ b/BitwardenKit/Core/Vault/Services/Mocks/BitwardenSdk+VaultMocking.swift @@ -477,6 +477,8 @@ public extension SendView { type: send.type, file: send.file.map(SendFileView.init), text: send.text.map(SendTextView.init), + // The app doesn't support v2 send items yet, so there's nothing to round-trip here. + data: nil, maxAccessCount: send.maxAccessCount, accessCount: send.accessCount, disabled: send.disabled, @@ -522,6 +524,8 @@ public extension Send { type: sendView.type, file: sendView.file.map(SendFile.init), text: sendView.text.map(SendText.init), + // The app doesn't support v2 send items yet, so there's nothing to round-trip here. + data: nil, maxAccessCount: sendView.maxAccessCount, accessCount: sendView.accessCount, disabled: sendView.disabled, diff --git a/BitwardenShared/Core/Auth/Models/Request/MasterPasswordUnlockDataRequestModel.swift b/BitwardenShared/Core/Auth/Models/Request/MasterPasswordUnlockDataRequestModel.swift index 94b08ef9e4..a424e8aa85 100644 --- a/BitwardenShared/Core/Auth/Models/Request/MasterPasswordUnlockDataRequestModel.swift +++ b/BitwardenShared/Core/Auth/Models/Request/MasterPasswordUnlockDataRequestModel.swift @@ -7,6 +7,9 @@ import BitwardenSdk struct MasterPasswordUnlockDataRequestModel: Encodable, Equatable { // MARK: Properties + /// The ID of the key contained in `masterKeyWrappedUserKey`, when the user's key has one. + let containedKeyId: String? + /// The KDF settings. let kdf: KdfConfig @@ -25,6 +28,7 @@ extension MasterPasswordUnlockDataRequestModel { /// init(unlockData: MasterPasswordUnlockData) { self.init( + containedKeyId: unlockData.containedKeyId, kdf: KdfConfig(kdf: unlockData.kdf), masterKeyWrappedUserKey: unlockData.masterKeyWrappedUserKey, salt: unlockData.salt, diff --git a/BitwardenShared/Core/Auth/Models/Request/UpdateKdfRequestModelTests.swift b/BitwardenShared/Core/Auth/Models/Request/UpdateKdfRequestModelTests.swift index 99986d7559..3dc674aae9 100644 --- a/BitwardenShared/Core/Auth/Models/Request/UpdateKdfRequestModelTests.swift +++ b/BitwardenShared/Core/Auth/Models/Request/UpdateKdfRequestModelTests.swift @@ -19,6 +19,7 @@ class UpdateKdfRequestModelTests: BitwardenTestCase { kdf: .argon2id(iterations: 3, memory: 64, parallelism: 4), masterKeyWrappedUserKey: "MASTER_KEY_WRAPPED_USER_KEY", salt: "UNLOCK_SALT", + containedKeyId: "CONTAINED_KEY_ID", ), oldMasterPasswordAuthenticationData: MasterPasswordAuthenticationData( kdf: .pbkdf2(iterations: 100_000), @@ -39,6 +40,7 @@ class UpdateKdfRequestModelTests: BitwardenTestCase { masterPasswordHash: "OLD_MASTER_PASSWORD_AUTHENTICATION_HASH", newMasterPasswordHash: "MASTER_PASSWORD_AUTHENTICATION_HASH", unlockData: MasterPasswordUnlockDataRequestModel( + containedKeyId: "CONTAINED_KEY_ID", kdf: KdfConfig(kdfType: .argon2id, iterations: 3, memory: 64, parallelism: 4), masterKeyWrappedUserKey: "MASTER_KEY_WRAPPED_USER_KEY", salt: "UNLOCK_SALT", diff --git a/BitwardenShared/Core/Auth/Services/API/Account/AccountAPIServiceTests.swift b/BitwardenShared/Core/Auth/Services/API/Account/AccountAPIServiceTests.swift index 67584a53df..51b0f032dd 100644 --- a/BitwardenShared/Core/Auth/Services/API/Account/AccountAPIServiceTests.swift +++ b/BitwardenShared/Core/Auth/Services/API/Account/AccountAPIServiceTests.swift @@ -384,6 +384,7 @@ class AccountAPIServiceTests: BitwardenTestCase { // swiftlint:disable:this type masterPasswordHash: "MASTER_PASSWORD_HASH", newMasterPasswordHash: "NEW_MASTER_PASSWORD_HINT", unlockData: MasterPasswordUnlockDataRequestModel( + containedKeyId: nil, kdf: KdfConfig(), masterKeyWrappedUserKey: "MASTER_KEY_WRAPPED_USER_KEY", salt: "UNLOCK_SALT", diff --git a/BitwardenShared/Core/Auth/Services/API/Account/Requests/UpdateKdfRequestTests.swift b/BitwardenShared/Core/Auth/Services/API/Account/Requests/UpdateKdfRequestTests.swift index cf55471523..5f4da41c4d 100644 --- a/BitwardenShared/Core/Auth/Services/API/Account/Requests/UpdateKdfRequestTests.swift +++ b/BitwardenShared/Core/Auth/Services/API/Account/Requests/UpdateKdfRequestTests.swift @@ -12,28 +12,7 @@ class UpdateKdfRequestTests: BitwardenTestCase { override func setUp() { super.setUp() - subject = UpdateKdfRequest( - requestModel: UpdateKdfRequestModel( - authenticationData: MasterPasswordAuthenticationDataRequestModel( - kdf: KdfConfig( - kdfType: .argon2id, - iterations: 3, - memory: 64, - parallelism: 4, - ), - masterPasswordAuthenticationHash: "MASTER_PASSWORD_AUTHENTICATION_HASH", - salt: "AUTHENTICATION_SALT", - ), - key: "key", - masterPasswordHash: "MASTER_PASSWORD_HASH", - newMasterPasswordHash: "NEW_MASTER_PASSWORD_HINT", - unlockData: MasterPasswordUnlockDataRequestModel( - kdf: KdfConfig(), - masterKeyWrappedUserKey: "MASTER_KEY_WRAPPED_USER_KEY", - salt: "UNLOCK_SALT", - ), - ), - ) + subject = makeSubject() } override func tearDown() { @@ -77,6 +56,41 @@ class UpdateKdfRequestTests: BitwardenTestCase { ) } + /// `body` includes the contained key ID in the unlock data when the user's key has one. + func test_body_containedKeyId() throws { + subject = makeSubject(containedKeyId: "CONTAINED_KEY_ID") + let bodyData = try XCTUnwrap(subject.body?.encode()) + XCTAssertEqual( + bodyData.prettyPrintedJson, + """ + { + "authenticationData" : { + "kdf" : { + "iterations" : 3, + "kdfType" : 1, + "memory" : 64, + "parallelism" : 4 + }, + "masterPasswordAuthenticationHash" : "MASTER_PASSWORD_AUTHENTICATION_HASH", + "salt" : "AUTHENTICATION_SALT" + }, + "key" : "key", + "masterPasswordHash" : "MASTER_PASSWORD_HASH", + "newMasterPasswordHash" : "NEW_MASTER_PASSWORD_HINT", + "unlockData" : { + "containedKeyId" : "CONTAINED_KEY_ID", + "kdf" : { + "iterations" : 600000, + "kdfType" : 0 + }, + "masterKeyWrappedUserKey" : "MASTER_KEY_WRAPPED_USER_KEY", + "salt" : "UNLOCK_SALT" + } + } + """, + ) + } + /// `method` is `.post`. func test_method() { XCTAssertEqual(subject.method, .post) @@ -86,4 +100,36 @@ class UpdateKdfRequestTests: BitwardenTestCase { func test_path() { XCTAssertEqual(subject.path, "/accounts/kdf") } + + // MARK: Private + + /// Returns an `UpdateKdfRequest` for testing. + /// + /// - Parameter containedKeyId: The ID of the key contained in the wrapped user key. + /// + private func makeSubject(containedKeyId: String? = nil) -> UpdateKdfRequest { + UpdateKdfRequest( + requestModel: UpdateKdfRequestModel( + authenticationData: MasterPasswordAuthenticationDataRequestModel( + kdf: KdfConfig( + kdfType: .argon2id, + iterations: 3, + memory: 64, + parallelism: 4, + ), + masterPasswordAuthenticationHash: "MASTER_PASSWORD_AUTHENTICATION_HASH", + salt: "AUTHENTICATION_SALT", + ), + key: "key", + masterPasswordHash: "MASTER_PASSWORD_HASH", + newMasterPasswordHash: "NEW_MASTER_PASSWORD_HINT", + unlockData: MasterPasswordUnlockDataRequestModel( + containedKeyId: containedKeyId, + kdf: KdfConfig(), + masterKeyWrappedUserKey: "MASTER_KEY_WRAPPED_USER_KEY", + salt: "UNLOCK_SALT", + ), + ), + ) + } } diff --git a/BitwardenShared/Core/Tools/Extensions/BitwardenSdk+Tools.swift b/BitwardenShared/Core/Tools/Extensions/BitwardenSdk+Tools.swift index 6bda48c119..5b0146c854 100644 --- a/BitwardenShared/Core/Tools/Extensions/BitwardenSdk+Tools.swift +++ b/BitwardenShared/Core/Tools/Extensions/BitwardenSdk+Tools.swift @@ -89,6 +89,8 @@ extension BitwardenSdk.Send { type: type, file: model.file.map(SendFile.init), text: model.text.map(SendText.init), + // The API response model has no v2 send item payload, which the app doesn't support yet. + data: nil, maxAccessCount: model.maxAccessCount, accessCount: model.accessCount, disabled: model.disabled, diff --git a/BitwardenShared/Core/Tools/Extensions/TestHelpers/BitwardenSdk+ToolsFixtures.swift b/BitwardenShared/Core/Tools/Extensions/TestHelpers/BitwardenSdk+ToolsFixtures.swift index 912be1c8de..fd76a5410b 100644 --- a/BitwardenShared/Core/Tools/Extensions/TestHelpers/BitwardenSdk+ToolsFixtures.swift +++ b/BitwardenShared/Core/Tools/Extensions/TestHelpers/BitwardenSdk+ToolsFixtures.swift @@ -38,6 +38,7 @@ extension Send { type: sdkType, file: file.map(SendFile.init), text: text.map(SendText.init), + data: nil, maxAccessCount: maxAccessCount, accessCount: accessCount, disabled: disabled, diff --git a/BitwardenShared/UI/Tools/PreviewContent/SendView+Fixtures.swift b/BitwardenShared/UI/Tools/PreviewContent/SendView+Fixtures.swift index 5a5f3fc4bb..73f1ecff08 100644 --- a/BitwardenShared/UI/Tools/PreviewContent/SendView+Fixtures.swift +++ b/BitwardenShared/UI/Tools/PreviewContent/SendView+Fixtures.swift @@ -36,6 +36,7 @@ extension SendView { type: type, file: file, text: text, + data: nil, maxAccessCount: maxAccessCount, accessCount: accessCount, disabled: disabled, diff --git a/BitwardenShared/UI/Tools/Send/Send/SendList/Fixtures/SendListState+Fixtures.swift b/BitwardenShared/UI/Tools/Send/Send/SendList/Fixtures/SendListState+Fixtures.swift index b1d763bf82..e7dedb31c8 100644 --- a/BitwardenShared/UI/Tools/Send/Send/SendList/Fixtures/SendListState+Fixtures.swift +++ b/BitwardenShared/UI/Tools/Send/Send/SendList/Fixtures/SendListState+Fixtures.swift @@ -45,6 +45,7 @@ extension SendListState { type: .file, file: nil, text: nil, + data: nil, maxAccessCount: nil, accessCount: 0, disabled: false, @@ -68,6 +69,7 @@ extension SendListState { type: .text, file: nil, text: nil, + data: nil, maxAccessCount: nil, accessCount: 0, disabled: false, @@ -91,6 +93,7 @@ extension SendListState { type: .text, file: nil, text: nil, + data: nil, maxAccessCount: 1, accessCount: 1, disabled: true, @@ -128,6 +131,7 @@ extension SendListState { type: .text, file: nil, text: nil, + data: nil, maxAccessCount: nil, accessCount: 0, disabled: false, @@ -151,6 +155,7 @@ extension SendListState { type: .text, file: nil, text: nil, + data: nil, maxAccessCount: nil, accessCount: 0, disabled: false, @@ -174,6 +179,7 @@ extension SendListState { type: .text, file: nil, text: nil, + data: nil, maxAccessCount: 1, accessCount: 1, disabled: true, @@ -210,6 +216,7 @@ extension SendListState { type: .file, file: nil, text: nil, + data: nil, maxAccessCount: nil, accessCount: 0, disabled: false, @@ -233,6 +240,7 @@ extension SendListState { type: .text, file: nil, text: nil, + data: nil, maxAccessCount: nil, accessCount: 0, disabled: false, @@ -256,6 +264,7 @@ extension SendListState { type: .text, file: nil, text: nil, + data: nil, maxAccessCount: 1, accessCount: 1, disabled: true, diff --git a/BitwardenShared/UI/Tools/Send/SendItem/AddEditSendItem/AddEditSendItemState.swift b/BitwardenShared/UI/Tools/Send/SendItem/AddEditSendItem/AddEditSendItemState.swift index 683b66d9d1..23a386a490 100644 --- a/BitwardenShared/UI/Tools/Send/SendItem/AddEditSendItem/AddEditSendItemState.swift +++ b/BitwardenShared/UI/Tools/Send/SendItem/AddEditSendItem/AddEditSendItemState.swift @@ -263,6 +263,8 @@ extension AddEditSendItemState { type: sdkType, file: type == .file ? newFileView() : nil, text: type == .text ? newTextView() : nil, + // The app only creates v1 sends, which carry no send item payload. + data: nil, maxAccessCount: maximumAccessCount == 0 ? nil : UInt32(maximumAccessCount), accessCount: 0, // Defaulting to `0`, since the API ignores the values we set here. disabled: isDeactivateThisSendOn, diff --git a/project-common.yml b/project-common.yml index 26f2b31cd7..4784be185a 100644 --- a/project-common.yml +++ b/project-common.yml @@ -14,7 +14,7 @@ include: packages: BitwardenSdk: url: https://github.com/bitwarden/sdk-swift - revision: b7e7be7e7f5adde3cafcb27d79fac80a53c5c3c8 # 3.0.0-7742-9794da5 + revision: d90abf9f6c11cfacb66b567ae201c9321a3e0eea # 3.0.0-7918-e132bb1 Firebase: url: https://github.com/firebase/firebase-ios-sdk exactVersion: 12.14.0