diff --git a/apps/browser/src/auth/services/auth-request-answering/extension-auth-request-answering.service.spec.ts b/apps/browser/src/auth/services/auth-request-answering/extension-auth-request-answering.service.spec.ts index c39743ae94a..55c8f5df1b2 100644 --- a/apps/browser/src/auth/services/auth-request-answering/extension-auth-request-answering.service.spec.ts +++ b/apps/browser/src/auth/services/auth-request-answering/extension-auth-request-answering.service.spec.ts @@ -2,6 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { of } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AuthRequestAnsweringService } from "@bitwarden/common/auth/abstractions/auth-request-answering/auth-request-answering.service.abstraction"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthServerNotificationTags } from "@bitwarden/common/auth/enums/auth-server-notification-tags"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; @@ -31,7 +32,7 @@ describe("ExtensionAuthRequestAnsweringService", () => { let platformUtilsService: MockProxy; let systemNotificationsService: MockProxy; - let sut: ExtensionAuthRequestAnsweringService; + let sut: AuthRequestAnsweringService; const userId = "9f4c3452-6a45-48af-a7d0-74d3e8b65e4c" as UserId; const authRequestId = "auth-request-id-123"; diff --git a/apps/desktop/src/auth/services/auth-request-answering/desktop-auth-request-answering.service.spec.ts b/apps/desktop/src/auth/services/auth-request-answering/desktop-auth-request-answering.service.spec.ts index 220055f0206..bd66dcad505 100644 --- a/apps/desktop/src/auth/services/auth-request-answering/desktop-auth-request-answering.service.spec.ts +++ b/apps/desktop/src/auth/services/auth-request-answering/desktop-auth-request-answering.service.spec.ts @@ -2,6 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { of } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AuthRequestAnsweringService } from "@bitwarden/common/auth/abstractions/auth-request-answering/auth-request-answering.service.abstraction"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; @@ -20,7 +21,7 @@ describe("DesktopAuthRequestAnsweringService", () => { let pendingAuthRequestsState: MockProxy; let i18nService: MockProxy; - let sut: DesktopAuthRequestAnsweringService; + let sut: AuthRequestAnsweringService; const userId = "9f4c3452-6a45-48af-a7d0-74d3e8b65e4c" as UserId; const authRequestId = "auth-request-id-123"; diff --git a/libs/common/src/auth/abstractions/auth-request-answering/auth-request-answering.service.abstraction.ts b/libs/common/src/auth/abstractions/auth-request-answering/auth-request-answering.service.abstraction.ts index 7881e0f1a80..60e671661d1 100644 --- a/libs/common/src/auth/abstractions/auth-request-answering/auth-request-answering.service.abstraction.ts +++ b/libs/common/src/auth/abstractions/auth-request-answering/auth-request-answering.service.abstraction.ts @@ -1,5 +1,6 @@ import { Observable } from "rxjs"; +import { SystemNotificationEvent } from "@bitwarden/common/platform/system-notifications/system-notifications.service"; import { UserId } from "@bitwarden/user-core"; export abstract class AuthRequestAnsweringService { @@ -8,8 +9,7 @@ export abstract class AuthRequestAnsweringService { * later time. Even in the event the dialog is shown immediately, this will write to global state * so that even if someone closes a window or a popup and comes back, it could be processed later. * Only way to clear out the global state is to respond to the auth request. - * - * Currently implemented on Extension and Desktop. + * - Implemented on Extension and Desktop. * * @param userId The UserId that the auth request is for. * @param authRequestId The id of the auth request that is to be processed. @@ -29,9 +29,18 @@ export abstract class AuthRequestAnsweringService { /** * Sets up listeners for scenarios where the user unlocks and we want to process * any pending auth requests in state. - * - Implemented in Extension and Desktop * * @param destroy$ The destroy$ observable from the caller */ abstract setupUnlockListenersForProcessingAuthRequests(destroy$: Observable): void; + + /** + * When a system notification is clicked, this method is used to process that event. + * - Implemented on Extension only. + * - Desktop does not implement this method because click handling is already setup in + * electron-main-messaging.service.ts. + * + * @param event The event passed in. Check initNotificationSubscriptions in main.background.ts. + */ + abstract handleAuthRequestNotificationClicked(event: SystemNotificationEvent): Promise; } diff --git a/libs/common/src/auth/services/auth-request-answering/default-auth-request-answering.service.spec.ts b/libs/common/src/auth/services/auth-request-answering/default-auth-request-answering.service.spec.ts index 6de05949e17..5fc4e9114fc 100644 --- a/libs/common/src/auth/services/auth-request-answering/default-auth-request-answering.service.spec.ts +++ b/libs/common/src/auth/services/auth-request-answering/default-auth-request-answering.service.spec.ts @@ -6,6 +6,10 @@ import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { + ButtonLocation, + SystemNotificationEvent, +} from "@bitwarden/common/platform/system-notifications/system-notifications.service"; import { UserId } from "@bitwarden/user-core"; import { AuthRequestAnsweringService } from "../../abstractions/auth-request-answering/auth-request-answering.service.abstraction"; @@ -399,4 +403,22 @@ describe("DefaultAuthRequestAnsweringService", () => { }); }); }); + + describe("handleAuthRequestNotificationClicked()", () => { + it("should throw an error", async () => { + // Arrange + const event: SystemNotificationEvent = { + id: "123", + buttonIdentifier: ButtonLocation.NotificationButton, + }; + + // Act + const promise = sut.handleAuthRequestNotificationClicked(event); + + // Assert + await expect(promise).rejects.toThrow( + "handleAuthRequestNotificationClicked() not implemented for this client", + ); + }); + }); }); diff --git a/libs/common/src/auth/services/auth-request-answering/default-auth-request-answering.service.ts b/libs/common/src/auth/services/auth-request-answering/default-auth-request-answering.service.ts index 90713366bb8..190476fd04e 100644 --- a/libs/common/src/auth/services/auth-request-answering/default-auth-request-answering.service.ts +++ b/libs/common/src/auth/services/auth-request-answering/default-auth-request-answering.service.ts @@ -19,6 +19,7 @@ import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/for import { getOptionalUserId, getUserId } from "@bitwarden/common/auth/services/account.service"; import { MasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { SystemNotificationEvent } from "@bitwarden/common/platform/system-notifications/system-notifications.service"; import { UserId } from "@bitwarden/user-core"; import { AuthRequestAnsweringService } from "../../abstractions/auth-request-answering/auth-request-answering.service.abstraction"; @@ -113,4 +114,8 @@ export class DefaultAuthRequestAnsweringService implements AuthRequestAnsweringS } } } + + async handleAuthRequestNotificationClicked(event: SystemNotificationEvent): Promise { + throw new Error("handleAuthRequestNotificationClicked() not implemented for this client"); + } } diff --git a/libs/common/src/auth/services/auth-request-answering/noop-auth-request-answering.service.ts b/libs/common/src/auth/services/auth-request-answering/noop-auth-request-answering.service.ts index 416e6d06833..38e51e697e5 100644 --- a/libs/common/src/auth/services/auth-request-answering/noop-auth-request-answering.service.ts +++ b/libs/common/src/auth/services/auth-request-answering/noop-auth-request-answering.service.ts @@ -1,3 +1,4 @@ +import { SystemNotificationEvent } from "@bitwarden/common/platform/system-notifications/system-notifications.service"; import { UserId } from "@bitwarden/user-core"; import { AuthRequestAnsweringService } from "../../abstractions/auth-request-answering/auth-request-answering.service.abstraction"; @@ -6,5 +7,14 @@ export class NoopAuthRequestAnsweringService implements AuthRequestAnsweringServ async userMeetsConditionsToShowApprovalDialog(userId: UserId): Promise { throw new Error("userMeetsConditionsToShowApprovalDialog() not implemented for this client"); } - setupUnlockListenersForProcessingAuthRequests(): void {} + + setupUnlockListenersForProcessingAuthRequests(): void { + throw new Error( + "setupUnlockListenersForProcessingAuthRequests() not implemented for this client", + ); + } + + async handleAuthRequestNotificationClicked(event: SystemNotificationEvent): Promise { + throw new Error("handleAuthRequestNotificationClicked() not implemented for this client"); + } }