Compare commits

...

2 Commits

25 changed files with 205 additions and 133 deletions

View File

@ -10,10 +10,12 @@ 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',
imports: [RouterOutlet, CommonModule, FormsModule, PoliciesModule, TtsFiltersModule, NavigationComponent],
standalone: true,
imports: [RouterOutlet, CommonModule, FormsModule, PoliciesModule, TtsFiltersModule, AuthModule, NavigationComponent],
providers: [AuthUserGuard],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'

View File

@ -1,33 +1,43 @@
import { Routes } from '@angular/router';
import { PolicyComponent } from './policies/policy/policy.component';
import { AuthUserGuard } from './shared/auth/auth.user.guard';
import { LoginComponent } from './login/login.component';
import { TtsLoginComponent } from './tts-login/tts-login.component';
import { LoginComponent } from './auth/login/login.component';
import { TtsLoginComponent } from './auth/tts-login/tts-login.component';
import { TwitchAuthCallbackComponent } from './twitch-auth-callback/twitch-auth-callback.component';
import { FiltersComponent } from './tts-filters/filters/filters.component';
import { AuthAdminGuard } from './shared/auth/auth.admin.guard';
import { ActionComponent } from './actions/action/action.component';
import { AuthVisitorGuard } from './shared/auth/auth.visitor.guard';
export const routes: Routes = [
{
path: 'policies',
component: PolicyComponent,
canActivate: [AuthUserGuard],
},
{
path: 'filters',
component: FiltersComponent,
canActivate: [AuthUserGuard],
},
{
path: 'login',
component: LoginComponent,
},
{
path: 'tts-login',
component: TtsLoginComponent,
canActivate: [AuthUserGuard],
},
{
path: 'auth',
component: TwitchAuthCallbackComponent
}
{
path: 'policies',
component: PolicyComponent,
canActivate: [AuthUserGuard],
},
{
path: 'filters',
component: FiltersComponent,
canActivate: [AuthUserGuard],
},
{
path: 'actions',
component: ActionComponent,
canActivate: [AuthAdminGuard],
},
{
path: 'login',
component: LoginComponent,
canActivate: [AuthVisitorGuard],
},
{
path: 'tts-login',
component: TtsLoginComponent,
canActivate: [AuthUserGuard],
},
{
path: 'auth',
component: TwitchAuthCallbackComponent,
canActivate: [AuthVisitorGuard],
}
];

View File

@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { LoginComponent } from './login/login.component';
import { TtsLoginComponent } from './tts-login/tts-login.component';
import { ImpersonationComponent } from './impersonation/impersonation.component';
@NgModule({
declarations: [],
imports: [
LoginComponent,
TtsLoginComponent,
ImpersonationComponent
]
})
export class AuthModule { }

View File

@ -0,0 +1,19 @@
@if (isAdmin()) {
<mat-card appearance="outlined">
<mat-card-header>
<mat-card-title> Impersonation</mat-card-title>
<mat-card-subtitle>Impersonate as another user</mat-card-subtitle>
</mat-card-header>
<mat-card-actions>
<mat-form-field>
<mat-label>User to impersonate</mat-label>
<mat-select (selectionChange)="onChange($event)" [(value)]="impersonated">
<mat-option>{{getUsername()}}</mat-option>
@for (user of users; track user.id) {
<mat-option [value]="user.id">{{ user.name }}</mat-option>
}
</mat-select>
</mat-form-field>
</mat-card-actions>
</mat-card>
}

View File

@ -1,16 +1,17 @@
import { Component, Inject, OnInit, PLATFORM_ID } from '@angular/core';
import { ApiAuthenticationService } from '../shared/services/api/api-authentication.service';
import { ApiAuthenticationService } from '../../shared/services/api/api-authentication.service';
import { MatCardModule } from '@angular/material/card';
import { MatSelectModule } from '@angular/material/select';
import { HttpClient } from '@angular/common/http';
import { isPlatformBrowser } from '@angular/common';
import { environment } from '../../environments/environment';
import EventService from '../shared/services/EventService';
import { HermesClientService } from '../hermes-client.service';
import { environment } from '../../../environments/environment';
import EventService from '../../shared/services/EventService';
import { HermesClientService } from '../../hermes-client.service';
import { Router } from '@angular/router';
@Component({
selector: 'impersonation',
standalone: true,
imports: [MatCardModule, MatSelectModule],
templateUrl: './impersonation.component.html',
styleUrl: './impersonation.component.scss'

View File

@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { MatCardModule } from '@angular/material/card';
import { Router, RouterModule } from '@angular/router';
import { Subscription } from 'rxjs';
import { environment } from '../../environments/environment';
import { environment } from '../../../environments/environment';
@Component({
selector: 'login',

View File

@ -4,16 +4,17 @@ import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatButtonModule } from '@angular/material/button';
import EventService from '../shared/services/EventService';
import EventService from '../../shared/services/EventService';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { environment } from '../../environments/environment';
import { HermesClientService } from '../hermes-client.service';
import { environment } from '../../../environments/environment';
import { HermesClientService } from '../../hermes-client.service';
import { MatCard } from '@angular/material/card';
@Component({
selector: 'tts-login',
standalone: true,
imports: [MatButtonModule, MatCard, MatFormFieldModule, MatSelectModule, MatInputModule, FormsModule],
templateUrl: './tts-login.component.html',
styleUrl: './tts-login.component.scss'

View File

@ -1,19 +0,0 @@
@if (isAdmin()) {
<mat-card appearance="outlined">
<mat-card-header>
<mat-card-title> Impersonation</mat-card-title>
<mat-card-subtitle>Impersonate as another user</mat-card-subtitle>
</mat-card-header>
<mat-card-actions>
<mat-form-field>
<mat-label>User to impersonate</mat-label>
<mat-select (selectionChange)="onChange($event)" [(value)]="impersonated">
<mat-option>{{getUsername()}}</mat-option>
@for (user of users; track user.id) {
<mat-option [value]="user.id">{{ user.name }}</mat-option>
}
</mat-select>
</mat-form-field>
</mat-card-actions>
</mat-card>
}

View File

@ -1,37 +1,30 @@
<nav>
<impersonation />
<ul>
<li>
<a
routerLink="/login"
routerLinkActive="active"
*ngIf="!isLoggedIn()">
Login
</a>
</li>
<li>
<a
routerLink="/tts-login"
routerLinkActive="active"
*ngIf="isLoggedIn() && !isTTSLoggedIn()">
TTS Login
</a>
</li>
<li>
<a
routerLink="/policies"
routerLinkActive="active"
*ngIf="isLoggedIn() && isTTSLoggedIn()">
Policies
</a>
</li>
<li>
<a
routerLink="/filters"
routerLinkActive="active"
*ngIf="isLoggedIn() && isTTSLoggedIn()">
Filters
</a>
</li>
</ul>
<impersonation />
<ul>
<li>
<a routerLink="/login" routerLinkActive="active" *ngIf="!isLoggedIn()">
Login
</a>
</li>
<li>
<a routerLink="/tts-login" routerLinkActive="active" *ngIf="isLoggedIn() && !isTTSLoggedIn()">
TTS Login
</a>
</li>
<li>
<a routerLink="/policies" routerLinkActive="active" *ngIf="isLoggedIn() && isTTSLoggedIn()">
Policies
</a>
</li>
<li>
<a routerLink="/filters" routerLinkActive="active" *ngIf="isLoggedIn() && isTTSLoggedIn()">
Filters
</a>
</li>
<li>
<a routerLink="/actions" routerLinkActive="active" *ngIf="isLoggedIn() && isTTSLoggedIn() && isAdmin()">
Actions
</a>
</li>
</ul>
</nav>

View File

@ -3,27 +3,29 @@ import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { HermesClientService } from '../hermes-client.service';
import { ApiAuthenticationService } from '../shared/services/api/api-authentication.service';
import { ImpersonationComponent } from '../impersonation/impersonation.component';
import { MatCardModule } from '@angular/material/card';
import { AuthModule } from '../auth/auth.module';
import { ImpersonationComponent } from "../auth/impersonation/impersonation.component";
@Component({
selector: 'navigation',
imports: [CommonModule, RouterModule, ImpersonationComponent, MatCardModule],
templateUrl: './navigation.component.html',
styleUrl: './navigation.component.scss'
selector: 'navigation',
standalone: true,
imports: [CommonModule, RouterModule, MatCardModule, AuthModule, ImpersonationComponent],
templateUrl: './navigation.component.html',
styleUrl: './navigation.component.scss'
})
export class NavigationComponent {
constructor(private auth: ApiAuthenticationService, private hermes: HermesClientService) { }
constructor(private auth: ApiAuthenticationService, private hermes: HermesClientService) { }
isLoggedIn() {
return this.auth.isAuthenticated();
}
isLoggedIn() {
return this.auth.isAuthenticated();
}
isAdmin() {
return this.isLoggedIn() && this.auth.isAdmin()
}
isAdmin() {
return this.isLoggedIn() && this.auth.isAdmin()
}
isTTSLoggedIn() {
return this.hermes?.logged_in ?? false;
}
isTTSLoggedIn() {
return this.hermes?.logged_in ?? false;
}
}

View File

@ -0,0 +1,15 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { ApiAuthenticationService } from '../services/api/api-authentication.service';
@Injectable({
providedIn: 'root'
})
export class AuthVisitorGuard implements CanActivate {
constructor(private auth: ApiAuthenticationService, private router: Router) { }
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
return !this.auth.isAuthenticated();
}
}

View File

@ -1,9 +1,13 @@
<ul>
<li>
{{item.search}}
<span>
{{item.search}}
</span>
</li>
<li>
{{item.replace}}
<span>
{{item.replace}}
</span>
</li>
<li>
<mat-menu #filterMenu>
@ -11,7 +15,7 @@
<button mat-menu-item (click)="onDelete.emit(item)">Delete</button>
</mat-menu>
<button mat-icon-button [matMenuTriggerFor]="filterMenu">
<button mat-icon-button class="small-button" [matMenuTriggerFor]="filterMenu">
<mat-icon>more_vert</mat-icon>
</button>
</li>

View File

@ -13,9 +13,14 @@ ul {
li {
list-style-type: none;
white-space: pre;
text-align: justify;
text-align: start;
text-wrap: wrap;
span {
overflow: hidden;
text-overflow: hidden;
}
> button {
background: #dddddd;
border-radius: 50%;
@ -30,4 +35,8 @@ ul {
li:nth-child(2) {
flex: 1;
}
}
.small-button {
transform: scale(0.8);
}

View File

@ -1,5 +1,5 @@
<div>
<ul>
<ul class="data">
<li>
<ul class="header">
<li>Search</li>

View File

@ -1,40 +1,50 @@
ul {
margin: 0;
padding: 0;
div {
background-color: #fafafa;
}
li {
ul.data {
margin: 0;
padding: 0;
> li {
display: block;
list-style-type: none;
padding: 0.75em 1em;
border-bottom: 1px solid #aaaaaa;
}
}
li:first-child {
> li:first-child {
padding: 0 1em;
border-bottom: 0 solid #aaaaaa;
}
}
li:last-child {
> li:last-child {
border-bottom: 0 solid #aaaaaa;
}
> li:nth-child(2n) {
background-color: #f5f5f5;
}
}
ul.header {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-evenly;
background-color: #fafafa;
li {
border-bottom: 0 solid #aaaaaa;
font-weight: 500;
list-style-type: none;
white-space: pre;
text-align: justify;
}
li {
border-bottom: 0 solid #aaaaaa;
font-weight: 500;
list-style-type: none;
white-space: pre;
text-align: justify;
background-color: #fafafa;
}
li:nth-child(1),
li:nth-child(2) {
flex: 1;
}
li:nth-child(1),
li:nth-child(2) {
flex: 1;
}
}

View File

@ -1,5 +1,13 @@
main {
background-color: #fafafa;
}
article {
display: flex;
justify-content: space-between;
width: 70%;
justify-content: center;
gap: 10em;
}
button {
transform: scale(0.7);
}

View File

@ -7,6 +7,7 @@ import { environment } from '../../environments/environment';
@Component({
selector: 'app-twitch-auth-callback',
standalone: true,
imports: [],
templateUrl: './twitch-auth-callback.component.html',
styleUrl: './twitch-auth-callback.component.scss'