From 25ada6f80f7f1ba14fc06d4755559727f480fc94 Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Mon, 4 Aug 2025 09:20:12 -0700 Subject: [PATCH] refactor(login-approval-component) [Auth/PM-14940] Update LoginApprovalComponent (#15511) - Renames the `LoginApprovalComponent` to `LoginApprovalDialogComponent` - Renames the property `notificationId` to `authRequestId` for clarity - Updates text content on the component --- apps/browser/src/_locales/en/messages.json | 19 -- apps/desktop/src/app/app.component.ts | 5 +- .../src/app/services/services.module.ts | 8 +- ...approval-dialog-component.service.spec.ts} | 22 +-- ...ogin-approval-dialog-component.service.ts} | 12 +- apps/desktop/src/locales/en/messages.json | 63 +++++-- .../device-management-old.component.ts | 4 +- apps/web/src/locales/en/messages.json | 19 -- .../device-management-item-group.component.ts | 7 +- .../device-management-table.component.ts | 7 +- ...-approval-dialog-component.service.spec.ts | 30 ++++ ...login-approval-dialog-component.service.ts | 16 ++ libs/angular/src/auth/login-approval/index.ts | 3 + ...l-dialog-component.service.abstraction.ts} | 4 +- .../login-approval-dialog.component.html} | 16 +- .../login-approval-dialog.component.spec.ts} | 61 ++++--- .../login-approval-dialog.component.ts} | 167 ++++++++++-------- .../src/services/jslib-services.module.ts | 8 +- libs/auth/src/angular/index.ts | 4 - ...t-login-approval-component.service.spec.ts | 25 --- ...efault-login-approval-component.service.ts | 16 -- libs/auth/src/common/abstractions/index.ts | 1 - 22 files changed, 261 insertions(+), 256 deletions(-) rename apps/desktop/src/auth/login/{desktop-login-approval-component.service.spec.ts => desktop-login-approval-dialog-component.service.spec.ts} (75%) rename apps/desktop/src/auth/login/{desktop-login-approval-component.service.ts => desktop-login-approval-dialog-component.service.ts} (65%) create mode 100644 libs/angular/src/auth/login-approval/default-login-approval-dialog-component.service.spec.ts create mode 100644 libs/angular/src/auth/login-approval/default-login-approval-dialog-component.service.ts create mode 100644 libs/angular/src/auth/login-approval/index.ts rename libs/{auth/src/common/abstractions/login-approval-component.service.abstraction.ts => angular/src/auth/login-approval/login-approval-dialog-component.service.abstraction.ts} (57%) rename libs/{auth/src/angular/login-approval/login-approval.component.html => angular/src/auth/login-approval/login-approval-dialog.component.html} (72%) rename libs/{auth/src/angular/login-approval/login-approval.component.spec.ts => angular/src/auth/login-approval/login-approval-dialog.component.spec.ts} (77%) rename libs/{auth/src/angular/login-approval/login-approval.component.ts => angular/src/auth/login-approval/login-approval-dialog.component.ts} (56%) delete mode 100644 libs/auth/src/angular/login-approval/default-login-approval-component.service.spec.ts delete mode 100644 libs/auth/src/angular/login-approval/default-login-approval-component.service.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index a1b41b44bfd..ad933c24875 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -3657,25 +3657,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "areYouTryingToAccessYourAccount": { - "message": "Are you trying to access your account?" - }, - "logInConfirmedForEmailOnDevice": { - "message": "Login confirmed for $EMAIL$ on $DEVICE$", - "placeholders": { - "email": { - "content": "$1", - "example": "name@example.com" - }, - "device": { - "content": "$2", - "example": "iOS" - } - } - }, - "youDeniedALogInAttemptFromAnotherDevice": { - "message": "You denied a login attempt from another device. If this really was you, try to log in with the device again." - }, "loginRequestHasAlreadyExpired": { "message": "Login request has already expired." }, diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index 72bad5befe9..b0c5eb03723 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -24,11 +24,12 @@ import { } from "rxjs"; import { CollectionService } from "@bitwarden/admin-console/common"; +import { LoginApprovalDialogComponent } from "@bitwarden/angular/auth/login-approval"; import { DeviceTrustToastService } from "@bitwarden/angular/auth/services/device-trust-toast.service.abstraction"; import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref"; import { DocumentLangSetter } from "@bitwarden/angular/platform/i18n"; import { ModalService } from "@bitwarden/angular/services/modal.service"; -import { FingerprintDialogComponent, LoginApprovalComponent } from "@bitwarden/auth/angular"; +import { FingerprintDialogComponent } from "@bitwarden/auth/angular"; import { DESKTOP_SSO_CALLBACK, LogoutReason, @@ -476,7 +477,7 @@ export class AppComponent implements OnInit, OnDestroy { case "openLoginApproval": if (message.notificationId != null) { this.dialogService.closeAll(); - const dialogRef = LoginApprovalComponent.open(this.dialogService, { + const dialogRef = LoginApprovalDialogComponent.open(this.dialogService, { notificationId: message.notificationId, }); await firstValueFrom(dialogRef.closed); diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 1bd8924ac15..4482c38fc3a 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -5,6 +5,7 @@ import { Router } from "@angular/router"; import { Subject, merge } from "rxjs"; import { OrganizationUserApiService } from "@bitwarden/admin-console/common"; +import { LoginApprovalDialogComponentServiceAbstraction } from "@bitwarden/angular/auth/login-approval"; import { SetInitialPasswordService } from "@bitwarden/angular/auth/password-management/set-initial-password/set-initial-password.service.abstraction"; import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; import { @@ -31,7 +32,6 @@ import { } from "@bitwarden/auth/angular"; import { InternalUserDecryptionOptionsServiceAbstraction, - LoginApprovalComponentServiceAbstraction, LoginEmailService, SsoUrlService, } from "@bitwarden/auth/common"; @@ -107,7 +107,7 @@ import { import { LockComponentService } from "@bitwarden/key-management-ui"; import { DefaultSshImportPromptService, SshImportPromptService } from "@bitwarden/vault"; -import { DesktopLoginApprovalComponentService } from "../../auth/login/desktop-login-approval-component.service"; +import { DesktopLoginApprovalDialogComponentService } from "../../auth/login/desktop-login-approval-dialog-component.service"; import { DesktopLoginComponentService } from "../../auth/login/desktop-login-component.service"; import { DesktopTwoFactorAuthDuoComponentService } from "../../auth/services/desktop-two-factor-auth-duo-component.service"; import { DesktopAutofillSettingsService } from "../../autofill/services/desktop-autofill-settings.service"; @@ -444,8 +444,8 @@ const safeProviders: SafeProvider[] = [ deps: [], }), safeProvider({ - provide: LoginApprovalComponentServiceAbstraction, - useClass: DesktopLoginApprovalComponentService, + provide: LoginApprovalDialogComponentServiceAbstraction, + useClass: DesktopLoginApprovalDialogComponentService, deps: [I18nServiceAbstraction], }), safeProvider({ diff --git a/apps/desktop/src/auth/login/desktop-login-approval-component.service.spec.ts b/apps/desktop/src/auth/login/desktop-login-approval-dialog-component.service.spec.ts similarity index 75% rename from apps/desktop/src/auth/login/desktop-login-approval-component.service.spec.ts rename to apps/desktop/src/auth/login/desktop-login-approval-dialog-component.service.spec.ts index efe17960068..2ae584d7e7f 100644 --- a/apps/desktop/src/auth/login/desktop-login-approval-component.service.spec.ts +++ b/apps/desktop/src/auth/login/desktop-login-approval-dialog-component.service.spec.ts @@ -2,13 +2,13 @@ import { TestBed } from "@angular/core/testing"; import { mock, MockProxy } from "jest-mock-extended"; import { Subject } from "rxjs"; -import { LoginApprovalComponent } from "@bitwarden/auth/angular"; +import { LoginApprovalDialogComponent } from "@bitwarden/angular/auth/login-approval"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { DesktopLoginApprovalComponentService } from "./desktop-login-approval-component.service"; +import { DesktopLoginApprovalDialogComponentService } from "./desktop-login-approval-dialog-component.service"; -describe("DesktopLoginApprovalComponentService", () => { - let service: DesktopLoginApprovalComponentService; +describe("DesktopLoginApprovalDialogComponentService", () => { + let service: DesktopLoginApprovalDialogComponentService; let i18nService: MockProxy; let originalIpc: any; @@ -31,12 +31,12 @@ describe("DesktopLoginApprovalComponentService", () => { TestBed.configureTestingModule({ providers: [ - DesktopLoginApprovalComponentService, + DesktopLoginApprovalDialogComponentService, { provide: I18nServiceAbstraction, useValue: i18nService }, ], }); - service = TestBed.inject(DesktopLoginApprovalComponentService); + service = TestBed.inject(DesktopLoginApprovalDialogComponentService); }); afterEach(() => { @@ -54,7 +54,7 @@ describe("DesktopLoginApprovalComponentService", () => { const message = `Confirm access attempt for ${email}`; const closeText = "Close"; - const loginApprovalComponent = { email } as LoginApprovalComponent; + const loginApprovalDialogComponent = { email } as LoginApprovalDialogComponent; i18nService.t.mockImplementation((key: string) => { switch (key) { case "accountAccessRequested": @@ -71,18 +71,20 @@ describe("DesktopLoginApprovalComponentService", () => { jest.spyOn(ipc.platform, "isWindowVisible").mockResolvedValue(false); jest.spyOn(ipc.auth, "loginRequest").mockResolvedValue(); - await service.showLoginRequestedAlertIfWindowNotVisible(loginApprovalComponent.email); + await service.showLoginRequestedAlertIfWindowNotVisible(loginApprovalDialogComponent.email); expect(ipc.auth.loginRequest).toHaveBeenCalledWith(title, message, closeText); }); it("does not call ipc.auth.loginRequest when window is visible", async () => { - const loginApprovalComponent = { email: "test@bitwarden.com" } as LoginApprovalComponent; + const loginApprovalDialogComponent = { + email: "test@bitwarden.com", + } as LoginApprovalDialogComponent; jest.spyOn(ipc.platform, "isWindowVisible").mockResolvedValue(true); jest.spyOn(ipc.auth, "loginRequest"); - await service.showLoginRequestedAlertIfWindowNotVisible(loginApprovalComponent.email); + await service.showLoginRequestedAlertIfWindowNotVisible(loginApprovalDialogComponent.email); expect(ipc.auth.loginRequest).not.toHaveBeenCalled(); }); diff --git a/apps/desktop/src/auth/login/desktop-login-approval-component.service.ts b/apps/desktop/src/auth/login/desktop-login-approval-dialog-component.service.ts similarity index 65% rename from apps/desktop/src/auth/login/desktop-login-approval-component.service.ts rename to apps/desktop/src/auth/login/desktop-login-approval-dialog-component.service.ts index 3b4658f34c5..9c48f71990a 100644 --- a/apps/desktop/src/auth/login/desktop-login-approval-component.service.ts +++ b/apps/desktop/src/auth/login/desktop-login-approval-dialog-component.service.ts @@ -1,13 +1,15 @@ import { Injectable } from "@angular/core"; -import { DefaultLoginApprovalComponentService } from "@bitwarden/auth/angular"; -import { LoginApprovalComponentServiceAbstraction } from "@bitwarden/auth/common"; +import { + DefaultLoginApprovalDialogComponentService, + LoginApprovalDialogComponentServiceAbstraction, +} from "@bitwarden/angular/auth/login-approval"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; @Injectable() -export class DesktopLoginApprovalComponentService - extends DefaultLoginApprovalComponentService - implements LoginApprovalComponentServiceAbstraction +export class DesktopLoginApprovalDialogComponentService + extends DefaultLoginApprovalDialogComponentService + implements LoginApprovalDialogComponentServiceAbstraction { constructor(private i18nService: I18nServiceAbstraction) { super(); diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 97b1107056e..8b30bd85ec9 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -3027,9 +3027,6 @@ "message": "Toggle character count", "description": "'Character count' describes a feature that displays a number next to each character of the password." }, - "areYouTryingToAccessYourAccount": { - "message": "Are you trying to access your account?" - }, "accessAttemptBy": { "message": "Access attempt by $EMAIL$", "placeholders": { @@ -3039,6 +3036,50 @@ } } }, + "loginRequestApprovedForEmailOnDevice": { + "message": "Login request approved for $EMAIL$ on $DEVICE$", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + }, + "device": { + "content": "$2", + "example": "Web app - Chrome" + } + } + }, + "youDeniedLoginAttemptFromAnotherDevice": { + "message": "You denied a login attempt from another device. If this was you, try to log in with the device again." + }, + "webApp": { + "message": "Web app" + }, + "mobile": { + "message": "Mobile", + "description": "Mobile app" + }, + "extension": { + "message": "Extension", + "description": "Browser extension/addon" + }, + "desktop": { + "message": "Desktop", + "description": "Desktop app" + }, + "cli": { + "message": "CLI" + }, + "sdk": { + "message": "SDK", + "description": "Software Development Kit" + }, + "server": { + "message": "Server" + }, + "loginRequest": { + "message": "Login request" + }, "deviceType": { "message": "Device Type" }, @@ -3054,22 +3095,6 @@ "denyAccess": { "message": "Deny access" }, - "logInConfirmedForEmailOnDevice": { - "message": "Login confirmed for $EMAIL$ on $DEVICE$", - "placeholders": { - "email": { - "content": "$1", - "example": "name@example.com" - }, - "device": { - "content": "$2", - "example": "iOS" - } - } - }, - "youDeniedALogInAttemptFromAnotherDevice": { - "message": "You denied a login attempt from another device. If this really was you, try to log in with the device again." - }, "justNow": { "message": "Just now" }, diff --git a/apps/web/src/app/auth/settings/security/device-management-old.component.ts b/apps/web/src/app/auth/settings/security/device-management-old.component.ts index 556ba381acc..816da6e873f 100644 --- a/apps/web/src/app/auth/settings/security/device-management-old.component.ts +++ b/apps/web/src/app/auth/settings/security/device-management-old.component.ts @@ -3,7 +3,7 @@ import { Component, DestroyRef } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { firstValueFrom } from "rxjs"; -import { LoginApprovalComponent } from "@bitwarden/auth/angular"; +import { LoginApprovalDialogComponent } from "@bitwarden/angular/auth/login-approval"; import { AuthRequestApiServiceAbstraction } from "@bitwarden/auth/common"; import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction"; import { @@ -325,7 +325,7 @@ export class DeviceManagementOldComponent { return; } - const dialogRef = LoginApprovalComponent.open(this.dialogService, { + const dialogRef = LoginApprovalDialogComponent.open(this.dialogService, { notificationId: device.devicePendingAuthRequest.id, }); diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 2a75bf51900..62f73fd4935 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -1428,9 +1428,6 @@ "notificationSentDevicePart1": { "message": "Unlock Bitwarden on your device or on the " }, - "areYouTryingToAccessYourAccount": { - "message": "Are you trying to access your account?" - }, "accessAttemptBy": { "message": "Access attempt by $EMAIL$", "placeholders": { @@ -3981,22 +3978,6 @@ "thisRequestIsNoLongerValid": { "message": "This request is no longer valid." }, - "logInConfirmedForEmailOnDevice": { - "message": "Login confirmed for $EMAIL$ on $DEVICE$", - "placeholders": { - "email": { - "content": "$1", - "example": "name@example.com" - }, - "device": { - "content": "$2", - "example": "iOS" - } - } - }, - "youDeniedALogInAttemptFromAnotherDevice": { - "message": "You denied a login attempt from another device. If this really was you, try to log in with the device again." - }, "loginRequestApprovedForEmailOnDevice": { "message": "Login request approved for $EMAIL$ on $DEVICE$", "placeholders": { diff --git a/libs/angular/src/auth/device-management/device-management-item-group.component.ts b/libs/angular/src/auth/device-management/device-management-item-group.component.ts index 62468a18225..864712ceb78 100644 --- a/libs/angular/src/auth/device-management/device-management-item-group.component.ts +++ b/libs/angular/src/auth/device-management/device-management-item-group.component.ts @@ -2,13 +2,12 @@ import { CommonModule } from "@angular/common"; import { Component, Input } from "@angular/core"; import { firstValueFrom } from "rxjs"; -// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. -// eslint-disable-next-line no-restricted-imports -import { LoginApprovalComponent } from "@bitwarden/auth/angular"; import { DevicePendingAuthRequest } from "@bitwarden/common/auth/abstractions/devices/responses/device.response"; import { BadgeModule, DialogService, ItemModule } from "@bitwarden/components"; import { I18nPipe } from "@bitwarden/ui-common"; +import { LoginApprovalDialogComponent } from "../login-approval/login-approval-dialog.component"; + import { DeviceDisplayData } from "./device-management.component"; import { clearAuthRequestAndResortDevices } from "./resort-devices.helper"; @@ -29,7 +28,7 @@ export class DeviceManagementItemGroupComponent { return; } - const loginApprovalDialog = LoginApprovalComponent.open(this.dialogService, { + const loginApprovalDialog = LoginApprovalDialogComponent.open(this.dialogService, { notificationId: pendingAuthRequest.id, }); diff --git a/libs/angular/src/auth/device-management/device-management-table.component.ts b/libs/angular/src/auth/device-management/device-management-table.component.ts index 1d20e54deec..c3c835f05ed 100644 --- a/libs/angular/src/auth/device-management/device-management-table.component.ts +++ b/libs/angular/src/auth/device-management/device-management-table.component.ts @@ -3,9 +3,6 @@ import { Component, Input, OnChanges, SimpleChanges } from "@angular/core"; import { firstValueFrom } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -// This import has been flagged as unallowed for this class. It may be involved in a circular dependency loop. -// eslint-disable-next-line no-restricted-imports -import { LoginApprovalComponent } from "@bitwarden/auth/angular"; import { DevicePendingAuthRequest } from "@bitwarden/common/auth/abstractions/devices/responses/device.response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { @@ -17,6 +14,8 @@ import { TableModule, } from "@bitwarden/components"; +import { LoginApprovalDialogComponent } from "../login-approval/login-approval-dialog.component"; + import { DeviceDisplayData } from "./device-management.component"; import { clearAuthRequestAndResortDevices } from "./resort-devices.helper"; @@ -68,7 +67,7 @@ export class DeviceManagementTableComponent implements OnChanges { return; } - const loginApprovalDialog = LoginApprovalComponent.open(this.dialogService, { + const loginApprovalDialog = LoginApprovalDialogComponent.open(this.dialogService, { notificationId: pendingAuthRequest.id, }); diff --git a/libs/angular/src/auth/login-approval/default-login-approval-dialog-component.service.spec.ts b/libs/angular/src/auth/login-approval/default-login-approval-dialog-component.service.spec.ts new file mode 100644 index 00000000000..018b1ce2547 --- /dev/null +++ b/libs/angular/src/auth/login-approval/default-login-approval-dialog-component.service.spec.ts @@ -0,0 +1,30 @@ +import { TestBed } from "@angular/core/testing"; + +import { DefaultLoginApprovalDialogComponentService } from "./default-login-approval-dialog-component.service"; +import { LoginApprovalDialogComponent } from "./login-approval-dialog.component"; + +describe("DefaultLoginApprovalDialogComponentService", () => { + let service: DefaultLoginApprovalDialogComponentService; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [DefaultLoginApprovalDialogComponentService], + }); + + service = TestBed.inject(DefaultLoginApprovalDialogComponentService); + }); + + it("is created successfully", () => { + expect(service).toBeTruthy(); + }); + + it("has showLoginRequestedAlertIfWindowNotVisible method that is a no-op", async () => { + const loginApprovalDialogComponent = {} as LoginApprovalDialogComponent; + + const result = await service.showLoginRequestedAlertIfWindowNotVisible( + loginApprovalDialogComponent.email, + ); + + expect(result).toBeUndefined(); + }); +}); diff --git a/libs/angular/src/auth/login-approval/default-login-approval-dialog-component.service.ts b/libs/angular/src/auth/login-approval/default-login-approval-dialog-component.service.ts new file mode 100644 index 00000000000..5fefd3c3abb --- /dev/null +++ b/libs/angular/src/auth/login-approval/default-login-approval-dialog-component.service.ts @@ -0,0 +1,16 @@ +import { LoginApprovalDialogComponentServiceAbstraction } from "./login-approval-dialog-component.service.abstraction"; + +/** + * Default implementation of the LoginApprovalDialogComponentServiceAbstraction. + */ +export class DefaultLoginApprovalDialogComponentService + implements LoginApprovalDialogComponentServiceAbstraction +{ + /** + * No-op implementation of the showLoginRequestedAlertIfWindowNotVisible method. + * @returns + */ + async showLoginRequestedAlertIfWindowNotVisible(email?: string): Promise { + return; + } +} diff --git a/libs/angular/src/auth/login-approval/index.ts b/libs/angular/src/auth/login-approval/index.ts new file mode 100644 index 00000000000..7b34b17d56b --- /dev/null +++ b/libs/angular/src/auth/login-approval/index.ts @@ -0,0 +1,3 @@ +export * from "./login-approval-dialog.component"; +export * from "./login-approval-dialog-component.service.abstraction"; +export * from "./default-login-approval-dialog-component.service"; diff --git a/libs/auth/src/common/abstractions/login-approval-component.service.abstraction.ts b/libs/angular/src/auth/login-approval/login-approval-dialog-component.service.abstraction.ts similarity index 57% rename from libs/auth/src/common/abstractions/login-approval-component.service.abstraction.ts rename to libs/angular/src/auth/login-approval/login-approval-dialog-component.service.abstraction.ts index eaa62359808..f29311402a7 100644 --- a/libs/auth/src/common/abstractions/login-approval-component.service.abstraction.ts +++ b/libs/angular/src/auth/login-approval/login-approval-dialog-component.service.abstraction.ts @@ -1,7 +1,7 @@ /** - * Abstraction for the LoginApprovalComponent service. + * Abstraction for the LoginApprovalDialogComponent service. */ -export abstract class LoginApprovalComponentServiceAbstraction { +export abstract class LoginApprovalDialogComponentServiceAbstraction { /** * Shows a login requested alert if the window is not visible. */ diff --git a/libs/auth/src/angular/login-approval/login-approval.component.html b/libs/angular/src/auth/login-approval/login-approval-dialog.component.html similarity index 72% rename from libs/auth/src/angular/login-approval/login-approval.component.html rename to libs/angular/src/auth/login-approval/login-approval-dialog.component.html index d37e30c5e0a..f2850406235 100644 --- a/libs/auth/src/angular/login-approval/login-approval.component.html +++ b/libs/angular/src/auth/login-approval/login-approval-dialog.component.html @@ -1,5 +1,6 @@ - {{ "areYouTryingToAccessYourAccount" | i18n }} + {{ "loginRequest" | i18n }} +
@@ -8,28 +9,29 @@ -

{{ "accessAttemptBy" | i18n: email }}

+

{{ "accessAttemptBy" | i18n: email }}

- {{ "fingerprintPhraseHeader" | i18n }} + {{ "fingerprintPhraseHeader" | i18n }}

{{ fingerprintPhrase }}

- {{ "deviceType" | i18n }} -

{{ authRequestResponse?.requestDeviceType }}

+ {{ "deviceType" | i18n }} +

{{ readableDeviceTypeName }}

- {{ "location" | i18n }} + {{ "location" | i18n }}

{{ authRequestResponse?.requestCountryName }} ({{ authRequestResponse?.requestIpAddress }})

- {{ "time" | i18n }} + {{ "time" | i18n }}

{{ requestTimeText }}

+