wip
This commit is contained in:
parent
9b55805acd
commit
bf413c2e09
6 changed files with 82 additions and 63 deletions
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
<div class="centerNav"></div>
|
||||
<div class="rightNav">
|
||||
@if (auth.loggedIn) {
|
||||
@if (auth.isAuth()) {
|
||||
<button class="ybtn sbButton">
|
||||
<a (click)="logout()" class="logout">Logout</a>
|
||||
</button>
|
||||
|
@ -19,7 +19,7 @@
|
|||
</header>
|
||||
|
||||
<div class="container">
|
||||
@if (auth.loggedIn) {
|
||||
@if (auth.isAuth()) {
|
||||
<app-navigation [events]="toggleNavSubject.asObservable()"></app-navigation>
|
||||
} @else {
|
||||
<div class="content">
|
||||
|
|
|
@ -29,7 +29,7 @@ export function authIntercept(
|
|||
next: HttpHandlerFn,
|
||||
): Observable<HttpEvent<unknown>> {
|
||||
let authSvc: AuthService = inject(AuthService);
|
||||
if (authSvc.loggedIn) {
|
||||
if (authSvc.isAuth()) {
|
||||
req = req.clone({
|
||||
setHeaders: {
|
||||
Authorization: `Bearer ${authSvc.getToken()}`,
|
||||
|
|
|
@ -1,56 +1,93 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Injectable, signal, computed, effect, inject, DestroyRef } from '@angular/core';
|
||||
import { HttpClient, HttpResponse } from '@angular/common/http';
|
||||
import { Router } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { tap } from 'rxjs/operators';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
|
||||
export class Jwt {
|
||||
constructor(public jwt: string) {}
|
||||
}
|
||||
|
||||
type AuthState = {
|
||||
user: string | null;
|
||||
token: string | null;
|
||||
is_auth: boolean;
|
||||
};
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class AuthService {
|
||||
loggedIn: boolean = false;
|
||||
private _accessTokenKey = 'jwt';
|
||||
private _storedToken = localStorage.getItem(this._accessTokenKey);
|
||||
destroyed = inject(DestroyRef);
|
||||
|
||||
private _state = signal<AuthState>({
|
||||
user: null,
|
||||
token: this._storedToken,
|
||||
is_auth: this._storedToken !== null,
|
||||
});
|
||||
loginFailed = signal<boolean>(false);
|
||||
token = computed(() => this._state().token);
|
||||
isAuth = computed(() => this._state().is_auth);
|
||||
user = computed(() => this._state().user);
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private _router: Router,
|
||||
) {
|
||||
let ssJWT = localStorage.getItem('jwt');
|
||||
if (ssJWT) {
|
||||
this.loggedIn = true;
|
||||
}
|
||||
effect(() => {
|
||||
const token = this.token();
|
||||
if (token !== null) {
|
||||
localStorage.setItem(this._accessTokenKey, token);
|
||||
} else {
|
||||
localStorage.removeItem(this._accessTokenKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
login(username: string, password: string): Observable<HttpResponse<Jwt>> {
|
||||
login(username: string, password: string) {
|
||||
return this.http
|
||||
.post<Jwt>(
|
||||
'/api/login',
|
||||
{ username: username, password: password },
|
||||
{ observe: 'response' },
|
||||
)
|
||||
.pipe(
|
||||
tap((event) => {
|
||||
if (event.status == 200) {
|
||||
localStorage.setItem('jwt', event.body?.jwt.toString() ?? '');
|
||||
this.loggedIn = true;
|
||||
this._router.navigateByUrl('/home');
|
||||
}
|
||||
}),
|
||||
);
|
||||
.post<Jwt>('/api/login', { username: username, password: password })
|
||||
.pipe(takeUntilDestroyed(this.destroyed))
|
||||
.subscribe({
|
||||
next: (res) => {
|
||||
let state = <AuthState>{
|
||||
user: username,
|
||||
token: res.jwt,
|
||||
is_auth: true,
|
||||
};
|
||||
this._state.set(state);
|
||||
this.loginFailed.update(() => false);
|
||||
this._router.navigateByUrl('/');
|
||||
},
|
||||
error: (err) => {
|
||||
this.loginFailed.update(() => true);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
_clearState() {
|
||||
this._state.update((state) => {
|
||||
state.is_auth = false;
|
||||
state.token = null;
|
||||
return state;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
logout() {
|
||||
console.log("logout!");
|
||||
this.http
|
||||
.get('/api/logout', { withCredentials: true, observe: 'response' })
|
||||
.subscribe((event) => {
|
||||
if (event.status == 200) {
|
||||
this.loggedIn = false;
|
||||
}
|
||||
});
|
||||
localStorage.removeItem('jwt');
|
||||
this.loggedIn = false;
|
||||
.get('/api/logout', { withCredentials: true})
|
||||
.subscribe({
|
||||
next: (event) => {
|
||||
this._clearState();
|
||||
},
|
||||
error: (err) => {
|
||||
this._clearState();
|
||||
}
|
||||
});
|
||||
this._router.navigateByUrl('/login');
|
||||
}
|
||||
|
||||
|
@ -60,14 +97,18 @@ export class AuthService {
|
|||
.pipe(
|
||||
tap((event) => {
|
||||
if (event.status == 200) {
|
||||
localStorage.setItem('jwt', event.body?.jwt.toString() ?? '');
|
||||
this.loggedIn = true;
|
||||
let tok = event.body?.jwt.toString();
|
||||
this._state.update((state) => {
|
||||
state.is_auth = true;
|
||||
state.token = tok ? tok : null;
|
||||
return state;
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
getToken(): string | null {
|
||||
return localStorage.getItem('jwt');
|
||||
return localStorage.getItem(this._accessTokenKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<button class="login sbButton" (click)="onSubmit()">Login</button>
|
||||
</div>
|
||||
</form>
|
||||
@if (failed) {
|
||||
@if (failed()) {
|
||||
<div role="alert">
|
||||
<span>Login Failed!</span>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Component, inject } from '@angular/core';
|
||||
import { Component, inject, signal } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { AuthService } from '../login/auth.service';
|
||||
import { catchError, of, Subscription } from 'rxjs';
|
||||
|
@ -17,31 +17,9 @@ export class LoginComponent {
|
|||
router: Router = inject(Router);
|
||||
username: string = '';
|
||||
password: string = '';
|
||||
failed: boolean = false;
|
||||
private subscriptions = new Subscription();
|
||||
failed = this.apiService.loginFailed;
|
||||
|
||||
onSubmit() {
|
||||
this.failed = false;
|
||||
this.subscriptions.add(
|
||||
this.apiService
|
||||
.login(this.username, this.password)
|
||||
.pipe(
|
||||
catchError(() => {
|
||||
this.failed = true;
|
||||
return of(null);
|
||||
}),
|
||||
)
|
||||
.subscribe((event) => {
|
||||
if (event?.status == 200) {
|
||||
this.router.navigateByUrl('/');
|
||||
} else {
|
||||
this.failed = true;
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscriptions.unsubscribe();
|
||||
this.apiService.login(this.username, this.password);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ export class TalkgroupService {
|
|||
if (sh) {
|
||||
this.shareSvc.getShare(sh).subscribe(this.fetchAll);
|
||||
} else {
|
||||
if (this.authSvc.loggedIn) {
|
||||
if (this.authSvc.isAuth()) {
|
||||
this.fetchAll.next(null);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue