mirror of
https://github.com/bitwarden/browser
synced 2025-12-21 18:53:29 +00:00
fix(Multi-Account-Logout: [Auth/PM-19555] Fix multi account logout on lock screens not redirecting properly (#14630)
* PM-19555 - LogoutService - build abstraction, default, and extension service and register with service modules * PM-19555 - Lock Comp - use logoutService * PM-19555 - LoginDecryptionOptions - Use logout service which removed need for extension-login-decryption-options.service * PM-19555 - AccountSwitcher logic update - (1) Use logout service + redirect guard routing (2) Remove logout method from account switcher service (3) use new NewActiveUser type * PM-19555 - Extension - Acct Switcher comp - clean up TODOs * PM-19555 - Add TODOs for remaining tech debt * PM-19555 - Add tests for new logout services. * PM-19555 - Extension - LoginInitiated - show acct switcher b/c user is AuthN * PM-19555 - Add TODO to replace LogoutCallback with LogoutService * PM-19555 WIP * PM-19555 - Extension App Comp - account switching to account in TDE locked state works now. * PM-19555 - Extension App Comp - add docs * PM-19555 - Extension App Comp - add early return * PM-19555 - Desktop App Comp - add handling for TDE lock case to switch account logic. * PM-19555 - Extension - Account Component - if account unlocked go to vault * PM-19555 - Per PR feedback, clean up unnecessary nullish coalescing operator. * PM-19555 - Extension - AppComponent - fix everHadUserKey merge issue * PM-19555 - PR feedback - refactor switchAccount and locked message handling on browser & desktop to require user id. I audited all callsites for both to ensure this *shouldn't* error.
This commit is contained in:
@@ -6,3 +6,4 @@ export * from "./user-decryption-options.service.abstraction";
|
||||
export * from "./auth-request.service.abstraction";
|
||||
export * from "./login-approval-component.service.abstraction";
|
||||
export * from "./login-success-handler.service";
|
||||
export * from "./logout.service";
|
||||
|
||||
19
libs/auth/src/common/abstractions/logout.service.ts
Normal file
19
libs/auth/src/common/abstractions/logout.service.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { LogoutReason } from "../types";
|
||||
|
||||
export interface NewActiveUser {
|
||||
userId: UserId;
|
||||
authenticationStatus: AuthenticationStatus;
|
||||
}
|
||||
|
||||
export abstract class LogoutService {
|
||||
/**
|
||||
* Logs out the user.
|
||||
* @param userId The user id.
|
||||
* @param logoutReason The optional reason for logging out.
|
||||
* @returns The new active user or undefined if there isn't a new active account.
|
||||
*/
|
||||
abstract logout(userId: UserId, logoutReason?: LogoutReason): Promise<NewActiveUser | undefined>;
|
||||
}
|
||||
@@ -7,3 +7,4 @@ export * from "./auth-request/auth-request-api.service";
|
||||
export * from "./accounts/lock.service";
|
||||
export * from "./login-success-handler/default-login-success-handler.service";
|
||||
export * from "./sso-redirect/sso-url.service";
|
||||
export * from "./logout/default-logout.service";
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { MockProxy, mock } from "jest-mock-extended";
|
||||
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { LogoutService } from "../../abstractions";
|
||||
import { LogoutReason } from "../../types";
|
||||
|
||||
import { DefaultLogoutService } from "./default-logout.service";
|
||||
|
||||
describe("DefaultLogoutService", () => {
|
||||
let logoutService: LogoutService;
|
||||
let messagingService: MockProxy<MessagingService>;
|
||||
|
||||
beforeEach(() => {
|
||||
messagingService = mock<MessagingService>();
|
||||
logoutService = new DefaultLogoutService(messagingService);
|
||||
});
|
||||
|
||||
it("instantiates", () => {
|
||||
expect(logoutService).not.toBeFalsy();
|
||||
});
|
||||
|
||||
describe("logout", () => {
|
||||
it("sends logout message without a logout reason when not provided", async () => {
|
||||
const userId = "1" as UserId;
|
||||
|
||||
await logoutService.logout(userId);
|
||||
|
||||
expect(messagingService.send).toHaveBeenCalledWith("logout", { userId });
|
||||
});
|
||||
|
||||
it("sends logout message with a logout reason when provided", async () => {
|
||||
const userId = "1" as UserId;
|
||||
const logoutReason: LogoutReason = "vaultTimeout";
|
||||
await logoutService.logout(userId, logoutReason);
|
||||
expect(messagingService.send).toHaveBeenCalledWith("logout", { userId, logoutReason });
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
|
||||
import { LogoutService, NewActiveUser } from "../../abstractions/logout.service";
|
||||
import { LogoutReason } from "../../types";
|
||||
|
||||
export class DefaultLogoutService implements LogoutService {
|
||||
constructor(protected messagingService: MessagingService) {}
|
||||
async logout(userId: UserId, logoutReason?: LogoutReason): Promise<NewActiveUser | undefined> {
|
||||
this.messagingService.send("logout", { userId, logoutReason });
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user