From 9f7e11b09d8588b1ccaac6c648e93e6ecc318417 Mon Sep 17 00:00:00 2001 From: Federico Maccaroni Date: Thu, 21 Nov 2024 15:18:55 -0300 Subject: [PATCH] PM-15119 Fix issue where SSH Key item was not able to be cloned. Also enabled the ssh-key-vault-item to be remotely configured. --- .../Platform/Models/Enum/FeatureFlag.swift | 2 +- .../Models/Enum/FeatureFlagTests.swift | 2 +- .../AddEditItemProcessorTests.swift | 64 +++++++++++++------ .../AddEditSSHKeyItem/SSHKeyItemState.swift | 9 +++ .../UI/Vault/VaultItem/CipherItemState.swift | 2 +- 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift b/BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift index 036d3aae4..e5121e127 100644 --- a/BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift +++ b/BitwardenShared/Core/Platform/Models/Enum/FeatureFlag.swift @@ -85,7 +85,6 @@ enum FeatureFlag: String, CaseIterable, Codable { .importLoginsFlow, .nativeCarouselFlow, .nativeCreateAccountFlow, - .sshKeyVaultItem, .testLocalFeatureFlag, .testLocalInitialBoolFlag, .testLocalInitialIntFlag, @@ -93,6 +92,7 @@ enum FeatureFlag: String, CaseIterable, Codable { false case .emailVerification, .refactorSsoDetailsEndpoint, + .sshKeyVaultItem, .testRemoteFeatureFlag, .testRemoteInitialBoolFlag, .testRemoteInitialIntFlag, diff --git a/BitwardenShared/Core/Platform/Models/Enum/FeatureFlagTests.swift b/BitwardenShared/Core/Platform/Models/Enum/FeatureFlagTests.swift index 2c0558ea2..49a4dc27e 100644 --- a/BitwardenShared/Core/Platform/Models/Enum/FeatureFlagTests.swift +++ b/BitwardenShared/Core/Platform/Models/Enum/FeatureFlagTests.swift @@ -16,6 +16,7 @@ final class FeatureFlagTests: BitwardenTestCase { func test_isRemotelyConfigured() { XCTAssertTrue(FeatureFlag.emailVerification.isRemotelyConfigured) XCTAssertTrue(FeatureFlag.refactorSsoDetailsEndpoint.isRemotelyConfigured) + XCTAssertTrue(FeatureFlag.sshKeyVaultItem.isRemotelyConfigured) XCTAssertTrue(FeatureFlag.testRemoteInitialBoolFlag.isRemotelyConfigured) XCTAssertTrue(FeatureFlag.testRemoteInitialIntFlag.isRemotelyConfigured) XCTAssertTrue(FeatureFlag.testRemoteInitialStringFlag.isRemotelyConfigured) @@ -25,7 +26,6 @@ final class FeatureFlagTests: BitwardenTestCase { XCTAssertFalse(FeatureFlag.importLoginsFlow.isRemotelyConfigured) XCTAssertFalse(FeatureFlag.nativeCarouselFlow.isRemotelyConfigured) XCTAssertFalse(FeatureFlag.nativeCreateAccountFlow.isRemotelyConfigured) - XCTAssertFalse(FeatureFlag.sshKeyVaultItem.isRemotelyConfigured) XCTAssertFalse(FeatureFlag.testLocalFeatureFlag.isRemotelyConfigured) XCTAssertFalse(FeatureFlag.testLocalInitialBoolFlag.isRemotelyConfigured) XCTAssertFalse(FeatureFlag.testLocalInitialIntFlag.isRemotelyConfigured) diff --git a/BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditItemProcessorTests.swift b/BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditItemProcessorTests.swift index d97cf3dd1..64a26cf40 100644 --- a/BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditItemProcessorTests.swift +++ b/BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditItemProcessorTests.swift @@ -1086,26 +1086,6 @@ class AddEditItemProcessorTests: BitwardenTestCase { XCTAssertEqual(coordinator.routes.last, .dismiss()) } - /// `perform(_:)` with `.savePressed` saves the item for SSH Key - @MainActor - func test_perform_savePressed_sshKey() async { - subject.state.type = .sshKey - subject.state.name = "sshKey" - - await subject.perform(.savePressed) - - try XCTAssertEqual( - XCTUnwrap(vaultRepository.addCipherCiphers.first).type, - .sshKey - ) - - try XCTAssertEqual( - XCTUnwrap(vaultRepository.addCipherCiphers.first).name, - "sshKey" - ) - XCTAssertEqual(coordinator.routes.last, .dismiss()) - } - /// `perform(_:)` with `.savePressed` saves the item. @MainActor func test_perform_savePressed_card() async throws { @@ -1178,6 +1158,50 @@ class AddEditItemProcessorTests: BitwardenTestCase { XCTAssertEqual(coordinator.routes.last, .dismiss()) } + /// `perform(_:)` with `.savePressed` saves the item for `.sshKey`. + @MainActor + func test_perform_savePressed_sshKey() async throws { + subject.state.name = "vault item" + subject.state.type = .sshKey + let expectedSSHKeyItemState = SSHKeyItemState( + canViewPrivateKey: true, + isPrivateKeyVisible: false, + privateKey: "privateKey", + publicKey: "publicKey", + keyFingerprint: "fingerprint" + ) + subject.state.sshKeyState = expectedSSHKeyItemState + await subject.perform(.savePressed) + + try XCTAssertEqual( + XCTUnwrap(vaultRepository.addCipherCiphers.first).creationDate.timeIntervalSince1970, + Date().timeIntervalSince1970, + accuracy: 1 + ) + try XCTAssertEqual( + XCTUnwrap(vaultRepository.addCipherCiphers.first).revisionDate.timeIntervalSince1970, + Date().timeIntervalSince1970, + accuracy: 1 + ) + + let added = try XCTUnwrap(vaultRepository.addCipherCiphers.first) + XCTAssertNil(added.identity) + XCTAssertNil(added.login) + XCTAssertNil(added.secureNote) + XCTAssertNotNil(added.sshKey) + XCTAssertNil(added.card) + XCTAssertEqual(added.sshKeyItemState(), expectedSSHKeyItemState) + let unwrappedState = try XCTUnwrap(subject.state as? CipherItemState) + XCTAssertEqual( + added, + unwrappedState + .newCipherView( + creationDate: vaultRepository.addCipherCiphers[0].creationDate + ) + ) + XCTAssertEqual(coordinator.routes.last, .dismiss()) + } + /// `perform(_:)` with `.savePressed` in the app extension completes the autofill request if a /// username and password was entered. @MainActor diff --git a/BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditSSHKeyItem/SSHKeyItemState.swift b/BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditSSHKeyItem/SSHKeyItemState.swift index 293073d9c..5be1b8dc4 100644 --- a/BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditSSHKeyItem/SSHKeyItemState.swift +++ b/BitwardenShared/UI/Vault/VaultItem/AddEditItem/AddEditSSHKeyItem/SSHKeyItemState.swift @@ -19,4 +19,13 @@ struct SSHKeyItemState: Equatable, Sendable { /// The fingerprint of the SSH key. var keyFingerprint: String = "" + + /// Gets the `SshKeyView` from this state. + var sshKeyView: SshKeyView { + SshKeyView( + privateKey: privateKey, + publicKey: publicKey, + fingerprint: keyFingerprint + ) + } } diff --git a/BitwardenShared/UI/Vault/VaultItem/CipherItemState.swift b/BitwardenShared/UI/Vault/VaultItem/CipherItemState.swift index 3c65b885b..1f6fd4d39 100644 --- a/BitwardenShared/UI/Vault/VaultItem/CipherItemState.swift +++ b/BitwardenShared/UI/Vault/VaultItem/CipherItemState.swift @@ -366,7 +366,7 @@ extension CipherItemState { identity: type == .identity ? identityState.identityView : nil, card: type == .card ? cardItemState.cardView : nil, secureNote: type == .secureNote ? .init(type: .generic) : nil, - sshKey: nil, // SSH keys cannot be created in mobile yet. + sshKey: type == .sshKey ? sshKeyState.sshKeyView : nil, favorite: isFavoriteOn, reprompt: isMasterPasswordRePromptOn ? .password : .none, organizationUseTotp: false,