mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Account management works but the app is reloaded multiple times
This commit is contained in:
parent
45f2b5b641
commit
b436d48826
29
angular.json
29
angular.json
@ -85,23 +85,6 @@
|
||||
"browserTarget": "Kyoo:build"
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "src/test.ts",
|
||||
"polyfills": "src/polyfills.ts",
|
||||
"tsConfig": "tsconfig.spec.json",
|
||||
"karmaConfig": "karma.conf.js",
|
||||
"assets": [
|
||||
"src/favicon.ico",
|
||||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles.sass"
|
||||
],
|
||||
"scripts": []
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
@ -114,18 +97,6 @@
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
},
|
||||
"e2e": {
|
||||
"builder": "@angular-devkit/build-angular:protractor",
|
||||
"options": {
|
||||
"protractorConfig": "e2e/protractor.conf.js",
|
||||
"devServerTarget": "Kyoo:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "Kyoo:serve:production"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
|
@ -5,9 +5,7 @@
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
"lint": "ng lint"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
|
@ -13,6 +13,7 @@ import { ShowResolverService } from './services/show-resolver.service';
|
||||
import { StreamResolverService } from "./services/stream-resolver.service";
|
||||
import { ShowDetailsComponent } from './show-details/show-details.component';
|
||||
import {LoginComponent} from "./login/login.component";
|
||||
import {LoggedComponent} from "./logged/logged.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "browse", component: BrowseComponent, pathMatch: "full", resolve: { shows: LibraryResolverService } },
|
||||
@ -23,6 +24,7 @@ const routes: Routes = [
|
||||
{ path: "watch/:item", component: PlayerComponent, resolve: { item: StreamResolverService } },
|
||||
{ path: "search/:query", component: SearchComponent, resolve: { items: SearchResolverService } },
|
||||
{ path: "login", component: LoginComponent },
|
||||
{ path: "logged", component: LoggedComponent },
|
||||
{ path: "**", component: NotFoundComponent }
|
||||
];
|
||||
|
||||
|
@ -19,11 +19,22 @@
|
||||
<input placeholder="Search" id="search" type="search" (input)="onUpdateValue($event)"/>
|
||||
<mat-icon matTooltipPosition="below" matTooltip="Search" (click)="openSearch()">search</mat-icon>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="icon" routerLink="/login" routerLinkActive="active" matTooltipPosition="below" matTooltip="Login">
|
||||
<li class="nav-item" *ngIf="!isLoggedIn(); else accountDrop">
|
||||
<a class="icon" (click)="login()" matTooltipPosition="below" matTooltip="Login">
|
||||
<mat-icon>account_circle</mat-icon>
|
||||
</a>
|
||||
</li>
|
||||
<ng-template #accountDrop>
|
||||
<li class="nav-item">
|
||||
<button mat-icon-button [matMenuTriggerFor]="accountMenu" class="icon" matTooltipPosition="below" [matTooltip]="authManager.user.profile.name">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</li>
|
||||
<mat-menu #accountMenu="matMenu">
|
||||
<button mat-menu-item>Settings</button>
|
||||
<button mat-menu-item>Logout</button>
|
||||
</mat-menu>
|
||||
</ng-template>
|
||||
</ul>
|
||||
</nav>
|
||||
<mat-progress-bar *ngIf="this.isLoading" color="accent" mode="indeterminate"> </mat-progress-bar>
|
||||
|
@ -71,7 +71,6 @@ input::-webkit-search-cancel-button
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.icon
|
||||
{
|
||||
padding: 8px;
|
||||
@ -83,4 +82,4 @@ input::-webkit-search-cancel-button
|
||||
cursor: pointer;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { Event, Router, NavigationStart, NavigationEnd, NavigationCancel, NavigationError } from '@angular/router';
|
||||
import * as $ from "jquery";
|
||||
import { Location } from "@angular/common";
|
||||
import {AuthService} from "./services/auth.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@ -14,7 +15,7 @@ export class AppComponent
|
||||
libraries: Library[];
|
||||
isLoading: boolean = false;
|
||||
|
||||
constructor(http: HttpClient, private router: Router, private location: Location)
|
||||
constructor(http: HttpClient, private router: Router, private location: Location, private authManager: AuthService)
|
||||
{
|
||||
http.get<Library[]>("api/libraries").subscribe(result =>
|
||||
{
|
||||
@ -66,6 +67,16 @@ export class AppComponent
|
||||
this.location.back();
|
||||
}
|
||||
}
|
||||
|
||||
isLoggedIn(): boolean
|
||||
{
|
||||
return this.authManager.isLoggedIn();
|
||||
}
|
||||
|
||||
login()
|
||||
{
|
||||
this.authManager.login();
|
||||
}
|
||||
}
|
||||
|
||||
interface Library
|
||||
|
@ -30,6 +30,7 @@ import { MatFormFieldModule } from "@angular/material/form-field";
|
||||
import {MatTabsModule} from "@angular/material/tabs";
|
||||
import {PasswordValidator} from "./misc/password-validator";
|
||||
import {MatCheckboxModule} from "@angular/material/checkbox";
|
||||
import { LoggedComponent } from './logged/logged.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -44,7 +45,8 @@ import {MatCheckboxModule} from "@angular/material/checkbox";
|
||||
PeopleListComponent,
|
||||
ShowsListComponent,
|
||||
LoginComponent,
|
||||
PasswordValidator
|
||||
PasswordValidator,
|
||||
LoggedComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
1
src/app/logged/logged.component.html
Normal file
1
src/app/logged/logged.component.html
Normal file
@ -0,0 +1 @@
|
||||
<p>logged works!</p>
|
0
src/app/logged/logged.component.scss
Normal file
0
src/app/logged/logged.component.scss
Normal file
21
src/app/logged/logged.component.ts
Normal file
21
src/app/logged/logged.component.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {AuthService} from "../services/auth.service";
|
||||
import {Router} from "@angular/router";
|
||||
|
||||
@Component({
|
||||
selector: 'app-logged',
|
||||
templateUrl: './logged.component.html',
|
||||
styleUrls: ['./logged.component.scss']
|
||||
})
|
||||
export class LoggedComponent implements OnInit
|
||||
{
|
||||
constructor(private authManager: AuthService, private router: Router) { }
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.authManager.loginCallback().then(result =>
|
||||
{
|
||||
// this.router.navigateByUrl("");
|
||||
});
|
||||
}
|
||||
}
|
@ -35,9 +35,9 @@
|
||||
</div>
|
||||
</form>
|
||||
</mat-tab>
|
||||
<mat-tab label="Signin">
|
||||
<mat-tab label="Register">
|
||||
<br/>
|
||||
<form #signinForm="ngForm" (ngSubmit)="signin()">
|
||||
<form #signinForm="ngForm" (ngSubmit)="register()">
|
||||
<mat-card-content>
|
||||
<mat-form-field appearance="outline" class="w-75">
|
||||
<mat-label>Email</mat-label>
|
||||
|
@ -1,6 +1,10 @@
|
||||
import { Component } from '@angular/core';
|
||||
import {AuthService} from "../services/auth.service";
|
||||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import {catchError} from "rxjs/operators";
|
||||
import {EMPTY} from "rxjs";
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
@ -12,25 +16,29 @@ export class LoginComponent
|
||||
loginInformation: {username: string, password: string, stayLoggedIn: boolean} = {username: "", password: "", stayLoggedIn: false};
|
||||
signinInformation: {email: string, username: string, password: string} = {email: "", username: "", password: ""};
|
||||
hidePassword: boolean = true;
|
||||
redirectURI: string = "/";
|
||||
redirectURI: string;
|
||||
|
||||
constructor(private authService: AuthService, private router: Router, private route: ActivatedRoute)
|
||||
constructor(private router: Router, private route: ActivatedRoute, private http: HttpClient, private snackBar: MatSnackBar)
|
||||
{
|
||||
if (this.route.snapshot.queryParams["redirectURI"])
|
||||
this.redirectURI = this.route.snapshot.queryParams["redirectURI"];
|
||||
if (this.route.snapshot.queryParams["ReturnUrl"])
|
||||
this.redirectURI = this.route.snapshot.queryParams["ReturnUrl"];
|
||||
if (this.route.snapshot.queryParams["otac"])
|
||||
this.useOTAC(this.route.snapshot.queryParams["otac"]);
|
||||
}
|
||||
|
||||
async login()
|
||||
{
|
||||
this.authService.login(this.loginInformation)
|
||||
.subscribe(() =>
|
||||
{
|
||||
this.router.navigateByUrl(this.redirectURI);
|
||||
}, error => {
|
||||
console.log("Login error: " + error);
|
||||
});
|
||||
this.http.post("/api/account/login", this.loginInformation).pipe(catchError((error =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
this.snackBar.open(`An unknown error occured: ${error.message}.`, null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
return EMPTY;
|
||||
}))).subscribe(() =>
|
||||
{
|
||||
window.location.href = this.redirectURI;
|
||||
}, error => {
|
||||
console.log("Login error: " + error);
|
||||
});
|
||||
}
|
||||
|
||||
useOTAC(otac: string)
|
||||
@ -38,14 +46,14 @@ export class LoginComponent
|
||||
console.log("Got an OTAC: " + otac);
|
||||
}
|
||||
|
||||
async signin()
|
||||
async register()
|
||||
{
|
||||
this.authService.register(this.signinInformation)
|
||||
.subscribe(result =>
|
||||
{
|
||||
this.useOTAC(result);
|
||||
}, error => {
|
||||
console.log("Register error: " + error);
|
||||
});
|
||||
// @ts-ignore
|
||||
this.http.post<string>("/api/account/register", this.signinInformation, {responseType: "text"}).pipe(catchError((error =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
this.snackBar.open(`An unknown error occured: ${error.message}.`, null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
return EMPTY;
|
||||
}))).subscribe(otac => { this.useOTAC(otac); });
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { UserManager, UserManagerSettings, User } from 'oidc-client';
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import { catchError } from 'rxjs/operators';
|
||||
import {EMPTY, Observable} from "rxjs";
|
||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||
import {UserManager, UserManagerSettings, User, Profile} from 'oidc-client';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -13,45 +9,52 @@ export class AuthService
|
||||
user: User | null;
|
||||
private _userManager = new UserManager(this.getClientSettings());
|
||||
|
||||
constructor(private http: HttpClient, private snackBar: MatSnackBar)
|
||||
constructor()
|
||||
{
|
||||
this._userManager.getUser().then(user =>
|
||||
{
|
||||
this.user = user;
|
||||
if (user)
|
||||
console.log("Logged in as: " + user.profile.name);
|
||||
else
|
||||
console.log("Not logged in.");
|
||||
});
|
||||
}
|
||||
|
||||
login(loginInformation: any)
|
||||
isLoggedIn(): boolean
|
||||
{
|
||||
return this.http.post("/api/account/login", loginInformation).pipe(catchError((error =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
this.snackBar.open(`An unknown error occured: ${error.message}.`, null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
return EMPTY;
|
||||
})));
|
||||
return this.user != null && !this.user.expired;
|
||||
}
|
||||
|
||||
register(userRegistration: any) : Observable<string>
|
||||
|
||||
getClaims(): Profile
|
||||
{
|
||||
// @ts-ignore
|
||||
return this.http.post<string>("/api/account/register", userRegistration, {responseType: "text"}).pipe(catchError((error =>
|
||||
return this.user.profile;
|
||||
}
|
||||
|
||||
login()
|
||||
{
|
||||
return this._userManager.signinRedirect();
|
||||
}
|
||||
|
||||
loginCallback()
|
||||
{
|
||||
return this._userManager.signinCallback().then(user =>
|
||||
{
|
||||
console.log(error.status + " - " + error.message);
|
||||
this.snackBar.open(`An unknown error occured: ${error.message}.`, null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 2500 });
|
||||
return EMPTY;
|
||||
})));
|
||||
this.user = user;
|
||||
console.log("Logged in!");
|
||||
});
|
||||
}
|
||||
|
||||
getClientSettings(): UserManagerSettings
|
||||
{
|
||||
return {
|
||||
authority: "",
|
||||
authority: window.location.origin,
|
||||
client_id: "kyoo.webapp",
|
||||
redirect_uri: "/logged",
|
||||
response_type:"id_token token",
|
||||
scope:"openid profile kyoo.read"
|
||||
silent_redirect_uri: "/silent",
|
||||
response_type: "code",
|
||||
scope: "openid profile kyoo.read offline_access",
|
||||
automaticSilentRenew: true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
12
src/assets/silent.html
Normal file
12
src/assets/silent.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Silent renew</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
new window.Oidc.UserManager().signinSilentCallback();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -103,3 +103,8 @@ mat-icon
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.cdk-overlay-container
|
||||
{
|
||||
z-index: 2000 !important;
|
||||
}
|
BIN
static/icon.jpg
BIN
static/icon.jpg
Binary file not shown.
Before Width: | Height: | Size: 25 KiB |
BIN
static/logo.jpg
BIN
static/logo.jpg
Binary file not shown.
Before Width: | Height: | Size: 63 KiB |
Loading…
x
Reference in New Issue
Block a user