diff --git a/apps/web/src/app/auth/settings/account/account.component.html b/apps/web/src/app/auth/settings/account/account.component.html index a5e5329fce..6d72ad1037 100644 --- a/apps/web/src/app/auth/settings/account/account.component.html +++ b/apps/web/src/app/auth/settings/account/account.component.html @@ -4,7 +4,7 @@
-

{{ "changeEmail" | i18n }}

+

{{ "areYouTryingtoLogin" | i18n }}

@@ -29,4 +29,11 @@ + + +
+ +
diff --git a/apps/web/src/app/auth/settings/account/account.component.ts b/apps/web/src/app/auth/settings/account/account.component.ts index 51bf427696..3d2084237c 100644 --- a/apps/web/src/app/auth/settings/account/account.component.ts +++ b/apps/web/src/app/auth/settings/account/account.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; import { combineLatest, from, lastValueFrom, map, Observable } from "rxjs"; import { ModalService } from "@bitwarden/angular/services/modal.service"; +import { LoginApprovalComponent } from "@bitwarden/auth/angular"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -78,4 +79,15 @@ export class AccountComponent implements OnInit { const dialogRef = DeleteAccountDialogComponent.open(this.dialogService); await lastValueFrom(dialogRef.closed); }; + + // TODO: remove this - for testing only + openLoginApproval() { + LoginApprovalComponent.open(this.dialogService, { + data: { + name: "test name", + userId: "yourUserId", + fingerprint: "test fingerprint", + }, + }); + } } diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 3189777aa7..41c857d2a4 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -86,6 +86,12 @@ "atRiskApplications": { "message": "At-risk applications" }, + "deviceType": { + "message": "Device type" + }, + "ipAddress": { + "message": "IP address" + }, "totalApplications": { "message": "Total applications" }, diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index d3d9e60091..9e30fd89dd 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -58,3 +58,6 @@ export * from "./vault-timeout-input/vault-timeout-input.component"; // self hosted environment configuration dialog export * from "./self-hosted-env-config-dialog/self-hosted-env-config-dialog.component"; + +// login approval +export * from "./login/login-approval.component"; diff --git a/libs/auth/src/angular/login/login-approval.component.html b/libs/auth/src/angular/login/login-approval.component.html new file mode 100644 index 0000000000..c30e6a1038 --- /dev/null +++ b/libs/auth/src/angular/login/login-approval.component.html @@ -0,0 +1,28 @@ +
+ + + {{ "areYouTryingtoLogin" | i18n }} + {{ name }} + + +

{{ "fingerprintPhraseHeader" | i18n }}

+

+ {{ fingerprint }} +

+

{{ "deviceType" | i18n }}

+

test

+

{{ "ipAddress" | i18n }}

+

test

+

{{ "time" | i18n }}

+

test

+
+ + + + +
+
diff --git a/libs/auth/src/angular/login/login-approval.component.ts b/libs/auth/src/angular/login/login-approval.component.ts new file mode 100644 index 0000000000..98037eb62f --- /dev/null +++ b/libs/auth/src/angular/login/login-approval.component.ts @@ -0,0 +1,70 @@ +import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; +import { CommonModule } from "@angular/common"; +import { Component, Inject, OnInit } from "@angular/core"; +import { FormGroup, ReactiveFormsModule } from "@angular/forms"; +import { RouterLink } from "@angular/router"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { + AsyncActionsModule, + ButtonModule, + DialogModule, + DialogService, + FormFieldModule, +} from "@bitwarden/components"; + +export type LoginApprovalDialogData = { + name: string; + userId: string; + fingerprint: string; +}; + +@Component({ + selector: "login-approval", + templateUrl: "login-approval.component.html", + standalone: true, + imports: [ + CommonModule, + JslibModule, + ReactiveFormsModule, + FormFieldModule, + AsyncActionsModule, + RouterLink, + ButtonModule, + DialogModule, + ], +}) +export class LoginApprovalComponent implements OnInit { + name: string; + userId: string; + fingerprint: string; + + loading = true; + formPromise: Promise; + + formGroup = new FormGroup({}); + + constructor( + @Inject(DIALOG_DATA) protected data: LoginApprovalDialogData, + private dialogRef: DialogRef, + ) { + this.name = data.name; + this.userId = data.userId; + } + + async ngOnInit() { + this.loading = false; + } + + submit = async () => { + if (this.loading) { + return; + } + + this.dialogRef.close(); + }; + + static open(dialogService: DialogService, config: DialogConfig) { + return dialogService.open(LoginApprovalComponent, config); + } +}