From 2692294b4b4cc929cff972c5ca66ab2227ae7c72 Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 9 Jan 2025 18:11:44 +0000 Subject: [PATCH] Fixed minor issues with login & logout. Cleaned up the UI. --- src/app/app.component.ts | 99 ++++++++++--------- .../impersonation/impersonation.component.ts | 8 +- src/app/auth/login/login.component.html | 32 +++--- src/app/auth/login/login.component.scss | 32 +++++- src/app/auth/tts-login/tts-login.component.ts | 8 +- src/app/policies/policy/policy.component.ts | 2 +- .../tts-filters/filters/filters.component.ts | 2 +- .../twitch-auth-callback.component.ts | 31 ++++-- 8 files changed, 128 insertions(+), 86 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 5baf77b..3ed9012 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,67 +1,72 @@ -import { CommonModule, isPlatformBrowser } from '@angular/common'; +import { isPlatformBrowser } from '@angular/common'; import { Component, OnInit, Inject, PLATFORM_ID, NgZone, OnDestroy } from '@angular/core'; import { Router, RouterOutlet } from '@angular/router'; -import { FormsModule } from '@angular/forms' import { HermesClientService } from './hermes-client.service'; import { AuthUserGuard } from './shared/auth/auth.user.guard' import { Subscription } from 'rxjs'; import { NavigationComponent } from "./navigation/navigation.component"; import EventService from './shared/services/EventService'; import { ApiAuthenticationService } from './shared/services/api/api-authentication.service'; -import { PoliciesModule } from './policies/policies.module'; -import { TtsFiltersModule } from './tts-filters/tts-filters.module'; import { AuthModule } from './auth/auth.module'; @Component({ - selector: 'app-root', - standalone: true, - imports: [RouterOutlet, CommonModule, FormsModule, PoliciesModule, TtsFiltersModule, AuthModule, NavigationComponent], - providers: [AuthUserGuard], - templateUrl: './app.component.html', - styleUrl: './app.component.scss' + selector: 'app-root', + standalone: true, + imports: [RouterOutlet, AuthModule, NavigationComponent], + providers: [AuthUserGuard], + templateUrl: './app.component.html', + styleUrl: './app.component.scss' }) export class AppComponent implements OnInit, OnDestroy { - private isBrowser: boolean; - private ngZone: NgZone; - private subscriptions: Subscription[]; + private isBrowser: boolean; + private ngZone: NgZone; + private subscriptions: Subscription[]; - constructor(private auth: ApiAuthenticationService, private client: HermesClientService, private events: EventService, private router: Router, ngZone: NgZone, @Inject(PLATFORM_ID) private platformId: Object) { - this.ngZone = ngZone; - this.isBrowser = isPlatformBrowser(this.platformId); - this.subscriptions = []; + constructor(private auth: ApiAuthenticationService, private client: HermesClientService, private events: EventService, private router: Router, ngZone: NgZone, @Inject(PLATFORM_ID) private platformId: Object) { + this.ngZone = ngZone; + this.isBrowser = isPlatformBrowser(this.platformId); + this.subscriptions = []; + } + + ngOnInit(): void { + if (!this.isBrowser) + return; + + this.auth.update(); + + this.addSubscription(this.events.listen('logoff', async (message) => { + localStorage.removeItem('jwt'); + if (!document.location.href.includes('/login')) { + if (message) + await this.router.navigate(['login'], { + queryParams: { message: message } + }); + else + await this.router.navigate(['login']); + } + })); + + this.addSubscription(this.events.listen('login', async (_) => { + if (['/login', '/auth'].some(partial => document.location.href.includes(partial))) { + await this.router.navigate(['tts-login']); + } + })); + + const connection = this.client.connect(); + if (connection) { + this.addSubscription(connection); } + this.ngZone.runOutsideAngular(() => setInterval(() => this.client.heartbeat(), 15000)); + } - ngOnInit(): void { - if (!this.isBrowser) - return; - - this.auth.update(); - - this.addSubscription(this.events.listen('logoff', (message) => { - localStorage.removeItem('jwt'); - if (!document.location.href.includes('/login')) { - this.router.navigate(['/login?warning=' + message]); - } - })); - - this.addSubscription(this.events.listen('login', (_) => { - if (document.location.href.includes('/login')) { - this.router.navigate(['/tts-login']); - } - })); - - this.client.connect(); - this.ngZone.runOutsideAngular(() => setInterval(() => this.client.heartbeat(), 15000)); + ngOnDestroy() { + for (let s of this.subscriptions) { + s.unsubscribe(); } + } - ngOnDestroy() { - for (let s of this.subscriptions) { - s.unsubscribe(); - } - } - - private addSubscription(s: Subscription) { - this.subscriptions.push(s); - } + private addSubscription(s: Subscription) { + this.subscriptions.push(s); + } } \ No newline at end of file diff --git a/src/app/auth/impersonation/impersonation.component.ts b/src/app/auth/impersonation/impersonation.component.ts index f6eb2b1..bada955 100644 --- a/src/app/auth/impersonation/impersonation.component.ts +++ b/src/app/auth/impersonation/impersonation.component.ts @@ -59,10 +59,10 @@ export class ImpersonationComponent implements OnInit { body: { impersonation: e.value } - }).subscribe((data: any) => { + }).subscribe(async (data: any) => { this.hermes.disconnect(); this.events.emit('impersonation', e.value); - this.router.navigate(['/tts-login']); + await this.router.navigate(['tts-login']); }); } else { this.http.put(environment.API_HOST + '/admin/impersonate', { @@ -71,10 +71,10 @@ export class ImpersonationComponent implements OnInit { headers: { 'Authorization': 'Bearer ' + localStorage.getItem('jwt') } - }).subscribe((data: any) => { + }).subscribe(async (data: any) => { this.hermes.disconnect(); this.events.emit('impersonation', e.value); - this.router.navigate(['/tts-login']); + await this.router.navigate(['tts-login']); }); } } diff --git a/src/app/auth/login/login.component.html b/src/app/auth/login/login.component.html index 02669bf..6a9f5a0 100644 --- a/src/app/auth/login/login.component.html +++ b/src/app/auth/login/login.component.html @@ -1,21 +1,19 @@
-
- - -

Login

-
+ + +

Login

+
- -

Log in with your favorite livestream service

+ +

Log in with your favorite livestream service

- - - - Twitch - - - -
-
-
+ + + + Twitch + + + + +
\ No newline at end of file diff --git a/src/app/auth/login/login.component.scss b/src/app/auth/login/login.component.scss index dd6c8cd..95dec7b 100644 --- a/src/app/auth/login/login.component.scss +++ b/src/app/auth/login/login.component.scss @@ -1,13 +1,35 @@ .login { - display: grid; - grid-template-columns: 1fr max-content 1fr; - place-items: center; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; } .mat-mdc-card-header { - align-self: center; + display: grid; + grid-template-columns: 1fr; +} + +.title { + text-align: center; + margin: 0; } .mat-mdc-card-content { - align-self: center; + align-self: center; +} + +a { + cursor: pointer; +} + +.services p { + margin-bottom: 2em; +} + +.twitch { + background-color: #a970ff; + color: black; + font-weight: 500; } \ No newline at end of file diff --git a/src/app/auth/tts-login/tts-login.component.ts b/src/app/auth/tts-login/tts-login.component.ts index 76297db..4829f93 100644 --- a/src/app/auth/tts-login/tts-login.component.ts +++ b/src/app/auth/tts-login/tts-login.component.ts @@ -36,12 +36,12 @@ export class TtsLoginComponent implements OnInit, OnDestroy { } }).subscribe((data: any) => this.api_keys = data); - this.subscription = this.events.listen('tts_login_ack', _ => { - this.router.navigate(['/policies']) + this.subscription = this.events.listen('tts_login_ack', async _ => { + await this.router.navigate(['policies']) }); - this.events.listen('tts_logoff', _ => { + this.events.listen('tts_logoff', async _ => { this.selected_api_key = undefined; - this.router.navigate(['/tts-login']) + await this.router.navigate(['tts-login']) }); this.events.listen('impersonation', _ => { this.selected_api_key = undefined; diff --git a/src/app/policies/policy/policy.component.ts b/src/app/policies/policy/policy.component.ts index 0f0c64c..5d7203a 100644 --- a/src/app/policies/policy/policy.component.ts +++ b/src/app/policies/policy/policy.component.ts @@ -32,7 +32,7 @@ export class PolicyComponent implements OnInit, OnDestroy { return; if (!this.client.logged_in) { - this.router.navigate(["/tts-login"]); + this.router.navigate(["tts-login"]); return; } } diff --git a/src/app/tts-filters/filters/filters.component.ts b/src/app/tts-filters/filters/filters.component.ts index f3a47ce..ede3922 100644 --- a/src/app/tts-filters/filters/filters.component.ts +++ b/src/app/tts-filters/filters/filters.component.ts @@ -58,7 +58,7 @@ export class FiltersComponent implements OnInit, OnDestroy { return; if (!this.client.logged_in) { - this.router.navigate(["/tts-login"]); + this.router.navigate(["tts-login"]); return; } } diff --git a/src/app/twitch-auth-callback/twitch-auth-callback.component.ts b/src/app/twitch-auth-callback/twitch-auth-callback.component.ts index ab6ccde..dca95d0 100644 --- a/src/app/twitch-auth-callback/twitch-auth-callback.component.ts +++ b/src/app/twitch-auth-callback/twitch-auth-callback.component.ts @@ -19,28 +19,45 @@ export class TwitchAuthCallbackComponent implements OnInit { this.isBrowser = isPlatformBrowser(this.platformId) } - ngOnInit(): void { + async ngOnInit(): Promise { if (!this.isBrowser) { return; } + if (this.auth.isAuthenticated()) { + await this.router.navigate(['tts-login']); + return; + } + const code = this.route.snapshot.queryParamMap.get('code'); const scope = this.route.snapshot.queryParamMap.get('scope'); const state = this.route.snapshot.queryParamMap.get('state'); - if (!code || !scope || !state) + if (!code || !scope || !state) { + await this.router.navigate(['login'], { + queryParams: { + error: 'callback_issue' + } + }); return; + } this.http.post(environment.API_HOST + '/auth/twitch/callback', { code, scope, state }) - .subscribe((data: any) => { - if (!data?.authenticated) { - this.router.navigate(['/login?error=callback_error']); + .subscribe(async (response: any) => { + if (!response?.authenticated) { + await this.router.navigate(['login'], { + queryParams: { + error: 'callback_issue' + } + }); return; } - localStorage.setItem('jwt', data.token); + localStorage.setItem('jwt', response.token); this.auth.update(); - this.router.navigate(['/tts-login']); + + console.log('logged in. so nav to tts login.'); + await this.router.navigate(['tts-login']); }); } }