diff --git a/angular.json b/angular.json index 50b7f79e..c72ee753 100644 --- a/angular.json +++ b/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" - } - } } } }}, diff --git a/package.json b/package.json index a0e72f12..73630896 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index a3dea235..e7dce1a0 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -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 } ]; diff --git a/src/app/app.component.html b/src/app/app.component.html index 59db43c4..0aa9aedd 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -19,11 +19,22 @@ search - + + + + + + + diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 8de6972c..0b559097 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -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; } -} +} \ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts index d3b10c82..02650aa4 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -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("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 diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 98f0aaae..16a26c7e 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -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, diff --git a/src/app/logged/logged.component.html b/src/app/logged/logged.component.html new file mode 100644 index 00000000..17e21512 --- /dev/null +++ b/src/app/logged/logged.component.html @@ -0,0 +1 @@ +

logged works!

diff --git a/src/app/logged/logged.component.scss b/src/app/logged/logged.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/logged/logged.component.ts b/src/app/logged/logged.component.ts new file mode 100644 index 00000000..83442f7c --- /dev/null +++ b/src/app/logged/logged.component.ts @@ -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(""); + }); + } +} diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 0b7772a3..60a85774 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -35,9 +35,9 @@ - +
-
+ Email diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index 69f06ed8..f81e3b96 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -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("/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); }); } } diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index 891cec2a..48609f85 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -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 + + getClaims(): Profile { - // @ts-ignore - return this.http.post("/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 }; } } diff --git a/src/assets/silent.html b/src/assets/silent.html new file mode 100644 index 00000000..d8d70d57 --- /dev/null +++ b/src/assets/silent.html @@ -0,0 +1,12 @@ + + + + + Silent renew + + + + + \ No newline at end of file diff --git a/src/styles.scss b/src/styles.scss index ecaaddb8..105625c2 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -103,3 +103,8 @@ mat-icon padding-left: 0; padding-right: 0; } + +.cdk-overlay-container +{ + z-index: 2000 !important; +} \ No newline at end of file diff --git a/static/icon.jpg b/static/icon.jpg deleted file mode 100644 index e514c1ce..00000000 Binary files a/static/icon.jpg and /dev/null differ diff --git a/static/logo.jpg b/static/logo.jpg deleted file mode 100644 index 6af789b2..00000000 Binary files a/static/logo.jpg and /dev/null differ