mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-13 18:16:55 -07:00
frontend is all done !wip
This commit is contained in:
parent
2fc4ef2613
commit
2cd9c4d9b1
14 changed files with 146 additions and 52 deletions
|
@ -208,7 +208,7 @@ namespace Ombi.Api.Plex
|
|||
AddHeaders(request);
|
||||
var forwardUrl = wizard
|
||||
? new Request($"Wizard/OAuth/{pinId}", applicationUrl, HttpMethod.Get)
|
||||
: new Request($"api/v1/PlexOAuth/{pinId}", applicationUrl, HttpMethod.Get);
|
||||
: new Request($"Login/OAuth/{pinId}", applicationUrl, HttpMethod.Get);
|
||||
|
||||
request.AddQueryString("forwardUrl", forwardUrl.FullUri.ToString());
|
||||
request.AddQueryString("pinID", pinId.ToString());
|
||||
|
|
|
@ -24,6 +24,7 @@ import { CookieComponent } from "./auth/cookie.component";
|
|||
import { PageNotFoundComponent } from "./errors/not-found.component";
|
||||
import { LandingPageComponent } from "./landingpage/landingpage.component";
|
||||
import { LoginComponent } from "./login/login.component";
|
||||
import { LoginOAuthComponent } from "./login/loginoauth.component";
|
||||
import { ResetPasswordComponent } from "./login/resetpassword.component";
|
||||
import { TokenResetPasswordComponent } from "./login/tokenresetpassword.component";
|
||||
|
||||
|
@ -41,6 +42,7 @@ const routes: Routes = [
|
|||
{ path: "*", component: PageNotFoundComponent },
|
||||
{ path: "", redirectTo: "/search", pathMatch: "full" },
|
||||
{ path: "login", component: LoginComponent },
|
||||
{ path: "Login/OAuth/:pin", component: LoginOAuthComponent },
|
||||
{ path: "login/:landing", component: LoginComponent },
|
||||
{ path: "reset", component: ResetPasswordComponent },
|
||||
{ path: "token", component: TokenResetPasswordComponent },
|
||||
|
@ -116,6 +118,7 @@ export function HttpLoaderFactory(http: HttpClient, platformLocation: PlatformLo
|
|||
ResetPasswordComponent,
|
||||
TokenResetPasswordComponent,
|
||||
CookieComponent,
|
||||
LoginOAuthComponent,
|
||||
],
|
||||
providers: [
|
||||
NotificationService,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
username: string;
|
||||
password: string;
|
||||
rememberMe: boolean;
|
||||
usePlexOAuth: boolean;
|
||||
}
|
||||
|
||||
export interface ILocalUser {
|
||||
|
|
|
@ -7,11 +7,13 @@ include the remember me checkbox
|
|||
<div *ngIf="background" @fadeInOut class="bg" [style.background-image]="background"></div>
|
||||
<div class="container" id="login">
|
||||
<div class="card card-container">
|
||||
|
||||
<!-- <img class="profile-img-card" src="//lh3.googleusercontent.com/-6V8xOA6M7BA/AAAAAAAAAAI/AAAAAAAAAAA/rzlHcD0KYwo/photo.jpg?sz=120" alt="" /> -->
|
||||
<div *ngIf="!customizationSettings.logo"><img id="profile-img" class="profile-img-card" src="{{baseUrl}}/images/logo.png"/></div>
|
||||
<div *ngIf="customizationSettings.logo"><img id="profile-img" class="center" [src]="customizationSettings.logo" /></div>
|
||||
<p id="profile-name" class="profile-name-card"></p>
|
||||
|
||||
<div *ngIf="showLoginForm && loginWithOmbi">
|
||||
<form *ngIf="authenticationSettings" class="form-signin" novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
|
||||
|
||||
|
||||
|
@ -27,6 +29,16 @@ include the remember me checkbox
|
|||
</div>
|
||||
<button class="btn btn-success" type="submit" [translate]="'Login.SignInButton'"></button>
|
||||
</form><!-- /form -->
|
||||
</div>
|
||||
<div class="form-signin" *ngIf="plexEnabled && customizationSettings.applicationUrl && !loginWithOmbi">
|
||||
<button class="btn btn-success" type="button" (click)="loginWithOmbi = true">
|
||||
Continue With {{appName}}</button>
|
||||
</div>
|
||||
<div class="form-signin" *ngIf="plexEnabled && customizationSettings.applicationUrl && !loginWithOmbi">
|
||||
<button class="btn btn-primary" type="button" (click)="oauth()">
|
||||
Continue With Plex</button>
|
||||
</div>
|
||||
|
||||
<a [routerLink]="['/reset']" class="forgot-password col-md-12">
|
||||
<b [translate]="'Login.ForgottenPassword'"></b>
|
||||
</a>
|
||||
|
|
|
@ -25,9 +25,39 @@ export class LoginComponent implements OnDestroy, OnInit {
|
|||
public form: FormGroup;
|
||||
public customizationSettings: ICustomizationSettings;
|
||||
public authenticationSettings: IAuthenticationSettings;
|
||||
public plexEnabled: boolean;
|
||||
public background: any;
|
||||
public landingFlag: boolean;
|
||||
public baseUrl: string;
|
||||
|
||||
public get showLoginForm(): boolean {
|
||||
if(this.customizationSettings.applicationUrl && this.plexEnabled) {
|
||||
this.loginWithOmbi = false;
|
||||
return false;
|
||||
}
|
||||
if(!this.customizationSettings.applicationUrl || !this.plexEnabled) {
|
||||
|
||||
this.loginWithOmbi = true;
|
||||
return true;
|
||||
}
|
||||
if(this.loginWithOmbi) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
this.loginWithOmbi = true;
|
||||
return true;
|
||||
}
|
||||
public loginWithOmbi: boolean = false;
|
||||
|
||||
public get appName(): string {
|
||||
if(this.customizationSettings.applicationName) {
|
||||
return this.customizationSettings.applicationName;
|
||||
} else {
|
||||
return "Ombi";
|
||||
}
|
||||
}
|
||||
|
||||
private timer: any;
|
||||
|
||||
private errorBody: string;
|
||||
|
@ -68,6 +98,7 @@ export class LoginComponent implements OnDestroy, OnInit {
|
|||
public ngOnInit() {
|
||||
this.settingsService.getAuthentication().subscribe(x => this.authenticationSettings = x);
|
||||
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
||||
this.settingsService.getStatusPlex().subscribe(x => this.plexEnabled = x);
|
||||
this.images.getRandomBackground().subscribe(x => {
|
||||
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")");
|
||||
});
|
||||
|
@ -90,7 +121,7 @@ export class LoginComponent implements OnDestroy, OnInit {
|
|||
return;
|
||||
}
|
||||
const value = form.value;
|
||||
const user = { password: value.password, username: value.username, rememberMe:value.rememberMe };
|
||||
const user = { password: value.password, username: value.username, rememberMe: value.rememberMe, usePlexOAuth: false };
|
||||
this.authService.requiresPassword(user).subscribe(x => {
|
||||
if(x && this.authenticationSettings.allowNoPassword) {
|
||||
// Looks like this user requires a password
|
||||
|
@ -111,6 +142,12 @@ export class LoginComponent implements OnDestroy, OnInit {
|
|||
});
|
||||
}
|
||||
|
||||
public oauth() {
|
||||
this.authService.login({usePlexOAuth: true, password:"",rememberMe:true,username:""}).subscribe(x => {
|
||||
window.location.href = x.url;
|
||||
})
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
|
|
9
src/Ombi/ClientApp/app/login/loginoauth.component.html
Normal file
9
src/Ombi/ClientApp/app/login/loginoauth.component.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
<div >
|
||||
|
||||
<div class="container" id="login">
|
||||
<div class="card card-container">
|
||||
<label>Please Wait...</label>
|
||||
</div><!-- /card-container -->
|
||||
</div><!-- /container -->
|
||||
</div>
|
35
src/Ombi/ClientApp/app/login/loginoauth.component.ts
Normal file
35
src/Ombi/ClientApp/app/login/loginoauth.component.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
|
||||
import { AuthService } from "../auth/auth.service";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./loginoauth.component.html"
|
||||
})
|
||||
export class LoginOAuthComponent implements OnInit {
|
||||
public pin: number;
|
||||
|
||||
constructor(private authService: AuthService, private router: Router,
|
||||
private route: ActivatedRoute) {
|
||||
this.route.params
|
||||
.subscribe((params: any) => {
|
||||
this.pin = params.pin;
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.auth();
|
||||
}
|
||||
|
||||
public auth() {
|
||||
this.authService.oAuth(this.pin).subscribe(x => {
|
||||
localStorage.setItem("id_token", x.access_token);
|
||||
|
||||
if (this.authService.loggedIn()) {
|
||||
this.router.navigate(["search"]);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
|
@ -71,6 +71,10 @@ export class SettingsService extends ServiceHelpers {
|
|||
return this.http.get<IPlexSettings>(`${this.url}/Plex/`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public getStatusPlex(): Observable<boolean> {
|
||||
return this.http.get<boolean>(`${this.url}/Plexstatus/`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public savePlex(settings: IPlexSettings): Observable<boolean> {
|
||||
return this.http.post<boolean>(`${this.url}/Plex/`, JSON.stringify(settings), {headers: this.headers});
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ export class CreateAdminComponent {
|
|||
this.identityService.createWizardUser({username: this.username, password: this.password, usePlexAdminAccount: false}).subscribe(x => {
|
||||
if (x) {
|
||||
// Log me in.
|
||||
this.auth.login({ username: this.username, password: this.password, rememberMe:false }).subscribe(c => {
|
||||
this.auth.login({ username: this.username, password: this.password, rememberMe: false, usePlexOAuth:false }).subscribe(c => {
|
||||
|
||||
localStorage.setItem("id_token", c.access_token);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<button (click)="oauth()" class="btn btn-sucess">Sign In With Plex <i class="fa fa-key"></i></button>
|
||||
<button (click)="oauth()" class="btn btn-sucess" type="button">Continue With Plex</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { Component } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
|
||||
import { ConfirmationService } from "primeng/primeng";
|
||||
|
||||
import { PlexService } from "../../services";
|
||||
import { IdentityService, NotificationService, SettingsService } from "../../services";
|
||||
|
@ -17,7 +16,6 @@ export class PlexComponent {
|
|||
|
||||
constructor(private plexService: PlexService, private router: Router,
|
||||
private notificationService: NotificationService,
|
||||
private confirmationService: ConfirmationService,
|
||||
private identityService: IdentityService,
|
||||
private settings: SettingsService,
|
||||
private auth: AuthService) { }
|
||||
|
@ -28,25 +26,21 @@ export class PlexComponent {
|
|||
this.notificationService.error("Username or password was incorrect. Could not authenticate with Plex.");
|
||||
return;
|
||||
}
|
||||
this.confirmationService.confirm({
|
||||
message: "Do you want your Plex user to be the main admin account on Ombi?",
|
||||
header: "Use Plex Account",
|
||||
icon: "fa fa-check",
|
||||
accept: () => {
|
||||
|
||||
this.identityService.createWizardUser({
|
||||
username: "",
|
||||
password: "",
|
||||
usePlexAdminAccount: true,
|
||||
}).subscribe(x => {
|
||||
if (x) {
|
||||
this.auth.login({ username: this.login, password: this.password, rememberMe:false }).subscribe(c => {
|
||||
}).subscribe(y => {
|
||||
if (y) {
|
||||
this.auth.login({ username: this.login, password: this.password, rememberMe: false, usePlexOAuth: false }).subscribe(c => {
|
||||
localStorage.setItem("id_token", c.access_token);
|
||||
|
||||
// Mark that we have done the settings now
|
||||
this.settings.getOmbi().subscribe(ombi => {
|
||||
ombi.wizard = true;
|
||||
|
||||
this.settings.saveOmbi(ombi).subscribe(x => {
|
||||
this.settings.saveOmbi(ombi).subscribe(s => {
|
||||
this.settings.getUserManagementSettings().subscribe(usr => {
|
||||
|
||||
usr.importPlexAdmin = true;
|
||||
|
@ -63,12 +57,8 @@ export class PlexComponent {
|
|||
return;
|
||||
}
|
||||
});
|
||||
},
|
||||
reject: () => {
|
||||
this.router.navigate(["Wizard/CreateAdmin"]);
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public oauth() {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
|
||||
import { ConfirmationService } from "primeng/primeng";
|
||||
|
||||
import { PlexOAuthService, IdentityService, SettingsService } from "../../services";
|
||||
import { AuthService } from "./../../auth/auth.service";
|
||||
|
||||
|
@ -14,7 +12,6 @@ export class PlexOAuthComponent implements OnInit {
|
|||
|
||||
constructor(private route: ActivatedRoute,
|
||||
private plexOauth: PlexOAuthService,
|
||||
private confirmationService: ConfirmationService,
|
||||
private identityService: IdentityService,
|
||||
private settings: SettingsService,
|
||||
private router: Router,
|
||||
|
@ -28,19 +25,18 @@ export class PlexOAuthComponent implements OnInit {
|
|||
|
||||
ngOnInit(): void {
|
||||
this.plexOauth.oAuth(this.pinId).subscribe(x => {
|
||||
x.accessToken;
|
||||
if(!x.accessToken) {
|
||||
return;
|
||||
// RETURN
|
||||
}
|
||||
|
||||
|
||||
this.confirmationService.confirm({
|
||||
message: "Do you want your Plex user to be the main admin account on Ombi?",
|
||||
header: "Use Plex Account",
|
||||
icon: "fa fa-check",
|
||||
accept: () => {
|
||||
this.identityService.createWizardUser({
|
||||
username: "",
|
||||
password: "",
|
||||
usePlexAdminAccount: true,
|
||||
}).subscribe(x => {
|
||||
if (x) {
|
||||
}).subscribe(u => {
|
||||
if (u) {
|
||||
this.auth.oAuth(this.pinId).subscribe(c => {
|
||||
localStorage.setItem("id_token", c.access_token);
|
||||
|
||||
|
@ -48,7 +44,7 @@ export class PlexOAuthComponent implements OnInit {
|
|||
this.settings.getOmbi().subscribe(ombi => {
|
||||
ombi.wizard = true;
|
||||
|
||||
this.settings.saveOmbi(ombi).subscribe(x => {
|
||||
this.settings.saveOmbi(ombi).subscribe(s => {
|
||||
this.settings.getUserManagementSettings().subscribe(usr => {
|
||||
|
||||
usr.importPlexAdmin = true;
|
||||
|
@ -65,11 +61,7 @@ export class PlexOAuthComponent implements OnInit {
|
|||
return;
|
||||
}
|
||||
});
|
||||
},
|
||||
reject: () => {
|
||||
this.router.navigate(["Wizard/CreateAdmin"]);
|
||||
},
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -151,6 +151,16 @@ namespace Ombi.Controllers
|
|||
return s;
|
||||
}
|
||||
|
||||
[HttpGet("plexstatus")]
|
||||
[AllowAnonymous]
|
||||
public async Task<bool> PlexStatusSettings()
|
||||
{
|
||||
var s = await Get<PlexSettings>();
|
||||
|
||||
|
||||
return s.Enable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the Plex settings.
|
||||
/// </summary>
|
||||
|
|
|
@ -48,6 +48,8 @@ namespace Ombi.Controllers
|
|||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> GetToken([FromBody] UserAuthModel model)
|
||||
{
|
||||
if (!model.UsePlexOAuth)
|
||||
{
|
||||
await _audit.Record(AuditType.None, AuditArea.Authentication,
|
||||
$"UserName {model.Username} attempting to authenticate");
|
||||
|
@ -67,8 +69,7 @@ namespace Ombi.Controllers
|
|||
user.EmailLogin = true;
|
||||
}
|
||||
|
||||
if (!model.UsePlexOAuth)
|
||||
{
|
||||
|
||||
// Verify Password
|
||||
if (await _userManager.CheckPasswordAsync(user, model.Password))
|
||||
{
|
||||
|
@ -91,7 +92,7 @@ namespace Ombi.Controllers
|
|||
error = "Application URL has not been set"
|
||||
});
|
||||
}
|
||||
return new RedirectResult(url.ToString());
|
||||
return new JsonResult(new { url = url.ToString() });
|
||||
}
|
||||
|
||||
return new UnauthorizedResult();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue