1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 00:33:44 +00:00

[PM-7169][PM-5267] Remove auth status from account info (#8539)

* remove active account unlocked from state service

* Remove status from account service `AccountInfo`

* Fixup lingering usages of status

Fixup missed factories

* Fixup account info usage

* fixup CLI build

* Fixup current account type

* Add helper for all auth statuses to auth service

* Fix tests

* Uncomment mistakenly commented code

* Rework logged out account exclusion tests

* Correct test description

* Avoid getters returning observables

* fixup type
This commit is contained in:
Matt Gibson
2024-04-12 02:25:45 -05:00
committed by GitHub
parent c7ea35280d
commit 8d698d9d84
31 changed files with 200 additions and 304 deletions

View File

@@ -33,10 +33,6 @@ export type InitOptions = {
export abstract class StateService<T extends Account = Account> {
accounts$: Observable<{ [userId: string]: T }>;
activeAccount$: Observable<string>;
/**
* @deprecated use accountService.activeAccount$ instead
*/
activeAccountUnlocked$: Observable<boolean>;
addAccount: (account: T) => Promise<void>;
setActiveUser: (userId: string) => Promise<void>;

View File

@@ -4,7 +4,6 @@ import { firstValueFrom, of, tap } from "rxjs";
import { FakeAccountService, mockAccountServiceWith } from "../../../spec/fake-account-service";
import { FakeActiveUserState, FakeSingleUserState } from "../../../spec/fake-state";
import { FakeStateProvider } from "../../../spec/fake-state-provider";
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
import { FakeMasterPasswordService } from "../../auth/services/master-password/fake-master-password.service";
import { CsprngArray } from "../../types/csprng";
import { UserId } from "../../types/guid";
@@ -273,15 +272,6 @@ describe("cryptoService", () => {
await expect(cryptoService.setUserKey(null, mockUserId)).rejects.toThrow("No key provided.");
});
it("should update the user's lock state", async () => {
await cryptoService.setUserKey(mockUserKey, mockUserId);
expect(accountService.mock.setAccountStatus).toHaveBeenCalledWith(
mockUserId,
AuthenticationStatus.Unlocked,
);
});
describe("Pin Key refresh", () => {
let cryptoSvcMakePinKey: jest.SpyInstance;
const protectedPin =
@@ -353,23 +343,6 @@ describe("cryptoService", () => {
accountService.activeAccount$ = accountService.activeAccountSubject.asObservable();
});
it("sets the maximum account status of the active user id to locked when user id is not specified", async () => {
await cryptoService.clearKeys();
expect(accountService.mock.setMaxAccountStatus).toHaveBeenCalledWith(
mockUserId,
AuthenticationStatus.Locked,
);
});
it("sets the maximum account status of the specified user id to locked when user id is specified", async () => {
const userId = "someOtherUser" as UserId;
await cryptoService.clearKeys(userId);
expect(accountService.mock.setMaxAccountStatus).toHaveBeenCalledWith(
userId,
AuthenticationStatus.Locked,
);
});
describe.each([
USER_ENCRYPTED_ORGANIZATION_KEYS,
USER_ENCRYPTED_PROVIDER_KEYS,

View File

@@ -7,7 +7,6 @@ import { ProfileProviderOrganizationResponse } from "../../admin-console/models/
import { ProfileProviderResponse } from "../../admin-console/models/response/profile-provider.response";
import { AccountService } from "../../auth/abstractions/account.service";
import { InternalMasterPasswordServiceAbstraction } from "../../auth/abstractions/master-password.service.abstraction";
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
import { KdfConfig } from "../../auth/models/domain/kdf-config";
import { Utils } from "../../platform/misc/utils";
import { CsprngArray } from "../../types/csprng";
@@ -152,8 +151,6 @@ export class CryptoService implements CryptoServiceAbstraction {
[userId, key] = await this.stateProvider.setUserState(USER_KEY, key, userId);
await this.stateProvider.setUserState(USER_EVER_HAD_USER_KEY, true, userId);
await this.accountService.setAccountStatus(userId, AuthenticationStatus.Unlocked);
await this.storeAdditionalKeys(key, userId);
}
@@ -256,14 +253,13 @@ export class CryptoService implements CryptoServiceAbstraction {
* Clears the user key. Clears all stored versions of the user keys as well, such as the biometrics key
* @param userId The desired user
*/
async clearUserKey(userId: UserId): Promise<void> {
private async clearUserKey(userId: UserId): Promise<void> {
if (userId == null) {
// nothing to do
return;
}
// Set userId to ensure we have one for the account status update
await this.stateProvider.setUserState(USER_KEY, null, userId);
await this.accountService.setMaxAccountStatus(userId, AuthenticationStatus.Locked);
await this.clearAllStoredUserKeys(userId);
}

View File

@@ -2,7 +2,6 @@ import { firstValueFrom } from "rxjs";
import { FakeStateProvider, awaitAsync } from "../../../spec";
import { FakeAccountService } from "../../../spec/fake-account-service";
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
import { UserId } from "../../types/guid";
import { CloudRegion, Region } from "../abstractions/environment.service";
@@ -32,12 +31,10 @@ describe("EnvironmentService", () => {
[testUser]: {
name: "name",
email: "email",
status: AuthenticationStatus.Locked,
},
[alternateTestUser]: {
name: "name",
email: "email",
status: AuthenticationStatus.Locked,
},
});
stateProvider = new FakeStateProvider(accountService);
@@ -50,7 +47,6 @@ describe("EnvironmentService", () => {
id: userId,
email: "test@example.com",
name: `Test Name ${userId}`,
status: AuthenticationStatus.Unlocked,
});
await awaitAsync();
};

View File

@@ -1,9 +1,8 @@
import { BehaviorSubject, Observable, map } from "rxjs";
import { BehaviorSubject } from "rxjs";
import { Jsonify, JsonValue } from "type-fest";
import { AccountService } from "../../auth/abstractions/account.service";
import { TokenService } from "../../auth/abstractions/token.service";
import { AuthenticationStatus } from "../../auth/enums/authentication-status";
import { AdminAuthRequestStorable } from "../../auth/models/domain/admin-auth-req-storable";
import { KdfConfig } from "../../auth/models/domain/kdf-config";
import { BiometricKey } from "../../auth/types/biometric-key";
@@ -68,8 +67,6 @@ export class StateService<
protected activeAccountSubject = new BehaviorSubject<string | null>(null);
activeAccount$ = this.activeAccountSubject.asObservable();
activeAccountUnlocked$: Observable<boolean>;
private hasBeenInited = false;
protected isRecoveredSession = false;
@@ -89,13 +86,7 @@ export class StateService<
protected tokenService: TokenService,
private migrationRunner: MigrationRunner,
protected useAccountCache: boolean = true,
) {
this.activeAccountUnlocked$ = this.accountService.activeAccount$.pipe(
map((a) => {
return a?.status === AuthenticationStatus.Unlocked;
}),
);
}
) {}
async init(initOptions: InitOptions = {}): Promise<void> {
// Deconstruct and apply defaults
@@ -151,7 +142,6 @@ export class StateService<
await this.accountService.addAccount(state.activeUserId as UserId, {
name: activeDiskAccount.profile.name,
email: activeDiskAccount.profile.email,
status: AuthenticationStatus.LoggedOut,
});
}
await this.accountService.switchAccount(state.activeUserId as UserId);
@@ -177,16 +167,7 @@ export class StateService<
// TODO: Temporary update to avoid routing all account status changes through account service for now.
// The determination of state should be handled by the various services that control those values.
const token = await this.tokenService.getAccessToken(userId as UserId);
const autoKey = await this.getUserKeyAutoUnlock({ userId: userId });
const accountStatus =
token == null
? AuthenticationStatus.LoggedOut
: autoKey == null
? AuthenticationStatus.Locked
: AuthenticationStatus.Unlocked;
await this.accountService.addAccount(userId as UserId, {
status: accountStatus,
name: diskAccount.profile.name,
email: diskAccount.profile.email,
});
@@ -206,7 +187,6 @@ export class StateService<
await this.setLastActive(new Date().getTime(), { userId: account.profile.userId });
// TODO: Temporary update to avoid routing all account status changes through account service for now.
await this.accountService.addAccount(account.profile.userId as UserId, {
status: AuthenticationStatus.Locked,
name: account.profile.name,
email: account.profile.email,
});
@@ -1406,8 +1386,6 @@ export class StateService<
return state;
});
// TODO: Invert this logic, we should remove accounts based on logged out emit
await this.accountService.setAccountStatus(userId as UserId, AuthenticationStatus.LoggedOut);
}
// settings persist even on reset, and are not affected by this method

View File

@@ -9,7 +9,6 @@ import { Jsonify } from "type-fest";
import { awaitAsync, trackEmissions } from "../../../../spec";
import { FakeStorageService } from "../../../../spec/fake-storage.service";
import { AccountInfo } from "../../../auth/abstractions/account.service";
import { AuthenticationStatus } from "../../../auth/enums/authentication-status";
import { UserId } from "../../../types/guid";
import { StorageServiceProvider } from "../../services/storage-service.provider";
import { StateDefinition } from "../state-definition";
@@ -84,7 +83,6 @@ describe("DefaultActiveUserState", () => {
id: userId,
email: `test${id}@example.com`,
name: `Test User ${id}`,
status: AuthenticationStatus.Unlocked,
});
await awaitAsync();
};