mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
[PM-6688] Use AccountService as account source (#8893)
* Use account service to track accounts and active account * Remove state service active account Observables. * Add email verified to account service * Do not store account info on logged out accounts * Add account activity tracking to account service * Use last account activity from account service * migrate or replicate account service data * Add `AccountActivityService` that handles storing account last active data * Move active and next active user to account service * Remove authenticated accounts from state object * Fold account activity into account service * Fix builds * Fix desktop app switch * Fix logging out non active user * Expand helper to handle new authenticated accounts location * Prefer view observable to tons of async pipes * Fix `npm run test:types` * Correct user activity sorting test * Be more precise about log out messaging * Fix dev compare errors All stored values are serializable, the next step wasn't necessary and was erroring on some types that lack `toString`. * If the account in unlocked on load of lock component, navigate away from lock screen * Handle no users case for auth service statuses * Specify account to switch to * Filter active account out of inactive accounts * Prefer constructor init * Improve comparator * Use helper methods internally * Fixup component tests * Clarify name * Ensure accounts object has only valid userIds * Capitalize const values * Prefer descriptive, single-responsibility guards * Update libs/common/src/state-migrations/migrate.ts Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * Fix merge * Add user Id validation activity for undefined was being set, which was resulting in requests for the auth status of `"undefined"` (string) userId, due to key enumeration. These changes stop that at both locations, as well as account add for good measure. --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>
This commit is contained in:
@@ -128,6 +128,7 @@ describe("AuthRequestLoginStrategy", () => {
|
||||
|
||||
masterPasswordService.masterKeySubject.next(masterKey);
|
||||
cryptoService.decryptUserKeyWithMasterKey.mockResolvedValue(userKey);
|
||||
tokenService.decodeAccessToken.mockResolvedValue({ sub: mockUserId });
|
||||
|
||||
await authRequestLoginStrategy.logIn(credentials);
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ describe("LoginStrategy", () => {
|
||||
expect(messagingService.send).toHaveBeenCalledWith("loggedIn");
|
||||
});
|
||||
|
||||
it("throws if active account isn't found after being initialized", async () => {
|
||||
it("throws if new account isn't active after being initialized", async () => {
|
||||
const idTokenResponse = identityTokenResponseFactory();
|
||||
apiService.postIdentityToken.mockResolvedValue(idTokenResponse);
|
||||
|
||||
@@ -228,7 +228,8 @@ describe("LoginStrategy", () => {
|
||||
stateService.getVaultTimeoutAction.mockResolvedValue(mockVaultTimeoutAction);
|
||||
stateService.getVaultTimeout.mockResolvedValue(mockVaultTimeout);
|
||||
|
||||
accountService.activeAccountSubject.next(null);
|
||||
accountService.switchAccount = jest.fn(); // block internal switch to new account
|
||||
accountService.activeAccountSubject.next(null); // simulate no active account
|
||||
|
||||
await expect(async () => await passwordLoginStrategy.logIn(credentials)).rejects.toThrow();
|
||||
});
|
||||
|
||||
@@ -169,6 +169,12 @@ export abstract class LoginStrategy {
|
||||
const vaultTimeoutAction = await this.stateService.getVaultTimeoutAction({ userId });
|
||||
const vaultTimeout = await this.stateService.getVaultTimeout({ userId });
|
||||
|
||||
await this.accountService.addAccount(userId, {
|
||||
name: accountInformation.name,
|
||||
email: accountInformation.email,
|
||||
emailVerified: accountInformation.email_verified,
|
||||
});
|
||||
|
||||
// set access token and refresh token before account initialization so authN status can be accurate
|
||||
// User id will be derived from the access token.
|
||||
await this.tokenService.setTokens(
|
||||
@@ -178,6 +184,8 @@ export abstract class LoginStrategy {
|
||||
tokenResponse.refreshToken, // Note: CLI login via API key sends undefined for refresh token.
|
||||
);
|
||||
|
||||
await this.accountService.switchAccount(userId);
|
||||
|
||||
await this.stateService.addAccount(
|
||||
new Account({
|
||||
profile: {
|
||||
|
||||
@@ -164,6 +164,7 @@ describe("PasswordLoginStrategy", () => {
|
||||
|
||||
masterPasswordService.masterKeySubject.next(masterKey);
|
||||
cryptoService.decryptUserKeyWithMasterKey.mockResolvedValue(userKey);
|
||||
tokenService.decodeAccessToken.mockResolvedValue({ sub: userId });
|
||||
|
||||
await passwordLoginStrategy.logIn(credentials);
|
||||
|
||||
@@ -199,6 +200,7 @@ describe("PasswordLoginStrategy", () => {
|
||||
it("forces the user to update their master password on successful login when it does not meet master password policy requirements", async () => {
|
||||
passwordStrengthService.getPasswordStrength.mockReturnValue({ score: 0 } as any);
|
||||
policyService.evaluateMasterPassword.mockReturnValue(false);
|
||||
tokenService.decodeAccessToken.mockResolvedValue({ sub: userId });
|
||||
|
||||
const result = await passwordLoginStrategy.logIn(credentials);
|
||||
|
||||
@@ -213,6 +215,7 @@ describe("PasswordLoginStrategy", () => {
|
||||
it("forces the user to update their master password on successful 2FA login when it does not meet master password policy requirements", async () => {
|
||||
passwordStrengthService.getPasswordStrength.mockReturnValue({ score: 0 } as any);
|
||||
policyService.evaluateMasterPassword.mockReturnValue(false);
|
||||
tokenService.decodeAccessToken.mockResolvedValue({ sub: userId });
|
||||
|
||||
const token2FAResponse = new IdentityTwoFactorResponse({
|
||||
TwoFactorProviders: ["0"],
|
||||
|
||||
@@ -65,6 +65,7 @@ describe("UserDecryptionOptionsService", () => {
|
||||
await fakeAccountService.addAccount(givenUser, {
|
||||
name: "Test User 1",
|
||||
email: "test1@email.com",
|
||||
emailVerified: false,
|
||||
});
|
||||
await fakeStateProvider.setUserState(
|
||||
USER_DECRYPTION_OPTIONS,
|
||||
|
||||
Reference in New Issue
Block a user