Merge branch 'develop-test2' of https://github.com/Ombi-app/Ombi into develop-test2

pull/4019/head
twanariens 4 years ago
commit e51c950c86

@ -14,6 +14,8 @@ export interface IPlexOAuthViewModel {
export interface IPlexOAuthAccessToken { export interface IPlexOAuthAccessToken {
accessToken: string; accessToken: string;
success: boolean;
error: string;
} }
export interface IPlexUser { export interface IPlexUser {

@ -15,7 +15,7 @@
<input type="password" matInput id="adminPassword" name="Password" [(ngModel)]="user.password" placeholder="Password"> <input type="password" matInput id="adminPassword" name="Password" [(ngModel)]="user.password" placeholder="Password">
</mat-form-field> </mat-form-field>
</div> </div>
<small class="important">You'll need to configure e-mail to recover any lost password!</small> <small class="important">You'll need to configure e-mail to reset your password!</small>
</div> </div>
</div> </div>
</div> </div>

@ -4,21 +4,22 @@
</div> </div>
<div class="right-container mediaserver"> <div class="right-container mediaserver">
<div class="right-container-content mediaserver"> <div class="right-container-content mediaserver">
<h1>Customize your Ombi</h1> <h1 *ngIf="!config.applicationName">Customize your Ombi</h1>
<h1 *ngIf="config.applicationName">Customize your {{config.applicationName}}</h1>
<div> <div>
<mat-form-field> <mat-form-field>
<input type="text" matInput id="applicationname" name="Application Name" placeholder="Application Name"> <input type="text" matInput id="applicationname" name="Application Name" [(ngModel)]="config.applicationName" placeholder="Application Name">
</mat-form-field> </mat-form-field>
</div> </div>
<div> <div>
<mat-form-field> <mat-form-field>
<input matInput type="text" id="applicationurl" name="Application URL" placeholder="Application URL"> <input matInput type="text" id="applicationurl" name="Application URL" [(ngModel)]="config.applicationUrl" placeholder="Application URL">
</mat-form-field> </mat-form-field>
</div> </div>
<div> <div>
<mat-form-field> <mat-form-field>
<mat-label>Custom Logo</mat-label> <mat-label>Custom Logo</mat-label>
<input matInput type="url" id="customlogo" name="Custom Logo" placeholder="Input the URL of your custom logo"> <input matInput type="url" id="customlogo" name="Custom Logo" [(ngModel)]="config.logo" placeholder="Input the URL of your custom logo">
</mat-form-field> </mat-form-field>
</div> </div>
</div> </div>

@ -1,4 +1,6 @@
import { Component, Input } from "@angular/core"; import { Component, Input } from "@angular/core";
import { IOmbiConfigModel } from "../models/OmbiConfigModel";
import { WizardService } from "../services/wizard.service";
@Component({ @Component({
selector: "wizard-ombi", selector: "wizard-ombi",
@ -7,5 +9,5 @@
}) })
export class OmbiConfigComponent { export class OmbiConfigComponent {
constructor() { } @Input() public config: IOmbiConfigModel;
} }

@ -1,4 +1,4 @@
<div class="mediaserver-container"> <div class="mediaserver-container" >
<div class="left-container mediaserver"> <div class="left-container mediaserver">
<img src="https://www.plex.tv/wp-content/themes/plex/assets/img/plex-logo.svg"> <img src="https://www.plex.tv/wp-content/themes/plex/assets/img/plex-logo.svg">
</div> </div>
@ -8,12 +8,12 @@
<div class="form-group"> <div class="form-group">
<div> <div>
<mat-form-field> <mat-form-field>
<input matInput type="text" [(ngModel)]="login" id="username" placeholder="Username"> <input matInput type="text" [(ngModel)]="login" id="username" placeholder="Username" [disabled]="completed">
</mat-form-field> </mat-form-field>
</div> </div>
<div> <div>
<mat-form-field> <mat-form-field>
<input matInput type="password" [(ngModel)]="password" placeholder="Password"> <input matInput type="password" [(ngModel)]="password" placeholder="Password" [disabled]="completed">
</mat-form-field> </mat-form-field>
</div> </div>
</div> </div>
@ -21,13 +21,15 @@
<div class="plex-buttons"> <div class="plex-buttons">
<div class="form-group"> <div class="form-group">
<div style="text-align: center; margin-top: 20px"> <div style="text-align: center; margin-top: 20px">
<button (click)="requestAuthToken()" mat-raised-button color="primary" class="viewon-btn standard">Request Token <i class="fas fa-key"></i></button> <button (click)="requestAuthToken()" mat-raised-button color="primary" class="viewon-btn standard" [disabled]="completed">Request Token <i class="fas fa-key"></i></button>
</div> </div>
</div> </div>
<p class="text-center space-or">OR</p> <p class="text-center space-or">OR</p>
<div class="form-group"> <div class="form-group">
<div style="text-align: center; margin-top: 20px"> <div style="text-align: center; margin-top: 20px">
<button (click)="oauth()" mat-raised-button color="accent" type="button" class="viewon-btn plex">Login With Plex</button> <button (click)="oauth()" mat-raised-button color="accent" type="button" class="viewon-btn plex" [disabled]="completed">
<i *ngIf="oauthLoading" class="fas fa-circle-notch fa-spin fa-fw"></i>
Login With Plex</button>
</div> </div>
</div> </div>
</div> </div>

@ -16,6 +16,8 @@ export class PlexComponent implements OnInit, OnDestroy {
public login: string; public login: string;
public password: string; public password: string;
public pinTimer: any; public pinTimer: any;
public completed: boolean;
public oauthLoading: boolean;
private clientId: string; private clientId: string;
@ -43,7 +45,7 @@ export class PlexComponent implements OnInit, OnDestroy {
usePlexAdminAccount: true, usePlexAdminAccount: true,
}).subscribe(y => { }).subscribe(y => {
if (y.result) { if (y.result) {
this.router.navigate(["login"]); this.notificationService.success("Created your Plex User!");
} else { } else {
this.notificationService.error("Could not get the Plex Admin Information"); this.notificationService.error("Could not get the Plex Admin Information");
if (y.errors.length > 0) { if (y.errors.length > 0) {
@ -57,6 +59,7 @@ export class PlexComponent implements OnInit, OnDestroy {
} }
public oauth() { public oauth() {
this.oauthLoading = true;
const oAuthWindow = window.open(window.location.toString(), "_blank", `toolbar=0, const oAuthWindow = window.open(window.location.toString(), "_blank", `toolbar=0,
location=0, location=0,
status=0, status=0,
@ -69,20 +72,24 @@ export class PlexComponent implements OnInit, OnDestroy {
this.authService.login({ usePlexOAuth: true, password: "", rememberMe: true, username: "", plexTvPin: pin }).subscribe(x => { this.authService.login({ usePlexOAuth: true, password: "", rememberMe: true, username: "", plexTvPin: pin }).subscribe(x => {
oAuthWindow!.location.replace(x.url); oAuthWindow!.location.replace(x.url);
this.pinTimer = setInterval(() => { this.pinTimer = setInterval(() => {
// this.notify.info("Authenticating", "Loading... Please Wait"); // this.notify.info("Authenticating", "Loading... Please Wait");
this.getPinResult(x.pinId); this.getPinResult(x.pinId);
}, 10000); }, 3000);
}); });
}); });
} }
public getPinResult(pinId: number) { public getPinResult(pinId: number) {
this.plexOauth.oAuth(pinId).subscribe(x => { this.plexOauth.oAuth(pinId).subscribe(x => {
if (!x.accessToken) { if (!x.accessToken) {
if(!x.success) {
this.oauthLoading = false;
clearInterval(this.pinTimer);
this.notificationService.error(`Error From Plex: ${x.error}`)
}
return; return;
// RETURN
} }
this.identityService.createWizardUser({ this.identityService.createWizardUser({
@ -93,10 +100,14 @@ export class PlexComponent implements OnInit, OnDestroy {
if (u.result) { if (u.result) {
this.authService.oAuth(pinId).subscribe(c => { this.authService.oAuth(pinId).subscribe(c => {
this.store.save("id_token", c.access_token); this.store.save("id_token", c.access_token);
this.router.navigate(["login"]); this.completed = true;
this.notificationService.success("Created your Plex User!");
this.oauthLoading = false;
clearInterval(this.pinTimer);
}); });
} else { } else {
this.oauthLoading = false;
if (u.errors.length > 0) { if (u.errors.length > 0) {
console.log(u.errors[0]); console.log(u.errors[0]);
} }

@ -1,6 +1,7 @@
import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; import { PlatformLocation, APP_BASE_HREF } from "@angular/common";
import { HttpClient } from "@angular/common/http"; import { HttpClient } from "@angular/common/http";
import { Injectable, Inject } from "@angular/core"; import { Injectable, Inject } from "@angular/core";
import { Observable } from "rxjs";
import { ICustomizationSettings } from "../../interfaces"; import { ICustomizationSettings } from "../../interfaces";
import { ServiceHelpers } from "../../services"; import { ServiceHelpers } from "../../services";
import { IOmbiConfigModel } from "../models/OmbiConfigModel"; import { IOmbiConfigModel } from "../models/OmbiConfigModel";
@ -12,7 +13,7 @@ export class WizardService extends ServiceHelpers {
super(http, "/api/v2/wizard/", href); super(http, "/api/v2/wizard/", href);
} }
public async addOmbiConfig(config: IOmbiConfigModel): Promise<ICustomizationSettings> { public addOmbiConfig(config: IOmbiConfigModel): Observable<ICustomizationSettings> {
return await this.http.post<ICustomizationSettings>(`${this.url}config`, config, {headers: this.headers}).toPromise(); return this.http.post<ICustomizationSettings>(`${this.url}config`, config, {headers: this.headers});
} }
} }

@ -44,7 +44,7 @@
</form> </form>
</mat-step> </mat-step>
<mat-step> <mat-step>
<form > <form>
<ng-template matStepLabel>Create a local admin</ng-template> <ng-template matStepLabel>Create a local admin</ng-template>
<wizard-local-admin [user]="localUser"></wizard-local-admin> <wizard-local-admin [user]="localUser"></wizard-local-admin>
<div> <div>
@ -56,7 +56,7 @@
<mat-step [optional]="true"> <mat-step [optional]="true">
<form > <form >
<ng-template matStepLabel>Ombi config</ng-template> <ng-template matStepLabel>Ombi config</ng-template>
<wizard-ombi></wizard-ombi> <wizard-ombi [config]="config"></wizard-ombi>
<div> <div>
<button mat-button matStepperPrevious class="mat-raised-button mat-error left">Back</button> <button mat-button matStepperPrevious class="mat-raised-button mat-error left">Back</button>
<button mat-button matStepperNext class="mat-raised-button mat-accent right">Next</button> <button mat-button matStepperNext class="mat-raised-button mat-accent right">Next</button>
@ -84,4 +84,4 @@
</mat-step> </mat-step>
</mat-horizontal-stepper> </mat-horizontal-stepper>
</div> </div>
</div> </div>

@ -1,37 +1,53 @@
import { Component, OnInit } from "@angular/core"; import { AfterViewInit, Component, OnInit, ViewChild } from "@angular/core";
import { Router } from "@angular/router"; import { Router } from "@angular/router";
import { ICreateWizardUser } from "../../interfaces"; import { ICreateWizardUser } from "../../interfaces";
import { IdentityService, NotificationService } from "../../services"; import { IdentityService, NotificationService } from "../../services";
import { IOmbiConfigModel } from "../models/OmbiConfigModel";
import { WizardService } from "../services/wizard.service";
import { MatHorizontalStepper } from'@angular/material/stepper';
import { StepperSelectionEvent } from "@angular/cdk/stepper";
@Component({ @Component({
templateUrl: "./welcome.component.html", templateUrl: "./welcome.component.html",
styleUrls: ["./welcome.component.scss"], styleUrls: ["./welcome.component.scss"],
}) })
export class WelcomeComponent implements OnInit { export class WelcomeComponent implements OnInit {
@ViewChild('stepper', {static: false}) public stepper: MatHorizontalStepper;
public localUser: ICreateWizardUser; public localUser: ICreateWizardUser;
public config: IOmbiConfigModel;
constructor(private router: Router,
private identityService: IdentityService, private notificationService: NotificationService) { }
public ngOnInit(): void { constructor(private router: Router, private identityService: IdentityService,
private notificationService: NotificationService, private WizardService: WizardService) { }
public ngOnInit(): void {
this.localUser = { this.localUser = {
password:"", password:"",
username:"", username:"",
usePlexAdminAccount:false usePlexAdminAccount:false
} }
this.config = {
applicationName: null,
applicationUrl: null,
logo: null
};
} }
public createUser() { public createUser() {
this.identityService.createWizardUser(this.localUser).subscribe(x => { this.WizardService.addOmbiConfig(this.config).subscribe(config => {
if (x.result) { if(config != null) {
this.identityService.createWizardUser(this.localUser).subscribe(x => {
if (x.result) {
// save the config
this.router.navigate(["login"]); this.router.navigate(["login"]);
} else { } else {
if (x.errors.length > 0) { if (x.errors.length > 0) {
this.notificationService.error(x.errors[0]); this.notificationService.error(x.errors[0]);
this.stepper.previous();
} }
} }
}); });
} }
}, configErr => this.notificationService.error(configErr));
}
} }

@ -139,7 +139,7 @@ namespace Ombi.Controllers.V1
public async Task<SaveWizardResult> CreateWizardUser([FromBody] CreateUserWizardModel user) public async Task<SaveWizardResult> CreateWizardUser([FromBody] CreateUserWizardModel user)
{ {
var users = UserManager.Users; var users = UserManager.Users;
if (users.Any(x => x.NormalizedUserName != "API")) if (users.Any(x => x.UserType == UserType.LocalUser))
{ {
// No one should be calling this. Only the wizard // No one should be calling this. Only the wizard
return new SaveWizardResult { Result = false, Errors = new List<string> { "Looks like there is an existing user!" } }; return new SaveWizardResult { Result = false, Errors = new List<string> { "Looks like there is an existing user!" } };
@ -169,7 +169,7 @@ namespace Ombi.Controllers.V1
ImportPlexAdmin = true ImportPlexAdmin = true
}); });
return await SaveWizardUser(user, adminUser); return await SaveWizardUser(user, adminUser, false);
} }
var userToCreate = new OmbiUser var userToCreate = new OmbiUser
@ -179,10 +179,10 @@ namespace Ombi.Controllers.V1
StreamingCountry = "US" StreamingCountry = "US"
}; };
return await SaveWizardUser(user, userToCreate); return await SaveWizardUser(user, userToCreate, true);
} }
private async Task<SaveWizardResult> SaveWizardUser(CreateUserWizardModel user, OmbiUser userToCreate) private async Task<SaveWizardResult> SaveWizardUser(CreateUserWizardModel user, OmbiUser userToCreate, bool completeWizard)
{ {
IdentityResult result; IdentityResult result;
var retVal = new SaveWizardResult(); var retVal = new SaveWizardResult();
@ -210,10 +210,13 @@ namespace Ombi.Controllers.V1
_log.LogInformation("Added the Admin role"); _log.LogInformation("Added the Admin role");
} }
// Update the wizard flag if (completeWizard)
var settings = await OmbiSettings.GetSettingsAsync(); {
settings.Wizard = true; // Update the wizard flag
await OmbiSettings.SaveSettingsAsync(settings); var settings = await OmbiSettings.GetSettingsAsync();
settings.Wizard = true;
await OmbiSettings.SaveSettingsAsync(settings);
}
} }
if (!result.Succeeded) if (!result.Succeeded)
{ {

Loading…
Cancel
Save