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:
@@ -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>;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user