You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Ombi/src/Ombi/ClientApp/src/app/login/login.component.ts

273 lines
7.3 KiB

import { Component, OnDestroy, OnInit, Inject } from "@angular/core";
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { TranslateService } from "@ngx-translate/core";
import { APP_BASE_HREF } from "@angular/common";
import { AuthService } from "../auth/auth.service";
import { IAuthenticationSettings, ICustomizationSettings } from "../interfaces";
import { PlexTvService } from "../services";
import { SettingsService } from "../services";
import { StatusService } from "../services";
import { StorageService } from "../shared/storage/storage-service";
import { MatSnackBar } from "@angular/material/snack-bar";
import { CustomizationFacade } from "../state/customization";
@Component({
templateUrl: "./login.component.html",
styleUrls: ["./login.component.scss"],
})
export class LoginComponent implements OnDestroy, OnInit {
public form: UntypedFormGroup;
public customizationSettings: ICustomizationSettings;
public authenticationSettings: IAuthenticationSettings;
public plexEnabled: boolean;
public landingFlag: boolean;
public baseUrl: string;
public loginWithOmbi: boolean;
public pinTimer: any;
public oauthLoading: boolean;
public get appName(): string {
if (this.customizationSettings.applicationName) {
return this.customizationSettings.applicationName;
} else {
return "Ombi";
}
}
public get appNameTranslate(): object {
return { appName: this.appName };
}
private clientId: string;
private errorBody: string;
private errorValidation: string;
private href: string;
private oAuthWindow: Window | null;
constructor(
private authService: AuthService,
private router: Router,
private status: StatusService,
private fb: UntypedFormBuilder,
private settingsService: SettingsService,
private customziationFacade: CustomizationFacade,
private route: ActivatedRoute,
@Inject(APP_BASE_HREF) href: string,
private translate: TranslateService,
private plexTv: PlexTvService,
private store: StorageService,
private readonly notify: MatSnackBar
) {
this.href = href;
this.route.params.subscribe((params: any) => {
this.landingFlag = params.landing;
if (!this.landingFlag) {
this.settingsService.getLandingPage().subscribe((x) => {
if (x.enabled && !this.landingFlag) {
this.router.navigate(["landingpage"]);
}
});
}
});
this.form = this.fb.group({
username: ["", Validators.required],
password: [""],
rememberMe: [false],
});
this.status.getWizardStatus().subscribe((x) => {
if (!x.result) {
this.router.navigate(["Wizard"]);
}
});
if (authService.loggedIn()) {
this.router.navigate(["/"]);
}
}
public ngOnInit() {
this.customziationFacade.settings$().subscribe(x => this.customizationSettings = x);
this.settingsService
.getAuthentication()
.subscribe((x) => {
this.authenticationSettings = x;
this.headerAuth();
});
this.settingsService.getClientId().subscribe((x) => (this.clientId = x));
const base = this.href;
if (base.length > 1) {
this.baseUrl = base;
}
this.translate
.get("Login.Errors.IncorrectCredentials")
.subscribe((x) => (this.errorBody = x));
this.translate
.get("Common.Errors.Validation")
.subscribe((x) => (this.errorValidation = x));
}
public onSubmit(form: UntypedFormGroup) {
if (form.invalid) {
this.notify.open(this.errorValidation, "OK", {
duration: 300000,
});
return;
}
const value = form.value;
const user = {
password: value.password,
username: value.username,
rememberMe: value.rememberMe,
usePlexOAuth: false,
plexTvPin: { id: 0, code: "" },
};
this.authService.requiresPassword(user).subscribe((x) => {
if (x && this.authenticationSettings.allowNoPassword) {
// Looks like this user requires a password
this.authenticationSettings.allowNoPassword = false;
return;
}
this.authService.login(user).subscribe(
(x) => {
this.store.save("id_token", x.access_token);
if (this.authService.loggedIn()) {
this.ngOnDestroy();
this.router.navigate(["/"]);
} else {
this.notify.open(this.errorBody, "OK", {
duration: 3000,
});
}
},
(err) => {
this.notify.open(this.errorBody, "OK", {
duration: 3000000,
});
}
);
});
}
public oauth() {
if (this.oAuthWindow) {
this.oAuthWindow.close();
}
this.oAuthWindow = window.open(
window.location.toString(),
"_blank",
`toolbar=0,
location=0,
status=0,
menubar=0,
scrollbars=1,
resizable=1,
width=500,
height=500`
);
this.plexTv.GetPin(this.clientId, this.appName).subscribe((pin: any) => {
this.authService
.login({
usePlexOAuth: true,
password: "",
rememberMe: true,
username: "",
plexTvPin: pin,
})
.subscribe((x) => {
this.oAuthWindow!.location.replace(x.url);
if (this.pinTimer) {
clearInterval(this.pinTimer);
}
this.pinTimer = setInterval(() => {
this.oauthLoading = true;
this.getPinResult(x.pinId);
}, 1000);
});
});
}
public getPinResult(pinId: number) {
if (this.oAuthWindow.closed) {
if (this.pinTimer) {
clearInterval(this.pinTimer);
}
}
this.authService.oAuth(pinId).subscribe(
(x) => {
if (x.access_token) {
clearInterval(this.pinTimer);
this.store.save("id_token", x.access_token);
if (this.authService.loggedIn()) {
this.ngOnDestroy();
if (this.oAuthWindow) {
this.oAuthWindow.close();
}
this.oauthLoading = false;
this.router.navigate(["search"]);
return;
}
}
// if (notifyUser) {
// this.notify.open("Could not log you in!", "OK", {
// duration: 3000,
// });
// }
this.oauthLoading = false;
},
(err) => {
console.log(err);
this.notify.open("You are not authenticated with Ombi", "OK", {
duration: 3000,
});
this.router.navigate(["login"]);
}
);
}
public headerAuth() {
if (this.authenticationSettings.enableHeaderAuth) {
this.authService.headerAuth().subscribe({
next: (x) => {
this.store.save("id_token", x.access_token);
if (this.authService.loggedIn()) {
this.ngOnDestroy();
this.router.navigate(["/"]);
} else {
this.notify.open(this.errorBody, "OK", {
duration: 3000,
});
}
},
error: (e) => {
this.notify.open(this.errorBody, "OK", {
duration: 3000000,
});
console.error(e);
}
}
);
}
}
public ngOnDestroy() {
clearInterval(this.pinTimer);
}
}