mirror of https://github.com/ghostfolio/ghostfolio
8 changed files with 114 additions and 4 deletions
@ -0,0 +1,11 @@ |
|||||
|
import { NgModule } from '@angular/core'; |
||||
|
import { RouterModule, Routes } from '@angular/router'; |
||||
|
import { WebauthnPageComponent } from '@ghostfolio/client/pages/webauthn/webauthn-page.component'; |
||||
|
|
||||
|
const routes: Routes = [{ path: '', component: WebauthnPageComponent }]; |
||||
|
|
||||
|
@NgModule({ |
||||
|
imports: [RouterModule.forChild(routes)], |
||||
|
exports: [RouterModule] |
||||
|
}) |
||||
|
export class WebauthnPageRoutingModule {} |
@ -0,0 +1,46 @@ |
|||||
|
import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; |
||||
|
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; |
||||
|
import { WebAuthnService } from '@ghostfolio/client/services/web-authn.service'; |
||||
|
import { Router } from '@angular/router'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'gf-webauthn-page', |
||||
|
templateUrl: './webauthn-page.html', |
||||
|
styleUrls: ['./webauthn-page.scss'] |
||||
|
}) |
||||
|
export class WebauthnPageComponent implements OnInit { |
||||
|
public hasError = false; |
||||
|
|
||||
|
constructor( |
||||
|
private changeDetectorRef: ChangeDetectorRef, |
||||
|
private router: Router, |
||||
|
private tokenStorageService: TokenStorageService, |
||||
|
private webAuthnService: WebAuthnService |
||||
|
) {} |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
this.signIn(); |
||||
|
} |
||||
|
|
||||
|
public deregisterDevice() { |
||||
|
this.webAuthnService |
||||
|
.deregister() |
||||
|
.subscribe(() => this.router.navigate([''])); |
||||
|
} |
||||
|
|
||||
|
public signIn() { |
||||
|
this.hasError = false; |
||||
|
|
||||
|
this.webAuthnService.login().subscribe( |
||||
|
({ authToken }) => { |
||||
|
this.tokenStorageService.saveToken(authToken, false); |
||||
|
this.router.navigate(['']); |
||||
|
}, |
||||
|
(error) => { |
||||
|
console.error(error); |
||||
|
this.hasError = true; |
||||
|
this.changeDetectorRef.markForCheck(); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
<div class="container"> |
||||
|
<div class="row mt-5"> |
||||
|
<div *ngIf="!hasError" class="col d-flex justify-content-center"> |
||||
|
<mat-spinner [diameter]="100"></mat-spinner> |
||||
|
</div> |
||||
|
<div *ngIf="hasError" class="col d-flex flex-column justify-content-center"> |
||||
|
<h3 class="d-flex justify-content-center mb-3" i18n> |
||||
|
Authentication failed |
||||
|
</h3> |
||||
|
<button |
||||
|
(click)="signIn()" |
||||
|
class="mb-3" |
||||
|
mat-flat-button |
||||
|
color="primary" |
||||
|
i18n |
||||
|
> |
||||
|
Try again |
||||
|
</button> |
||||
|
<button (click)="deregisterDevice()" mat-flat-button i18n> |
||||
|
Forget fingerprint sign in |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
@ -0,0 +1,20 @@ |
|||||
|
import { CommonModule } from '@angular/common'; |
||||
|
import { NgModule } from '@angular/core'; |
||||
|
|
||||
|
import { WebauthnPageRoutingModule } from './webauthn-page-routing.module'; |
||||
|
import { WebauthnPageComponent } from '@ghostfolio/client/pages/webauthn/webauthn-page.component'; |
||||
|
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; |
||||
|
import { MatButtonModule } from '@angular/material/button'; |
||||
|
|
||||
|
@NgModule({ |
||||
|
declarations: [WebauthnPageComponent], |
||||
|
exports: [], |
||||
|
imports: [ |
||||
|
WebauthnPageRoutingModule, |
||||
|
CommonModule, |
||||
|
MatButtonModule, |
||||
|
MatProgressSpinnerModule |
||||
|
], |
||||
|
providers: [] |
||||
|
}) |
||||
|
export class WebauthnPageModule {} |
Loading…
Reference in new issue