Skip to content

Commit

Permalink
PM-12312: Update autofill setup progress when account is created and …
Browse files Browse the repository at this point in the history
…autofill is enabled (#963)
  • Loading branch information
matt-livefront authored Sep 24, 2024
1 parent 26ddba5 commit 6827509
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
10 changes: 9 additions & 1 deletion BitwardenShared/Core/Auth/Services/AuthService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,9 @@ class DefaultAuthService: AuthService { // swiftlint:disable:this type_body_leng
/// The service to get server-specified configuration
private let configService: ConfigService

/// The store which makes credential identities available to the system for AutoFill suggestions.
private let credentialIdentityStore: CredentialIdentityStore

/// The service used by the application to manage the environment settings.
private let environmentService: EnvironmentService

Expand Down Expand Up @@ -308,6 +311,8 @@ class DefaultAuthService: AuthService { // swiftlint:disable:this type_body_leng
/// - authAPIService: The API service used to make calls related to the auth process.
/// - clientService: The service that handles common client functionality such as encryption and decryption.
/// - configService: The service to get server-specified configuration.
/// - credentialIdentityStore: The store which makes credential identities available to the
/// system for AutoFill suggestions.
/// - environmentService: The service used by the application to manage the environment settings.
/// - keychainRepository: The repository used to manages keychain items.
/// - policyService: The service used by the application to manage the policy.
Expand All @@ -321,6 +326,7 @@ class DefaultAuthService: AuthService { // swiftlint:disable:this type_body_leng
authAPIService: AuthAPIService,
clientService: ClientService,
configService: ConfigService,
credentialIdentityStore: CredentialIdentityStore = ASCredentialIdentityStore.shared,
environmentService: EnvironmentService,
keychainRepository: KeychainRepository,
policyService: PolicyService,
Expand All @@ -333,6 +339,7 @@ class DefaultAuthService: AuthService { // swiftlint:disable:this type_body_leng
self.authAPIService = authAPIService
self.clientService = clientService
self.configService = configService
self.credentialIdentityStore = credentialIdentityStore
self.environmentService = environmentService
self.keychainRepository = keychainRepository
self.policyService = policyService
Expand Down Expand Up @@ -586,7 +593,8 @@ class DefaultAuthService: AuthService { // swiftlint:disable:this type_body_leng
}

if isNewAccount, await configService.getFeatureFlag(.nativeCreateAccountFlow) {
try await stateService.setAccountSetupAutofill(.incomplete)
let isAutofillEnabled = await credentialIdentityStore.isAutofillEnabled()
try await stateService.setAccountSetupAutofill(isAutofillEnabled ? .complete : .incomplete)
try await stateService.setAccountSetupVaultUnlock(.incomplete)
}
}
Expand Down
32 changes: 32 additions & 0 deletions BitwardenShared/Core/Auth/Services/AuthServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_
var client: MockHTTPClient!
var clientService: MockClientService!
var configService: MockConfigService!
var credentialIdentityStore: MockCredentialIdentityStore!
var environmentService: MockEnvironmentService!
var keychainRepository: MockKeychainRepository!
var stateService: MockStateService!
Expand Down Expand Up @@ -44,6 +45,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_
version: "2024.6.0"
)
))
credentialIdentityStore = MockCredentialIdentityStore()
environmentService = MockEnvironmentService()
keychainRepository = MockKeychainRepository()
policyService = MockPolicyService()
Expand All @@ -57,6 +59,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_
authAPIService: authAPIService,
clientService: clientService,
configService: configService,
credentialIdentityStore: credentialIdentityStore,
environmentService: environmentService,
keychainRepository: keychainRepository,
policyService: policyService,
Expand All @@ -75,6 +78,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_
client = nil
clientService = nil
configService = nil
credentialIdentityStore = nil
environmentService = nil
keychainRepository = nil
stateService = nil
Expand Down Expand Up @@ -393,6 +397,7 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_
appSettingsStore.appId = "App id"
clientService.mockAuth.hashPasswordResult = .success("hashed password")
configService.featureFlagsBool[.nativeCreateAccountFlow] = true
credentialIdentityStore.state.mockIsEnabled = false
stateService.preAuthEnvironmentUrls = EnvironmentUrlData(base: URL(string: "https://vault.bitwarden.com"))
systemDevice.modelIdentifier = "Model id"

Expand Down Expand Up @@ -452,6 +457,33 @@ class AuthServiceTests: BitwardenTestCase { // swiftlint:disable:this type_body_
assertGetConfig()
}

/// `loginWithMasterPassword(_:username:captchaToken:)` logs the user in with the password for
/// a newly created account and sets their autofill account setup progress to complete if
/// autofill is already enabled.
func test_loginWithMasterPassword_isNewAccount_autofillEnabled() async throws {
client.results = [
.httpSuccess(testData: .preLoginSuccess),
.httpSuccess(testData: .identityTokenSuccess),
]
appSettingsStore.appId = "App id"
clientService.mockAuth.hashPasswordResult = .success("hashed password")
configService.featureFlagsBool[.nativeCreateAccountFlow] = true
credentialIdentityStore.state.mockIsEnabled = true
stateService.preAuthEnvironmentUrls = EnvironmentUrlData(base: URL(string: "https://vault.bitwarden.com"))
systemDevice.modelIdentifier = "Model id"

// Attempt to login.
try await subject.loginWithMasterPassword(
"Password1234!",
username: "[email protected]",
captchaToken: nil,
isNewAccount: true
)

XCTAssertEqual(stateService.accountSetupAutofill["13512467-9cfe-43b0-969f-07534084764b"], .complete)
XCTAssertEqual(stateService.accountSetupVaultUnlock["13512467-9cfe-43b0-969f-07534084764b"], .incomplete)
}

/// `loginWithMasterPassword(_:username:captchaToken:)` logs in with the password updates AccountProfile's
/// `.forcePasswordResetReason` value if policy requires user to update password.
func test_loginWithMasterPassword_updatesAccountProfile() async throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class DefaultAutofillCredentialService {

extension DefaultAutofillCredentialService: AutofillCredentialService {
func isAutofillCredentialsEnabled() async -> Bool {
await identityStore.state().isEnabled
await identityStore.isAutofillEnabled()
}

func provideCredential(
Expand Down Expand Up @@ -477,6 +477,14 @@ protocol CredentialIdentityStore {
func state() async -> ASCredentialIdentityStoreState
}

extension CredentialIdentityStore {
/// Returns whether autofilling credentials via the extension is enabled.
///
func isAutofillEnabled() async -> Bool {
await state().isEnabled
}
}

// MARK: - ASCredentialIdentityStore+CredentialIdentityStore

extension ASCredentialIdentityStore: CredentialIdentityStore {}

0 comments on commit 6827509

Please sign in to comment.