-
Notifications
You must be signed in to change notification settings - Fork 137
/
auth.service.ts
106 lines (93 loc) · 2.87 KB
/
auth.service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import {Injectable} from '@angular/core';
import {from, Observable, of} from 'rxjs';
import {environment} from '../environments/environment';
import { HttpClient, HttpParams } from '@angular/common/http';
import {catchError, finalize, map, mapTo, switchMap, tap} from 'rxjs/operators';
import {LoadingController, NavController, ToastController} from '@ionic/angular';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private loggedIn = false;
constructor(private readonly httpClient: HttpClient,
private readonly navCtrl: NavController,
private readonly toastCtrl: ToastController,
private readonly loadingCtrl: LoadingController) {
}
isAuthenticated(): Observable<boolean> {
return this.httpClient.get<void>(`${environment.serverUrl}/authenticate`, {
withCredentials: true
}).pipe(
tap(() => this.loggedIn = true),
map(() => true),
catchError(() => {
this.loggedIn = false;
return of(false);
})
);
}
login(username: string, password: string): Observable<boolean> {
let loading: HTMLIonLoadingElement;
return from(this.loadingCtrl.create({
spinner: 'bubbles',
message: `Logging in ...`
})).pipe(
tap(c => {
loading = c;
c.present();
}),
switchMap(() => this.submitLogin(username, password)),
finalize(() => loading.dismiss()),
tap(success => {
if (success) {
this.storePassword(username, password).then(() => this.navCtrl.navigateRoot('/home'));
} else {
this.showError();
}
})
);
}
logout(): Observable<void> {
return this.httpClient.get<void>(`${environment.serverUrl}/logout`, {
withCredentials: true
}).pipe(tap(() => this.loggedIn = false));
}
isLoggedIn(): boolean {
return this.loggedIn;
}
private async storePassword(username: string, password: string): Promise<Credential | null> {
// @ts-ignore
if (!window.PasswordCredential) {
return Promise.resolve(null);
}
// @ts-ignore
const cred = new window.PasswordCredential({
id: username,
password,
name: username
});
navigator.credentials.store(cred);
return cred;
}
private async showError(): Promise<void> {
const toast = await this.toastCtrl.create({
message: 'Login failed',
duration: 4000,
position: 'bottom'
});
return toast.present();
}
private submitLogin(username: string, password: string): Observable<boolean> {
const body = new HttpParams().set('username', username).set('password', password);
return this.httpClient.post<void>(`${environment.serverUrl}/login`, body, {
withCredentials: true
}).pipe(
tap(() => this.loggedIn = true),
mapTo(true),
catchError(() => {
this.loggedIn = false;
return of(false);
})
);
}
}